Author: coheigea
Date: Tue Dec 10 15:48:25 2013
New Revision: 1549869

URL: http://svn.apache.org/r1549869
Log:
[WSS-481] - Problem with EncryptSignature + EndorsingSupportingTokens

Modified:
    
webservices/wss4j/trunk/ws-security-policy-stax/src/main/java/org/apache/wss4j/policy/stax/PolicyInputProcessor.java
    
webservices/wss4j/trunk/ws-security-policy-stax/src/main/java/org/apache/wss4j/policy/stax/assertionStates/SignatureProtectionAssertionState.java
    
webservices/wss4j/trunk/ws-security-policy-stax/src/test/java/org/apache/wss4j/policy/stax/test/AbstractPolicyTestBase.java
    
webservices/wss4j/trunk/ws-security-policy-stax/src/test/java/org/apache/wss4j/policy/stax/test/AsymmetricBindingIntegrationTest.java
    
webservices/wss4j/trunk/ws-security-policy-stax/src/test/java/org/apache/wss4j/policy/stax/test/AsymmetricBindingTest.java
    
webservices/wss4j/trunk/ws-security-policy-stax/src/test/java/org/apache/wss4j/policy/stax/test/SymmetricBindingTest.java

Modified: 
webservices/wss4j/trunk/ws-security-policy-stax/src/main/java/org/apache/wss4j/policy/stax/PolicyInputProcessor.java
URL: 
http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-policy-stax/src/main/java/org/apache/wss4j/policy/stax/PolicyInputProcessor.java?rev=1549869&r1=1549868&r2=1549869&view=diff
==============================================================================
--- 
webservices/wss4j/trunk/ws-security-policy-stax/src/main/java/org/apache/wss4j/policy/stax/PolicyInputProcessor.java
 (original)
+++ 
webservices/wss4j/trunk/ws-security-policy-stax/src/main/java/org/apache/wss4j/policy/stax/PolicyInputProcessor.java
 Tue Dec 10 15:48:25 2013
@@ -39,6 +39,8 @@ import org.apache.xml.security.stax.secu
 import javax.xml.namespace.QName;
 import javax.xml.stream.XMLStreamConstants;
 import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.events.Attribute;
+
 import java.util.List;
 
 /**
@@ -198,6 +200,7 @@ public class PolicyInputProcessor extend
 
                     EncryptedElementSecurityEvent encryptedElementSecurityEvent
                             = new EncryptedElementSecurityEvent(null, false, 
null);
+                    
encryptedElementSecurityEvent.setCorrelationID(getId(xmlSecEvent));
                     encryptedElementSecurityEvent.setElementPath(elementPath);
                     
policyEnforcer.registerSecurityEvent(encryptedElementSecurityEvent);
 
@@ -219,6 +222,29 @@ public class PolicyInputProcessor extend
                 break;
         }
     }
+    
+    protected String getId(XMLSecEvent xmlSecEvent) {
+        XMLSecStartElement xmlSecStartElement = xmlSecEvent.asStartElement();
+        if (xmlSecStartElement.getOnElementDeclaredAttributes().size() >= 0) {
+            Attribute attribute = 
xmlSecStartElement.getAttributeByName(WSSConstants.ATT_wsu_Id);
+            if (attribute != null) {
+                return attribute.getValue();
+            }
+            attribute = 
xmlSecStartElement.getAttributeByName(WSSConstants.ATT_NULL_Id);
+            if (attribute != null) {
+                return attribute.getValue();
+            }
+            attribute = 
xmlSecStartElement.getAttributeByName(WSSConstants.ATT_NULL_ID);
+            if (attribute != null) {
+                return attribute.getValue();
+            }
+            attribute = 
xmlSecStartElement.getAttributeByName(WSSConstants.ATT_NULL_AssertionID);
+            if (attribute != null) {
+                return attribute.getValue();
+            }
+        }
+        return null;
+    }
 
     protected void init(InputProcessorChain inputProcessorChain) {
         if (!this.initDone) {

Modified: 
webservices/wss4j/trunk/ws-security-policy-stax/src/main/java/org/apache/wss4j/policy/stax/assertionStates/SignatureProtectionAssertionState.java
URL: 
http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-policy-stax/src/main/java/org/apache/wss4j/policy/stax/assertionStates/SignatureProtectionAssertionState.java?rev=1549869&r1=1549868&r2=1549869&view=diff
==============================================================================
--- 
webservices/wss4j/trunk/ws-security-policy-stax/src/main/java/org/apache/wss4j/policy/stax/assertionStates/SignatureProtectionAssertionState.java
 (original)
+++ 
webservices/wss4j/trunk/ws-security-policy-stax/src/main/java/org/apache/wss4j/policy/stax/assertionStates/SignatureProtectionAssertionState.java
 Tue Dec 10 15:48:25 2013
@@ -22,15 +22,20 @@ import org.apache.wss4j.policy.Assertion
 import org.apache.wss4j.policy.WSSPolicyException;
 import org.apache.wss4j.policy.model.AbstractSecurityAssertion;
 import org.apache.wss4j.policy.model.AbstractSymmetricAsymmetricBinding;
+import org.apache.xml.security.exceptions.XMLSecurityException;
 import 
org.apache.xml.security.stax.securityEvent.EncryptedElementSecurityEvent;
 import org.apache.xml.security.stax.securityEvent.SecurityEvent;
 import org.apache.xml.security.stax.securityEvent.SecurityEventConstants;
+import org.apache.xml.security.stax.securityEvent.TokenSecurityEvent;
+import org.apache.xml.security.stax.securityToken.SecurityToken;
 import org.apache.wss4j.policy.stax.Assertable;
 import org.apache.wss4j.stax.ext.WSSConstants;
 import org.apache.wss4j.stax.ext.WSSUtils;
 import org.apache.wss4j.stax.securityEvent.WSSecurityEventConstants;
+import org.apache.wss4j.stax.securityToken.WSSecurityTokenConstants;
 
 import javax.xml.namespace.QName;
+
 import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.LinkedList;
@@ -41,6 +46,10 @@ import java.util.List;
  */
 public class SignatureProtectionAssertionState extends AssertionState 
