8038349: Signing XML with DSA throws Exception when key is larger than 1024 bits
authormullan
Fri, 02 May 2014 10:01:46 -0400
changeset 24251 da7dc40edb67
parent 23932 0c547f072113
child 24252 69d134ce50ed
8038349: Signing XML with DSA throws Exception when key is larger than 1024 bits Reviewed-by: xuelei
jdk/src/share/classes/com/sun/org/apache/xml/internal/security/algorithms/JCEMapper.java
jdk/src/share/classes/com/sun/org/apache/xml/internal/security/algorithms/SignatureAlgorithm.java
jdk/src/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/SignatureDSA.java
jdk/src/share/classes/com/sun/org/apache/xml/internal/security/signature/XMLSignature.java
jdk/src/share/classes/com/sun/org/apache/xml/internal/security/utils/JavaUtils.java
jdk/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMSignatureMethod.java
jdk/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMXMLSignatureFactory.java
jdk/test/javax/xml/crypto/dsig/GenerationTests.java
jdk/test/javax/xml/crypto/dsig/KeySelectors.java
--- a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/algorithms/JCEMapper.java	Wed Apr 16 11:56:58 2014 +0100
+++ b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/algorithms/JCEMapper.java	Fri May 02 10:01:46 2014 -0400
@@ -87,6 +87,10 @@
             new Algorithm("", "SHA1withDSA", "Signature")
         );
         algorithmsMap.put(
+            XMLSignature.ALGO_ID_SIGNATURE_DSA_SHA256,
+            new Algorithm("", "SHA256withDSA", "Signature")
+        );
+        algorithmsMap.put(
             XMLSignature.ALGO_ID_SIGNATURE_NOT_RECOMMENDED_RSA_MD5,
             new Algorithm("", "MD5withRSA", "Signature")
         );
--- a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/algorithms/SignatureAlgorithm.java	Wed Apr 16 11:56:58 2014 +0100
+++ b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/algorithms/SignatureAlgorithm.java	Fri May 02 10:01:46 2014 -0400
@@ -380,7 +380,12 @@
      * This method registers the default algorithms.
      */
     public static void registerDefaultAlgorithms() {
-        algorithmHash.put(SignatureDSA.URI, SignatureDSA.class);
+        algorithmHash.put(
+            XMLSignature.ALGO_ID_SIGNATURE_DSA, SignatureDSA.class
+        );
+        algorithmHash.put(
+            XMLSignature.ALGO_ID_SIGNATURE_DSA_SHA256, SignatureDSA.SHA256.class
+        );
         algorithmHash.put(
             XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA1, SignatureBaseRSA.SignatureRSASHA1.class
         );
--- a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/SignatureDSA.java	Wed Apr 16 11:56:58 2014 +0100
+++ b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/SignatureDSA.java	Fri May 02 10:01:46 2014 -0400
@@ -31,13 +31,15 @@
 import java.security.SecureRandom;
 import java.security.Signature;
 import java.security.SignatureException;
+import java.security.interfaces.DSAKey;
 import java.security.spec.AlgorithmParameterSpec;
 
 import com.sun.org.apache.xml.internal.security.algorithms.JCEMapper;
 import com.sun.org.apache.xml.internal.security.algorithms.SignatureAlgorithmSpi;
+import com.sun.org.apache.xml.internal.security.signature.XMLSignature;
 import com.sun.org.apache.xml.internal.security.signature.XMLSignatureException;
 import com.sun.org.apache.xml.internal.security.utils.Base64;
-import com.sun.org.apache.xml.internal.security.utils.Constants;
+import com.sun.org.apache.xml.internal.security.utils.JavaUtils;
 
 public class SignatureDSA extends SignatureAlgorithmSpi {
 
@@ -45,19 +47,19 @@
     private static java.util.logging.Logger log =
         java.util.logging.Logger.getLogger(SignatureDSA.class.getName());
 
-    /** Field URI */
-    public static final String URI = Constants.SignatureSpecNS + "dsa-sha1";
-
     /** Field algorithm */
     private java.security.Signature signatureAlgorithm = null;
 
+    /** size of Q */
+    private int size;
+
     /**
      * Method engineGetURI
      *
      * @inheritDoc
      */
     protected String engineGetURI() {
-        return SignatureDSA.URI;
+        return XMLSignature.ALGO_ID_SIGNATURE_DSA;
     }
 
     /**
@@ -66,7 +68,7 @@
      * @throws XMLSignatureException
      */
     public SignatureDSA() throws XMLSignatureException {
-        String algorithmID = JCEMapper.translateURItoJCEID(SignatureDSA.URI);
+        String algorithmID = JCEMapper.translateURItoJCEID(engineGetURI());
         if (log.isLoggable(java.util.logging.Level.FINE)) {
             log.log(java.util.logging.Level.FINE, "Created SignatureDSA using " + algorithmID);
         }
@@ -110,7 +112,8 @@
                 log.log(java.util.logging.Level.FINE, "Called DSA.verify() on " + Base64.encode(signature));
             }
 
-            byte[] jcebytes = SignatureDSA.convertXMLDSIGtoASN1(signature);
+            byte[] jcebytes = JavaUtils.convertDsaXMLDSIGtoASN1(signature,
+                                                                size/8);
 
             return this.signatureAlgorithm.verify(jcebytes);
         } catch (SignatureException ex) {
@@ -150,6 +153,7 @@
             }
             throw new XMLSignatureException("empty", ex);
         }
