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 F31B499DB for ; Fri, 9 Mar 2012 12:11:58 +0000 (UTC) Received: (qmail 25656 invoked by uid 500); 9 Mar 2012 12:11:58 -0000 Delivered-To: apmail-cxf-commits-archive@cxf.apache.org Received: (qmail 25585 invoked by uid 500); 9 Mar 2012 12:11:58 -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 25568 invoked by uid 99); 9 Mar 2012 12:11:58 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 09 Mar 2012 12:11:58 +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; Fri, 09 Mar 2012 12:11:55 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id 6A62223889FA; Fri, 9 Mar 2012 12:11:35 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1298801 - in /cxf/trunk/services/sts/sts-core/src: main/java/org/apache/cxf/sts/operation/ main/java/org/apache/cxf/sts/request/ main/java/org/apache/cxf/sts/token/provider/ test/java/org/apache/cxf/sts/common/ test/java/org/apache/cxf/sts... Date: Fri, 09 Mar 2012 12:11:34 -0000 To: commits@cxf.apache.org From: coheigea@apache.org X-Mailer: svnmailer-1.0.8-patched Message-Id: <20120309121135.6A62223889FA@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: coheigea Date: Fri Mar 9 12:11:34 2012 New Revision: 1298801 URL: http://svn.apache.org/viewvc?rev=1298801&view=rev Log: [CXF-4156] - Support SymmetricKeys for Entropy/BinarySecret Elements - Part II - Support for processing an EncryptedKey child of the client Entropy Added: cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/request/BinarySecret.java - copied, changed from r1298624, cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/request/Entropy.java cxf/trunk/services/sts/sts-core/src/test/resources/servicestore.jks Modified: cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/operation/AbstractOperation.java cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/request/Entropy.java cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/request/RequestParser.java 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/common/PasswordCallbackHandler.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/request/RequestParserUnitTest.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/operation/AbstractOperation.java URL: http://svn.apache.org/viewvc/cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/operation/AbstractOperation.java?rev=1298801&r1=1298800&r2=1298801&view=diff ============================================================================== --- cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/operation/AbstractOperation.java (original) +++ cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/operation/AbstractOperation.java Fri Mar 9 12:11:34 2012 @@ -173,7 +173,7 @@ public abstract class AbstractOperation stsProperties.configureProperties(); RequestParser requestParser = new RequestParser(); - requestParser.parseRequest(request, context); + requestParser.parseRequest(request, context, stsProperties); return requestParser; } Copied: cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/request/BinarySecret.java (from r1298624, cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/request/Entropy.java) URL: http://svn.apache.org/viewvc/cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/request/BinarySecret.java?p2=cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/request/BinarySecret.java&p1=cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/request/Entropy.java&r1=1298624&r2=1298801&rev=1298801&view=diff ============================================================================== --- cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/request/Entropy.java (original) +++ cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/request/BinarySecret.java Fri Mar 9 12:11:34 2012 @@ -19,9 +19,9 @@ package org.apache.cxf.sts.request; /** - * This class contains values that have been extracted from an Entropy structure. + * This class contains values that have been extracted from a BinarySecret structure. */ -public class Entropy { +public class BinarySecret { private byte[] binarySecretValue; private String binarySecretType; Modified: cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/request/Entropy.java URL: http://svn.apache.org/viewvc/cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/request/Entropy.java?rev=1298801&r1=1298800&r2=1298801&view=diff ============================================================================== --- cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/request/Entropy.java (original) +++ cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/request/Entropy.java Fri Mar 9 12:11:34 2012 @@ -22,23 +22,23 @@ package org.apache.cxf.sts.request; * This class contains values that have been extracted from an Entropy structure. */ public class Entropy { - private byte[] binarySecretValue; - private String binarySecretType; + private byte[] decryptedKey; + private BinarySecret binarySecret; - public byte[] getBinarySecretValue() { - return binarySecretValue; + public BinarySecret getBinarySecret() { + return binarySecret; } - public void setBinarySecretValue(byte[] binarySecretValue) { - this.binarySecretValue = binarySecretValue; + public void setBinarySecret(BinarySecret binarySecret) { + this.binarySecret = binarySecret; } - public String getBinarySecretType() { - return binarySecretType; + public void setDecryptedKey(byte[] decryptedKey) { + this.decryptedKey = decryptedKey; } - public void setBinarySecretType(String binarySecretType) { - this.binarySecretType = binarySecretType; + public byte[] getDecryptedKey() { + return decryptedKey; } } \ No newline at end of file Modified: cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/request/RequestParser.java URL: http://svn.apache.org/viewvc/cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/request/RequestParser.java?rev=1298801&r1=1298800&r2=1298801&view=diff ============================================================================== --- cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/request/RequestParser.java (original) +++ cxf/trunk/services/sts/sts-core/src/main/java/org/apache/cxf/sts/request/RequestParser.java Fri Mar 9 12:11:34 2012 @@ -51,6 +51,7 @@ import org.apache.cxf.helpers.CastUtils; import org.apache.cxf.helpers.DOMUtils; import org.apache.cxf.sts.QNameConstants; import org.apache.cxf.sts.STSConstants; +import org.apache.cxf.sts.STSPropertiesMBean; import org.apache.cxf.sts.claims.RequestClaim; import org.apache.cxf.sts.claims.RequestClaimCollection; import org.apache.cxf.ws.security.sts.provider.STSException; @@ -69,10 +70,15 @@ import org.apache.cxf.ws.security.sts.pr import org.apache.cxf.ws.security.sts.provider.model.xmldsig.KeyInfoType; import org.apache.cxf.ws.security.sts.provider.model.xmldsig.X509DataType; import org.apache.ws.security.WSConstants; +import org.apache.ws.security.WSDocInfo; +import org.apache.ws.security.WSSConfig; import org.apache.ws.security.WSSecurityEngineResult; +import org.apache.ws.security.WSSecurityException; +import org.apache.ws.security.handler.RequestData; import org.apache.ws.security.handler.WSHandlerConstants; import org.apache.ws.security.handler.WSHandlerResult; import org.apache.ws.security.message.token.SecurityContextToken; +import org.apache.ws.security.processor.EncryptedKeyProcessor; import org.apache.xml.security.utils.Constants; /** @@ -87,7 +93,7 @@ public class RequestParser { private TokenRequirements tokenRequirements = new TokenRequirements(); public void parseRequest( - RequestSecurityTokenType request, WebServiceContext wsContext + RequestSecurityTokenType request, WebServiceContext wsContext, STSPropertiesMBean stsProperties ) throws STSException { LOG.fine("Parsing RequestSecurityToken"); keyRequirements = new KeyRequirements(); @@ -99,7 +105,7 @@ public class RequestParser { JAXBElement jaxbElement = (JAXBElement) requestObject; boolean found = parseTokenRequirements(jaxbElement, tokenRequirements, wsContext); if (!found) { - found = parseKeyRequirements(jaxbElement, keyRequirements, wsContext); + found = parseKeyRequirements(jaxbElement, keyRequirements, wsContext, stsProperties); } if (!found) { LOG.log(Level.WARNING, "Found a JAXB object of unknown type: " + jaxbElement.getName()); @@ -151,7 +157,8 @@ public class RequestParser { * Parse the Key and Encryption requirements into the KeyRequirements argument. */ private static boolean parseKeyRequirements( - JAXBElement jaxbElement, KeyRequirements keyRequirements, WebServiceContext wsContext + JAXBElement jaxbElement, KeyRequirements keyRequirements, + WebServiceContext wsContext, STSPropertiesMBean stsProperties ) { if (QNameConstants.AUTHENTICATION_TYPE.equals(jaxbElement.getName())) { String authenticationType = (String)jaxbElement.getValue(); @@ -191,7 +198,7 @@ public class RequestParser { keyRequirements.setReceivedKey(receivedKey); } else if (QNameConstants.ENTROPY.equals(jaxbElement.getName())) { EntropyType entropyType = (EntropyType)jaxbElement.getValue(); - Entropy entropy = parseEntropy(entropyType); + Entropy entropy = parseEntropy(entropyType, stsProperties); keyRequirements.setEntropy(entropy); } else if (QNameConstants.REQUEST_TYPE.equals(jaxbElement.getName())) { //NOPMD // Skip the request type. @@ -421,22 +428,53 @@ public class RequestParser { /** * Parse an Entropy object * @param entropy an Entropy object + * @param stsProperties A STSPropertiesMBean object used to decrypt an EncryptedKey */ - private static Entropy parseEntropy(EntropyType entropyType) { + private static Entropy parseEntropy( + EntropyType entropyType, STSPropertiesMBean stsProperties + ) throws STSException { for (Object entropyObject : entropyType.getAny()) { - JAXBElement entropyObjectJaxb = (JAXBElement) entropyObject; - if (QNameConstants.BINARY_SECRET.equals(entropyObjectJaxb.getName())) { - BinarySecretType binarySecret = - (BinarySecretType)entropyObjectJaxb.getValue(); - LOG.fine("Found BinarySecret Entropy type"); - Entropy entropy = new Entropy(); - entropy.setBinarySecretType(binarySecret.getType()); - entropy.setBinarySecretValue(binarySecret.getValue()); - return entropy; + if (entropyObject instanceof JAXBElement) { + JAXBElement entropyObjectJaxb = (JAXBElement) entropyObject; + if (QNameConstants.BINARY_SECRET.equals(entropyObjectJaxb.getName())) { + BinarySecretType binarySecretType = + (BinarySecretType)entropyObjectJaxb.getValue(); + LOG.fine("Found BinarySecret Entropy type"); + Entropy entropy = new Entropy(); + BinarySecret binarySecret = new BinarySecret(); + binarySecret.setBinarySecretType(binarySecretType.getType()); + binarySecret.setBinarySecretValue(binarySecretType.getValue()); + entropy.setBinarySecret(binarySecret); + return entropy; + } else { + LOG.fine("Unsupported Entropy type: " + entropyObjectJaxb.getName()); + } + } else if (entropyObject instanceof Element + && "EncryptedKey".equals(((Element)entropyObject).getLocalName())) { + EncryptedKeyProcessor processor = new EncryptedKeyProcessor(); + Element entropyElement = (Element)entropyObject; + RequestData requestData = new RequestData(); + requestData.setDecCrypto(stsProperties.getSignatureCrypto()); + requestData.setCallbackHandler(stsProperties.getCallbackHandler()); + requestData.setWssConfig(WSSConfig.getNewInstance()); + try { + List results = + processor.handleToken( + entropyElement, requestData, new WSDocInfo(entropyElement.getOwnerDocument()) + ); + Entropy entropy = new Entropy(); + entropy.setDecryptedKey((byte[])results.get(0).get(WSSecurityEngineResult.TAG_SECRET)); + return entropy; + } catch (WSSecurityException e) { + LOG.log(Level.WARNING, "", e); + throw new STSException(e.getMessage(), e, STSException.INVALID_REQUEST); + } } else { - LOG.fine("Unsupported Entropy type: " + entropyObjectJaxb.getName()); + LOG.log(Level.WARNING, "An unknown element was received"); + throw new STSException( + "An unknown element was received", STSException.BAD_REQUEST + ); } - // TODO support EncryptedKey } return null; } 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=1298801&r1=1298800&r2=1298801&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 Fri Mar 9 12:11:34 2012 @@ -26,6 +26,7 @@ import org.apache.cxf.common.logging.Log import org.apache.cxf.sts.STSConstants; import org.apache.cxf.sts.STSPropertiesMBean; import org.apache.cxf.sts.SignatureProperties; +import org.apache.cxf.sts.request.BinarySecret; import org.apache.cxf.sts.request.Entropy; import org.apache.cxf.sts.request.KeyRequirements; import org.apache.cxf.ws.security.sts.provider.STSException; @@ -68,25 +69,46 @@ public class SymmetricKeyHandler { clientEntropy = keyRequirements.getEntropy(); if (clientEntropy == null) { LOG.log(Level.WARNING, "A SymmetricKey KeyType is requested, but no client entropy is provided"); - } else if (STSConstants.NONCE_TYPE.equals(clientEntropy.getBinarySecretType())) { - byte[] nonce = clientEntropy.getBinarySecretValue(); - if (nonce == null || (nonce.length < (keySize / 8))) { - LOG.log(Level.WARNING, "User Entropy rejected"); - clientEntropy = null; - } - String computedKeyAlgorithm = keyRequirements.getComputedKeyAlgorithm(); - if (!STSConstants.COMPUTED_KEY_PSHA1.equals(computedKeyAlgorithm)) { + } else if (clientEntropy.getBinarySecret() != null) { + BinarySecret binarySecret = clientEntropy.getBinarySecret(); + if (STSConstants.NONCE_TYPE.equals(binarySecret.getBinarySecretType())) { + byte[] nonce = binarySecret.getBinarySecretValue(); + if (nonce == null || (nonce.length < (keySize / 8))) { + LOG.log(Level.WARNING, "User Entropy rejected"); + clientEntropy = null; + } + String computedKeyAlgorithm = keyRequirements.getComputedKeyAlgorithm(); + if (!STSConstants.COMPUTED_KEY_PSHA1.equals(computedKeyAlgorithm)) { + LOG.log( + Level.WARNING, + "The computed key algorithm of " + computedKeyAlgorithm + " is not supported" + ); + throw new STSException( + "Computed Key Algorithm not supported", STSException.INVALID_REQUEST + ); + } + } else if (STSConstants.SYMMETRIC_KEY_TYPE.equals(binarySecret.getBinarySecretType()) + || binarySecret.getBinarySecretType() == null) { + byte[] secretValue = binarySecret.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 computed key algorithm of " + computedKeyAlgorithm + " is not supported" + Level.WARNING, "The type " + binarySecret.getBinarySecretType() + " is not supported" ); throw new STSException( - "Computed Key Algorithm not supported", STSException.INVALID_REQUEST + "No user supplied entropy for SymmetricKey case", STSException.INVALID_REQUEST ); } - } else if (STSConstants.SYMMETRIC_KEY_TYPE.equals(clientEntropy.getBinarySecretType()) - || clientEntropy.getBinarySecretType() == null) { - byte[] secretValue = clientEntropy.getBinarySecretValue(); + } else if (clientEntropy.getDecryptedKey() != null) { + byte[] secretValue = clientEntropy.getDecryptedKey(); if ((secretValue.length * 8) < signatureProperties.getMinimumKeySize() || (secretValue.length * 8) > signatureProperties.getMaximumKeySize()) { LOG.log( @@ -97,9 +119,9 @@ public class SymmetricKeyHandler { clientEntropy = null; } } else { - LOG.log(Level.WARNING, "The type " + clientEntropy.getBinarySecretType() + " is not supported"); + LOG.log(Level.WARNING, "The user supplied Entropy structure is invalid"); throw new STSException( - "No user supplied entropy for SymmetricKey case", STSException.INVALID_REQUEST + "The user supplied Entropy structure is invalid", STSException.INVALID_REQUEST ); } } @@ -108,22 +130,32 @@ public class SymmetricKeyHandler { * Create the Symmetric Key */ public void createSymmetricKey() { - if (clientEntropy != null - && (STSConstants.SYMMETRIC_KEY_TYPE.equals(clientEntropy.getBinarySecretType()) - || clientEntropy.getBinarySecretType() == null)) { - secret = clientEntropy.getBinarySecretValue(); - computedKey = false; - } else { + computedKey = false; + boolean generateEntropy = true; + + if (clientEntropy != null) { + BinarySecret binarySecret = clientEntropy.getBinarySecret(); + if (binarySecret != null + && (STSConstants.SYMMETRIC_KEY_TYPE.equals(binarySecret.getBinarySecretType()) + || binarySecret.getBinarySecretType() == null)) { + secret = binarySecret.getBinarySecretValue(); + generateEntropy = false; + } else if (clientEntropy.getDecryptedKey() != null) { + secret = clientEntropy.getDecryptedKey(); + generateEntropy = false; + } + } + + if (generateEntropy) { try { 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", ex, STSException.INVALID_REQUEST); - } - if (clientEntropy != null) { - byte[] nonce = clientEntropy.getBinarySecretValue(); + } + if (clientEntropy != null && clientEntropy.getBinarySecret() != null) { + byte[] nonce = clientEntropy.getBinarySecret().getBinarySecretValue(); try { P_SHA1 psha1 = new P_SHA1(); secret = psha1.createKey(nonce, entropyBytes, 0, keySize / 8); Modified: cxf/trunk/services/sts/sts-core/src/test/java/org/apache/cxf/sts/common/PasswordCallbackHandler.java URL: http://svn.apache.org/viewvc/cxf/trunk/services/sts/sts-core/src/test/java/org/apache/cxf/sts/common/PasswordCallbackHandler.java?rev=1298801&r1=1298800&r2=1298801&view=diff ============================================================================== --- cxf/trunk/services/sts/sts-core/src/test/java/org/apache/cxf/sts/common/PasswordCallbackHandler.java (original) +++ cxf/trunk/services/sts/sts-core/src/test/java/org/apache/cxf/sts/common/PasswordCallbackHandler.java Fri Mar 9 12:11:34 2012 @@ -40,6 +40,9 @@ public class PasswordCallbackHandler imp } else if ("mystskey".equals(pc.getIdentifier())) { pc.setPassword("stskpass"); break; + } else if ("myservicekey".equals(pc.getIdentifier())) { + pc.setPassword("skpass"); + break; } } } 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=1298801&r1=1298800&r2=1298801&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 Fri Mar 9 12:11:34 2012 @@ -21,6 +21,7 @@ package org.apache.cxf.sts.operation; import java.security.Principal; import java.security.cert.X509Certificate; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Properties; @@ -59,9 +60,15 @@ import org.apache.cxf.ws.security.sts.pr import org.apache.cxf.ws.security.sts.provider.model.UseKeyType; import org.apache.ws.security.CustomTokenPrincipal; import org.apache.ws.security.WSConstants; +import org.apache.ws.security.WSDocInfo; +import org.apache.ws.security.WSSConfig; import org.apache.ws.security.components.crypto.Crypto; import org.apache.ws.security.components.crypto.CryptoFactory; import org.apache.ws.security.components.crypto.CryptoType; +import org.apache.ws.security.handler.RequestData; +import org.apache.ws.security.message.WSSecEncryptedKey; +import org.apache.ws.security.saml.SAMLKeyInfo; +import org.apache.ws.security.saml.ext.AssertionWrapper; import org.apache.ws.security.saml.ext.builder.SAML1Constants; import org.apache.ws.security.saml.ext.builder.SAML2Constants; import org.apache.ws.security.util.Base64; @@ -588,6 +595,119 @@ public class IssueSamlUnitTest extends o assertTrue(tokenString.contains(SAML2Constants.CONF_HOLDER_KEY)); } + /** + * 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 in an EncryptedKey structure. + */ + @org.junit.Test + public void testIssueSaml2SymmetricKeyTokenEncryptedKey() 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 + WSSecEncryptedKey builder = new WSSecEncryptedKey(); + builder.setUserInfo("mystskey"); + builder.setKeyIdentifierType(WSConstants.ISSUER_SERIAL); + builder.setKeyEncAlgo(WSConstants.KEYTRANSPORT_RSAOEP); + + Document doc = DOMUtils.createDocument(); + builder.prepare(doc, stsProperties.getSignatureCrypto()); + Element encryptedKeyElement = builder.getEncryptedKeyElement(); + byte[] secret = builder.getEphemeralKey(); + + EntropyType entropyType = new EntropyType(); + entropyType.getAny().add(encryptedKeyElement); + 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 that the (encrypted) secret sent in Entropy was used in the SAML Subject KeyInfo + AssertionWrapper assertionWrapper = new AssertionWrapper(assertion); + RequestData data = new RequestData(); + + Properties properties = new Properties(); + properties.put( + "org.apache.ws.security.crypto.provider", "org.apache.ws.security.components.crypto.Merlin" + ); + properties.put("org.apache.ws.security.crypto.merlin.keystore.password", "sspass"); + properties.put("org.apache.ws.security.crypto.merlin.keystore.file", "servicestore.jks"); + + data.setDecCrypto(CryptoFactory.getInstance(properties)); + data.setCallbackHandler(new PasswordCallbackHandler()); + data.setWssConfig(WSSConfig.getNewInstance()); + + assertionWrapper.parseHOKSubject(data, new WSDocInfo(assertion.getOwnerDocument())); + SAMLKeyInfo samlKeyInfo = assertionWrapper.getSubjectKeyInfo(); + assertTrue(Arrays.equals(secret, samlKeyInfo.getSecret())); + } + /** * Test to successfully issue a Saml 1.1 token with no References Modified: cxf/trunk/services/sts/sts-core/src/test/java/org/apache/cxf/sts/request/RequestParserUnitTest.java URL: http://svn.apache.org/viewvc/cxf/trunk/services/sts/sts-core/src/test/java/org/apache/cxf/sts/request/RequestParserUnitTest.java?rev=1298801&r1=1298800&r2=1298801&view=diff ============================================================================== --- cxf/trunk/services/sts/sts-core/src/test/java/org/apache/cxf/sts/request/RequestParserUnitTest.java (original) +++ cxf/trunk/services/sts/sts-core/src/test/java/org/apache/cxf/sts/request/RequestParserUnitTest.java Fri Mar 9 12:11:34 2012 @@ -147,7 +147,7 @@ public class RequestParserUnitTest exten resultsList.add(new WSHandlerResult("actor", engineResultList)); msgContext.put(WSHandlerConstants.RECV_RESULTS, resultsList); - parser.parseRequest(request, wsContext); + parser.parseRequest(request, wsContext, null); SCTCanceller sctCanceller = new SCTCanceller(); assertTrue(sctCanceller.canHandleToken(parser.getTokenRequirements().getCancelTarget())); @@ -178,7 +178,7 @@ public class RequestParserUnitTest exten resultsList.add(new WSHandlerResult("actor", engineResultList)); msgContext.put(WSHandlerConstants.RECV_RESULTS, resultsList); - parser.parseRequest(request, wsContext); + parser.parseRequest(request, wsContext, null); SCTValidator sctValidator = new SCTValidator(); assertTrue(sctValidator.canHandleToken(parser.getTokenRequirements().getValidateTarget())); @@ -210,7 +210,7 @@ public class RequestParserUnitTest exten resultsList.add(new WSHandlerResult("actor", engineResultList)); msgContext.put(WSHandlerConstants.RECV_RESULTS, resultsList); - parser.parseRequest(request, wsContext); + parser.parseRequest(request, wsContext, null); assertNotNull(parser.getKeyRequirements().getReceivedKey().getX509Cert()); } 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=1298801&r1=1298800&r2=1298801&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 Fri Mar 9 12:11:34 2012 @@ -33,6 +33,7 @@ import org.apache.cxf.sts.STSPropertiesM import org.apache.cxf.sts.SignatureProperties; import org.apache.cxf.sts.StaticSTSProperties; import org.apache.cxf.sts.common.PasswordCallbackHandler; +import org.apache.cxf.sts.request.BinarySecret; import org.apache.cxf.sts.request.Entropy; import org.apache.cxf.sts.request.KeyRequirements; import org.apache.cxf.sts.request.ReceivedKey; @@ -193,10 +194,12 @@ public class SAMLProviderKeyTypeTest ext assertTrue(samlTokenProvider.canHandleToken(WSConstants.WSS_SAML_TOKEN_TYPE)); Entropy entropy = new Entropy(); - entropy.setBinarySecretValue(WSSecurityUtil.generateNonce(256 / 8)); + BinarySecret binarySecret = new BinarySecret(); + binarySecret.setBinarySecretValue(WSSecurityUtil.generateNonce(256 / 8)); + entropy.setBinarySecret(binarySecret); providerParameters.getKeyRequirements().setEntropy(entropy); - entropy.setBinarySecretType("bad-type"); + binarySecret.setBinarySecretType("bad-type"); try { samlTokenProvider.createToken(providerParameters); fail("Failure expected on a bad type"); @@ -204,7 +207,7 @@ public class SAMLProviderKeyTypeTest ext // expected as no type is provided } - entropy.setBinarySecretType(STSConstants.NONCE_TYPE); + binarySecret.setBinarySecretType(STSConstants.NONCE_TYPE); try { samlTokenProvider.createToken(providerParameters); fail("Failure expected on no computed key algorithm"); @@ -256,7 +259,9 @@ public class SAMLProviderKeyTypeTest ext assertTrue(samlTokenProvider.canHandleToken(WSConstants.WSS_SAML_TOKEN_TYPE)); Entropy entropy = new Entropy(); - entropy.setBinarySecretValue(WSSecurityUtil.generateNonce(256 / 8)); + BinarySecret binarySecret = new BinarySecret(); + binarySecret.setBinarySecretValue(WSSecurityUtil.generateNonce(256 / 8)); + entropy.setBinarySecret(binarySecret); providerParameters.getKeyRequirements().setEntropy(entropy); TokenProviderResponse providerResponse = samlTokenProvider.createToken(providerParameters); @@ -288,10 +293,12 @@ public class SAMLProviderKeyTypeTest ext assertTrue(samlTokenProvider.canHandleToken(WSConstants.WSS_SAML2_TOKEN_TYPE)); Entropy entropy = new Entropy(); - entropy.setBinarySecretValue(WSSecurityUtil.generateNonce(256 / 8)); + BinarySecret binarySecret = new BinarySecret(); + binarySecret.setBinarySecretValue(WSSecurityUtil.generateNonce(256 / 8)); + entropy.setBinarySecret(binarySecret); providerParameters.getKeyRequirements().setEntropy(entropy); - entropy.setBinarySecretType("bad-type"); + binarySecret.setBinarySecretType("bad-type"); try { samlTokenProvider.createToken(providerParameters); fail("Failure expected on a bad type"); @@ -299,7 +306,7 @@ public class SAMLProviderKeyTypeTest ext // expected as no type is provided } - entropy.setBinarySecretType(STSConstants.NONCE_TYPE); + binarySecret.setBinarySecretType(STSConstants.NONCE_TYPE); try { samlTokenProvider.createToken(providerParameters); fail("Failure expected on no computed key algorithm"); Added: cxf/trunk/services/sts/sts-core/src/test/resources/servicestore.jks URL: http://svn.apache.org/viewvc/cxf/trunk/services/sts/sts-core/src/test/resources/servicestore.jks?rev=1298801&view=auto ============================================================================== Files cxf/trunk/services/sts/sts-core/src/test/resources/servicestore.jks (added) and cxf/trunk/services/sts/sts-core/src/test/resources/servicestore.jks Fri Mar 9 12:11:34 2012 differ