ws-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From gi...@apache.org
Subject svn commit: r1491556 - in /webservices/wss4j/trunk/ws-security-stax/src: main/java/org/apache/wss4j/stax/impl/processor/output/SecurityHeaderReorderProcessor.java test/java/org/apache/wss4j/stax/test/HeaderOrderingTest.java
Date Mon, 10 Jun 2013 18:25:46 GMT
Author: giger
Date: Mon Jun 10 18:25:45 2013
New Revision: 1491556

URL: http://svn.apache.org/r1491556
Log:
WSS-450 - Inbound Processing code fails with an Encrypted Signature 

Modified:
    webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/wss4j/stax/impl/processor/output/SecurityHeaderReorderProcessor.java
    webservices/wss4j/trunk/ws-security-stax/src/test/java/org/apache/wss4j/stax/test/HeaderOrderingTest.java

Modified: webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/wss4j/stax/impl/processor/output/SecurityHeaderReorderProcessor.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/wss4j/stax/impl/processor/output/SecurityHeaderReorderProcessor.java?rev=1491556&r1=1491555&r2=1491556&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/wss4j/stax/impl/processor/output/SecurityHeaderReorderProcessor.java
(original)
+++ webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/wss4j/stax/impl/processor/output/SecurityHeaderReorderProcessor.java
Mon Jun 10 18:25:45 2013
@@ -31,7 +31,6 @@ import org.apache.xml.security.stax.ext.
 import org.apache.xml.security.stax.ext.stax.XMLSecStartElement;
 import org.apache.xml.security.stax.impl.processor.output.FinalOutputProcessor;
 
-import javax.xml.namespace.QName;
 import javax.xml.stream.XMLStreamConstants;
 import javax.xml.stream.XMLStreamException;
 import java.util.*;