+        size = ((DSAKey)publicKey).getParams().getQ().bitLength();
     }
 
     /**
@@ -159,7 +163,7 @@
         try {
             byte jcebytes[] = this.signatureAlgorithm.sign();
 
-            return SignatureDSA.convertASN1toXMLDSIG(jcebytes);
+            return JavaUtils.convertDsaASN1toXMLDSIG(jcebytes, size/8);
         } catch (IOException ex) {
             throw new XMLSignatureException("empty", ex);
         } catch (SignatureException ex) {
@@ -185,6 +189,7 @@
         } catch (InvalidKeyException ex) {
             throw new XMLSignatureException("empty", ex);
         }
+        size = ((DSAKey)privateKey).getParams().getQ().bitLength();
     }
 
     /**
@@ -204,6 +209,7 @@
         } catch (InvalidKeyException ex) {
             throw new XMLSignatureException("empty", ex);
         }
+        size = ((DSAKey)privateKey).getParams().getQ().bitLength();
     }
 
     /**
@@ -258,100 +264,6 @@
     }
 
     /**
-     * Converts an ASN.1 DSA value to a XML Signature DSA Value.
-     *
-     * The JAVA JCE DSA Signature algorithm creates ASN.1 encoded (r,s) value
-     * pairs; the XML Signature requires the core BigInteger values.
-     *
-     * @param asn1Bytes
-     * @return the decode bytes
-     *
-     * @throws IOException
-     * @see <A HREF="http://www.w3.org/TR/xmldsig-core/#dsa-sha1">6.4.1 DSA</A>
-     */
-    private static byte[] convertASN1toXMLDSIG(byte asn1Bytes[]) throws IOException {
-
-        byte rLength = asn1Bytes[3];
-        int i;
-
-        for (i = rLength; (i > 0) && (asn1Bytes[(4 + rLength) - i] == 0); i--);
-
-        byte sLength = asn1Bytes[5 + rLength];
-        int j;
-
-        for (j = sLength;
-            (j > 0) && (asn1Bytes[(6 + rLength + sLength) - j] == 0); j--);
-
-        if ((asn1Bytes[0] != 48) || (asn1Bytes[1] != asn1Bytes.length - 2)
-            || (asn1Bytes[2] != 2) || (i > 20)
-            || (asn1Bytes[4 + rLength] != 2) || (j > 20)) {
-            throw new IOException("Invalid ASN.1 format of DSA signature");
-        }
-        byte xmldsigBytes[] = new byte[40];
-
-        System.arraycopy(asn1Bytes, (4 + rLength) - i, xmldsigBytes, 20 - i, i);
-        System.arraycopy(asn1Bytes, (6 + rLength + sLength) - j, xmldsigBytes,
-                         40 - j, j);
-
-        return xmldsigBytes;
-    }
-
-    /**
-     * Converts a XML Signature DSA Value to an ASN.1 DSA value.
-     *
-     * The JAVA JCE DSA Signature algorithm creates ASN.1 encoded (r,s) value
-     * pairs; the XML Signature requires the core BigInteger values.
-     *
-     * @param xmldsigBytes
-     * @return the encoded ASN.1 bytes
-     *
-     * @throws IOException
-     * @see <A HREF="http://www.w3.org/TR/xmldsig-core/#dsa-sha1">6.4.1 DSA</A>
-     */
-    private static byte[] convertXMLDSIGtoASN1(byte xmldsigBytes[]) throws IOException {
-
-        if (xmldsigBytes.length != 40) {
-            throw new IOException("Invalid XMLDSIG format of DSA signature");
-        }
-
-        int i;
-
-        for (i = 20; (i > 0) && (xmldsigBytes[20 - i] == 0); i--);
-
-        int j = i;
-
-        if (xmldsigBytes[20 - i] < 0) {
-            j += 1;
-        }
-
-        int k;
-
-        for (k = 20; (k > 0) && (xmldsigBytes[40 - k] == 0); k--);
-
-        int l = k;
-
-        if (xmldsigBytes[40 - k] < 0) {
-            l += 1;
-        }
-
-        byte asn1Bytes[] = new byte[6 + j + l];
-
-        asn1Bytes[0] = 48;
-        asn1Bytes[1] = (byte) (4 + j + l);
-        asn1Bytes[2] = 2;
-        asn1Bytes[3] = (byte) j;
-
-        System.arraycopy(xmldsigBytes, 20 - i, asn1Bytes, (4 + j) - i, i);
-
-        asn1Bytes[4 + j] = 2;
-        asn1Bytes[5 + j] = (byte) l;
-
-        System.arraycopy(xmldsigBytes, 40 - k, asn1Bytes, (6 + j + l) - k, k);
-
-        return asn1Bytes;
-    }
-
-    /**
      * Method engineSetHMACOutputLength
      *
      * @param HMACOutputLength
@@ -373,4 +285,15 @@
     ) throws XMLSignatureException {
         throw new XMLSignatureException("algorithms.CannotUseAlgorithmParameterSpecOnDSA");
     }
+
+    public static class SHA256 extends SignatureDSA {
+
+        public SHA256() throws XMLSignatureException {
+            super();
+        }
+
+        public String engineGetURI() {
+            return XMLSignature.ALGO_ID_SIGNATURE_DSA_SHA256;
+        }
+    }
 }
--- a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/signature/XMLSignature.java	Wed Apr 16 11:56:58 2014 +0100
+++ b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/signature/XMLSignature.java	Fri May 02 10:01:46 2014 -0400
@@ -85,6 +85,10 @@
     public static final String ALGO_ID_SIGNATURE_DSA =
         Constants.SignatureSpecNS + "dsa-sha1";
 
+    /** Signature - Optional DSAwithSHA256 */
+    public static final String ALGO_ID_SIGNATURE_DSA_SHA256 =
+        Constants.SignatureSpec11NS + "dsa-sha256";
+
     /** Signature - Recommended RSAwithSHA1 */
     public static final String ALGO_ID_SIGNATURE_RSA =
         Constants.SignatureSpecNS + "rsa-sha1";
