You are viewing a plain text version of this content. The canonical link for it is here.
Posted to wss4j-dev@ws.apache.org by co...@apache.org on 2009/04/03 13:33:36 UTC

svn commit: r761625 - in /webservices/wss4j/trunk: src/org/apache/ws/security/ src/org/apache/ws/security/message/token/ src/org/apache/ws/security/processor/ src/org/apache/ws/security/saml/ src/org/apache/ws/security/transform/ test/wssec/

Author: coheigea
Date: Fri Apr  3 11:33:35 2009
New Revision: 761625

URL: http://svn.apache.org/viewvc?rev=761625&view=rev
Log:
[WSS-117] - Added support for using KeyIdentifiers to reference SAML tokens.

Modified:
    webservices/wss4j/trunk/src/org/apache/ws/security/WSConstants.java
    webservices/wss4j/trunk/src/org/apache/ws/security/message/token/SecurityTokenReference.java
    webservices/wss4j/trunk/src/org/apache/ws/security/processor/SignatureProcessor.java
    webservices/wss4j/trunk/src/org/apache/ws/security/saml/WSSecSignatureSAML.java
    webservices/wss4j/trunk/src/org/apache/ws/security/transform/STRTransform.java
    webservices/wss4j/trunk/test/wssec/TestWSSecurityNewST1.java
    webservices/wss4j/trunk/test/wssec/TestWSSecurityNewST2.java
    webservices/wss4j/trunk/test/wssec/TestWSSecurityNewST3.java

Modified: webservices/wss4j/trunk/src/org/apache/ws/security/WSConstants.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/org/apache/ws/security/WSConstants.java?rev=761625&r1=761624&r2=761625&view=diff
==============================================================================
--- webservices/wss4j/trunk/src/org/apache/ws/security/WSConstants.java (original)
+++ webservices/wss4j/trunk/src/org/apache/ws/security/WSConstants.java Fri Apr  3 11:33:35 2009
@@ -122,6 +122,7 @@
     public static final String ASSERTION_LN = "Assertion";
     public static final String WSS_SAML_NS = "http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.0#";
     public static final String WSS_SAML_ASSERTION = "SAMLAssertion-1.1";
+    public static final String WSS_SAML_KI_VALUE_TYPE = WSS_SAML_NS + SAML_ASSERTION_ID;
 
     //
     // SOAP-ENV Namespaces

Modified: webservices/wss4j/trunk/src/org/apache/ws/security/message/token/SecurityTokenReference.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/org/apache/ws/security/message/token/SecurityTokenReference.java?rev=761625&r1=761624&r2=761625&view=diff
==============================================================================
--- webservices/wss4j/trunk/src/org/apache/ws/security/message/token/SecurityTokenReference.java (original)
+++ webservices/wss4j/trunk/src/org/apache/ws/security/message/token/SecurityTokenReference.java Fri Apr  3 11:33:35 2009
@@ -153,7 +153,6 @@
         Element tokElement = null;
         String tmpS = WSConstants.WSS_SAML_NS + WSConstants.WSS_SAML_ASSERTION;
         String saml10 = WSConstants.WSS_SAML_NS + WSConstants.SAML_ASSERTION_ID;
-        
         if (tmpS.equals(ref.getValueType())
             || saml10.equals(ref.getValueType())
             || WSConstants.WSC_SCT.equals(ref.getValueType())) {
@@ -223,6 +222,104 @@
         }
         return tokElement;
     }
