You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ws.apache.org by co...@apache.org on 2012/09/05 15:59:57 UTC

svn commit: r1381188 - in /webservices/wss4j/branches/1_6_x-fixes/src: main/java/org/apache/ws/security/action/ main/java/org/apache/ws/security/handler/ test/java/org/apache/ws/security/message/

Author: coheigea
Date: Wed Sep  5 13:59:57 2012
New Revision: 1381188

URL: http://svn.apache.org/viewvc?rev=1381188&view=rev
Log:
[WSS-231] - There is an issue with the position of the <Timestamp> element in the <Security> header when using WSS4J calling .NET Web Services with WS-Security.


Conflicts:

	src/main/java/org/apache/ws/security/action/SignatureAction.java
	src/main/java/org/apache/ws/security/handler/RequestData.java

Modified:
    webservices/wss4j/branches/1_6_x-fixes/src/main/java/org/apache/ws/security/action/SignatureAction.java
    webservices/wss4j/branches/1_6_x-fixes/src/main/java/org/apache/ws/security/handler/RequestData.java
    webservices/wss4j/branches/1_6_x-fixes/src/main/java/org/apache/ws/security/handler/WSHandler.java
    webservices/wss4j/branches/1_6_x-fixes/src/test/java/org/apache/ws/security/message/SignatureTest.java

Modified: webservices/wss4j/branches/1_6_x-fixes/src/main/java/org/apache/ws/security/action/SignatureAction.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/branches/1_6_x-fixes/src/main/java/org/apache/ws/security/action/SignatureAction.java?rev=1381188&r1=1381187&r2=1381188&view=diff
==============================================================================
--- webservices/wss4j/branches/1_6_x-fixes/src/main/java/org/apache/ws/security/action/SignatureAction.java (original)
+++ webservices/wss4j/branches/1_6_x-fixes/src/main/java/org/apache/ws/security/action/SignatureAction.java Wed Sep  5 13:59:57 2012
@@ -19,14 +19,22 @@
 
 package org.apache.ws.security.action;
 
+import java.util.List;
+
 import javax.security.auth.callback.CallbackHandler;
 
+import org.apache.ws.security.WSConstants;
+import org.apache.ws.security.WSEncryptionPart;
 import org.apache.ws.security.WSPasswordCallback;
 import org.apache.ws.security.WSSecurityException;
 import org.apache.ws.security.handler.RequestData;
 import org.apache.ws.security.handler.WSHandler;
 import org.apache.ws.security.message.WSSecSignature;
