Author: coheigea
Date: Thu Mar 8 11:15:17 2012
New Revision: 1298359
URL: http://svn.apache.org/viewvc?rev=1298359&view=rev
Log:
[CXF-4156] - Support SymmetricKeys for Entropy/BinarySecret Elements
- Part I.
Modified:
cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/provider/SymmetricKeyHandler.java
cxf/trunk/services/sts/sts-core/src/test/java/org/apache/cxf/sts/operation/IssueSamlUnitTest.java
cxf/trunk/services/sts/sts-core/src/test/java/org/apache/cxf/sts/token/provider/SAMLProviderKeyTypeTest.java
Modified:
cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/provider/SymmetricKeyHandler.java
URL:
http://svn.apache.org/viewvc/cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/provider/SymmetricKeyHandler.java?rev=1298359&r1=1298358&r2=1298359&view=diff
==============================================================================
---
cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/provider/SymmetricKeyHandler.java
(original)
+++
cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/provider/SymmetricKeyHandler.java
Thu Mar 8 11:15:17 2012
@@ -63,20 +63,13 @@ public class SymmetricKeyHandler {
+ " not accepted so defaulting to " +
signatureProperties.getKeySize()
);
}
-
+
// Test Entropy
clientEntropy = keyRequirements.getEntropy();
if (clientEntropy == null) {
LOG.log(Level.WARNING, "A SymmetricKey KeyType is requested, but
no client entropy is provided");
- } else {
- String binarySecurityType = clientEntropy.getBinarySecretType();
+ } else if
(STSConstants.NONCE_TYPE.equals(clientEntropy.getBinarySecretType())) {
byte[] nonce = clientEntropy.getBinarySecretValue();
- if (!STSConstants.NONCE_TYPE.equals(binarySecurityType)) {
- LOG.log(Level.WARNING, "The type " + binarySecurityType + " is
not supported");
- throw new STSException(
- "No user supplied entropy for SymmetricKey case",
STSException.INVALID_REQUEST
- );
- }
if (nonce == null || (nonce.length < (keySize / 8))) {
LOG.log(Level.WARNING, "User Entropy rejected");
clientEntropy = null;
@@ -91,6 +84,23 @@ public class SymmetricKeyHandler {
"Computed Key Algorithm not supported",
STSException.INVALID_REQUEST
);
}
+ } else if
(STSConstants.SYMMETRIC_KEY_TYPE.equals(clientEntropy.getBinarySecretType())
+ || clientEntropy.getBinarySecretType() == null) {
+ byte[] secretValue = clientEntropy.getBinarySecretValue();
+ if ((secretValue.length * 8) <
signatureProperties.getMinimumKeySize()
+ || (secretValue.length * 8) >
signatureProperties.getMaximumKeySize()) {
+ LOG.log(
+ Level.WARNING, "Received secret of length " +
secret.length
+ + " bits is not accepted"
+ );
+ LOG.log(Level.WARNING, "User Entropy rejected");
+ clientEntropy = null;
+ }
+ } else {
+ LOG.log(Level.WARNING, "The type " +
clientEntropy.getBinarySecretType() + " is not supported");
+ throw new STSException(
+ "No user supplied entropy for SymmetricKey case",
STSException.INVALID_REQUEST
+ );
}
}
@@ -98,23 +108,30 @@ public class SymmetricKeyHandler {
* Create the Symmetric Key
*/
public void createSymmetricKey() {
- try {
- entropyBytes = WSSecurityUtil.generateNonce(keySize / 8);
- secret = entropyBytes;
+ if (clientEntropy != null
+ &&
(STSConstants.SYMMETRIC_KEY_TYPE.equals(clientEntropy.getBinarySecretType())
+ || clientEntropy.getBinarySecretType() == null)) {
+ secret = clientEntropy.getBinarySecretValue();
computedKey = false;
- } catch (WSSecurityException ex) {
- LOG.log(Level.WARNING, "", ex);
- throw new STSException("Error in creating symmetric key", ex,
STSException.INVALID_REQUEST);
- }
- if (clientEntropy != null) {
- byte[] nonce = clientEntropy.getBinarySecretValue();
+ } else {
try {
- P_SHA1 psha1 = new P_SHA1();
- secret = psha1.createKey(nonce, entropyBytes, 0, keySize / 8);
- computedKey = true;
- } catch (ConversationException ex) {
+ entropyBytes = WSSecurityUtil.generateNonce(keySize / 8);
+ secret = entropyBytes;
+ computedKey = false;
+ } catch (WSSecurityException ex) {
LOG.log(Level.WARNING, "", ex);
- throw new STSException("Error in creating symmetric key",
STSException.INVALID_REQUEST);
+ throw new STSException("Error in creating symmetric key", ex,
STSException.INVALID_REQUEST);
+ }
+ if (clientEntropy != null) {
+ byte[] nonce = clientEntropy.getBinarySecretValue();
+ try {
+ P_SHA1 psha1 = new P_SHA1();
+ secret = psha1.createKey(nonce, entropyBytes, 0, keySize /
8);
+ computedKey = true;
+ } catch (ConversationException ex) {
+ LOG.log(Level.WARNING, "", ex);
+ throw new STSException("Error in creating symmetric key",
STSException.INVALID_REQUEST);
+ }
}
}
}
Modified:
cxf/trunk/services/sts/sts-core/src/test/java/org/apache/cxf/sts/operation/IssueSamlUnitTest.java
URL:
http://svn.apache.org/viewvc/cxf/trunk/services/sts/sts-core/src/test/java/org/apache/cxf/sts/operation/IssueSamlUnitTest.java?rev=1298359&r1=1298358&r2=1298359&view=diff
==============================================================================
---
cxf/trunk/services/sts/sts-core/src/test/java/org/apache/cxf/sts/operation/IssueSamlUnitTest.java
(original)
+++
cxf/trunk/services/sts/sts-core/src/test/java/org/apache/cxf/sts/operation/IssueSamlUnitTest.java
Thu Mar 8 11:15:17 2012
@@ -497,6 +497,99 @@ public class IssueSamlUnitTest extends o
}
/**
+ * Test to successfully issue a Saml2 SymmetricKey token. Rather than
using a Nonce as the
+ * Entropy, a secret key is supplied by the client instead.
+ */
+ @org.junit.Test
+ public void testIssueSaml2SymmetricKeyTokenSecretKey() throws Exception {
+ TokenIssueOperation issueOperation = new TokenIssueOperation();
+
+ // Add Token Provider
+ List<TokenProvider> providerList = new ArrayList<TokenProvider>();
+ providerList.add(new SAMLTokenProvider());
+ issueOperation.setTokenProviders(providerList);
+
+ // Add Service
+ ServiceMBean service = new StaticService();
+
service.setEndpoints(Collections.singletonList("http://dummy-service.com/dummy"));
+ issueOperation.setServices(Collections.singletonList(service));
+
+ // Add STSProperties object
+ STSPropertiesMBean stsProperties = new StaticSTSProperties();
+ Crypto crypto = CryptoFactory.getInstance(getEncryptionProperties());
+ stsProperties.setEncryptionCrypto(crypto);
+ stsProperties.setSignatureCrypto(crypto);
+ stsProperties.setEncryptionUsername("myservicekey");
+ stsProperties.setSignatureUsername("mystskey");
+ stsProperties.setCallbackHandler(new PasswordCallbackHandler());
+ stsProperties.setIssuer("STS");
+ issueOperation.setStsProperties(stsProperties);
+
+ // Mock up a request
+ RequestSecurityTokenType request = new RequestSecurityTokenType();
+ JAXBElement<String> tokenType =
+ new JAXBElement<String>(
+ QNameConstants.TOKEN_TYPE, String.class,
WSConstants.WSS_SAML2_TOKEN_TYPE
+ );
+ request.getAny().add(tokenType);
+ JAXBElement<String> keyType =
+ new JAXBElement<String>(
+ QNameConstants.KEY_TYPE, String.class,
STSConstants.SYMMETRIC_KEY_KEYTYPE
+ );
+ request.getAny().add(keyType);
+
request.getAny().add(createAppliesToElement("http://dummy-service.com/dummy"));
+
+ // Mock up message context
+ MessageImpl msg = new MessageImpl();
+ WrappedMessageContext msgCtx = new WrappedMessageContext(msg);
+ msgCtx.put(
+ SecurityContext.class.getName(),
+ createSecurityContext(new CustomTokenPrincipal("alice"))
+ );
+ WebServiceContextImpl webServiceContext = new
WebServiceContextImpl(msgCtx);
+
+ // Now add Entropy
+ BinarySecretType binarySecretType = new BinarySecretType();
+ binarySecretType.setType(STSConstants.SYMMETRIC_KEY_TYPE);
+ binarySecretType.setValue(WSSecurityUtil.generateNonce(256 / 8));
+ JAXBElement<BinarySecretType> binarySecretTypeJaxb =
+ new JAXBElement<BinarySecretType>(
+ QNameConstants.BINARY_SECRET, BinarySecretType.class,
binarySecretType
+ );
+
+ EntropyType entropyType = new EntropyType();
+ entropyType.getAny().add(binarySecretTypeJaxb);
+ JAXBElement<EntropyType> entropyJaxbType =
+ new JAXBElement<EntropyType>(QNameConstants.ENTROPY,
EntropyType.class, entropyType);
+ request.getAny().add(entropyJaxbType);
+
+ RequestSecurityTokenResponseCollectionType response =
+ issueOperation.issue(request, webServiceContext);
+ List<RequestSecurityTokenResponseType> securityTokenResponse =
+ response.getRequestSecurityTokenResponse();
+ assertTrue(!securityTokenResponse.isEmpty());
+
+ // Test the generated token.
+ Element assertion = null;
+ for (Object tokenObject : securityTokenResponse.get(0).getAny()) {
+ if (tokenObject instanceof JAXBElement<?>
+ &&
REQUESTED_SECURITY_TOKEN.equals(((JAXBElement<?>)tokenObject).getName())) {
+ RequestedSecurityTokenType rstType =
+
(RequestedSecurityTokenType)((JAXBElement<?>)tokenObject).getValue();
+ assertion = (Element)rstType.getAny();
+ }
+ }
+
+ assertNotNull(assertion);
+ String tokenString = DOM2Writer.nodeToString(assertion);
+ assertTrue(tokenString.contains("AttributeStatement"));
+ assertTrue(tokenString.contains("alice"));
+ assertFalse(tokenString.contains(SAML2Constants.CONF_BEARER));
+ assertTrue(tokenString.contains(SAML2Constants.CONF_HOLDER_KEY));
+ }
+
+
+ /**
* Test to successfully issue a Saml 1.1 token with no References
*/
@org.junit.Test
Modified:
cxf/trunk/services/sts/sts-core/src/test/java/org/apache/cxf/sts/token/provider/SAMLProviderKeyTypeTest.java
URL:
http://svn.apache.org/viewvc/cxf/trunk/services/sts/sts-core/src/test/java/org/apache/cxf/sts/token/provider/SAMLProviderKeyTypeTest.java?rev=1298359&r1=1298358&r2=1298359&view=diff
==============================================================================
---
cxf/trunk/services/sts/sts-core/src/test/java/org/apache/cxf/sts/token/provider/SAMLProviderKeyTypeTest.java
(original)
+++
cxf/trunk/services/sts/sts-core/src/test/java/org/apache/cxf/sts/token/provider/SAMLProviderKeyTypeTest.java
Thu Mar 8 11:15:17 2012
@@ -195,12 +195,6 @@ public class SAMLProviderKeyTypeTest ext
Entropy entropy = new Entropy();
entropy.setBinarySecretValue(WSSecurityUtil.generateNonce(256 / 8));
providerParameters.getKeyRequirements().setEntropy(entropy);
- try {
- samlTokenProvider.createToken(providerParameters);
- fail("Failure expected on no type");
- } catch (STSException ex) {
- // expected as no type is provided
- }
entropy.setBinarySecretType("bad-type");
try {
@@ -251,6 +245,39 @@ public class SAMLProviderKeyTypeTest ext
}
/**
+ * Create a default Saml1 SymmetricKey Assertion. Rather than using a
Nonce as the Entropy,
+ * a secret key is supplied by the client instead.
+ */
+ @org.junit.Test
+ public void testDefaultSaml1SymmetricKeyAssertionSecretKey() throws
Exception {
+ TokenProvider samlTokenProvider = new SAMLTokenProvider();
+ TokenProviderParameters providerParameters =
+ createProviderParameters(WSConstants.WSS_SAML_TOKEN_TYPE,
STSConstants.SYMMETRIC_KEY_KEYTYPE);
+
assertTrue(samlTokenProvider.canHandleToken(WSConstants.WSS_SAML_TOKEN_TYPE));
+
+ Entropy entropy = new Entropy();
+ entropy.setBinarySecretValue(WSSecurityUtil.generateNonce(256 / 8));
+ providerParameters.getKeyRequirements().setEntropy(entropy);
+
+ TokenProviderResponse providerResponse =
samlTokenProvider.createToken(providerParameters);
+ assertTrue(providerResponse != null);
+ assertTrue(providerResponse.getToken() != null &&
providerResponse.getTokenId() != null);
+
+ Element token = providerResponse.getToken();
+ String tokenString = DOM2Writer.nodeToString(token);
+ assertTrue(tokenString.contains(providerResponse.getTokenId()));
+ assertTrue(tokenString.contains("AttributeStatement"));
+ assertFalse(tokenString.contains("AuthenticationStatement"));
+ assertTrue(tokenString.contains("alice"));
+ assertTrue(tokenString.contains(SAML1Constants.CONF_HOLDER_KEY));
+ assertFalse(tokenString.contains(SAML1Constants.CONF_BEARER));
+
+ assertFalse(providerResponse.isComputedKey());
+ assertNull(providerResponse.getEntropy());
+ }
+
+
+ /**
* Create a default Saml2 SymmetricKey Assertion.
*/
@org.junit.Test
@@ -263,12 +290,6 @@ public class SAMLProviderKeyTypeTest ext
Entropy entropy = new Entropy();
entropy.setBinarySecretValue(WSSecurityUtil.generateNonce(256 / 8));
providerParameters.getKeyRequirements().setEntropy(entropy);
- try {
- samlTokenProvider.createToken(providerParameters);
- fail("Failure expected on no type");
- } catch (STSException ex) {
- // expected as no type is provided
- }
entropy.setBinarySecretType("bad-type");
try {