You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by co...@apache.org on 2014/07/28 16:44:06 UTC

git commit: Largeish refactor to properly support SignedParts associated with EndorsingSupportingTokens

Repository: cxf
Updated Branches:
  refs/heads/master 2d4f5cd45 -> f2dc0d49c


Largeish refactor to properly support SignedParts associated with EndorsingSupportingTokens


Project: http://git-wip-us.apache.org/repos/asf/cxf/repo
Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/f2dc0d49
Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/f2dc0d49
Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/f2dc0d49

Branch: refs/heads/master
Commit: f2dc0d49c17b884b18e05d4a912bbe0cf2d37977
Parents: 2d4f5cd
Author: Colm O hEigeartaigh <co...@apache.org>
Authored: Mon Jul 28 15:43:15 2014 +0100
Committer: Colm O hEigeartaigh <co...@apache.org>
Committed: Mon Jul 28 15:43:52 2014 +0100

----------------------------------------------------------------------
 .../policyhandlers/AbstractBindingBuilder.java  | 92 ++++++++++++++------
 .../AsymmetricBindingHandler.java               | 32 +++----
 .../policyhandlers/SymmetricBindingHandler.java | 17 ++--
 .../AbstractSupportingTokenPolicyValidator.java | 52 ++++++++++-
 .../EndorsingEncryptedTokenPolicyValidator.java |  5 +-
 .../EndorsingTokenPolicyValidator.java          |  5 +-
 ...dEndorsingEncryptedTokenPolicyValidator.java |  5 +-
 .../SignedEndorsingTokenPolicyValidator.java    |  5 +-
 .../cxf/systest/ws/x509/X509TokenTest.java      | 29 ++++++
 .../cxf/systest/ws/x509/DoubleItX509.wsdl       | 72 +++++++++++++++
 .../org/apache/cxf/systest/ws/x509/client.xml   |  9 ++
 .../org/apache/cxf/systest/ws/x509/server.xml   |  8 ++
 .../apache/cxf/systest/ws/x509/stax-server.xml  |  9 ++
 13 files changed, 282 insertions(+), 58 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cxf/blob/f2dc0d49/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/AbstractBindingBuilder.java
----------------------------------------------------------------------
diff --git a/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/AbstractBindingBuilder.java b/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/AbstractBindingBuilder.java
index 0a6a075..6aa6142 100644
--- a/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/AbstractBindingBuilder.java
+++ b/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/AbstractBindingBuilder.java
@@ -111,6 +111,7 @@ import org.apache.wss4j.dom.util.WSSecurityUtil;
 import org.apache.wss4j.policy.SPConstants;
 import org.apache.wss4j.policy.SPConstants.IncludeTokenType;
 import org.apache.wss4j.policy.model.AbstractBinding;
+import org.apache.wss4j.policy.model.AbstractSecurityAssertion;
 import org.apache.wss4j.policy.model.AbstractSymmetricAsymmetricBinding;
 import org.apache.wss4j.policy.model.AbstractToken;
 import org.apache.wss4j.policy.model.AbstractToken.DerivedKeys;
@@ -177,6 +178,7 @@ public abstract class AbstractBindingBuilder extends AbstractCommonBindingHandle
     
     private Element lastSupportingTokenElement;
     private Element lastDerivedKeyElement;
+    private List<AbstractSecurityAssertion> suppTokenParts = new ArrayList<AbstractSecurityAssertion>();
     
     public AbstractBindingBuilder(
                            WSSConfig config,
@@ -392,7 +394,11 @@ public abstract class AbstractBindingBuilder extends AbstractCommonBindingHandle
             for (AssertionInfo assertionInfo : tokensInfos) {
                 if (assertionInfo.getAssertion() instanceof SupportingTokens) {
                     assertionInfo.setAsserted(true);
-                    handleSupportingTokens((SupportingTokens)assertionInfo.getAssertion(), endorse, ret);
+                    try {
+                        handleSupportingTokens((SupportingTokens)assertionInfo.getAssertion(), endorse, ret);
+                    } catch (SOAPException ex) {
+                        throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, ex);
+                    }
                 }
             }
         }
@@ -403,13 +409,15 @@ public abstract class AbstractBindingBuilder extends AbstractCommonBindingHandle
         SupportingTokens suppTokens, 
         boolean endorse,
         List<SupportingToken> ret
-    ) throws WSSecurityException {
+    ) throws WSSecurityException, SOAPException {
         if (suppTokens == null) {
             return ret;
         }
         for (AbstractToken token : suppTokens.getTokens()) {
             assertToken(token);
             if (!isTokenRequired(token.getIncludeTokenType())) {
+                // Check for any SignedParts so as *not* to sign them
+                getSignedParts(suppTokens);
                 continue;
             }
             if (token instanceof UsernameToken) {
@@ -442,7 +450,8 @@ public abstract class AbstractBindingBuilder extends AbstractCommonBindingHandle
         
                 if (secToken.getX509Certificate() == null) {  
                     ret.add(
-                        new SupportingToken(token, new WSSecurityTokenHolder(wssConfig, secToken))
+                        new SupportingToken(token, new WSSecurityTokenHolder(wssConfig, secToken),
+                                            getSignedParts(suppTokens))
                     );
                 } else {
                     WSSecSignature sig = new WSSecSignature(wssConfig);                    
@@ -482,7 +491,7 @@ public abstract class AbstractBindingBuilder extends AbstractCommonBindingHandle
                         throw new Fault(e);
                     }
                     
-                    ret.add(new SupportingToken(token, sig));                
+                    ret.add(new SupportingToken(token, sig, getSignedParts(suppTokens)));                
                 }
 
             } else if (token instanceof X509Token) {
@@ -506,20 +515,20 @@ public abstract class AbstractBindingBuilder extends AbstractCommonBindingHandle
                         encryptedTokensList.add(part);
                     }
                 }
