You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by dk...@apache.org on 2013/02/13 18:09:25 UTC

svn commit: r1445748 - in /cxf/branches/2.5.x-fixes: ./ rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/ rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyvalidators/ systests/ws-security/src/test/java/org/apache/cxf/sys...

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>