+    
+    
+    /**
+     * Gets the signing token element, which may be a <code>BinarySecurityToken
+     * </code> or a SAML token.
+     * 
+     * The method gets the value of the KeyIdentifier contained in
+     * the {@link SecurityTokenReference} and tries to find the referenced
+     * Element in the document.
+     *
+     * @param doc the document that contains the binary security token
+     *            element. This could be different from the document
+     *            that contains the SecurityTokenReference (STR). See
+     *            STRTransform.derefenceBST() method
+     * @return Element containing the signing token
+     */
+    public Element getKeyIdentifierTokenElement(
+        Document doc, WSDocInfo docInfo, CallbackHandler cb
+    ) throws WSSecurityException {
+        String value = getKeyIdentifierValue();
+        String type = getKeyIdentifierValueType();
+        if (doDebug) {
+            log.debug("Token reference uri: " + value);
+        }
+        if (value == null) {
+            throw new WSSecurityException(
+                WSSecurityException.INVALID_SECURITY, "badReferenceURI"
+            );
+        }
+        Element tokElement = null;
+        String saml10 = WSConstants.WSS_SAML_NS + WSConstants.SAML_ASSERTION_ID;
+        if (saml10.equals(type)
+            || WSConstants.WSC_SCT.equals(type)) {
+            Element sa = docInfo.getAssertion();
+            String saID = null;
+            if (sa != null) {
+                saID = sa.getAttribute("AssertionID");
+            }
+            if (doDebug) {
+                log.debug("SAML token ID: " + saID);
+            }
+            String id = value;
+            if (id.charAt(0) == '#') {
+                id = id.substring(1);
+            }
+            if (saID == null || !saID.equals(id)) {
+                if (cb != null) {
+                    //try to find a custom token
+                    WSPasswordCallback pwcb = 
+                        new WSPasswordCallback(id, WSPasswordCallback.CUSTOM_TOKEN);
+                    try {
+                        cb.handle(new Callback[]{pwcb});
+                    } catch (Exception e) {
+                        throw new WSSecurityException(
+                            WSSecurityException.FAILURE,
+                            "noPassword", 
+                            new Object[] {id}, 
+                            e
+                        );
+                    }
+                    
+                    Element assertionElem = pwcb.getCustomToken();
+                    if (assertionElem != null) {
+                        sa = (Element)doc.importNode(assertionElem, true);
+                    }
+                    else {
+                        throw new WSSecurityException(
+                            WSSecurityException.INVALID_SECURITY,
+                            "badReferenceURI",
+                            new Object[]{"uri:" + value + ", saID: " + saID}
+                        );
+                    }
+                } else {
+                    throw new WSSecurityException(
+                        WSSecurityException.INVALID_SECURITY,
+                        "badReferenceURI",
+                        new Object[]{"uri:" + value + ", saID: " + saID}
+                    );
+                }
+            }
+            tokElement = sa;
+        } else {
+            tokElement = WSSecurityUtil.getElementByWsuId(doc, value);
+            
+            // In some scenarios id is used rather than wsu:Id
+            if (tokElement == null) {
+                tokElement = WSSecurityUtil.getElementByGenId(doc, value);
+            }
+        }
+        if (tokElement == null) {
+            throw new WSSecurityException(
+                WSSecurityException.SECURITY_TOKEN_UNAVAILABLE,
+                "noToken",
+                new Object[]{value}
+            );
+        }
+        return tokElement;
+    }
 
 
     /**

Modified: webservices/wss4j/trunk/src/org/apache/ws/security/processor/SignatureProcessor.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/org/apache/ws/security/processor/SignatureProcessor.java?rev=761625&r1=761624&r2=761625&view=diff
==============================================================================
--- webservices/wss4j/trunk/src/org/apache/ws/security/processor/SignatureProcessor.java (original)
+++ webservices/wss4j/trunk/src/org/apache/ws/security/processor/SignatureProcessor.java Fri Apr  3 11:33:35 2009
@@ -328,7 +328,6 @@
                 certs = secRef.getX509IssuerSerial(crypto);
             } else if (secRef.containsKeyIdentifier()) {
                 if (secRef.getKeyIdentifierValueType().equals(SecurityTokenReference.ENC_KEY_SHA1_URI)) {
-                    
                     String id = secRef.getKeyIdentifierValue();
                     WSPasswordCallback pwcb = 
                         new WSPasswordCallback(
@@ -349,6 +348,18 @@
                         );
                     }
                     secretKey = pwcb.getKey();
+                } else if (WSConstants.WSS_SAML_KI_VALUE_TYPE.equals(secRef.getKeyIdentifierValueType())) { 
+                    Element token = 
+                        secRef.getKeyIdentifierTokenElement(elem.getOwnerDocument(), wsDocInfo, cb);
+                    
+                    if (crypto == null) {
+                        throw new WSSecurityException(
+                            WSSecurityException.FAILURE, "noSigCryptoFile"
+                        );
+                    }
+                    samlKi = SAMLUtil.getSAMLKeyInfo(token, crypto, cb);
+                    certs = samlKi.getCerts();
+                    secretKey = samlKi.getSecret();
                 } else {
                     certs = secRef.getKeyIdentifier(crypto);
                 }

Modified: webservices/wss4j/trunk/src/org/apache/ws/security/saml/WSSecSignatureSAML.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/org/apache/ws/security/saml/WSSecSignatureSAML.java?rev=761625&r1=761624&r2=761625&view=diff
==============================================================================
--- webservices/wss4j/trunk/src/org/apache/ws/security/saml/WSSecSignatureSAML.java (original)
+++ webservices/wss4j/trunk/src/org/apache/ws/security/saml/WSSecSignatureSAML.java Fri Apr  3 11:33:35 2009
@@ -60,34 +60,25 @@
 
 public class WSSecSignatureSAML extends WSSecSignature {
 
-    private static Log log = LogFactory.getLog(WSSecSignatureSAML.class
-            .getName());
-
+    private static Log log = LogFactory.getLog(WSSecSignatureSAML.class.getName());
     private boolean senderVouches = false;
-
     private SecurityTokenReference secRefSaml = null;
-
     private Element samlToken = null;
-
     private Crypto userCrypto = null;
-
     private Crypto issuerCrypto = null;
-
     private String issuerKeyName = null;
-
     private String issuerKeyPW = null;
 
     /**
      * Constructor.
      */
     public WSSecSignatureSAML() {
+        doDebug = log.isDebugEnabled();
     }
 
     /**
      * Builds a signed soap envelope with SAML token.
      * 
-     * <p/>
-     * 
      * The method first gets an appropriate security header. According to the
      * defined parameters for certificate handling the signature elements are
      * constructed and inserted into the <code>wsse:Signature</code>
@@ -110,9 +101,10 @@
      * @return A signed SOAP envelope as <code>Document</code>
      * @throws org.apache.ws.security.WSSecurityException
      */
