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"