You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ws.apache.org by gi...@apache.org on 2012/12/08 18:41:52 UTC

svn commit: r1418719 - in /webservices/wss4j/trunk/ws-security-stax/src: main/java/org/apache/ws/security/stax/ext/ main/java/org/apache/ws/security/stax/impl/processor/input/ main/java/org/apache/ws/security/stax/impl/securityToken/ test/java/org/apac...

Author: giger
Date: Sat Dec  8 17:41:50 2012
New Revision: 1418719

URL: http://svn.apache.org/viewvc?rev=1418719&view=rev
Log:
WSS-373 - Check sender-vouches and holder-of-key requirements for SAML tokens.

Modified:
    webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/ws/security/stax/ext/InboundWSSec.java
    webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/ws/security/stax/impl/processor/input/SAMLTokenInputHandler.java
    webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/ws/security/stax/impl/processor/input/WSSSignatureReferenceVerifyInputProcessor.java
    webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/ws/security/stax/impl/securityToken/SAMLSecurityToken.java
    webservices/wss4j/trunk/ws-security-stax/src/test/java/org/apache/ws/security/stax/test/saml/SAMLTokenHOKTest.java
    webservices/wss4j/trunk/ws-security-stax/src/test/java/org/apache/ws/security/stax/test/saml/SAMLTokenSVTest.java
    webservices/wss4j/trunk/ws-security-stax/src/test/java/org/apache/ws/security/stax/test/saml/SAMLTokenTest.java

Modified: webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/ws/security/stax/ext/InboundWSSec.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/ws/security/stax/ext/InboundWSSec.java?rev=1418719&r1=1418718&r2=1418719&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/ws/security/stax/ext/InboundWSSec.java (original)
+++ webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/ws/security/stax/ext/InboundWSSec.java Sat Dec  8 17:41:50 2012
@@ -28,13 +28,17 @@ import org.apache.ws.security.stax.impl.
 import org.apache.ws.security.stax.securityEvent.WSSecurityEventConstants;
 import org.apache.xml.security.exceptions.XMLSecurityException;
 import org.apache.xml.security.stax.ext.InputProcessor;
+import org.apache.xml.security.stax.ext.SecurityToken;
+import org.apache.xml.security.stax.ext.SecurityTokenProvider;
 import org.apache.xml.security.stax.impl.DocumentContextImpl;
 import org.apache.xml.security.stax.impl.InputProcessorChainImpl;
 import org.apache.xml.security.stax.impl.XMLSecurityStreamReader;
 import org.apache.xml.security.stax.impl.processor.input.LogInputProcessor;
 import org.apache.xml.security.stax.impl.processor.input.XMLEventReaderInputProcessor;
+import org.apache.xml.security.stax.impl.util.IDGenerator;
 import org.apache.xml.security.stax.securityEvent.SecurityEvent;
 import org.apache.xml.security.stax.securityEvent.SecurityEventListener;
+import org.apache.xml.security.stax.securityEvent.TokenSecurityEvent;
 
 import javax.xml.stream.XMLInputFactory;
 import javax.xml.stream.XMLStreamException;
