You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ws.apache.org by co...@apache.org on 2012/11/21 18:18:51 UTC

svn commit: r1412201 [1/2] - in /webservices/wss4j/trunk: ws-security-common/src/main/java/org/apache/ws/security/common/crypto/ ws-security-common/src/main/java/org/apache/ws/security/common/saml/ ws-security-dom/src/main/java/org/apache/ws/security/d...

Author: coheigea
Date: Wed Nov 21 17:18:49 2012
New Revision: 1412201

URL: http://svn.apache.org/viewvc?rev=1412201&view=rev
Log:
[WSS-406] - Add the ability to define which algorithms are acceptable when processing a security header


Conflicts:

	ws-security-common/src/main/java/org/apache/ws/security/common/saml/SAMLUtil.java
	ws-security-dom/src/main/java/org/apache/ws/security/dom/handler/RequestData.java
	ws-security-dom/src/main/java/org/apache/ws/security/dom/handler/WSHandler.java
	ws-security-dom/src/main/java/org/apache/ws/security/dom/processor/DerivedKeyTokenProcessor.java
	ws-security-dom/src/main/java/org/apache/ws/security/dom/processor/EncryptedDataProcessor.java
	ws-security-dom/src/main/java/org/apache/ws/security/dom/processor/EncryptedKeyProcessor.java
	ws-security-dom/src/main/java/org/apache/ws/security/dom/processor/ReferenceListProcessor.java
	ws-security-dom/src/main/java/org/apache/ws/security/dom/processor/SAMLTokenProcessor.java
	ws-security-dom/src/main/java/org/apache/ws/security/dom/processor/SignatureProcessor.java

Added:
    webservices/wss4j/trunk/ws-security-common/src/main/java/org/apache/ws/security/common/crypto/AlgorithmSuite.java
    webservices/wss4j/trunk/ws-security-common/src/main/java/org/apache/ws/security/common/crypto/AlgorithmSuiteValidator.java
    webservices/wss4j/trunk/ws-security-dom/src/test/java/org/apache/ws/security/dom/message/EncryptionAlgorithmSuiteTest.java
    webservices/wss4j/trunk/ws-security-dom/src/test/java/org/apache/ws/security/dom/message/SignatureAlgorithmSuiteTest.java
    webservices/wss4j/trunk/ws-security-dom/src/test/java/org/apache/ws/security/dom/saml/SamlAlgorithmSuiteTest.java
Modified:
    webservices/wss4j/trunk/ws-security-common/src/main/java/org/apache/ws/security/common/saml/AssertionWrapper.java
    webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/WSDerivedKeyTokenPrincipal.java
    webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/handler/RequestData.java
    webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/handler/WSHandler.java
    webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/handler/WSHandlerConstants.java
    webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/message/token/DerivedKeyToken.java
    webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/processor/DerivedKeyTokenProcessor.java
    webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/processor/EncryptedDataProcessor.java
    webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/processor/EncryptedKeyProcessor.java
    webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/processor/ReferenceListProcessor.java
    webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/processor/SAMLTokenProcessor.java
    webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/processor/SignatureProcessor.java
    webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/str/SecurityTokenRefSTRParser.java

Added: webservices/wss4j/trunk/ws-security-common/src/main/java/org/apache/ws/security/common/crypto/AlgorithmSuite.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-common/src/main/java/org/apache/ws/security/common/crypto/AlgorithmSuite.java?rev=1412201&view=auto
==============================================================================
--- webservices/wss4j/trunk/ws-security-common/src/main/java/org/apache/ws/security/common/crypto/AlgorithmSuite.java (added)
+++ webservices/wss4j/trunk/ws-security-common/src/main/java/org/apache/ws/security/common/crypto/AlgorithmSuite.java Wed Nov 21 17:18:49 2012
@@ -0,0 +1,176 @@
+/**
+ * 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.ws.security.common.crypto;
+
+import java.util.HashSet;
+import java.util.Collections;
+import java.util.Set;
+
+/**
+ * This class holds the permitted values for encryption/signature/etc. algorithms on the
+ * inbound side. If the corresponding value is not null then the received algorithm must
+ * match the appropriate algorithm stored in this class.
+ */
+public class AlgorithmSuite {
+    
+    private Set<String> signatureMethods = Collections.emptySet();
+    private Set<String> c14nAlgorithms = Collections.emptySet();
+    private Set<String> digestAlgorithms = Collections.emptySet();
+    private Set<String> transformAlgorithms = Collections.emptySet();
+    
+    private Set<String> encryptionMethods = Collections.emptySet();
+    private Set<String> keyWrapAlgorithms = Collections.emptySet();
+    
+    private Set<String> derivedKeyAlgorithms = Collections.emptySet();
+    
+    private int maximumSymmetricKeyLength = 256;
+    private int minimumSymmetricKeyLength = 128;
+    private int maximumAsymmetricKeyLength = 4096;
+    private int minimumAsymmetricKeyLength = 1024;
+    
+    private int signatureDerivedKeyLength;
+    private int encryptionDerivedKeyLength;
+
+    public void addSignatureMethod(String signatureMethod) {
+        if (signatureMethods.isEmpty()) {
+            signatureMethods = new HashSet<String>();
+        }
+        signatureMethods.add(signatureMethod);
+    }
+    
+    public Set<String> getSignatureMethods() {
+        return signatureMethods;
+    }
+    
+    public void addC14nAlgorithm(String c14nAlgorithm) {
+        if (c14nAlgorithms.isEmpty()) {
+            c14nAlgorithms = new HashSet<String>();
+        }
+        c14nAlgorithms.add(c14nAlgorithm);
+    }
+    
+    public Set<String> getC14nAlgorithms() {
+        return c14nAlgorithms;
+    }
+    
+    public void addDigestAlgorithm(String digestAlgorithm) {
+        if (digestAlgorithms.isEmpty()) {
+            digestAlgorithms = new HashSet<String>();
+        }
+        digestAlgorithms.add(digestAlgorithm);
+    }
+    
+    public Set<String> getDigestAlgorithms() {
+        return digestAlgorithms;
+    }
+    
+    public void addTransformAlgorithm(String transformAlgorithm) {
+        if (transformAlgorithms.isEmpty()) {
+            transformAlgorithms = new HashSet<String>();
+        }
+        transformAlgorithms.add(transformAlgorithm);
+    }
+    
+    public Set<String> getTransformAlgorithms() {
+        return transformAlgorithms;
+    }
+    
+    public void addEncryptionMethod(String encryptionMethod) {
+        if (encryptionMethods.isEmpty()) {
+            encryptionMethods = new HashSet<String>();
+        }
+        encryptionMethods.add(encryptionMethod);
+    }
+    
+    public Set<String> getEncryptionMethods() {
+        return encryptionMethods;
+    }
+    
+    public void addKeyWrapAlgorithm(String keyWrapAlgorithm) {
+        if (keyWrapAlgorithms.isEmpty()) {
+            keyWrapAlgorithms = new HashSet<String>();
+        }
+        keyWrapAlgorithms.add(keyWrapAlgorithm);
+    }
+    
+    public Set<String> getKeyWrapAlgorithms() {
+        return keyWrapAlgorithms;
+    }
+    
+    public void addDerivedKeyAlgorithm(String derivedKeyAlgorithm) {
+        if (derivedKeyAlgorithms.isEmpty()) {
+            derivedKeyAlgorithms = new HashSet<String>();
+        }
+        derivedKeyAlgorithms.add(derivedKeyAlgorithm);
+    }
+    
+    public Set<String> getDerivedKeyAlgorithms() {
+        return derivedKeyAlgorithms;
+    }
+
+    public int getMaximumSymmetricKeyLength() {
+        return maximumSymmetricKeyLength;
+    }
+
+    public void setMaximumSymmetricKeyLength(int maximumSymmetricKeyLength) {
+        this.maximumSymmetricKeyLength = maximumSymmetricKeyLength;
+    }
+
+    public int getMinimumAsymmetricKeyLength() {
+        return minimumAsymmetricKeyLength;
+    }
+
+    public void setMinimumAsymmetricKeyLength(int minimumAsymmetricKeyLength) {
+        this.minimumAsymmetricKeyLength = minimumAsymmetricKeyLength;
+    }
+
+    public int getMaximumAsymmetricKeyLength() {
+        return maximumAsymmetricKeyLength;
+    }
+
+    public void setMaximumAsymmetricKeyLength(int maximumAsymmetricKeyLength) {
+        this.maximumAsymmetricKeyLength = maximumAsymmetricKeyLength;
+    }
+
+    public int getEncryptionDerivedKeyLength() {
+        return encryptionDerivedKeyLength;
+    }
+
+    public void setEncryptionDerivedKeyLength(int encryptionDerivedKeyLength) {
+        this.encryptionDerivedKeyLength = encryptionDerivedKeyLength;
+    }
+
+    public int getSignatureDerivedKeyLength() {
+        return signatureDerivedKeyLength;
+    }
+
+    public void setSignatureDerivedKeyLength(int signatureDerivedKeyLength) {
+        this.signatureDerivedKeyLength = signatureDerivedKeyLength;
+    }
+
+    public int getMinimumSymmetricKeyLength() {
+        return minimumSymmetricKeyLength;
+    }
+
+    public void setMinimumSymmetricKeyLength(int minimumSymmetricKeyLength) {
+        this.minimumSymmetricKeyLength = minimumSymmetricKeyLength;
+    }
+
+}
\ No newline at end of file