+import org.apache.ws.security.util.WSSecurityUtil;
+
 import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
 
 public class SignatureAction implements Action {
     public void execute(WSHandler handler, int actionToDo, Document doc, RequestData reqData)
@@ -58,7 +66,40 @@ public class SignatureAction implements 
         }
 
         try {
-            wsSign.build(doc, reqData.getSigCrypto(), reqData.getSecHeader());
+            wsSign.prepare(doc, reqData.getSigCrypto(), reqData.getSecHeader());
+
+            Element siblingElementToPrepend = null;
+            for (WSEncryptionPart part : reqData.getSignatureParts()) {
+                if ("STRTransform".equals(part.getName()) && part.getId() == null) {
+                    part.setId(wsSign.getSecurityTokenReferenceURI());
+                } else if (reqData.isAppendSignatureAfterTimestamp()
+                        && WSConstants.WSU_NS.equals(part.getNamespace()) 
+                        && "Timestamp".equals(part.getName())) {
+                    List<Element> elements = 
+                        WSSecurityUtil.findElements(
+                            doc.getDocumentElement(), part.getName(), part.getNamespace()
+                        );
+                    if (elements != null && !elements.isEmpty()) {
+                        Element timestampElement = elements.get(0);
+                        Node child = timestampElement.getNextSibling();
+                        while (child != null && child.getNodeType() != Node.ELEMENT_NODE) {
+                            child = child.getNextSibling();
+                        }
+                        siblingElementToPrepend = (Element)child;
+                    }
+                }
+            }
+
+            List<javax.xml.crypto.dsig.Reference> referenceList = 
+                wsSign.addReferencesToSign(reqData.getSignatureParts(), reqData.getSecHeader());
+
+            if (reqData.isAppendSignatureAfterTimestamp() && siblingElementToPrepend == null) {
+                wsSign.computeSignature(referenceList, false, null);
+            } else {
+                wsSign.computeSignature(referenceList, true, siblingElementToPrepend);
+            }
+
+            wsSign.prependBSTElementToHeader(reqData.getSecHeader());
             reqData.getSignatureValues().add(wsSign.getSignatureValue());
         } catch (WSSecurityException e) {
             throw new WSSecurityException("Error during Signature: ", e);

Modified: webservices/wss4j/branches/1_6_x-fixes/src/main/java/org/apache/ws/security/handler/RequestData.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/branches/1_6_x-fixes/src/main/java/org/apache/ws/security/handler/RequestData.java?rev=1381188&r1=1381187&r2=1381188&view=diff
==============================================================================
--- webservices/wss4j/branches/1_6_x-fixes/src/main/java/org/apache/ws/security/handler/RequestData.java (original)
+++ webservices/wss4j/branches/1_6_x-fixes/src/main/java/org/apache/ws/security/handler/RequestData.java Wed Sep  5 13:59:57 2012
@@ -84,6 +84,7 @@ public class RequestData {
     private ReplayCache timestampReplayCache;
     private ReplayCache nonceReplayCache;
     private Collection<Pattern> subjectDNPatterns = new ArrayList<Pattern>();
+    private boolean appendSignatureAfterTimestamp;
 
     public void clear() {
         soapConstants = null;
@@ -109,6 +110,7 @@ public class RequestData {
         timestampReplayCache = null;
         nonceReplayCache = null;
         subjectDNPatterns.clear();
+        appendSignatureAfterTimestamp = false;
     }
 
     public Object getMsgContext() {
@@ -512,4 +514,12 @@ public class RequestData {
         return subjectDNPatterns;
     }
 
+    public boolean isAppendSignatureAfterTimestamp() {
+        return appendSignatureAfterTimestamp;
+    }
+
+    public void setAppendSignatureAfterTimestamp(boolean appendSignatureAfterTimestamp) {
+        this.appendSignatureAfterTimestamp = appendSignatureAfterTimestamp;
+    }
+
 }

Modified: webservices/wss4j/branches/1_6_x-fixes/src/main/java/org/apache/ws/security/handler/WSHandler.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/branches/1_6_x-fixes/src/main/java/org/apache/ws/security/handler/WSHandler.java?rev=1381188&r1=1381187&r2=1381188&view=diff
==============================================================================
--- webservices/wss4j/branches/1_6_x-fixes/src/main/java/org/apache/ws/security/handler/WSHandler.java (original)
+++ webservices/wss4j/branches/1_6_x-fixes/src/main/java/org/apache/ws/security/handler/WSHandler.java Wed Sep  5 13:59:57 2012
@@ -43,6 +43,7 @@ import java.security.cert.X509Certificat
 import java.util.Arrays;
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -142,8 +143,8 @@ public abstract class WSHandler {
             }
             decodeSignatureParameter(reqData);
         }
-        /*
-         * If we need to handle zsigned SAML token then we may need the
+        /*7
+         * If we need to handle signed SAML token then we may need the
          * Signature parameters. The handle procedure loads the signature crypto
          * file on demand, thus don't do it here.
          */
@@ -185,11 +186,34 @@ public abstract class WSHandler {
                 wssConfig.getAction(WSConstants.SC).execute(this, WSConstants.SC, doc, reqData);
             }
         }
+        
+        // See if the Signature and Timestamp actions (in that order) are defined, and if
+        // the Timestamp is to be signed. In this case we need to swap the actions, as the 
+        // Timestamp must appear in the security header first for signature creation to work.
+        List<Integer> actionsToPerform = actions;
+        if (actions.contains(WSConstants.SIGN) && actions.contains(WSConstants.TS)
+            && (actions.indexOf(WSConstants.SIGN) < actions.indexOf(WSConstants.TS))) {
+            boolean signTimestamp = false;
+            for (WSEncryptionPart encP : reqData.getSignatureParts()) {
+                if (WSConstants.WSU_NS.equals(encP.getNamespace()) 
+                    && "Timestamp".equals(encP.getName())) {
+                    signTimestamp = true;
+                }
+            }
+            if (signTimestamp) {
+                actionsToPerform = new ArrayList<Integer>(actions);
+                Collections.copy(actionsToPerform, actions);
+                actionsToPerform.remove(actions.indexOf(WSConstants.SIGN));
+                actionsToPerform.add(WSConstants.SIGN);
+                reqData.setAppendSignatureAfterTimestamp(true);
+            }
+        }
+        
         /*
          * Here we have all necessary information to perform the requested
          * action(s).
          */
-        for (Integer actionToDo : actions) {
+        for (Integer actionToDo : actionsToPerform) {
             if (doDebug) {
                 log.debug("Performing Action: " + actionToDo);
             }

Modified: webservices/wss4j/branches/1_6_x-fixes/src/test/java/org/apache/ws/security/message/SignatureTest.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/branches/1_6_x-fixes/src/test/java/org/apache/ws/security/message/SignatureTest.java?rev=1381188&r1=1381187&r2=1381188&view=diff
==============================================================================
--- webservices/wss4j/branches/1_6_x-fixes/src/test/java/org/apache/ws/security/message/SignatureTest.java (original)
+++ webservices/wss4j/branches/1_6_x-fixes/src/test/java/org/apache/ws/security/message/SignatureTest.java Wed Sep  5 13:59:57 2012
@@ -682,6 +682,50 @@ public class SignatureTest extends org.j
         WSSecurityEngine newEngine = new WSSecurityEngine();
         newEngine.processSecurityHeader(doc, null, null, passwordCrypto);
     }
+    
+    /**
+     * A test for "There is an issue with the position of the <Timestamp> element in the
+     * <Security> header when using WSS4J calling .NET Web Services with WS-Security."
+     */
+    @org.junit.Test
+    public void
+    testWSS231() throws Exception {
+        final WSSConfig cfg = WSSConfig.getNewInstance();
+        final int action = WSConstants.SIGN | WSConstants.TS;
+        final RequestData reqData = new RequestData();
+        reqData.setWssConfig(cfg);
+        reqData.setUsername("16c73ab6-b892-458f-abf5-2f875f74882e");
+        
+        java.util.Map<String, Object> config = new java.util.TreeMap<String, Object>();
+        config.put(WSHandlerConstants.SIG_PROP_FILE, "crypto.properties");
+        config.put("password", "security");
+        config.put(
+            WSHandlerConstants.SIGNATURE_PARTS, "{}{" + WSConstants.WSU_NS + "}Timestamp"
+        );
+        reqData.setMsgContext(config);
+        
+        final java.util.List<Integer> actions = new java.util.ArrayList<Integer>();
+        actions.add(Integer.valueOf(WSConstants.SIGN));
+        actions.add(Integer.valueOf(WSConstants.TS));
+        final Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
+        CustomHandler handler = new CustomHandler();
+        handler.send(
+            action, 
+            doc, 
+            reqData, 
+            actions,
+            true
+        );
+        String outputString = 
+            org.apache.ws.security.util.XMLUtils.PrettyDocumentToString(doc);
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("Signed message:");
+            LOG.debug(outputString);
+        }
+        
+        List<WSSecurityEngineResult> results = verify(doc);
+        assertTrue(handler.checkResults(results, actions));
+    }
 
     /**
      * Verifies the soap envelope.