@@ -133,10 +137,36 @@ public class InboundWSSec {
                 Iterator<SecurityEvent> securityEventIterator = requestSecurityEvents.iterator();
                 while (securityEventIterator.hasNext()) {
                     SecurityEvent securityEvent = securityEventIterator.next();
-                    if (securityEvent.getSecurityEventType() == WSSecurityEventConstants.HttpsToken) {
-                        securityContextImpl.registerSecurityEvent(securityEvent);
-                        securityContextImpl.put(WSSConstants.TRANSPORT_SECURITY_ACTIVE, Boolean.TRUE);
-                        break;
+                    if (securityEvent instanceof TokenSecurityEvent) {
+                        final TokenSecurityEvent tokenSecurityEvent = (TokenSecurityEvent)securityEvent;
+
+                        if (securityEvent.getSecurityEventType() == WSSecurityEventConstants.HttpsToken) {
+                            securityContextImpl.registerSecurityEvent(securityEvent);
+                            securityContextImpl.put(WSSConstants.TRANSPORT_SECURITY_ACTIVE, Boolean.TRUE);
+                        }
+
+                        SecurityTokenProvider securityTokenProvider = new SecurityTokenProvider() {
+
+                            private String id;
+
+                            @SuppressWarnings("unchecked")
+                            @Override
+                            public SecurityToken getSecurityToken() throws XMLSecurityException {
+                                return tokenSecurityEvent.getSecurityToken();
+                            }
+
+                            @Override
+                            public String getId() {
+                                if (this.id == null) {
+                                    this.id = tokenSecurityEvent.getSecurityToken().getId();
+                                    if (this.id == null) {
+                                        this.id = IDGenerator.generateID(null);
+                                    }
+                                }
+                                return this.id;
+                            }
+                        };
+                        securityContextImpl.registerSecurityTokenProvider(securityTokenProvider.getId(), securityTokenProvider);
                     }
                 }
             } catch (XMLSecurityException e) {

Modified: webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/ws/security/stax/impl/processor/input/SAMLTokenInputHandler.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/ws/security/stax/impl/processor/input/SAMLTokenInputHandler.java?rev=1418719&r1=1418718&r2=1418719&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/ws/security/stax/impl/processor/input/SAMLTokenInputHandler.java (original)
+++ webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/ws/security/stax/impl/processor/input/SAMLTokenInputHandler.java Sat Dec  8 17:41:50 2012
@@ -29,6 +29,7 @@ import org.apache.ws.security.common.sam
 import org.apache.ws.security.common.saml.SAMLUtil;
 import org.apache.ws.security.stax.ext.WSSConstants;
 import org.apache.ws.security.stax.ext.WSSSecurityProperties;
+import org.apache.ws.security.stax.ext.WSSUtils;
 import org.apache.ws.security.stax.ext.WSSecurityContext;
 import org.apache.ws.security.stax.impl.securityToken.SAMLSecurityToken;
 import org.apache.ws.security.stax.securityEvent.SamlTokenSecurityEvent;
@@ -46,6 +47,10 @@ import org.apache.xml.security.stax.ext.
 import org.apache.xml.security.stax.impl.XMLSecurityEventReader;
 import org.apache.xml.security.stax.impl.securityToken.AbstractInboundSecurityToken;
 import org.apache.xml.security.stax.impl.securityToken.SecurityTokenFactory;
+import org.apache.xml.security.stax.securityEvent.SecurityEvent;
+import org.apache.xml.security.stax.securityEvent.SecurityEventConstants;
+import org.apache.xml.security.stax.securityEvent.SecurityEventListener;
+import org.apache.xml.security.stax.securityEvent.SignedElementSecurityEvent;
 import org.joda.time.DateTime;
 import org.opensaml.common.SAMLVersion;
 import org.opensaml.security.SAMLSignatureProfileValidator;
@@ -67,13 +72,14 @@ import javax.xml.namespace.QName;
 import javax.xml.parsers.DocumentBuilderFactory;
 import javax.xml.parsers.ParserConfigurationException;
 import javax.xml.stream.XMLStreamConstants;
+import javax.xml.stream.XMLStreamException;
 import javax.xml.stream.events.Comment;
 import javax.xml.stream.events.Namespace;
 import javax.xml.stream.events.ProcessingInstruction;
 import java.security.Key;
-import java.util.Deque;
-import java.util.Iterator;
-import java.util.List;
+import java.security.PublicKey;
+import java.security.cert.X509Certificate;
+import java.util.*;
 
 /**
  * Processor for the SAML Assertion XML Structure
@@ -86,8 +92,13 @@ public class SAMLTokenInputHandler exten
     private static final transient Log log = LogFactory.getLog(SAMLTokenInputHandler.class);
     private static final DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
 
+    private static final List<QName> saml1TokenPath = new ArrayList<QName>(WSSConstants.WSSE_SECURITY_HEADER_PATH);
+    private static final List<QName> saml2TokenPath = new ArrayList<QName>(WSSConstants.WSSE_SECURITY_HEADER_PATH);
+
     static {
         documentBuilderFactory.setNamespaceAware(true);
+        saml1TokenPath.add(WSSConstants.TAG_saml_Assertion);
+        saml2TokenPath.add(WSSConstants.TAG_saml2_Assertion);
     }
 
     /**
@@ -260,6 +271,11 @@ public class SAMLTokenInputHandler exten
         samlTokenSecurityEvent.setSecurityToken((SecurityToken) securityTokenProvider.getSecurityToken());
         samlTokenSecurityEvent.setCorrelationID(samlAssertionWrapper.getId());
         inputProcessorChain.getSecurityContext().registerSecurityEvent(samlTokenSecurityEvent);
+
+        SAMLTokenVerifierInputProcessor samlTokenVerifierInputProcessor =
+                new SAMLTokenVerifierInputProcessor(securityProperties, samlAssertionWrapper, securityTokenProvider, subjectSecurityToken);
+        inputProcessorChain.getSecurityContext().addSecurityEventListener(samlTokenVerifierInputProcessor);
+        inputProcessorChain.addProcessor(samlTokenVerifierInputProcessor);
     }
 
     private int getSubjectKeyInfoIndex(Deque<XMLSecEvent> eventQueue) {
@@ -614,4 +630,190 @@ public class SAMLTokenInputHandler exten
             }
         }
     }
+
+    /**
+     * Processor to check the holder-of-key or sender-vouches requirements against the received assertion
+     * which can not be done until the whole soap-header is processed and we now that the whole soap-body
+     * is signed.
+     */
+    class SAMLTokenVerifierInputProcessor extends AbstractInputProcessor implements SecurityEventListener {
+
+        private SamlAssertionWrapper samlAssertionWrapper;
+        private SecurityTokenProvider securityTokenProvider;
+        private SecurityToken subjectSecurityToken;
+        private List<SignedElementSecurityEvent> samlTokenSignedElementSecurityEvents = new ArrayList<SignedElementSecurityEvent>();
+        private SignedElementSecurityEvent bodySignedElementSecurityEvent;
+
+        SAMLTokenVerifierInputProcessor(XMLSecurityProperties securityProperties, SamlAssertionWrapper samlAssertionWrapper,
+                                        SecurityTokenProvider securityTokenProvider, SecurityToken subjectSecurityToken) {
+            super(securityProperties);
+            this.setPhase(XMLSecurityConstants.Phase.POSTPROCESSING);
+            this.addAfterProcessor(OperationInputProcessor.class.getName());
+            this.samlAssertionWrapper = samlAssertionWrapper;
+            this.securityTokenProvider = securityTokenProvider;
+            this.subjectSecurityToken = subjectSecurityToken;
+        }
+
+        @Override
+        public void registerSecurityEvent(SecurityEvent securityEvent) throws XMLSecurityException {
+            if (securityEvent.getSecurityEventType() == SecurityEventConstants.SignedElement) {
+                SignedElementSecurityEvent signedElementSecurityEvent = (SignedElementSecurityEvent)securityEvent;
+
+                List<QName> elementPath = signedElementSecurityEvent.getElementPath();
+                if (elementPath.equals(WSSConstants.SOAP_11_BODY_PATH)) {
+                    bodySignedElementSecurityEvent = signedElementSecurityEvent;
+                } else if (elementPath.equals(saml2TokenPath) || elementPath.equals(saml1TokenPath)) {
+                    samlTokenSignedElementSecurityEvents.add(signedElementSecurityEvent);
+                }
+            }
+        }
+
+        @Override
+        public XMLSecEvent processNextHeaderEvent(InputProcessorChain inputProcessorChain)
+                throws XMLStreamException, XMLSecurityException {
+            return inputProcessorChain.processHeaderEvent();
+        }
+
+        @Override
+        public XMLSecEvent processNextEvent(InputProcessorChain inputProcessorChain)
+                throws XMLStreamException, XMLSecurityException {
+
+            XMLSecEvent xmlSecEvent = inputProcessorChain.processEvent();
+            if (xmlSecEvent.getEventType() == XMLStreamConstants.START_ELEMENT) {
+                XMLSecStartElement xmlSecStartElement = xmlSecEvent.asStartElement();
+                List<QName> elementPath = xmlSecStartElement.getElementPath();
+                if (elementPath.size() == 3 && WSSUtils.isInSOAPBody(elementPath)) {
+                    inputProcessorChain.removeProcessor(this);
+                    checkPossessionOfKey(inputProcessorChain, samlAssertionWrapper, subjectSecurityToken);
+                }
+            }
+            return xmlSecEvent;
+        }
+
+        private void checkPossessionOfKey(
+                InputProcessorChain inputProcessorChain, SamlAssertionWrapper samlAssertionWrapper,
+                SecurityToken subjectSecurityToken) throws WSSecurityException {
+
+            try {
+                SecurityToken httpsSecurityToken = getHttpsSecurityToken(inputProcessorChain);
+
+                List<SecurityTokenProvider> securityTokenProviders =
+                        inputProcessorChain.getSecurityContext().getRegisteredSecurityTokenProviders();
+
+                List<String> confirmationMethods = samlAssertionWrapper.getConfirmationMethods();
+                for (int i = 0; i < confirmationMethods.size(); i++) {
+                    String confirmationMethod = confirmationMethods.get(i);
+                    if (OpenSAMLUtil.isMethodHolderOfKey(confirmationMethod)) {
+
+                        X509Certificate[] subjectCertificates = subjectSecurityToken.getX509Certificates();
+                        PublicKey subjectPublicKey = subjectSecurityToken.getPublicKey();
+                        Key subjectSecretKey = null;
+                        Map<String, Key> subjectKeyMap = subjectSecurityToken.getSecretKey();
+                        if (subjectKeyMap.size() > 0) {
+                            subjectSecretKey = subjectKeyMap.values().toArray(new Key[subjectKeyMap.size()])[0];
+                        }
+
+                        /**
+                         * Check the holder-of-key requirements against the received assertion. The subject
+                         * credential of the SAML Assertion must have been used to sign some portion of
+                         * the message, thus showing proof-of-possession of the private/secret key. Alternatively,
+                         * the subject credential of the SAML Assertion must match a client certificate credential
+                         * when 2-way TLS is used.
+                         */
+
+                        //compare https token first:
+                        if (httpsSecurityToken != null
+                                && httpsSecurityToken.getX509Certificates() != null
+                                && httpsSecurityToken.getX509Certificates().length > 0) {
+
+                            X509Certificate httpsCertificate = httpsSecurityToken.getX509Certificates()[0];
+
+                            //compare certificates:
+                            if (subjectCertificates != null && subjectCertificates.length > 0
+                                    && httpsCertificate.equals(subjectCertificates[0])) {
+                                    return;
+                                //compare public keys:
+                            } else if (httpsCertificate.getPublicKey().equals(subjectPublicKey)) {
+                                    return;
+                            }
+                        } else {
+                            for (int j = 0; j < securityTokenProviders.size(); j++) {
+                                SecurityTokenProvider securityTokenProvider = securityTokenProviders.get(j);
+                                SecurityToken securityToken = securityTokenProvider.getSecurityToken();
+                                if (securityToken == httpsSecurityToken) {
+                                    continue;
+                                }
+                                X509Certificate[] x509Certificates = securityToken.getX509Certificates();
+                                PublicKey publicKey = securityToken.getPublicKey();
+                                Map<String, Key> keyMap = securityToken.getSecretKey();
+                                if (x509Certificates != null && x509Certificates.length > 0
+                                        && subjectCertificates != null && subjectCertificates.length > 0 &&
+                                        subjectCertificates[0].equals(x509Certificates[0])) {
+                                        return;
+                                }
+                                if (publicKey != null && publicKey.equals(subjectPublicKey)) {
+                                    return;
+                                }
+                                 Iterator<Map.Entry<String,Key>> iterator = keyMap.entrySet().iterator();
+                                 while(iterator.hasNext()){
+                                     Map.Entry<String,Key> next = iterator.next();
+                                     if (next.getValue().equals(subjectSecretKey)) {
+                                         return;
+                                     }
+                                 }
+                            }
+                        }
+                    }
+                    else if (OpenSAMLUtil.isMethodSenderVouches(confirmationMethod)) {
+                        /**
+                         * Check the sender-vouches requirements against the received assertion. The SAML
+                         * Assertion and the SOAP Body must be signed by the same signature.
+                         */
+
+                        //
+                        // If we have a 2-way TLS connection, then we don't have to check that the
+                        // assertion + SOAP body are signed
+                        if (httpsSecurityToken != null
+                                && httpsSecurityToken.getX509Certificates() != null
+                                && httpsSecurityToken.getX509Certificates().length > 0) {
+                            return;
+                        }
+
+                        SignedElementSecurityEvent samlTokenSignedElementSecurityEvent = null;
+                        for (int j = 0; j < samlTokenSignedElementSecurityEvents.size(); j++) {
+                            SignedElementSecurityEvent signedElementSecurityEvent = samlTokenSignedElementSecurityEvents.get(j);
+                            if (((SecurityToken)securityTokenProvider.getSecurityToken()).getXMLSecEvent() ==
+                                    signedElementSecurityEvent.getXmlSecEvent()) {
+
+                                samlTokenSignedElementSecurityEvent = signedElementSecurityEvent;
+                            }
+                        }
+                        if (bodySignedElementSecurityEvent != null &&
+                                samlTokenSignedElementSecurityEvent != null &&
+                                bodySignedElementSecurityEvent.getSecurityToken() ==
+                                        samlTokenSignedElementSecurityEvent.getSecurityToken()) {
+                            return;
+                        }
+                    }
+                }
+            } catch (XMLSecurityException e) {
+                throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, e);
+            }
+            throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_AUTHENTICATION,
+                    "empty", "SAML proof-of-possession of the private/secret key failed");
+        }
+
+        private SecurityToken getHttpsSecurityToken(InputProcessorChain inputProcessorChain) throws XMLSecurityException {
+            List<SecurityTokenProvider> securityTokenProviders =
+                    inputProcessorChain.getSecurityContext().getRegisteredSecurityTokenProviders();
+            for (int i = 0; i < securityTokenProviders.size(); i++) {
+                SecurityTokenProvider securityTokenProvider = securityTokenProviders.get(i);
+                SecurityToken securityToken = securityTokenProvider.getSecurityToken();
+                if (securityToken.getTokenType() == WSSConstants.HttpsToken) {
+                    return securityToken;
+                }
+            }
+            return null;
+        }
+    }
 }

