Return-Path: X-Original-To: apmail-cxf-commits-archive@www.apache.org Delivered-To: apmail-cxf-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id BB0119B97 for ; Thu, 8 Mar 2012 11:15:40 +0000 (UTC) Received: (qmail 50666 invoked by uid 500); 8 Mar 2012 11:15:40 -0000 Delivered-To: apmail-cxf-commits-archive@cxf.apache.org Received: (qmail 50620 invoked by uid 500); 8 Mar 2012 11:15:40 -0000 Mailing-List: contact commits-help@cxf.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@cxf.apache.org Delivered-To: mailing list commits@cxf.apache.org Received: (qmail 50603 invoked by uid 99); 8 Mar 2012 11:15:40 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 08 Mar 2012 11:15:40 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 08 Mar 2012 11:15:38 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id 20C29238899C; Thu, 8 Mar 2012 11:15:18 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1298359 - in /cxf/trunk/services/sts/sts-core/src: main/java/org/apache/cxf/sts/token/provider/ test/java/org/apache/cxf/sts/operation/ test/java/org/apache/cxf/sts/token/provider/ Date: Thu, 08 Mar 2012 11:15:17 -0000 To: commits@cxf.apache.org From: coheigea@apache.org X-Mailer: svnmailer-1.0.8-patched Message-Id: <20120308111518.20C29238899C@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org 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 providerList = new ArrayList(); + 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 tokenType = + new JAXBElement( + QNameConstants.TOKEN_TYPE, String.class, WSConstants.WSS_SAML2_TOKEN_TYPE + ); + request.getAny().add(tokenType); + JAXBElement keyType = + new JAXBElement( + 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 binarySecretTypeJaxb = + new JAXBElement( + QNameConstants.BINARY_SECRET, BinarySecretType.class, binarySecretType + ); + + EntropyType entropyType = new EntropyType(); + entropyType.getAny().add(binarySecretTypeJaxb); + JAXBElement entropyJaxbType = + new JAXBElement(QNameConstants.ENTROPY, EntropyType.class, entropyType); + request.getAny().add(entropyJaxbType); + + RequestSecurityTokenResponseCollectionType response = + issueOperation.issue(request, webServiceContext); + List 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 {