implements Assertable {
 
+    private final ArrayList<EncryptedElementSecurityEvent> 
encryptedElementEvents = 
+        new ArrayList<EncryptedElementSecurityEvent>();
+    private final ArrayList<TokenSecurityEvent<? extends SecurityToken>> 
tokenSecurityEvents =
+            new ArrayList<TokenSecurityEvent<? extends SecurityToken>>();
     private final List<List<QName>> elementPaths = new 
ArrayList<List<QName>>();
 
     public SignatureProtectionAssertionState(AbstractSecurityAssertion 
assertion, boolean asserted) {
@@ -61,42 +70,144 @@ public class SignatureProtectionAssertio
     @Override
     public SecurityEventConstants.Event[] getSecurityEventType() {
         return new SecurityEventConstants.Event[]{
-                WSSecurityEventConstants.EncryptedElement
+                WSSecurityEventConstants.EncryptedElement,
+                WSSecurityEventConstants.EncryptedKeyToken,
+                WSSecurityEventConstants.IssuedToken,
+                WSSecurityEventConstants.KerberosToken,
+                SecurityEventConstants.KeyValueToken,
+                WSSecurityEventConstants.RelToken,
+                WSSecurityEventConstants.SamlToken,
+                WSSecurityEventConstants.SecurityContextToken,
+                WSSecurityEventConstants.UsernameToken,
+                SecurityEventConstants.X509Token,
+                WSSecurityEventConstants.Operation,
         };
     }
-
+    
     @Override
     public boolean assertEvent(SecurityEvent securityEvent) throws 
WSSPolicyException {
-        EncryptedElementSecurityEvent encryptedElementSecurityEvent = 
(EncryptedElementSecurityEvent) securityEvent;
-        AbstractSymmetricAsymmetricBinding abstractSymmetricAsymmetricBinding 
= (AbstractSymmetricAsymmetricBinding) getAssertion();
-        //todo better matching until we have a streaming xpath evaluation 
engine (work in progress)
-
-        Iterator<List<QName>> pathElementsIterator = elementPaths.iterator();
-        while (pathElementsIterator.hasNext()) {
-            List<QName> qNameList = pathElementsIterator.next();
-            if (WSSUtils.pathMatches(qNameList, 
encryptedElementSecurityEvent.getElementPath(), true, false)) {
-                if (encryptedElementSecurityEvent.isEncrypted()) {
-                    if 
(abstractSymmetricAsymmetricBinding.isEncryptSignature()) {
-                        setAsserted(true);
-                        return true;
-                    } else {
-                        setAsserted(false);
-                        setErrorMessage("Element " + 
WSSUtils.pathAsString(encryptedElementSecurityEvent.getElementPath()) + " must 
not be encrypted");
-                        return false;
-                    }
-                } else {
-                    if 
(abstractSymmetricAsymmetricBinding.isEncryptSignature()) {
-                        setAsserted(false);
-                        setErrorMessage("Element " + 
WSSUtils.pathAsString(encryptedElementSecurityEvent.getElementPath()) + " must 
be encrypted");
-                        return false;
-                    } else {
-                        setAsserted(true);
-                        return true;
-                    }
+        if (securityEvent instanceof EncryptedElementSecurityEvent) {
+            EncryptedElementSecurityEvent encryptedElementSecurityEvent = 
+                (EncryptedElementSecurityEvent) securityEvent;
+            // Store all matching Signature/SignatureConfirmation Elements
+            Iterator<List<QName>> pathElementsIterator = 
elementPaths.iterator();
+            while (pathElementsIterator.hasNext()) {
+                List<QName> qNameList = pathElementsIterator.next();
+                if (WSSUtils.pathMatches(qNameList, 
encryptedElementSecurityEvent.getElementPath(), true, false)) {
+                    encryptedElementEvents.add(encryptedElementSecurityEvent);
+                }
+            }
+        } else if (securityEvent instanceof TokenSecurityEvent) {
+            @SuppressWarnings("unchecked")
+            TokenSecurityEvent<? extends SecurityToken> tokenSecurityEvent 
+                = (TokenSecurityEvent<? extends SecurityToken>) securityEvent;
+            tokenSecurityEvents.add(tokenSecurityEvent);
+        }
+        
+        return true;
+    }
+    
+    @Override
+    public boolean isAsserted() {
+        clearErrorMessage();
+        
+        // If we only have one (main) Signature, then check that it matches 
the policy
+        if (encryptedElementEvents.size() == 1) {
+            return testEncryptedSignature(encryptedElementEvents.get(0));
+        } else if (encryptedElementEvents.size() > 1) {
+            // Otherwise we only check the policy for the main Signature
+            String endorsingSignatureId = findEndorsingSignatureId();
+            for (EncryptedElementSecurityEvent encryptedElementSecurityEvent : 
encryptedElementEvents) {
+                String elementId = 
encryptedElementSecurityEvent.getCorrelationID();
+                if (endorsingSignatureId != null && 
endorsingSignatureId.equals(elementId)) {
+                    // Skip this Endorsing Signature
+                    continue;
+                }
+                if (!testEncryptedSignature(encryptedElementSecurityEvent)) {
+                    return false;
                 }
             }
         }
-        //if we return false here other encrypted elements will trigger a 
PolicyViolationException
+
         return true;
     }
+    
+    private String findEndorsingSignatureId() {
+        for (int i = 0; i < tokenSecurityEvents.size(); i++) {
+            TokenSecurityEvent<? extends SecurityToken> tokenSecurityEvent = 
tokenSecurityEvents.get(i);
+            try {
+                SecurityToken securityToken = 
+                    
getEffectiveSignatureToken(tokenSecurityEvent.getSecurityToken());
+                if (isSignatureToken(securityToken) && 
!isMainSignatureToken(securityToken)) {
+                    return tokenSecurityEvent.getCorrelationID();
+                }
+            } catch (XMLSecurityException e) {
+                // Just return null here
+                return null;
+            }
+        }
+        return null;
+    }
+    
+    private boolean isSignatureToken(SecurityToken securityToken) {
+        List<WSSecurityTokenConstants.TokenUsage> tokenUsages = 
securityToken.getTokenUsages();
+        for (int i = 0; i < tokenUsages.size(); i++) {
+            WSSecurityTokenConstants.TokenUsage tokenUsage = 
tokenUsages.get(i);
+            if 
(WSSecurityTokenConstants.TokenUsage_Signature.equals(tokenUsage)
+                    || 
WSSecurityTokenConstants.TokenUsage_MainSignature.equals(tokenUsage)
+                    || tokenUsage.getName().contains("Endorsing")) {
+                return true;
+            }
+        }
+        return false;
+    }
+    
+    private boolean isMainSignatureToken(SecurityToken securityToken) throws 
XMLSecurityException {
+        SecurityToken rootToken = WSSUtils.getRootToken(securityToken);
+        List<WSSecurityTokenConstants.TokenUsage> tokenUsages = 
rootToken.getTokenUsages();
+        return 
tokenUsages.contains(WSSecurityTokenConstants.TokenUsage_MainSignature);
+    }
+    
+    private SecurityToken getEffectiveSignatureToken(SecurityToken 
securityToken) throws XMLSecurityException {
+        SecurityToken tmp = WSSUtils.getRootToken(securityToken);
+        List<? extends SecurityToken> wrappedTokens = tmp.getWrappedTokens();
+        for (int i = 0; i < wrappedTokens.size(); i++) {
+            SecurityToken token = wrappedTokens.get(i);
+            if (isSignatureToken(token)) {
+                //WSP 1.3, 6.5 [Token Protection] Property: Note that in cases 
where derived keys are used
+                //the 'main' token, and NOT the derived key token, is covered 
by the signature.
+                if 
(WSSecurityTokenConstants.DerivedKeyToken.equals(token.getTokenType())) {
+                    return tmp;
+                }
+                tmp = token;
+            }
+        }
+        return tmp;
+    }
+
+    private boolean testEncryptedSignature(EncryptedElementSecurityEvent 
encryptedElementSecurityEvent) {
+        AbstractSymmetricAsymmetricBinding abstractSymmetricAsymmetricBinding 
= 
+            (AbstractSymmetricAsymmetricBinding) getAssertion();
+        
+        if (encryptedElementSecurityEvent.isEncrypted()) {
+            if (abstractSymmetricAsymmetricBinding.isEncryptSignature()) {
+                setAsserted(true);
+                return true;
+            } else {
+                setAsserted(false);
+                setErrorMessage("Element " + 
WSSUtils.pathAsString(encryptedElementSecurityEvent.getElementPath()) + " must 
not be encrypted");
+                return false;
+            }
+        } else {
+            if (abstractSymmetricAsymmetricBinding.isEncryptSignature()) {
+                setAsserted(false);
+                setErrorMessage("Element " + 
WSSUtils.pathAsString(encryptedElementSecurityEvent.getElementPath()) + " must 
be encrypted");
+                return false;
+            } else {
+                setAsserted(true);
+                return true;
+            }
+        }
+    }
+
 }

Modified: 
webservices/wss4j/trunk/ws-security-policy-stax/src/test/java/org/apache/wss4j/policy/stax/test/AbstractPolicyTestBase.java
URL: 
http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-policy-stax/src/test/java/org/apache/wss4j/policy/stax/test/AbstractPolicyTestBase.java?rev=1549869&r1=1549868&r2=1549869&view=diff
==============================================================================
--- 
webservices/wss4j/trunk/ws-security-policy-stax/src/test/java/org/apache/wss4j/policy/stax/test/AbstractPolicyTestBase.java
 (original)
+++ 
webservices/wss4j/trunk/ws-security-policy-stax/src/test/java/org/apache/wss4j/policy/stax/test/AbstractPolicyTestBase.java
 Tue Dec 10 15:48:25 2013
@@ -44,6 +44,7 @@ import org.w3c.dom.Node;
 import org.w3c.dom.NodeList;
 import org.xml.sax.SAXException;
 
+import javax.xml.namespace.QName;
 import javax.xml.parsers.DocumentBuilder;
 import javax.xml.parsers.DocumentBuilderFactory;
 import javax.xml.parsers.ParserConfigurationException;
@@ -54,6 +55,7 @@ import java.io.InputStreamReader;
 import java.security.KeyStore;
 import java.security.cert.Certificate;
 import java.security.cert.X509Certificate;
+import java.util.Collections;
 import java.util.List;
 
 public class AbstractPolicyTestBase extends AbstractTestBase {
@@ -121,6 +123,15 @@ public class AbstractPolicyTestBase exte
             protected String getAlias() throws XMLSecurityException {
                 return keyAlias;
             }
+            
+            @Override
+            public List<QName> getElementPath() {
+                List<QName> elementPath = super.getElementPath();
+                if (elementPath != null) {
+                    return elementPath;
+                }
+                return Collections.emptyList();
+            }
         };
         x509SecurityToken.setSecretKey("", keyStore.getKey(keyAlias, 
"default".toCharArray()));
         
x509SecurityToken.setPublicKey(keyStore.getCertificate(keyAlias).getPublicKey());

Modified: 
webservices/wss4j/trunk/ws-security-policy-stax/src/test/java/org/apache/wss4j/policy/stax/test/AsymmetricBindingIntegrationTest.java
URL: 
http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-policy-stax/src/test/java/org/apache/wss4j/policy/stax/test/AsymmetricBindingIntegrationTest.java?rev=1549869&r1=1549868&r2=1549869&view=diff
==============================================================================
--- 
webservices/wss4j/trunk/ws-security-policy-stax/src/test/java/org/apache/wss4j/policy/stax/test/AsymmetricBindingIntegrationTest.java
 (original)
+++ 
webservices/wss4j/trunk/ws-security-policy-stax/src/test/java/org/apache/wss4j/policy/stax/test/AsymmetricBindingIntegrationTest.java
 Tue Dec 10 15:48:25 2013
@@ -1716,8 +1716,6 @@ public class AsymmetricBindingIntegratio
             Assert.fail("Exception expected");
         } catch (XMLStreamException e) {
             Assert.assertTrue(e.getCause() instanceof WSSecurityException);
-            Assert.assertEquals(e.getCause().getMessage(),
-                    "Element 
/{http://schemas.xmlsoap.org/soap/envelope/}Envelope/{http://schemas.xmlsoap.org/soap/envelope/}Header/{http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd}Security/{http://www.w3.org/2000/09/xmldsig#}Signature
 must be encrypted");
             Assert.assertEquals(((WSSecurityException) 
e.getCause()).getFaultCode(), WSSecurityException.INVALID_SECURITY);
         }
     }

Modified: 
webservices/wss4j/trunk/ws-security-policy-stax/src/test/java/org/apache/wss4j/policy/stax/test/AsymmetricBindingTest.java
URL: 
http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-policy-stax/src/test/java/org/apache/wss4j/policy/stax/test/AsymmetricBindingTest.java?rev=1549869&r1=1549868&r2=1549869&view=diff
==============================================================================
--- 
webservices/wss4j/trunk/ws-security-policy-stax/src/test/java/org/apache/wss4j/policy/stax/test/AsymmetricBindingTest.java
 (original)
+++ 
webservices/wss4j/trunk/ws-security-policy-stax/src/test/java/org/apache/wss4j/policy/stax/test/AsymmetricBindingTest.java
 Tue Dec 10 15:48:25 2013
@@ -241,8 +241,6 @@ public class AsymmetricBindingTest exten
             Assert.fail("Exception expected");
         } catch (WSSecurityException e) {
             Assert.assertTrue(e.getCause() instanceof 
PolicyViolationException);
-            Assert.assertEquals(e.getCause().getMessage(),
-                    "Element 
/{http://schemas.xmlsoap.org/soap/envelope/}Envelope/{http://schemas.xmlsoap.org/soap/envelope/}Header/{http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd}Security/{http://www.w3.org/2000/09/xmldsig#}Signature
 must be encrypted");
             Assert.assertEquals(e.getFaultCode(), 
WSSecurityException.INVALID_SECURITY);
         }
     }

Modified: 
webservices/wss4j/trunk/ws-security-policy-stax/src/test/java/org/apache/wss4j/policy/stax/test/SymmetricBindingTest.java
URL: 
http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-policy-stax/src/test/java/org/apache/wss4j/policy/stax/test/SymmetricBindingTest.java?rev=1549869&r1=1549868&r2=1549869&view=diff
==============================================================================
--- 
webservices/wss4j/trunk/ws-security-policy-stax/src/test/java/org/apache/wss4j/policy/stax/test/SymmetricBindingTest.java
 (original)
+++ 
webservices/wss4j/trunk/ws-security-policy-stax/src/test/java/org/apache/wss4j/policy/stax/test/SymmetricBindingTest.java
 Tue Dec 10 15:48:25 2013
@@ -253,7 +253,6 @@ public class SymmetricBindingTest extend
             policyEnforcer.registerSecurityEvent(operationSecurityEvent);
             Assert.fail("Exception expected");
         } catch (WSSecurityException e) {
-            Assert.assertTrue(e.getCause() instanceof 
PolicyViolationException);
             Assert.assertEquals(e.getCause().getMessage(),
                     "Element 
/{http://schemas.xmlsoap.org/soap/envelope/}Envelope/{http://schemas.xmlsoap.org/soap/envelope/}Header/{http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd}Security/{http://www.w3.org/2000/09/xmldsig#}Signature
 must be encrypted");
             Assert.assertEquals(e.getFaultCode(), 
WSSecurityException.INVALID_SECURITY);


Reply via email to