Added: webservices/wss4j/trunk/ws-security-common/src/main/java/org/apache/ws/security/common/crypto/AlgorithmSuiteValidator.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-common/src/main/java/org/apache/ws/security/common/crypto/AlgorithmSuiteValidator.java?rev=1412201&view=auto
==============================================================================
--- webservices/wss4j/trunk/ws-security-common/src/main/java/org/apache/ws/security/common/crypto/AlgorithmSuiteValidator.java (added)
+++ webservices/wss4j/trunk/ws-security-common/src/main/java/org/apache/ws/security/common/crypto/AlgorithmSuiteValidator.java Wed Nov 21 17:18:49 2012
@@ -0,0 +1,262 @@
+/**
+ * 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.ws.security.common.crypto;
+
+import java.security.PublicKey;
+import java.security.cert.X509Certificate;
+import java.security.interfaces.DSAPublicKey;
+import java.security.interfaces.RSAPublicKey;
+import java.util.Set;
+
+import javax.xml.crypto.dsig.Reference;
+import javax.xml.crypto.dsig.Transform;
+import javax.xml.crypto.dsig.XMLSignature;
+
+import org.apache.ws.security.common.ext.WSSecurityException;
+
+/**
+ * Validate signature/encryption/etc. algorithms against an AlgorithmSuite policy.
+ */
+public class AlgorithmSuiteValidator {
+    
+    private static final org.apache.commons.logging.Log LOG = 
+        org.apache.commons.logging.LogFactory.getLog(AlgorithmSuiteValidator.class);
+    
+    private final AlgorithmSuite algorithmSuite;
+    
+    public AlgorithmSuiteValidator(
+        AlgorithmSuite algorithmSuite
+    ) {
+        this.algorithmSuite = algorithmSuite;
+    }
+    
+    /**
+     * Check the Signature Method
+     */
+    public void checkSignatureMethod(
+        String signatureMethod
+    ) throws WSSecurityException {
+        Set<String> allowedSignatureMethods = algorithmSuite.getSignatureMethods();
+        if (!allowedSignatureMethods.isEmpty()
+            && !allowedSignatureMethods.contains(signatureMethod)) {
+            LOG.debug(
+                "SignatureMethod " + signatureMethod + " does not match required values"
+            );
+            throw new WSSecurityException(WSSecurityException.ErrorCode.INVALID_SECURITY);
+        }
+    }
+    
+    /**
+     * Check the C14n Algorithm
+     */
+    public void checkC14nAlgorithm(
+        String c14nAlgorithm
+    ) throws WSSecurityException {
+        Set<String> allowedC14nAlgorithms = algorithmSuite.getC14nAlgorithms();
+        if (!allowedC14nAlgorithms.isEmpty() && !allowedC14nAlgorithms.contains(c14nAlgorithm)) {
+            LOG.debug(
+                "C14nMethod " + c14nAlgorithm + " does not match required value"
+            );
+            throw new WSSecurityException(WSSecurityException.ErrorCode.INVALID_SECURITY);
+        }
+    }
+    
+    /**
+     * Check the Signature Algorithms
+     */
+    public void checkSignatureAlgorithms(
+        XMLSignature xmlSignature
+    ) throws WSSecurityException {
+        // Signature Algorithm
+        String signatureMethod = 
+            xmlSignature.getSignedInfo().getSignatureMethod().getAlgorithm();
+        checkSignatureMethod(signatureMethod);
+            
+        // C14n Algorithm
+        String c14nMethod = 
+            xmlSignature.getSignedInfo().getCanonicalizationMethod().getAlgorithm();
+        checkC14nAlgorithm(c14nMethod);
+        
+        for (Object refObject : xmlSignature.getSignedInfo().getReferences()) {
+            Reference reference = (Reference)refObject;
+            // Digest Algorithm
+            String digestMethod = reference.getDigestMethod().getAlgorithm();
+            Set<String> allowedDigestAlgorithms = algorithmSuite.getDigestAlgorithms();
+            if (!allowedDigestAlgorithms.isEmpty()
+                    && !allowedDigestAlgorithms.contains(digestMethod)) {
+                LOG.debug(
+                    "DigestMethod " + digestMethod + " does not match required value"
+                );
+                throw new WSSecurityException(WSSecurityException.ErrorCode.INVALID_SECURITY);
+            }
+            
+            // Transform Algorithms
+            for (int i = 0; i < reference.getTransforms().size(); i++) {
+                Transform transform = (Transform)reference.getTransforms().get(i);
+                String algorithm = transform.getAlgorithm();
+                Set<String> allowedTransformAlgorithms = 
+                        algorithmSuite.getTransformAlgorithms();
+                if (!allowedTransformAlgorithms.isEmpty() 
+                        && !allowedTransformAlgorithms.contains(algorithm)) {
+                    LOG.debug(
+                        "Transform method " + algorithm + " does not match required value"
+                    );
+                    throw new WSSecurityException(WSSecurityException.ErrorCode.INVALID_SECURITY);
+                }
+            }
+        }
+    }
+    
+    public void checkEncryptionKeyWrapAlgorithm(
+        String keyWrapAlgorithm
+    ) throws WSSecurityException {
+        Set<String> keyWrapAlgorithms = algorithmSuite.getKeyWrapAlgorithms();
+        if (!keyWrapAlgorithms.isEmpty()
+            && !keyWrapAlgorithms.contains(keyWrapAlgorithm)) {
+            LOG.debug(
+                "The Key transport method does not match the requirement"
+            );
+            throw new WSSecurityException(WSSecurityException.ErrorCode.INVALID_SECURITY);
+        }
+    }
+    
+    public void checkSymmetricEncryptionAlgorithm(
+        String symmetricAlgorithm
+    ) throws WSSecurityException {
+        Set<String> encryptionMethods = algorithmSuite.getEncryptionMethods();
+        if (!encryptionMethods.isEmpty()
+            && !encryptionMethods.contains(symmetricAlgorithm)) {
+            LOG.debug(
+                "The encryption algorithm does not match the requirement"
+            );
+            throw new WSSecurityException(WSSecurityException.ErrorCode.INVALID_SECURITY);
+        }
+    }
+
+    /**
+     * Check the asymmetric key length
+     */
+    public void checkAsymmetricKeyLength(
+        X509Certificate x509Certificate
+    ) throws WSSecurityException {
+        if (x509Certificate == null) {
+            return;
+        }
+        
+        checkAsymmetricKeyLength(x509Certificate.getPublicKey());
+    }
+    
+    /**
+     * Check the asymmetric key length
+     */
+    public void checkAsymmetricKeyLength(
+        PublicKey publicKey
+    ) throws WSSecurityException {
+        if (publicKey == null) {
+            return;
+        }
+        if (publicKey instanceof RSAPublicKey) {
+            int modulus = ((RSAPublicKey)publicKey).getModulus().bitLength();
+            if (modulus < algorithmSuite.getMinimumAsymmetricKeyLength()
+                || modulus > algorithmSuite.getMaximumAsymmetricKeyLength()) {
+                LOG.debug(
+                    "The asymmetric key length does not match the requirement"
+                );
+                throw new WSSecurityException(WSSecurityException.ErrorCode.INVALID_SECURITY);
+            }
+        } else if (publicKey instanceof DSAPublicKey) {
+            int length = ((DSAPublicKey)publicKey).getParams().getP().bitLength();
+            if (length < algorithmSuite.getMinimumAsymmetricKeyLength()
+                || length > algorithmSuite.getMaximumAsymmetricKeyLength()) {
+                LOG.debug(
+                    "The asymmetric key length does not match the requirement"
+                );
+                throw new WSSecurityException(WSSecurityException.ErrorCode.INVALID_SECURITY);
+            }
+        } else {
+            LOG.debug(
+                "An unknown public key was provided"
+            );
+            throw new WSSecurityException(WSSecurityException.ErrorCode.INVALID_SECURITY);
+        }
+    }
+    
+    /**
+     * Check the symmetric key length
+     */
+    public void checkSymmetricKeyLength(
+        int secretKeyLength
+    ) throws WSSecurityException {
+        if (secretKeyLength < (algorithmSuite.getMinimumSymmetricKeyLength() / 8)
+            || secretKeyLength > (algorithmSuite.getMaximumSymmetricKeyLength() / 8)) {
+            LOG.debug(
+                "The symmetric key length does not match the requirement"
+            );
+            throw new WSSecurityException(WSSecurityException.ErrorCode.INVALID_SECURITY);
+        }
+    }
+    
+    /**
+     * Check Signature Derived Key length (in bytes)
+     */
+    public void checkSignatureDerivedKeyLength(
+        int derivedKeyLength
+    ) throws WSSecurityException {
+        int requiredKeyLength = algorithmSuite.getSignatureDerivedKeyLength();
+        if (requiredKeyLength > 0 && (derivedKeyLength / 8) != requiredKeyLength) {
+            LOG.debug(
+                "The signature derived key length of " + derivedKeyLength + " does not match"
+                + "the requirement of " + requiredKeyLength
+            );
+        }
+    }
+    
+    /**
+     * Check Encryption Derived Key length (in bytes)
+     */
+    public void checkEncryptionDerivedKeyLength(
+        int derivedKeyLength
+    ) throws WSSecurityException {
+        int requiredKeyLength = algorithmSuite.getEncryptionDerivedKeyLength();
+        if (requiredKeyLength > 0 && (derivedKeyLength / 8) != requiredKeyLength) {
+            LOG.debug(
+                "The encryption derived key length of " + derivedKeyLength + " does not match"
+                + "the requirement of " + requiredKeyLength
+            );
+        }
+    }
+    
+    /**
+     * Check Derived Key algorithm
+     */
+    public void checkDerivedKeyAlgorithm(
+        String algorithm
+    ) throws WSSecurityException {
+        Set<String> derivedKeyAlgorithms = algorithmSuite.getDerivedKeyAlgorithms();
+        if (!derivedKeyAlgorithms.isEmpty()
+            && !derivedKeyAlgorithms.contains(algorithm)) {
+            LOG.debug(
+                "The Derived Key Algorithm does not match the requirement"
+            );
+            throw new WSSecurityException(WSSecurityException.ErrorCode.INVALID_SECURITY);
+        }
+    }
+        
+}