-    public Document build(Document doc, Crypto uCrypto,
-            SAMLAssertion assertion, Crypto iCrypto, String iKeyName,
-            String iKeyPW, WSSecHeader secHeader) throws WSSecurityException {
+    public Document build(
+        Document doc, Crypto uCrypto, SAMLAssertion assertion, 
+        Crypto iCrypto, String iKeyName, String iKeyPW, WSSecHeader secHeader
+    ) throws WSSecurityException {
 
         prepare(doc, uCrypto, assertion, iCrypto, iKeyName, iKeyPW, secHeader);
 
@@ -125,18 +117,17 @@
         }
         addReferencesToSign(parts, secHeader);
 
-        /*
-         * The order to prepend is: - signature Element - BinarySecurityToken
-         * (depends on mode) - SecurityTokenRefrence (depends on mode) - SAML
-         * token
-         */
-
+        //
+        // The order to prepend is: - signature Element - BinarySecurityToken
+        // (depends on mode) - SecurityTokenRefrence (depends on mode) - SAML
+        // token
+        //
         prependToHeader(secHeader);
 
-        /*
-         * if we have a BST prepend it in front of the Signature according to
-         * strict layout rules.
-         */
+        //
+        // if we have a BST prepend it in front of the Signature according to
+        // strict layout rules.
+        //
         if (bstToken != null) {
             prependBSTElementToHeader(secHeader);
         }
@@ -156,8 +147,6 @@
      * elements to sign may be added. After all references are added they can be
      * signed.
      * 
-     * <p/>
-     * 
      * This method does not add the Signature element to the security header.
      * See <code>prependSignatureElementToHeader()</code> method.
      * 
@@ -178,11 +167,11 @@
      *            The Security header
      * @throws WSSecurityException
      */
-    public void prepare(Document doc, Crypto uCrypto, SAMLAssertion assertion,
-            Crypto iCrypto, String iKeyName, String iKeyPW,
-            WSSecHeader secHeader) throws WSSecurityException {
+    public void prepare(
+        Document doc, Crypto uCrypto, SAMLAssertion assertion, Crypto iCrypto, 
+        String iKeyName, String iKeyPW, WSSecHeader secHeader
+    ) throws WSSecurityException {
 
-        doDebug = log.isDebugEnabled();
         if (doDebug) {
             log.debug("Beginning ST signing...");
         }
@@ -193,12 +182,12 @@
         issuerKeyName = iKeyName;
         issuerKeyPW = iKeyPW;
 
-        /*
-         * Get some information about the SAML token content. This controls how
-         * to deal with the whole stuff. First get the Authentication statement
-         * (includes Subject), then get the _first_ confirmation method only
-         * thats if "senderVouches" is true.
-         */
+        //
+        // Get some information about the SAML token content. This controls how
+        // to deal with the whole stuff. First get the Authentication statement
+        // (includes Subject), then get the _first_ confirmation method only
+        // thats if "senderVouches" is true.
+        //
         SAMLSubjectStatement samlSubjS = null;
         Iterator it = assertion.getStatements();
         while (it.hasNext()) {
@@ -225,10 +214,10 @@
         if (SAMLSubject.CONF_SENDER_VOUCHES.equals(confirmMethod)) {
             senderVouches = true;
         }
-        /*
-         * Gather some info about the document to process and store it for
-         * retrieval
-         */
+        //
+        // Gather some info about the document to process and store it for
+        // retrieval
+        //
         wsDocInfo = new WSDocInfo(doc);
 
         X509Certificate[] certs = null;
@@ -237,17 +226,19 @@
             certs = issuerCrypto.getCertificates(issuerKeyName);
             wsDocInfo.setCrypto(issuerCrypto);
         }
-        /*
-         * in case of key holder: - get the user's certificate that _must_ be
-         * included in the SAML token. To ensure the cert integrity the SAML
-         * token must be signed (by the issuer). Just check if its signed, but
-         * don't verify this SAML token's signature here (maybe later).
-         */
+        //
+        // in case of key holder: - get the user's certificate that _must_ be
+        // included in the SAML token. To ensure the cert integrity the SAML
+        // token must be signed (by the issuer). Just check if its signed, but
+        // don't verify this SAML token's signature here (maybe later).
+        //
         else {
-            if (userCrypto == null || assertion.isSigned() == false) {
-                throw new WSSecurityException(WSSecurityException.FAILURE,
-                        "invalidSAMLsecurity",
-                        new Object[] { "for SAML Signature (Key Holder)" });
+            if (userCrypto == null || !assertion.isSigned()) {
+                throw new WSSecurityException(
+                    WSSecurityException.FAILURE,
+                    "invalidSAMLsecurity",
+                    new Object[] { "for SAML Signature (Key Holder)" }
+                );
             }
             Element e = samlSubj.getKeyInfo();
             try {
@@ -268,10 +259,12 @@
                 // TODO: get alias name for cert, check against username set by
                 // caller
             } catch (XMLSecurityException e3) {
-                throw new WSSecurityException(WSSecurityException.FAILURE,
-                        "invalidSAMLsecurity",
-                        new Object[] { "cannot get certificate (key holder)" },
-                        e3);
+                throw new WSSecurityException(
+                    WSSecurityException.FAILURE,
+                    "invalidSAMLsecurity",
+                    new Object[] { "cannot get certificate (key holder)" },
+                    e3
+                );
             }
             wsDocInfo.setCrypto(userCrypto);
         }
@@ -301,25 +294,22 @@
         }
         sig = null;
         if (canonAlgo.equals(WSConstants.C14N_EXCL_OMIT_COMMENTS)) {
-            Element canonElem = XMLUtils.createElementInSignatureSpace(doc,
-                    Constants._TAG_CANONICALIZATIONMETHOD);
+            Element canonElem = 
+                XMLUtils.createElementInSignatureSpace(doc, Constants._TAG_CANONICALIZATIONMETHOD);
 
             canonElem.setAttributeNS(null, Constants._ATT_ALGORITHM, canonAlgo);
 
             if (wssConfig.isWsiBSPCompliant()) {
-                Set prefixes = getInclusivePrefixes(secHeader
-                        .getSecurityHeader(), false);
+                Set prefixes = getInclusivePrefixes(secHeader.getSecurityHeader(), false);
 
-                InclusiveNamespaces inclusiveNamespaces = new InclusiveNamespaces(
-                        doc, prefixes);
+                InclusiveNamespaces inclusiveNamespaces = 
+                    new InclusiveNamespaces(doc, prefixes);
 
                 canonElem.appendChild(inclusiveNamespaces.getElement());
             }
             try {
-                SignatureAlgorithm signatureAlgorithm = new SignatureAlgorithm(
-                        doc, sigAlgo);
-                sig = new XMLSignature(doc, null, signatureAlgorithm
-                        .getElement(), canonElem);
+                SignatureAlgorithm signatureAlgorithm = new SignatureAlgorithm(doc, sigAlgo);
+                sig = new XMLSignature(doc, null, signatureAlgorithm.getElement(), canonElem);
             } catch (XMLSecurityException e) {
                 log.error("", e);
                 throw new WSSecurityException(
@@ -351,92 +341,108 @@
 
         certUri = wssConfig.getIdAllocator().createSecureId("CertId-", certs[0]);  
 
-        /*
-         * If the sender vouches, then we must sign the SAML token _and_ at
-         * least one part of the message (usually the SOAP body). To do so we
-         * need to - put in a reference to the SAML token. Thus we create a STR
-         * and insert it into the wsse:Security header - set a reference of the
-         * created STR to the signature and use STR Transfrom during the
-         * signature
-         */
+        //
+        // If the sender vouches, then we must sign the SAML token _and_ at
+        // least one part of the message (usually the SOAP body). To do so we
+        // need to - put in a reference to the SAML token. Thus we create a STR
+        // and insert it into the wsse:Security header - set a reference of the
+        // created STR to the signature and use STR Transform during the
+        // signature
+        //
         Transforms transforms = null;
-
         try {
             if (senderVouches) {
                 secRefSaml = new SecurityTokenReference(doc);
-                String strSamlUri = wssConfig.getIdAllocator().createSecureId("STRSAMLId-", secRefSaml);
+                String strSamlUri = 
+                    wssConfig.getIdAllocator().createSecureId("STRSAMLId-", secRefSaml);
                 secRefSaml.setID(strSamlUri);
 
-                // Decouple Reference/KeyInfo setup - quick shot here
-                Reference ref = new Reference(doc);
-                ref.setURI("#" + assertion.getId());
-                ref.setValueType(WSConstants.WSS_SAML_NS
-                        + WSConstants.WSS_SAML_ASSERTION);
-                secRefSaml.setReference(ref);
-                // up to here
+                if (WSConstants.X509_KEY_IDENTIFIER == keyIdentifierType) {
+                    Element keyId = doc.createElementNS(WSConstants.WSSE_NS, "wsse:KeyIdentifier");
+                    keyId.setAttributeNS(
+                        null, "ValueType", WSConstants.WSS_SAML_KI_VALUE_TYPE
+                    );
+                    keyId.appendChild(doc.createTextNode(assertion.getId()));
+                    Element elem = secRefSaml.getElement();
+                    elem.appendChild(keyId);
+                } else {
+                    Reference ref = new Reference(doc);
+                    ref.setURI("#" + assertion.getId());
+                    ref.setValueType(WSConstants.WSS_SAML_KI_VALUE_TYPE);
+                    secRefSaml.setReference(ref);
+                }
 
                 Element ctx = createSTRParameter(doc);
                 transforms = new Transforms(doc);
-                transforms.addTransform(STRTransform.implementedTransformURI,
-                        ctx);
+                transforms.addTransform(STRTransform.implementedTransformURI, ctx);
                 sig.addDocument("#" + strSamlUri, transforms);
             }
         } catch (TransformationException e1) {
-            throw new WSSecurityException(WSSecurityException.FAILED_SIGNATURE,
-                    "noXMLSig", null, e1);
+            throw new WSSecurityException(
+                WSSecurityException.FAILED_SIGNATURE, "noXMLSig", null, e1
+            );
         } catch (XMLSignatureException e1) {
-            throw new WSSecurityException(WSSecurityException.FAILED_SIGNATURE,
-                    "noXMLSig", null, e1);
+            throw new WSSecurityException(
+                WSSecurityException.FAILED_SIGNATURE, "noXMLSig", null, e1
+            );
         }
 
-        switch (keyIdentifierType) {
-        case WSConstants.BST_DIRECT_REFERENCE:
-            Reference ref = new Reference(doc);
-            if (senderVouches) {
+        if (senderVouches) {
+            switch (keyIdentifierType) {
+            case WSConstants.BST_DIRECT_REFERENCE:
+                Reference ref = new Reference(doc);
                 ref.setURI("#" + certUri);
                 bstToken = new X509Security(doc);
                 ((X509Security) bstToken).setX509Certificate(certs[0]);
                 bstToken.setID(certUri);
                 wsDocInfo.setBst(bstToken.getElement());
                 ref.setValueType(bstToken.getValueType());
-            } else {
+                secRef.setReference(ref);
+                break;
+                
+            case WSConstants.X509_KEY_IDENTIFIER :
+                secRef.setKeyIdentifier(certs[0]);
+                break;
+
+            default:
+                throw new WSSecurityException(WSSecurityException.FAILURE, "unsupportedKeyId");
+            }
+        } else {
+            switch (keyIdentifierType) {
+            case WSConstants.BST_DIRECT_REFERENCE:
+                Reference ref = new Reference(doc);
                 ref.setURI("#" + assertion.getId());
-                ref.setValueType(WSConstants.WSS_SAML_NS
-                        + WSConstants.WSS_SAML_ASSERTION);
+                ref.setValueType(WSConstants.WSS_SAML_KI_VALUE_TYPE);
+                secRef.setReference(ref);
+                break;
+                
+            case WSConstants.X509_KEY_IDENTIFIER :
+                Element keyId = doc.createElementNS(WSConstants.WSSE_NS, "wsse:KeyIdentifier");
+                keyId.setAttributeNS(
+                    null, "ValueType", WSConstants.WSS_SAML_KI_VALUE_TYPE
+                );
+                keyId.appendChild(doc.createTextNode(assertion.getId()));
+                Element elem = secRef.getElement();
+                elem.appendChild(keyId);
+                break;
+
+            default:
+                throw new WSSecurityException(WSSecurityException.FAILURE, "unsupportedKeyId");
             }
-            secRef.setReference(ref);
-            break;
-        //
-        // case WSConstants.ISSUER_SERIAL :
-        // XMLX509IssuerSerial data =
-        // new XMLX509IssuerSerial(doc, certs[0]);
-        // secRef.setX509IssuerSerial(data);
-        // break;
-        //
-        // case WSConstants.X509_KEY_IDENTIFIER :
-        // secRef.setKeyIdentifier(certs[0]);
-        // break;
-        //
-        // case WSConstants.SKI_KEY_IDENTIFIER :
-        // secRef.setKeyIdentifierSKI(certs[0], crypto);
-        // break;
-        //
-        default:
-            throw new WSSecurityException(WSSecurityException.FAILURE,
-                    "unsupportedKeyId");
         }
-
         keyInfo.addUnknownElement(secRef.getElement());
         
         Element keyInfoElement = keyInfo.getElement();
-        keyInfoElement.setAttributeNS(WSConstants.XMLNS_NS, "xmlns:"
-                + WSConstants.SIG_PREFIX, WSConstants.SIG_NS);
+        keyInfoElement.setAttributeNS(
+            WSConstants.XMLNS_NS, "xmlns:" + WSConstants.SIG_PREFIX, WSConstants.SIG_NS
+        );
 
         try {
             samlToken = (Element) assertion.toDOM(doc);
         } catch (SAMLException e2) {
-            throw new WSSecurityException(WSSecurityException.FAILED_SIGNATURE,
-                    "noSAMLdoc", null, e2);
+            throw new WSSecurityException(
+                WSSecurityException.FAILED_SIGNATURE, "noSAMLdoc", null, e2
+            );
         }
         wsDocInfo.setAssertion(samlToken);
     }
@@ -448,8 +454,6 @@
      * allows to insert the SAML elements at any position in the Security
      * header.
      * 
-     * <p/>
-     * 
      * This methods first prepends the SAML security reference if mode is
      * <code>senderVouches</code>, then the SAML token itself,
      * 
@@ -459,7 +463,8 @@
     public void prependSAMLElementsToHeader(WSSecHeader secHeader) {
         if (senderVouches) {
             WSSecurityUtil.prependChildElement(
-                secHeader.getSecurityHeader(), secRefSaml.getElement());
+                secHeader.getSecurityHeader(), secRefSaml.getElement()
+            );
         }
 
         WSSecurityUtil.prependChildElement(secHeader.getSecurityHeader(), samlToken);
@@ -482,7 +487,7 @@
      * @throws WSSecurityException
      */
     public void addReferencesToSign(Vector references, WSSecHeader secHeader)
-            throws WSSecurityException {
+        throws WSSecurityException {
         Transforms transforms = null;
 
         Element envelope = document.getDocumentElement();
@@ -494,87 +499,88 @@
             String elemName = encPart.getName();
             String nmSpace = encPart.getNamespace();
 
-            /*
-             * Set up the elements to sign. There are two resevered element
-             * names: "Token" and "STRTransform" "Token": Setup the Signature to
-             * either sign the information that points to the security token or
-             * the token itself. If its a direct reference sign the token,
-             * otherwise sign the KeyInfo Element. "STRTransform": Setup the
-             * ds:Reference to use STR Transform
-             * 
-             */
+            //
+            // Set up the elements to sign. There are two reserved element
+            // names: "Token" and "STRTransform" "Token": Setup the Signature to
+            // either sign the information that points to the security token or
+            // the token itself. If its a direct reference sign the token,
+            // otherwise sign the KeyInfo Element. "STRTransform": Setup the
+            // ds:Reference to use STR Transform
+            // 
             transforms = new Transforms(document);
             try {
                 if (idToSign != null) {
-                    Element toSignById = WSSecurityUtil.findElementById(
-                            document.getDocumentElement(), idToSign,
-                            WSConstants.WSU_NS);
+                    Element toSignById = 
+                        WSSecurityUtil.findElementById(
+                            document.getDocumentElement(), idToSign, WSConstants.WSU_NS
+                        );
                     if (toSignById == null) {
-                        toSignById = WSSecurityUtil.findElementById(document
-                                .getDocumentElement(), idToSign, null);
+                        toSignById = 
+                            WSSecurityUtil.findElementById(
+                                document.getDocumentElement(), idToSign, null
+                            );
                     }
-                    transforms
-                            .addTransform(Transforms.TRANSFORM_C14N_EXCL_OMIT_COMMENTS);
+                    transforms.addTransform(Transforms.TRANSFORM_C14N_EXCL_OMIT_COMMENTS);
                     if (wssConfig.isWsiBSPCompliant()) {
                         transforms.item(0).getElement().appendChild(
-                                new InclusiveNamespaces(document,
-                                        getInclusivePrefixes(toSignById))
-                                        .getElement());
+                            new InclusiveNamespaces(
+                                document,
+                                getInclusivePrefixes(toSignById)
+                            ).getElement());
                     }
                     sig.addDocument("#" + idToSign, transforms);
                 } else if (elemName.equals("Token")) {
-                    transforms
-                            .addTransform(Transforms.TRANSFORM_C14N_EXCL_OMIT_COMMENTS);
+                    transforms.addTransform(Transforms.TRANSFORM_C14N_EXCL_OMIT_COMMENTS);
                     if (keyIdentifierType == WSConstants.BST_DIRECT_REFERENCE) {
                         if (wssConfig.isWsiBSPCompliant()) {
                             transforms.item(0).getElement().appendChild(
-                                    new InclusiveNamespaces(document,
-                                            getInclusivePrefixes(secHeader
-                                                    .getSecurityHeader()))
-                                            .getElement());
+                                new InclusiveNamespaces(
+                                    document,
+                                    getInclusivePrefixes(secHeader.getSecurityHeader())
+                                ).getElement());
                         }
                         sig.addDocument("#" + certUri, transforms);
                     } else {
                         if (wssConfig.isWsiBSPCompliant()) {
                             transforms.item(0).getElement().appendChild(
-                                    new InclusiveNamespaces(document,
-                                            getInclusivePrefixes(keyInfo
-                                                    .getElement()))
-                                            .getElement());
+                                new InclusiveNamespaces(
+                                    document,
+                                    getInclusivePrefixes(keyInfo.getElement())
+                                ).getElement());
                         }
                         sig.addDocument("#" + keyInfoUri, transforms);
                     }
                 } else if (elemName.equals("STRTransform")) { // STRTransform
                     Element ctx = createSTRParameter(document);
-                    transforms.addTransform(
-                            STRTransform.implementedTransformURI, ctx);
+                    transforms.addTransform(STRTransform.implementedTransformURI, ctx);
                     sig.addDocument("#" + strUri, transforms);
                 } else {
-                    Element body = (Element) WSSecurityUtil.findElement(
-                            envelope, elemName, nmSpace);
+                    Element body = 
+                        (Element) WSSecurityUtil.findElement(envelope, elemName, nmSpace);
                     if (body == null) {
                         throw new WSSecurityException(
-                                WSSecurityException.FAILURE, "noEncElement",
-                                new Object[] { nmSpace + ", " + elemName });
+                            WSSecurityException.FAILURE, "noEncElement",
+                            new Object[] { nmSpace + ", " + elemName }
+                        );
                     }
-                    transforms
-                            .addTransform(Transforms.TRANSFORM_C14N_EXCL_OMIT_COMMENTS);
+                    transforms.addTransform(Transforms.TRANSFORM_C14N_EXCL_OMIT_COMMENTS);
                     if (wssConfig.isWsiBSPCompliant()) {
                         transforms.item(0).getElement().appendChild(
-                                new InclusiveNamespaces(document,
-                                        getInclusivePrefixes(body))
-                                        .getElement());
+                            new InclusiveNamespaces(
+                                document,
+                                getInclusivePrefixes(body)
+                            ).getElement());
                     }
                     sig.addDocument("#" + setWsuId(body), transforms);
                 }
             } catch (TransformationException e1) {
                 throw new WSSecurityException(
-                        WSSecurityException.FAILED_SIGNATURE, "noXMLSig", null,
-                        e1);
+                    WSSecurityException.FAILED_SIGNATURE, "noXMLSig", null, e1
+                );
             } catch (XMLSignatureException e1) {
                 throw new WSSecurityException(
-                        WSSecurityException.FAILED_SIGNATURE, "noXMLSig", null,
-                        e1);
+                    WSSecurityException.FAILED_SIGNATURE, "noXMLSig", null, e1
+                );
             }
         }
     }
