ws-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From cohei...@apache.org
Subject svn commit: r1624049 - in /webservices/wss4j/trunk/ws-security-dom/src: main/java/org/apache/wss4j/dom/processor/SAMLTokenProcessor.java test/java/org/apache/wss4j/dom/saml/SignedSamlTokenHOKTest.java
Date Wed, 10 Sep 2014 16:06:16 GMT
Author: coheigea
Date: Wed Sep 10 16:06:15 2014
New Revision: 1624049

URL: http://svn.apache.org/r1624049
Log:
Record SAML Token signed results so that it can be used in SignedElements evaluation.

Modified:
    webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/SAMLTokenProcessor.java
    webservices/wss4j/trunk/ws-security-dom/src/test/java/org/apache/wss4j/dom/saml/SignedSamlTokenHOKTest.java

Modified: webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/SAMLTokenProcessor.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/SAMLTokenProcessor.java?rev=1624049&r1=1624048&r2=1624049&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/SAMLTokenProcessor.java
(original)
+++ webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/SAMLTokenProcessor.java
Wed Sep 10 16:06:15 2014
@@ -21,18 +21,21 @@ package org.apache.wss4j.dom.processor;
 
 import java.security.NoSuchProviderException;
 import java.security.PublicKey;
+import java.util.ArrayList;
 import java.util.List;
 
 import javax.xml.crypto.MarshalException;
+import javax.xml.crypto.dsig.Reference;
+import javax.xml.crypto.dsig.Transform;
 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.apache.wss4j.common.principal.SAMLTokenPrincipalImpl;
 import org.w3c.dom.Element;
 
+import org.apache.wss4j.common.principal.SAMLTokenPrincipalImpl;
 import org.apache.wss4j.common.crypto.AlgorithmSuite;
 import org.apache.wss4j.common.crypto.AlgorithmSuiteValidator;
 import org.apache.wss4j.common.ext.WSSecurityException;
@@ -41,6 +44,7 @@ import org.apache.wss4j.common.saml.SAML
 import org.apache.wss4j.common.saml.SamlAssertionWrapper;
 import org.apache.wss4j.common.util.DOM2Writer;
 import org.apache.wss4j.dom.WSConstants;
+import org.apache.wss4j.dom.WSDataRef;
 import org.apache.wss4j.dom.WSDocInfo;
 import org.apache.wss4j.dom.WSSecurityEngineResult;
 import org.apache.wss4j.dom.handler.RequestData;
@@ -76,8 +80,15 @@ public class SAMLTokenProcessor implemen
         
         Validator validator = 
             data.getValidator(new QName(elem.getNamespaceURI(), elem.getLocalName()));
