Index: src/org/apache/xml/security/algorithms/implementations/SignatureECDSA.java
===================================================================
--- src/org/apache/xml/security/algorithms/implementations/SignatureECDSA.java (revision 534385)
+++ src/org/apache/xml/security/algorithms/implementations/SignatureECDSA.java (working copy)
@@ -18,6 +18,7 @@
+import java.io.IOException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.Key;
@@ -33,6 +34,7 @@
import org.apache.xml.security.algorithms.SignatureAlgorithmSpi;
import org.apache.xml.security.signature.XMLSignature;
import org.apache.xml.security.signature.XMLSignatureException;
+import org.apache.xml.security.utils.Base64;
/**
@@ -52,6 +54,105 @@
private java.security.Signature _signatureAlgorithm = null;
/**
+ * Converts an ASN.1 ECDSA value to a XML Signature ECDSA Value.
+ *
+ * The JAVA JCE ECDSA 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 6.4.1 DSA
+ * @see 3.3. ECDSA Signatures
+ */
+ 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 > 24)
+ || (asn1Bytes[4 + rLength] != 2) || (j > 24)) {
+ throw new IOException("Invalid ASN.1 format of ECDSA signature");
+ }
+ byte xmldsigBytes[] = new byte[48];
+
+ System.arraycopy(asn1Bytes, (4 + rLength) - i, xmldsigBytes, 24 - i,
+ i);
+ System.arraycopy(asn1Bytes, (6 + rLength + sLength) - j, xmldsigBytes,
+ 48 - j, j);
+
+ return xmldsigBytes;
+ }
+
+ /**
+ * Converts a XML Signature ECDSA Value to an ASN.1 DSA value.
+ *
+ * The JAVA JCE ECDSA 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 6.4.1 DSA
+ * @see 3.3. ECDSA Signatures
+ */
+ private static byte[] convertXMLDSIGtoASN1(byte xmldsigBytes[])
+ throws IOException {
+
+ if (xmldsigBytes.length != 48) {
+ throw new IOException("Invalid XMLDSIG format of ECDSA signature");
+ }
+
+ int i;
+
+ for (i = 24; (i > 0) && (xmldsigBytes[24 - i] == 0); i--);
+
+ int j = i;
+
+ if (xmldsigBytes[24 - i] < 0) {
+ j += 1;
+ }
+
+ int k;
+
+ for (k = 24; (k > 0) && (xmldsigBytes[48 - k] == 0); k--);
+
+ int l = k;
+
+ if (xmldsigBytes[48 - 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, 24 - i, asn1Bytes, (4 + j) - i, i);
+
+ asn1Bytes[4 + j] = 2;
+ asn1Bytes[5 + j] = (byte) l;
+
+ System.arraycopy(xmldsigBytes, 48 - k, asn1Bytes, (6 + j + l) - k, k);
+
+ return asn1Bytes;
+ }
+
+ /**
* Constructor SignatureRSA
*
* @throws XMLSignatureException
@@ -98,9 +199,16 @@
throws XMLSignatureException {
try {
- return this._signatureAlgorithm.verify(signature);
+ byte[] jcebytes = SignatureECDSA.convertXMLDSIGtoASN1(signature);
+
+ if (log.isDebugEnabled())
+ log.debug("Called ECDSA.verify() on " + Base64.encode(signature));
+
+ return this._signatureAlgorithm.verify(jcebytes);
} catch (SignatureException ex) {
throw new XMLSignatureException("empty", ex);
+ } catch (IOException ex) {
+ throw new XMLSignatureException("empty", ex);
}
}
@@ -127,9 +235,13 @@
protected byte[] engineSign() throws XMLSignatureException {
try {
- return this._signatureAlgorithm.sign();
+ byte jcebytes[] = this._signatureAlgorithm.sign();
+
+ return SignatureECDSA.convertASN1toXMLDSIG(jcebytes);
} catch (SignatureException ex) {
throw new XMLSignatureException("empty", ex);
+ } catch (IOException ex) {
+ throw new XMLSignatureException("empty", ex);
}
}