@@ -589,24 +595,23 @@
      * @throws WSSecurityException
      */
     public void computeSignature() throws WSSecurityException {
-
         boolean remove = WSDocInfoStore.store(wsDocInfo);
 
         try {
             if (senderVouches) {
-                sig
-                        .sign(issuerCrypto.getPrivateKey(issuerKeyName,
-                                issuerKeyPW));
+                sig.sign(issuerCrypto.getPrivateKey(issuerKeyName, issuerKeyPW));
             } else {
                 sig.sign(userCrypto.getPrivateKey(user, password));
             }
             signatureValue = sig.getSignatureValue();
         } catch (XMLSignatureException e1) {
-            throw new WSSecurityException(WSSecurityException.FAILED_SIGNATURE,
-                    null, null, e1);
+            throw new WSSecurityException(
+                WSSecurityException.FAILED_SIGNATURE, null, null, e1
+            );
         } catch (Exception e1) {
-            throw new WSSecurityException(WSSecurityException.FAILED_SIGNATURE,
-                    null, null, e1);
+            throw new WSSecurityException(
+                WSSecurityException.FAILED_SIGNATURE, null, null, e1
+            );
         } finally {
             if (remove) {
                 WSDocInfoStore.delete(wsDocInfo);

Modified: webservices/wss4j/trunk/src/org/apache/ws/security/transform/STRTransform.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/org/apache/ws/security/transform/STRTransform.java?rev=761625&r1=761624&r2=761625&view=diff
==============================================================================
--- webservices/wss4j/trunk/src/org/apache/ws/security/transform/STRTransform.java (original)
+++ webservices/wss4j/trunk/src/org/apache/ws/security/transform/STRTransform.java Fri Apr  3 11:33:35 2009
@@ -243,7 +243,7 @@
     }
 
     private Element dereferenceSTR(Document doc, SecurityTokenReference secRef)
-        throws  WSSecurityException {
+        throws WSSecurityException {
         //
         // Third step: locate the security token referenced by the STR element.
         // Either the Token is contained in the document as a
@@ -287,23 +287,27 @@
             tokElement = createBSTX509(doc, cert, secRef.getElement());
         }
         //
-        // third case: KeyIdentifier, must be SKI, lookup in keystore, wrap in
-        // BST according to specification. No other KeyIdentifier type handled
-        // here - just SKI
+        // third case: KeyIdentifier. For SKI, lookup in keystore, wrap in
+        // BST according to specification. Otherwise if it's a wsse:KeyIdentifier it could
+        // be a SAML assertion, so try and find the referenced element.
         //
         else if (secRef.containsKeyIdentifier()) {
             if (doDebug) {
                 log.debug("STR: KeyIdentifier");
             }
-            X509Certificate cert = null;
-            X509Certificate[] certs = secRef.getKeyIdentifier(wsDocInfo.getCrypto());
-            if (certs == null || certs.length == 0 || certs[0] == null) {
-                throw new WSSecurityException(WSSecurityException.FAILED_CHECK);
+            if (WSConstants.WSS_SAML_KI_VALUE_TYPE.equals(secRef.getKeyIdentifierValueType())) {
+                tokElement = secRef.getKeyIdentifierTokenElement(doc, wsDocInfo, null);
+            } else {
+                X509Certificate cert = null;
+                X509Certificate[] certs = secRef.getKeyIdentifier(wsDocInfo.getCrypto());
+                if (certs == null || certs.length == 0 || certs[0] == null) {
+                    throw new WSSecurityException(WSSecurityException.FAILED_CHECK);
+                }
+                cert = certs[0];
+                tokElement = createBSTX509(doc, cert, secRef.getElement());
             }
-            cert = certs[0];
-            tokElement = createBSTX509(doc, cert, secRef.getElement());
         }
-        return (Element) tokElement;
+        return tokElement;
     }
 
     private Element createBSTX509(Document doc, X509Certificate cert, Element secRefE) 

Modified: webservices/wss4j/trunk/test/wssec/TestWSSecurityNewST1.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/test/wssec/TestWSSecurityNewST1.java?rev=761625&r1=761624&r2=761625&view=diff
==============================================================================
--- webservices/wss4j/trunk/test/wssec/TestWSSecurityNewST1.java (original)
+++ webservices/wss4j/trunk/test/wssec/TestWSSecurityNewST1.java Fri Apr  3 11:33:35 2009
@@ -23,6 +23,7 @@
 
 import org.apache.ws.security.saml.SAMLIssuerFactory;
 import org.apache.ws.security.saml.SAMLIssuer;
+import org.apache.ws.security.util.WSSecurityUtil;
 
 import org.apache.axis.Message;
 import org.apache.axis.MessageContext;
@@ -31,28 +32,25 @@
 import org.apache.axis.message.SOAPEnvelope;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
-import org.apache.ws.security.WSPasswordCallback;
+import org.apache.ws.security.WSConstants;
 import org.apache.ws.security.WSSecurityEngine;
+import org.apache.ws.security.WSSecurityEngineResult;
 import org.apache.ws.security.message.WSSecHeader;
 import org.apache.ws.security.message.WSSecSAMLToken;
 import org.w3c.dom.Document;
 
 import org.opensaml.SAMLAssertion;
 
-import javax.security.auth.callback.Callback;
-import javax.security.auth.callback.CallbackHandler;
-import javax.security.auth.callback.UnsupportedCallbackException;
 import java.io.ByteArrayInputStream;
-import java.io.IOException;
 import java.io.InputStream;
+import java.util.Vector;
 
 /**
- * WS-Security Test Case
- * <p/>
+ * Test-case for sending and processing an unsigned (sender vouches) SAML Assertion.
  * 
  * @author Davanum Srinivas (dims@yahoo.com)
  */
-public class TestWSSecurityNewST1 extends TestCase implements CallbackHandler {
+public class TestWSSecurityNewST1 extends TestCase {
     private static final Log LOG = LogFactory.getLog(TestWSSecurityNewST1.class);
     private static final String SOAPMSG = 
         "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" 
@@ -71,7 +69,6 @@
 
     /**
      * TestWSSecurity constructor
-     * <p/>
      * 
      * @param name name of the test
      */
@@ -81,7 +78,6 @@
 
     /**
      * JUnit suite
-     * <p/>
      * 
      * @return a junit test suite
      */
@@ -91,7 +87,6 @@
 
     /**
      * Setup method
-     * <p/>
      * 
      * @throws Exception Thrown when there is a problem in setup
      */
@@ -103,7 +98,6 @@
 
     /**
      * Constructs a soap envelope
-     * <p/>
      * 
      * @return soap envelope
      * @throws Exception if there is any problem constructing the soap envelope
@@ -116,12 +110,7 @@
     }
 
     /**
-     * Test that encrypt and decrypt a WS-Security envelope.
-     * This test uses the RSA_15 algorithm to transport (wrap) the symmetric
-     * key.
-     * <p/>
-     * 
-     * @throws Exception Thrown when there is any problem in signing or verification
+     * Test that creates, sends and processes an unsigned SAML assertion.
      */
     public void testSAMLUnsignedSenderVouches() throws Exception {
         SOAPEnvelope unsignedEnvelope = message.getSOAPEnvelope();
@@ -136,16 +125,22 @@
         secHeader.insertSecurityHeader(doc);
         LOG.info("Before SAMLUnsignedSenderVouches....");
         
-        Document signedDoc = wsSign.build(doc, assertion, secHeader);
+        Document unsignedDoc = wsSign.build(doc, assertion, secHeader);
         LOG.info("After SAMLUnsignedSenderVouches....");
 
         if (LOG.isDebugEnabled()) {
             LOG.debug("Unsigned SAML message (sender vouches):");
             String outputString = 
-                org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(signedDoc);
+                org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(unsignedDoc);
             LOG.debug(outputString);
         }
-        verify(signedDoc);
+        
+        Vector results = verify(unsignedDoc);
+        WSSecurityEngineResult actionResult =
+            WSSecurityUtil.fetchActionResult(results, WSConstants.ST_UNSIGNED);
+        SAMLAssertion receivedAssertion = 
+            (SAMLAssertion) actionResult.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
+        assertTrue(receivedAssertion != null);
     }
 
     /**
@@ -155,28 +150,12 @@
      * @param envelope 
      * @throws Exception Thrown when there is a problem in verification
      */
-    private void verify(Document doc) throws Exception {
-        secEngine.processSecurityHeader(doc, null, this, null);
+    private Vector verify(Document doc) throws Exception {
+        Vector results = secEngine.processSecurityHeader(doc, null, null, null);
         String outputString = 
             org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(doc);
         assertTrue(outputString.indexOf("LogTestService2") > 0 ? true : false);
+        return results;
     }
 
-    public void handle(Callback[] callbacks)
-        throws IOException, UnsupportedCallbackException {
-        for (int i = 0; i < callbacks.length; i++) {
-            if (callbacks[i] instanceof WSPasswordCallback) {
-                WSPasswordCallback pc = (WSPasswordCallback) callbacks[i];
-                /*
-                 * here call a function/method to lookup the password for
-                 * the given identifier (e.g. a user name or keystore alias)
-                 * e.g.: pc.setPassword(passStore.getPassword(pc.getIdentfifier))
-                 * for Testing we supply a fixed name here.
-                 */
-                pc.setPassword("security");
-            } else {
-                throw new UnsupportedCallbackException(callbacks[i], "Unrecognized Callback");
-            }
-        }
-    }
 }

Modified: webservices/wss4j/trunk/test/wssec/TestWSSecurityNewST2.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/test/wssec/TestWSSecurityNewST2.java?rev=761625&r1=761624&r2=761625&view=diff
==============================================================================
--- webservices/wss4j/trunk/test/wssec/TestWSSecurityNewST2.java (original)
+++ webservices/wss4j/trunk/test/wssec/TestWSSecurityNewST2.java Fri Apr  3 11:33:35 2009
@@ -35,7 +35,9 @@
 import org.apache.ws.security.WSPasswordCallback;
 import org.apache.ws.security.WSSConfig;
 import org.apache.ws.security.WSSecurityEngine;
+import org.apache.ws.security.WSSecurityEngineResult;
 import org.apache.ws.security.saml.WSSecSignatureSAML;
+import org.apache.ws.security.util.WSSecurityUtil;
 import org.apache.ws.security.components.crypto.Crypto;
 import org.apache.ws.security.components.crypto.CryptoFactory;
 import org.apache.ws.security.handler.RequestData;
@@ -52,10 +54,10 @@
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.io.InputStream;
+import java.util.Vector;
 
 /**
- * WS-Security Test Case
- * <p/>
+ * Test-case for sending and processing an signed (sender vouches) SAML Assertion.
  * 
  * @author Davanum Srinivas (dims@yahoo.com)
  */
@@ -79,7 +81,6 @@
 
     /**
      * TestWSSecurity constructor
-     * <p/>
      * 
      * @param name name of the test
      */
@@ -89,7 +90,6 @@
 
     /**
      * JUnit suite
-     * <p/>
      * 
      * @return a junit test suite
      */
@@ -99,7 +99,6 @@
 
     /**
      * Setup method
-     * <p/>
      * 
      * @throws Exception Thrown when there is a problem in setup
      */
@@ -111,7 +110,6 @@
 
     /**
      * Constructs a soap envelope
-     * <p/>
      * 
      * @return soap envelope
      * @throws Exception if there is any problem constructing the soap envelope
@@ -124,12 +122,7 @@
     }
 
     /**
-     * Test that encrypt and decrypt a WS-Security envelope.
-     * This test uses the RSA_15 algorithm to transport (wrap) the symmetric
-     * key.
-     * <p/>
-     * 
-     * @throws Exception Thrown when there is any problem in signing or verification
+     * Test that creates, sends and processes an signed SAML assertion.
      */
     public void testSAMLSignedSenderVouches() throws Exception {
         SOAPEnvelope unsignedEnvelope = message.getSOAPEnvelope();
@@ -150,7 +143,8 @@
         WSSecHeader secHeader = new WSSecHeader();
         secHeader.insertSecurityHeader(doc);
         
-        Document signedDoc = wsSign.build(doc, null, assertion, issuerCrypto, issuerKeyName, issuerKeyPW, secHeader);
+        Document signedDoc = 
+            wsSign.build(doc, null, assertion, issuerCrypto, issuerKeyName, issuerKeyPW, secHeader);
         LOG.info("After SAMLSignedSenderVouches....");
 
         if (LOG.isDebugEnabled()) {
@@ -159,7 +153,56 @@
                 org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(signedDoc);
             LOG.debug(outputString);
         }
-        verify(signedDoc);
+        
+        Vector results = verify(signedDoc);
+        WSSecurityEngineResult actionResult =
+            WSSecurityUtil.fetchActionResult(results, WSConstants.ST_UNSIGNED);
+        SAMLAssertion receivedAssertion = 
+            (SAMLAssertion) actionResult.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
+        assertTrue(receivedAssertion != null);
+    }
+    
+    
+    /**
+     * Test that creates, sends and processes an signed SAML assertion using a KeyIdentifier
+     * instead of direct reference.
+     */
+    public void testSAMLSignedSenderVouchesKeyIdentifier() throws Exception {
+        SOAPEnvelope unsignedEnvelope = message.getSOAPEnvelope();
+        SAMLIssuer saml = SAMLIssuerFactory.getInstance("saml.properties");
+
+        SAMLAssertion assertion = saml.newAssertion();
+
+        String issuerKeyName = saml.getIssuerKeyName();
+        String issuerKeyPW = saml.getIssuerKeyPassword();
+        Crypto issuerCrypto = saml.getIssuerCrypto();
+        WSSecSignatureSAML wsSign = new WSSecSignatureSAML();
+        wsSign.setKeyIdentifierType(WSConstants.X509_KEY_IDENTIFIER);
+        
+        LOG.info("Before SAMLSignedSenderVouches....");
+        
+        Document doc = unsignedEnvelope.getAsDocument();
+
+        WSSecHeader secHeader = new WSSecHeader();
+        secHeader.insertSecurityHeader(doc);
+        
+        Document signedDoc = 
+            wsSign.build(doc, null, assertion, issuerCrypto, issuerKeyName, issuerKeyPW, secHeader);
+        LOG.info("After SAMLSignedSenderVouches....");
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("Signed SAML message (sender vouches):");
+            String outputString = 
+                org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(signedDoc);
+            LOG.debug(outputString);
+        }
+        
+        Vector results = verify(signedDoc);
+        WSSecurityEngineResult actionResult =
+            WSSecurityUtil.fetchActionResult(results, WSConstants.ST_UNSIGNED);
+        SAMLAssertion receivedAssertion = 
+            (SAMLAssertion) actionResult.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
+        assertTrue(receivedAssertion != null);
     }
     
     
@@ -197,7 +240,13 @@
                 org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(signedDoc);
             LOG.debug(outputString);
         }
-        verify(signedDoc);
+        
+        Vector results = verify(signedDoc);
+        WSSecurityEngineResult actionResult =
+            WSSecurityUtil.fetchActionResult(results, WSConstants.ST_UNSIGNED);
+        SAMLAssertion receivedAssertion = 
+            (SAMLAssertion) actionResult.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
+        assertTrue(receivedAssertion != null);
     }
     
     
@@ -263,20 +312,20 @@
     
     /**
      * Verifies the soap envelope
-     * <p/>
      * 
      * @param doc
      * @throws Exception Thrown when there is a problem in verification
      */
-    private void verify(Document doc) throws Exception {
-        secEngine.processSecurityHeader(doc, null, this, crypto);
+    private Vector verify(Document doc) throws Exception {
+        Vector results = secEngine.processSecurityHeader(doc, null, this, crypto);
         String outputString = 
             org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(doc);
         assertTrue(outputString.indexOf("LogTestService2") > 0 ? true : false);
+        return results;
     }
 
     public void handle(Callback[] callbacks)
-            throws IOException, UnsupportedCallbackException {
+        throws IOException, UnsupportedCallbackException {
         for (int i = 0; i < callbacks.length; i++) {
             if (callbacks[i] instanceof WSPasswordCallback) {
                 WSPasswordCallback pc = (WSPasswordCallback) callbacks[i];

Modified: webservices/wss4j/trunk/test/wssec/TestWSSecurityNewST3.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/test/wssec/TestWSSecurityNewST3.java?rev=761625&r1=761624&r2=761625&view=diff
==============================================================================
--- webservices/wss4j/trunk/test/wssec/TestWSSecurityNewST3.java (original)
+++ webservices/wss4j/trunk/test/wssec/TestWSSecurityNewST3.java Fri Apr  3 11:33:35 2009
@@ -24,6 +24,7 @@
 import org.apache.ws.security.saml.SAMLIssuerFactory;
 import org.apache.ws.security.saml.SAMLIssuer;
 import org.apache.ws.security.saml.WSSecSignatureSAML;
+import org.apache.ws.security.util.WSSecurityUtil;
 
 import org.apache.axis.Message;
 import org.apache.axis.MessageContext;
@@ -35,6 +36,7 @@
 import org.apache.ws.security.WSConstants;
 import org.apache.ws.security.WSPasswordCallback;
 import org.apache.ws.security.WSSecurityEngine;
+import org.apache.ws.security.WSSecurityEngineResult;
 import org.apache.ws.security.components.crypto.Crypto;
 import org.apache.ws.security.components.crypto.CryptoFactory;
 import org.apache.ws.security.message.WSSecHeader;
@@ -49,10 +51,10 @@
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.io.InputStream;
+import java.util.Vector;
 
 /**
- * WS-Security Test Case
- * <p/>
+ * Test-case for sending and processing a (signed) holder-of-key SAML Assertion.
  * 
  * @author Davanum Srinivas (dims@yahoo.com)
  */
@@ -76,7 +78,6 @@
 
     /**
      * TestWSSecurity constructor
-     * <p/>
      * 
      * @param name name of the test
      */
@@ -86,7 +87,6 @@
 
     /**
      * JUnit suite
-     * <p/>
      * 
      * @return a junit test suite
      */
@@ -96,7 +96,6 @@
 
     /**
      * Setup method
-     * <p/>
      * 
      * @throws Exception Thrown when there is a problem in setup
      */
@@ -108,7 +107,6 @@
 
     /**
      * Constructs a soap envelope
-     * <p/>
      * 
      * @return soap envelope
      * @throws Exception if there is any problem constructing the soap envelope
@@ -121,12 +119,7 @@
     }
 
     /**
-     * Test that encrypt and decrypt a WS-Security envelope.
-     * This test uses the RSA_15 algorithm to transport (wrap) the symmetric
-     * key.
-     * <p/>
-     * 
-     * @throws Exception Thrown when there is any problem in signing or verification
+     * * Test that creates, sends and processes an signed SAML assertion.
      */
     public void testSAMLSignedKeyHolder() throws Exception {
         SOAPEnvelope unsignedEnvelope = message.getSOAPEnvelope();
@@ -150,9 +143,9 @@
 
         LOG.info("Before SAMLSignedKeyHolder....");
         
-        /*
-         * set up for keyHolder
-         */
+        //
+        // set up for keyHolder
+        //
         Document signedDoc = wsSign.build(doc, crypto, assertion, null, null, null, secHeader);
         LOG.info("After SAMLSignedKeyHolder....");
 
@@ -162,26 +155,80 @@
                 org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(signedDoc);
             LOG.debug(outputString);
         }
-        verify(signedDoc);
+        
+        Vector results = verify(signedDoc);
+        WSSecurityEngineResult actionResult =
+            WSSecurityUtil.fetchActionResult(results, WSConstants.ST_UNSIGNED);
+        SAMLAssertion receivedAssertion = 
+            (SAMLAssertion) actionResult.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
+        assertTrue(receivedAssertion != null);
+    }
+    
+    
+    /**
+     * Test that creates, sends and processes an signed SAML assertion using a KeyIdentifier
+     * instead of direct reference.
+     */
+    public void testSAMLSignedKeyHolderKeyIdentifier() throws Exception {
+        SOAPEnvelope unsignedEnvelope = message.getSOAPEnvelope();
+
+        Document doc = unsignedEnvelope.getAsDocument();
+        
+        SAMLIssuer saml = SAMLIssuerFactory.getInstance("saml4.properties");
+        // Provide info to SAML issuer that it can construct a Holder-of-key
+        // SAML token.
+        saml.setInstanceDoc(doc);
+        saml.setUserCrypto(crypto);
+        saml.setUsername("16c73ab6-b892-458f-abf5-2f875f74882e");
+        SAMLAssertion assertion = saml.newAssertion();
+
+        WSSecSignatureSAML wsSign = new WSSecSignatureSAML();
+        wsSign.setKeyIdentifierType(WSConstants.X509_KEY_IDENTIFIER);
+        wsSign.setUserInfo("16c73ab6-b892-458f-abf5-2f875f74882e", "security");
+
+        WSSecHeader secHeader = new WSSecHeader();
+        secHeader.insertSecurityHeader(doc);
+
+        LOG.info("Before SAMLSignedKeyHolder....");
+        
+        //
+        // set up for keyHolder
+        //
+        Document signedDoc = wsSign.build(doc, crypto, assertion, null, null, null, secHeader);
+        LOG.info("After SAMLSignedKeyHolder....");
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("Signed SAML message (key holder):");
+            String outputString = 
+                org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(signedDoc);
+            LOG.debug(outputString);
+        }
+        
+        Vector results = verify(signedDoc);
+        WSSecurityEngineResult actionResult =
+            WSSecurityUtil.fetchActionResult(results, WSConstants.ST_UNSIGNED);
+        SAMLAssertion receivedAssertion = 
+            (SAMLAssertion) actionResult.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
+        assertTrue(receivedAssertion != null);
     }
 
     
     /**
      * Verifies the soap envelope
-     * <p/>
      * 
      * @param envelope 
      * @throws Exception Thrown when there is a problem in verification
      */
-    private void verify(Document doc) throws Exception {
-        secEngine.processSecurityHeader(doc, null, this, crypto);
+    private Vector verify(Document doc) throws Exception {
+        Vector results = secEngine.processSecurityHeader(doc, null, this, crypto);
         String outputString = 
             org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(doc);
         assertTrue(outputString.indexOf("LogTestService2") > 0 ? true : false);
+        return results;
     }
 
     public void handle(Callback[] callbacks)
-            throws IOException, UnsupportedCallbackException {
+        throws IOException, UnsupportedCallbackException {
         for (int i = 0; i < callbacks.length; i++) {
             if (callbacks[i] instanceof WSPasswordCallback) {
                 WSPasswordCallback pc = (WSPasswordCallback) callbacks[i];



---------------------------------------------------------------------
To unsubscribe, e-mail: wss4j-dev-unsubscribe@ws.apache.org
For additional commands, e-mail: wss4j-dev-help@ws.apache.org