--- a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/utils/JavaUtils.java	Wed Apr 16 11:56:58 2014 +0100
+++ b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/utils/JavaUtils.java	Fri May 02 10:01:46 2014 -0400
@@ -145,4 +145,98 @@
 
         return retBytes;
     }
+
+    /**
+     * Converts an ASN.1 DSA value to a XML Signature DSA Value.
+     *
+     * The JCE DSA Signature algorithm creates ASN.1 encoded (r,s) value
+     * pairs (see section 2.2.2 of RFC 3279); the XML Signature requires the
+     * core BigInteger values.
+     *
+     * @param asn1Bytes the ASN.1 encoded bytes
+     * @param size size of r and s in bytes
+     * @return the XML Signature encoded bytes
+     * @throws IOException if the bytes are not encoded correctly
+     * @see <A HREF="http://www.w3.org/TR/xmldsig-core1/#sec-DSA">6.4.1 DSA</A>
+     */
+    public static byte[] convertDsaASN1toXMLDSIG(byte[] asn1Bytes, int size)
+        throws IOException
+    {
+        if (asn1Bytes[0] != 48 || asn1Bytes[1] != asn1Bytes.length - 2
+            || asn1Bytes[2] != 2) {
+            throw new IOException("Invalid ASN.1 format of DSA signature");
+        }
+
+        byte rLength = asn1Bytes[3];
+        int i;
+        for (i = rLength; i > 0 && asn1Bytes[4 + rLength - i] == 0; i--);
+
+        byte sLength = asn1Bytes[5 + rLength];
+        int j;
+        for (j = sLength;
+             j > 0 && asn1Bytes[6 + rLength + sLength - j] == 0; j--);
+
+        if (i > size || asn1Bytes[4 + rLength] != 2 || j > size) {
+            throw new IOException("Invalid ASN.1 format of DSA signature");
+        } else {
+            byte[] xmldsigBytes = new byte[size * 2];
+            System.arraycopy(asn1Bytes, 4 + rLength - i, xmldsigBytes,
+                             size - i, i);
+            System.arraycopy(asn1Bytes, 6 + rLength + sLength - j,
+                             xmldsigBytes, size * 2 - j, j);
+            return xmldsigBytes;
+        }
+    }
+
+    /**
+     * Converts an XML Signature DSA Value to a ASN.1 DSA value.
+     *
+     * The JCE DSA Signature algorithm creates ASN.1 encoded (r,s) value
+     * pairs (see section 2.2.2 of RFC 3279); the XML Signature requires the
+     * core BigInteger values.
+     *
+     * @param xmldsigBytes the XML Signature encoded bytes
+     * @param size size of r and s in bytes
+     * @return the ASN.1 encoded bytes
+     * @throws IOException if the bytes are not encoded correctly
+     * @see <A HREF="http://www.w3.org/TR/xmldsig-core1/#sec-DSA">6.4.1 DSA</A>
+     */
+    public static byte[] convertDsaXMLDSIGtoASN1(byte[] xmldsigBytes, int size)
+        throws IOException
+    {
+        int totalSize = size * 2;
+        if (xmldsigBytes.length != totalSize) {
+            throw new IOException("Invalid XMLDSIG format of DSA signature");
+        }
+
+        int i;
+        for (i = size; i > 0 && xmldsigBytes[size - i] == 0; i--);
+
+        int j = i;
+        if (xmldsigBytes[size - i] < 0) {
+            j++;
+        }
+
+        int k;
+        for (k = size; k > 0 && xmldsigBytes[totalSize - k] == 0; k--);
+
+        int l = k;
+        if (xmldsigBytes[totalSize - k] < 0) {
+            l++;
+        }
+
+        byte[] asn1Bytes = new byte[6 + j + l];
+        asn1Bytes[0] = 48;
+        asn1Bytes[1] = (byte)(4 + j + l);
+        asn1Bytes[2] = 2;
+        asn1Bytes[3] = (byte)j;
+        System.arraycopy(xmldsigBytes, size - i, asn1Bytes, 4 + j - i, i);
+
+        asn1Bytes[4 + j] = 2;
+        asn1Bytes[5 + j] = (byte) l;
+        System.arraycopy(xmldsigBytes, totalSize - k, asn1Bytes,
+                         6 + j + l - k, k);
+
+        return asn1Bytes;
+    }
 }
