Author: coheigea
Date: Mon Apr 11 11:24:29 2011
New Revision: 1091032

URL: http://svn.apache.org/viewvc?rev=1091032&view=rev
Log:
[WSS-276] - Support signing a SAML Assertion using a derived key
 - Added a fix plus a test.
 - Also fixed another bug with using the STRTransform with a direct reference.
 - Upgraded versions to 1.6.1-SNAPSHOT.

Added:
    
webservices/wss4j/trunk/src/test/java/org/apache/ws/security/saml/SamlTokenDerivedTest.java
Modified:
    webservices/wss4j/trunk/NOTICE
    webservices/wss4j/trunk/build.xml
    webservices/wss4j/trunk/pom.xml
    
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/message/WSSecDKSign.java
    
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/message/token/SecurityTokenReference.java

Modified: webservices/wss4j/trunk/NOTICE
URL: 
http://svn.apache.org/viewvc/webservices/wss4j/trunk/NOTICE?rev=1091032&r1=1091031&r2=1091032&view=diff
==============================================================================
--- webservices/wss4j/trunk/NOTICE (original)
+++ webservices/wss4j/trunk/NOTICE Mon Apr 11 11:24:29 2011
@@ -1,5 +1,5 @@
 Apache WebServices - WSS4J
-Copyright 2004-2009 The Apache Software Foundation
+Copyright 2004-2011 The Apache Software Foundation
 
 This product includes software developed by
 The Apache Software Foundation (http://www.apache.org/).

Modified: webservices/wss4j/trunk/build.xml
URL: 
http://svn.apache.org/viewvc/webservices/wss4j/trunk/build.xml?rev=1091032&r1=1091031&r2=1091032&view=diff
==============================================================================
--- webservices/wss4j/trunk/build.xml (original)
+++ webservices/wss4j/trunk/build.xml Mon Apr 11 11:24:29 2011
@@ -27,10 +27,10 @@ Build Instructions:
 
         <property name='product.version.major' value='1'/>
         <property name='product.version.minor' value='6'/>
-        <!--<property name='product.version.level' value='0'/>-->
+        <property name='product.version.level' value='1'/>
         <property name='product.version.qualifier' value='-SNAPSHOT'/>
-        <property name='product.version' 
value='${product.version.major}.${product.version.minor}${product.version.qualifier}'/>
-        <property name="year" value="2010"/>
+        <property name='product.version' 
value='${product.version.major}.${product.version.minor}.${product.version.level}${product.version.qualifier}'/>
+        <property name="year" value="2011"/>
         <property name="copyright" value="Copyright &#169; ${year} Apache 
WSS4J Project. All Rights Reserved."/>
 
         <!-- Give user a chance to override without editing this file

Modified: webservices/wss4j/trunk/pom.xml
URL: 
http://svn.apache.org/viewvc/webservices/wss4j/trunk/pom.xml?rev=1091032&r1=1091031&r2=1091032&view=diff
==============================================================================
--- webservices/wss4j/trunk/pom.xml (original)
+++ webservices/wss4j/trunk/pom.xml Mon Apr 11 11:24:29 2011
@@ -24,7 +24,7 @@
     <artifactId>wss4j</artifactId>
     <packaging>bundle</packaging>
     <name>WSS4J</name>
-    <version>1.6-SNAPSHOT</version>
+    <version>1.6.1-SNAPSHOT</version>
     <description>
         The Apache WSS4J project provides a Java implementation of the primary 
security standards 
         for Web Services, namely the OASIS Web Services Security (WS-Security) 
specifications 

Modified: 
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/message/WSSecDKSign.java
URL: 
http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/main/java/org/apache/ws/security/message/WSSecDKSign.java?rev=1091032&r1=1091031&r2=1091032&view=diff
==============================================================================
--- 
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/message/WSSecDKSign.java
 (original)
+++ 
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/message/WSSecDKSign.java
 Mon Apr 11 11:24:29 2011
@@ -27,6 +27,7 @@ import org.apache.ws.security.WSSecurity
 import org.apache.ws.security.conversation.ConversationException;
 import org.apache.ws.security.message.token.Reference;
 import org.apache.ws.security.message.token.SecurityTokenReference;
+import org.apache.ws.security.transform.STRTransform;
 import org.apache.ws.security.util.WSSecurityUtil;
 
 import org.w3c.dom.Document;
@@ -269,6 +270,7 @@ public class WSSecDKSign extends WSSecDe
                 );
             }
             URIDereferencer dereferencer = new DOMURIDereferencer();
+            signContext.setProperty(STRTransform.TRANSFORM_WS_DOC_INFO, 
wsDocInfo);
             wsDocInfo.setCallbackLookup(callbackLookup);
             ((DOMURIDereferencer)dereferencer).setWsDocInfo(wsDocInfo);
             signContext.setURIDereferencer(dereferencer);

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=1091032&r1=1091031&r2=1091032&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
 Mon Apr 11 11:24:29 2011