-        Credential credential = handleSAMLToken(elem, data, validator, wsDocInfo);
-        SamlAssertionWrapper samlAssertion = credential.getSamlAssertion();
+        
+        SamlAssertionWrapper samlAssertion = new SamlAssertionWrapper(elem);
+        XMLSignature xmlSignature = 
+            verifySignatureKeysAndAlgorithms(samlAssertion, data, wsDocInfo);
+        List<WSDataRef> dataRefs = createDataRefs(elem, samlAssertion, xmlSignature);
+        
+        Credential credential = 
+            handleSAMLToken(samlAssertion, data, validator, wsDocInfo);
+        samlAssertion = credential.getSamlAssertion();
         if (LOG.isDebugEnabled()) {
             LOG.debug("SAML Assertion issuer " + samlAssertion.getIssuerString());
             LOG.debug(DOM2Writer.nodeToString(elem));
@@ -99,6 +110,7 @@ public class SAMLTokenProcessor implemen
         WSSecurityEngineResult result = null;
         if (samlAssertion.isSigned()) {
             result = new WSSecurityEngineResult(WSConstants.ST_SIGNED, samlAssertion);
+            result.put(WSSecurityEngineResult.TAG_DATA_REF_URIS, dataRefs);
         } else {
             result = new WSSecurityEngineResult(WSConstants.ST_UNSIGNED, samlAssertion);
         }
@@ -132,16 +144,32 @@ public class SAMLTokenProcessor implemen
     }
 
     public Credential handleSAMLToken(
-        Element token, 
+        SamlAssertionWrapper samlAssertion, 
         RequestData data,
         Validator validator,
         WSDocInfo docInfo
     ) throws WSSecurityException {
-        SamlAssertionWrapper samlAssertion = new SamlAssertionWrapper(token);
-        if (samlAssertion.isSigned()) {
-            // Check for compliance against the defined AlgorithmSuite
-            AlgorithmSuite algorithmSuite = data.getSamlAlgorithmSuite();
+        // Parse the subject if it exists
+        samlAssertion.parseSubject(
+            new WSSSAMLKeyInfoProcessor(data, docInfo), data.getSigVerCrypto(), 
+            data.getCallbackHandler()
+        );
             
+        // Now delegate the rest of the verification to the Validator
+        Credential credential = new Credential();
+        credential.setSamlAssertion(samlAssertion);
+        if (validator != null) {
+            return validator.validate(credential, data);
+        }
+        return credential;
+    }
+    
+    private XMLSignature verifySignatureKeysAndAlgorithms(
+        SamlAssertionWrapper samlAssertion,
+        RequestData data,
+        WSDocInfo wsDocInfo
+    ) throws WSSecurityException {
+        if (samlAssertion.isSigned()) {
             Signature sig = samlAssertion.getSignature();
             KeyInfo keyInfo = sig.getKeyInfo();
             if (keyInfo == null) {
@@ -152,59 +180,92 @@ public class SAMLTokenProcessor implemen
             }
             SAMLKeyInfo samlKeyInfo = 
                 SAMLUtil.getCredentialFromKeyInfo(
-                    keyInfo.getDOM(), new WSSSAMLKeyInfoProcessor(data, docInfo), data.getSigVerCrypto()
+                    keyInfo.getDOM(), new WSSSAMLKeyInfoProcessor(data, wsDocInfo), data.getSigVerCrypto()
                 );
             
+            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",
+                    "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);
+            context.setProperty("org.jcp.xml.dsig.secureValidation", Boolean.TRUE);
+
+            XMLSignature xmlSignature;
+            try {
+                xmlSignature = signatureFactory.unmarshalXMLSignature(context);
+            } catch (MarshalException ex) {
+                throw new WSSecurityException(
+                    WSSecurityException.ErrorCode.FAILED_CHECK, "invalidSAMLsecurity", 
+                    ex, "cannot get certificate or key"
+                );
+            }
+            
+            // Check for compliance against the defined AlgorithmSuite
+            AlgorithmSuite algorithmSuite = data.getSamlAlgorithmSuite();
             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",
-                        "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);
-                context.setProperty("org.jcp.xml.dsig.secureValidation", Boolean.TRUE);
-
-                XMLSignature xmlSignature;
-                try {
-                    xmlSignature = signatureFactory.unmarshalXMLSignature(context);
-                } catch (MarshalException ex) {
-                    throw new WSSecurityException(
-                        WSSecurityException.ErrorCode.FAILED_CHECK, "invalidSAMLsecurity",

-                        ex, "cannot get certificate or key"
-                    );
-                }
-
                 algorithmSuiteValidator.checkSignatureAlgorithms(xmlSignature);
                 algorithmSuiteValidator.checkAsymmetricKeyLength(key);
             }
 
             samlAssertion.verifySignature(samlKeyInfo);
-        }
-        // Parse the subject if it exists
-        samlAssertion.parseSubject(
-            new WSSSAMLKeyInfoProcessor(data, docInfo), data.getSigVerCrypto(), 
-            data.getCallbackHandler()
-        );
             
-        // Now delegate the rest of the verification to the Validator
-        Credential credential = new Credential();
-        credential.setSamlAssertion(samlAssertion);
-        if (validator != null) {
-            return validator.validate(credential, data);
+            return xmlSignature;
         }
-        return credential;
+        
+        return null;
     }
 