Modified: webservices/wss4j/trunk/ws-security-common/src/main/java/org/apache/ws/security/common/saml/AssertionWrapper.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-common/src/main/java/org/apache/ws/security/common/saml/AssertionWrapper.java?rev=1412201&r1=1412200&r2=1412201&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-common/src/main/java/org/apache/ws/security/common/saml/AssertionWrapper.java (original)
+++ webservices/wss4j/trunk/ws-security-common/src/main/java/org/apache/ws/security/common/saml/AssertionWrapper.java Wed Nov 21 17:18:49 2012
@@ -511,6 +511,21 @@ public class AssertionWrapper {
                 SAMLUtil.getCredentialFromKeyInfo(
                     keyInfo.getDOM(), keyInfoProcessor, sigCrypto
                 );
+            verifySignature(samlKeyInfo);
+        } else {
+            LOG.debug("AssertionWrapper: no signature to validate");
+        }
+
+    }
+    
+    /**
+     * Verify the signature of this assertion
+     *
+     * @throws ValidationException
+     */
+    public void verifySignature(SAMLKeyInfo samlKeyInfo) throws WSSecurityException {
+        Signature sig = getSignature();
+        if (sig != null) {
             if (samlKeyInfo == null) {
                 throw new WSSecurityException(
                     WSSecurityException.ErrorCode.FAILURE, "invalidSAMLsecurity",

Modified: webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/WSDerivedKeyTokenPrincipal.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/WSDerivedKeyTokenPrincipal.java?rev=1412201&r1=1412200&r2=1412201&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/WSDerivedKeyTokenPrincipal.java (original)
+++ webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/WSDerivedKeyTokenPrincipal.java Wed Nov 21 17:18:49 2012
@@ -31,6 +31,7 @@ import java.security.Principal;
  */
 public class WSDerivedKeyTokenPrincipal implements Principal {
 
+    private String algorithm;
     private String id;
     private String nonce;
     private String label;
@@ -94,5 +95,14 @@ public class WSDerivedKeyTokenPrincipal 
     public void setBasetokenId(String basetokenId) {
         this.basetokenId = basetokenId;
     }
+    
+    public String getAlgorithm() {
+        return algorithm;
+    }
+
+    public void setAlgorithm(String algorithm) {
+        this.algorithm = algorithm;
+    }
+
 
 }

Modified: webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/handler/RequestData.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/handler/RequestData.java?rev=1412201&r1=1412200&r2=1412201&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/handler/RequestData.java (original)
+++ webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/handler/RequestData.java Wed Nov 21 17:18:49 2012
@@ -25,6 +25,7 @@ import java.util.Collection;
 import java.util.Collections;
 import java.util.LinkedList;
 import java.util.List;
+import java.util.Map;
 import java.util.regex.Pattern;
 
 import javax.security.auth.callback.CallbackHandler;
@@ -37,6 +38,7 @@ import org.apache.ws.security.dom.WSSCon
 import org.apache.ws.security.dom.bsp.BSPEnforcer;
 import org.apache.ws.security.dom.cache.ReplayCache;
 import org.apache.ws.security.common.bsp.BSPRule;
+import org.apache.ws.security.common.crypto.AlgorithmSuite;
 import org.apache.ws.security.common.crypto.Crypto;
 import org.apache.ws.security.common.ext.WSSecurityException;
 import org.apache.ws.security.dom.message.WSSecHeader;
@@ -92,6 +94,8 @@ public class RequestData {
     private Collection<Pattern> subjectDNPatterns = new ArrayList<Pattern>();
     private final List<BSPRule> ignoredBSPRules = new LinkedList<BSPRule>();
     private boolean appendSignatureAfterTimestamp;
+    private AlgorithmSuite algorithmSuite;
+    private Map<QName, AlgorithmSuite> algorithmSuiteMap = Collections.emptyMap();
 
     public void clear() {
         soapConstants = null;
@@ -119,6 +123,8 @@ public class RequestData {
         subjectDNPatterns.clear();
         ignoredBSPRules.clear();
         appendSignatureAfterTimestamp = false;
+        algorithmSuite = null;
+        algorithmSuiteMap.clear();
     }
 
     public Object getMsgContext() {
@@ -559,4 +565,20 @@ public class RequestData {
         this.appendSignatureAfterTimestamp = appendSignatureAfterTimestamp;
     }
 
+    public Map<QName, AlgorithmSuite> getAlgorithmSuiteMap() {
+        return algorithmSuiteMap;
+    }
+
+    public void setAlgorithmSuiteMap(Map<QName, AlgorithmSuite> algorithmSuiteMap) {
+        this.algorithmSuiteMap = algorithmSuiteMap;
+    }
+
+    public AlgorithmSuite getAlgorithmSuite() {
+        return algorithmSuite;
+    }
+
+    public void setAlgorithmSuite(AlgorithmSuite algorithmSuite) {
+        this.algorithmSuite = algorithmSuite;
+    }
+        
 }

Modified: webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/handler/WSHandler.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/handler/WSHandler.java?rev=1412201&r1=1412200&r2=1412201&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/handler/WSHandler.java (original)
+++ webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/handler/WSHandler.java Wed Nov 21 17:18:49 2012
@@ -19,12 +19,28 @@
 
 package org.apache.ws.security.dom.handler;
 
+import java.security.cert.X509Certificate;
+import java.util.Arrays;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.regex.Pattern;
+import java.util.regex.PatternSyntaxException;
+
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+
 import org.apache.ws.security.dom.WSConstants;
 import org.apache.ws.security.dom.WSEncryptionPart;
 import org.apache.ws.security.dom.WSSConfig;
 import org.apache.ws.security.dom.WSSecurityEngine;
 import org.apache.ws.security.dom.WSSecurityEngineResult;
 import org.apache.ws.security.dom.action.Action;
+import org.apache.ws.security.common.crypto.AlgorithmSuite;
 import org.apache.ws.security.common.crypto.Crypto;
 import org.apache.ws.security.common.crypto.CryptoFactory;
 import org.apache.ws.security.common.ext.WSPasswordCallback;
@@ -36,22 +52,6 @@ import org.apache.ws.security.dom.util.S
 import org.apache.ws.security.dom.util.WSSecurityUtil;
 import org.w3c.dom.Document;
 
-import javax.security.auth.callback.Callback;
-import javax.security.auth.callback.CallbackHandler;
-
-import java.security.cert.X509Certificate;
-import java.util.Arrays;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.Properties;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.regex.Pattern;
-import java.util.regex.PatternSyntaxException;
-
-
 /**
  * Extracted from WSDoAllReceiver and WSDoAllSender
  * Extended to all passwordless UsernameTokens and configurable identities.
@@ -539,6 +539,35 @@ public abstract class WSHandler {
         reqData.setUseSingleCert(useSingleCert);
     }
 
+    protected void decodeAlgorithmSuite(RequestData reqData) throws WSSecurityException {
+        AlgorithmSuite algorithmSuite = new AlgorithmSuite();
+        
+        Object mc = reqData.getMsgContext();
+        if (mc == null) {
+            return;
+        }
+        
+        String signatureAlgorithm = getString(WSHandlerConstants.SIG_ALGO, mc);
+        if (signatureAlgorithm != null && !"".equals(signatureAlgorithm)) {
+            algorithmSuite.addSignatureMethod(signatureAlgorithm);
+        }
+        String signatureDigestAlgorithm = getString(WSHandlerConstants.SIG_DIGEST_ALGO, mc);
+        if (signatureDigestAlgorithm != null && !"".equals(signatureDigestAlgorithm)) {
+            algorithmSuite.addDigestAlgorithm(signatureDigestAlgorithm);
+        }
+        
+        String encrAlgorithm = getString(WSHandlerConstants.ENC_SYM_ALGO, mc);
+        if (encrAlgorithm != null && !"".equals(encrAlgorithm)) {
+            algorithmSuite.addEncryptionMethod(encrAlgorithm);
+        }
+        String transportAlgorithm = getString(WSHandlerConstants.ENC_KEY_TRANSPORT, mc);
+        if (transportAlgorithm != null && !"".equals(transportAlgorithm)) {
+            algorithmSuite.addKeyWrapAlgorithm(transportAlgorithm);
+        }
+        
+        reqData.setAlgorithmSuite(algorithmSuite);
+    }
+    
     protected void decodeEncryptionParameter(RequestData reqData) 
         throws WSSecurityException {
         Object mc = reqData.getMsgContext();

Modified: webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/handler/WSHandlerConstants.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/handler/WSHandlerConstants.java?rev=1412201&r1=1412200&r2=1412201&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/handler/WSHandlerConstants.java (original)
+++ webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/handler/WSHandlerConstants.java Wed Nov 21 17:18:49 2012
@@ -598,7 +598,7 @@ public final class WSHandlerConstants {
 
     /**
      * Defines which symmetric encryption algorithm to use. WSS4J supports the
-     * following alorithms: {@link WSConstants#TRIPLE_DES},
+     * following algorithms: {@link WSConstants#TRIPLE_DES},
      * {@link WSConstants#AES_128}, {@link WSConstants#AES_256},
      * and {@link WSConstants#AES_192}. Except for AES 192 all of these
      * algorithms are required by the XML Encryption specification.
@@ -612,7 +612,6 @@ public final class WSHandlerConstants {
 
     /**
      * Defines which algorithm to use to encrypt the generated symmetric key.
-     * Currently WSS4J supports {@link WSConstants#KEYTRANSPORT_RSA15} only.
      * <p/>
      * The application may set this parameter using the following method:
      * <pre>

Modified: webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/message/token/DerivedKeyToken.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/message/token/DerivedKeyToken.java?rev=1412201&r1=1412200&r2=1412201&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/message/token/DerivedKeyToken.java (original)
+++ webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/message/token/DerivedKeyToken.java Wed Nov 21 17:18:49 2012
@@ -489,6 +489,7 @@ public class DerivedKeyToken {
         principal.setLabel(getLabel());
         principal.setLength(getLength());
         principal.setOffset(getOffset());
+        principal.setAlgorithm(getAlgorithm());
         
         String basetokenId = null;
         SecurityTokenReference securityTokenReference = getSecurityTokenReference();

Modified: webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/processor/DerivedKeyTokenProcessor.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/processor/DerivedKeyTokenProcessor.java?rev=1412201&r1=1412200&r2=1412201&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/processor/DerivedKeyTokenProcessor.java (original)
+++ webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/processor/DerivedKeyTokenProcessor.java Wed Nov 21 17:18:49 2012
@@ -19,18 +19,20 @@
 
 package org.apache.ws.security.dom.processor;
 
+import java.util.List;
+
+import org.w3c.dom.Element;
+
 import org.apache.ws.security.dom.WSConstants;
 import org.apache.ws.security.dom.WSDocInfo;
 import org.apache.ws.security.dom.WSSecurityEngineResult;
+import org.apache.ws.security.common.crypto.AlgorithmSuite;
+import org.apache.ws.security.common.crypto.AlgorithmSuiteValidator;
 import org.apache.ws.security.common.ext.WSSecurityException;
 import org.apache.ws.security.dom.handler.RequestData;
 import org.apache.ws.security.dom.message.token.DerivedKeyToken;
 import org.apache.ws.security.dom.str.DerivedKeyTokenSTRParser;
 import org.apache.ws.security.dom.str.STRParser;
-import org.w3c.dom.Element;
-
-
-import java.util.List;
 
 /**
  * The processor to process <code>wsc:DerivedKeyToken</code>.
@@ -46,6 +48,17 @@ public class DerivedKeyTokenProcessor im
     ) throws WSSecurityException {
         // Deserialize the DKT
         DerivedKeyToken dkt = new DerivedKeyToken(elem, data.getBSPEnforcer());
+        
+        // Check for compliance against the defined AlgorithmSuite
+        AlgorithmSuite algorithmSuite = data.getAlgorithmSuite();
+        if (algorithmSuite != null) {
+            AlgorithmSuiteValidator algorithmSuiteValidator = new
+                AlgorithmSuiteValidator(algorithmSuite);
+            algorithmSuiteValidator.checkDerivedKeyAlgorithm(
+                dkt.getAlgorithm()
+            );
+        }
+        
         byte[] secret = null;
         Element secRefElement = dkt.getSecurityTokenReferenceElement();
         if (secRefElement != null) {

Modified: webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/processor/EncryptedDataProcessor.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/processor/EncryptedDataProcessor.java?rev=1412201&r1=1412200&r2=1412201&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/processor/EncryptedDataProcessor.java (original)
+++ webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/processor/EncryptedDataProcessor.java Wed Nov 21 17:18:49 2012
@@ -19,12 +19,28 @@
 
 package org.apache.ws.security.dom.processor;
 
+import java.security.Principal;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.crypto.SecretKey;
+import javax.xml.namespace.QName;
+
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
 import org.apache.ws.security.dom.WSConstants;
 import org.apache.ws.security.dom.WSDataRef;
+import org.apache.ws.security.dom.WSDerivedKeyTokenPrincipal;
 import org.apache.ws.security.dom.WSDocInfo;
 import org.apache.ws.security.dom.WSSConfig;
 import org.apache.ws.security.dom.WSSecurityEngineResult;
 import org.apache.ws.security.common.bsp.BSPRule;
+import org.apache.ws.security.common.crypto.AlgorithmSuite;
+import org.apache.ws.security.common.crypto.AlgorithmSuiteValidator;
 import org.apache.ws.security.common.ext.WSSecurityException;
 import org.apache.ws.security.dom.bsp.BSPEnforcer;
 import org.apache.ws.security.dom.handler.RequestData;
@@ -33,17 +49,6 @@ import org.apache.ws.security.dom.str.Se
 import org.apache.ws.security.dom.util.WSSecurityUtil;
 import org.apache.xml.security.encryption.XMLCipher;
 import org.apache.xml.security.encryption.XMLEncryptionException;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-
-import javax.crypto.SecretKey;
-import javax.xml.namespace.QName;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
 
 /**
  * This will process incoming <code>xenc:EncryptedData</code> elements.
@@ -91,6 +96,7 @@ public class EncryptedDataProcessor impl
         
         SecretKey key = null;
         List<WSSecurityEngineResult> encrKeyResults = null;
+        Principal principal = null;
         if (secRefToken != null) {
             STRParser strParser = new SecurityTokenRefSTRParser();
             Map<String, Object> parameters = new HashMap<String, Object>();
@@ -100,6 +106,7 @@ public class EncryptedDataProcessor impl
                 wsDocInfo, parameters
             );
             byte[] secretKey = strParser.getSecretKey();
+            principal = strParser.getPrincipal();
             key = WSSecurityUtil.prepareSecretKey(symEncAlgo, secretKey);
         } else if (encryptedKeyElement != null) {
             EncryptedKeyProcessor encrKeyProc = new EncryptedKeyProcessor();
@@ -113,6 +120,24 @@ public class EncryptedDataProcessor impl
             );
         }
         
+        // Check for compliance against the defined AlgorithmSuite
+        AlgorithmSuite algorithmSuite = request.getAlgorithmSuite();
+        if (algorithmSuite != null) {
+            AlgorithmSuiteValidator algorithmSuiteValidator = new
+                AlgorithmSuiteValidator(algorithmSuite);
+
+            if (principal instanceof WSDerivedKeyTokenPrincipal) {
+                algorithmSuiteValidator.checkDerivedKeyAlgorithm(
+                    ((WSDerivedKeyTokenPrincipal)principal).getAlgorithm()
+                );
+                algorithmSuiteValidator.checkEncryptionDerivedKeyLength(
+                    ((WSDerivedKeyTokenPrincipal)principal).getLength()
+                );
+            }
+            algorithmSuiteValidator.checkSymmetricKeyLength(key.getEncoded().length);
+            algorithmSuiteValidator.checkSymmetricEncryptionAlgorithm(symEncAlgo);
+        }
+        
         // initialize Cipher ....
         XMLCipher xmlCipher = null;
         try {

Modified: webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/processor/EncryptedKeyProcessor.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/processor/EncryptedKeyProcessor.java?rev=1412201&r1=1412200&r2=1412201&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/processor/EncryptedKeyProcessor.java (original)
+++ webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/processor/EncryptedKeyProcessor.java Wed Nov 21 17:18:49 2012
@@ -32,7 +32,14 @@ import javax.crypto.SecretKey;
 import javax.crypto.spec.OAEPParameterSpec;
 import javax.crypto.spec.PSource;
 
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.Text;
+
 import org.apache.ws.security.common.bsp.BSPRule;
+import org.apache.ws.security.common.crypto.AlgorithmSuite;
+import org.apache.ws.security.common.crypto.AlgorithmSuiteValidator;
 import org.apache.ws.security.common.ext.WSSecurityException;
 import org.apache.ws.security.dom.WSConstants;
 import org.apache.ws.security.dom.WSDataRef;
@@ -46,10 +53,6 @@ import org.apache.ws.security.dom.util.W
 import org.apache.xml.security.algorithms.JCEMapper;
 import org.apache.xml.security.exceptions.Base64DecodingException;
 import org.apache.xml.security.utils.Base64;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-import org.w3c.dom.Text;
 
 public class EncryptedKeyProcessor implements Processor {
     private static org.apache.commons.logging.Log log = 
@@ -60,6 +63,15 @@ public class EncryptedKeyProcessor imple
         RequestData data,
         WSDocInfo wsDocInfo
     ) throws WSSecurityException {
+        return handleToken(elem, data, wsDocInfo, data.getAlgorithmSuite());
+    }
+    
+    public List<WSSecurityEngineResult> handleToken(
+        Element elem, 
+        RequestData data,
+        WSDocInfo wsDocInfo,
+        AlgorithmSuite algorithmSuite
+    ) throws WSSecurityException {
         if (log.isDebugEnabled()) {
             log.debug("Found encrypted key element");
         }
@@ -104,6 +116,17 @@ public class EncryptedKeyProcessor imple
         X509Certificate[] certs = 
             getCertificatesFromEncryptedKey(elem, data, wsDocInfo, strParser);
 
+        // Check for compliance against the defined AlgorithmSuite
+        if (algorithmSuite != null) {
+            AlgorithmSuiteValidator algorithmSuiteValidator = new
+                AlgorithmSuiteValidator(algorithmSuite);
+
+            algorithmSuiteValidator.checkAsymmetricKeyLength(certs[0]);
+            algorithmSuiteValidator.checkEncryptionKeyWrapAlgorithm(
+                encryptedKeyTransportMethod
+            );
+        }
+        
         try {
             PrivateKey privateKey = data.getDecCrypto().getPrivateKey(certs[0], data.getCallbackHandler());
             OAEPParameterSpec oaepParameterSpec = null;
@@ -377,7 +400,8 @@ public class EncryptedKeyProcessor imple
         }
         List<WSDataRef> dataRefs = new ArrayList<WSDataRef>();
         for (String dataRefURI : dataRefURIs) {
-            WSDataRef dataRef = decryptDataRef(doc, dataRefURI, docInfo, decryptedBytes, data);
+            WSDataRef dataRef = 
+                decryptDataRef(doc, dataRefURI, docInfo, decryptedBytes, data);
             dataRefs.add(dataRef);
         }
         return dataRefs;
@@ -417,6 +441,16 @@ public class EncryptedKeyProcessor imple
                 ex, new Object[]{symEncAlgo}
             );
         }
+        
+        // Check for compliance against the defined AlgorithmSuite
+        AlgorithmSuite algorithmSuite = data.getAlgorithmSuite();
+        if (algorithmSuite != null) {
+            AlgorithmSuiteValidator algorithmSuiteValidator = new
+                AlgorithmSuiteValidator(algorithmSuite);
+
+            algorithmSuiteValidator.checkSymmetricKeyLength(symmetricKey.getEncoded().length);
+            algorithmSuiteValidator.checkSymmetricEncryptionAlgorithm(symEncAlgo);
+        }
 
         return ReferenceListProcessor.decryptEncryptedData(
             doc, dataRefURI, encryptedDataElement, symmetricKey, symEncAlgo

Modified: webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/processor/ReferenceListProcessor.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/processor/ReferenceListProcessor.java?rev=1412201&r1=1412200&r2=1412201&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/processor/ReferenceListProcessor.java (original)
+++ webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/processor/ReferenceListProcessor.java Wed Nov 21 17:18:49 2012
@@ -19,6 +19,7 @@
 
 package org.apache.ws.security.dom.processor;
 
+import java.security.Principal;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
@@ -26,11 +27,19 @@ import java.util.Map;
 
 import javax.crypto.SecretKey;
 
+import org.w3c.dom.Attr;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
 import org.apache.ws.security.dom.WSConstants;
 import org.apache.ws.security.dom.WSDataRef;
+import org.apache.ws.security.dom.WSDerivedKeyTokenPrincipal;
 import org.apache.ws.security.dom.WSDocInfo;
 import org.apache.ws.security.dom.WSSecurityEngineResult;
 import org.apache.ws.security.common.bsp.BSPRule;
+import org.apache.ws.security.common.crypto.AlgorithmSuite;
+import org.apache.ws.security.common.crypto.AlgorithmSuiteValidator;
 import org.apache.ws.security.common.ext.WSSecurityException;
 import org.apache.ws.security.dom.bsp.BSPEnforcer;
 import org.apache.ws.security.dom.handler.RequestData;
@@ -40,12 +49,9 @@ import org.apache.ws.security.dom.messag
 import org.apache.ws.security.dom.str.STRParser;
 import org.apache.ws.security.dom.str.SecurityTokenRefSTRParser;
 import org.apache.ws.security.dom.util.WSSecurityUtil;
+
 import org.apache.xml.security.encryption.XMLCipher;
 import org.apache.xml.security.encryption.XMLEncryptionException;
-import org.w3c.dom.Attr;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
 
 public class ReferenceListProcessor implements Processor {
     private static org.apache.commons.logging.Log log = 
@@ -156,6 +162,7 @@ public class ReferenceListProcessor impl
                 keyInfoElement, "SecurityTokenReference", WSConstants.WSSE_NS
             );
         SecretKey symmetricKey = null;
+        Principal principal = null;
         if (secRefToken == null) {
             symmetricKey = X509Util.getSharedKey(keyInfoElement, symEncAlgo, data.getCallbackHandler());
         } else {
@@ -167,9 +174,29 @@ public class ReferenceListProcessor impl
                 wsDocInfo, parameters
             );
             byte[] secretKey = strParser.getSecretKey();
+            principal = strParser.getPrincipal();
             symmetricKey = WSSecurityUtil.prepareSecretKey(symEncAlgo, secretKey);
         }
         
+        // Check for compliance against the defined AlgorithmSuite
+        AlgorithmSuite algorithmSuite = data.getAlgorithmSuite();
+        if (algorithmSuite != null) {
+            AlgorithmSuiteValidator algorithmSuiteValidator = new
+                AlgorithmSuiteValidator(algorithmSuite);
+
+            if (principal instanceof WSDerivedKeyTokenPrincipal) {
+                algorithmSuiteValidator.checkDerivedKeyAlgorithm(
+                    ((WSDerivedKeyTokenPrincipal)principal).getAlgorithm()
+                );
+                algorithmSuiteValidator.checkEncryptionDerivedKeyLength(
+                    ((WSDerivedKeyTokenPrincipal)principal).getLength()
+                );
+            }
+
+            algorithmSuiteValidator.checkSymmetricKeyLength(symmetricKey.getEncoded().length);
+            algorithmSuiteValidator.checkSymmetricEncryptionAlgorithm(symEncAlgo);
+        }
+
         return 
             decryptEncryptedData(
                 doc, dataRefURI, encryptedDataElement, symmetricKey, symEncAlgo

Modified: webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/processor/SAMLTokenProcessor.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/processor/SAMLTokenProcessor.java?rev=1412201&r1=1412200&r2=1412201&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/processor/SAMLTokenProcessor.java (original)
+++ webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/processor/SAMLTokenProcessor.java Wed Nov 21 17:18:49 2012
@@ -19,27 +19,56 @@
 
 package org.apache.ws.security.dom.processor;
 
+import java.security.NoSuchProviderException;
+import java.security.PublicKey;
+import java.util.List;
+
+import javax.xml.crypto.MarshalException;
+import javax.xml.crypto.dsig.XMLSignature;
+import javax.xml.crypto.dsig.XMLSignatureFactory;
+import javax.xml.crypto.dsig.XMLValidateContext;
+import javax.xml.crypto.dsig.dom.DOMValidateContext;
+import javax.xml.namespace.QName;
+
+import org.w3c.dom.Element;
+
 import org.apache.ws.security.dom.SAMLTokenPrincipal;
 import org.apache.ws.security.dom.WSConstants;
 import org.apache.ws.security.dom.WSDocInfo;
+import org.apache.ws.security.dom.WSSecurityEngine;
 import org.apache.ws.security.dom.WSSecurityEngineResult;
+import org.apache.ws.security.common.crypto.AlgorithmSuite;
+import org.apache.ws.security.common.crypto.AlgorithmSuiteValidator;
 import org.apache.ws.security.common.ext.WSSecurityException;
 import org.apache.ws.security.common.saml.AssertionWrapper;
+import org.apache.ws.security.common.saml.SAMLKeyInfo;
+import org.apache.ws.security.common.saml.SAMLUtil;
 import org.apache.ws.security.common.util.DOM2Writer;
 import org.apache.ws.security.dom.handler.RequestData;
 import org.apache.ws.security.dom.saml.WSSSAMLKeyInfoProcessor;
 import org.apache.ws.security.dom.validate.Credential;
 import org.apache.ws.security.dom.validate.Validator;
 
-import org.w3c.dom.Element;
-
-import java.util.List;
-import javax.xml.namespace.QName;
+import org.opensaml.security.SAMLSignatureProfileValidator;
+import org.opensaml.xml.signature.KeyInfo;
+import org.opensaml.xml.signature.Signature;
+import org.opensaml.xml.validation.ValidationException;
 
 public class SAMLTokenProcessor implements Processor {
     private static org.apache.commons.logging.Log log = 
         org.apache.commons.logging.LogFactory.getLog(SAMLTokenProcessor.class);
-    
+    private XMLSignatureFactory signatureFactory;
+
+    public SAMLTokenProcessor() {
+        // Try to install the Santuario Provider - fall back to the JDK provider if this does
+        // not work
+        try {
+            signatureFactory = XMLSignatureFactory.getInstance("DOM", "ApacheXMLDSig");
+        } catch (NoSuchProviderException ex) {
+            signatureFactory = XMLSignatureFactory.getInstance("DOM");
+        }
+    }
+
     public List<WSSecurityEngineResult> handleToken(
         Element elem, 
         RequestData data, 
@@ -107,9 +136,68 @@ public class SAMLTokenProcessor implemen
     ) throws WSSecurityException {
         AssertionWrapper assertion = new AssertionWrapper(token);
         if (assertion.isSigned()) {
-            assertion.verifySignature(
-                new WSSSAMLKeyInfoProcessor(data, docInfo), data.getSigVerCrypto()
-            );
+            Signature sig = assertion.getSignature();
+
+            SAMLSignatureProfileValidator profileValidator = new SAMLSignatureProfileValidator();
+            try {
+                profileValidator.validate(sig);
+            } catch (ValidationException ex) {
+                throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE,
+                                              "empty", ex, "SAML signature validation failed");
+            }
+            
+            // Check for compliance against the defined AlgorithmSuite
+            AlgorithmSuite algorithmSuite = null;
+            if (assertion.getSaml2() != null) {
+                algorithmSuite = data.getAlgorithmSuiteMap().get(WSSecurityEngine.SAML2_TOKEN);
+            } else {
+                algorithmSuite = data.getAlgorithmSuiteMap().get(WSSecurityEngine.SAML_TOKEN);
+            }
+            
+            KeyInfo keyInfo = sig.getKeyInfo();
+            SAMLKeyInfo samlKeyInfo = 
+                SAMLUtil.getCredentialFromKeyInfo(
+                    keyInfo.getDOM(), 
+                    new WSSSAMLKeyInfoProcessor(data, docInfo),
+                    data.getSigVerCrypto()
+                );
+            
+            if (algorithmSuite != null) {
+                AlgorithmSuiteValidator algorithmSuiteValidator = new
+                    AlgorithmSuiteValidator(algorithmSuite);
+
+                PublicKey key = null;
+                if (samlKeyInfo.getCerts() != null && samlKeyInfo.getCerts()[0] != null) {
+                    key = samlKeyInfo.getCerts()[0].getPublicKey();
+                } else if (samlKeyInfo.getPublicKey() != null) {
+                    key = samlKeyInfo.getPublicKey();
+                } else {
+                    throw new WSSecurityException(
+                        WSSecurityException.ErrorCode.FAILURE, "invalidSAMLsecurity",
+                        new Object[]{"cannot get certificate or key"}
+                    );
+                }
+            
+                // Not checking signature here, just marshalling into an XMLSignature
+                // structure for testing the transform/digest algorithms etc.
+                XMLValidateContext context = new DOMValidateContext(key, sig.getDOM());
+                context.setProperty("org.apache.jcp.xml.dsig.secureValidation", Boolean.TRUE);
+
+                XMLSignature xmlSignature;
+                try {
+                    xmlSignature = signatureFactory.unmarshalXMLSignature(context);
+                } catch (MarshalException ex) {
+                    throw new WSSecurityException(
+                        WSSecurityException.ErrorCode.FAILED_CHECK, "invalidSAMLsecurity", 
+                        new Object[]{"cannot get certificate or key"}, ex
+                    );
+                }
+
+                algorithmSuiteValidator.checkSignatureAlgorithms(xmlSignature);
+                algorithmSuiteValidator.checkAsymmetricKeyLength(key);
+            }
+
+            assertion.verifySignature(samlKeyInfo);
         }
         // Parse the HOK subject if it exists
         assertion.parseHOKSubject( 

Modified: webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/processor/SignatureProcessor.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/processor/SignatureProcessor.java?rev=1412201&r1=1412200&r2=1412201&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/processor/SignatureProcessor.java (original)
+++ webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/processor/SignatureProcessor.java Wed Nov 21 17:18:49 2012
@@ -52,13 +52,20 @@ import javax.xml.crypto.dsig.keyinfo.Key
 import javax.xml.crypto.dsig.spec.ExcC14NParameterSpec;
 import javax.xml.crypto.dsig.spec.HMACParameterSpec;
 
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
 import org.apache.ws.security.common.bsp.BSPRule;
+import org.apache.ws.security.common.crypto.AlgorithmSuite;
+import org.apache.ws.security.common.crypto.AlgorithmSuiteValidator;
 import org.apache.ws.security.common.crypto.Crypto;
 import org.apache.ws.security.common.crypto.CryptoType;
 import org.apache.ws.security.common.ext.WSSecurityException;
 import org.apache.ws.security.dom.PublicKeyPrincipal;
 import org.apache.ws.security.dom.WSConstants;
 import org.apache.ws.security.dom.WSDataRef;
+import org.apache.ws.security.dom.WSDerivedKeyTokenPrincipal;
 import org.apache.ws.security.dom.WSDocInfo;
 import org.apache.ws.security.dom.WSSecurityEngine;
 import org.apache.ws.security.dom.WSSecurityEngineResult;
@@ -79,9 +86,6 @@ import org.apache.ws.security.dom.util.W
 import org.apache.ws.security.dom.util.XmlSchemaDateFormat;
 import org.apache.ws.security.dom.validate.Credential;
 import org.apache.ws.security.dom.validate.Validator;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
 
 public class SignatureProcessor implements Processor {
     private static final org.apache.commons.logging.Log LOG = 
@@ -197,6 +201,35 @@ public class SignatureProcessor implemen
             throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_CHECK);
         }
         
+        // Check for compliance against the defined AlgorithmSuite
+        AlgorithmSuite algorithmSuite = data.getAlgorithmSuite();
+        if (algorithmSuite != null ) {
+            AlgorithmSuiteValidator algorithmSuiteValidator = new
+                AlgorithmSuiteValidator(algorithmSuite);
+
+            if (principal instanceof WSDerivedKeyTokenPrincipal) {
+                algorithmSuiteValidator.checkDerivedKeyAlgorithm(
+                    ((WSDerivedKeyTokenPrincipal)principal).getAlgorithm()
+                );
+                algorithmSuiteValidator.checkSignatureDerivedKeyLength(
+                    ((WSDerivedKeyTokenPrincipal)principal).getLength()
+                );
+            } else {
+                Key key = null;
+                if (certs != null && certs[0] != null) {
+                    key = certs[0].getPublicKey();
+                } else if (publicKey != null) {
+                    key = publicKey;
+                }
+
+                if (key instanceof PublicKey) {
+                    algorithmSuiteValidator.checkAsymmetricKeyLength((PublicKey)key);
+                } else {
+                    algorithmSuiteValidator.checkSymmetricKeyLength(secretKey.length);
+                }
+            }
+        }
+        
         XMLSignature xmlSignature = 
             verifyXMLSignature(elem, certs, publicKey, secretKey, signatureMethod, data, wsDocInfo);
         byte[] signatureValue = xmlSignature.getSignatureValue().getValue();
@@ -371,6 +404,14 @@ public class SignatureProcessor implemen
             XMLSignature xmlSignature = signatureFactory.unmarshalXMLSignature(context);
             checkBSPCompliance(xmlSignature, data.getBSPEnforcer());
             
+            // Check for compliance against the defined AlgorithmSuite
+            AlgorithmSuite algorithmSuite = data.getAlgorithmSuite();
+            if (algorithmSuite != null) {
+                AlgorithmSuiteValidator algorithmSuiteValidator = new
+                    AlgorithmSuiteValidator(algorithmSuite);
+                algorithmSuiteValidator.checkSignatureAlgorithms(xmlSignature);
+            }
+            
             // Test for replay attacks
             testMessageReplay(elem, xmlSignature.getSignatureValue().getValue(), data, wsDocInfo);
             

Modified: webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/str/SecurityTokenRefSTRParser.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/str/SecurityTokenRefSTRParser.java?rev=1412201&r1=1412200&r2=1412201&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/str/SecurityTokenRefSTRParser.java (original)
+++ webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/ws/security/dom/str/SecurityTokenRefSTRParser.java Wed Nov 21 17:18:49 2012
@@ -61,6 +61,7 @@ public class SecurityTokenRefSTRParser i
     public static final String SIGNATURE_METHOD = "signature_method";
     
     private byte[] secretKey;
+    private Principal principal;
     
     /**
      * Parse a SecurityTokenReference element and extract credentials.
@@ -190,7 +191,7 @@ public class SecurityTokenRefSTRParser i
      * @return the Principal associated with this SecurityTokenReference
      */
     public Principal getPrincipal() {
-        return null;
+        return principal;
     }
     
     /**
@@ -307,6 +308,7 @@ public class SecurityTokenRefSTRParser i
                 (byte[])result.get(WSSecurityEngineResult.TAG_SECRET);
             String algorithm = (String)parameters.get(SIGNATURE_METHOD);
             secretKey = dkt.deriveKey(WSSecurityUtil.getKeyLength(algorithm), secret);
+            principal = dkt.createPrincipal();
         } else if (WSConstants.ST_UNSIGNED == action || WSConstants.ST_SIGNED == action) {
             AssertionWrapper assertion = 
                 (AssertionWrapper)result.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);

Added: webservices/wss4j/trunk/ws-security-dom/src/test/java/org/apache/ws/security/dom/message/EncryptionAlgorithmSuiteTest.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-dom/src/test/java/org/apache/ws/security/dom/message/EncryptionAlgorithmSuiteTest.java?rev=1412201&view=auto
==============================================================================
--- webservices/wss4j/trunk/ws-security-dom/src/test/java/org/apache/ws/security/dom/message/EncryptionAlgorithmSuiteTest.java (added)
+++ webservices/wss4j/trunk/ws-security-dom/src/test/java/org/apache/ws/security/dom/message/EncryptionAlgorithmSuiteTest.java Wed Nov 21 17:18:49 2012
@@ -0,0 +1,253 @@
+/**
+ * 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.ws.security.dom.message;
+
+import java.util.List;
+
+import javax.crypto.KeyGenerator;
+import javax.crypto.SecretKey;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import org.apache.ws.security.common.crypto.AlgorithmSuite;
+import org.apache.ws.security.common.crypto.Crypto;
+import org.apache.ws.security.common.crypto.CryptoFactory;
+import org.apache.ws.security.common.ext.WSSecurityException;
+import org.apache.ws.security.common.util.XMLUtils;
+import org.apache.ws.security.dom.WSConstants;
+import org.apache.ws.security.dom.WSSConfig;
+import org.apache.ws.security.dom.WSSecurityEngine;
+import org.apache.ws.security.dom.WSSecurityEngineResult;
+import org.apache.ws.security.dom.common.KeystoreCallbackHandler;
+import org.apache.ws.security.dom.common.SOAPUtil;
+import org.apache.ws.security.dom.common.SecretKeyCallbackHandler;
+import org.apache.ws.security.dom.handler.RequestData;
+import org.apache.ws.security.dom.util.WSSecurityUtil;
+import org.apache.xml.security.utils.Base64;
+
+/**
+ * A set of test-cases for encrypting and decrypting SOAP requests when specifying an 
+ * AlgorithmSuite policy.
+ */
+public class EncryptionAlgorithmSuiteTest extends org.junit.Assert {
+    private static final org.apache.commons.logging.Log LOG = 
+        org.apache.commons.logging.LogFactory.getLog(EncryptionAlgorithmSuiteTest.class);
+    
+    private Crypto crypto = null;
+    
+    public EncryptionAlgorithmSuiteTest() throws Exception {
+        WSSConfig.init();
+        crypto = CryptoFactory.getInstance();
+    }
+
+    @org.junit.Test
+    public void testEncryption() throws Exception {
+        WSSecEncrypt builder = new WSSecEncrypt();
+        builder.setUserInfo("16c73ab6-b892-458f-abf5-2f875f74882e");
+        builder.setKeyIdentifierType(WSConstants.BST_DIRECT_REFERENCE);
+        builder.setSymmetricEncAlgorithm(WSConstants.TRIPLE_DES);
+        
+        Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
+        WSSecHeader secHeader = new WSSecHeader();
+        secHeader.insertSecurityHeader(doc);
+        
+        Document encryptedDoc = builder.build(doc, crypto, secHeader);
+
+        if (LOG.isDebugEnabled()) {
+            String outputString = 
+                XMLUtils.PrettyDocumentToString(encryptedDoc);
+            LOG.debug(outputString);
+        }
+        
+        Element securityHeader = WSSecurityUtil.getSecurityHeader(encryptedDoc, null);
+        AlgorithmSuite algorithmSuite = createAlgorithmSuite();
+        
+        verify(securityHeader, algorithmSuite, crypto);
+        
+        algorithmSuite.setMinimumAsymmetricKeyLength(1024);
+        
+        try {
+            verify(securityHeader, algorithmSuite, crypto);
+            fail("Expected failure as 512-bit keys are not allowed");
+        } catch (WSSecurityException ex) {
+            // expected
+        }
+    }
+    
+    @org.junit.Test
+    public void testEncryptionKeyTransportRSAOAEP() throws Exception {
+        
+        Crypto wssCrypto = CryptoFactory.getInstance("wss40.properties");
+        
+        WSSecEncrypt builder = new WSSecEncrypt();
+        builder.setUserInfo("wss40");
+        builder.setKeyIdentifierType(WSConstants.BST_DIRECT_REFERENCE);
+        builder.setSymmetricEncAlgorithm(WSConstants.TRIPLE_DES);
+        builder.setKeyEncAlgo(WSConstants.KEYTRANSPORT_RSAOEP);
+        
+        Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
+        WSSecHeader secHeader = new WSSecHeader();
+        secHeader.insertSecurityHeader(doc);
+        
+        Document encryptedDoc = builder.build(doc, wssCrypto, secHeader);
+
+        if (LOG.isDebugEnabled()) {
+            String outputString = 
+                XMLUtils.PrettyDocumentToString(encryptedDoc);
+            LOG.debug(outputString);
+        }
+        
+        Element securityHeader = WSSecurityUtil.getSecurityHeader(encryptedDoc, null);
+        AlgorithmSuite algorithmSuite = createAlgorithmSuite();
+        
+        try {
+            verify(securityHeader, algorithmSuite, wssCrypto);
+            fail("Expected failure as RSA OAEP is not allowed");
+        } catch (WSSecurityException ex) {
+            // expected
+        }
+        
+        algorithmSuite.addKeyWrapAlgorithm(WSConstants.KEYTRANSPORT_RSAOEP);
+        verify(securityHeader, algorithmSuite, wssCrypto);
+    }
+    
+    @org.junit.Test
+    public void testEncryptionMethodAES128() throws Exception {
+        
+        Crypto wssCrypto = CryptoFactory.getInstance("wss40.properties");
+        
+        WSSecEncrypt builder = new WSSecEncrypt();
+        builder.setUserInfo("wss40");
+        builder.setKeyIdentifierType(WSConstants.BST_DIRECT_REFERENCE);
+        builder.setSymmetricEncAlgorithm(WSConstants.AES_128);
+        
+        Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
+        WSSecHeader secHeader = new WSSecHeader();
+        secHeader.insertSecurityHeader(doc);
+        
+        Document encryptedDoc = builder.build(doc, wssCrypto, secHeader);
+
+        if (LOG.isDebugEnabled()) {
+            String outputString = 
+                XMLUtils.PrettyDocumentToString(encryptedDoc);
+            LOG.debug(outputString);
+        }
+        
+        Element securityHeader = WSSecurityUtil.getSecurityHeader(encryptedDoc, null);
+        AlgorithmSuite algorithmSuite = createAlgorithmSuite();
+        
+        try {
+            verify(securityHeader, algorithmSuite, wssCrypto);
+            fail("Expected failure as AES 128 is not allowed");
+        } catch (WSSecurityException ex) {
+            // expected
+        }
+        
+        algorithmSuite.addEncryptionMethod(WSConstants.AES_128);
+        verify(securityHeader, algorithmSuite, wssCrypto);
+    }
+    
+    @org.junit.Test
+    public void testSymmetricEncryption() throws Exception {
+        
+        KeyGenerator keyGen = KeyGenerator.getInstance("AES");
+        keyGen.init(128);
+        SecretKey key = keyGen.generateKey();
+        byte[] keyData = key.getEncoded();
+        
+        WSSecEncrypt builder = new WSSecEncrypt();
+        builder.setKeyIdentifierType(WSConstants.ENCRYPTED_KEY_SHA1_IDENTIFIER);
+        builder.setSymmetricKey(key);
+        builder.setEncryptSymmKey(false);
+        
+        Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
+        WSSecHeader secHeader = new WSSecHeader();
+        secHeader.insertSecurityHeader(doc);
+        
+        Document encryptedDoc = builder.build(doc, crypto, secHeader);
+
+        if (LOG.isDebugEnabled()) {
+            String outputString = 
+                XMLUtils.PrettyDocumentToString(encryptedDoc);
+            LOG.debug(outputString);
+        }
+        
+        byte[] encodedBytes = WSSecurityUtil.generateDigest(keyData);
+        String identifier = Base64.encode(encodedBytes);
+        SecretKeyCallbackHandler secretKeyCallbackHandler = new SecretKeyCallbackHandler();
+        secretKeyCallbackHandler.addSecretKey(identifier, keyData);
+        
+        Element securityHeader = WSSecurityUtil.getSecurityHeader(encryptedDoc, null);
+        AlgorithmSuite algorithmSuite = createAlgorithmSuite();
+        
+        WSSecurityEngine secEngine = new WSSecurityEngine();
+        RequestData data = new RequestData();
+        data.setDecCrypto(crypto);
+        data.setCallbackHandler(secretKeyCallbackHandler);
+        
+        data.setAlgorithmSuite(algorithmSuite);
+        
+        algorithmSuite.addEncryptionMethod(WSConstants.AES_128);
+        secEngine.processSecurityHeader(securityHeader, data);
+        
+        algorithmSuite.setMinimumSymmetricKeyLength(256);
+        try {
+            secEngine.processSecurityHeader(securityHeader, data);
+            fail("Expected failure as a 128 bit key is not allowed");
+        } catch (WSSecurityException ex) {
+            // expected
+        }
+        
+        algorithmSuite.setMinimumSymmetricKeyLength(64);
+        algorithmSuite.setMaximumSymmetricKeyLength(120);
+        try {
+            secEngine.processSecurityHeader(securityHeader, data);
+            fail("Expected failure as a 128 bit key is not allowed");
+        } catch (WSSecurityException ex) {
+            // expected
+        }
+    }
+    
+    
+    private AlgorithmSuite createAlgorithmSuite() {
+        AlgorithmSuite algorithmSuite = new AlgorithmSuite();
+        algorithmSuite.setMinimumAsymmetricKeyLength(512);
+        algorithmSuite.addKeyWrapAlgorithm(WSConstants.KEYTRANSPORT_RSA15);
+        algorithmSuite.addEncryptionMethod(WSConstants.TRIPLE_DES);
+        
+        return algorithmSuite;
+    }
+
+    private List<WSSecurityEngineResult> verify(
+        Element securityHeader, AlgorithmSuite algorithmSuite, Crypto decCrypto
+    ) throws Exception {
+        WSSecurityEngine secEngine = new WSSecurityEngine();
+        RequestData data = new RequestData();
+        data.setDecCrypto(decCrypto);
+        
+        data.setAlgorithmSuite(algorithmSuite);
+        
+        data.setCallbackHandler(new KeystoreCallbackHandler());
+        
+        return secEngine.processSecurityHeader(securityHeader, data);
+    }
+
+}

Added: webservices/wss4j/trunk/ws-security-dom/src/test/java/org/apache/ws/security/dom/message/SignatureAlgorithmSuiteTest.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-dom/src/test/java/org/apache/ws/security/dom/message/SignatureAlgorithmSuiteTest.java?rev=1412201&view=auto
==============================================================================
--- webservices/wss4j/trunk/ws-security-dom/src/test/java/org/apache/ws/security/dom/message/SignatureAlgorithmSuiteTest.java (added)
+++ webservices/wss4j/trunk/ws-security-dom/src/test/java/org/apache/ws/security/dom/message/SignatureAlgorithmSuiteTest.java Wed Nov 21 17:18:49 2012
@@ -0,0 +1,289 @@
+/**
+ * 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.ws.security.dom.message;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.crypto.KeyGenerator;
+import javax.crypto.SecretKey;
+import javax.xml.crypto.dsig.SignatureMethod;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import org.apache.ws.security.common.bsp.BSPRule;
+import org.apache.ws.security.common.crypto.AlgorithmSuite;
+import org.apache.ws.security.common.crypto.Crypto;
+import org.apache.ws.security.common.crypto.CryptoFactory;
+import org.apache.ws.security.common.ext.WSSecurityException;
+import org.apache.ws.security.common.util.XMLUtils;
+import org.apache.ws.security.dom.WSConstants;
+import org.apache.ws.security.dom.WSSConfig;
+import org.apache.ws.security.dom.WSSecurityEngine;
+import org.apache.ws.security.dom.WSSecurityEngineResult;
+import org.apache.ws.security.dom.common.SOAPUtil;
+import org.apache.ws.security.dom.common.SecretKeyCallbackHandler;
+import org.apache.ws.security.dom.handler.RequestData;
+import org.apache.ws.security.dom.util.WSSecurityUtil;
+import org.apache.xml.security.utils.Base64;
+
+/**
+ * A set of test-cases for signing and verifying SOAP requests when specifying an 
+ * AlgorithmSuite policy.
+ */
+public class SignatureAlgorithmSuiteTest extends org.junit.Assert {
+    private static final org.apache.commons.logging.Log LOG = 
+        org.apache.commons.logging.LogFactory.getLog(SignatureAlgorithmSuiteTest.class);
+    
+    private Crypto crypto = null;
+    
+    public SignatureAlgorithmSuiteTest() throws Exception {
+        WSSConfig.init();
+        crypto = CryptoFactory.getInstance();
+    }
+
+    @org.junit.Test
+    public void testSignature() throws Exception {
+        WSSecSignature builder = new WSSecSignature();
+        builder.setUserInfo("16c73ab6-b892-458f-abf5-2f875f74882e", "security");
+        builder.setKeyIdentifierType(WSConstants.ISSUER_SERIAL);
+        builder.setSignatureAlgorithm(WSConstants.RSA_SHA1);
+
+        Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
+        WSSecHeader secHeader = new WSSecHeader();
+        secHeader.insertSecurityHeader(doc);
+        Document signedDoc = builder.build(doc, crypto, secHeader);
+
+        if (LOG.isDebugEnabled()) {
+            String outputString = 
+                XMLUtils.PrettyDocumentToString(signedDoc);
+            LOG.debug(outputString);
+        }
+        
+        Element securityHeader = WSSecurityUtil.getSecurityHeader(signedDoc, null);
+        AlgorithmSuite algorithmSuite = createAlgorithmSuite();
+        
+        verify(securityHeader, algorithmSuite, crypto);
+        
+        algorithmSuite.setMinimumAsymmetricKeyLength(1024);
+        
+        try {
+            verify(securityHeader, algorithmSuite, crypto);
+            fail("Expected failure as 512-bit keys are not allowed");
+        } catch (WSSecurityException ex) {
+            // expected
+        }
+    }
+    
+    @org.junit.Test
+    public void testSignatureMethodDSA() throws Exception {
+        Crypto dsaCrypto = CryptoFactory.getInstance("wss40.properties");
+        
+        WSSecSignature builder = new WSSecSignature();
+        builder.setUserInfo("wss40DSA", "security");
+        builder.setKeyIdentifierType(WSConstants.ISSUER_SERIAL);
+        builder.setSignatureAlgorithm(WSConstants.DSA);
+
+        Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
+        WSSecHeader secHeader = new WSSecHeader();
+        secHeader.insertSecurityHeader(doc);
+        Document signedDoc = builder.build(doc, dsaCrypto, secHeader);
+
+        if (LOG.isDebugEnabled()) {
+            String outputString = 
+                XMLUtils.PrettyDocumentToString(signedDoc);
+            LOG.debug(outputString);
+        }
+        
+        Element securityHeader = WSSecurityUtil.getSecurityHeader(signedDoc, null);
+        AlgorithmSuite algorithmSuite = createAlgorithmSuite();
+        
+        try {
+            verify(securityHeader, algorithmSuite, dsaCrypto);
+            fail("Expected failure as DSA is not allowed");
+        } catch (WSSecurityException ex) {
+            // expected
+        }
+        
+        algorithmSuite.addSignatureMethod(WSConstants.DSA);
+        verify(securityHeader, algorithmSuite, dsaCrypto);
+    }
+    
+    @org.junit.Test
+    public void testSymmetricKey() throws Exception {
+        
+        KeyGenerator keyGen = KeyGenerator.getInstance("AES");
+        keyGen.init(128);
+        SecretKey key = keyGen.generateKey();
+        byte[] keyData = key.getEncoded();
+        
+        WSSecSignature builder = new WSSecSignature();
+        builder.setKeyIdentifierType(WSConstants.ENCRYPTED_KEY_SHA1_IDENTIFIER);
+        builder.setSecretKey(keyData);
+        builder.setSignatureAlgorithm(SignatureMethod.HMAC_SHA1);
+        
+        Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
+        WSSecHeader secHeader = new WSSecHeader();
+        secHeader.insertSecurityHeader(doc);
+        Document signedDoc = builder.build(doc, crypto, secHeader);
+
+        if (LOG.isDebugEnabled()) {
+            String outputString = 
+                XMLUtils.PrettyDocumentToString(signedDoc);
+            LOG.debug(outputString);
+        }
+        
+        byte[] encodedBytes = WSSecurityUtil.generateDigest(keyData);
+        String identifier = Base64.encode(encodedBytes);
+        SecretKeyCallbackHandler secretKeyCallbackHandler = new SecretKeyCallbackHandler();
+        secretKeyCallbackHandler.addSecretKey(identifier, keyData);
+        
+        Element securityHeader = WSSecurityUtil.getSecurityHeader(signedDoc, null);
+        AlgorithmSuite algorithmSuite = createAlgorithmSuite();
+        
+        WSSecurityEngine secEngine = new WSSecurityEngine();
+        RequestData data = new RequestData();
+        data.setSigCrypto(crypto);
+        data.setCallbackHandler(secretKeyCallbackHandler);
+        data.setAlgorithmSuite(algorithmSuite);
+        
+        try {
+            secEngine.processSecurityHeader(securityHeader, data);
+            fail("Expected failure as HMAC-SHA1 is not allowed");
+        } catch (WSSecurityException ex) {
+            // expected
+        }
+        
+        algorithmSuite.addSignatureMethod(WSConstants.HMAC_SHA1);
+        secEngine.processSecurityHeader(securityHeader, data);
+        
+        algorithmSuite.setMinimumSymmetricKeyLength(256);
+        try {
+            secEngine.processSecurityHeader(securityHeader, data);
+            fail("Expected failure as a 128 bit key is not allowed");
+        } catch (WSSecurityException ex) {
+            // expected
+        }
+        
+        algorithmSuite.setMinimumSymmetricKeyLength(64);
+        algorithmSuite.setMaximumSymmetricKeyLength(120);
+        try {
+            secEngine.processSecurityHeader(securityHeader, data);
+            fail("Expected failure as a 128 bit key is not allowed");
+        } catch (WSSecurityException ex) {
+            // expected
+        }
+    }
+    
+    @org.junit.Test
+    public void testC14nMethod() throws Exception {
+        WSSecSignature builder = new WSSecSignature();
+        builder.setUserInfo("16c73ab6-b892-458f-abf5-2f875f74882e", "security");
+        builder.setKeyIdentifierType(WSConstants.ISSUER_SERIAL);
+        builder.setSignatureAlgorithm(WSConstants.RSA_SHA1);
+        builder.setSigCanonicalization(WSConstants.C14N_EXCL_WITH_COMMENTS);
+
+        Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
+        WSSecHeader secHeader = new WSSecHeader();
+        secHeader.insertSecurityHeader(doc);
+        Document signedDoc = builder.build(doc, crypto, secHeader);
+
+        if (LOG.isDebugEnabled()) {
+            String outputString = 
+                XMLUtils.PrettyDocumentToString(signedDoc);
+            LOG.debug(outputString);
+        }
+
+        Element securityHeader = WSSecurityUtil.getSecurityHeader(signedDoc, null);
+        AlgorithmSuite algorithmSuite = createAlgorithmSuite();
+        
+        try {
+            verify(securityHeader, algorithmSuite, crypto);
+            fail("Expected failure as C14n algorithm is not allowed");
+        } catch (WSSecurityException ex) {
+            // expected
+        }
+        
+        algorithmSuite.addC14nAlgorithm(WSConstants.C14N_EXCL_WITH_COMMENTS);
+        verify(securityHeader, algorithmSuite, crypto);
+    }
+    
+    @org.junit.Test
+    public void testDigestMethod() throws Exception {
+        WSSecSignature builder = new WSSecSignature();
+        builder.setUserInfo("16c73ab6-b892-458f-abf5-2f875f74882e", "security");
+        builder.setKeyIdentifierType(WSConstants.ISSUER_SERIAL);
+        builder.setSignatureAlgorithm(WSConstants.RSA_SHA1);
+        builder.setDigestAlgo(WSConstants.SHA256);
+
+        Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
+        WSSecHeader secHeader = new WSSecHeader();
+        secHeader.insertSecurityHeader(doc);
+        Document signedDoc = builder.build(doc, crypto, secHeader);
+
+        if (LOG.isDebugEnabled()) {
+            String outputString = 
+                XMLUtils.PrettyDocumentToString(signedDoc);
+            LOG.debug(outputString);
+        }
+
+        Element securityHeader = WSSecurityUtil.getSecurityHeader(signedDoc, null);
+        AlgorithmSuite algorithmSuite = createAlgorithmSuite();
+        
+        try {
+            verify(securityHeader, algorithmSuite, crypto);
+            fail("Expected failure as Digest algorithm is not allowed");
+        } catch (WSSecurityException ex) {
+            // expected
+        }
+        
+        algorithmSuite.addDigestAlgorithm(WSConstants.SHA256);
+        verify(securityHeader, algorithmSuite, crypto);
+    }
+    
+    private AlgorithmSuite createAlgorithmSuite() {
+        AlgorithmSuite algorithmSuite = new AlgorithmSuite();
+        algorithmSuite.addSignatureMethod(WSConstants.RSA_SHA1);
+        algorithmSuite.setMinimumAsymmetricKeyLength(512);
+        algorithmSuite.addC14nAlgorithm(WSConstants.C14N_EXCL_OMIT_COMMENTS);
+        algorithmSuite.addDigestAlgorithm(WSConstants.SHA1);
+        
+        return algorithmSuite;
+    }
+
+    private List<WSSecurityEngineResult> verify(
+        Element securityHeader, AlgorithmSuite algorithmSuite, Crypto sigVerCrypto
+    ) throws Exception {
+        WSSecurityEngine secEngine = new WSSecurityEngine();
+        RequestData data = new RequestData();
+        data.setSigVerCrypto(sigVerCrypto);
+        
+        data.setAlgorithmSuite(algorithmSuite);
+        
+        List<BSPRule> ignoredRules = new ArrayList<BSPRule>();
+        ignoredRules.add(BSPRule.R5404);
+        ignoredRules.add(BSPRule.R5406);
+        data.setIgnoredBSPRules(ignoredRules);
+        
+        return secEngine.processSecurityHeader(securityHeader, data);
+    }
+
+}