You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@santuario.apache.org by co...@apache.org on 2020/05/07 06:36:04 UTC

svn commit: r1877463 - in /santuario/xml-security-java/trunk/src: main/java/org/apache/xml/security/encryption/ main/java/org/apache/xml/security/stax/ext/ main/java/org/apache/xml/security/stax/impl/processor/input/ test/java/org/apache/xml/security/t...

Author: coheigea
Date: Thu May  7 06:36:04 2020
New Revision: 1877463

URL: http://svn.apache.org/viewvc?rev=1877463&view=rev
Log:
Some refactor of the encryption + stax modules based on Jacoco output

Modified:
    santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/encryption/XMLCipher.java
    santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/encryption/XMLCipherInput.java
    santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/ext/InboundXMLSec.java
    santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/ext/XMLSec.java
    santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/ext/XMLSecurityUtils.java
    santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/impl/processor/input/AbstractDecryptInputProcessor.java
    santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/impl/processor/input/AbstractSignatureInputHandler.java
    santuario/xml-security-java/trunk/src/test/java/org/apache/xml/security/test/dom/encryption/XMLCipherTest.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/encryption/XMLCipher.java
URL: http://svn.apache.org/viewvc/santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/encryption/XMLCipher.java?rev=1877463&r1=1877462&r2=1877463&view=diff
==============================================================================
--- santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/encryption/XMLCipher.java (original)
+++ santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/encryption/XMLCipher.java Thu May  7 06:36:04 2020
@@ -34,12 +34,15 @@ import java.security.SecureRandom;
 import java.security.spec.AlgorithmParameterSpec;
 import java.security.spec.MGF1ParameterSpec;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
+import java.util.Set;
 
 import javax.crypto.BadPaddingException;
 import javax.crypto.Cipher;