--- a/jdk/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMSignatureMethod.java	Wed Apr 16 11:56:58 2014 +0100
+++ b/jdk/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMSignatureMethod.java	Fri May 02 10:01:46 2014 -0400
@@ -21,7 +21,7 @@
  * under the License.
  */
 /*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
  */
 /*
  * $Id: DOMSignatureMethod.java 1333415 2012-05-03 12:03:51Z coheigea $
@@ -34,10 +34,12 @@
 
 import java.io.IOException;
 import java.security.*;
+import java.security.interfaces.DSAKey;
 import java.security.spec.AlgorithmParameterSpec;
 import org.w3c.dom.Element;
 
 import com.sun.org.apache.xml.internal.security.algorithms.implementations.SignatureECDSA;
+import com.sun.org.apache.xml.internal.security.utils.JavaUtils;
 import org.jcp.xml.dsig.internal.SignerOutputStream;
 
 /**
@@ -68,6 +70,8 @@
         "http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha384";
     static final String ECDSA_SHA512 =
         "http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha512";
+    static final String DSA_SHA256 =
+        "http://www.w3.org/2009/xmldsig11#dsa-sha256";
 
     /**
      * Creates a <code>DOMSignatureMethod</code>.
@@ -119,6 +123,8 @@
             return new SHA512withRSA(smElem);
         } else if (alg.equals(SignatureMethod.DSA_SHA1)) {
             return new SHA1withDSA(smElem);
+        } else if (alg.equals(DSA_SHA256)) {
+            return new SHA256withDSA(smElem);
         } else if (alg.equals(ECDSA_SHA1)) {
             return new SHA1withECDSA(smElem);
         } else if (alg.equals(ECDSA_SHA256)) {
@@ -178,7 +184,9 @@
         try {
             Type type = getAlgorithmType();
             if (type == Type.DSA) {
-                return signature.verify(convertXMLDSIGtoASN1(sig));
+                int size = ((DSAKey)key).getParams().getQ().bitLength();
+                return signature.verify(JavaUtils.convertDsaXMLDSIGtoASN1(sig,
+                                                                       size/8));
             } else if (type == Type.ECDSA) {
                 return signature.verify(SignatureECDSA.convertXMLDSIGtoASN1(sig));
             } else {
@@ -222,7 +230,9 @@
         try {
             Type type = getAlgorithmType();
             if (type == Type.DSA) {
-                return convertASN1toXMLDSIG(signature.sign());
+                int size = ((DSAKey)key).getParams().getQ().bitLength();
+                return JavaUtils.convertDsaASN1toXMLDSIG(signature.sign(),
+                                                         size/8);
             } else if (type == Type.ECDSA) {
                 return SignatureECDSA.convertASN1toXMLDSIG(signature.sign());
             } else {
@@ -235,101 +245,6 @@
         }
     }
 
-    /**
-     * Converts an ASN.1 DSA value to a XML Signature DSA Value.
-     *
-     * The JAVA JCE DSA Signature algorithm creates ASN.1 encoded (r,s) value
-     * pairs; the XML Signature requires the core BigInteger values.
-     *
-     * @param asn1Bytes
-     *
-     * @throws IOException
-     * @see <A HREF="http://www.w3.org/TR/xmldsig-core/#dsa-sha1">6.4.1 DSA</A>
-     */
-    private static byte[] convertASN1toXMLDSIG(byte asn1Bytes[])
-        throws IOException
-    {
-        byte rLength = asn1Bytes[3];
-        int i;
-
-        for (i = rLength; (i > 0) && (asn1Bytes[(4 + rLength) - i] == 0); i--);
-
-        byte sLength = asn1Bytes[5 + rLength];
-        int j;
-
-        for (j = sLength;
-            (j > 0) && (asn1Bytes[(6 + rLength + sLength) - j] == 0); j--);
-
-        if ((asn1Bytes[0] != 48) || (asn1Bytes[1] != asn1Bytes.length - 2)
-            || (asn1Bytes[2] != 2) || (i > 20)
-            || (asn1Bytes[4 + rLength] != 2) || (j > 20)) {
-            throw new IOException("Invalid ASN.1 format of DSA signature");
-        } else {
-            byte xmldsigBytes[] = new byte[40];
-
-            System.arraycopy(asn1Bytes, (4+rLength)-i, xmldsigBytes, 20-i, i);
-            System.arraycopy(asn1Bytes, (6+rLength+sLength)-j, xmldsigBytes,
-                             40 - j, j);
-
-            return xmldsigBytes;
-        }
-    }
-
-    /**
-     * Converts a XML Signature DSA Value to an ASN.1 DSA value.
-     *
-     * The JAVA JCE DSA Signature algorithm creates ASN.1 encoded (r,s) value
-     * pairs; the XML Signature requires the core BigInteger values.
-     *
-     * @param xmldsigBytes
-     *
-     * @throws IOException
-     * @see <A HREF="http://www.w3.org/TR/xmldsig-core/#dsa-sha1">6.4.1 DSA</A>
-     */
-    private static byte[] convertXMLDSIGtoASN1(byte xmldsigBytes[])
-        throws IOException
-    {
-        if (xmldsigBytes.length != 40) {
-            throw new IOException("Invalid XMLDSIG format of DSA signature");
-        }
-
-        int i;
-
-        for (i = 20; (i > 0) && (xmldsigBytes[20 - i] == 0); i--);
-
-        int j = i;
-
-        if (xmldsigBytes[20 - i] < 0) {
-            j += 1;
-        }
-
-        int k;
-
-        for (k = 20; (k > 0) && (xmldsigBytes[40 - k] == 0); k--);
-
-        int l = k;
-
-        if (xmldsigBytes[40 - k] < 0) {
-            l += 1;
-        }
-
-        byte asn1Bytes[] = new byte[6 + j + l];
-
-        asn1Bytes[0] = 48;
-        asn1Bytes[1] = (byte)(4 + j + l);
-        asn1Bytes[2] = 2;
-        asn1Bytes[3] = (byte)j;
-
-        System.arraycopy(xmldsigBytes, 20 - i, asn1Bytes, (4 + j) - i, i);
-
-        asn1Bytes[4 + j] = 2;
-        asn1Bytes[5 + j] = (byte) l;
-
-        System.arraycopy(xmldsigBytes, 40 - k, asn1Bytes, (6 + j + l) - k, k);
-
-        return asn1Bytes;
-    }
-
     static final class SHA1withRSA extends DOMSignatureMethod {
         SHA1withRSA(AlgorithmParameterSpec params)
             throws InvalidAlgorithmParameterException {
@@ -425,6 +340,25 @@
         }
     }
 
