You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@santuario.apache.org by gi...@apache.org on 2014/11/30 16:36:50 UTC

svn commit: r1642553 - in /santuario/xml-security-java/trunk/src: main/java/org/apache/xml/security/stax/ext/ main/java/org/apache/xml/security/stax/impl/processor/output/ test/java/org/apache/xml/security/test/stax/signature/

Author: giger
Date: Sun Nov 30 15:36:50 2014
New Revision: 1642553

URL: http://svn.apache.org/r1642553
Log:
SANTUARIO-405: Customize location of signature with StAX API. Thanks to Loeiz Tanguy for the original patch.


Modified:
    santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/ext/XMLSecurityProperties.java
    santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/impl/processor/output/XMLSignatureEndingOutputProcessor.java
    santuario/xml-security-java/trunk/src/test/java/org/apache/xml/security/test/stax/signature/SignatureCreationTest.java

Modified: santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/ext/XMLSecurityProperties.java
URL: http://svn.apache.org/viewvc/santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/ext/XMLSecurityProperties.java?rev=1642553&r1=1642552&r2=1642553&view=diff
==============================================================================
--- santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/ext/XMLSecurityProperties.java (original)
+++ santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/ext/XMLSecurityProperties.java Sun Nov 30 15:36:50 2014
@@ -67,6 +67,8 @@ public class XMLSecurityProperties {
 
     private Key signatureVerificationKey;
 
+    private int signaturePosition = 0;
+
     public XMLSecurityProperties() {
     }
 
@@ -96,6 +98,7 @@ public class XMLSecurityProperties {
         this.signatureKeyIdentifier = xmlSecurityProperties.signatureKeyIdentifier;
         this.useSingleCert = xmlSecurityProperties.useSingleCert;
         this.signatureVerificationKey = xmlSecurityProperties.signatureVerificationKey;
+        this.signaturePosition = xmlSecurityProperties.signaturePosition;        
     }
 
     public SecurityTokenConstants.KeyIdentifier getSignatureKeyIdentifier() {
@@ -105,6 +108,25 @@ public class XMLSecurityProperties {
     public void setSignatureKeyIdentifier(SecurityTokenConstants.KeyIdentifier signatureKeyIdentifier) {
         this.signatureKeyIdentifier = signatureKeyIdentifier;
     }
+
+    /**
+     * returns the position of the signature. By default, the signature
+     * is located at the first child of the root element
+     *
+     * @return The signature position
+     */
+    public int getSignaturePosition() {
+        return signaturePosition;
+    }
+
+    /**
+     * Specifies the position of the signature
+     *
+     * @param signaturePosition Position of the signature (by default: 0)
+     */
+    public void setSignaturePosition(int signaturePosition) {
+        this.signaturePosition = signaturePosition;
+    }
     
     /**
      * returns the KeyIdentifierType which will be used in the secured document

Modified: santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/impl/processor/output/XMLSignatureEndingOutputProcessor.java
URL: http://svn.apache.org/viewvc/santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/impl/processor/output/XMLSignatureEndingOutputProcessor.java?rev=1642553&r1=1642552&r2=1642553&view=diff
==============================================================================
--- santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/impl/processor/output/XMLSignatureEndingOutputProcessor.java (original)
+++ santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/impl/processor/output/XMLSignatureEndingOutputProcessor.java Sun Nov 30 15:36:50 2014
@@ -62,7 +62,7 @@ public class XMLSignatureEndingOutputPro
         this.signedInfoProcessor.init(outputProcessorChain);
         return this.signedInfoProcessor;
     }
-    
+
     @Override
     public void processHeaderEvent(OutputProcessorChain outputProcessorChain) throws XMLStreamException, XMLSecurityException {
         super.processHeaderEvent(outputProcessorChain);
@@ -76,8 +76,16 @@ public class XMLSignatureEndingOutputPro
             OutputProcessorChain outputProcessorChain, Deque<XMLSecEvent> xmlSecEventDeque)
             throws XMLStreamException, XMLSecurityException {
 
-        //@see SANTUARIO-324
-        //output root element...
+        // @see SANTUARIO-405
+        // Enhances SANTUARIO-324
+        // Output the signature at a specific position. 
+        // By default, this is just after the root element
+        int signaturePosition = getSecurityProperties().getSignaturePosition();
+        if (signaturePosition < 0) {
+            signaturePosition = 0;
+        }
+
+        // forward to the root element and output it
         XMLSecEvent xmlSecEvent = xmlSecEventDeque.pop();
         while (!xmlSecEvent.isStartElement()) {
             outputProcessorChain.reset();
@@ -86,6 +94,30 @@ public class XMLSignatureEndingOutputPro
         }
         outputProcessorChain.reset();
         outputProcessorChain.processEvent(xmlSecEvent);
+
+        // search the specified position
+        int depth = 0;
+        int position = 0;
+        while (position != signaturePosition) {
+            xmlSecEvent = xmlSecEventDeque.pop();
+
+            if (xmlSecEvent.isStartElement()) {
+                depth++;
+            } else if (xmlSecEvent.isEndElement()) {
+                depth--;
+                if (depth == 0) {
+                    position++;
+                } else if (depth < 0) {
+                    // root-end-element reached
+                    xmlSecEventDeque.push(xmlSecEvent);
+                    break;
+                }
+            }
+
+            outputProcessorChain.reset();
+            outputProcessorChain.processEvent(xmlSecEvent);
+        }
+
         //...then call super to append the signature and flush the rest
         super.flushBufferAndCallbackAfterHeader(outputProcessorChain, xmlSecEventDeque);
     }

Modified: santuario/xml-security-java/trunk/src/test/java/org/apache/xml/security/test/stax/signature/SignatureCreationTest.java
URL: http://svn.apache.org/viewvc/santuario/xml-security-java/trunk/src/test/java/org/apache/xml/security/test/stax/signature/SignatureCreationTest.java?rev=1642553&r1=1642552&r2=1642553&view=diff
==============================================================================
--- santuario/xml-security-java/trunk/src/test/java/org/apache/xml/security/test/stax/signature/SignatureCreationTest.java (original)
+++ santuario/xml-security-java/trunk/src/test/java/org/apache/xml/security/test/stax/signature/SignatureCreationTest.java Sun Nov 30 15:36:50 2014
@@ -271,7 +271,86 @@ public class SignatureCreationTest exten
         // Verify using DOM
         verifyUsingDOM(document, cert, properties.getSignatureSecureParts());
     }
-    
+
+    @Test
+    public void testSignAtSpecificPosition() throws Exception {
+        signAtSpecificPosition(-1);
+        signAtSpecificPosition(0);
+        signAtSpecificPosition(1);
+        signAtSpecificPosition(2);
+        signAtSpecificPosition(999);
+    }
+
+    private void signAtSpecificPosition(int position) throws Exception {
+        // Set up the Configuration
+        XMLSecurityProperties properties = new XMLSecurityProperties();
+        List<XMLSecurityConstants.Action> actions = new ArrayList<XMLSecurityConstants.Action>();
+        actions.add(XMLSecurityConstants.SIGNATURE);
+        properties.setActions(actions);
+
+        // Specify the signature position
+        properties.setSignaturePosition(position);
+
+        // Set the key up
+        KeyStore keyStore = KeyStore.getInstance("jks");
+        keyStore.load(
+                this.getClass().getClassLoader().getResource("transmitter.jks").openStream(),
+                "default".toCharArray()
+        );
+        Key key = keyStore.getKey("transmitter", "default".toCharArray());
+        properties.setSignatureKey(key);
+        X509Certificate cert = (X509Certificate) keyStore.getCertificate("transmitter");
+        properties.setSignatureCerts(new X509Certificate[]{cert});
+
+        SecurePart securePart
+                = new SecurePart(null,
+                SecurePart.Modifier.Content,
+                new String[]{
+                        "http://www.w3.org/2000/09/xmldsig#enveloped-signature",
+                        "http://www.w3.org/TR/2001/REC-xml-c14n-20010315"
+                },
+                "http://www.w3.org/2000/09/xmldsig#sha1");
+        securePart.setSecureEntireRequest(true);
+        properties.addSignaturePart(securePart);
+
+        OutboundXMLSec outboundXMLSec = XMLSec.getOutboundXMLSec(properties);
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        XMLStreamWriter xmlStreamWriter = outboundXMLSec.processOutMessage(baos, "UTF-8");
+
+        InputStream sourceDocument
+                = this.getClass().getClassLoader().getResourceAsStream(
+                "ie/baltimore/merlin-examples/merlin-xmlenc-five/plaintext.xml");
+        XMLStreamReader xmlStreamReader = xmlInputFactory.createXMLStreamReader(sourceDocument);
+
+        XmlReaderToWriter.writeAll(xmlStreamReader, xmlStreamWriter);
+        xmlStreamWriter.close();
+
+        System.out.println("Got:\n" + new String(baos.toByteArray(), "UTF-8"));
+
+        Document document
+                = XMLUtils.createDocumentBuilder(false).parse(new ByteArrayInputStream(baos.toByteArray()));
+
+        //find first child element:
+        Node childNode = XMLUtils.getNextElement(document.getDocumentElement().getFirstChild());
+
+        int expectedPosition = position < 0 ? 0 : position;
+        int curPos = 0;
+        while (curPos != expectedPosition) {
+            Node node = XMLUtils.getNextElement(childNode.getNextSibling());
+            curPos++;
+            if (node != null) {
+                childNode = node;
+            } else {
+                break;
+            }
+        }
+
+        Assert.assertEquals(childNode.getLocalName(), "Signature");
+
+        // Verify using DOM
+        verifyUsingDOM(document, cert, properties.getSignatureSecureParts());
+    }
+
     @Test
     public void testMultipleElements() throws Exception {
         // Set up the Configuration