@@ -241,6 +244,8 @@ public class XMLCipher {
         CAMELLIA_128_KeyWrap + "\n" + CAMELLIA_192_KeyWrap + "\n" + CAMELLIA_256_KeyWrap + "\n" +
         SEED_128_KeyWrap + "\n";
 
+    private static final Set<String> SUPPORTED_ALGORITHMS;
+
     private static final boolean HAVE_FUNCTIONAL_IDENTITY_TRANSFORMER = haveFunctionalIdentityTransformer();
 
     /** Cipher created during initialisation that is used for encryption */
@@ -286,6 +291,33 @@ public class XMLCipher {
     /** List of internal KeyResolvers for DECRYPT and UNWRAP modes. */
     private List<KeyResolverSpi> internalKeyResolvers;
 
+    static {
+        Set<String> encryptionAlgorithms = new HashSet<>();
+        encryptionAlgorithms.add(TRIPLEDES);
+        encryptionAlgorithms.add(AES_128);
+        encryptionAlgorithms.add(AES_256);
+        encryptionAlgorithms.add(AES_192);
+        encryptionAlgorithms.add(AES_128_GCM);
+        encryptionAlgorithms.add(AES_192_GCM);
+        encryptionAlgorithms.add(AES_256_GCM);
+        encryptionAlgorithms.add(SEED_128);
+        encryptionAlgorithms.add(CAMELLIA_128);
+        encryptionAlgorithms.add(CAMELLIA_192);
+        encryptionAlgorithms.add(CAMELLIA_256);
+        encryptionAlgorithms.add(RSA_v1dot5);
+        encryptionAlgorithms.add(RSA_OAEP);
+        encryptionAlgorithms.add(RSA_OAEP_11);
+        encryptionAlgorithms.add(TRIPLEDES_KeyWrap);
+        encryptionAlgorithms.add(AES_128_KeyWrap);
+        encryptionAlgorithms.add(AES_256_KeyWrap);
+        encryptionAlgorithms.add(AES_192_KeyWrap);
+        encryptionAlgorithms.add(CAMELLIA_128_KeyWrap);
+        encryptionAlgorithms.add(CAMELLIA_192_KeyWrap);
+        encryptionAlgorithms.add(CAMELLIA_256_KeyWrap);
+        encryptionAlgorithms.add(SEED_128_KeyWrap);
+        SUPPORTED_ALGORITHMS = Collections.unmodifiableSet(encryptionAlgorithms);
+    }
+
     /**
      * Creates a new <code>XMLCipher</code>.
      *
@@ -344,29 +376,7 @@ public class XMLCipher {
      * @since 1.0.
      */
     private static boolean isValidEncryptionAlgorithm(String algorithm) {
-        return
-            algorithm.equals(TRIPLEDES) ||
-            algorithm.equals(AES_128) ||
-            algorithm.equals(AES_256) ||
-            algorithm.equals(AES_192) ||
-            algorithm.equals(AES_128_GCM) ||
-            algorithm.equals(AES_192_GCM) ||
-            algorithm.equals(AES_256_GCM) ||
-            algorithm.equals(SEED_128) ||
-            algorithm.equals(CAMELLIA_128) ||
-            algorithm.equals(CAMELLIA_192) ||
-            algorithm.equals(CAMELLIA_256) ||
-            algorithm.equals(RSA_v1dot5) ||
-            algorithm.equals(RSA_OAEP) ||
-            algorithm.equals(RSA_OAEP_11) ||
-            algorithm.equals(TRIPLEDES_KeyWrap) ||
-            algorithm.equals(AES_128_KeyWrap) ||
-            algorithm.equals(AES_256_KeyWrap) ||
-            algorithm.equals(AES_192_KeyWrap) ||
-            algorithm.equals(CAMELLIA_128_KeyWrap) ||
-            algorithm.equals(CAMELLIA_192_KeyWrap) ||
-            algorithm.equals(CAMELLIA_256_KeyWrap) ||
-            algorithm.equals(SEED_128_KeyWrap);
+        return SUPPORTED_ALGORITHMS.contains(algorithm);
     }
 
     /**
@@ -903,32 +913,10 @@ public class XMLCipher {
      */
     public Document doFinal(Document context, Document source) throws /* XMLEncryption */Exception {
         LOG.debug("Processing source document...");
-        if (null == context) {
-            throw new XMLEncryptionException("empty", "Context document unexpectedly null...");
-        }
         if (null == source) {
             throw new XMLEncryptionException("empty", "Source document unexpectedly null...");
         }
-
-        contextDocument = context;
-
-        Document result = null;
-
-        switch (cipherMode) {
-        case DECRYPT_MODE:
-            result = decryptElement(source.getDocumentElement());
-            break;
-        case ENCRYPT_MODE:
-            result = encryptElement(source.getDocumentElement());
-            break;
-        case UNWRAP_MODE:
-        case WRAP_MODE:
-            break;
-        default:
-            throw new XMLEncryptionException(new IllegalStateException());
-        }
-
-        return result;
+        return doFinal(context, source.getDocumentElement());
     }
 
     /**

Modified: santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/encryption/XMLCipherInput.java
URL: http://svn.apache.org/viewvc/santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/encryption/XMLCipherInput.java?rev=1877463&r1=1877462&r2=1877463&view=diff
==============================================================================
--- santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/encryption/XMLCipherInput.java (original)
+++ santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/encryption/XMLCipherInput.java Thu May  7 06:36:04 2020
@@ -50,9 +50,6 @@ public class XMLCipherInput {
     /** The data we are working with */
     private CipherData cipherData;
 
-    /** MODES */
-    private int mode;
-
     private boolean secureValidation;
 
     /**
@@ -63,7 +60,6 @@ public class XMLCipherInput {
      */
     public XMLCipherInput(CipherData data) throws XMLEncryptionException {
         cipherData = data;
-        mode = XMLCipher.DECRYPT_MODE;
         if (cipherData == null) {
             throw new XMLEncryptionException("CipherData is null");
         }
@@ -77,11 +73,7 @@ public class XMLCipherInput {
      * @throws XMLEncryptionException {@link XMLEncryptionException}
      */
     public XMLCipherInput(EncryptedType input) throws XMLEncryptionException {
-        cipherData = input == null ? null : input.getCipherData();
-        mode = XMLCipher.DECRYPT_MODE;
-        if (cipherData == null) {
-            throw new XMLEncryptionException("CipherData is null");
-        }
+        this(input == null ? null : input.getCipherData());
     }
 
     /**
@@ -98,10 +90,7 @@ public class XMLCipherInput {
      * @return The decripted bytes.
      */
     public byte[] getBytes() throws XMLEncryptionException {  //NOPMD
-        if (mode == XMLCipher.DECRYPT_MODE) {
-            return getDecryptBytes();
-        }
-        return null;
+        return getDecryptBytes();
     }
 
     /**
@@ -153,9 +142,7 @@ public class XMLCipherInput {
 
             try {
                 return input.getBytes();
-            } catch (IOException ex) {
-                throw new XMLEncryptionException(ex);
-            } catch (CanonicalizationException ex) {
+            } catch (IOException | CanonicalizationException ex) {
                 throw new XMLEncryptionException(ex);
             }
 

Modified: santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/ext/InboundXMLSec.java
URL: http://svn.apache.org/viewvc/santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/ext/InboundXMLSec.java?rev=1877463&r1=1877462&r2=1877463&view=diff
==============================================================================
--- santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/ext/InboundXMLSec.java (original)
+++ santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/ext/InboundXMLSec.java Thu May  7 06:36:04 2020
@@ -144,9 +144,9 @@ public class InboundXMLSec {
         inputProcessorChain.addProcessor(new XMLSecurityInputProcessor(securityProperties));
 
         if (LOG.isTraceEnabled()) {
-            LogInputProcessor LOGInputProcessor = new LogInputProcessor(securityProperties);
-            LOGInputProcessor.addAfterProcessor(XMLSecurityInputProcessor.class.getName());
-            inputProcessorChain.addProcessor(LOGInputProcessor);
+            LogInputProcessor logInputProcessor = new LogInputProcessor(securityProperties);
+            logInputProcessor.addAfterProcessor(XMLSecurityInputProcessor.class.getName());
+            inputProcessorChain.addProcessor(logInputProcessor);
         }
 
         return new XMLSecurityStreamReader(inputProcessorChain, securityProperties);

Modified: santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/ext/XMLSec.java
URL: http://svn.apache.org/viewvc/santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/ext/XMLSec.java?rev=1877463&r1=1877462&r2=1877463&view=diff
==============================================================================
--- santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/ext/XMLSec.java (original)
+++ santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/ext/XMLSec.java Thu May  7 06:36:04 2020
@@ -64,14 +64,10 @@ public class XMLSec {
 
                 Schema schema = XMLSecurityUtils.loadXMLSecuritySchemas();
                 XMLSecurityConstants.setJaxbSchemas(schema);
-            } catch (JAXBException e) {
-                throw new RuntimeException(e);
-            } catch (SAXException e) {
+            } catch (JAXBException | SAXException e) {
                 throw new RuntimeException(e);
             }
-        } catch (XMLSecurityException e) {
-            throw new RuntimeException(e.getMessage(), e);
-        } catch (URISyntaxException e) {
+        } catch (XMLSecurityException | URISyntaxException e) {
             throw new RuntimeException(e.getMessage(), e);
         }
     }

Modified: santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/ext/XMLSecurityUtils.java
URL: http://svn.apache.org/viewvc/santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/ext/XMLSecurityUtils.java?rev=1877463&r1=1877462&r2=1877463&view=diff
==============================================================================
--- santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/ext/XMLSecurityUtils.java (original)
+++ santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/ext/XMLSecurityUtils.java Thu May  7 06:36:04 2020
@@ -146,29 +146,13 @@ public class XMLSecurityUtils {
             } else {
                 childTransformer.setTransformer(transformer);
             }
-        } catch (InstantiationException e) {
-            throw new XMLSecurityException(e);
-        } catch (IllegalAccessException e) {
+        } catch (InstantiationException | IllegalAccessException e) {
             throw new XMLSecurityException(e);
         }
         return childTransformer;
     }
 
     @SuppressWarnings("unchecked")
-    public static <T> T getType(List<Object> objects, Class<T> clazz) {
-        for (int i = 0; i < objects.size(); i++) {
-            Object o = objects.get(i);
-            if (o instanceof JAXBElement) {
-                o = ((JAXBElement<?>) o).getValue();
-            }
-            if (clazz.isAssignableFrom(o.getClass())) {
-                return (T) o;
-            }
-        }
-        return null;
-    }
-
-    @SuppressWarnings("unchecked")
     public static <T> T getQNameType(List<Object> objects, QName qName) {
         for (int i = 0; i < objects.size(); i++) {
             Object o = objects.get(i);

Modified: santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/impl/processor/input/AbstractDecryptInputProcessor.java
URL: http://svn.apache.org/viewvc/santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/impl/processor/input/AbstractDecryptInputProcessor.java?rev=1877463&r1=1877462&r2=1877463&view=diff
==============================================================================
--- santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/impl/processor/input/AbstractDecryptInputProcessor.java (original)
+++ santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/impl/processor/input/AbstractDecryptInputProcessor.java Thu May  7 06:36:04 2020
@@ -24,7 +24,6 @@ import java.io.OutputStream;
 import java.io.OutputStreamWriter;
 import java.io.PipedInputStream;
 import java.io.PipedOutputStream;
-import java.io.UnsupportedEncodingException;
 import java.nio.charset.Charset;
 import java.nio.charset.StandardCharsets;
 import java.security.Key;
@@ -335,8 +334,6 @@ public abstract class AbstractDecryptInp
                 try {
                     prologInputStream = writeWrapperStartElement(xmlSecStartElement);
                     epilogInputStream = writeWrapperEndElement();
-                } catch (UnsupportedEncodingException e) {
-                    throw new XMLSecurityException(e);
                 } catch (IOException e) {
                     throw new XMLSecurityException(e);
                 }
@@ -452,11 +449,7 @@ public abstract class AbstractDecryptInp
                 symCipher = Cipher.getInstance(jceName);
             }
             //we have to defer the initialization of the cipher until we can extract the IV...
-        } catch (NoSuchAlgorithmException e) {
-            throw new XMLSecurityException(e);
-        } catch (NoSuchPaddingException e) {
-            throw new XMLSecurityException(e);
-        } catch (NoSuchProviderException e) {
+        } catch (NoSuchAlgorithmException | NoSuchPaddingException | NoSuchProviderException e) {
             throw new XMLSecurityException(e);
         }
         return symCipher;
@@ -843,9 +836,7 @@ public abstract class AbstractDecryptInp
                             byte[] bytes = cipher.doFinal();
                             outputStream.write(bytes);
                             outputStream.close();
-                        } catch (IllegalBlockSizeException e) {
-                            throw new IOException(e);
-                        } catch (BadPaddingException e) {
+                        } catch (IllegalBlockSizeException | BadPaddingException e) {
                             throw new IOException(e);
                         }
                     }

Modified: santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/impl/processor/input/AbstractSignatureInputHandler.java
URL: http://svn.apache.org/viewvc/santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/impl/processor/input/AbstractSignatureInputHandler.java?rev=1877463&r1=1877462&r2=1877463&view=diff
==============================================================================
--- santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/impl/processor/input/AbstractSignatureInputHandler.java (original)
+++ santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/impl/processor/input/AbstractSignatureInputHandler.java Thu May  7 06:36:04 2020
@@ -64,10 +64,13 @@ import java.security.NoSuchProviderExcep
 import java.security.spec.MGF1ParameterSpec;
 import java.security.spec.PSSParameterSpec;
 import java.util.ArrayDeque;
+import java.util.Collections;
 import java.util.Deque;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Iterator;
 import java.util.Map;
+import java.util.Set;
 
 import static org.apache.xml.security.algorithms.implementations.SignatureBaseRSA.SignatureRSASSAPSS.DigestAlgorithm.SHA256;
 import static org.apache.xml.security.algorithms.implementations.SignatureBaseRSA.SignatureRSASSAPSS.DigestAlgorithm.fromXmlDigestAlgorithm;
@@ -77,6 +80,18 @@ import static org.apache.xml.security.al
 public abstract class AbstractSignatureInputHandler extends AbstractInputSecurityHeaderHandler {
 
     private static final transient Logger LOG = LoggerFactory.getLogger(AbstractSignatureInputHandler.class);
+    private static final Set<String> C14N_ALGORITHMS;
+
+    static {
+        Set<String> algorithms = new HashSet<>();
+        algorithms.add(XMLSecurityConstants.NS_C14N_OMIT_COMMENTS);
+        algorithms.add(XMLSecurityConstants.NS_C14N_WITH_COMMENTS);
+        algorithms.add(XMLSecurityConstants.NS_C14N_EXCL_OMIT_COMMENTS);
+        algorithms.add(XMLSecurityConstants.NS_C14N_EXCL_WITH_COMMENTS);
+        algorithms.add(XMLSecurityConstants.NS_C14N11_OMIT_COMMENTS);
+        algorithms.add(XMLSecurityConstants.NS_C14N11_WITH_COMMENTS);
+        C14N_ALGORITHMS = Collections.unmodifiableSet(algorithms);
+    }
 
     @Override
     public void handle(final InputProcessorChain inputProcessorChain, final XMLSecurityProperties securityProperties,
@@ -114,12 +129,7 @@ public abstract class AbstractSignatureI
         Iterator<XMLSecEvent> iterator;
 
         String c14NMethod = signatureType.getSignedInfo().getCanonicalizationMethod().getAlgorithm();
-        if (XMLSecurityConstants.NS_C14N_OMIT_COMMENTS.equals(c14NMethod) ||
-                XMLSecurityConstants.NS_C14N_WITH_COMMENTS.equals(c14NMethod) ||
-                XMLSecurityConstants.NS_C14N_EXCL_OMIT_COMMENTS.equals(c14NMethod) ||
-                XMLSecurityConstants.NS_C14N_EXCL_WITH_COMMENTS.equals(c14NMethod) ||
-                XMLSecurityConstants.NS_C14N11_OMIT_COMMENTS.equals(c14NMethod) ||
-                XMLSecurityConstants.NS_C14N11_WITH_COMMENTS.equals(c14NMethod)) {
+        if (c14NMethod != null && C14N_ALGORITHMS.contains(c14NMethod)) {
 
             iterator = eventDeque.descendingIterator();
             //forward to <Signature> Element
@@ -348,9 +358,7 @@ public abstract class AbstractSignatureI
                         transformerProperties,
                         canonicalizationMethodType.getAlgorithm(),
                         XMLSecurityConstants.DIRECTION.IN);
-            } catch (NoSuchAlgorithmException e) {
-                throw new XMLSecurityException(e);
-            } catch (NoSuchProviderException e) {
+            } catch (NoSuchAlgorithmException | NoSuchProviderException e) {
                 throw new XMLSecurityException(e);
             }
 
@@ -397,9 +405,7 @@ public abstract class AbstractSignatureI
             try {
                 transformer.doFinal();
                 bufferedSignerOutputStream.close();
-            } catch (IOException e) {
-                throw new XMLSecurityException(e);
-            } catch (XMLStreamException e) {
+            } catch (IOException | XMLStreamException e) {
                 throw new XMLSecurityException(e);
             }
             if (!signerOutputStream.verify(signatureType.getSignatureValue().getValue())) {

Modified: santuario/xml-security-java/trunk/src/test/java/org/apache/xml/security/test/dom/encryption/XMLCipherTest.java
URL: http://svn.apache.org/viewvc/santuario/xml-security-java/trunk/src/test/java/org/apache/xml/security/test/dom/encryption/XMLCipherTest.java?rev=1877463&r1=1877462&r2=1877463&view=diff
==============================================================================
--- santuario/xml-security-java/trunk/src/test/java/org/apache/xml/security/test/dom/encryption/XMLCipherTest.java (original)
+++ santuario/xml-security-java/trunk/src/test/java/org/apache/xml/security/test/dom/encryption/XMLCipherTest.java Thu May  7 06:36:04 2020
@@ -156,6 +156,7 @@ public class XMLCipherTest {
 
             cipher = XMLCipher.getInstance(XMLCipher.AES_192_KeyWrap);
             cipher.init(XMLCipher.WRAP_MODE, kek);
+            cipher.setSecureValidation(true);
             EncryptedKey encryptedKey = cipher.encryptKey(d, key);
 
             // encrypt
@@ -179,6 +180,7 @@ public class XMLCipherTest {
             cipher = XMLCipher.getInstance(XMLCipher.AES_128);
             cipher.init(XMLCipher.DECRYPT_MODE, null);
             cipher.setKEK(kek);
+            cipher.setSecureValidation(true);
             dd = cipher.doFinal(ed, ee);
 
             target = toString(dd);
@@ -224,6 +226,7 @@ public class XMLCipherTest {
 
             cipher = XMLCipher.getInstance(XMLCipher.RSA_v1dot5);
             cipher.init(XMLCipher.WRAP_MODE, pub);
+            cipher.setSecureValidation(true);
             EncryptedKey encryptedKey = cipher.encryptKey(d, key);
 
             // encrypt
@@ -250,6 +253,7 @@ public class XMLCipherTest {
             cipher = XMLCipher.getInstance(XMLCipher.AES_256);
             cipher.init(XMLCipher.DECRYPT_MODE, null);
             cipher.setKEK(priv);
+            cipher.setSecureValidation(true);
             dd = cipher.doFinal(ed, ee);
 
             target = toString(dd);

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=1877463&r1=1877462&r2=1877463&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 Thu May  7 06:36:04 2020
@@ -20,6 +20,7 @@ package org.apache.xml.security.test.sta
 
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
+import java.io.FileInputStream;
 import java.io.InputStream;
 import java.nio.charset.StandardCharsets;
 import java.security.Key;
@@ -735,6 +736,69 @@ public class SignatureCreationTest exten
         }
 
         // Verify using DOM
+        verifyUsingDOM(document, cert, properties.getSignatureSecureParts());
+    }
+
+    @Test
+    public void testDSASignatureCreation() throws Exception {
+        // Set up the Configuration
+        XMLSecurityProperties properties = new XMLSecurityProperties();
+        List<XMLSecurityConstants.Action> actions = new ArrayList<>();
+        actions.add(XMLSecurityConstants.SIGNATURE);
+        properties.setActions(actions);
+
+        // Set the key up
+        KeyStore keyStore = KeyStore.getInstance("jks");
+        FileInputStream fis = null;
+        if (BASEDIR != null && !"".equals(BASEDIR)) {
+            fis =
+                    new FileInputStream(BASEDIR + System.getProperty("file.separator")
+                            + "src/test/resources/org/apache/xml/security/samples/input/keystore.jks"
+                    );
+        } else {
+            fis =
+                    new FileInputStream("src/test/resources/org/apache/xml/security/samples/input/keystore.jks");
+        }
+        keyStore.load(fis, "xmlsecurity".toCharArray());
+        Key key = keyStore.getKey("test", "xmlsecurity".toCharArray());
+        properties.setSignatureKey(key);
+        X509Certificate cert = (X509Certificate)keyStore.getCertificate("test");
+        properties.setSignatureCerts(new X509Certificate[]{cert});
+
+        SecurePart securePart =
+                new SecurePart(new QName("urn:example:po", "PaymentInfo"), SecurePart.Modifier.Content);
+        properties.addSignaturePart(securePart);
+
+        OutboundXMLSec outboundXMLSec = XMLSec.getOutboundXMLSec(properties);
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        XMLStreamWriter xmlStreamWriter = outboundXMLSec.processOutMessage(baos, StandardCharsets.UTF_8.name());
+
+        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(), StandardCharsets.UTF_8.name()));
+        Document document = null;
+        try (InputStream is = new ByteArrayInputStream(baos.toByteArray())) {
+            document = XMLUtils.read(is, false);
+        }
+
+        //first child element must be the dsig:Signature @see SANTUARIO-324:
+        Node childNode = document.getDocumentElement().getFirstChild();
+        while (childNode != null) {
+            if (childNode.getNodeType() == Node.ELEMENT_NODE) {
+                Element element = (Element)childNode;
+                assertEquals(element.getLocalName(), "Signature");
+                break;
+            }
+            childNode = childNode.getNextSibling();
+        }
+
+        // Verify using DOM
         verifyUsingDOM(document, cert, properties.getSignatureSecureParts());
     }