@@ -46,8 +45,8 @@ import java.util.*;
  */
 public class SecurityHeaderReorderProcessor extends AbstractOutputProcessor {
 
-    final private Map<XMLSecurityConstants.Action, Map<QName, Deque<XMLSecEvent>>>
actionEventMap =
-            new LinkedHashMap<XMLSecurityConstants.Action, Map<QName, Deque<XMLSecEvent>>>();
+    final private Map<XMLSecurityConstants.Action, Map<SecurityHeaderOrder, Deque<XMLSecEvent>>>
actionEventMap =
+            new LinkedHashMap<XMLSecurityConstants.Action, Map<SecurityHeaderOrder,
Deque<XMLSecEvent>>>();
 
     private int securityHeaderIndex = 0;
     private Deque<XMLSecEvent> currentDeque;
@@ -65,12 +64,12 @@ public class SecurityHeaderReorderProces
         XMLSecurityConstants.Action[] outActions = getSecurityProperties().getOutAction();
         for (int i = outActions.length - 1; i >= 0; i--) {
             XMLSecurityConstants.Action outAction = outActions[i];
-            actionEventMap.put(outAction, new TreeMap<QName, Deque<XMLSecEvent>>(new
Comparator<QName>() {
+            actionEventMap.put(outAction, new TreeMap<SecurityHeaderOrder, Deque<XMLSecEvent>>(new
Comparator<SecurityHeaderOrder>() {
                 @Override
-                public int compare(QName o1, QName o2) {
-                    if (WSSConstants.TAG_dsig_Signature.equals(o1)) {
+                public int compare(SecurityHeaderOrder o1, SecurityHeaderOrder o2) {
+                    if (WSSConstants.TAG_dsig_Signature.equals(o1.getSecurityHeaderElementName()))
{
                         return 1;
-                    } else if (WSSConstants.TAG_dsig_Signature.equals(o2)) {
+                    } else if (WSSConstants.TAG_dsig_Signature.equals(o2.getSecurityHeaderElementName()))
{
                         return -1;
                     }
                     return 1;
@@ -95,12 +94,43 @@ public class SecurityHeaderReorderProces
             if (xmlSecEvent.isEndElement() && xmlSecEvent.asEndElement().getName().equals(WSSConstants.TAG_wsse_Security))
{
                 OutputProcessorChain subOutputProcessorChain = outputProcessorChain.createSubChain(this);
 
-                Iterator<Map.Entry<XMLSecurityConstants.Action, Map<QName, Deque<XMLSecEvent>>>>
iterator = actionEventMap.entrySet().iterator();
+                Iterator<Map.Entry<XMLSecurityConstants.Action, Map<SecurityHeaderOrder,
Deque<XMLSecEvent>>>> iterator = actionEventMap.entrySet().iterator();
+                loop:
                 while (iterator.hasNext()) {
-                    Map.Entry<XMLSecurityConstants.Action, Map<QName, Deque<XMLSecEvent>>>
next = iterator.next();
-                    Iterator<Map.Entry<QName, Deque<XMLSecEvent>>> entryIterator
= next.getValue().entrySet().iterator();
+                    Map.Entry<XMLSecurityConstants.Action, Map<SecurityHeaderOrder,
Deque<XMLSecEvent>>> next = iterator.next();
+
+                    boolean encryptAction = false;
+                    Iterator<Map.Entry<SecurityHeaderOrder, Deque<XMLSecEvent>>>
entryIterator = next.getValue().entrySet().iterator();
                     while (entryIterator.hasNext()) {
-                        Map.Entry<QName, Deque<XMLSecEvent>> entry = entryIterator.next();
+                        Map.Entry<SecurityHeaderOrder, Deque<XMLSecEvent>> entry
= entryIterator.next();
+                        //output all non encrypted headers until...
+                        if (!entry.getKey().isEncrypted()) {
+                            Deque<XMLSecEvent> xmlSecEvents = entry.getValue();
+                            while (!xmlSecEvents.isEmpty()) {
+                                XMLSecEvent event = xmlSecEvents.pop();
+                                subOutputProcessorChain.reset();
+                                subOutputProcessorChain.processEvent(event);
+                            }
+                            //remove the actual header so that it won't be outputted twice
in the loop below
+                            entryIterator.remove();
+                        }
+                        //... the action is encryption and...
+                        if (entry.getKey().getAction().getName().contains("Encrypt")) {
+                            encryptAction = true;
+                        }
+                    }
+                    //...output the rest of the encrypt action and...
+                    if (encryptAction) {
+                        break loop;
+                    }
+                }
+                //...loop again over the headers and output the leftover headers
+                iterator = actionEventMap.entrySet().iterator();
+                while (iterator.hasNext()) {
+                    Map.Entry<XMLSecurityConstants.Action, Map<SecurityHeaderOrder,
Deque<XMLSecEvent>>> next = iterator.next();
+                    Iterator<Map.Entry<SecurityHeaderOrder, Deque<XMLSecEvent>>>
entryIterator = next.getValue().entrySet().iterator();
+                    while (entryIterator.hasNext()) {
+                        Map.Entry<SecurityHeaderOrder, Deque<XMLSecEvent>> entry
= entryIterator.next();
                         Deque<XMLSecEvent> xmlSecEvents = entry.getValue();
                         while (!xmlSecEvents.isEmpty()) {
                             XMLSecEvent event = xmlSecEvents.pop();
@@ -129,24 +159,9 @@ public class SecurityHeaderReorderProces
                                         " but got " + xmlSecStartElement.getName());
                     }
 
-                    Map<QName, Deque<XMLSecEvent>> map = null;
-                    if (!securityHeaderOrder.isEncrypted()) {
-                        map = actionEventMap.get(securityHeaderOrder.getAction());
-                    } else {
-                        Iterator<Map.Entry<XMLSecurityConstants.Action, Map<QName,
Deque<XMLSecEvent>>>> iterator = actionEventMap.entrySet().iterator();
-                        while (iterator.hasNext()) {
-                            Map.Entry<XMLSecurityConstants.Action, Map<QName, Deque<XMLSecEvent>>>
next = iterator.next();
-                            if (next.getKey().getName().contains("Encrypt")) {
-                                map = next.getValue();
-                                break;
-                            }
-                        }
-                        if (map == null) {
-                            throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE,
"empty", "No encrypt action found");
-                        }
-                    }
+                    Map<SecurityHeaderOrder, Deque<XMLSecEvent>> map = actionEventMap.get(securityHeaderOrder.getAction());
                     currentDeque = new ArrayDeque<XMLSecEvent>();
-                    map.put(securityHeaderOrder.getSecurityHeaderElementName(), currentDeque);
+                    map.put(securityHeaderOrder, currentDeque);
 
                     securityHeaderIndex++;
                     break;

Modified: webservices/wss4j/trunk/ws-security-stax/src/test/java/org/apache/wss4j/stax/test/HeaderOrderingTest.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-stax/src/test/java/org/apache/wss4j/stax/test/HeaderOrderingTest.java?rev=1491556&r1=1491555&r2=1491556&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-stax/src/test/java/org/apache/wss4j/stax/test/HeaderOrderingTest.java
(original)
+++ webservices/wss4j/trunk/ws-security-stax/src/test/java/org/apache/wss4j/stax/test/HeaderOrderingTest.java
Mon Jun 10 18:25:45 2013
@@ -665,4 +665,74 @@ public class HeaderOrderingTest extends 
             doInboundSecurityWithWSS4J_1(documentBuilderFactory.newDocumentBuilder().parse(new
ByteArrayInputStream(baos.toByteArray())), action, properties, true);
         }
     }
+
+    @Test
+    public void testUsernameTokenPlusTimestampPlusSignatureWithBSTSignedAndEncryptedStrictHeaderOrdering()
throws Exception {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+
+        {
+            WSSSecurityProperties securityProperties = new WSSSecurityProperties();
+            WSSConstants.Action[] actions = new WSSConstants.Action[]{WSSConstants.SIGNATURE,
WSSConstants.ENCRYPT, WSSConstants.USERNAMETOKEN, WSSConstants.TIMESTAMP};
+            securityProperties.setOutAction(actions);
+            securityProperties.loadSignatureKeyStore(this.getClass().getClassLoader().getResource("transmitter.jks"),
"default".toCharArray());
+            securityProperties.setSignatureUser("transmitter");
+            securityProperties.setTokenUser("transmitter");
+            securityProperties.setCallbackHandler(new CallbackHandlerImpl());
+            securityProperties.setSignatureKeyIdentifier(WSSecurityTokenConstants.KeyIdentifier_SecurityTokenDirectReference);
+            securityProperties.addSignaturePart(
+                    new SecurePart(new QName(WSSConstants.NS_WSSE10, "UsernameToken"), SecurePart.Modifier.Element)
+            );
+            securityProperties.addSignaturePart(
+                    new SecurePart(new QName(WSSConstants.NS_WSU10, "Timestamp"), SecurePart.Modifier.Element)
+            );
+            securityProperties.addSignaturePart(
+                    new SecurePart(new QName(WSSConstants.NS_SOAP11, "Body"), SecurePart.Modifier.Element)
+            );
+
+            securityProperties.setEncryptionUser("receiver");
+            securityProperties.loadEncryptionKeystore(this.getClass().getClassLoader().getResource("transmitter.jks"),
"default".toCharArray());
+            securityProperties.setEncryptionKeyIdentifier(WSSecurityTokenConstants.KeyIdentifier_SecurityTokenDirectReference);
+            securityProperties.addEncryptionPart(
+                    new SecurePart(new QName(WSSConstants.NS_DSIG, "Signature"), SecurePart.Modifier.Element)
+            );
+            securityProperties.addEncryptionPart(
+                    new SecurePart(new QName(WSSConstants.NS_WSSE10, "UsernameToken"), SecurePart.Modifier.Element)
+            );
+            securityProperties.addEncryptionPart(
+                    new SecurePart(new QName(WSSConstants.NS_WSU10, "Timestamp"), SecurePart.Modifier.Element)
+            );
+            securityProperties.addEncryptionPart(
+                    new SecurePart(new QName(WSSConstants.NS_SOAP11, "Body"), SecurePart.Modifier.Content)
+            );
+
+            OutboundWSSec wsSecOut = WSSec.getOutboundWSSec(securityProperties);
+            XMLStreamWriter xmlStreamWriter = wsSecOut.processOutMessage(baos, "UTF-8", new
ArrayList<SecurityEvent>());
+            XMLStreamReader xmlStreamReader = xmlInputFactory.createXMLStreamReader(this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml"));
+            XmlReaderToWriter.writeAll(xmlStreamReader, xmlStreamWriter);
+            xmlStreamWriter.close();
+
+            Document document = documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray()));
+
+            NodeList securityHeaderElement = document.getElementsByTagNameNS(WSConstants.WSSE_NS,
"Security");
+            Assert.assertEquals(1, securityHeaderElement.getLength());
+            NodeList childs = securityHeaderElement.item(0).getChildNodes();
+
+            Assert.assertEquals(childs.getLength(), 6);
+            Assert.assertEquals(childs.item(0).getLocalName(), "BinarySecurityToken");
+            Assert.assertEquals(childs.item(1).getLocalName(), "EncryptedKey");
+            Assert.assertEquals(childs.item(2).getLocalName(), "EncryptedData");
+            Assert.assertEquals(childs.item(3).getLocalName(), "EncryptedData");
+            Assert.assertEquals(childs.item(4).getLocalName(), "BinarySecurityToken");
+            Assert.assertEquals(childs.item(5).getLocalName(), "EncryptedData");
+
+            NodeList sigReferences = document.getElementsByTagNameNS(WSConstants.SIG_NS,
"Reference");
+            Assert.assertEquals(0, sigReferences.getLength()); //0 because the signature
is encrypted
+        }
+
+        //done UsernameToken; now verification:
+        {
+            String action = WSHandlerConstants.SIGNATURE  + " " + WSHandlerConstants.USERNAME_TOKEN
+ " " + WSHandlerConstants.TIMESTAMP + " " + WSHandlerConstants.ENCRYPT;
+            doInboundSecurityWithWSS4J(documentBuilderFactory.newDocumentBuilder().parse(new
ByteArrayInputStream(baos.toByteArray())), action);
+        }
+    }
 }



Mime
View raw message