-                ret.add(new SupportingToken(token, sig));
+                ret.add(new SupportingToken(token, sig, getSignedParts(suppTokens)));
             } else if (token instanceof KeyValueToken) {
                 WSSecSignature sig = getSignatureBuilder(suppTokens, token, endorse);
                 if (suppTokens.isEncryptedToken()) {
                     WSEncryptionPart part = new WSEncryptionPart(sig.getBSTTokenId(), "Element");
                     encryptedTokensList.add(part);
                 }
-                ret.add(new SupportingToken(token, sig));                
+                ret.add(new SupportingToken(token, sig, getSignedParts(suppTokens)));                
             } else if (token instanceof SamlToken) {
                 SamlAssertionWrapper assertionWrapper = addSamlToken((SamlToken)token);
                 if (assertionWrapper != null) {
                     Element assertionElement = assertionWrapper.toDOM(saaj.getSOAPPart());
                     addSupportingElement(assertionElement);
-                    ret.add(new SupportingToken(token, assertionWrapper));
+                    ret.add(new SupportingToken(token, assertionWrapper, getSignedParts(suppTokens)));
                     if (suppTokens.isEncryptedToken()) {
                         WSEncryptionPart part = new WSEncryptionPart(assertionWrapper.getId(), "Element");
                         part.setElement(assertionElement);
@@ -528,6 +537,7 @@ public abstract class AbstractBindingBuilder extends AbstractCommonBindingHandle
                 }
             }
         }
+        
         return ret;
     }
     
