Author: dkulp Date: Wed Feb 13 17:09:25 2013 New Revision: 1445748 URL: http://svn.apache.org/r1445748 Log: Merged revisions 1445728 via git cherry-pick from https://svn.apache.org/repos/asf/cxf/branches/2.6.x-fixes
........ r1445728 | dkulp | 2013-02-13 11:48:33 -0500 (Wed, 13 Feb 2013) | 18 lines Merged revisions 1445370 via git cherry-pick from https://svn.apache.org/repos/asf/cxf/branches/2.7.x-fixes ........ r1445370 | dkulp | 2013-02-12 16:15:31 -0500 (Tue, 12 Feb 2013) | 10 lines Merged revisions 1442923 via git cherry-pick from https://svn.apache.org/repos/asf/cxf/trunk ........ r1442923 | coheigea | 2013-02-06 07:16:40 -0500 (Wed, 06 Feb 2013) | 2 lines [CXF-4814] - Support multiple AlgorithmSuite policy alternatives ........ ........ ........ Added: cxf/branches/2.5.x-fixes/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/AlgorithmSuiteTranslater.java cxf/branches/2.5.x-fixes/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyvalidators/AlgorithmSuitePolicyValidator.java Modified: cxf/branches/2.5.x-fixes/pom.xml cxf/branches/2.5.x-fixes/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/PolicyBasedWSS4JInInterceptor.java cxf/branches/2.5.x-fixes/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyvalidators/AbstractBindingPolicyValidator.java cxf/branches/2.5.x-fixes/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyvalidators/TransportBindingPolicyValidator.java cxf/branches/2.5.x-fixes/systests/ws-security/src/test/java/org/apache/cxf/systest/ws/algsuite/AlgorithmSuiteTest.java cxf/branches/2.5.x-fixes/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/algsuite/DoubleItAlgSuite.wsdl cxf/branches/2.5.x-fixes/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/algsuite/client/client.xml cxf/branches/2.5.x-fixes/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/algsuite/server/server.xml Modified: cxf/branches/2.5.x-fixes/pom.xml URL: http://svn.apache.org/viewvc/cxf/branches/2.5.x-fixes/pom.xml?rev=1445748&r1=1445747&r2=1445748&view=diff ============================================================================== --- cxf/branches/2.5.x-fixes/pom.xml (original) +++ cxf/branches/2.5.x-fixes/pom.xml Wed Feb 13 17:09:25 2013 @@ -549,7 +549,7 @@ <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-source-plugin</artifactId> - <version>2.2</version> + <version>2.2.1</version> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> Added: cxf/branches/2.5.x-fixes/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/AlgorithmSuiteTranslater.java URL: http://svn.apache.org/viewvc/cxf/branches/2.5.x-fixes/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/AlgorithmSuiteTranslater.java?rev=1445748&view=auto ============================================================================== --- cxf/branches/2.5.x-fixes/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/AlgorithmSuiteTranslater.java (added) +++ cxf/branches/2.5.x-fixes/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/AlgorithmSuiteTranslater.java Wed Feb 13 17:09:25 2013 @@ -0,0 +1,183 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.cxf.ws.security.wss4j; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import org.apache.cxf.ws.policy.AssertionInfo; +import org.apache.cxf.ws.policy.AssertionInfoMap; +import org.apache.cxf.ws.security.policy.SP12Constants; +import org.apache.cxf.ws.security.policy.SPConstants; +import org.apache.cxf.ws.security.policy.model.Binding; +import org.apache.cxf.ws.security.policy.model.SamlToken; +import org.apache.cxf.ws.security.policy.model.SupportingToken; +import org.apache.ws.security.WSConstants; +import org.apache.ws.security.WSSecurityException; +import org.apache.ws.security.components.crypto.AlgorithmSuite; +import org.apache.ws.security.handler.RequestData; + +/** + * Translate any AlgorithmSuite policy that may be operative into a WSS4J AlgorithmSuite object + * to enforce what algorithms are allowed in a request. + */ +public final class AlgorithmSuiteTranslater { + + public void translateAlgorithmSuites(AssertionInfoMap aim, RequestData data) throws WSSecurityException { + if (aim == null) { + return; + } + + List<org.apache.cxf.ws.security.policy.model.AlgorithmSuite> algorithmSuites = + getAlgorithmSuites(getBindings(aim)); + if (!algorithmSuites.isEmpty()) { + // Translate into WSS4J's AlgorithmSuite class + AlgorithmSuite algorithmSuite = translateAlgorithmSuites(algorithmSuites); + data.setAlgorithmSuite(algorithmSuite); + } + + // Now look for an AlgorithmSuite for a SAML Assertion + Collection<AssertionInfo> ais = aim.get(SP12Constants.SAML_TOKEN); + if (ais != null && !ais.isEmpty()) { + List<org.apache.cxf.ws.security.policy.model.AlgorithmSuite> samlAlgorithmSuites + = new ArrayList<org.apache.cxf.ws.security.policy.model.AlgorithmSuite>(); + for (AssertionInfo ai : ais) { + SamlToken samlToken = (SamlToken)ai.getAssertion(); + SupportingToken supportingToken = samlToken.getSupportingToken(); + if (supportingToken != null && supportingToken.getAlgorithmSuite() != null) { + samlAlgorithmSuites.add(supportingToken.getAlgorithmSuite()); + } + } + + if (!samlAlgorithmSuites.isEmpty()) { + data.setSamlAlgorithmSuite(translateAlgorithmSuites(samlAlgorithmSuites)); + } + } + } + + /** + * Translate a list of CXF AlgorithmSuite objects into a single WSS4J AlgorithmSuite object + */ + private AlgorithmSuite translateAlgorithmSuites( + List<org.apache.cxf.ws.security.policy.model.AlgorithmSuite> algorithmSuites + ) { + AlgorithmSuite algorithmSuite = null; + + for (org.apache.cxf.ws.security.policy.model.AlgorithmSuite cxfAlgorithmSuite + : algorithmSuites) { + if (cxfAlgorithmSuite == null) { + continue; + } + + // Translate into WSS4J's AlgorithmSuite class + if (algorithmSuite == null) { + algorithmSuite = new AlgorithmSuite(); + } + + // Set asymmetric key lengths + if (algorithmSuite.getMaximumAsymmetricKeyLength() + < cxfAlgorithmSuite.getMaximumAsymmetricKeyLength()) { + algorithmSuite.setMaximumAsymmetricKeyLength( + cxfAlgorithmSuite.getMaximumAsymmetricKeyLength()); + } + if (algorithmSuite.getMinimumAsymmetricKeyLength() + > cxfAlgorithmSuite.getMinimumAsymmetricKeyLength()) { + algorithmSuite.setMinimumAsymmetricKeyLength( + cxfAlgorithmSuite.getMinimumAsymmetricKeyLength()); + } + + // Set symmetric key lengths + if (algorithmSuite.getMaximumSymmetricKeyLength() + < cxfAlgorithmSuite.getMaximumSymmetricKeyLength()) { + algorithmSuite.setMaximumSymmetricKeyLength( + cxfAlgorithmSuite.getMaximumSymmetricKeyLength()); + } + if (algorithmSuite.getMinimumSymmetricKeyLength() + > cxfAlgorithmSuite.getMinimumSymmetricKeyLength()) { + algorithmSuite.setMinimumSymmetricKeyLength( + cxfAlgorithmSuite.getMinimumSymmetricKeyLength()); + } + + algorithmSuite.addEncryptionMethod(cxfAlgorithmSuite.getEncryption()); + algorithmSuite.addKeyWrapAlgorithm(cxfAlgorithmSuite.getSymmetricKeyWrap()); + algorithmSuite.addKeyWrapAlgorithm(cxfAlgorithmSuite.getAsymmetricKeyWrap()); + + algorithmSuite.addSignatureMethod(cxfAlgorithmSuite.getAsymmetricSignature()); + algorithmSuite.addSignatureMethod(cxfAlgorithmSuite.getSymmetricSignature()); + algorithmSuite.addDigestAlgorithm(cxfAlgorithmSuite.getDigest()); + algorithmSuite.addC14nAlgorithm(cxfAlgorithmSuite.getInclusiveC14n()); + + algorithmSuite.addTransformAlgorithm(cxfAlgorithmSuite.getInclusiveC14n()); + algorithmSuite.addTransformAlgorithm(SPConstants.STRT10); + algorithmSuite.addTransformAlgorithm(WSConstants.NS_XMLDSIG_ENVELOPED_SIGNATURE); + + algorithmSuite.addDerivedKeyAlgorithm(SPConstants.P_SHA1); + algorithmSuite.addDerivedKeyAlgorithm(SPConstants.P_SHA1_L128); + } + + return algorithmSuite; + } + + /** + * Get all of the WS-SecurityPolicy Bindings that are in operation + */ + private List<Binding> getBindings(AssertionInfoMap aim) { + List<Binding> bindings = new ArrayList<Binding>(); + if (aim != null) { + Collection<AssertionInfo> ais = aim.get(SP12Constants.TRANSPORT_BINDING); + if (ais != null && !ais.isEmpty()) { + for (AssertionInfo ai : ais) { + bindings.add((Binding)ai.getAssertion()); + } + } + ais = aim.get(SP12Constants.ASYMMETRIC_BINDING); + if (ais != null && !ais.isEmpty()) { + for (AssertionInfo ai : ais) { + bindings.add((Binding)ai.getAssertion()); + } + } + ais = aim.get(SP12Constants.SYMMETRIC_BINDING); + if (ais != null && !ais.isEmpty()) { + for (AssertionInfo ai : ais) { + bindings.add((Binding)ai.getAssertion()); + } + } + } + return bindings; + } + + /** + * Get all of the CXF AlgorithmSuites from the bindings + */ + private List<org.apache.cxf.ws.security.policy.model.AlgorithmSuite> getAlgorithmSuites( + List<Binding> bindings + ) { + List<org.apache.cxf.ws.security.policy.model.AlgorithmSuite> algorithmSuites = + new ArrayList<org.apache.cxf.ws.security.policy.model.AlgorithmSuite>(); + for (Binding binding : bindings) { + if (binding.getAlgorithmSuite() != null) { + algorithmSuites.add(binding.getAlgorithmSuite()); + } + } + return algorithmSuites; + } + +} Modified: cxf/branches/2.5.x-fixes/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/PolicyBasedWSS4JInInterceptor.java URL: http://svn.apache.org/viewvc/cxf/branches/2.5.x-fixes/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/PolicyBasedWSS4JInInterceptor.java?rev=1445748&r1=1445747&r2=1445748&view=diff ============================================================================== --- cxf/branches/2.5.x-fixes/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/PolicyBasedWSS4JInInterceptor.java (original) +++ cxf/branches/2.5.x-fixes/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/PolicyBasedWSS4JInInterceptor.java Wed Feb 13 17:09:25 2013 @@ -58,17 +58,12 @@ import org.apache.cxf.ws.policy.Assertio import org.apache.cxf.ws.security.SecurityConstants; import org.apache.cxf.ws.security.policy.SP11Constants; import org.apache.cxf.ws.security.policy.SP12Constants; -import org.apache.cxf.ws.security.policy.SPConstants; -import org.apache.cxf.ws.security.policy.model.Binding; import org.apache.cxf.ws.security.policy.model.ContentEncryptedElements; import org.apache.cxf.ws.security.policy.model.Header; import org.apache.cxf.ws.security.policy.model.RequiredElements; import org.apache.cxf.ws.security.policy.model.RequiredParts; -import org.apache.cxf.ws.security.policy.model.SamlToken; import org.apache.cxf.ws.security.policy.model.SignedEncryptedElements; import org.apache.cxf.ws.security.policy.model.SignedEncryptedParts; -import org.apache.cxf.ws.security.policy.model.SupportingToken; -import org.apache.cxf.ws.security.policy.model.UsernameToken; import org.apache.cxf.ws.security.policy.model.Wss11; import org.apache.cxf.ws.security.wss4j.CryptoCoverageUtil.CoverageScope; import org.apache.cxf.ws.security.wss4j.CryptoCoverageUtil.CoverageType; @@ -95,7 +90,6 @@ import org.apache.ws.security.WSConstant import org.apache.ws.security.WSDataRef; import org.apache.ws.security.WSSecurityEngineResult; import org.apache.ws.security.WSSecurityException; -import org.apache.ws.security.components.crypto.AlgorithmSuite; import org.apache.ws.security.components.crypto.Crypto; import org.apache.ws.security.components.crypto.CryptoFactory; import org.apache.ws.security.handler.RequestData; @@ -494,97 +488,10 @@ public class PolicyBasedWSS4JInIntercept * algorithms that are allowed for encryption, signature, etc. */ protected void setAlgorithmSuites(SoapMessage message, RequestData data) throws WSSecurityException { - Binding binding = getBinding(message); - if (binding != null && binding.getAlgorithmSuite() != null) { - // Translate into WSS4J's AlgorithmSuite class - AlgorithmSuite algorithmSuite = translateAlgorithmSuite(binding.getAlgorithmSuite()); - data.setAlgorithmSuite(algorithmSuite); - } - - // Now look for an AlgorithmSuite for a SAML Assertion - AssertionInfoMap aim = message.get(AssertionInfoMap.class); - if (aim != null) { - Collection<AssertionInfo> ais = aim.get(SP12Constants.SAML_TOKEN); - if (ais != null && !ais.isEmpty()) { - for (AssertionInfo ai : ais) { - SamlToken samlToken = (SamlToken)ai.getAssertion(); - SupportingToken supportingToken = samlToken.getSupportingToken(); - if (supportingToken != null && supportingToken.getAlgorithmSuite() != null) { - AlgorithmSuite algorithmSuite = - translateAlgorithmSuite(supportingToken.getAlgorithmSuite()); - data.setSamlAlgorithmSuite(algorithmSuite); - break; - } - } - } - } - } - - /** - * Translate a CXF AlgorithmSuite object into WSS4J's AlgorithmSuite object - */ - private AlgorithmSuite translateAlgorithmSuite( - org.apache.cxf.ws.security.policy.model.AlgorithmSuite cxfAlgorithmSuite - ) { - // Translate into WSS4J's AlgorithmSuite class - AlgorithmSuite algorithmSuite = new AlgorithmSuite(); - algorithmSuite.setEncryptionDerivedKeyLength( - cxfAlgorithmSuite.getEncryptionDerivedKeyLength()); - algorithmSuite.setSignatureDerivedKeyLength( - cxfAlgorithmSuite.getSignatureDerivedKeyLength()); - algorithmSuite.setMaximumAsymmetricKeyLength( - cxfAlgorithmSuite.getMaximumAsymmetricKeyLength()); - algorithmSuite.setMinimumAsymmetricKeyLength( - cxfAlgorithmSuite.getMinimumAsymmetricKeyLength()); - algorithmSuite.setMaximumSymmetricKeyLength( - cxfAlgorithmSuite.getMaximumSymmetricKeyLength()); - algorithmSuite.setMinimumSymmetricKeyLength( - cxfAlgorithmSuite.getMinimumSymmetricKeyLength()); - - algorithmSuite.addEncryptionMethod(cxfAlgorithmSuite.getEncryption()); - algorithmSuite.addKeyWrapAlgorithm(cxfAlgorithmSuite.getSymmetricKeyWrap()); - algorithmSuite.addKeyWrapAlgorithm(cxfAlgorithmSuite.getAsymmetricKeyWrap()); - - algorithmSuite.addSignatureMethod(cxfAlgorithmSuite.getAsymmetricSignature()); - algorithmSuite.addSignatureMethod(cxfAlgorithmSuite.getSymmetricSignature()); - algorithmSuite.addDigestAlgorithm(cxfAlgorithmSuite.getDigest()); - algorithmSuite.addC14nAlgorithm(cxfAlgorithmSuite.getInclusiveC14n()); - - algorithmSuite.addTransformAlgorithm(cxfAlgorithmSuite.getInclusiveC14n()); - algorithmSuite.addTransformAlgorithm(SPConstants.STRT10); - algorithmSuite.addTransformAlgorithm(WSConstants.NS_XMLDSIG_ENVELOPED_SIGNATURE); - - algorithmSuite.addDerivedKeyAlgorithm(SPConstants.P_SHA1); - algorithmSuite.addDerivedKeyAlgorithm(SPConstants.P_SHA1_L128); - - return algorithmSuite; + AlgorithmSuiteTranslater translater = new AlgorithmSuiteTranslater(); + translater.translateAlgorithmSuites(message.get(AssertionInfoMap.class), data); } - /** - * Get the WS-SecurityPolicy Binding that is in operation - */ - private Binding getBinding(SoapMessage message) { - AssertionInfoMap aim = message.get(AssertionInfoMap.class); - if (aim != null) { - Collection<AssertionInfo> ais = aim.get(SP12Constants.TRANSPORT_BINDING); - if (ais != null && !ais.isEmpty()) { - AssertionInfo ai = ais.iterator().next(); - return (Binding)ai.getAssertion(); - } - ais = aim.get(SP12Constants.ASYMMETRIC_BINDING); - if (ais != null && !ais.isEmpty()) { - AssertionInfo ai = ais.iterator().next(); - return (Binding)ai.getAssertion(); - } - ais = aim.get(SP12Constants.SYMMETRIC_BINDING); - if (ais != null && !ais.isEmpty()) { - AssertionInfo ai = ais.iterator().next(); - return (Binding)ai.getAssertion(); - } - } - return null; - } - protected void computeAction(SoapMessage message, RequestData data) throws WSSecurityException { String action = getString(WSHandlerConstants.ACTION, message); if (action == null) { Modified: cxf/branches/2.5.x-fixes/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyvalidators/AbstractBindingPolicyValidator.java URL: http://svn.apache.org/viewvc/cxf/branches/2.5.x-fixes/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyvalidators/AbstractBindingPolicyValidator.java?rev=1445748&r1=1445747&r2=1445748&view=diff ============================================================================== --- cxf/branches/2.5.x-fixes/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyvalidators/AbstractBindingPolicyValidator.java (original) +++ cxf/branches/2.5.x-fixes/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyvalidators/AbstractBindingPolicyValidator.java Wed Feb 13 17:09:25 2013 @@ -169,6 +169,12 @@ public abstract class AbstractBindingPol List<WSSecurityEngineResult> signedResults, Message message ) { + // Check the AlgorithmSuite + AlgorithmSuitePolicyValidator algorithmValidator = new AlgorithmSuitePolicyValidator(results); + if (!algorithmValidator.validatePolicy(ai, binding.getAlgorithmSuite())) { + return false; + } + // Check the IncludeTimestamp if (!validateTimestamp(binding.isIncludeTimestamp(), false, results, signedResults, message)) { String error = "Received Timestamp does not match the requirements"; Added: cxf/branches/2.5.x-fixes/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyvalidators/AlgorithmSuitePolicyValidator.java URL: http://svn.apache.org/viewvc/cxf/branches/2.5.x-fixes/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyvalidators/AlgorithmSuitePolicyValidator.java?rev=1445748&view=auto ============================================================================== --- cxf/branches/2.5.x-fixes/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyvalidators/AlgorithmSuitePolicyValidator.java (added) +++ cxf/branches/2.5.x-fixes/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyvalidators/AlgorithmSuitePolicyValidator.java Wed Feb 13 17:09:25 2013 @@ -0,0 +1,269 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.cxf.ws.security.wss4j.policyvalidators; + +import java.security.Principal; +import java.security.PublicKey; +import java.security.cert.X509Certificate; +import java.security.interfaces.DSAPublicKey; +import java.security.interfaces.RSAPublicKey; +import java.util.List; + +import org.apache.cxf.helpers.CastUtils; +import org.apache.cxf.ws.policy.AssertionInfo; +import org.apache.cxf.ws.security.policy.model.AlgorithmSuite; +import org.apache.ws.security.WSConstants; +import org.apache.ws.security.WSDataRef; +import org.apache.ws.security.WSDerivedKeyTokenPrincipal; +import org.apache.ws.security.WSSecurityEngineResult; +import org.apache.ws.security.transform.STRTransform; + +/** + * Validate a WSSecurityEngineResult corresponding to the processing of a Signature, EncryptedKey or + * EncryptedData structure against an AlgorithmSuite policy. + */ +public class AlgorithmSuitePolicyValidator { + + private List<WSSecurityEngineResult> results; + + public AlgorithmSuitePolicyValidator( + List<WSSecurityEngineResult> results + ) { + this.results = results; + } + + public boolean validatePolicy( + AssertionInfo aiBinding, AlgorithmSuite algorithmPolicy + ) { + boolean success = true; + for (WSSecurityEngineResult result : results) { + Integer actInt = (Integer)result.get(WSSecurityEngineResult.TAG_ACTION); + if (WSConstants.SIGN == actInt + && !checkSignatureAlgorithms(result, algorithmPolicy, aiBinding)) { + success = false; + } else if (WSConstants.ENCR == actInt + && !checkEncryptionAlgorithms(result, algorithmPolicy, aiBinding)) { + success = false; + } + } + return success; + } + + /** + * Check the Signature Algorithms + */ + private boolean checkSignatureAlgorithms( + WSSecurityEngineResult result, + AlgorithmSuite algorithmPolicy, + AssertionInfo ai + ) { + String signatureMethod = + (String)result.get(WSSecurityEngineResult.TAG_SIGNATURE_METHOD); + if (!algorithmPolicy.getAsymmetricSignature().equals(signatureMethod) + && !algorithmPolicy.getSymmetricSignature().equals(signatureMethod)) { + ai.setNotAsserted( + "The signature method does not match the requirement" + ); + return false; + } + String c14nMethod = + (String)result.get(WSSecurityEngineResult.TAG_CANONICALIZATION_METHOD); + if (!algorithmPolicy.getInclusiveC14n().equals(c14nMethod)) { + ai.setNotAsserted( + "The c14n method does not match the requirement" + ); + return false; + } + + List<WSDataRef> dataRefs = + CastUtils.cast((List<?>)result.get(WSSecurityEngineResult.TAG_DATA_REF_URIS)); + if (!checkDataRefs(dataRefs, algorithmPolicy, ai)) { + return false; + } + + if (!checkKeyLengths(result, algorithmPolicy, ai, true)) { + return false; + } + + return true; + } + + /** + * Check the individual signature references + */ + private boolean checkDataRefs( + List<WSDataRef> dataRefs, + AlgorithmSuite algorithmPolicy, + AssertionInfo ai + ) { + for (WSDataRef dataRef : dataRefs) { + String digestMethod = dataRef.getDigestAlgorithm(); + if (!algorithmPolicy.getDigest().equals(digestMethod)) { + ai.setNotAsserted( + "The digest method does not match the requirement" + ); + return false; + } + + List<String> transformAlgorithms = dataRef.getTransformAlgorithms(); + // Only a max of 2 transforms per reference is allowed + if (transformAlgorithms == null || transformAlgorithms.size() > 2) { + ai.setNotAsserted("The transform algorithms do not match the requirement"); + return false; + } + for (String transformAlgorithm : transformAlgorithms) { + if (!(algorithmPolicy.getInclusiveC14n().equals(transformAlgorithm) + || STRTransform.TRANSFORM_URI.equals(transformAlgorithm))) { + ai.setNotAsserted("The transform algorithms do not match the requirement"); + return false; + } + } + } + return true; + } + + /** + * Check the Encryption Algorithms + */ + private boolean checkEncryptionAlgorithms( + WSSecurityEngineResult result, + AlgorithmSuite algorithmPolicy, + AssertionInfo ai + ) { + String transportMethod = + (String)result.get(WSSecurityEngineResult.TAG_ENCRYPTED_KEY_TRANSPORT_METHOD); + if (transportMethod != null + && !algorithmPolicy.getSymmetricKeyWrap().equals(transportMethod) + && !algorithmPolicy.getAsymmetricKeyWrap().equals(transportMethod)) { + ai.setNotAsserted( + "The Key transport method does not match the requirement" + ); + return false; + } + + List<WSDataRef> dataRefs = + CastUtils.cast((List<?>)result.get(WSSecurityEngineResult.TAG_DATA_REF_URIS)); + if (dataRefs != null) { + for (WSDataRef dataRef : dataRefs) { + String encryptionAlgorithm = dataRef.getAlgorithm(); + if (!algorithmPolicy.getEncryption().equals(encryptionAlgorithm)) { + ai.setNotAsserted( + "The encryption algorithm does not match the requirement" + ); + return false; + } + } + } + + if (!checkKeyLengths(result, algorithmPolicy, ai, false)) { + return false; + } + + return true; + } + + /** + * Check the key lengths of the secret and public keys. + */ + private boolean checkKeyLengths( + WSSecurityEngineResult result, + AlgorithmSuite algorithmPolicy, + AssertionInfo ai, + boolean signature + ) { + PublicKey publicKey = (PublicKey)result.get(WSSecurityEngineResult.TAG_PUBLIC_KEY); + if (publicKey != null && !checkPublicKeyLength(publicKey, algorithmPolicy, ai)) { + return false; + } + + X509Certificate x509Cert = + (X509Certificate)result.get(WSSecurityEngineResult.TAG_X509_CERTIFICATE); + if (x509Cert != null && !checkPublicKeyLength(x509Cert.getPublicKey(), algorithmPolicy, ai)) { + return false; + } + + byte[] secret = (byte[])result.get(WSSecurityEngineResult.TAG_SECRET); + if (signature) { + Principal principal = (Principal)result.get(WSSecurityEngineResult.TAG_PRINCIPAL); + if (principal instanceof WSDerivedKeyTokenPrincipal) { + int requiredLength = algorithmPolicy.getSignatureDerivedKeyLength(); + if (secret == null || secret.length != (requiredLength / 8)) { + ai.setNotAsserted( + "The signature derived key length does not match the requirement" + ); + return false; + } + } else if (secret != null + && (secret.length < (algorithmPolicy.getMinimumSymmetricKeyLength() / 8) + || secret.length > (algorithmPolicy.getMaximumSymmetricKeyLength() / 8))) { + ai.setNotAsserted( + "The symmetric key length does not match the requirement" + ); + return false; + } + } else if (secret != null + && (secret.length < (algorithmPolicy.getMinimumSymmetricKeyLength() / 8) + || secret.length > (algorithmPolicy.getMaximumSymmetricKeyLength() / 8))) { + ai.setNotAsserted( + "The symmetric key length does not match the requirement" + ); + return false; + } + + return true; + } + + /** + * Check the public key lengths + */ + private boolean checkPublicKeyLength( + PublicKey publicKey, + AlgorithmSuite algorithmPolicy, + AssertionInfo ai + ) { + if (publicKey instanceof RSAPublicKey) { + int modulus = ((RSAPublicKey)publicKey).getModulus().bitLength(); + if (modulus < algorithmPolicy.getMinimumAsymmetricKeyLength() + || modulus > algorithmPolicy.getMaximumAsymmetricKeyLength()) { + ai.setNotAsserted( + "The asymmetric key length does not match the requirement" + ); + return false; + } + } else if (publicKey instanceof DSAPublicKey) { + int length = ((DSAPublicKey)publicKey).getParams().getP().bitLength(); + if (length < algorithmPolicy.getMinimumAsymmetricKeyLength() + || length > algorithmPolicy.getMaximumAsymmetricKeyLength()) { + ai.setNotAsserted( + "The asymmetric key length does not match the requirement" + ); + return false; + } + } else { + ai.setNotAsserted( + "An unknown public key was provided" + ); + return false; + } + + return true; + } + +} Modified: cxf/branches/2.5.x-fixes/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyvalidators/TransportBindingPolicyValidator.java URL: http://svn.apache.org/viewvc/cxf/branches/2.5.x-fixes/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyvalidators/TransportBindingPolicyValidator.java?rev=1445748&r1=1445747&r2=1445748&view=diff ============================================================================== --- cxf/branches/2.5.x-fixes/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyvalidators/TransportBindingPolicyValidator.java (original) +++ cxf/branches/2.5.x-fixes/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyvalidators/TransportBindingPolicyValidator.java Wed Feb 13 17:09:25 2013 @@ -70,6 +70,12 @@ public class TransportBindingPolicyValid assertPolicy(aim, binding.getTransportToken()); } + // Check the AlgorithmSuite + AlgorithmSuitePolicyValidator algorithmValidator = new AlgorithmSuitePolicyValidator(results); + if (!algorithmValidator.validatePolicy(ai, binding.getAlgorithmSuite())) { + continue; + } + // Check the IncludeTimestamp if (!validateTimestamp(binding.isIncludeTimestamp(), true, results, signedResults, message)) { String error = "Received Timestamp does not match the requirements"; Modified: cxf/branches/2.5.x-fixes/systests/ws-security/src/test/java/org/apache/cxf/systest/ws/algsuite/AlgorithmSuiteTest.java URL: http://svn.apache.org/viewvc/cxf/branches/2.5.x-fixes/systests/ws-security/src/test/java/org/apache/cxf/systest/ws/algsuite/AlgorithmSuiteTest.java?rev=1445748&r1=1445747&r2=1445748&view=diff ============================================================================== --- cxf/branches/2.5.x-fixes/systests/ws-security/src/test/java/org/apache/cxf/systest/ws/algsuite/AlgorithmSuiteTest.java (original) +++ cxf/branches/2.5.x-fixes/systests/ws-security/src/test/java/org/apache/cxf/systest/ws/algsuite/AlgorithmSuiteTest.java Wed Feb 13 17:09:25 2013 @@ -73,6 +73,7 @@ public class AlgorithmSuiteTest extends URL wsdl = AlgorithmSuiteTest.class.getResource("DoubleItAlgSuite.wsdl"); Service service = Service.create(wsdl, SERVICE_QNAME); QName portQName = new QName(NAMESPACE, "DoubleItSymmetric128Port"); + DoubleItPortType port = service.getPort(portQName, DoubleItPortType.class); updateAddressPort(port, PORT); @@ -106,6 +107,34 @@ public class AlgorithmSuiteTest extends // expected } } + + bus.shutdown(true); + } + + @org.junit.Test + public void testCombinedPolicy() throws Exception { + + if (!SecurityTestUtil.checkUnrestrictedPoliciesInstalled()) { + return; + } + + SpringBusFactory bf = new SpringBusFactory(); + URL busFile = AlgorithmSuiteTest.class.getResource("client/client.xml"); + + Bus bus = bf.createBus(busFile.toString()); + SpringBusFactory.setDefaultBus(bus); + SpringBusFactory.setThreadDefaultBus(bus); + + URL wsdl = AlgorithmSuiteTest.class.getResource("DoubleItAlgSuite.wsdl"); + Service service = Service.create(wsdl, SERVICE_QNAME); + + // The client + server use Basic256 (but there is a sp:TripleDesRsa15 policy in the + // WSDL as well) + QName portQName = new QName(NAMESPACE, "DoubleItSymmetricCombinedPort"); + DoubleItPortType port = service.getPort(portQName, DoubleItPortType.class); + updateAddressPort(port, PORT); + + port.doubleIt(25); bus.shutdown(true); } @@ -198,4 +227,4 @@ public class AlgorithmSuiteTest extends bus.shutdown(true); } -} \ No newline at end of file +} Modified: cxf/branches/2.5.x-fixes/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/algsuite/DoubleItAlgSuite.wsdl URL: http://svn.apache.org/viewvc/cxf/branches/2.5.x-fixes/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/algsuite/DoubleItAlgSuite.wsdl?rev=1445748&r1=1445747&r2=1445748&view=diff ============================================================================== --- cxf/branches/2.5.x-fixes/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/algsuite/DoubleItAlgSuite.wsdl (original) +++ cxf/branches/2.5.x-fixes/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/algsuite/DoubleItAlgSuite.wsdl Wed Feb 13 17:09:25 2013 @@ -57,6 +57,9 @@ <wsdl:port name="DoubleItSymmetric128Port3" binding="tns:DoubleItInlinePolicyBinding"> <soap:address location="http://localhost:9010/DoubleItSymmetric128no3" /> </wsdl:port> + <wsdl:port name="DoubleItSymmetricCombinedPort" binding="tns:DoubleItInlinePolicyBinding"> + <soap:address location="http://localhost:9010/DoubleItSymmetricCombined" /> + </wsdl:port> <wsdl:port name="DoubleItEncryptionOAEPPort" binding="tns:DoubleItInlinePolicyBinding"> <soap:address location="http://localhost:9010/DoubleItEncryptionOAEP" /> </wsdl:port> @@ -73,5 +76,5 @@ <soap:address location="http://localhost:9010/DoubleItSignatureno2" /> </wsdl:port> </wsdl:service> - + </wsdl:definitions> Modified: cxf/branches/2.5.x-fixes/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/algsuite/client/client.xml URL: http://svn.apache.org/viewvc/cxf/branches/2.5.x-fixes/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/algsuite/client/client.xml?rev=1445748&r1=1445747&r2=1445748&view=diff ============================================================================== --- cxf/branches/2.5.x-fixes/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/algsuite/client/client.xml (original) +++ cxf/branches/2.5.x-fixes/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/algsuite/client/client.xml Wed Feb 13 17:09:25 2013 @@ -98,6 +98,25 @@ </jaxws:client> <jaxws:client + name="{http://www.example.org/contract/DoubleIt}DoubleItSymmetricCombinedPort" + createdFromAPI="true"> + <jaxws:properties> + <entry key="ws-security.username" value="Alice" /> + <entry key="ws-security.callback-handler" + value="org.apache.cxf.systest.ws.wssec10.client.UTPasswordCallback" /> + <entry key="ws-security.encryption.properties" + value="org/apache/cxf/systest/ws/wssec10/client/bob.properties" /> + <entry key="ws-security.encryption.username" value="bob" /> + </jaxws:properties> + <jaxws:features> + <p:policies> + <wsp:PolicyReference xmlns:wsp="http://www.w3.org/ns/ws-policy" + URI="#DoubleItSymmetric256Policy" /> + </p:policies> + </jaxws:features> + </jaxws:client> + + <jaxws:client name="{http://www.example.org/contract/DoubleIt}DoubleItEncryptionOAEPPort" createdFromAPI="true"> <jaxws:outInterceptors> Modified: cxf/branches/2.5.x-fixes/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/algsuite/server/server.xml URL: http://svn.apache.org/viewvc/cxf/branches/2.5.x-fixes/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/algsuite/server/server.xml?rev=1445748&r1=1445747&r2=1445748&view=diff ============================================================================== --- cxf/branches/2.5.x-fixes/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/algsuite/server/server.xml (original) +++ cxf/branches/2.5.x-fixes/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/algsuite/server/server.xml Wed Feb 13 17:09:25 2013 @@ -113,6 +113,29 @@ </jaxws:endpoint> + <jaxws:endpoint id="SymmetricEndpointCombined" + address="http://localhost:${testutil.ports.Server}/DoubleItSymmetricCombined" + serviceName="s:DoubleItService" endpointName="s:DoubleItSymmetricCombinedPort" + xmlns:s="http://www.example.org/contract/DoubleIt" + implementor="org.apache.cxf.systest.ws.common.DoubleItImpl" + wsdlLocation="org/apache/cxf/systest/ws/algsuite/DoubleItAlgSuite.wsdl"> + + <jaxws:properties> + <entry key="ws-security.callback-handler" + value="org.apache.cxf.systest.ws.wssec10.client.UTPasswordCallback" /> + <entry key="ws-security.signature.properties" + value="org/apache/cxf/systest/ws/wssec10/client/bob.properties" /> + <entry key="ws-security.subject.cert.constraints" value=".*O=apache.org.*"/> + </jaxws:properties> + <jaxws:features> + <p:policies> + <wsp:PolicyReference xmlns:wsp="http://www.w3.org/ns/ws-policy" + URI="#Combined" /> + </p:policies> + </jaxws:features> + + </jaxws:endpoint> + <jaxws:endpoint id="EncryptionOAEPEndpoint" address="http://localhost:${testutil.ports.Server}/DoubleItEncryptionOAEP" serviceName="s:DoubleItService" endpointName="s:DoubleItEncryptionOAEPPort" @@ -287,5 +310,82 @@ </wsp:ExactlyOne> </wsp:Policy> + <wsp:Policy wsu:Id="Combined" + xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" + xmlns:wsp="http://www.w3.org/ns/ws-policy" + xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702"> + <wsp:ExactlyOne> + <wsp:All> + <sp:SymmetricBinding> + <wsp:Policy> + <sp:ProtectionToken> + <wsp:Policy> + <sp:X509Token + sp:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/Never"> + <wsp:Policy> + <sp:WssX509V3Token10 /> + <sp:RequireKeyIdentifierReference /> + </wsp:Policy> + </sp:X509Token> + </wsp:Policy> + </sp:ProtectionToken> + <sp:Layout> + <wsp:Policy> + <sp:Lax/> + </wsp:Policy> + </sp:Layout> + <sp:IncludeTimestamp/> + <sp:OnlySignEntireHeadersAndBody/> + <sp:AlgorithmSuite> + <wsp:Policy> + <sp:TripleDesRsa15/> + </wsp:Policy> + </sp:AlgorithmSuite> + </wsp:Policy> + </sp:SymmetricBinding> + <sp:EncryptedParts> + <sp:Body/> + </sp:EncryptedParts> + <sp:SignedParts> + <sp:Body/> + </sp:SignedParts> + </wsp:All> + <wsp:All> + <sp:SymmetricBinding> + <wsp:Policy> + <sp:ProtectionToken> + <wsp:Policy> + <sp:X509Token + sp:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/Never"> + <wsp:Policy> + <sp:WssX509V3Token10 /> + <sp:RequireKeyIdentifierReference /> + </wsp:Policy> + </sp:X509Token> + </wsp:Policy> + </sp:ProtectionToken> + <sp:Layout> + <wsp:Policy> + <sp:Lax/> + </wsp:Policy> + </sp:Layout> + <sp:IncludeTimestamp/> + <sp:OnlySignEntireHeadersAndBody/> + <sp:AlgorithmSuite> + <wsp:Policy> + <sp:Basic256/> + </wsp:Policy> + </sp:AlgorithmSuite> + </wsp:Policy> + </sp:SymmetricBinding> + <sp:EncryptedParts> + <sp:Body/> + </sp:EncryptedParts> + <sp:SignedParts> + <sp:Body/> + </sp:SignedParts> + </wsp:All> + </wsp:ExactlyOne> + </wsp:Policy> </beans>
