Author: sguilhen(a)redhat.com
Date: 2009-09-16 10:09:44 -0400 (Wed, 16 Sep 2009)
New Revision: 794
Modified:
identity-federation/trunk/jboss-identity-bindings/src/test/java/org/jboss/test/identity/federation/bindings/wstrust/JBossSTSUnitTestCase.java
identity-federation/trunk/jboss-identity-fed-core/src/main/java/org/jboss/identity/federation/core/wstrust/StandardRequestHandler.java
identity-federation/trunk/jboss-identity-fed-core/src/main/java/org/jboss/identity/federation/core/wstrust/WSTrustConstants.java
identity-federation/trunk/jboss-identity-fed-core/src/main/java/org/jboss/identity/federation/core/wstrust/WSTrustRequestContext.java
identity-federation/trunk/jboss-identity-fed-core/src/main/java/org/jboss/identity/federation/core/wstrust/WSTrustUtil.java
identity-federation/trunk/jboss-identity-fed-core/src/main/java/org/jboss/identity/federation/core/wstrust/wrappers/RequestSecurityToken.java
Log:
JBID-138: added symmetric key logic to StandardRequestHandler
Modified:
identity-federation/trunk/jboss-identity-bindings/src/test/java/org/jboss/test/identity/federation/bindings/wstrust/JBossSTSUnitTestCase.java
===================================================================
---
identity-federation/trunk/jboss-identity-bindings/src/test/java/org/jboss/test/identity/federation/bindings/wstrust/JBossSTSUnitTestCase.java 2009-09-14
22:54:54 UTC (rev 793)
+++
identity-federation/trunk/jboss-identity-bindings/src/test/java/org/jboss/test/identity/federation/bindings/wstrust/JBossSTSUnitTestCase.java 2009-09-16
14:09:44 UTC (rev 794)
@@ -48,6 +48,7 @@
import org.jboss.identity.federation.core.wstrust.WSTrustException;
import org.jboss.identity.federation.core.wstrust.WSTrustJAXBFactory;
import org.jboss.identity.federation.core.wstrust.WSTrustRequestHandler;
+import org.jboss.identity.federation.core.wstrust.WSTrustUtil;
import org.jboss.identity.federation.core.wstrust.plugins.saml.SAML20TokenProvider;
import org.jboss.identity.federation.core.wstrust.plugins.saml.SAMLUtil;
import
org.jboss.identity.federation.core.wstrust.wrappers.BaseRequestSecurityTokenResponse;
@@ -65,6 +66,9 @@
import org.jboss.identity.federation.ws.addressing.EndpointReferenceType;
import org.jboss.identity.federation.ws.addressing.ObjectFactory;
import org.jboss.identity.federation.ws.policy.AppliesTo;
+import org.jboss.identity.federation.ws.trust.BinarySecretType;
+import org.jboss.identity.federation.ws.trust.EntropyType;
+import org.jboss.identity.federation.ws.trust.RequestedProofTokenType;
import org.jboss.identity.federation.ws.trust.RequestedReferenceType;
import org.jboss.identity.federation.ws.trust.RequestedSecurityTokenType;
import org.jboss.identity.federation.ws.trust.StatusType;
@@ -182,7 +186,7 @@
assertNotNull("Unexpected null token provider", provider);
assertTrue("Unexpected token provider type", provider instanceof
SAML20TokenProvider);
assertNull(config.getProviderForTokenElementNS("SpecialToken",
"InvalidNamespace"));
-
+
// check the service provider -> token type mapping.
assertEquals("Invalid token type for service provider 1",
"http://www.tokens.org/SpecialToken", config
.getTokenTypeForService("http://services.testcorp.org/provider1"));
@@ -363,6 +367,91 @@
/**
* <p>
+ * This test requests a security token specifying a key type (symmetric or public).
The generated security token
+ * should include the key as a proof-of-possession token. In the symmetric key case,
the WS-Trust response should
+ * also include either the computed key (when client key is combined with the key
generated by the STS) or the key
+ * generated by the STS (when client keys is not specified and is up to the STS to
create one).
+ * </p>
+ *
+ * @throws Exception if an error occurs while running the test.
+ */
+ @SuppressWarnings("unchecked")
+ public void testInvokeSAML20WithProofToken() throws Exception
+ {
+ // create a simple token request, asking for a SAMLv2.0 token.
+ RequestSecurityToken request = this.createRequest("testcontext",
WSTrustConstants.ISSUE_REQUEST,
+ SAMLUtil.SAML2_TOKEN_TYPE, null);
+
+ // add a symmetric key type to the request, but don't supply any client key -
STS should generate one.
+ request.setKeyType(URI.create(WSTrustConstants.KEY_TYPE_SYMMETRIC));
+
+ // use the factory to marshall the request.
+ WSTrustJAXBFactory factory = WSTrustJAXBFactory.getInstance();
+ Source requestMessage = factory.marshallRequestSecurityToken(request);
+
+ // invoke the token service.
+ Source responseMessage = this.tokenService.invoke(requestMessage);
+ BaseRequestSecurityTokenResponse baseResponse = WSTrustJAXBFactory.getInstance()
+ .parseRequestSecurityTokenResponse(responseMessage);
+
+ // validate the security token response.
+ this.validateSAMLAssertionResponse(baseResponse);
+
+ // check if the response contains the STS-generated key.
+ RequestSecurityTokenResponseCollection collection =
(RequestSecurityTokenResponseCollection) baseResponse;
+ RequestSecurityTokenResponse response =
collection.getRequestSecurityTokenResponses().get(0);
+ RequestedProofTokenType proofToken = response.getRequestedProofToken();
+ assertNotNull("Unexpected null proof token", proofToken);
+ assertTrue(proofToken.getAny() instanceof JAXBElement);
+ JAXBElement proofElement = (JAXBElement) proofToken.getAny();
+ assertEquals("Unexpected proof token content", BinarySecretType.class,
proofElement.getDeclaredType());
+ BinarySecretType serverBinarySecret = (BinarySecretType) proofElement.getValue();
+ assertNotNull("Unexpected null secret", serverBinarySecret.getValue());
+ // default key size is 256 bits (32 bytes).
+ assertEquals("Unexpected secret size", 32,
serverBinarySecret.getValue().length);
+
+ // let's now create a request that specifies the client entropy using a 512
bits secret.
+ byte[] clientSecret = WSTrustUtil.createRandomSecret(64);
+ BinarySecretType clientBinarySecret = new BinarySecretType();
+ clientBinarySecret.setType(WSTrustConstants.BS_TYPE_NONCE);
+ clientBinarySecret.setValue(clientSecret);
+ EntropyType clientEntropy = new EntropyType();
+ clientEntropy.getAny().add(
+ new
org.jboss.identity.federation.ws.trust.ObjectFactory().createBinarySecret(clientBinarySecret));
+ request.setEntropy(clientEntropy);
+ request.setKeySize(512);
+
+ // invoke the token service.
+ requestMessage = factory.marshallRequestSecurityToken(request);
+ responseMessage = this.tokenService.invoke(requestMessage);
+ baseResponse =
WSTrustJAXBFactory.getInstance().parseRequestSecurityTokenResponse(responseMessage);
+
+ // validate the security token response.
+ this.validateSAMLAssertionResponse(baseResponse);
+
+ collection = (RequestSecurityTokenResponseCollection) baseResponse;
+ response = collection.getRequestSecurityTokenResponses().get(0);
+ proofToken = response.getRequestedProofToken();
+ assertNotNull("Unexpected null proof token", proofToken);
+ assertTrue(proofToken.getAny() instanceof JAXBElement);
+ proofElement = (JAXBElement) proofToken.getAny();
+ // proof token should contain only the computed key algorithm.
+ assertEquals("Unexpected proof token content", "ComputedKey",
proofElement.getName().getLocalPart());
+ assertEquals("Unexpected computed key algorithm",
WSTrustConstants.CK_PSHA1, proofElement.getValue());
+ // server entropy must have been included in the response to allow construction of
the computed key.
+ EntropyType serverEntropy = response.getEntropy();
+ assertNotNull("Unexpected null server entropy");
+ assertEquals("Invalid number of elements in server entropy", 1,
serverEntropy.getAny().size());
+ JAXBElement serverEntropyContent = (JAXBElement) serverEntropy.getAny().get(0);
+ assertEquals("Unexpected proof token content", BinarySecretType.class,
serverEntropyContent.getDeclaredType());
+ serverBinarySecret = (BinarySecretType) serverEntropyContent.getValue();
+ assertEquals("Unexpected binary secret type",
WSTrustConstants.BS_TYPE_NONCE, serverBinarySecret.getType());
+ assertNotNull("Unexpected null secret value",
serverBinarySecret.getValue());
+ assertEquals("Unexpected secret size", 64,
serverBinarySecret.getValue().length);
+ }
+
+ /**
+ * <p>
* This test case first generates a SAMLV2.0 assertion and then sends a WS-Trust
validate message to the STS to get
* the assertion validated, checking the validation results.
* </p>
@@ -382,8 +471,7 @@
// invoke the token service.
Source responseMessage = this.tokenService.invoke(requestMessage);
- BaseRequestSecurityTokenResponse baseResponse = factory
- .parseRequestSecurityTokenResponse(responseMessage);
+ BaseRequestSecurityTokenResponse baseResponse =
factory.parseRequestSecurityTokenResponse(responseMessage);
// get the SAML assertion from the request.
RequestSecurityTokenResponseCollection collection =
(RequestSecurityTokenResponseCollection) baseResponse;
@@ -457,12 +545,11 @@
}
catch (WebServiceException we)
{
- assertEquals("Unexpected exception message", "Exception in handling
token request:", we
- .getMessage());
+ assertEquals("Unexpected exception message", "Exception in
handling token request:", we.getMessage());
assertNotNull("Unexpected null cause", we.getCause());
assertTrue("Unexpected cause type", we.getCause() instanceof
WSTrustException);
assertEquals("Unexpected exception message", "Unable to find a
token provider for the token request", we
- .getCause().getMessage());
+ .getCause().getMessage());
}
}
@@ -501,9 +588,9 @@
assertTrue("Unexpected token class", token instanceof Element);
Element element = (Element) requestedToken.getAny();
assertEquals("Unexpected namespace value",
"http://www.tokens.org", element.getNamespaceURI());
-
- assertEquals("Unexpected attribute value",
"http://www.tokens.org/SpecialToken", element
- .getAttributeNS("http://www.tokens.org", "TokenType"));
+
+ assertEquals("Unexpected attribute value",
"http://www.tokens.org/SpecialToken", element.getAttributeNS(
+ "http://www.tokens.org", "TokenType"));
assertEquals("Unexpected token value", "Principal:sguilhen",
element.getFirstChild().getNodeValue());
}
Modified:
identity-federation/trunk/jboss-identity-fed-core/src/main/java/org/jboss/identity/federation/core/wstrust/StandardRequestHandler.java
===================================================================
---
identity-federation/trunk/jboss-identity-fed-core/src/main/java/org/jboss/identity/federation/core/wstrust/StandardRequestHandler.java 2009-09-14
22:54:54 UTC (rev 793)
+++
identity-federation/trunk/jboss-identity-fed-core/src/main/java/org/jboss/identity/federation/core/wstrust/StandardRequestHandler.java 2009-09-16
14:09:44 UTC (rev 794)
@@ -22,10 +22,13 @@
package org.jboss.identity.federation.core.wstrust;
import java.net.URI;
+import java.security.InvalidKeyException;
import java.security.KeyPair;
+import java.security.NoSuchAlgorithmException;
import java.security.Principal;
import java.security.PublicKey;
+import javax.xml.bind.JAXBElement;
import javax.xml.crypto.dsig.DigestMethod;
import javax.xml.crypto.dsig.SignatureMethod;
@@ -36,6 +39,10 @@
import org.jboss.identity.federation.core.wstrust.wrappers.RequestSecurityToken;
import org.jboss.identity.federation.core.wstrust.wrappers.RequestSecurityTokenResponse;
import org.jboss.identity.federation.ws.policy.AppliesTo;
+import org.jboss.identity.federation.ws.trust.BinarySecretType;
+import org.jboss.identity.federation.ws.trust.EntropyType;
+import org.jboss.identity.federation.ws.trust.ObjectFactory;
+import org.jboss.identity.federation.ws.trust.RequestedProofTokenType;
import org.jboss.identity.federation.ws.trust.RequestedSecurityTokenType;
import org.jboss.identity.federation.ws.trust.StatusType;
import org.w3c.dom.Document;
@@ -57,6 +64,8 @@
private boolean trace = log.isTraceEnabled();
+ private static long KEY_SIZE = 256;
+
private STSConfiguration configuration;
/*
@@ -118,50 +127,78 @@
request.setLifetime(WSTrustUtil.createDefaultLifetime(this.configuration.getIssuedTokenTimeout()));
}
requestContext.setServiceProviderPublicKey(providerPublicKey);
- provider.issueToken(requestContext);
- if (requestContext.getSecurityToken() == null)
- throw new WSTrustException("Token issued by provider " +
provider.getClass().getName() + " is null");
+ // get the key type and size from the request, setting default values if not
specified.
+ URI keyType = request.getKeyType();
+ if (keyType == null)
+ {
+ keyType = URI.create(WSTrustConstants.KEY_TYPE_BEARER);
+ request.setKeyType(keyType);
+ }
+ long keySize = request.getKeySize();
+ if (keySize == 0)
+ {
+ keySize = KEY_SIZE;
+ request.setKeySize(keySize);
+ }
- // sign the issued token if needed.
- /*if (this.configuration.signIssuedToken() &&
this.configuration.getSTSKeyPair() != null)
+ // create proof-of-possession token and server entropy (if needed).
+ RequestedProofTokenType requestedProofToken = null;
+ EntropyType serverEntropy = null;
+
+ if (WSTrustConstants.KEY_TYPE_SYMMETRIC.equalsIgnoreCase(keyType.toString()))
{
- KeyPair keyPair = this.configuration.getSTSKeyPair();
- if (keyPair != null)
+ requestedProofToken = new RequestedProofTokenType();
+ ObjectFactory objFactory = new ObjectFactory();
+ // symmetric key case: if client entropy is found, compute a key. If not,
generate a new key.
+ byte[] clientSecret = null;
+ EntropyType clientEntropy = request.getEntropy();
+ if (clientEntropy != null)
+ clientSecret = WSTrustUtil.getBinarySecret(clientEntropy);
+
+ byte[] serverSecret = WSTrustUtil.createRandomSecret((int) keySize / 8);
+ BinarySecretType serverBinarySecret = new BinarySecretType();
+ serverBinarySecret.setType(WSTrustConstants.BS_TYPE_NONCE);
+ serverBinarySecret.setValue(serverSecret);
+ serverEntropy = new EntropyType();
+
serverEntropy.getAny().add(objFactory.createBinarySecret(serverBinarySecret));
+
+ if (clientSecret != null && clientSecret.length != 0)
{
- URI signatureURI = request.getSignatureAlgorithm();
- String signatureMethod = signatureURI != null ? signatureURI.toString() :
SignatureMethod.RSA_SHA1;
+ // client secret has been specified - combine it with the sts secret.
+
requestedProofToken.setAny(objFactory.createComputedKey(WSTrustConstants.CK_PSHA1));
try
{
- Element tokenElement = (Element)
requestContext.getSecurityToken().getTokenValue();
- XMLSignatureUtil.sign(tokenElement.getOwnerDocument(), keyPair,
DigestMethod.SHA1, signatureMethod,
- "#" + requestContext.getSecurityToken().getTokenID());
- if(trace)
- {
- try
- {
- log.trace("Signed Token:" +
DocumentUtil.getNodeAsString(tokenElement));
-
- Document tokenDocument = DocumentUtil.createDocument();
- tokenDocument.appendChild(tokenDocument.importNode(tokenElement,
true));
- log.trace("valid=" +
XMLSignatureUtil.validate(tokenDocument, keyPair.getPublic()));
-
- }catch(Exception ignore){}
- }
+ byte[] combinedSecret = WSTrustUtil.P_SHA1(clientSecret, serverSecret,
(int) keySize / 8);
+ requestContext.setProofToken(combinedSecret);
}
catch (Exception e)
{
- throw new WSTrustException("Failed to sign security token",
e);
+ throw new WSTrustException("Error generating combined secret
key", e);
}
}
- }*/
+ else
+ {
+ // client secret has not been specified - use the sts secret only.
+
requestedProofToken.setAny(objFactory.createBinarySecret(serverBinarySecret));
+ requestContext.setProofToken(serverSecret);
+ }
+ }
+ else if (WSTrustConstants.KEY_TYPE_PUBLIC.equalsIgnoreCase(keyType.toString()))
+ {
+ // TODO: implement public key case.
+ }
+ // issue the security token using the constructed context.
+ provider.issueToken(requestContext);
+
+ if (requestContext.getSecurityToken() == null)
+ throw new WSTrustException("Token issued by provider " +
provider.getClass().getName() + " is null");
+
// construct the ws-trust security token response.
RequestedSecurityTokenType requestedSecurityToken = new
RequestedSecurityTokenType();
requestedSecurityToken.setAny(requestContext.getSecurityToken().getTokenValue());
- // TODO: create proof token and encrypt the token if needed
-
RequestSecurityTokenResponse response = new RequestSecurityTokenResponse();
if (request.getContext() != null)
response.setContext(request.getContext());
@@ -170,7 +207,12 @@
response.setLifetime(request.getLifetime());
response.setAppliesTo(appliesTo);
response.setRequestedSecurityToken(requestedSecurityToken);
-
+
+ if(requestedProofToken != null)
+ response.setRequestedProofToken(requestedProofToken);
+ if(serverEntropy != null)
+ response.setEntropy(serverEntropy);
+
// set the attached and unattached references.
if (requestContext.getAttachedReference() != null)
response.setRequestedAttachedReference(requestContext.getAttachedReference());
@@ -283,11 +325,11 @@
request.setTokenType(URI.create(WSTrustConstants.STATUS_TYPE));
Node securityToken = request.getValidateTargetElement().getFirstChild();
- SecurityTokenProvider provider = this.configuration.getProviderForTokenElementNS(
- securityToken.getLocalName(), securityToken.getNamespaceURI());
+ SecurityTokenProvider provider =
this.configuration.getProviderForTokenElementNS(securityToken.getLocalName(),
+ securityToken.getNamespaceURI());
if (provider == null)
- throw new WSTrustException("No SecurityTokenProvider configured for "
- + securityToken.getNamespaceURI() + ":" +
securityToken.getLocalName());
+ throw new WSTrustException("No SecurityTokenProvider configured for "
+ securityToken.getNamespaceURI() + ":"
+ + securityToken.getLocalName());
WSTrustRequestContext context = new WSTrustRequestContext(request,
callerPrincipal);
@@ -328,7 +370,7 @@
}
// TODO: add logging statements alerting that signature validation was not
performed.
- // if the signature is valid, then let the provider handle perform any additional
validation checks.
+ // if the signature is valid, then let the provider perform any additional
validation checks.
if (status == null)
{
provider.validateToken(context);
Modified:
identity-federation/trunk/jboss-identity-fed-core/src/main/java/org/jboss/identity/federation/core/wstrust/WSTrustConstants.java
===================================================================
---
identity-federation/trunk/jboss-identity-fed-core/src/main/java/org/jboss/identity/federation/core/wstrust/WSTrustConstants.java 2009-09-14
22:54:54 UTC (rev 793)
+++
identity-federation/trunk/jboss-identity-fed-core/src/main/java/org/jboss/identity/federation/core/wstrust/WSTrustConstants.java 2009-09-16
14:09:44 UTC (rev 794)
@@ -43,6 +43,19 @@
public static final String STATUS_CODE_VALID = BASE_NAMESPACE +
"status/valid";
public static final String STATUS_CODE_INVALID = BASE_NAMESPACE +
"status/invalid";
+ // WS-Trust key types.
+ public static final String KEY_TYPE_BEARER = BASE_NAMESPACE + "Bearer";
+ public static final String KEY_TYPE_SYMMETRIC = BASE_NAMESPACE +
"SymmetricKey";
+ public static final String KEY_TYPE_PUBLIC = BASE_NAMESPACE + "PublicKey";
+
+ // WS-Trust binary secret types.
+ public static final String BS_TYPE_ASYMMETRIC = BASE_NAMESPACE +
"AsymmetricKey";
+ public static final String BS_TYPE_SYMMETRIC = BASE_NAMESPACE +
"SymmetricKey";
+ public static final String BS_TYPE_NONCE = BASE_NAMESPACE + "Nonce";
+
+ // WS-Trust computed key types.
+ public static final String CK_PSHA1 = BASE_NAMESPACE + "CK/PSHA1";
+
// WSS namespaces values.
public static final String WSA_NS = "http://www.w3.org/2005/08/addressing";
public static final String WSU_NS =
"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd";
Modified:
identity-federation/trunk/jboss-identity-fed-core/src/main/java/org/jboss/identity/federation/core/wstrust/WSTrustRequestContext.java
===================================================================
---
identity-federation/trunk/jboss-identity-fed-core/src/main/java/org/jboss/identity/federation/core/wstrust/WSTrustRequestContext.java 2009-09-14
22:54:54 UTC (rev 793)
+++
identity-federation/trunk/jboss-identity-fed-core/src/main/java/org/jboss/identity/federation/core/wstrust/WSTrustRequestContext.java 2009-09-16
14:09:44 UTC (rev 794)
@@ -49,6 +49,8 @@
private final RequestSecurityToken request;
+ private Object proofToken;
+
// information supplied by the token provider.
private SecurityToken securityToken;
@@ -147,9 +149,33 @@
/**
* <p>
- * Obtains the security token contained in this context.
+ * Obtains the proof-of-possession token.
* </p>
*
+ * @return an {@code Object} representing the proof-of-possession token.
+ */
+ public Object getProofToken()
+ {
+ return this.proofToken;
+ }
+
+ /**
+ * <p>
+ * Sets the proof-of-possession token in the request context.
+ * </p>
+ *
+ * @param proofToken an {@code Object} representing the proof-of-possession token.
+ */
+ public void setProofToken(Object proofToken)
+ {
+ this.proofToken = proofToken;
+ }
+
+ /**
+ * <p>
+ * Obtains the security token set by the token provider.
+ * </p>
+ *
* @return a reference to the {@code SecurityToken} instance.
*/
public SecurityToken getSecurityToken()
Modified:
identity-federation/trunk/jboss-identity-fed-core/src/main/java/org/jboss/identity/federation/core/wstrust/WSTrustUtil.java
===================================================================
---
identity-federation/trunk/jboss-identity-fed-core/src/main/java/org/jboss/identity/federation/core/wstrust/WSTrustUtil.java 2009-09-14
22:54:54 UTC (rev 793)
+++
identity-federation/trunk/jboss-identity-fed-core/src/main/java/org/jboss/identity/federation/core/wstrust/WSTrustUtil.java 2009-09-16
14:09:44 UTC (rev 794)
@@ -21,9 +21,14 @@
*/
package org.jboss.identity.federation.core.wstrust;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
import java.util.GregorianCalendar;
import java.util.Map;
+import javax.crypto.Mac;
+import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.JAXBElement;
import javax.xml.namespace.QName;
@@ -32,6 +37,8 @@
import org.jboss.identity.federation.ws.addressing.EndpointReferenceType;
import org.jboss.identity.federation.ws.addressing.ObjectFactory;
import org.jboss.identity.federation.ws.policy.AppliesTo;
+import org.jboss.identity.federation.ws.trust.BinarySecretType;
+import org.jboss.identity.federation.ws.trust.EntropyType;
import org.jboss.identity.federation.ws.trust.RequestedReferenceType;
import org.jboss.identity.federation.ws.wss.secext.KeyIdentifierType;
import org.jboss.identity.federation.ws.wss.secext.SecurityTokenReferenceType;
@@ -43,6 +50,7 @@
*
* @author <a href="mailto:sguilhen@redhat.com">Stefan Guilhen</a>
*/
+@SuppressWarnings("unchecked")
public class WSTrustUtil
{
@@ -62,7 +70,7 @@
keyIdentifier.setValue(value);
return keyIdentifier;
}
-
+
/**
* <p>
* Creates an instance of {@code RequestedReferenceType} with the specified values.
This method first creates a
@@ -86,7 +94,7 @@
return reference;
}
-
+
/**
* <p>
* Creates an instance of {@code AppliesTo} using the specified endpoint address.
@@ -154,4 +162,105 @@
return new Lifetime(created, expires);
}
+ /**
+ * <p>
+ * Parses the specified {@code EntropyType} and returns the first binary secret
contained in the entropy.
+ * </p>
+ *
+ * @param entropy a reference to the {@code EntropyType} that contains the binary
secret.
+ * @return a {@code byte[]} containing the secret; {@code null} if the specified
entropy doesn't contain
+ * any secret.
+ */
+ public static byte[] getBinarySecret(EntropyType entropy)
+ {
+ byte[] secret = null;
+
+ for (Object obj : entropy.getAny())
+ {
+ JAXBElement element = (JAXBElement) obj;
+ if (element.getDeclaredType().equals(BinarySecretType.class))
+ {
+ BinarySecretType binarySecret = (BinarySecretType) element.getValue();
+ secret = binarySecret.getValue();
+ break;
+ }
+ }
+ return secret;
+ }
+
+ /**
+ * <p>
+ * Creates a random {@code byte[]} secret of the specified size.
+ * </p>
+ * @param size the size of the secret to be created, in bytes.
+ * @return a {@code byte[]} containing the generated secret.
+ */
+ public static byte[] createRandomSecret(final int size)
+ {
+ SecureRandom random = new SecureRandom();
+ byte[] secret = new byte[size];
+ random.nextBytes(secret);
+ return secret;
+ }
+
+ /**
+ * <p>
+ * This method implements the {@code P_SHA-1} function as defined in the <i>RFC
2246 - The TLS Protocol Version 1.0
+ * Section 5. HMAC and the pseudorandom function</i>:
+ *
+ * <pre>
+ * P_hash(secret, seed) = HMAC_hash(secret, A(1) + seed) +
+ * HMAC_hash(secret, A(2) + seed) +
+ * HMAC_hash(secret, A(3) + seed) + ...
+ *
+ * Where + indicates concatenation.
+ *
+ * A() is defined as:
+ * A(0) = seed
+ * A(i) = HMAC_hash(secret, A(i-1))
+ * </pre>
+ * </p>
+ *
+ * @param secret a {@code byte[]} that represents the HMAC secret.
+ * @param seed a {@code byte[]} that represents the seed to be used.
+ * @param requiredSize an {@code int} that specifies the size (in bytes) of the
result.
+ * @return a {@code byte[]} containing the result of the {@code P_SHA-1} function.
+ * @throws NoSuchAlgorithmException if an error occurs while creating the {@code Mac}
instance.
+ * @throws InvalidKeyException if an error occurs while initializing the {@code Mac}
instance.
+ */
+ public static byte[] P_SHA1(byte[] secret, byte[] seed, int requiredSize) throws
NoSuchAlgorithmException,
+ InvalidKeyException
+ {
+ int offset = 0, copySize;
+ byte[] result = new byte[requiredSize];
+ byte[] A, partialResult;
+
+ SecretKeySpec key = new SecretKeySpec(secret, "HMACSHA1");
+ Mac mac = Mac.getInstance("HMACSHA1");
+
+ // initialize A - A(0) = seed
+ A = seed;
+ while (requiredSize > 0)
+ {
+ // calculate the value of A()
+ mac.init(key);
+ mac.update(A);
+ A = mac.doFinal();
+
+ // now calculate HMAC_hash(secret, A + seed)
+ mac.reset();
+ mac.init(key);
+ mac.update(A);
+ mac.update(seed);
+ partialResult = mac.doFinal();
+
+ // copy the necessary bytes to the result.
+ copySize = Math.min(requiredSize, partialResult.length);
+ System.arraycopy(partialResult, 0, result, offset, copySize);
+ offset += copySize;
+ requiredSize -= copySize;
+ }
+ return result;
+ }
+
}
Modified:
identity-federation/trunk/jboss-identity-fed-core/src/main/java/org/jboss/identity/federation/core/wstrust/wrappers/RequestSecurityToken.java
===================================================================
---
identity-federation/trunk/jboss-identity-fed-core/src/main/java/org/jboss/identity/federation/core/wstrust/wrappers/RequestSecurityToken.java 2009-09-14
22:54:54 UTC (rev 793)
+++
identity-federation/trunk/jboss-identity-fed-core/src/main/java/org/jboss/identity/federation/core/wstrust/wrappers/RequestSecurityToken.java 2009-09-16
14:09:44 UTC (rev 794)
@@ -592,7 +592,7 @@
* Obtains the size of they key that has been set in the request.
* </p>
*
- * @return a {@code long} representing the key size in bytes.
+ * @return a {@code long} representing the key size.
*/
public long getKeySize()
{
@@ -604,7 +604,7 @@
* Sets the size of the key in the request.
* </p>
*
- * @param keySize a {@code long} representing the key size in bytes.
+ * @param keySize a {@code long} representing the key size.
*/
public void setKeySize(long keySize)
{