+    private List<WSDataRef> createDataRefs(
+        Element token, SamlAssertionWrapper samlAssertion, XMLSignature xmlSignature
+    ) {
+        if (xmlSignature == null) {
+            return null;
+        }
+        
+        List<WSDataRef> protectedRefs = new ArrayList<WSDataRef>();
+        String signatureMethod = 
+            xmlSignature.getSignedInfo().getSignatureMethod().getAlgorithm();
+        
+        for (Object refObject : xmlSignature.getSignedInfo().getReferences()) {
+            Reference reference = (Reference)refObject;
+            
+            if ("".equals(reference.getURI()) 
+                || reference.getURI().equals(samlAssertion.getId())
+                || reference.getURI().equals("#" + samlAssertion.getId())) {
+                WSDataRef ref = new WSDataRef();
+                ref.setWsuId(reference.getURI());
+                ref.setProtectedElement(token);
+                ref.setAlgorithm(signatureMethod);
+                ref.setDigestAlgorithm(reference.getDigestMethod().getAlgorithm());
+                ref.setDigestValue(reference.getDigestValue());
+    
+                // Set the Transform algorithms as well
+                @SuppressWarnings("unchecked")
+                List<Transform> transforms = (List<Transform>)reference.getTransforms();
+                List<String> transformAlgorithms = new ArrayList<String>(transforms.size());
+                for (Transform transform : transforms) {
+                    transformAlgorithms.add(transform.getAlgorithm());
+                }
+                ref.setTransformAlgorithms(transformAlgorithms);
+    
+                ref.setXpath(ReferenceListProcessor.getXPath(token));
+                protectedRefs.add(ref);
+            }
+        }
+        
+        return protectedRefs;
+    }
 }

Modified: webservices/wss4j/trunk/ws-security-dom/src/test/java/org/apache/wss4j/dom/saml/SignedSamlTokenHOKTest.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-dom/src/test/java/org/apache/wss4j/dom/saml/SignedSamlTokenHOKTest.java?rev=1624049&r1=1624048&r2=1624049&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-dom/src/test/java/org/apache/wss4j/dom/saml/SignedSamlTokenHOKTest.java
(original)
+++ webservices/wss4j/trunk/ws-security-dom/src/test/java/org/apache/wss4j/dom/saml/SignedSamlTokenHOKTest.java
Wed Sep 10 16:06:15 2014
@@ -139,16 +139,24 @@ public class SignedSamlTokenHOKTest exte
         assertTrue(receivedSamlAssertion.isSigned());
         assertTrue(receivedSamlAssertion.getSignatureValue() != null);
         
+        // Test we have a WSDataRef for the signed SAML token as well
+        List<WSDataRef> refs =
+            (List<WSDataRef>) actionResult.get(WSSecurityEngineResult.TAG_DATA_REF_URIS);
+        assertTrue(refs.size() == 1);
+        
+        WSDataRef wsDataRef = refs.get(0);
+        String xpath = wsDataRef.getXpath();
+        assertEquals("/SOAP-ENV:Envelope/SOAP-ENV:Header/wsse:Security/saml1:Assertion",
xpath);
+        
         // Test we processed a signature (SOAP body)
         actionResult = WSSecurityUtil.fetchActionResult(results, WSConstants.SIGN);
         assertTrue(actionResult != null);
         assertFalse(actionResult.isEmpty());
-        final List<WSDataRef> refs =
-            (List<WSDataRef>) actionResult.get(WSSecurityEngineResult.TAG_DATA_REF_URIS);
+        refs = (List<WSDataRef>) actionResult.get(WSSecurityEngineResult.TAG_DATA_REF_URIS);
         assertTrue(refs.size() == 1);
         
-        WSDataRef wsDataRef = refs.get(0);
-        String xpath = wsDataRef.getXpath();
+        wsDataRef = refs.get(0);
+        xpath = wsDataRef.getXpath();
         assertEquals("/SOAP-ENV:Envelope/SOAP-ENV:Body", xpath);
     }
     



Mime
View raw message