@@ -539,7 +549,7 @@ public abstract class AbstractBindingBuilder extends AbstractCommonBindingHandle
             if (utBuilder != null) {
                 utBuilder.prepare(saaj.getSOAPPart());
                 addSupportingElement(utBuilder.getUsernameTokenElement());
-                ret.add(new SupportingToken(token, utBuilder));
+                ret.add(new SupportingToken(token, utBuilder, null));
                 if (encryptedToken) {
                     WSEncryptionPart part = new WSEncryptionPart(utBuilder.getId(), "Element");
                     part.setElement(utBuilder.getUsernameTokenElement());
@@ -551,7 +561,7 @@ public abstract class AbstractBindingBuilder extends AbstractCommonBindingHandle
             if (utBuilder != null) {
                 utBuilder.prepare(saaj.getSOAPPart());
                 addSupportingElement(utBuilder.getUsernameTokenElement());
-                ret.add(new SupportingToken(token, utBuilder));
+                ret.add(new SupportingToken(token, utBuilder, null));
                 //WebLogic and WCF always encrypt these
                 //See:  http://e-docs.bea.com/wls/docs103/webserv_intro/interop.html
                 //encryptedTokensIdList.add(utBuilder.getId());
@@ -1066,7 +1076,7 @@ public abstract class AbstractBindingBuilder extends AbstractCommonBindingHandle
                                    celements == null ? null : celements.getXPaths());
     }    
     
-    public List<WSEncryptionPart> getSignedParts() 
+    public List<WSEncryptionPart> getSignedParts(SupportingTokens supportingToken) 
         throws SOAPException {
         
         boolean isSignBody = false;
@@ -1074,20 +1084,38 @@ public abstract class AbstractBindingBuilder extends AbstractCommonBindingHandle
         SignedParts parts = null;
         SignedElements elements = null;
         
-        Collection<AssertionInfo> ais = getAllAssertionsByLocalname(SPConstants.SIGNED_PARTS);
-        if (!ais.isEmpty()) {
-            for (AssertionInfo ai : ais) {
-                parts = (SignedParts)ai.getAssertion();
-                ai.setAsserted(true);
-            }            
-        }
-        
-        ais = getAllAssertionsByLocalname(SPConstants.SIGNED_ELEMENTS);
-        if (!ais.isEmpty()) {
-            for (AssertionInfo ai : ais) {
-                elements = (SignedElements)ai.getAssertion();
-                ai.setAsserted(true);
-            }            
+        if (supportingToken != null && supportingToken.isEndorsing()) {
+            parts = supportingToken.getSignedParts();
+            elements = supportingToken.getSignedElements();
+            // Store them so that the main Signature doesn't sign them
+            if (parts != null) {
+                suppTokenParts.add(parts);
+            }
+            if (elements != null) {
+                suppTokenParts.add(elements);
+            }
+        } else {
+            Collection<AssertionInfo> ais = getAllAssertionsByLocalname(SPConstants.SIGNED_PARTS);
+            if (!ais.isEmpty()) {
+                for (AssertionInfo ai : ais) {
+                    SignedParts signedParts = (SignedParts)ai.getAssertion();
+                    if (!suppTokenParts.contains(signedParts)) {
+                        parts = signedParts;
+                        ai.setAsserted(true);
+                    }
+                }            
+            }
+            
+            ais = getAllAssertionsByLocalname(SPConstants.SIGNED_ELEMENTS);
+            if (!ais.isEmpty()) {
+                for (AssertionInfo ai : ais) {
+                    SignedElements signedElements = (SignedElements)ai.getAssertion();
+                    if (!suppTokenParts.contains(signedElements)) {
+                        elements = signedElements;
+                        ai.setAsserted(true);
+                    }
+                }            
+            }
         }
         
         List<WSEncryptionPart> signedParts = new ArrayList<WSEncryptionPart>();
@@ -1785,6 +1813,12 @@ public abstract class AbstractBindingBuilder extends AbstractCommonBindingHandle
             sigPart.setElement(bottomUpElement);
             sigParts.add(sigPart);
             
+            if (supportingToken.getSignedParts() != null) {
+                for (WSEncryptionPart signedPart : supportingToken.getSignedParts()) {
+                    sigParts.add(signedPart);
+                }
+            }
+            
             if (tempTok instanceof WSSecSignature) {
                 WSSecSignature sig = (WSSecSignature)tempTok;
                 if (isTokenProtection && sig.getBSTTokenId() != null) {
@@ -2191,10 +2225,13 @@ public abstract class AbstractBindingBuilder extends AbstractCommonBindingHandle
     static class SupportingToken {
         private final AbstractToken token;
         private final Object tokenImplementation;
+        private final List<WSEncryptionPart> signedParts;
         
-        public SupportingToken(AbstractToken token, Object tokenImplementation) {
+        public SupportingToken(AbstractToken token, Object tokenImplementation,
+                               List<WSEncryptionPart> signedParts) {
             this.token = token;
             this.tokenImplementation = tokenImplementation;
+            this.signedParts = signedParts;
         }
         
         public AbstractToken getToken() {
@@ -2204,5 +2241,10 @@ public abstract class AbstractBindingBuilder extends AbstractCommonBindingHandle
         public Object getTokenImplementation() {
             return tokenImplementation;
         }
+
+        public List<WSEncryptionPart> getSignedParts() {
+            return signedParts;
+        }
+
     }
 }

http://git-wip-us.apache.org/repos/asf/cxf/blob/f2dc0d49/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/AsymmetricBindingHandler.java
----------------------------------------------------------------------
diff --git a/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/AsymmetricBindingHandler.java b/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/AsymmetricBindingHandler.java
index 2182092..9ea8487 100644
--- a/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/AsymmetricBindingHandler.java
+++ b/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/AsymmetricBindingHandler.java
@@ -308,13 +308,26 @@ public class AsymmetricBindingHandler extends AbstractBindingBuilder {
             assertToken(initiatorToken);
         }
         
+        List<WSEncryptionPart> sigParts = new ArrayList<WSEncryptionPart>();
+        if (timestampEl != null) {
+            WSEncryptionPart timestampPart = 
+                convertToEncryptionPart(timestampEl.getElement());
+            sigParts.add(timestampPart);
+        }
+
+        try {
+            addSupportingTokens(sigParts);
+        } catch (WSSecurityException ex) {
+            LOG.log(Level.FINE, ex.getMessage(), ex);
+            policyNotAsserted(encryptionToken, ex);
+        }
+        
         List<WSEncryptionPart> encrParts = null;
-        List<WSEncryptionPart> sigParts = null;
         try {
             encrParts = getEncryptedParts();
             //Signed parts are determined before encryption because encrypted signed  headers
             //will not be included otherwise
-            sigParts = getSignedParts();
+            sigParts.addAll(this.getSignedParts(null));
         } catch (SOAPException ex) {
             LOG.log(Level.FINE, ex.getMessage(), ex);
             throw new Fault(ex);
@@ -325,19 +338,6 @@ public class AsymmetricBindingHandler extends AbstractBindingBuilder {
             encrBase = doEncryption(wrapper, encrParts, true);
             handleEncryptedSignedHeaders(encrParts, sigParts);
         }
-
-        if (timestampEl != null) {
-            WSEncryptionPart timestampPart = 
-                convertToEncryptionPart(timestampEl.getElement());
-            sigParts.add(timestampPart);
-        }
-
-        try {
-            addSupportingTokens(sigParts);
-        } catch (WSSecurityException ex) {
-            LOG.log(Level.FINE, ex.getMessage(), ex);
-            policyNotAsserted(encryptionToken, ex);
-        }
         
         if (!isRequestor()) {
             addSignatureConfirmation(sigParts);
@@ -597,7 +597,7 @@ public class AsymmetricBindingHandler extends AbstractBindingBuilder {
         }
         
         AbstractToken sigToken = wrapper.getToken();
-        sigParts.addAll(this.getSignedParts());
+        sigParts.addAll(this.getSignedParts(null));
         if (sigParts.isEmpty()) {
             // Add the BST to the security header if required
             if (!attached && isTokenRequired(sigToken.getIncludeTokenType())) {

http://git-wip-us.apache.org/repos/asf/cxf/blob/f2dc0d49/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/SymmetricBindingHandler.java
----------------------------------------------------------------------
diff --git a/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/SymmetricBindingHandler.java b/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/SymmetricBindingHandler.java
index a036644..99314f7 100644
--- a/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/SymmetricBindingHandler.java
+++ b/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/SymmetricBindingHandler.java
@@ -139,8 +139,6 @@ public class SymmetricBindingHandler extends AbstractBindingBuilder {
             AbstractTokenWrapper encryptionWrapper = getEncryptionToken();
             assertTokenWrapper(encryptionWrapper);
             AbstractToken encryptionToken = encryptionWrapper.getToken();
-            List<WSEncryptionPart> encrParts = getEncryptedParts();
-            List<WSEncryptionPart> sigParts = getSignedParts();
             
             if (encryptionToken != null) {
                 //The encryption token can be an IssuedToken or a 
@@ -192,17 +190,19 @@ public class SymmetricBindingHandler extends AbstractBindingBuilder {
                     attached = true;
                 }
                 
-                WSSecBase encr = doEncryption(encryptionWrapper, tok, attached, encrParts, true);
-                
-                handleEncryptedSignedHeaders(encrParts, sigParts);
-                
+                List<WSEncryptionPart> sigParts = new ArrayList<WSEncryptionPart>();
                 if (timestampEl != null) {
                     WSEncryptionPart timestampPart = 
                         convertToEncryptionPart(timestampEl.getElement());
                     sigParts.add(timestampPart);        
                 }
-                
                 addSupportingTokens(sigParts);
+                sigParts.addAll(this.getSignedParts(null));
+
+                List<WSEncryptionPart> encrParts = getEncryptedParts();
+                WSSecBase encr = doEncryption(encryptionWrapper, tok, attached, encrParts, true);
+                handleEncryptedSignedHeaders(encrParts, sigParts);
+                
                 if (!isRequestor()) {
                     addSignatureConfirmation(sigParts);
                 }
@@ -327,13 +327,14 @@ public class SymmetricBindingHandler extends AbstractBindingBuilder {
             }
         
             //Add timestamp
-            List<WSEncryptionPart> sigs = getSignedParts();
+            List<WSEncryptionPart> sigs = new ArrayList<WSEncryptionPart>();
             if (timestampEl != null) {
                 WSEncryptionPart timestampPart = convertToEncryptionPart(timestampEl.getElement());
                 sigs.add(timestampPart);        
             }
 
             addSupportingTokens(sigs);
+            sigs.addAll(getSignedParts(null));
             if (isRequestor()) {
                 if (!sigs.isEmpty()) {
                     signatures.add(doSignature(sigs, sigAbstractTokenWrapper, sigToken, sigTok, tokIncluded));

http://git-wip-us.apache.org/repos/asf/cxf/blob/f2dc0d49/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyvalidators/AbstractSupportingTokenPolicyValidator.java
----------------------------------------------------------------------
diff --git a/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyvalidators/AbstractSupportingTokenPolicyValidator.java b/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyvalidators/AbstractSupportingTokenPolicyValidator.java
index 93cb1f6..a6419dd 100644
--- a/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyvalidators/AbstractSupportingTokenPolicyValidator.java
+++ b/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyvalidators/AbstractSupportingTokenPolicyValidator.java
@@ -23,6 +23,7 @@ import java.security.PublicKey;
 import java.security.cert.X509Certificate;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collection;
 import java.util.List;
 import java.util.Map;
 import java.util.logging.Level;
@@ -38,13 +39,14 @@ import javax.xml.xpath.XPathFactory;
 
 import org.w3c.dom.Element;
 import org.w3c.dom.NodeList;
-
 import org.apache.cxf.common.logging.LogUtils;
 import org.apache.cxf.helpers.CastUtils;
 import org.apache.cxf.helpers.DOMUtils;
 import org.apache.cxf.helpers.MapNamespaceContext;
 import org.apache.cxf.message.Message;
 import org.apache.cxf.security.transport.TLSSessionInfo;
+import org.apache.cxf.ws.policy.AssertionInfo;
+import org.apache.cxf.ws.policy.AssertionInfoMap;
 import org.apache.wss4j.common.saml.SAMLKeyInfo;
 import org.apache.wss4j.common.saml.SamlAssertionWrapper;
 import org.apache.wss4j.dom.WSConstants;
@@ -55,12 +57,17 @@ import org.apache.wss4j.dom.message.token.BinarySecurity;
 import org.apache.wss4j.dom.message.token.KerberosSecurity;
 import org.apache.wss4j.dom.message.token.PKIPathSecurity;
 import org.apache.wss4j.dom.message.token.X509Security;
+import org.apache.wss4j.policy.SP11Constants;
+import org.apache.wss4j.policy.SP12Constants;
+import org.apache.wss4j.policy.SPConstants;
+import org.apache.wss4j.policy.model.AbstractSecurityAssertion;
 import org.apache.wss4j.policy.model.EncryptedElements;
 import org.apache.wss4j.policy.model.EncryptedParts;
 import org.apache.wss4j.policy.model.Header;
 import org.apache.wss4j.policy.model.RequiredElements;
 import org.apache.wss4j.policy.model.SignedElements;
 import org.apache.wss4j.policy.model.SignedParts;
+import org.apache.wss4j.policy.model.SupportingTokens;
 
 /**
  * A base class to use to validate various SupportingToken policies.
@@ -873,4 +880,47 @@ public abstract class AbstractSupportingTokenPolicyValidator
         this.encryptedParts = encryptedParts;
     }
     
+    protected void assertSecurePartsIfTokenNotRequired(
+        SupportingTokens supportingToken, AssertionInfoMap aim
+    ) {
+        if (supportingToken.getSignedParts() != null) {
+            assertSecurePartsIfTokenNotRequired(supportingToken.getSignedParts(),
+                                                SPConstants.SIGNED_PARTS, aim);
+        }
+        if (supportingToken.getSignedElements() != null) {
+            assertSecurePartsIfTokenNotRequired(supportingToken.getSignedElements(),
+                                                SPConstants.SIGNED_ELEMENTS, aim);
+        }
+        if (supportingToken.getEncryptedParts() != null) {
+            assertSecurePartsIfTokenNotRequired(supportingToken.getEncryptedParts(),
+                                                SPConstants.ENCRYPTED_PARTS, aim);
+        }
+        if (supportingToken.getEncryptedElements() != null) {
+            assertSecurePartsIfTokenNotRequired(supportingToken.getEncryptedElements(),
+                                                SPConstants.ENCRYPTED_ELEMENTS, aim);
+        }
+    }
+
+    protected void assertSecurePartsIfTokenNotRequired(
+        AbstractSecurityAssertion securedPart, String localName, AssertionInfoMap aim
+    ) {
+        Collection<AssertionInfo> sp11Ais = aim.get(new QName(SP11Constants.SP_NS, localName));
+        if (sp11Ais != null && !sp11Ais.isEmpty()) {
+            for (AssertionInfo ai : sp11Ais) {
+                if (ai.getAssertion().equals(securedPart)) {
+                    ai.setAsserted(true);
+                }
+            }    
+        }
+
+        Collection<AssertionInfo> sp12Ais = aim.get(new QName(SP12Constants.SP_NS, localName));
+        if (sp12Ais != null && !sp12Ais.isEmpty()) {
+            for (AssertionInfo ai : sp12Ais) {
+                if (ai.getAssertion().equals(securedPart)) {
+                    ai.setAsserted(true);
+                }
+            }    
+        }
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/cxf/blob/f2dc0d49/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyvalidators/EndorsingEncryptedTokenPolicyValidator.java
----------------------------------------------------------------------
diff --git a/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyvalidators/EndorsingEncryptedTokenPolicyValidator.java b/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyvalidators/EndorsingEncryptedTokenPolicyValidator.java
index bb8b89f..cb490ba 100644
--- a/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyvalidators/EndorsingEncryptedTokenPolicyValidator.java
+++ b/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyvalidators/EndorsingEncryptedTokenPolicyValidator.java
@@ -64,13 +64,13 @@ public class EndorsingEncryptedTokenPolicyValidator extends AbstractSupportingTo
             setSignedResults(signedResults);
             setEncryptedResults(encryptedResults);
             
-            parsePolicies(ais, message);
+            parsePolicies(aim, ais, message);
         }
         
         return true;
     }
     
-    private void parsePolicies(Collection<AssertionInfo> ais, Message message) {
+    private void parsePolicies(AssertionInfoMap aim, Collection<AssertionInfo> ais, Message message) {
         for (AssertionInfo ai : ais) {
             SupportingTokens binding = (SupportingTokens)ai.getAssertion();
             ai.setAsserted(true);
@@ -83,6 +83,7 @@ public class EndorsingEncryptedTokenPolicyValidator extends AbstractSupportingTo
             List<AbstractToken> tokens = binding.getTokens();
             for (AbstractToken token : tokens) {
                 if (!isTokenRequired(token, message)) {
+                    assertSecurePartsIfTokenNotRequired(binding, aim);
                     continue;
                 }
                 

http://git-wip-us.apache.org/repos/asf/cxf/blob/f2dc0d49/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyvalidators/EndorsingTokenPolicyValidator.java
----------------------------------------------------------------------
diff --git a/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyvalidators/EndorsingTokenPolicyValidator.java b/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyvalidators/EndorsingTokenPolicyValidator.java
index af09a72..50082c3 100644
--- a/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyvalidators/EndorsingTokenPolicyValidator.java
+++ b/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyvalidators/EndorsingTokenPolicyValidator.java
@@ -64,13 +64,13 @@ public class EndorsingTokenPolicyValidator extends AbstractSupportingTokenPolicy
             setSignedResults(signedResults);
             setEncryptedResults(encryptedResults);
             
-            parsePolicies(ais, message);
+            parsePolicies(aim, ais, message);
         }
         
         return true;
     }
     
-    private void parsePolicies(Collection<AssertionInfo> ais, Message message) {
+    private void parsePolicies(AssertionInfoMap aim, Collection<AssertionInfo> ais, Message message) {
         for (AssertionInfo ai : ais) {
             SupportingTokens binding = (SupportingTokens)ai.getAssertion();
             ai.setAsserted(true);
@@ -83,6 +83,7 @@ public class EndorsingTokenPolicyValidator extends AbstractSupportingTokenPolicy
             List<AbstractToken> tokens = binding.getTokens();
             for (AbstractToken token : tokens) {
                 if (!isTokenRequired(token, message)) {
+                    assertSecurePartsIfTokenNotRequired(binding, aim);
                     continue;
                 }
                 

http://git-wip-us.apache.org/repos/asf/cxf/blob/f2dc0d49/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyvalidators/SignedEndorsingEncryptedTokenPolicyValidator.java
----------------------------------------------------------------------
diff --git a/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyvalidators/SignedEndorsingEncryptedTokenPolicyValidator.java b/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyvalidators/SignedEndorsingEncryptedTokenPolicyValidator.java
index 8ecc843..da0640b 100644
--- a/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyvalidators/SignedEndorsingEncryptedTokenPolicyValidator.java
+++ b/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyvalidators/SignedEndorsingEncryptedTokenPolicyValidator.java
@@ -65,13 +65,13 @@ public class SignedEndorsingEncryptedTokenPolicyValidator extends AbstractSuppor
             setSignedResults(signedResults);
             setEncryptedResults(encryptedResults);
             
-            parsePolicies(ais, message);
+            parsePolicies(aim, ais, message);
         }
         
         return true;
     }
     
-    private void parsePolicies(Collection<AssertionInfo> ais, Message message) {
+    private void parsePolicies(AssertionInfoMap aim, Collection<AssertionInfo> ais, Message message) {
         for (AssertionInfo ai : ais) {
             SupportingTokens binding = (SupportingTokens)ai.getAssertion();
             ai.setAsserted(true);
@@ -84,6 +84,7 @@ public class SignedEndorsingEncryptedTokenPolicyValidator extends AbstractSuppor
             List<AbstractToken> tokens = binding.getTokens();
             for (AbstractToken token : tokens) {
                 if (!isTokenRequired(token, message)) {
+                    assertSecurePartsIfTokenNotRequired(binding, aim);
                     continue;
                 }
                 

http://git-wip-us.apache.org/repos/asf/cxf/blob/f2dc0d49/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyvalidators/SignedEndorsingTokenPolicyValidator.java
----------------------------------------------------------------------
diff --git a/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyvalidators/SignedEndorsingTokenPolicyValidator.java b/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyvalidators/SignedEndorsingTokenPolicyValidator.java
index 9077e7c..5262e7f 100644
--- a/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyvalidators/SignedEndorsingTokenPolicyValidator.java
+++ b/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyvalidators/SignedEndorsingTokenPolicyValidator.java
@@ -64,13 +64,13 @@ public class SignedEndorsingTokenPolicyValidator extends AbstractSupportingToken
             setSignedResults(signedResults);
             setEncryptedResults(encryptedResults);
 
-            parsePolicies(ais, message);
+            parsePolicies(aim, ais, message);
         }
         
         return true;
     }
     
-    private void parsePolicies(Collection<AssertionInfo> ais, Message message) {
+    private void parsePolicies(AssertionInfoMap aim, Collection<AssertionInfo> ais, Message message) {
         for (AssertionInfo ai : ais) {
             SupportingTokens binding = (SupportingTokens)ai.getAssertion();
             ai.setAsserted(true);
@@ -83,6 +83,7 @@ public class SignedEndorsingTokenPolicyValidator extends AbstractSupportingToken
             List<AbstractToken> tokens = binding.getTokens();
             for (AbstractToken token : tokens) {
                 if (!isTokenRequired(token, message)) {
+                    assertSecurePartsIfTokenNotRequired(binding, aim);
                     continue;
                 }
                 

http://git-wip-us.apache.org/repos/asf/cxf/blob/f2dc0d49/systests/ws-security/src/test/java/org/apache/cxf/systest/ws/x509/X509TokenTest.java
----------------------------------------------------------------------
diff --git a/systests/ws-security/src/test/java/org/apache/cxf/systest/ws/x509/X509TokenTest.java b/systests/ws-security/src/test/java/org/apache/cxf/systest/ws/x509/X509TokenTest.java
index 633116c..ae4ab7f 100644
--- a/systests/ws-security/src/test/java/org/apache/cxf/systest/ws/x509/X509TokenTest.java
+++ b/systests/ws-security/src/test/java/org/apache/cxf/systest/ws/x509/X509TokenTest.java
@@ -769,6 +769,35 @@ public class X509TokenTest extends AbstractBusClientServerTestBase {
     }
     
     @org.junit.Test
+    public void testAsymmetricEndorsing() throws Exception {
+
+        SpringBusFactory bf = new SpringBusFactory();
+        URL busFile = X509TokenTest.class.getResource("client.xml");
+
+        Bus bus = bf.createBus(busFile.toString());
+        SpringBusFactory.setDefaultBus(bus);
+        SpringBusFactory.setThreadDefaultBus(bus);
+
+        URL wsdl = X509TokenTest.class.getResource("DoubleItX509.wsdl");
+        Service service = Service.create(wsdl, SERVICE_QNAME);
+        QName portQName = new QName(NAMESPACE, "DoubleItAsymmetricEndorsingPort");
+        DoubleItPortType x509Port = 
+                service.getPort(portQName, DoubleItPortType.class);
+        updateAddressPort(x509Port, test.getPort());
+        
+        if (test.isStreaming()) {
+            SecurityTestUtil.enableStreaming(x509Port);
+        }
+        
+        if (!test.isStreaming() && !STAX_PORT.equals(test.getPort())) {
+            x509Port.doubleIt(25);
+        }
+        
+        ((java.io.Closeable)x509Port).close();
+        bus.shutdown(true);
+    }
+  
+    @org.junit.Test
     public void testSymmetricUsernameToken() throws Exception {
 
         SpringBusFactory bf = new SpringBusFactory();

http://git-wip-us.apache.org/repos/asf/cxf/blob/f2dc0d49/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/x509/DoubleItX509.wsdl
----------------------------------------------------------------------
diff --git a/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/x509/DoubleItX509.wsdl b/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/x509/DoubleItX509.wsdl
index 2e170ff..567af07 100644
--- a/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/x509/DoubleItX509.wsdl
+++ b/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/x509/DoubleItX509.wsdl
@@ -415,6 +415,22 @@
             </wsdl:fault>
         </wsdl:operation>
     </wsdl:binding>
+    <wsdl:binding name="DoubleItAsymmetricEndorsingBinding" type="tns:DoubleItPortType">
+        <wsp:PolicyReference URI="#DoubleItAsymmetricEndorsingPolicy"/>
+        <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
+        <wsdl:operation name="DoubleIt">
+            <soap:operation soapAction=""/>
+            <wsdl:input>
+                <soap:body use="literal"/>
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal"/>
+            </wsdl:output>
+            <wsdl:fault name="DoubleItFault">
+                <soap:body use="literal" name="DoubleItFault"/>
+            </wsdl:fault>
+        </wsdl:operation>
+    </wsdl:binding>
     <wsdl:binding name="DoubleItSymmetricUsernameTokenBinding" type="tns:DoubleItPortType">
         <wsp:PolicyReference URI="#DoubleItSymmetricUsernameTokenPolicy"/>
         <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
@@ -659,6 +675,9 @@
         <wsdl:port name="DoubleItAsymmetricUsernameTokenPort" binding="tns:DoubleItAsymmetricUsernameTokenBinding">
             <soap:address location="http://localhost:9001/DoubleItX509AsymmetricUsernameToken"/>
         </wsdl:port>
+        <wsdl:port name="DoubleItAsymmetricEndorsingPort" binding="tns:DoubleItAsymmetricEndorsingBinding">
+            <soap:address location="http://localhost:9001/DoubleItX509AsymmetricEndorsing"/>
+        </wsdl:port>
         <wsdl:port name="DoubleItSymmetricUsernameTokenPort" binding="tns:DoubleItSymmetricUsernameTokenBinding">
             <soap:address location="http://localhost:9001/DoubleItX509SymmetricUsernameToken"/>
         </wsdl:port>
@@ -1411,6 +1430,59 @@
             </wsp:All>
         </wsp:ExactlyOne>
     </wsp:Policy>
+    <wsp:Policy wsu:Id="DoubleItAsymmetricEndorsingPolicy">
+        <wsp:ExactlyOne>
+            <wsp:All>
+                <sp:AsymmetricBinding>
+                    <wsp:Policy>
+                        <sp:InitiatorToken>
+                            <wsp:Policy>
+                                <sp:X509Token sp:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/AlwaysToRecipient">
+                                    <wsp:Policy>
+                                        <sp:WssX509V3Token10/>
+                                    </wsp:Policy>
+                                </sp:X509Token>
+                            </wsp:Policy>
+                        </sp:InitiatorToken>
+                        <sp:RecipientToken>
+                            <wsp:Policy>
+                                <sp:X509Token sp:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/Never">
+                                    <wsp:Policy>
+                                        <sp:WssX509V3Token10/>
+                                    </wsp:Policy>
+                                </sp:X509Token>
+                            </wsp:Policy>
+                        </sp:RecipientToken>
+                        <sp:Layout>
+                            <wsp:Policy>
+                                <sp:Lax/>
+                            </wsp:Policy>
+                        </sp:Layout>
+                        <sp:IncludeTimestamp/>
+                        <sp:OnlySignEntireHeadersAndBody/>
+                        <sp:AlgorithmSuite>
+                            <wsp:Policy>
+                                <sp:Basic128/>
+                            </wsp:Policy>
+                        </sp:AlgorithmSuite>
+                    </wsp:Policy>
+                </sp:AsymmetricBinding>
+                <sp:EndorsingSupportingTokens>
+                    <wsp:Policy>
+                        <sp:X509Token sp:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/AlwaysToRecipient">
+                            <wsp:Policy>
+                                <sp:RequireThumbprintReference/>
+                                <sp:WssX509V3Token10/>
+                            </wsp:Policy>
+                        </sp:X509Token>
+                        <sp:SignedParts>
+                            <sp:Body/>
+                        </sp:SignedParts>
+                    </wsp:Policy>
+                </sp:EndorsingSupportingTokens>
+            </wsp:All>
+        </wsp:ExactlyOne>
+    </wsp:Policy>
     <wsp:Policy wsu:Id="DoubleItSymmetricUsernameTokenPolicy">
         <wsp:ExactlyOne>
             <wsp:All>

http://git-wip-us.apache.org/repos/asf/cxf/blob/f2dc0d49/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/x509/client.xml
----------------------------------------------------------------------
diff --git a/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/x509/client.xml b/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/x509/client.xml
index a7a292b..072090d 100644
--- a/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/x509/client.xml
+++ b/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/x509/client.xml
@@ -230,6 +230,15 @@
             <entry key="ws-security.callback-handler" value="org.apache.cxf.systest.ws.common.KeystorePasswordCallback"/>
         </jaxws:properties>
     </jaxws:client>
+    <jaxws:client name="{http://www.example.org/contract/DoubleIt}DoubleItAsymmetricEndorsingPort" createdFromAPI="true">
+        <jaxws:properties>
+            <entry key="ws-security.encryption.properties" value="bob.properties"/>
+            <entry key="ws-security.encryption.username" value="bob"/>
+            <entry key="ws-security.signature.properties" value="alice.properties"/>
+            <entry key="ws-security.signature.username" value="alice"/>
+            <entry key="ws-security.callback-handler" value="org.apache.cxf.systest.ws.common.KeystorePasswordCallback"/>
+        </jaxws:properties>
+    </jaxws:client>
     <jaxws:client name="{http://www.example.org/contract/DoubleIt}DoubleItSymmetricUsernameTokenPort" createdFromAPI="true">
         <jaxws:properties>
             <entry key="ws-security.encryption.properties" value="bob.properties"/>

http://git-wip-us.apache.org/repos/asf/cxf/blob/f2dc0d49/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/x509/server.xml
----------------------------------------------------------------------
diff --git a/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/x509/server.xml b/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/x509/server.xml
index a5b968e..43aa897 100644
--- a/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/x509/server.xml
+++ b/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/x509/server.xml
@@ -238,6 +238,14 @@
             <entry key="ws-security.subject.cert.constraints" value=".*O=apache.org.*"/>
         </jaxws:properties>
     </jaxws:endpoint>
+    <jaxws:endpoint xmlns:s="http://www.example.org/contract/DoubleIt" id="AsymmetricEndorsing" address="http://localhost:${testutil.ports.Server}/DoubleItX509AsymmetricEndorsing" serviceName="s:DoubleItService" endpointName="s:DoubleItAsymmetricEndorsingPort" implementor="org.apache.cxf.systest.ws.common.DoubleItImpl" wsdlLocation="org/apache/cxf/systest/ws/x509/DoubleItX509.wsdl">
+        <jaxws:properties>
+            <entry key="ws-security.callback-handler" value="org.apache.cxf.systest.ws.common.KeystorePasswordCallback"/>
+            <entry key="ws-security.signature.properties" value="bob.properties"/>
+            <entry key="ws-security.encryption.username" value="useReqSigCert"/>
+            <entry key="ws-security.subject.cert.constraints" value=".*O=apache.org.*"/>
+        </jaxws:properties>
+    </jaxws:endpoint>
     <jaxws:endpoint xmlns:s="http://www.example.org/contract/DoubleIt" id="SymmetricUsernameToken" address="http://localhost:${testutil.ports.Server}/DoubleItX509SymmetricUsernameToken" serviceName="s:DoubleItService" endpointName="s:DoubleItSymmetricUsernameTokenPort" implementor="org.apache.cxf.systest.ws.common.DoubleItImpl" wsdlLocation="org/apache/cxf/systest/ws/x509/DoubleItX509.wsdl">
         <jaxws:properties>
             <entry key="ws-security.callback-handler" value="org.apache.cxf.systest.ws.common.KeystorePasswordCallback"/>

http://git-wip-us.apache.org/repos/asf/cxf/blob/f2dc0d49/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/x509/stax-server.xml
----------------------------------------------------------------------
diff --git a/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/x509/stax-server.xml b/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/x509/stax-server.xml
index f068c93..6c88e53 100644
--- a/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/x509/stax-server.xml
+++ b/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/x509/stax-server.xml
@@ -263,6 +263,15 @@
             <entry key="ws-security.enable.streaming" value="true"/>
         </jaxws:properties>
     </jaxws:endpoint>
+    <jaxws:endpoint xmlns:s="http://www.example.org/contract/DoubleIt" id="AsymmetricEndorsing" address="http://localhost:${testutil.ports.StaxServer}/DoubleItX509AsymmetricEndorsing" serviceName="s:DoubleItService" endpointName="s:DoubleItAsymmetricEndorsingPort" implementor="org.apache.cxf.systest.ws.common.DoubleItImpl" wsdlLocation="org/apache/cxf/systest/ws/x509/DoubleItX509.wsdl">
+        <jaxws:properties>
+            <entry key="ws-security.callback-handler" value="org.apache.cxf.systest.ws.common.KeystorePasswordCallback"/>
+            <entry key="ws-security.signature.properties" value="bob.properties"/>
+            <entry key="ws-security.encryption.username" value="useReqSigCert"/>
+            <entry key="ws-security.subject.cert.constraints" value=".*O=apache.org.*"/>
+            <entry key="ws-security.enable.streaming" value="true"/>
+        </jaxws:properties>
+    </jaxws:endpoint>
     <jaxws:endpoint xmlns:s="http://www.example.org/contract/DoubleIt" id="SymmetricUsernameToken" address="http://localhost:${testutil.ports.StaxServer}/DoubleItX509SymmetricUsernameToken" serviceName="s:DoubleItService" endpointName="s:DoubleItSymmetricUsernameTokenPort" implementor="org.apache.cxf.systest.ws.common.DoubleItImpl" wsdlLocation="org/apache/cxf/systest/ws/x509/DoubleItX509.wsdl">
         <jaxws:properties>
             <entry key="ws-security.callback-handler" value="org.apache.cxf.systest.ws.common.KeystorePasswordCallback"/>