Author: coheigea
Date: Thu Jan 20 14:02:55 2011
New Revision: 1061303

URL: http://svn.apache.org/viewvc?rev=1061303&view=rev
Log:
[WSS-146] - Added support for referencing a SAML assertion via direct reference 
in an EncryptedKey element
 - Added wsse11:TokenType attribute for referencing SAML assertions.

Modified:
    
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/WSConstants.java
    
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/message/WSSecEncrypt.java
    
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/message/WSSecEncryptedKey.java
    
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/message/token/SecurityTokenReference.java
    
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/saml/WSSecSignatureSAML.java
    
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/str/EncryptedKeySTRParser.java
    
webservices/wss4j/trunk/src/test/java/org/apache/ws/security/saml/SamlReferenceTest.java

Modified: 
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/WSConstants.java
URL: 
http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/main/java/org/apache/ws/security/WSConstants.java?rev=1061303&r1=1061302&r2=1061303&view=diff
==============================================================================
--- 
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/WSConstants.java 
(original)
+++ 
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/WSConstants.java 
Thu Jan 20 14:02:55 2011
@@ -156,6 +156,7 @@ public class WSConstants {
     public static final String X509_CERT_LN = "X509Certificate";
     public static final String KEYINFO_LN = "KeyInfo";
     public static final String KEYVALUE_LN = "KeyValue";
+    public static final String TOKEN_TYPE = "TokenType";
     
     public static final String ELEM_ENVELOPE = "Envelope";
     public static final String ELEM_HEADER = "Header";
@@ -234,6 +235,8 @@ public class WSConstants {
     //
     public static final String WSS_SAML_KI_VALUE_TYPE = SAMLTOKEN_NS + "#" + 
SAML_ASSERTION_ID;
     public static final String WSS_SAML2_KI_VALUE_TYPE = SAMLTOKEN_NS11 + "#" 
+ SAML2_ASSERTION_ID;
+    public static final String WSS_SAML_TOKEN_TYPE = SAMLTOKEN_NS11 + 
"#SAMLV1.1";
+    public static final String WSS_SAML2_TOKEN_TYPE = SAMLTOKEN_NS11 + 
"#SAMLV2.0";
     public static final String PASSWORD_DIGEST = USERNAMETOKEN_NS + 
"#PasswordDigest";
     public static final String PASSWORD_TEXT = USERNAMETOKEN_NS + 
"#PasswordText";
 

Modified: 
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/message/WSSecEncrypt.java
URL: 
http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/main/java/org/apache/ws/security/message/WSSecEncrypt.java?rev=1061303&r1=1061302&r2=1061303&view=diff
==============================================================================
--- 
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/message/WSSecEncrypt.java
 (original)
+++ 
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/message/WSSecEncrypt.java
 Thu Jan 20 14:02:55 2011
@@ -511,13 +511,18 @@ public class WSSecEncrypt extends WSSecE
             keyInfo.addUnknownElement(secToken.getElement());
         } else if (keyIdentifierType == WSConstants.EMBEDDED_KEYNAME) {
             keyInfo.addKeyName(embeddedKeyName == null ? user : 
embeddedKeyName);
-            // TODO Support SAML2 here
         } else if 
(WSConstants.WSS_SAML_KI_VALUE_TYPE.equals(customReferenceValue)) {
             SecurityTokenReference secToken = new 
SecurityTokenReference(document);
             secToken.setKeyIdentifier(
                 WSConstants.WSS_SAML_KI_VALUE_TYPE, (encKeyIdDirectId ? 
"":"#") + encKeyId
             );
             keyInfo.addUnknownElement(secToken.getElement());
+        } else if 
(WSConstants.WSS_SAML2_KI_VALUE_TYPE.equals(customReferenceValue)) {
+            SecurityTokenReference secToken = new 
SecurityTokenReference(document);
+            secToken.setKeyIdentifier(
+                WSConstants.WSS_SAML2_KI_VALUE_TYPE, (encKeyIdDirectId ? 
"":"#") + encKeyId
+            );
+            keyInfo.addUnknownElement(secToken.getElement());
         } else if (securityTokenReference != null) {
             Element tmpE = securityTokenReference.getElement();
             tmpE.setAttributeNS(

Modified: 
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/message/WSSecEncryptedKey.java
URL: 
http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/main/java/org/apache/ws/security/message/WSSecEncryptedKey.java?rev=1061303&r1=1061302&r2=1061303&view=diff
==============================================================================
--- 
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/message/WSSecEncryptedKey.java
 (original)
+++ 
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/message/WSSecEncryptedKey.java
 Thu Jan 20 14:02:55 2011
@@ -299,8 +299,37 @@ public class WSSecEncryptedKey extends W
             secToken.setReference(ref);
             break;
             
+        case WSConstants.CUSTOM_SYMM_SIGNING :
+            Reference refCust = new Reference(document);
+            refCust.setValueType(customEKTokenValueType);
+            refCust.setURI("#" + customEKTokenId);
+            secToken.setReference(refCust);
+            if 
(WSConstants.WSS_SAML_KI_VALUE_TYPE.equals(customEKTokenValueType)) {
+                secToken.addTokenType(WSConstants.WSS_SAML_TOKEN_TYPE);
+            } else if 
(WSConstants.WSS_SAML2_KI_VALUE_TYPE.equals(customEKTokenValueType)) {
+                secToken.addTokenType(WSConstants.WSS_SAML2_TOKEN_TYPE);
+            }
+            break;
+            
+        case WSConstants.CUSTOM_SYMM_SIGNING_DIRECT :
+            Reference refCustd = new Reference(document);
+            refCustd.setValueType(customEKTokenValueType);
+            refCustd.setURI(customEKTokenId);
+            secToken.setReference(refCustd);
+            if 
(WSConstants.WSS_SAML_KI_VALUE_TYPE.equals(customEKTokenValueType)) {
+                secToken.addTokenType(WSConstants.WSS_SAML_TOKEN_TYPE);
+            } else if 
(WSConstants.WSS_SAML2_KI_VALUE_TYPE.equals(customEKTokenValueType)) {
+                secToken.addTokenType(WSConstants.WSS_SAML2_TOKEN_TYPE);
+            }
+            break;
+            
         case WSConstants.CUSTOM_KEY_IDENTIFIER:
             secToken.setKeyIdentifier(customEKTokenValueType, customEKTokenId);
+            if 
(WSConstants.WSS_SAML_KI_VALUE_TYPE.equals(customEKTokenValueType)) {
+                secToken.addTokenType(WSConstants.WSS_SAML_TOKEN_TYPE);
+            } else if 
(WSConstants.WSS_SAML2_KI_VALUE_TYPE.equals(customEKTokenValueType)) {
+                secToken.addTokenType(WSConstants.WSS_SAML2_TOKEN_TYPE);
+            }
             break;           
 
         default:

Modified: 
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/message/token/SecurityTokenReference.java
URL: 
http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/main/java/org/apache/ws/security/message/token/SecurityTokenReference.java?rev=1061303&r1=1061302&r2=1061303&view=diff
==============================================================================
--- 
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/message/token/SecurityTokenReference.java
 (original)
+++ 
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/message/token/SecurityTokenReference.java
 Thu Jan 20 14:02:55 2011
@@ -105,6 +105,19 @@ public class SecurityTokenReference {
     public void addWSUNamespace() {
         WSSecurityUtil.setNamespace(element, WSConstants.WSU_NS, 
WSConstants.WSU_PREFIX);
     }
+    
+    /**
+     * Add a wsse11:TokenType attribute to this SecurityTokenReference
+     * @param tokenType the wsse11:TokenType attribute to add
+     */
+    public void addTokenType(String tokenType) {
+        WSSecurityUtil.setNamespace(element, WSConstants.WSSE11_NS, 
WSConstants.WSSE11_PREFIX);
+        element.setAttributeNS(
+            WSConstants.WSSE11_NS, 
+            WSConstants.WSSE11_PREFIX + ":" + WSConstants.TOKEN_TYPE, 
+            tokenType
+        );
+    }
 
     /**
      * set the reference.

Modified: 
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/saml/WSSecSignatureSAML.java
URL: 
http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/main/java/org/apache/ws/security/saml/WSSecSignatureSAML.java?rev=1061303&r1=1061302&r2=1061303&view=diff
==============================================================================
--- 
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/saml/WSSecSignatureSAML.java
 (original)
+++ 
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/saml/WSSecSignatureSAML.java
 Thu Jan 20 14:02:55 2011
@@ -333,8 +333,10 @@ public class WSSecSignatureSAML extends 
                     ref.setURI("#" + assertion.getId());
                     if (assertion.getSaml1() != null) {
                         ref.setValueType(WSConstants.WSS_SAML_KI_VALUE_TYPE);
+                        
secRefSaml.addTokenType(WSConstants.WSS_SAML_TOKEN_TYPE);
                     } else if (assertion.getSaml2() != null) {
                         ref.setValueType(WSConstants.WSS_SAML2_KI_VALUE_TYPE);
+                        
secRefSaml.addTokenType(WSConstants.WSS_SAML2_TOKEN_TYPE);
                     }
                     secRefSaml.setReference(ref);
                 } else {
@@ -342,8 +344,10 @@ public class WSSecSignatureSAML extends 
                     String valueType = null;
                     if (assertion.getSaml1() != null) {
                         valueType = WSConstants.WSS_SAML_KI_VALUE_TYPE;
+                        
secRefSaml.addTokenType(WSConstants.WSS_SAML_TOKEN_TYPE);
                     } else if (assertion.getSaml2() != null) {
                         valueType = WSConstants.WSS_SAML2_KI_VALUE_TYPE;
+                        
secRefSaml.addTokenType(WSConstants.WSS_SAML2_TOKEN_TYPE);
                     }
                     keyId.setAttributeNS(
                         null, "ValueType", valueType
@@ -394,8 +398,10 @@ public class WSSecSignatureSAML extends 
             ref.setURI("#" + assertion.getId());
             if (assertion.getSaml1() != null) {
                 ref.setValueType(WSConstants.WSS_SAML_KI_VALUE_TYPE);
+                secRef.addTokenType(WSConstants.WSS_SAML_TOKEN_TYPE);
             } else if (assertion.getSaml2() != null) {
                 ref.setValueType(WSConstants.WSS_SAML2_KI_VALUE_TYPE);
+                secRef.addTokenType(WSConstants.WSS_SAML2_TOKEN_TYPE);
             }
             secRef.setReference(ref);
         } else {
@@ -403,8 +409,10 @@ public class WSSecSignatureSAML extends 
             String valueType = null;
             if (assertion.getSaml1() != null) {
                 valueType = WSConstants.WSS_SAML_KI_VALUE_TYPE;
+                secRef.addTokenType(WSConstants.WSS_SAML_TOKEN_TYPE);
             } else if (assertion.getSaml2() != null) {
                 valueType = WSConstants.WSS_SAML2_KI_VALUE_TYPE;
+                secRef.addTokenType(WSConstants.WSS_SAML2_TOKEN_TYPE);
             }
             keyId.setAttributeNS(
                 null, "ValueType", valueType

Modified: 
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/str/EncryptedKeySTRParser.java
URL: 
http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/main/java/org/apache/ws/security/str/EncryptedKeySTRParser.java?rev=1061303&r1=1061302&r2=1061303&view=diff
==============================================================================
--- 
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/str/EncryptedKeySTRParser.java
 (original)
+++ 
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/str/EncryptedKeySTRParser.java
 Thu Jan 20 14:02:55 2011
@@ -31,6 +31,7 @@ import org.apache.ws.security.message.to
 import org.apache.ws.security.message.token.X509Security;
 import org.apache.ws.security.saml.SAMLKeyInfo;
 import org.apache.ws.security.saml.SAMLUtil;
+import org.apache.ws.security.saml.ext.AssertionWrapper;
 import org.w3c.dom.Element;
 
 import java.security.Principal;
@@ -112,6 +113,12 @@ public class EncryptedKeySTRParser imple
                             (X509Certificate[])result.get(
                                 WSSecurityEngineResult.TAG_X509_CERTIFICATES
                             );
+                    } else if (WSConstants.ST_UNSIGNED == action) {
+                        AssertionWrapper assertion = 
+                            
(AssertionWrapper)result.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
+                        SAMLKeyInfo keyInfo = 
+                            SAMLUtil.getCredentialFromSubject(assertion, 
crypto, cb);
+                        certs = keyInfo.getCerts();
                     } else {
                         throw new WSSecurityException(
                             WSSecurityException.UNSUPPORTED_SECURITY_TOKEN,

Modified: 
webservices/wss4j/trunk/src/test/java/org/apache/ws/security/saml/SamlReferenceTest.java
URL: 
http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/test/java/org/apache/ws/security/saml/SamlReferenceTest.java?rev=1061303&r1=1061302&r2=1061303&view=diff
==============================================================================
--- 
webservices/wss4j/trunk/src/test/java/org/apache/ws/security/saml/SamlReferenceTest.java
 (original)
+++ 
webservices/wss4j/trunk/src/test/java/org/apache/ws/security/saml/SamlReferenceTest.java
 Thu Jan 20 14:02:55 2011
@@ -53,6 +53,8 @@ import javax.security.auth.callback.Call
 
 /**
  * Some tests for how SAML tokens are referenced.
+ * TODO - Add tests for references from an EncryptedData structure to a SAML 
Assertion when
+ * WSS-265 is fixed: https://issues.apache.org/jira/browse/WSS-265
  */
 public class SamlReferenceTest extends org.junit.Assert {
     private static final Log LOG = LogFactory.getLog(SamlReferenceTest.class);
@@ -107,14 +109,16 @@ public class SamlReferenceTest extends o
                 "security", secHeader
             );
 
+        String outputString = 
+            
org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(signedDoc);
         if (LOG.isDebugEnabled()) {
             LOG.debug("Signed SAML message Key Identifier (sender vouches):");
-            String outputString = 
-                
org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(signedDoc);
             LOG.debug(outputString);
         }
+        assert outputString.contains(WSConstants.WSS_SAML_KI_VALUE_TYPE);
+        assert outputString.contains(WSConstants.WSS_SAML_TOKEN_TYPE);
         
-        List<WSSecurityEngineResult> results = verify(signedDoc, crypto);
+        List<WSSecurityEngineResult> results = verify(signedDoc, crypto, null);
         WSSecurityEngineResult actionResult =
             WSSecurityUtil.fetchActionResult(results, WSConstants.ST_UNSIGNED);
         AssertionWrapper receivedAssertion = 
@@ -167,14 +171,16 @@ public class SamlReferenceTest extends o
                 "security", secHeader
             );
 
+        String outputString = 
+            org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(doc);
         if (LOG.isDebugEnabled()) {
             LOG.debug("Signed SAML message Direct Reference (sender 
vouches):");
-            String outputString = 
-                
org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(signedDoc);
             LOG.debug(outputString);
         }
+        assert outputString.contains(WSConstants.WSS_SAML_KI_VALUE_TYPE);
+        assert outputString.contains(WSConstants.WSS_SAML_TOKEN_TYPE);
         
-        List<WSSecurityEngineResult> results = verify(signedDoc, crypto);
+        List<WSSecurityEngineResult> results = verify(signedDoc, crypto, null);
         WSSecurityEngineResult actionResult =
             WSSecurityUtil.fetchActionResult(results, WSConstants.ST_UNSIGNED);
         AssertionWrapper receivedAssertion = 
@@ -231,15 +237,16 @@ public class SamlReferenceTest extends o
         Document signedDoc = 
             wsSign.build(doc, userCrypto, assertion, null, null, null, 
secHeader);
 
-
+        String outputString = 
+            org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(doc);
         if (LOG.isDebugEnabled()) {
             LOG.debug("Signed SAML message Key Identifier (holder-of-key):");
-            String outputString = 
-                
org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(signedDoc);
             LOG.debug(outputString);
         }
+        assert outputString.contains(WSConstants.WSS_SAML_KI_VALUE_TYPE);
+        assert outputString.contains(WSConstants.WSS_SAML_TOKEN_TYPE);
         
-        List<WSSecurityEngineResult> results = verify(signedDoc, trustCrypto);
+        List<WSSecurityEngineResult> results = verify(signedDoc, trustCrypto, 
null);
         WSSecurityEngineResult actionResult =
             WSSecurityUtil.fetchActionResult(results, WSConstants.ST_UNSIGNED);
         AssertionWrapper receivedAssertion = 
@@ -296,15 +303,16 @@ public class SamlReferenceTest extends o
         Document signedDoc = 
             wsSign.build(doc, userCrypto, assertion, null, null, null, 
secHeader);
 
-
+        String outputString = 
+            org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(doc);
         if (LOG.isDebugEnabled()) {
             LOG.debug("Signed SAML message Direct Reference (holder-of-key):");
-            String outputString = 
-                
org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(signedDoc);
             LOG.debug(outputString);
         }
+        assert outputString.contains(WSConstants.WSS_SAML_KI_VALUE_TYPE);
+        assert outputString.contains(WSConstants.WSS_SAML_TOKEN_TYPE);
         
-        List<WSSecurityEngineResult> results = verify(signedDoc, trustCrypto);
+        List<WSSecurityEngineResult> results = verify(signedDoc, trustCrypto, 
null);
         WSSecurityEngineResult actionResult =
             WSSecurityUtil.fetchActionResult(results, WSConstants.ST_UNSIGNED);
         AssertionWrapper receivedAssertion = 
@@ -370,40 +378,129 @@ public class SamlReferenceTest extends o
             LOG.debug("Encrypted message:");
             LOG.debug(outputString);
         }
+        assert outputString.contains(WSConstants.WSS_SAML_KI_VALUE_TYPE);
+        assert outputString.contains(WSConstants.WSS_SAML_TOKEN_TYPE);
         
-        verify(encryptedDoc, crypto);
+        verify(encryptedDoc, crypto, crypto);
     }
     
     
     /**
      * The body of the SOAP request is encrypted using a secret key, which is 
in turn encrypted
      * using the certificate embedded in the SAML assertion and referenced 
using a Key Identifier.
-     * This test checks that KeyIdentifier (and not Reference) elements are 
used to identify 
-     * SAML tokens
+     * This tests that we can process a KeyIdentifier to a SAML Assertion in 
the KeyInfo of an
+     * EncryptedKey.
      */
     @org.junit.Test
-    @org.junit.Ignore
-    public void testSAMLEncryptedKey() throws Exception {
+    @SuppressWarnings("unchecked")
+    public void testSAML1HOKEKKeyIdentifier() throws Exception {
         // Create a SAML assertion
-        SAMLIssuer saml = SAMLIssuerFactory.getInstance("saml_hok.properties");
-        Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
-        Crypto hokCrypto = CryptoFactory.getInstance("crypto.properties");
+        SAML1CallbackHandler callbackHandler = new SAML1CallbackHandler();
+        callbackHandler.setStatement(SAML1CallbackHandler.Statement.AUTHN);
+        callbackHandler.setConfirmationMethod(SAML1Constants.CONF_HOLDER_KEY);
+        SAMLIssuer saml = new SAMLIssuerImpl();
+        saml.setIssuerName("www.example.com");
+        saml.setIssuerCrypto(issuerCrypto);
+        saml.setIssuerKeyName("wss40_server");
+        saml.setIssuerKeyPassword("security");
+        saml.setSignAssertion(true);
+        saml.setCallbackHandler(callbackHandler);
         AssertionWrapper assertion = saml.newAssertion();
+
+        Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
+        WSSecHeader secHeader = new WSSecHeader();
         Node assertionNode = assertion.toDOM(doc);
+        secHeader.insertSecurityHeader(doc);
+        secHeader.getSecurityHeader().appendChild(assertionNode);
+        
+        // Encrypt the SOAP body
+        WSSecEncrypt builder = new WSSecEncrypt();
+        builder.setUserInfo("wss40");
+        builder.setSymmetricEncAlgorithm(WSConstants.TRIPLE_DES);
+        builder.setKeyIdentifierType(WSConstants.CUSTOM_KEY_IDENTIFIER);
+        builder.setCustomEKTokenValueType(WSConstants.WSS_SAML_KI_VALUE_TYPE);
+        builder.setCustomEKTokenId(assertion.getId());
+        builder.prepare(doc, userCrypto);
+        
+        List<WSEncryptionPart> parts = new ArrayList<WSEncryptionPart>();
+        WSEncryptionPart encP = 
+            new WSEncryptionPart(
+                "add", "http://ws.apache.org/counter/counter_port_type";, 
"Element"
+            );
+        parts.add(encP);
+        Element refElement = builder.encryptForRef(null, parts);
+        builder.addInternalRefElement(refElement);
+        builder.appendToHeader(secHeader);
+
+        String outputString = 
+            org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(doc);
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("Encrypted SAML 1.1 message Key Identifier 
(holder-of-key):");
+            LOG.debug(outputString);
+        }
+        assert outputString.contains(WSConstants.WSS_SAML_KI_VALUE_TYPE);
+        assert outputString.contains(WSConstants.WSS_SAML_TOKEN_TYPE);
+        
+        List<WSSecurityEngineResult> results = verify(doc, trustCrypto, 
userCrypto);
+        WSSecurityEngineResult actionResult =
+            WSSecurityUtil.fetchActionResult(results, WSConstants.ST_UNSIGNED);
+        AssertionWrapper receivedAssertion = 
+            (AssertionWrapper) 
actionResult.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
+        assertTrue(receivedAssertion != null);
+        assert receivedAssertion.isSigned();
+        
+        // Test we processed an encrypted element
+        actionResult = WSSecurityUtil.fetchActionResult(results, 
WSConstants.ENCR);
+        assertTrue(actionResult != null);
+        assertFalse(actionResult.isEmpty());
+        final List<WSDataRef> refs =
+            (List<WSDataRef>) 
actionResult.get(WSSecurityEngineResult.TAG_DATA_REF_URIS);
+        assertTrue(refs.size() == 1);
+        
+        WSDataRef wsDataRef = (WSDataRef)refs.get(0);
+        String xpath = wsDataRef.getXpath();
+        assertEquals("/SOAP-ENV:Envelope/SOAP-ENV:Body/add", xpath);
         
+    }
+    
+    /**
+     * The body of the SOAP request is encrypted using a secret key, which is 
in turn encrypted
+     * using the certificate embedded in the SAML assertion and referenced 
using Direct
+     * Reference. This method is not spec compliant and is included to make 
sure we can process 
+     * third-party Assertions referenced in this way. This tests that we can 
process a Direct
+     * Reference to a SAML Assertion in the KeyInfo of an EncryptedKey.
+     */
+    @org.junit.Test
+    @SuppressWarnings("unchecked")
+    public void testSAML1HOKEKDirectReference() throws Exception {
+        // Create a SAML assertion
+        SAML1CallbackHandler callbackHandler = new SAML1CallbackHandler();
+        callbackHandler.setStatement(SAML1CallbackHandler.Statement.AUTHN);
+        callbackHandler.setConfirmationMethod(SAML1Constants.CONF_HOLDER_KEY);
+        SAMLIssuer saml = new SAMLIssuerImpl();
+        saml.setIssuerName("www.example.com");
+        saml.setIssuerCrypto(issuerCrypto);
+        saml.setIssuerKeyName("wss40_server");
+        saml.setIssuerKeyPassword("security");
+        saml.setSignAssertion(true);
+        saml.setCallbackHandler(callbackHandler);
+        AssertionWrapper assertion = saml.newAssertion();
+
+        Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
         WSSecHeader secHeader = new WSSecHeader();
+        Node assertionNode = assertion.toDOM(doc);
         secHeader.insertSecurityHeader(doc);
         secHeader.getSecurityHeader().appendChild(assertionNode);
         
         // Encrypt the SOAP body
         WSSecEncrypt builder = new WSSecEncrypt();
-        builder.setUserInfo("16c73ab6-b892-458f-abf5-2f875f74882e");
+        builder.setUserInfo("wss40");
         builder.setSymmetricEncAlgorithm(WSConstants.TRIPLE_DES);
-        builder.setKeyIdentifierType(WSConstants.CUSTOM_KEY_IDENTIFIER);
+        builder.setKeyIdentifierType(WSConstants.CUSTOM_SYMM_SIGNING);
         builder.setCustomEKTokenValueType(WSConstants.WSS_SAML_KI_VALUE_TYPE);
         builder.setCustomEKTokenId(assertion.getId());
+        builder.prepare(doc, userCrypto);
         
-        builder.prepare(doc, hokCrypto);
         List<WSEncryptionPart> parts = new ArrayList<WSEncryptionPart>();
         WSEncryptionPart encP = 
             new WSEncryptionPart(
@@ -414,19 +511,35 @@ public class SamlReferenceTest extends o
         builder.addInternalRefElement(refElement);
         builder.appendToHeader(secHeader);
 
+        String outputString = 
+            org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(doc);
         if (LOG.isDebugEnabled()) {
-            LOG.debug("Signed SAML message (HOK):");
-            String outputString = 
-                
org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(doc);
+            LOG.debug("Encrypted SAML 1.1 message Direct Reference 
(holder-of-key):");
             LOG.debug(outputString);
         }
+        assert outputString.contains(WSConstants.WSS_SAML_KI_VALUE_TYPE);
+        assert outputString.contains(WSConstants.WSS_SAML_TOKEN_TYPE);
         
-        List<WSSecurityEngineResult> results = verify(doc, hokCrypto);
+        List<WSSecurityEngineResult> results = verify(doc, trustCrypto, 
userCrypto);
         WSSecurityEngineResult actionResult =
             WSSecurityUtil.fetchActionResult(results, WSConstants.ST_UNSIGNED);
         AssertionWrapper receivedAssertion = 
             (AssertionWrapper) 
actionResult.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
         assertTrue(receivedAssertion != null);
+        assert receivedAssertion.isSigned();
+        
+        // Test we processed an encrypted element
+        actionResult = WSSecurityUtil.fetchActionResult(results, 
WSConstants.ENCR);
+        assertTrue(actionResult != null);
+        assertFalse(actionResult.isEmpty());
+        final List<WSDataRef> refs =
+            (List<WSDataRef>) 
actionResult.get(WSSecurityEngineResult.TAG_DATA_REF_URIS);
+        assertTrue(refs.size() == 1);
+        
+        WSDataRef wsDataRef = (WSDataRef)refs.get(0);
+        String xpath = wsDataRef.getXpath();
+        assertEquals("/SOAP-ENV:Envelope/SOAP-ENV:Body/add", xpath);
+        
     }
     
     
@@ -436,9 +549,11 @@ public class SamlReferenceTest extends o
      * @param doc
      * @throws Exception Thrown when there is a problem in verification
      */
-    private List<WSSecurityEngineResult> verify(Document doc, Crypto 
verifyCrypto) throws Exception {
+    private List<WSSecurityEngineResult> verify(
+        Document doc, Crypto verifyCrypto, Crypto decCrypto
+    ) throws Exception {
         List<WSSecurityEngineResult> results = 
-            secEngine.processSecurityHeader(doc, null, callbackHandler, 
verifyCrypto);
+            secEngine.processSecurityHeader(doc, null, callbackHandler, 
verifyCrypto, decCrypto);
         String outputString = 
             org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(doc);
         assertTrue(outputString.indexOf("counter_port_type") > 0 ? true : 
false);


Reply via email to