Modified: webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/ws/security/stax/impl/processor/input/WSSSignatureReferenceVerifyInputProcessor.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/ws/security/stax/impl/processor/input/WSSSignatureReferenceVerifyInputProcessor.java?rev=1418719&r1=1418718&r2=1418719&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/ws/security/stax/impl/processor/input/WSSSignatureReferenceVerifyInputProcessor.java (original)
+++ webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/ws/security/stax/impl/processor/input/WSSSignatureReferenceVerifyInputProcessor.java Sat Dec  8 17:41:50 2012
@@ -32,6 +32,7 @@ import org.apache.xml.security.binding.x
 import org.apache.xml.security.exceptions.XMLSecurityException;
 import org.apache.xml.security.stax.ext.*;
 import org.apache.xml.security.stax.ext.stax.XMLSecEvent;
+import org.apache.xml.security.stax.ext.stax.XMLSecStartElement;
 import org.apache.xml.security.stax.impl.processor.input.AbstractSignatureReferenceVerifyInputProcessor;
 import org.apache.xml.security.stax.securityEvent.AlgorithmSuiteSecurityEvent;
 import org.apache.xml.security.stax.securityEvent.SignedElementSecurityEvent;
@@ -180,14 +181,14 @@ public class WSSSignatureReferenceVerify
     @Override
     protected InternalSignatureReferenceVerifier getSignatureReferenceVerifier(
             XMLSecurityProperties securityProperties, InputProcessorChain inputProcessorChain,
-            ReferenceType referenceType, QName startElement) throws XMLSecurityException {
+            ReferenceType referenceType, XMLSecStartElement startElement) throws XMLSecurityException {
         return new InternalSignatureReferenceVerifier((WSSSecurityProperties) securityProperties,
-                inputProcessorChain, referenceType,
-                startElement);
+                inputProcessorChain, referenceType, startElement);
     }
 
     private void detectReplayAttack(InputProcessorChain inputProcessorChain) throws WSSecurityException {
-        TimestampSecurityEvent timestampSecurityEvent = inputProcessorChain.getSecurityContext().get(WSSConstants.PROP_TIMESTAMP_SECURITYEVENT);
+        TimestampSecurityEvent timestampSecurityEvent =
+                inputProcessorChain.getSecurityContext().get(WSSConstants.PROP_TIMESTAMP_SECURITYEVENT);
         if (timestampSecurityEvent != null) {
             final String cacheKey = String.valueOf(
                     timestampSecurityEvent.getCreated().getTimeInMillis()) +
@@ -285,7 +286,8 @@ public class WSSSignatureReferenceVerify
             SecurityTokenReference securityTokenReference = (SecurityTokenReference) securityToken;
             //todo analyse and fix me: the following statement could be problematic
             inputProcessorChain.getDocumentContext().setIsInSignedContent(inputProcessorChain.getProcessors().indexOf(internalSignatureReferenceVerifier), internalSignatureReferenceVerifier);
-            internalSignatureReferenceVerifier.setStartElement(securityTokenReference.getXmlSecEvents().getLast().asStartElement().getName());
+            XMLSecStartElement xmlSecStartElement = securityTokenReference.getXmlSecEvents().getLast().asStartElement();
+            internalSignatureReferenceVerifier.setStartElement(xmlSecStartElement);
             Iterator<XMLSecEvent> xmlSecEventIterator = securityTokenReference.getXmlSecEvents().descendingIterator();
             try {
                 while (xmlSecEventIterator.hasNext()) {
@@ -301,8 +303,8 @@ public class WSSSignatureReferenceVerify
     class InternalSignatureReferenceVerifier extends AbstractSignatureReferenceVerifyInputProcessor.InternalSignatureReferenceVerifier {
 
         InternalSignatureReferenceVerifier(WSSSecurityProperties securityProperties, InputProcessorChain inputProcessorChain,
-                                           ReferenceType referenceType, QName startElementName) throws XMLSecurityException {
-            super(securityProperties, inputProcessorChain, referenceType, startElementName);
+                                           ReferenceType referenceType, XMLSecStartElement startElement) throws XMLSecurityException {
+            super(securityProperties, inputProcessorChain, referenceType, startElement);
             this.addAfterProcessor(WSSSignatureReferenceVerifyInputProcessor.class.getName());
         }
 

Modified: webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/ws/security/stax/impl/securityToken/SAMLSecurityToken.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/ws/security/stax/impl/securityToken/SAMLSecurityToken.java?rev=1418719&r1=1418718&r2=1418719&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/ws/security/stax/impl/securityToken/SAMLSecurityToken.java (original)
+++ webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/ws/security/stax/impl/securityToken/SAMLSecurityToken.java Sat Dec  8 17:41:50 2012
@@ -55,25 +55,6 @@ public class SAMLSecurityToken extends A
         this.subjectSecurityToken = subjectSecurityToken;
     }
 
-    public SAMLSecurityToken(SAMLVersion samlVersion, Key secretKey, PublicKey publicKey,
-                             X509Certificate[] x509Certificates, String issuer,
-                             WSSecurityContext wsSecurityContext, Crypto crypto,
-                             String id, WSSConstants.KeyIdentifierType keyIdentifierType) {
-        super(wsSecurityContext, id, keyIdentifierType);
-        this.samlVersion = samlVersion;
-        this.issuer = issuer;
-        this.crypto = crypto;
-        if (secretKey != null) {
-            setSecretKey("", secretKey);
-        }
-        if (publicKey != null) {
-            setPublicKey(publicKey);
-        }
-        if (x509Certificates != null) {
-            setX509Certificates(x509Certificates);
-        }
-    }
-
     @Override
     public boolean isAsymmetric() throws XMLSecurityException {
         if (this.subjectSecurityToken != null && this.subjectSecurityToken.isAsymmetric()) {

Modified: webservices/wss4j/trunk/ws-security-stax/src/test/java/org/apache/ws/security/stax/test/saml/SAMLTokenHOKTest.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-stax/src/test/java/org/apache/ws/security/stax/test/saml/SAMLTokenHOKTest.java?rev=1418719&r1=1418718&r2=1418719&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-stax/src/test/java/org/apache/ws/security/stax/test/saml/SAMLTokenHOKTest.java (original)
+++ webservices/wss4j/trunk/ws-security-stax/src/test/java/org/apache/ws/security/stax/test/saml/SAMLTokenHOKTest.java Sat Dec  8 17:41:50 2012
@@ -36,6 +36,8 @@ import org.apache.ws.security.stax.ext.I
 import org.apache.ws.security.stax.ext.OutboundWSSec;
 import org.apache.ws.security.stax.ext.WSSConstants;
 import org.apache.ws.security.stax.ext.WSSSecurityProperties;
+import org.apache.ws.security.stax.impl.securityToken.HttpsSecurityToken;
+import org.apache.ws.security.stax.securityEvent.HttpsTokenSecurityEvent;
 import org.apache.ws.security.stax.test.AbstractTestBase;
 import org.apache.ws.security.stax.test.CallbackHandlerImpl;
 import org.apache.ws.security.stax.test.utils.SOAPUtil;
@@ -58,6 +60,7 @@ import java.io.ByteArrayOutputStream;
 import java.io.InputStream;
 import java.security.KeyStore;
 import java.util.ArrayList;
+import java.util.List;
 import java.util.Properties;
 
 /**
@@ -514,6 +517,64 @@ public class SAMLTokenHOKTest extends Ab
     }
 
     @Test
+    public void testSAMLAssertionHOKTransportSecurityInbound() throws Exception {
+
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        {
+            SAML1CallbackHandler callbackHandler = new SAML1CallbackHandler();
+            callbackHandler.setStatement(SAML1CallbackHandler.Statement.AUTHN);
+            callbackHandler.setConfirmationMethod(SAML1Constants.CONF_HOLDER_KEY);
+            callbackHandler.setIssuer("www.example.com");
+            //callbackHandler.setResource("http://resource.org");
+
+            InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
+            String action = WSHandlerConstants.SAML_TOKEN_SIGNED;
+            Properties properties = new Properties();
+            properties.put(WSHandlerConstants.SAML_CALLBACK_REF, callbackHandler);
+            Document securedDocument = doOutboundSecurityWithWSS4J(sourceDocument, action, properties);
+
+            //some test that we can really sure we get what we want from WSS4J
+            NodeList nodeList = securedDocument.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
+            Assert.assertEquals(nodeList.getLength(), 2);
+
+            Element messageSig = (Element)nodeList.item(1);
+            messageSig.getParentNode().removeChild(messageSig);
+
+            javax.xml.transform.Transformer transformer = TRANSFORMER_FACTORY.newTransformer();
+            transformer.transform(new DOMSource(securedDocument), new StreamResult(baos));
+        }
+
+        //done signature; now test sig-verification:
+        {
+            WSSSecurityProperties securityProperties = new WSSSecurityProperties();
+            securityProperties.loadSignatureVerificationKeystore(this.getClass().getClassLoader().getResource("receiver.jks"), "default".toCharArray());
+            securityProperties.setCallbackHandler(new CallbackHandlerImpl());
+            InboundWSSec wsSecIn = WSSec.getInboundWSSec(securityProperties);
+
+            HttpsTokenSecurityEvent httpsTokenSecurityEvent = new HttpsTokenSecurityEvent();
+            httpsTokenSecurityEvent.setAuthenticationType(HttpsTokenSecurityEvent.AuthenticationType.HttpsClientCertificateAuthentication);
+            CryptoType cryptoType = new CryptoType(CryptoType.TYPE.ALIAS);
+            cryptoType.setAlias("transmitter");
+            HttpsSecurityToken httpsSecurityToken = new HttpsSecurityToken(
+                    securityProperties.getSignatureVerificationCrypto().getX509Certificates(cryptoType)[0], null);
+            httpsTokenSecurityEvent.setSecurityToken(httpsSecurityToken);
+
+            List<SecurityEvent> requestSecurityEvents = new ArrayList<SecurityEvent>();
+            requestSecurityEvents.add(httpsTokenSecurityEvent);
+
+            XMLStreamReader xmlStreamReader = wsSecIn.processInMessage(
+                    xmlInputFactory.createXMLStreamReader(new ByteArrayInputStream(baos.toByteArray())),
+                    requestSecurityEvents, null);
+
+            Document document = StAX2DOM.readDoc(documentBuilderFactory.newDocumentBuilder(), xmlStreamReader);
+
+            //header element must still be there
+            NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
+            Assert.assertEquals(nodeList.getLength(), 1);
+        }
+    }
+
+    @Test
     public void testSAML2AuthnOutbound() throws Exception {
 
         ByteArrayOutputStream baos = new ByteArrayOutputStream();

Modified: webservices/wss4j/trunk/ws-security-stax/src/test/java/org/apache/ws/security/stax/test/saml/SAMLTokenSVTest.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-stax/src/test/java/org/apache/ws/security/stax/test/saml/SAMLTokenSVTest.java?rev=1418719&r1=1418718&r2=1418719&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-stax/src/test/java/org/apache/ws/security/stax/test/saml/SAMLTokenSVTest.java (original)
+++ webservices/wss4j/trunk/ws-security-stax/src/test/java/org/apache/ws/security/stax/test/saml/SAMLTokenSVTest.java Sat Dec  8 17:41:50 2012
@@ -18,11 +18,14 @@
  */
 package org.apache.ws.security.stax.test.saml;
 
+import org.apache.ws.security.common.crypto.CryptoType;
 import org.apache.ws.security.common.saml.builder.SAML1Constants;
 import org.apache.ws.security.common.saml.builder.SAML2Constants;
 import org.apache.ws.security.dom.handler.WSHandlerConstants;
 import org.apache.ws.security.stax.WSSec;
 import org.apache.ws.security.stax.ext.*;
+import org.apache.ws.security.stax.impl.securityToken.HttpsSecurityToken;
+import org.apache.ws.security.stax.securityEvent.HttpsTokenSecurityEvent;
 import org.apache.ws.security.stax.test.AbstractTestBase;
 import org.apache.ws.security.stax.test.CallbackHandlerImpl;
 import org.apache.ws.security.stax.test.utils.StAX2DOM;
@@ -43,6 +46,7 @@ import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.InputStream;
 import java.util.ArrayList;
+import java.util.List;
 import java.util.Properties;
 
 /**
@@ -315,6 +319,60 @@ public class SAMLTokenSVTest extends Abs
     }
 
     @Test
+    public void testSAMLAssertionSVTransportSecurityInbound() throws Exception {
+
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        {
+            SAML1CallbackHandler callbackHandler = new SAML1CallbackHandler();
+            callbackHandler.setStatement(SAML1CallbackHandler.Statement.AUTHZ);
+            callbackHandler.setIssuer("www.example.com");
+            callbackHandler.setResource("http://resource.org");
+
+            InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
+            String action = WSHandlerConstants.SAML_TOKEN_UNSIGNED;
+            Properties properties = new Properties();
+            properties.put(WSHandlerConstants.SAML_CALLBACK_REF, callbackHandler);
+            Document securedDocument = doOutboundSecurityWithWSS4J(sourceDocument, action, properties);
+
+            //some test that we can really sure we get what we want from WSS4J
+            NodeList nodeList = securedDocument.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
+            Assert.assertEquals(nodeList.getLength(), 0);
+
+            javax.xml.transform.Transformer transformer = TRANSFORMER_FACTORY.newTransformer();
+            transformer.transform(new DOMSource(securedDocument), new StreamResult(baos));
+        }
+
+        //done signature; now test sig-verification:
+        {
+            WSSSecurityProperties securityProperties = new WSSSecurityProperties();
+            securityProperties.loadSignatureVerificationKeystore(this.getClass().getClassLoader().getResource("receiver.jks"), "default".toCharArray());
+            securityProperties.setCallbackHandler(new CallbackHandlerImpl());
+            InboundWSSec wsSecIn = WSSec.getInboundWSSec(securityProperties);
+
+            HttpsTokenSecurityEvent httpsTokenSecurityEvent = new HttpsTokenSecurityEvent();
+            httpsTokenSecurityEvent.setAuthenticationType(HttpsTokenSecurityEvent.AuthenticationType.HttpsClientCertificateAuthentication);
+            CryptoType cryptoType = new CryptoType(CryptoType.TYPE.ALIAS);
+            cryptoType.setAlias("transmitter");
+            HttpsSecurityToken httpsSecurityToken = new HttpsSecurityToken(
+                    securityProperties.getSignatureVerificationCrypto().getX509Certificates(cryptoType)[0], null);
+            httpsTokenSecurityEvent.setSecurityToken(httpsSecurityToken);
+
+            List<SecurityEvent> requestSecurityEvents = new ArrayList<SecurityEvent>();
+            requestSecurityEvents.add(httpsTokenSecurityEvent);
+
+            XMLStreamReader xmlStreamReader = wsSecIn.processInMessage(
+                    xmlInputFactory.createXMLStreamReader(new ByteArrayInputStream(baos.toByteArray())),
+                    requestSecurityEvents, null);
+
+            Document document = StAX2DOM.readDoc(documentBuilderFactory.newDocumentBuilder(), xmlStreamReader);
+
+            //header element must still be there
+            NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
+            Assert.assertEquals(nodeList.getLength(), 0);
+        }
+    }
+
+    @Test
     public void testSAML2AuthnAssertionOutbound() throws Exception {
 
         ByteArrayOutputStream baos = new ByteArrayOutputStream();

Modified: webservices/wss4j/trunk/ws-security-stax/src/test/java/org/apache/ws/security/stax/test/saml/SAMLTokenTest.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-stax/src/test/java/org/apache/ws/security/stax/test/saml/SAMLTokenTest.java?rev=1418719&r1=1418718&r2=1418719&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-stax/src/test/java/org/apache/ws/security/stax/test/saml/SAMLTokenTest.java (original)
+++ webservices/wss4j/trunk/ws-security-stax/src/test/java/org/apache/ws/security/stax/test/saml/SAMLTokenTest.java Sat Dec  8 17:41:50 2012
@@ -103,14 +103,15 @@ public class SAMLTokenTest extends Abstr
             callbackHandler.setIssuer("www.example.com");
 
             InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
-            String action = WSHandlerConstants.SAML_TOKEN_UNSIGNED;
+            String action = WSHandlerConstants.SAML_TOKEN_UNSIGNED + " " + WSHandlerConstants.SIGNATURE;
             Properties properties = new Properties();
             properties.put(WSHandlerConstants.SAML_CALLBACK_REF, callbackHandler);
+            properties.setProperty(WSHandlerConstants.SIGNATURE_PARTS, "{Element}{urn:oasis:names:tc:SAML:1.0:assertion}Assertion;{Element}{http://schemas.xmlsoap.org/soap/envelope/}Body;");
             Document securedDocument = doOutboundSecurityWithWSS4J(sourceDocument, action, properties);
 
             //some test that we can really sure we get what we want from WSS4J
             NodeList nodeList = securedDocument.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
-            Assert.assertEquals(nodeList.getLength(), 0);
+            Assert.assertEquals(nodeList.getLength(), 1);
 
             javax.xml.transform.Transformer transformer = TRANSFORMER_FACTORY.newTransformer();
             transformer.transform(new DOMSource(securedDocument), new StreamResult(baos));
@@ -128,7 +129,7 @@ public class SAMLTokenTest extends Abstr
 
             //header element must still be there
             NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
-            Assert.assertEquals(nodeList.getLength(), 0);
+            Assert.assertEquals(nodeList.getLength(), 1);
         }
     }
 
@@ -174,14 +175,15 @@ public class SAMLTokenTest extends Abstr
             callbackHandler.setIssuer("www.example.com");
 
             InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
-            String action = WSHandlerConstants.SAML_TOKEN_UNSIGNED;
+            String action = WSHandlerConstants.SAML_TOKEN_UNSIGNED + " " + WSHandlerConstants.SIGNATURE;
             Properties properties = new Properties();
             properties.put(WSHandlerConstants.SAML_CALLBACK_REF, callbackHandler);
+            properties.setProperty(WSHandlerConstants.SIGNATURE_PARTS, "{Element}{urn:oasis:names:tc:SAML:1.0:assertion}Assertion;{Element}{http://schemas.xmlsoap.org/soap/envelope/}Body;");
             Document securedDocument = doOutboundSecurityWithWSS4J(sourceDocument, action, properties);
 
             //some test that we can really sure we get what we want from WSS4J
             NodeList nodeList = securedDocument.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
-            Assert.assertEquals(nodeList.getLength(), 0);
+            Assert.assertEquals(nodeList.getLength(), 1);
 
             javax.xml.transform.Transformer transformer = TRANSFORMER_FACTORY.newTransformer();
             transformer.transform(new DOMSource(securedDocument), new StreamResult(baos));
@@ -199,7 +201,7 @@ public class SAMLTokenTest extends Abstr
 
             //header element must still be there
             NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
-            Assert.assertEquals(nodeList.getLength(), 0);
+            Assert.assertEquals(nodeList.getLength(), 1);
         }
     }
 
@@ -247,14 +249,15 @@ public class SAMLTokenTest extends Abstr
             callbackHandler.setResource("http://resource.org");
 
             InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
-            String action = WSHandlerConstants.SAML_TOKEN_UNSIGNED;
+            String action = WSHandlerConstants.SAML_TOKEN_UNSIGNED + " " + WSHandlerConstants.SIGNATURE;
             Properties properties = new Properties();
             properties.put(WSHandlerConstants.SAML_CALLBACK_REF, callbackHandler);
+            properties.setProperty(WSHandlerConstants.SIGNATURE_PARTS, "{Element}{urn:oasis:names:tc:SAML:1.0:assertion}Assertion;{Element}{http://schemas.xmlsoap.org/soap/envelope/}Body;");
             Document securedDocument = doOutboundSecurityWithWSS4J(sourceDocument, action, properties);
 
             //some test that we can really sure we get what we want from WSS4J
             NodeList nodeList = securedDocument.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
-            Assert.assertEquals(nodeList.getLength(), 0);
+            Assert.assertEquals(nodeList.getLength(), 1);
 
             javax.xml.transform.Transformer transformer = TRANSFORMER_FACTORY.newTransformer();
             transformer.transform(new DOMSource(securedDocument), new StreamResult(baos));
@@ -272,7 +275,7 @@ public class SAMLTokenTest extends Abstr
 
             //header element must still be there
             NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
-            Assert.assertEquals(nodeList.getLength(), 0);
+            Assert.assertEquals(nodeList.getLength(), 1);
         }
     }
 
@@ -319,14 +322,15 @@ public class SAMLTokenTest extends Abstr
             callbackHandler.setIssuer("www.example.com");
 
             InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
-            String action = WSHandlerConstants.SAML_TOKEN_UNSIGNED;
+            String action = WSHandlerConstants.SAML_TOKEN_UNSIGNED + " " + WSHandlerConstants.SIGNATURE;
             Properties properties = new Properties();
             properties.put(WSHandlerConstants.SAML_CALLBACK_REF, callbackHandler);
+            properties.setProperty(WSHandlerConstants.SIGNATURE_PARTS, "{Element}{urn:oasis:names:tc:SAML:2.0:assertion}Assertion;{Element}{http://schemas.xmlsoap.org/soap/envelope/}Body;");
             Document securedDocument = doOutboundSecurityWithWSS4J(sourceDocument, action, properties);
 
             //some test that we can really sure we get what we want from WSS4J
             NodeList nodeList = securedDocument.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
-            Assert.assertEquals(nodeList.getLength(), 0);
+            Assert.assertEquals(nodeList.getLength(), 1);
 
             javax.xml.transform.Transformer transformer = TRANSFORMER_FACTORY.newTransformer();
             transformer.transform(new DOMSource(securedDocument), new StreamResult(baos));
@@ -344,7 +348,7 @@ public class SAMLTokenTest extends Abstr
 
             //header element must still be there
             NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
-            Assert.assertEquals(nodeList.getLength(), 0);
+            Assert.assertEquals(nodeList.getLength(), 1);
         }
     }
 
@@ -391,14 +395,15 @@ public class SAMLTokenTest extends Abstr
             callbackHandler.setIssuer("www.example.com");
 
             InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
-            String action = WSHandlerConstants.SAML_TOKEN_UNSIGNED;
+            String action = WSHandlerConstants.SAML_TOKEN_UNSIGNED + " " + WSHandlerConstants.SIGNATURE;
             Properties properties = new Properties();
             properties.put(WSHandlerConstants.SAML_CALLBACK_REF, callbackHandler);
+            properties.setProperty(WSHandlerConstants.SIGNATURE_PARTS, "{Element}{urn:oasis:names:tc:SAML:2.0:assertion}Assertion;{Element}{http://schemas.xmlsoap.org/soap/envelope/}Body;");
             Document securedDocument = doOutboundSecurityWithWSS4J(sourceDocument, action, properties);
 
             //some test that we can really sure we get what we want from WSS4J
             NodeList nodeList = securedDocument.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
-            Assert.assertEquals(nodeList.getLength(), 0);
+            Assert.assertEquals(nodeList.getLength(), 1);
 
             javax.xml.transform.Transformer transformer = TRANSFORMER_FACTORY.newTransformer();
             transformer.transform(new DOMSource(securedDocument), new StreamResult(baos));
@@ -416,7 +421,7 @@ public class SAMLTokenTest extends Abstr
 
             //header element must still be there
             NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
-            Assert.assertEquals(nodeList.getLength(), 0);
+            Assert.assertEquals(nodeList.getLength(), 1);
         }
     }
 
@@ -465,14 +470,15 @@ public class SAMLTokenTest extends Abstr
             callbackHandler.setResource("http://resource.org");
 
             InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
-            String action = WSHandlerConstants.SAML_TOKEN_UNSIGNED;
+            String action = WSHandlerConstants.SAML_TOKEN_UNSIGNED + " " + WSHandlerConstants.SIGNATURE;
             Properties properties = new Properties();
             properties.put(WSHandlerConstants.SAML_CALLBACK_REF, callbackHandler);
+            properties.setProperty(WSHandlerConstants.SIGNATURE_PARTS, "{Element}{urn:oasis:names:tc:SAML:2.0:assertion}Assertion;{Element}{http://schemas.xmlsoap.org/soap/envelope/}Body;");
             Document securedDocument = doOutboundSecurityWithWSS4J(sourceDocument, action, properties);
 
             //some test that we can really sure we get what we want from WSS4J
             NodeList nodeList = securedDocument.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
-            Assert.assertEquals(nodeList.getLength(), 0);
+            Assert.assertEquals(nodeList.getLength(), 1);
 
             javax.xml.transform.Transformer transformer = TRANSFORMER_FACTORY.newTransformer();
             transformer.transform(new DOMSource(securedDocument), new StreamResult(baos));
@@ -490,7 +496,7 @@ public class SAMLTokenTest extends Abstr
 
             //header element must still be there
             NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
-            Assert.assertEquals(nodeList.getLength(), 0);
+            Assert.assertEquals(nodeList.getLength(), 1);
         }
     }