@@ -270,7 +270,7 @@ public class SecurityTokenReference {
         if (callbackLookup == null) {
             callbackLookup = new DOMCallbackLookup(doc);
         }
-        return callbackLookup.getElement(uri, type, true);
+        return callbackLookup.getElement(id, type, true);
     }
     
     /**

Added: 
webservices/wss4j/trunk/src/test/java/org/apache/ws/security/saml/SamlTokenDerivedTest.java
URL: 
http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/test/java/org/apache/ws/security/saml/SamlTokenDerivedTest.java?rev=1091032&view=auto
==============================================================================
--- 
webservices/wss4j/trunk/src/test/java/org/apache/ws/security/saml/SamlTokenDerivedTest.java
 (added)
+++ 
webservices/wss4j/trunk/src/test/java/org/apache/ws/security/saml/SamlTokenDerivedTest.java
 Mon Apr 11 11:24:29 2011
@@ -0,0 +1,208 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.ws.security.saml;
+
+import org.apache.ws.security.WSConstants;
+import org.apache.ws.security.WSDataRef;
+import org.apache.ws.security.WSEncryptionPart;
+import org.apache.ws.security.WSSConfig;
+import org.apache.ws.security.WSSecurityEngine;
+import org.apache.ws.security.WSSecurityEngineResult;
+import org.apache.ws.security.WSSecurityException;
+import org.apache.ws.security.common.KeystoreCallbackHandler;
+import org.apache.ws.security.common.SAML1CallbackHandler;
+import org.apache.ws.security.common.SOAPUtil;
+import org.apache.ws.security.components.crypto.Crypto;
+import org.apache.ws.security.components.crypto.CryptoFactory;
+import org.apache.ws.security.components.crypto.CryptoType;
+import org.apache.ws.security.message.WSSecDKSign;
+import org.apache.ws.security.message.WSSecHeader;
+import org.apache.ws.security.message.token.SecurityTokenReference;
+import org.apache.ws.security.saml.ext.AssertionWrapper;
+import org.apache.ws.security.saml.ext.SAMLParms;
+import org.apache.ws.security.saml.ext.builder.SAML1Constants;
+import org.apache.ws.security.util.WSSecurityUtil;
+
+import org.w3c.dom.Document;
+
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.security.auth.callback.CallbackHandler;
+
+/**
+ * Test-case for sending and processing a signed (sender vouches) SAML 
Assertion using a 
+ * derived key.
+ */
+public class SamlTokenDerivedTest extends org.junit.Assert {
+    private static final org.apache.commons.logging.Log LOG = 
+        
org.apache.commons.logging.LogFactory.getLog(SamlTokenDerivedTest.class);
+    private WSSecurityEngine secEngine = new WSSecurityEngine();
+    private CallbackHandler callbackHandler = new KeystoreCallbackHandler();
+    private Crypto crypto = null;
+    
+    public SamlTokenDerivedTest() throws Exception {
+        WSSConfig.init();
+        crypto = CryptoFactory.getInstance("crypto.properties");
+    }
+    
+    /**
+     * Test that creates, sends and processes a signed SAML 1.1 authentication 
assertion
+     * using a derived key.
+     */
+    @org.junit.Test
+    @SuppressWarnings("unchecked")
+    public void testSAML1AuthnAssertionDerived() throws Exception {
+        //
+        // Create a SAML Assertion + STR, and add both to the security header
+        //
+        SAML1CallbackHandler callbackHandler = new SAML1CallbackHandler();
+        callbackHandler.setStatement(SAML1CallbackHandler.Statement.AUTHN);
+        
callbackHandler.setConfirmationMethod(SAML1Constants.CONF_SENDER_VOUCHES);
+        callbackHandler.setIssuer("www.example.com");
+        
+        SAMLParms samlParms = new SAMLParms();
+        samlParms.setCallbackHandler(callbackHandler);
+        AssertionWrapper assertion = new AssertionWrapper(samlParms);
+        
+        Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
+        WSSecHeader secHeader = new WSSecHeader();
+        secHeader.insertSecurityHeader(doc);
+        
+        SecurityTokenReference secRefSaml = 
+            createSamlSTR(doc, assertion, WSSConfig.getNewInstance());
+        secHeader.getSecurityHeader().appendChild(assertion.toDOM(doc));
+        secHeader.getSecurityHeader().appendChild(secRefSaml.getElement());
+        
+        //
+        // Create a Derived Key object for signature
+        //
+        WSSecDKSign sigBuilder = createDKSign(doc, secRefSaml);
+        Document signedDoc = sigBuilder.build(doc, secHeader);
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("SAML 1.1 Authn Assertion Derived (sender vouches):");
+            String outputString = 
+                
org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(signedDoc);
+            LOG.debug(outputString);
+        }
+        
+        // Test we processed a SAML assertion
+        List<WSSecurityEngineResult> results = verify(signedDoc);
+        WSSecurityEngineResult actionResult =
+            WSSecurityUtil.fetchActionResult(results, WSConstants.ST_UNSIGNED);
+        AssertionWrapper receivedAssertion = 
+            (AssertionWrapper) 
actionResult.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);
+        assertTrue(receivedAssertion != null);
+        
+        // Test we processed a signature (SAML assertion + SOAP body)
+        actionResult = WSSecurityUtil.fetchActionResult(results, 
WSConstants.SIGN);
+        assertTrue(actionResult != null);
+        assertFalse(actionResult.isEmpty());
+        final List<WSDataRef> refs =
+            (List<WSDataRef>) 
actionResult.get(WSSecurityEngineResult.TAG_DATA_REF_URIS);
+        assertTrue(refs.size() == 2);
+        
+        WSDataRef wsDataRef = (WSDataRef)refs.get(0);
+        String xpath = wsDataRef.getXpath();
+        assertEquals("/SOAP-ENV:Envelope/SOAP-ENV:Body", xpath);
+        
+        wsDataRef = (WSDataRef)refs.get(1);
+        xpath = wsDataRef.getXpath();
+        
assertEquals("/SOAP-ENV:Envelope/SOAP-ENV:Header/wsse:Security/saml1:Assertion",
 xpath);