+    static final class SHA256withDSA extends DOMSignatureMethod {
+        SHA256withDSA(AlgorithmParameterSpec params)
+            throws InvalidAlgorithmParameterException {
+            super(params);
+        }
+        SHA256withDSA(Element dmElem) throws MarshalException {
+            super(dmElem);
+        }
+        public String getAlgorithm() {
+            return DSA_SHA256;
+        }
+        String getJCAAlgorithm() {
+            return "SHA256withDSA";
+        }
+        Type getAlgorithmType() {
+            return Type.DSA;
+        }
+    }
+
     static final class SHA1withECDSA extends DOMSignatureMethod {
         SHA1withECDSA(AlgorithmParameterSpec params)
             throws InvalidAlgorithmParameterException {
--- a/jdk/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMXMLSignatureFactory.java	Wed Apr 16 11:56:58 2014 +0100
+++ b/jdk/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMXMLSignatureFactory.java	Fri May 02 10:01:46 2014 -0400
@@ -21,7 +21,7 @@
  * under the License.
  */
 /*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
  */
 /*
  * $Id: DOMXMLSignatureFactory.java 1333869 2012-05-04 10:42:44Z coheigea $
@@ -239,6 +239,8 @@
             return new DOMSignatureMethod.SHA512withRSA(params);
         } else if (algorithm.equals(SignatureMethod.DSA_SHA1)) {
             return new DOMSignatureMethod.SHA1withDSA(params);
+        } else if (algorithm.equals(DOMSignatureMethod.DSA_SHA256)) {
+            return new DOMSignatureMethod.SHA256withDSA(params);
         } else if (algorithm.equals(SignatureMethod.HMAC_SHA1)) {
             return new DOMHMACSignatureMethod.SHA1(params);
         } else if (algorithm.equals(DOMHMACSignatureMethod.HMAC_SHA256)) {
--- a/jdk/test/javax/xml/crypto/dsig/GenerationTests.java	Wed Apr 16 11:56:58 2014 +0100
+++ b/jdk/test/javax/xml/crypto/dsig/GenerationTests.java	Fri May 02 10:01:46 2014 -0400
@@ -23,7 +23,7 @@
 
 /**
  * @test
- * @bug 4635230 6283345 6303830 6824440 6867348 7094155 8038184
+ * @bug 4635230 6283345 6303830 6824440 6867348 7094155 8038184 8038349
  * @summary Basic unit tests for generating XML Signatures with JSR 105
  * @compile -XDignore.symbol.file KeySelectors.java SignatureValidator.java
  *     X509KeySelector.java GenerationTests.java
@@ -80,9 +80,10 @@
     private static KeyInfoFactory kifac;
     private static DocumentBuilder db;
     private static CanonicalizationMethod withoutComments;
-    private static SignatureMethod dsaSha1, rsaSha1, rsaSha256, rsaSha384, rsaSha512;
+    private static SignatureMethod dsaSha1, dsaSha256, rsaSha1,
+                                   rsaSha256, rsaSha384, rsaSha512;
     private static DigestMethod sha1, sha256, sha384, sha512;
-    private static KeyInfo dsa, rsa, rsa1024;
+    private static KeyInfo dsa1024, dsa2048, rsa, rsa1024;
     private static KeySelector kvks = new KeySelectors.KeyValueKeySelector();
     private static KeySelector sks;
     private static Key signingKey;
@@ -106,10 +107,13 @@
         "http://www.w3.org/TR/xml-stylesheet";
     private final static String STYLESHEET_B64 =
         "http://www.w3.org/Signature/2002/04/xml-stylesheet.b64";
+    private final static String DSA_SHA256 =
+        "http://www.w3.org/2009/xmldsig11#dsa-sha256";
 
     public static void main(String args[]) throws Exception {
         setup();
-        test_create_signature_enveloped_dsa();
+        test_create_signature_enveloped_dsa(1024);
+        test_create_signature_enveloped_dsa(2048);
         test_create_signature_enveloping_b64_dsa();
         test_create_signature_enveloping_dsa();
         test_create_signature_enveloping_hmac_sha1_40();
@@ -157,15 +161,18 @@
         withoutComments = fac.newCanonicalizationMethod
             (CanonicalizationMethod.INCLUSIVE, (C14NMethodParameterSpec)null);
         dsaSha1 = fac.newSignatureMethod(SignatureMethod.DSA_SHA1, null);
+        dsaSha256 = fac.newSignatureMethod(DSA_SHA256, null);
         sha1 = fac.newDigestMethod(DigestMethod.SHA1, null);
         sha256 = fac.newDigestMethod(DigestMethod.SHA256, null);
         sha384 = fac.newDigestMethod
             ("http://www.w3.org/2001/04/xmldsig-more#sha384", null);
         sha512 = fac.newDigestMethod(DigestMethod.SHA512, null);
-        dsa = kifac.newKeyInfo(Collections.singletonList
+        dsa1024 = kifac.newKeyInfo(Collections.singletonList
             (kifac.newKeyValue(validatingKey)));
+        dsa2048 = kifac.newKeyInfo(Collections.singletonList
+            (kifac.newKeyValue(getPublicKey("DSA", 2048))));
         rsa = kifac.newKeyInfo(Collections.singletonList
-            (kifac.newKeyValue(getPublicKey("RSA"))));
+            (kifac.newKeyValue(getPublicKey("RSA", 512))));
         rsa1024 = kifac.newKeyInfo(Collections.singletonList
             (kifac.newKeyValue(getPublicKey("RSA", 1024))));
         rsaSha1 = fac.newSignatureMethod(SignatureMethod.RSA_SHA1, null);
@@ -180,11 +187,25 @@
         httpUd = new HttpURIDereferencer();
     }
 
-    static void test_create_signature_enveloped_dsa() throws Exception {
-        System.out.println("* Generating signature-enveloped-dsa.xml");
+    static void test_create_signature_enveloped_dsa(int size) throws Exception {
+        System.out.println("* Generating signature-enveloped-dsa-"
+                           + size + ".xml");
+        SignatureMethod sm = null;
+        KeyInfo ki = null;
+        Key privKey;
+        if (size == 1024) {
+            sm = dsaSha1;
+            ki = dsa1024;
+            privKey = signingKey;
+        } else if (size == 2048) {
+            sm = dsaSha256;
+            ki = dsa2048;
+            privKey = getPrivateKey("DSA", 2048);
+        } else throw new RuntimeException("unsupported keysize:" + size);
+
         // create SignedInfo
         SignedInfo si = fac.newSignedInfo
-            (withoutComments, dsaSha1, Collections.singletonList
+            (withoutComments, sm, Collections.singletonList
                 (fac.newReference
                     ("", sha1, Collections.singletonList
                         (fac.newTransform(Transform.ENVELOPED,
@@ -192,7 +213,7 @@
                  null, null)));
 
         // create XMLSignature
-        XMLSignature sig = fac.newXMLSignature(si, dsa);
+        XMLSignature sig = fac.newXMLSignature(si, ki);
 
         Document doc = db.newDocument();
         Element envelope = doc.createElementNS
@@ -201,12 +222,12 @@
             "xmlns", "http://example.org/envelope");
         doc.appendChild(envelope);
 
-        DOMSignContext dsc = new DOMSignContext(signingKey, envelope);
+        DOMSignContext dsc = new DOMSignContext(privKey, envelope);
 
         sig.sign(dsc);
-//      StringWriter sw = new StringWriter();
-//      dumpDocument(doc, sw);
-//      System.out.println(sw.toString());
+//        StringWriter sw = new StringWriter();
+//        dumpDocument(doc, sw);
+//        System.out.println(sw.toString());
 
         DOMValidateContext dvc = new DOMValidateContext
             (kvks, envelope.getFirstChild());
@@ -226,21 +247,21 @@
     static void test_create_signature_enveloping_b64_dsa() throws Exception {
         System.out.println("* Generating signature-enveloping-b64-dsa.xml");
         test_create_signature_enveloping
-            (sha1, dsaSha1, dsa, signingKey, kvks, true);
+            (sha1, dsaSha1, dsa1024, signingKey, kvks, true);
         System.out.println();
     }
 
     static void test_create_signature_enveloping_dsa() throws Exception {
         System.out.println("* Generating signature-enveloping-dsa.xml");
         test_create_signature_enveloping
-            (sha1, dsaSha1, dsa, signingKey, kvks, false);
+            (sha1, dsaSha1, dsa1024, signingKey, kvks, false);
         System.out.println();
     }
 
     static void test_create_signature_enveloping_sha256_dsa() throws Exception {
         System.out.println("* Generating signature-enveloping-sha256-dsa.xml");
         test_create_signature_enveloping
-            (sha256, dsaSha1, dsa, signingKey, kvks, false);
+            (sha256, dsaSha1, dsa1024, signingKey, kvks, false);
         System.out.println();
     }
 
@@ -293,7 +314,7 @@
     static void test_create_signature_enveloping_rsa() throws Exception {
         System.out.println("* Generating signature-enveloping-rsa.xml");
         test_create_signature_enveloping(sha1, rsaSha1, rsa,
-            getPrivateKey("RSA"), kvks, false);
+            getPrivateKey("RSA", 512), kvks, false);
         System.out.println();
     }
 
@@ -301,7 +322,7 @@
         throws Exception {
         System.out.println("* Generating signature-enveloping-sha384-rsa_sha256.xml");
         test_create_signature_enveloping(sha384, rsaSha256, rsa,
-            getPrivateKey("RSA"), kvks, false);
+            getPrivateKey("RSA", 512), kvks, false);
         System.out.println();
     }
 
@@ -323,13 +344,13 @@
 
     static void test_create_signature_external_b64_dsa() throws Exception {
         System.out.println("* Generating signature-external-b64-dsa.xml");
-        test_create_signature_external(dsaSha1, dsa, signingKey, kvks, true);
+        test_create_signature_external(dsaSha1, dsa1024, signingKey, kvks, true);
         System.out.println();
     }
 
     static void test_create_signature_external_dsa() throws Exception {
         System.out.println("* Generating signature-external-dsa.xml");
-        test_create_signature_external(dsaSha1, dsa, signingKey, kvks, false);
+        test_create_signature_external(dsaSha1, dsa1024, signingKey, kvks, false);
         System.out.println();
     }
 
@@ -441,7 +462,7 @@
 
         // create XMLSignature
         XMLSignature sig = fac.newXMLSignature(si, rsa, objs, "signature", null);
-        DOMSignContext dsc = new DOMSignContext(getPrivateKey("RSA"), doc);
+        DOMSignContext dsc = new DOMSignContext(getPrivateKey("RSA", 512), doc);
 
         sig.sign(dsc);
 
@@ -487,7 +508,7 @@
         XMLSignature sig = fac.newXMLSignature(si, rsa,
                                                Collections.singletonList(obj),
                                                "signature", null);
-        DOMSignContext dsc = new DOMSignContext(getPrivateKey("RSA"), doc);
+        DOMSignContext dsc = new DOMSignContext(getPrivateKey("RSA", 512), doc);
         dsc.setIdAttributeNS(nc, null, "Id");
 
         sig.sign(dsc);
@@ -530,7 +551,7 @@
         XMLSignature sig = fac.newXMLSignature(si, rsa,
                                                Collections.singletonList(obj),
                                                "signature", null);
-        DOMSignContext dsc = new DOMSignContext(getPrivateKey("RSA"), doc);
+        DOMSignContext dsc = new DOMSignContext(getPrivateKey("RSA", 512), doc);
         sig.sign(dsc);
     }
 
@@ -1116,6 +1137,16 @@
         "90670890367185141189796";
     private static final String DSA_X =
         "0527140396812450214498055937934275626078768840117";
+    private static final String DSA_2048_Y =
+        "15119007057343785981993995134621348945077524760182795513668325877793414638620983617627033248732235626178802906346261435991040697338468329634416089753032362617771631199351767336660070462291411472735835843440140283101463231807789628656218830720378705090795271104661936237385140354825159080766174663596286149653433914842868551355716015585570827642835307073681358328172009941968323702291677280809277843998510864653406122348712345584706761165794179850728091522094227603562280855104749858249588234915206290448353957550635709520273178475097150818955098638774564910092913714625772708285992586894795017709678223469405896699928";
+    private static final String DSA_2048_P =
+        "18111848663142005571178770624881214696591339256823507023544605891411707081617152319519180201250440615163700426054396403795303435564101919053459832890139496933938670005799610981765220283775567361483662648340339405220348871308593627647076689407931875483406244310337925809427432681864623551598136302441690546585427193224254314088256212718983105131138772434658820375111735710449331518776858786793875865418124429269409118756812841019074631004956409706877081612616347900606555802111224022921017725537417047242635829949739109274666495826205002104010355456981211025738812433088757102520562459649777989718122219159982614304359";
+    private static final String DSA_2048_Q =
+        "19689526866605154788513693571065914024068069442724893395618704484701";
+    private static final String DSA_2048_G =
+        "2859278237642201956931085611015389087970918161297522023542900348087718063098423976428252369340967506010054236052095950169272612831491902295835660747775572934757474194739347115870723217560530672532404847508798651915566434553729839971841903983916294692452760249019857108409189016993380919900231322610083060784269299257074905043636029708121288037909739559605347853174853410208334242027740275688698461842637641566056165699733710043802697192696426360843173620679214131951400148855611740858610821913573088059404459364892373027492936037789337011875710759208498486908611261954026964574111219599568903257472567764789616958430";
+    private static final String DSA_2048_X =
+        "14562787764977288900757387442281559936279834964901963465277698843172";
     private static final String RSA_MOD =
         "010800185049102889923150759252557522305032794699952150943573164381" +
         "936603255999071981574575044810461362008102247767482738822150129277" +
@@ -1138,43 +1169,48 @@
         "204903524890556839550490384015324575598723478554854070823335021842" +
         "210112348400928769";
 
-    private static PublicKey getPublicKey(String algo) throws Exception {
-        return getPublicKey(algo, 512);
-    }
-
     private static PublicKey getPublicKey(String algo, int keysize)
         throws Exception {
         KeyFactory kf = KeyFactory.getInstance(algo);
         KeySpec kspec;
         if (algo.equalsIgnoreCase("DSA")) {
-            kspec = new DSAPublicKeySpec(new BigInteger(DSA_Y),
-                                         new BigInteger(DSA_P),
-                                         new BigInteger(DSA_Q),
-                                         new BigInteger(DSA_G));
+            if (keysize == 1024) {
+                kspec = new DSAPublicKeySpec(new BigInteger(DSA_Y),
+                                             new BigInteger(DSA_P),
+                                             new BigInteger(DSA_Q),
+                                             new BigInteger(DSA_G));
+            } else if (keysize == 2048) {
+                kspec = new DSAPublicKeySpec(new BigInteger(DSA_2048_Y),
+                                             new BigInteger(DSA_2048_P),
+                                             new BigInteger(DSA_2048_Q),
+                                             new BigInteger(DSA_2048_G));
+            } else throw new RuntimeException("Unsupported keysize:" + keysize);
         } else if (algo.equalsIgnoreCase("RSA")) {
             if (keysize == 512) {
                 kspec = new RSAPublicKeySpec(new BigInteger(RSA_MOD),
                                              new BigInteger(RSA_PUB));
-            } else {
+            } else if (keysize == 1024) {
                 kspec = new RSAPublicKeySpec(new BigInteger(RSA_1024_MOD),
                                              new BigInteger(RSA_PUB));
-            }
+            } else throw new RuntimeException("Unsupported keysize:" + keysize);
         } else throw new RuntimeException("Unsupported key algorithm " + algo);
         return kf.generatePublic(kspec);
     }
 
-    private static PrivateKey getPrivateKey(String algo) throws Exception {
-        return getPrivateKey(algo, 512);
-    }
-
     private static PrivateKey getPrivateKey(String algo, int keysize)
         throws Exception {
         KeyFactory kf = KeyFactory.getInstance(algo);
         KeySpec kspec;
         if (algo.equalsIgnoreCase("DSA")) {
-            kspec = new DSAPrivateKeySpec
-                (new BigInteger(DSA_X), new BigInteger(DSA_P),
-                 new BigInteger(DSA_Q), new BigInteger(DSA_G));
+            if (keysize == 1024) {
+                kspec = new DSAPrivateKeySpec
+                    (new BigInteger(DSA_X), new BigInteger(DSA_P),
+                     new BigInteger(DSA_Q), new BigInteger(DSA_G));
+            } else if (keysize == 2048) {
+                kspec = new DSAPrivateKeySpec
+                    (new BigInteger(DSA_2048_X), new BigInteger(DSA_2048_P),
+                     new BigInteger(DSA_2048_Q), new BigInteger(DSA_2048_G));
+            } else throw new RuntimeException("Unsupported keysize:" + keysize);
         } else if (algo.equalsIgnoreCase("RSA")) {
             if (keysize == 512) {
                 kspec = new RSAPrivateKeySpec
--- a/jdk/test/javax/xml/crypto/dsig/KeySelectors.java	Wed Apr 16 11:56:58 2014 +0100
+++ b/jdk/test/javax/xml/crypto/dsig/KeySelectors.java	Fri May 02 10:01:46 2014 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -175,7 +175,8 @@
         //@@@FIXME: this should also work for key types other than DSA/RSA
         static boolean algEquals(String algURI, String algName) {
             if (algName.equalsIgnoreCase("DSA") &&
-                algURI.equals(SignatureMethod.DSA_SHA1)) {
+                algURI.equals(SignatureMethod.DSA_SHA1) ||
+                algURI.equals("http://www.w3.org/2009/xmldsig11#dsa-sha256")) {
                 return true;
             } else if (algName.equalsIgnoreCase("RSA") &&
                 (algURI.equals(SignatureMethod.RSA_SHA1) ||