jdk/src/share/classes/com/sun/org/apache/xml/internal/security/utils/JavaUtils.java
changeset 24251 da7dc40edb67
parent 18780 f47b920867e7
--- 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;
+    }
 }