+    }
+    
+    /**
+     * Create a SecurityTokenReference to a SAML Assertion
+     */
+    private SecurityTokenReference createSamlSTR(
+        Document doc, 
+        AssertionWrapper assertion,
+        WSSConfig wssConfig
+    ) {
+        SecurityTokenReference secRefSaml = new SecurityTokenReference(doc);
+        String secRefID = 
wssConfig.getIdAllocator().createSecureId("STRSAMLId-", secRefSaml);
+        secRefSaml.setID(secRefID);
+
+        org.apache.ws.security.message.token.Reference ref = 
+            new org.apache.ws.security.message.token.Reference(doc);
+        ref.setURI("#" + assertion.getId());
+        ref.setValueType(WSConstants.WSS_SAML_KI_VALUE_TYPE);
+        secRefSaml.addTokenType(WSConstants.WSS_SAML_TOKEN_TYPE);
+        secRefSaml.setReference(ref);
+        
+        return secRefSaml;
+    }
+    
+    /**
+     * Create a WSSecDKSign object, that signs the SOAP Body as well as the 
SAML Assertion
+     * via a STR Transform.
+     */
+    private WSSecDKSign createDKSign(
+        Document doc,
+        SecurityTokenReference secRefSaml
+    ) throws WSSecurityException {
+        SecurityTokenReference secToken = new SecurityTokenReference(doc);
+        CryptoType cryptoType = new CryptoType(CryptoType.TYPE.ALIAS);
+        cryptoType.setAlias("16c73ab6-b892-458f-abf5-2f875f74882e");
+        X509Certificate[] certs = crypto.getX509Certificates(cryptoType);
+        secToken.setKeyIdentifierThumb(certs[0]);
+        
+        WSSecDKSign sigBuilder = new WSSecDKSign();
+        java.security.Key key = 
+            crypto.getPrivateKey("16c73ab6-b892-458f-abf5-2f875f74882e", 
"security");
+        sigBuilder.setExternalKey(key.getEncoded(), secToken.getElement());
+        sigBuilder.setSignatureAlgorithm(WSConstants.HMAC_SHA1);
+        List<WSEncryptionPart> parts = new ArrayList<WSEncryptionPart>(2);
+        String soapNamespace = 
WSSecurityUtil.getSOAPNamespace(doc.getDocumentElement());
+        WSEncryptionPart encP = 
+            new WSEncryptionPart(
+                WSConstants.ELEM_BODY,
+                soapNamespace, 
+                "Content"
+            );
+        parts.add(encP);
+        encP = new WSEncryptionPart("STRTransform", "", "Element");
+        encP.setId(secRefSaml.getID());
+        encP.setElement(secRefSaml.getElement());
+        parts.add(encP);
+        sigBuilder.setParts(parts);
+        
+        return sigBuilder;
+    }
+   
+    /**
+     * Verifies the soap envelope
+     * <p/>
+     * 
+     * @param envelope 
+     * @throws Exception Thrown when there is a problem in verification
+     */
+    private List<WSSecurityEngineResult> verify(Document doc) throws Exception 
{
+        List<WSSecurityEngineResult> results = 
+            secEngine.processSecurityHeader(doc, null, callbackHandler, 
crypto);
+        String outputString = 
+            org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(doc);
+        assertTrue(outputString.indexOf("counter_port_type") > 0 ? true : 
false);
+        return results;
+    }
+
+}


Reply via email to