You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ws.apache.org by co...@apache.org on 2012/02/09 16:00:50 UTC

svn commit: r1242349 - in /webservices/wss4j/branches/swssf/streaming-xml-security/src/main: java/org/swssf/xmlsec/impl/algorithms/ECDSAUtils.java java/org/swssf/xmlsec/impl/algorithms/PKISignatureAlgorithm.java resources/security-config.xml

Author: coheigea
Date: Thu Feb  9 15:00:50 2012
New Revision: 1242349

URL: http://svn.apache.org/viewvc?rev=1242349&view=rev
Log:
Add support for ECDSA for signature creation and verification

Added:
    webservices/wss4j/branches/swssf/streaming-xml-security/src/main/java/org/swssf/xmlsec/impl/algorithms/ECDSAUtils.java
Modified:
    webservices/wss4j/branches/swssf/streaming-xml-security/src/main/java/org/swssf/xmlsec/impl/algorithms/PKISignatureAlgorithm.java
    webservices/wss4j/branches/swssf/streaming-xml-security/src/main/resources/security-config.xml

Added: webservices/wss4j/branches/swssf/streaming-xml-security/src/main/java/org/swssf/xmlsec/impl/algorithms/ECDSAUtils.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/branches/swssf/streaming-xml-security/src/main/java/org/swssf/xmlsec/impl/algorithms/ECDSAUtils.java?rev=1242349&view=auto
==============================================================================
--- webservices/wss4j/branches/swssf/streaming-xml-security/src/main/java/org/swssf/xmlsec/impl/algorithms/ECDSAUtils.java (added)
+++ webservices/wss4j/branches/swssf/streaming-xml-security/src/main/java/org/swssf/xmlsec/impl/algorithms/ECDSAUtils.java Thu Feb  9 15:00:50 2012
@@ -0,0 +1,155 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.swssf.xmlsec.impl.algorithms;
+
+import java.io.IOException;
+
+/**
+ * @author $Author: coheigea $
+ * @version $Revision: 1181995 $ $Date: 2011-10-11 19:03:00 +0100 (Tue, 11 Oct 2011) $
+ */
+public final class ECDSAUtils {
+
+    private ECDSAUtils() {
+        // complete
+    }
+    
+    /**
+     * 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 <A HREF="http://www.w3.org/TR/xmldsig-core/#dsa-sha1">6.4.1 DSA</A>
+     * @see <A HREF="ftp://ftp.rfc-editor.org/in-notes/rfc4050.txt">3.3. ECDSA Signatures</A>
+     */
+    public static byte[] convertASN1toXMLDSIG(byte asn1Bytes[]) throws IOException {
+
+        if (asn1Bytes.length < 8 || asn1Bytes[0] != 48) {
+            throw new IOException("Invalid ASN.1 format of ECDSA signature");
+        }
+        int offset;
+        if (asn1Bytes[1] > 0) {
+            offset = 2;
+        } else if (asn1Bytes[1] == (byte) 0x81) {
+            offset = 3;
+        } else {
+            throw new IOException("Invalid ASN.1 format of ECDSA signature");
+        }
+
+        byte rLength = asn1Bytes[offset + 1];
+        int i;
+
+        for (i = rLength; (i > 0) && (asn1Bytes[(offset + 2 + rLength) - i] == 0); i--);
+
+        byte sLength = asn1Bytes[offset + 2 + rLength + 1];
+        int j;
+
+        for (j = sLength;
+            (j > 0) && (asn1Bytes[(offset + 2 + rLength + 2 + sLength) - j] == 0); j--);
+
+        int rawLen = Math.max(i, j);
+
+        if ((asn1Bytes[offset - 1] & 0xff) != asn1Bytes.length - offset
+            || (asn1Bytes[offset - 1] & 0xff) != 2 + rLength + 2 + sLength
+            || asn1Bytes[offset] != 2
+            || asn1Bytes[offset + 2 + rLength] != 2) {
+            throw new IOException("Invalid ASN.1 format of ECDSA signature");
+        } 
+        byte xmldsigBytes[] = new byte[2*rawLen];
+
+        System.arraycopy(asn1Bytes, (offset + 2 + rLength) - i, xmldsigBytes, rawLen - i, i);
+        System.arraycopy(asn1Bytes, (offset + 2 + rLength + 2 + sLength) - j, xmldsigBytes,
+                         2*rawLen - 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 <A HREF="http://www.w3.org/TR/xmldsig-core/#dsa-sha1">6.4.1 DSA</A>
+     * @see <A HREF="ftp://ftp.rfc-editor.org/in-notes/rfc4050.txt">3.3. ECDSA Signatures</A>
+     */
+    public static byte[] convertXMLDSIGtoASN1(byte xmldsigBytes[]) throws IOException {
+
+        int rawLen = xmldsigBytes.length/2;
+
+        int i;
+
+        for (i = rawLen; (i > 0) && (xmldsigBytes[rawLen - i] == 0); i--);
+
+        int j = i;
+
+        if (xmldsigBytes[rawLen - i] < 0) {
+            j += 1;
+        }
+
+        int k;
+
+        for (k = rawLen; (k > 0) && (xmldsigBytes[2*rawLen - k] == 0); k--);
+
+        int l = k;
+
+        if (xmldsigBytes[2*rawLen - k] < 0) {
+            l += 1;
+        }
+
+        int len = 2 + j + 2 + l;
+        if (len > 255) {
+            throw new IOException("Invalid XMLDSIG format of ECDSA signature");
+        }
+        int offset;
+        byte asn1Bytes[];
+        if (len < 128) {
+            asn1Bytes = new byte[2 + 2 + j + 2 + l];
+            offset = 1;
+        } else {
+            asn1Bytes = new byte[3 + 2 + j + 2 + l];
+            asn1Bytes[1] = (byte) 0x81;
+            offset = 2;
+        }
+        asn1Bytes[0] = 48;
+        asn1Bytes[offset++] = (byte) len;
+        asn1Bytes[offset++] = 2;
+        asn1Bytes[offset++] = (byte) j;
+
+        System.arraycopy(xmldsigBytes, rawLen - i, asn1Bytes, (offset + j) - i, i);
+
+        offset += j;
+
+        asn1Bytes[offset++] = 2;
+        asn1Bytes[offset++] = (byte) l;
+
+        System.arraycopy(xmldsigBytes, 2*rawLen - k, asn1Bytes, (offset + l) - k, k);
+
+        return asn1Bytes;
+    }
+}

Modified: webservices/wss4j/branches/swssf/streaming-xml-security/src/main/java/org/swssf/xmlsec/impl/algorithms/PKISignatureAlgorithm.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/branches/swssf/streaming-xml-security/src/main/java/org/swssf/xmlsec/impl/algorithms/PKISignatureAlgorithm.java?rev=1242349&r1=1242348&r2=1242349&view=diff
==============================================================================
--- webservices/wss4j/branches/swssf/streaming-xml-security/src/main/java/org/swssf/xmlsec/impl/algorithms/PKISignatureAlgorithm.java (original)
+++ webservices/wss4j/branches/swssf/streaming-xml-security/src/main/java/org/swssf/xmlsec/impl/algorithms/PKISignatureAlgorithm.java Thu Feb  9 15:00:50 2012
@@ -21,6 +21,7 @@ package org.swssf.xmlsec.impl.algorithms
 import org.swssf.xmlsec.ext.XMLSecurityException;
 import org.xmlsecurity.ns.configuration.AlgorithmType;
 
+import java.io.IOException;
 import java.security.*;
 import java.security.spec.AlgorithmParameterSpec;
 
@@ -88,12 +89,18 @@ public class PKISignatureAlgorithm imple
 
     public byte[] engineSign() throws XMLSecurityException {
         try {
-            return signature.sign();
+            byte[] jcebytes = signature.sign();
+            if (algorithmType.getJCEName().contains("ECDSA")) {
+                return ECDSAUtils.convertASN1toXMLDSIG(jcebytes);
+            }
+            return jcebytes;
         } catch (SignatureException e) {
             throw new XMLSecurityException(XMLSecurityException.ErrorCode.FAILED_SIGNATURE, e);
+        } catch (IOException e) {
+            throw new XMLSecurityException(XMLSecurityException.ErrorCode.FAILED_SIGNATURE, e);
         }
     }
-
+    
     public void engineInitVerify(Key verificationKey) throws XMLSecurityException {
         try {
             signature.initVerify((PublicKey) verificationKey);
@@ -104,9 +111,15 @@ public class PKISignatureAlgorithm imple
 
     public boolean engineVerify(byte[] signature) throws XMLSecurityException {
         try {
-            return this.signature.verify(signature);
+            byte[] jcebytes = signature;
+            if (algorithmType.getJCEName().contains("ECDSA")) {
+                jcebytes = ECDSAUtils.convertXMLDSIGtoASN1(jcebytes);
+            }
+            return this.signature.verify(jcebytes);
         } catch (SignatureException e) {
             throw new XMLSecurityException(XMLSecurityException.ErrorCode.FAILED_CHECK, e);
+        } catch (IOException e) {
+            throw new XMLSecurityException(XMLSecurityException.ErrorCode.FAILED_CHECK, e);
         }
     }
 

Modified: webservices/wss4j/branches/swssf/streaming-xml-security/src/main/resources/security-config.xml
URL: http://svn.apache.org/viewvc/webservices/wss4j/branches/swssf/streaming-xml-security/src/main/resources/security-config.xml?rev=1242349&r1=1242348&r2=1242349&view=diff
==============================================================================
--- webservices/wss4j/branches/swssf/streaming-xml-security/src/main/resources/security-config.xml (original)
+++ webservices/wss4j/branches/swssf/streaming-xml-security/src/main/resources/security-config.xml Thu Feb  9 15:00:50 2012
@@ -174,11 +174,37 @@
                     Description="ECDSA Signature with SHA-1 message digest"
                     AlgorithmClass="Signature"
                     RequirementLevel="OPTIONAL"
-                    SpecificationURL="http://www.ietf.org/internet-drafts/draft-eastlake-xmldsig-uri-02.txt"
-                    KeyLength="160"
-                    RequiredKey="ECDSAwithSHA1"
+                    SpecificationURL="http://www.ietf.org/rfc/rfc4051.txt"
+                    RequiredKey="SHA1withECDSA"
+                    JCEProvider="BC"
+                    JCEName="SHA1withECDSA"/>
+
+         <Algorithm URI="http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha256"
+                    Description="ECDSA Signature with SHA-256 message digest"
+                    AlgorithmClass="Signature"
+                    RequirementLevel="OPTIONAL"
+                    SpecificationURL="http://www.ietf.org/rfc/rfc4051.txt"
+                    RequiredKey="SHA256withECDSA"
+                    JCEProvider="BC"
+                    JCEName="SHA256withECDSA"/>
+
+         <Algorithm URI="http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha384"
+                    Description="ECDSA Signature with SHA-384 message digest"
+                    AlgorithmClass="Signature"
+                    RequirementLevel="OPTIONAL"
+                    SpecificationURL="http://www.ietf.org/rfc/rfc4051.txt"
+                    RequiredKey="SHA384withECDSA"
+                    JCEProvider="BC"
+                    JCEName="SHA384withECDSA"/>
+
+         <Algorithm URI="http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha512"
+                    Description="ECDSA Signature with SHA-512 message digest"
+                    AlgorithmClass="Signature"
+                    RequirementLevel="OPTIONAL"
+                    SpecificationURL="http://www.ietf.org/rfc/rfc4051.txt"
+                    RequiredKey="SHA512withECDSA"
                     JCEProvider="BC"
-                    JCEName="ECDSAwithSHA1"/>
+                    JCEName="SHA512withECDSA"/>
 
          <!-- MAC Algorithms -->
          <Algorithm URI="http://www.w3.org/2001/04/xmldsig-more#hmac-md5"