You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@santuario.apache.org by co...@apache.org on 2009/07/14 13:10:04 UTC
svn commit: r793853 - in /xml/security/trunk: data/at/buergerkarte/
data/org/apache/xml/security/samples/input/
src/org/apache/xml/security/algorithms/implementations/
src_unitTests/org/apache/xml/security/test/signature/
Author: coheigea
Date: Tue Jul 14 11:10:03 2009
New Revision: 793853
URL: http://svn.apache.org/viewvc?rev=793853&view=rev
Log:
[42239] - ECDSA signature vlaue interop patch.
Added:
xml/security/trunk/data/at/buergerkarte/
xml/security/trunk/data/at/buergerkarte/testresp.xml (with props)
xml/security/trunk/data/org/apache/xml/security/samples/input/ecdsa.jks (with props)
xml/security/trunk/data/org/apache/xml/security/samples/input/ecdsaSignature.xml (with props)
xml/security/trunk/src_unitTests/org/apache/xml/security/test/signature/ECDSASignatureTest.java (with props)
xml/security/trunk/src_unitTests/org/apache/xml/security/test/signature/IndexedDocument.java (with props)
xml/security/trunk/src_unitTests/org/apache/xml/security/test/signature/XPointerResourceResolver.java (with props)
Modified:
xml/security/trunk/src/org/apache/xml/security/algorithms/implementations/SignatureECDSA.java
xml/security/trunk/src_unitTests/org/apache/xml/security/test/signature/AllTests.java
Added: xml/security/trunk/data/at/buergerkarte/testresp.xml
URL: http://svn.apache.org/viewvc/xml/security/trunk/data/at/buergerkarte/testresp.xml?rev=793853&view=auto
==============================================================================
--- xml/security/trunk/data/at/buergerkarte/testresp.xml (added)
+++ xml/security/trunk/data/at/buergerkarte/testresp.xml Tue Jul 14 11:10:03 2009
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="UTF-8"?><dsig:Signature Id="signature-20070418142710935-6555091641353629364" xmlns:dsig="http://www.w3.org/2000/09/xmldsig#"><dsig:SignedInfo><dsig:CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/><dsig:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha1"/><dsig:Reference Id="signed-data-reference-0-20070418142710935-6555091641353629364" URI="#signed-data-object-0-20070418142710935-6555091641353629364"><dsig:Transforms><dsig:Transform Algorithm="http://www.w3.org/2002/06/xmldsig-filter2"><xpf2:XPath Filter="intersect" xmlns:xpf2="http://www.w3.org/2002/06/xmldsig-filter2">//*[@Id='signed-data-object-0-20070418142710935-6555091641353629364']/node()</xpf2:XPath></dsig:Transform><dsig:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#base64"/><dsig:Transform Algorithm="http://www.w3.org/TR/1999/REC-xslt-19991116"><xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Tran
sform">
+<!--
+ xmlns:fn="http://www.w3.org/2005/02/xpath-functions"
+ xmlns:date="http://exslt.org/dates-and-times"
+ xmlns:dyn="http://exslt.org/dynamic"
+ xmlns:exsl="http://exslt.org/common" -->
+<xsl:output method="xml"/>
+<xsl:template match="/org.clazzes.tapestry.sl.test.data.TestObject">
+ <html xmlns="http://www.w3.org/1999/xhtml">
+ <head><title>Objektliste</title><style type="text/css"/></head>
+ <body>
+ <h2>Objekte</h2>
+ <table>
+ <tr>
+ <th>Code</th>
+ <th>Name</th>
+ <th>from</th>
+ <th>to</th>
+ </tr>
+ <tr>
+ <td><xsl:value-of select="code"/></td>
+ <td><xsl:value-of select="name"/></td>
+ <td><xsl:value-of select="fromKm"/></td>
+ <td><xsl:value-of select="toKm"/></td>
+ </tr>
+ </table>
+ </body>
+ </html>
+</xsl:template>
+
+</xsl:stylesheet></dsig:Transform><dsig:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/></dsig:Transforms><dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/><dsig:DigestValue>ZvBPjlGyC2r8NzmfCLjvPwI47yQ=</dsig:DigestValue></dsig:Reference><dsig:Reference Id="etsi-data-reference-1-20070418142710935-6555091641353629364" Type="http://uri.etsi.org/01903/v1.1.1#SignedProperties" URI="#xmlns(etsi=http://uri.etsi.org/01903/v1.1.1%23)%20xpointer(id('etsi-data-object-1-20070418142710935-6555091641353629364')/child::etsi:QualifyingProperties/child::etsi:SignedProperties)"><dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/><dsig:DigestValue>3XTXxNKDqPOGcRDrk2u09NuwLhQ=</dsig:DigestValue></dsig:Reference></dsig:SignedInfo><dsig:SignatureValue>7oi4kPJ9co9jfDD6HkVNRKloY10wjDhsh2U8z8/WOIcB9fOhkQ7FKTGERmBmyxLt</dsig:SignatureValue><dsig:KeyInfo><dsig:X509Data><dsig:X509Certificate>MIIEjTCCA3WgAwIBAgIDAxChMA0GCSqGSIb3DQEBBQUAMIGXMQswCQYD
VQQGEwJBVDFIMEYGA1UE
+Cgw/QS1UcnVzdCBHZXMuIGYuIFNpY2hlcmhlaXRzc3lzdGVtZSBpbSBlbGVrdHIuIERhdGVudmVy
+a2VociBHbWJIMR4wHAYDVQQLDBVhLXNpZ24tUHJlbWl1bS1TaWctMDIxHjAcBgNVBAMMFWEtc2ln
+bi1QcmVtaXVtLVNpZy0wMjAeFw0wNzAzMjMwODE1NDVaFw0xMTAzMjMwODE1NDVaMGwxCzAJBgNV
+BAYTAkFUMRYwFAYDVQQDDA1Xb2xmZ2FuZyBHbGFzMQ0wCwYDVQQEDARHbGFzMREwDwYDVQQqDAhX
+b2xmZ2FuZzEVMBMGA1UEBRMMNDY5MjkxMDk4ODY4MQwwCgYDVQQMDANEci4wSTATBgcqhkjOPQIB
+BggqhkjOPQMBAQMyAAT7gEPYqwvFHYgev7WGnBcmg9RNSeaUWk5pNRGrK+lgewClDkuxGhzCBngk
+UPPRt66jggHlMIIB4TATBgNVHSMEDDAKgAhN3+H/S9nJ3zAnBggrBgEFBQcBAwEB/wQYMBYwCAYG
+BACORgEBMAoGCCsGAQUFBwsBMHsGCCsGAQUFBwEBBG8wbTBCBggrBgEFBQcwAoY2aHR0cDovL3d3
+dy5hLXRydXN0LmF0L2NlcnRzL2Etc2lnbi1QcmVtaXVtLVNpZy0wMmEuY3J0MCcGCCsGAQUFBzAB
+hhtodHRwOi8vb2NzcC5hLXRydXN0LmF0L29jc3AwWQYDVR0gBFIwUDBEBgYqKAARAQswOjA4Bggr
+BgEFBQcCARYsaHR0cDovL3d3dy5hLXRydXN0LmF0L2RvY3MvY3AvYS1zaWduLVByZW1pdW0wCAYG
+BACLMAEBMIGaBgNVHR8EgZIwgY8wgYyggYmggYaGgYNsZGFwOi8vbGRhcC5hLXRydXN0LmF0L291
+PWEtc2lnbi1QcmVtaXVtLVNpZy0wMixvPUEtVHJ1c3QsYz1BVD9jZXJ0aWZpY2F0ZXJldm9jYXRp
+b25saXN0P2Jhc2U/b2JqZWN0Y2xhc3M9ZWlkQ2VydGlmaWNhdGlvbkF1dGhvcml0eTARBgNVHQ4E
+CgQIRGl7fFO8rawwDgYDVR0PAQH/BAQDAgbAMAkGA1UdEwQCMAAwDQYJKoZIhvcNAQEFBQADggEB
+AC8Cmjr0T8Fk3tQ9VeHnliG7iYEx6NymrRGNnrEfSyLx/d2UtlgOEzpW6hlZWO/2TvOF7ZUZVAub
+hbSDVWJurTRlsWeMIwIfDP6KVTooSorPaIK1p8mgDqhkW5usGYG+n0MBH1aMM3WnOylp4G5qh6bJ
+fSzWLjcI2gfPoqsDkCx9rPN5sOEAcpwHt/fA1vqjozI24j3K1tvbc6Z7w2pYfqLk/LZKi0QrhmPD
+BnRLj6pnej9fxCkHndfd4S2rAGdWM5T4heSq47X8Ns/VfeZFvAXK6cV4EtVjVNe6dBQfKmLKjJzo
+DSr1O8T/oYExuQRup78GOVk9+CF97oF7hXu2WgI=</dsig:X509Certificate></dsig:X509Data></dsig:KeyInfo><dsig:Object Id="signed-data-object-0-20070418142710935-6555091641353629364">PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48b3JnLmNsYXp6ZXMudGFwZXN0
+cnkuc2wudGVzdC5kYXRhLlRlc3RPYmplY3Q+CiAgPGNvZGU+Y29kZTE8L2NvZGU+CiAgPG5hbWU+
+VGVzdDE8L25hbWU+CiAgPGZyb21LbT40NC40NDwvZnJvbUttPgogIDx0b0ttPjc3Ljc3PC90b0tt
+Pgo8L29yZy5jbGF6emVzLnRhcGVzdHJ5LnNsLnRlc3QuZGF0YS5UZXN0T2JqZWN0Pg==</dsig:Object><dsig:Object Id="etsi-data-object-1-20070418142710935-6555091641353629364"><etsi:QualifyingProperties Target="#signature-20070418142710935-6555091641353629364" xmlns:etsi="http://uri.etsi.org/01903/v1.1.1#"><etsi:SignedProperties><etsi:SignedSignatureProperties><etsi:SigningTime>2007-04-18T14:27:00Z</etsi:SigningTime><etsi:SigningCertificate><etsi:Cert><etsi:CertDigest><etsi:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/><etsi:DigestValue>VoH1/KR6R+FRsOTiOO7ptHrVRDY=</etsi:DigestValue></etsi:CertDigest><etsi:IssuerSerial><dsig:X509IssuerName>CN=a-sign-Premium-Sig-02,OU=a-sign-Premium-Sig-02,O=A-Trust Ges. f. Sicherheitssysteme im elektr. Datenverkehr GmbH,C=AT</dsig:X509IssuerName><dsig:X509SerialNumber>200865</dsig:X509SerialNumber></etsi:IssuerSerial></etsi:Cert></etsi:SigningCertificate><etsi:SignaturePolicyIdentifier><etsi:SignaturePolicyImplied/></etsi:SignaturePolicyIden
tifier></etsi:SignedSignatureProperties><etsi:SignedDataObjectProperties><etsi:DataObjectFormat ObjectReference="#signed-data-reference-0-20070418142710935-6555091641353629364"><etsi:MimeType>application/xhtml+xml</etsi:MimeType></etsi:DataObjectFormat></etsi:SignedDataObjectProperties></etsi:SignedProperties></etsi:QualifyingProperties></dsig:Object></dsig:Signature>
Propchange: xml/security/trunk/data/at/buergerkarte/testresp.xml
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: xml/security/trunk/data/at/buergerkarte/testresp.xml
------------------------------------------------------------------------------
svn:keywords = Rev Date
Propchange: xml/security/trunk/data/at/buergerkarte/testresp.xml
------------------------------------------------------------------------------
svn:mime-type = text/xml
Added: xml/security/trunk/data/org/apache/xml/security/samples/input/ecdsa.jks
URL: http://svn.apache.org/viewvc/xml/security/trunk/data/org/apache/xml/security/samples/input/ecdsa.jks?rev=793853&view=auto
==============================================================================
Binary file - no diff available.
Propchange: xml/security/trunk/data/org/apache/xml/security/samples/input/ecdsa.jks
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: xml/security/trunk/data/org/apache/xml/security/samples/input/ecdsaSignature.xml
URL: http://svn.apache.org/viewvc/xml/security/trunk/data/org/apache/xml/security/samples/input/ecdsaSignature.xml?rev=793853&view=auto
==============================================================================
--- xml/security/trunk/data/org/apache/xml/security/samples/input/ecdsaSignature.xml (added)
+++ xml/security/trunk/data/org/apache/xml/security/samples/input/ecdsaSignature.xml Tue Jul 14 11:10:03 2009
@@ -0,0 +1,38 @@
+<!-- Comment before -->
+<RootElement>Some simple text
+<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
+<ds:SignedInfo>
+
+<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></ds:CanonicalizationMethod>
+<ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha1"></ds:SignatureMethod>
+<ds:Reference URI="">
+<ds:Transforms>
+<ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"></ds:Transform>
+<ds:Transform Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments"></ds:Transform>
+</ds:Transforms>
+<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></ds:DigestMethod>
+<ds:DigestValue>LKyUpNaZJ2joznVzwEup5JDwtS0=</ds:DigestValue>
+</ds:Reference>
+</ds:SignedInfo>
+<ds:SignatureValue>
+Qma5I5AZiSzQ6J4UZwjpteD2qvQclABKATPQ5MZ7mmOFYfj8xAlpXWu2u+Oa/4mpP9jK9OUUcTU9
+Psfucz+qPA==
+</ds:SignatureValue>
+<ds:KeyInfo>
+<ds:X509Data>
+<ds:X509Certificate>
+MIICEjCCAbegAwIBAgIGARJQ/UmbMAsGByqGSM49BAEFADBQMSEwHwYDVQQDExhYTUwgRUNEU0Eg
+U2lnbmF0dXJlIFRlc3QxFjAUBgoJkiaJk/IsZAEZEwZhcGFjaGUxEzARBgoJkiaJk/IsZAEZEwNv
+cmcwHhcNMDcwNTAzMDgxMDE1WhcNMTEwNTAzMDgxMDE1WjBQMSEwHwYDVQQDExhYTUwgRUNEU0Eg
+U2lnbmF0dXJlIFRlc3QxFjAUBgoJkiaJk/IsZAEZEwZhcGFjaGUxEzARBgoJkiaJk/IsZAEZEwNv
+cmcwgbQwgY0GByqGSM49AgEwgYECAQEwLAYHKoZIzj0BAQIhAP//////////////////////////
+//////////////2XMCcEIQD////////////////////////////////////////9lAQCAKYEAgMB
+AiEA/////////////////////2xhEHCZWtEARYQbCbdhuJMDIgADZubz40WiQ+v/nrjhfizYmEIl
+tKIr/n7hwGwpG3CDEk2jIDAeMAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgGmMAsGByqGSM49
+BAEFAANIADBFAiEA63Pq7/YfDDrnbCxXVX20T3dn77iL8dvC1Cb24Al9VFkCIHUeymf/N+H60OQL
+v9Wg/X8Cbp2am42qjQvaKtb4+BFk
+</ds:X509Certificate>
+</ds:X509Data>
+</ds:KeyInfo>
+</ds:Signature></RootElement>
+<!-- Comment after -->
Propchange: xml/security/trunk/data/org/apache/xml/security/samples/input/ecdsaSignature.xml
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: xml/security/trunk/data/org/apache/xml/security/samples/input/ecdsaSignature.xml
------------------------------------------------------------------------------
svn:keywords = Rev Date
Propchange: xml/security/trunk/data/org/apache/xml/security/samples/input/ecdsaSignature.xml
------------------------------------------------------------------------------
svn:mime-type = text/xml
Modified: xml/security/trunk/src/org/apache/xml/security/algorithms/implementations/SignatureECDSA.java
URL: http://svn.apache.org/viewvc/xml/security/trunk/src/org/apache/xml/security/algorithms/implementations/SignatureECDSA.java?rev=793853&r1=793852&r2=793853&view=diff
==============================================================================
--- xml/security/trunk/src/org/apache/xml/security/algorithms/implementations/SignatureECDSA.java (original)
+++ xml/security/trunk/src/org/apache/xml/security/algorithms/implementations/SignatureECDSA.java Tue Jul 14 11:10:03 2009
@@ -80,17 +80,24 @@
for (j = sLength;
(j > 0) && (asn1Bytes[(6 + rLength + sLength) - j] == 0); j--);
+ int rawLen = ((i+7)/8)*8;
+
+ int tmp = ((j+7)/8)*8;
+
+ if (tmp > rawLen)
+ rawLen = tmp;
+
if ((asn1Bytes[0] != 48) || (asn1Bytes[1] != asn1Bytes.length - 2)
- || (asn1Bytes[2] != 2) || (i > 24)
- || (asn1Bytes[4 + rLength] != 2) || (j > 24)) {
+ || (asn1Bytes[2] != 2) || rawLen < 24
+ || (asn1Bytes[4 + rLength] != 2) ) {
throw new IOException("Invalid ASN.1 format of ECDSA signature");
}
- byte xmldsigBytes[] = new byte[48];
+ byte xmldsigBytes[] = new byte[2*rawLen];
- System.arraycopy(asn1Bytes, (4 + rLength) - i, xmldsigBytes, 24 - i,
+ System.arraycopy(asn1Bytes, (4 + rLength) - i, xmldsigBytes, rawLen - i,
i);
System.arraycopy(asn1Bytes, (6 + rLength + sLength) - j, xmldsigBytes,
- 48 - j, j);
+ 2*rawLen - j, j);
return xmldsigBytes;
}
@@ -111,27 +118,29 @@
private static byte[] convertXMLDSIGtoASN1(byte xmldsigBytes[])
throws IOException {
- if (xmldsigBytes.length != 48) {
+ if (xmldsigBytes.length < 48) {
throw new IOException("Invalid XMLDSIG format of ECDSA signature");
}
+ int rawLen = xmldsigBytes.length/2;
+
int i;
- for (i = 24; (i > 0) && (xmldsigBytes[24 - i] == 0); i--);
+ for (i = rawLen; (i > 0) && (xmldsigBytes[rawLen - i] == 0); i--);
int j = i;
- if (xmldsigBytes[24 - i] < 0) {
+ if (xmldsigBytes[rawLen - i] < 0) {
j += 1;
}
int k;
- for (k = 24; (k > 0) && (xmldsigBytes[48 - k] == 0); k--);
+ for (k = rawLen; (k > 0) && (xmldsigBytes[2*rawLen - k] == 0); k--);
int l = k;
- if (xmldsigBytes[48 - k] < 0) {
+ if (xmldsigBytes[2*rawLen - k] < 0) {
l += 1;
}
@@ -142,12 +151,12 @@
asn1Bytes[2] = 2;
asn1Bytes[3] = (byte) j;
- System.arraycopy(xmldsigBytes, 24 - i, asn1Bytes, (4 + j) - i, i);
+ System.arraycopy(xmldsigBytes, rawLen - 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);
+ System.arraycopy(xmldsigBytes, 2*rawLen - k, asn1Bytes, (6 + j + l) - k, k);
return asn1Bytes;
}
Modified: xml/security/trunk/src_unitTests/org/apache/xml/security/test/signature/AllTests.java
URL: http://svn.apache.org/viewvc/xml/security/trunk/src_unitTests/org/apache/xml/security/test/signature/AllTests.java?rev=793853&r1=793852&r2=793853&view=diff
==============================================================================
--- xml/security/trunk/src_unitTests/org/apache/xml/security/test/signature/AllTests.java (original)
+++ xml/security/trunk/src_unitTests/org/apache/xml/security/test/signature/AllTests.java Tue Jul 14 11:10:03 2009
@@ -18,6 +18,7 @@
suite.addTest(UnknownAlgoSignatureTest.suite());
suite.addTest(KeyValueTest.suite());
suite.addTest(ProcessingInstructionTest.suite());
+ suite.addTest(ECDSASignatureTest.suite());
suite.addTest(NoKeyInfoTest.suite());
//$JUnit-END$
return suite;
Added: xml/security/trunk/src_unitTests/org/apache/xml/security/test/signature/ECDSASignatureTest.java
URL: http://svn.apache.org/viewvc/xml/security/trunk/src_unitTests/org/apache/xml/security/test/signature/ECDSASignatureTest.java?rev=793853&view=auto
==============================================================================
--- xml/security/trunk/src_unitTests/org/apache/xml/security/test/signature/ECDSASignatureTest.java (added)
+++ xml/security/trunk/src_unitTests/org/apache/xml/security/test/signature/ECDSASignatureTest.java Tue Jul 14 11:10:03 2009
@@ -0,0 +1,321 @@
+/*
+ * Copyright 1999-2009 The Apache Software Foundation.
+ *
+ * Licensed 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.apache.xml.security.test.signature;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.lang.reflect.Constructor;
+import java.security.KeyStore;
+import java.security.PrivateKey;
+import java.security.Security;
+import java.security.cert.X509Certificate;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+import org.apache.xml.security.algorithms.SignatureAlgorithm;
+import org.apache.xml.security.c14n.Canonicalizer;
+import org.apache.xml.security.keys.KeyInfo;
+import org.apache.xml.security.signature.XMLSignature;
+import org.apache.xml.security.transforms.Transforms;
+import org.apache.xml.security.utils.Constants;
+import org.apache.xml.security.utils.XMLUtils;
+import org.apache.xpath.XPathAPI;
+import org.w3c.dom.Element;
+
+/**
+ * Tests that creates and verifies ECDSA signatures.
+ *
+ * @author Wolfgang Glas
+ */
+public class ECDSASignatureTest extends TestCase {
+
+ /** {@link org.apache.commons.logging} logging facility */
+ private static org.apache.commons.logging.Log log =
+ org.apache.commons.logging.LogFactory.getLog(ECDSASignatureTest.class.getName());
+
+ private static final String BASEDIR = System.getProperty("basedir");
+ private static final String SEP = System.getProperty("file.separator");
+ private static final String ECDSA_JKS =
+ "data/org/apache/xml/security/samples/input/ecdsa.jks";
+ private static final String ECDSA_JKS_PASSWORD = "security";
+
+ private KeyStore keyStore;
+
+ private javax.xml.parsers.DocumentBuilder db;
+
+ private File makeDataFile(String relPath) {
+ if (BASEDIR != null && !"".equals(BASEDIR)) {
+ return new File(BASEDIR + SEP + relPath);
+ } else {
+ return new File(relPath);
+ }
+ }
+
+ public static Test suite() {
+ return new TestSuite(ECDSASignatureTest.class);
+ }
+
+ public ECDSASignatureTest(String name) {
+ super(name);
+ }
+
+ public static void main(String[] args) {
+ String[] testCaseName = {"-noloading", ECDSASignatureTest.class.getName()};
+ junit.textui.TestRunner.main(testCaseName);
+ }
+
+ protected void setUp() throws Exception {
+ //
+ // If the BouncyCastle provider is not installed, then try to load it
+ // via reflection. If it is not available, then skip this test as it is
+ // required for elliptic curves
+ //
+ if (Security.getProvider("BC") == null) {
+ Constructor cons = null;
+ try {
+ Class c = Class.forName("org.bouncycastle.jce.provider.BouncyCastleProvider");
+ cons = c.getConstructor(new Class[] {});
+ } catch (Exception e) {
+ //ignore
+ }
+ if (cons == null) {
+ // BouncyCastle is not available so just return
+ return;
+ } else {
+ Security.addProvider((java.security.Provider)cons.newInstance(new Object[]{}));
+ }
+ }
+
+ javax.xml.parsers.DocumentBuilderFactory dbf =
+ javax.xml.parsers.DocumentBuilderFactory.newInstance();
+ dbf.setNamespaceAware(true);
+ log.info("dbf.isIgnoringComments()=" + dbf.isIgnoringComments());
+ log.info("dbf.isIgnoringElementContentWhitespace()=" + dbf.isIgnoringElementContentWhitespace());
+
+ String id = "http://apache.org/xml/properties/dom/document-class-name";
+
+ dbf.setAttribute(id, IndexedDocument.class.getName());
+
+ db = dbf.newDocumentBuilder();
+ org.apache.xml.security.Init.init();
+ }
+
+ public void testOne() throws Exception {
+ if (Security.getProvider("BC") == null) {
+ return;
+ }
+
+ keyStore = KeyStore.getInstance("JKS");
+ keyStore.load(
+ new java.io.FileInputStream(ECDSA_JKS),
+ ECDSA_JKS_PASSWORD.toCharArray()
+ );
+
+ doVerify(doSign());
+ doVerify(doSign());
+ }
+
+ public void testTwo() throws Exception {
+ if (Security.getProvider("BC") == null) {
+ return;
+ }
+
+ File file =
+ makeDataFile("data/org/apache/xml/security/samples/input/ecdsaSignature.xml");
+ InputStream is = new FileInputStream(file);
+
+ doVerify(is);
+ }
+
+ public void testThree() throws Exception {
+ if (Security.getProvider("BC") == null) {
+ return;
+ }
+
+ File file = makeDataFile("data/at/buergerkarte/testresp.xml");
+ InputStream is = new FileInputStream(file);
+
+ doVerify(is);
+ }
+
+ private byte[] doSign() throws Exception {
+ PrivateKey privateKey =
+ (PrivateKey)keyStore.getKey("ECDSA", ECDSA_JKS_PASSWORD.toCharArray());
+ org.w3c.dom.Document doc = db.newDocument();
+ doc.appendChild(doc.createComment(" Comment before "));
+ Element root = doc.createElementNS("", "RootElement");
+
+ doc.appendChild(root);
+ root.appendChild(doc.createTextNode("Some simple text\n"));
+
+ Element canonElem = XMLUtils.createElementInSignatureSpace(doc,
+ Constants._TAG_CANONICALIZATIONMETHOD);
+ canonElem.setAttributeNS(null, Constants._ATT_ALGORITHM,
+ Canonicalizer.ALGO_ID_C14N_EXCL_OMIT_COMMENTS);
+
+ SignatureAlgorithm signatureAlgorithm = new SignatureAlgorithm(doc,
+ XMLSignature.ALGO_ID_SIGNATURE_ECDSA_SHA1);
+ XMLSignature sig = new XMLSignature(doc, null, signatureAlgorithm
+ .getElement(), canonElem);
+
+ root.appendChild(sig.getElement());
+ doc.appendChild(doc.createComment(" Comment after "));
+ Transforms transforms = new Transforms(doc);
+ transforms.addTransform(Transforms.TRANSFORM_ENVELOPED_SIGNATURE);
+ transforms.addTransform(Transforms.TRANSFORM_C14N_WITH_COMMENTS);
+ sig.addDocument("", transforms, Constants.ALGO_ID_DIGEST_SHA1);
+
+ X509Certificate x509 = (X509Certificate)keyStore.getCertificate("ECDSA");
+ sig.addKeyInfo(x509);
+ sig.sign(privateKey);
+
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+
+ XMLUtils.outputDOMc14nWithComments(doc, bos);
+ return bos.toByteArray();
+ }
+
+ private void doVerify(byte[] signedXml) throws Exception {
+ doVerify(new ByteArrayInputStream(signedXml));
+ }
+
+ private void doVerify(InputStream is) throws Exception {
+ org.w3c.dom.Document doc = this.db.parse(is);
+ Element nscontext = XMLUtils.createDSctx(doc, "ds",Constants.SignatureSpecNS);
+ Element sigElement = (Element) XPathAPI.selectSingleNode(doc,"//ds:Signature[1]", nscontext);
+ XMLSignature signature = new XMLSignature(sigElement, "");
+
+ signature.addResourceResolver(new XPointerResourceResolver(sigElement));
+
+ KeyInfo ki = signature.getKeyInfo();
+
+ if (ki == null) {
+ throw new RuntimeException("No keyinfo");
+ }
+ X509Certificate cert = signature.getKeyInfo().getX509Certificate();
+
+ if (cert == null) {
+ throw new RuntimeException("No certificate");
+ }
+ assertTrue(signature.checkSignatureValue(cert) );
+ }
+
+ /**
+ * DO NOT DELETE THIS COMMENTED OUT METHOD!
+ *
+ * The reason this method is commented out is to avoid introducing explicit
+ * BouncyCastle dependencies.
+ *
+ * Create an X.509 Certificate and associated private key using the Elliptic Curve
+ * DSA algorithm, and store in a KeyStore. This method was used to generate the
+ * keystore used for this test ("data/org/apache/xml/security/samples/input/ecdsa.jks").
+ *
+ private static void setUpKeyAndCertificate() throws Exception {
+
+ java.security.KeyPairGenerator kpg =
+ java.security.KeyPairGenerator.getInstance("ECDSA");
+
+ java.math.BigInteger mod_p =
+ new java.math.BigInteger("115792089237316195423570985008687907853269984665640564039457584007913129639319");
+ java.math.BigInteger mod_q =
+ new java.math.BigInteger("115792089237316195423570985008687907853073762908499243225378155805079068850323");
+
+ org.bouncycastle.math.ec.ECCurve.Fp curve =
+ new org.bouncycastle.math.ec.ECCurve.Fp(
+ mod_p, // p
+ new java.math.BigInteger("115792089237316195423570985008687907853269984665640564039457584007913129639316"), // a
+ new java.math.BigInteger("166")
+ ); // b
+
+ java.security.spec.AlgorithmParameterSpec spec =
+ new org.bouncycastle.jce.spec.ECParameterSpec(
+ curve,
+ new org.bouncycastle.math.ec.ECPoint.Fp(curve,
+ new org.bouncycastle.math.ec.ECFieldElement.Fp(
+ curve.getQ(), new java.math.BigInteger("1")
+ ), // x
+ new org.bouncycastle.math.ec.ECFieldElement.Fp(
+ curve.getQ(), new java.math.BigInteger("64033881142927202683649881450433473985931760268884941288852745803908878638612")
+ )
+ ), // y
+ mod_q
+ );
+
+ kpg.initialize(spec);
+
+ java.security.KeyPair kp=kpg.genKeyPair();
+ org.bouncycastle.x509.X509V3CertificateGenerator certGen =
+ new org.bouncycastle.x509.X509V3CertificateGenerator();
+
+ long now = System.currentTimeMillis();
+ certGen.setSerialNumber(java.math.BigInteger.valueOf(now));
+
+ org.bouncycastle.jce.X509Principal subject =
+ new org.bouncycastle.jce.X509Principal(
+ "CN=XML ECDSA Signature Test,DC=apache,DC=org"
+ );
+ certGen.setIssuerDN(subject);
+ certGen.setSubjectDN(subject);
+
+ java.util.Date from_date = new java.util.Date(now);
+ certGen.setNotBefore(from_date);
+ java.util.Calendar cal = new java.util.GregorianCalendar();
+ cal.setTime(from_date);
+ cal.add(java.util.Calendar.YEAR, 4);
+ java.util.Date to_date = cal.getTime();
+ certGen.setNotAfter(to_date);
+
+ certGen.setPublicKey(kp.getPublic());
+ certGen.setSignatureAlgorithm("SHA1withECDSA");
+ certGen.addExtension(
+ org.bouncycastle.asn1.x509.X509Extensions.BasicConstraints,
+ true,
+ new org.bouncycastle.asn1.x509.BasicConstraints(false)
+ );
+ certGen.addExtension(
+ org.bouncycastle.asn1.x509.X509Extensions.KeyUsage,
+ true,
+ new org.bouncycastle.asn1.x509.KeyUsage(
+ org.bouncycastle.asn1.x509.KeyUsage.digitalSignature |
+ org.bouncycastle.asn1.x509.KeyUsage.keyEncipherment |
+ org.bouncycastle.asn1.x509.KeyUsage.keyCertSign |
+ org.bouncycastle.asn1.x509.KeyUsage.cRLSign
+ )
+ );
+
+ X509Certificate x509 = certGen.generateX509Certificate(kp.getPrivate());
+
+ KeyStore keyStore = KeyStore.getInstance("JKS");
+ keyStore.load(null, ECDSA_JKS_PASSWORD.toCharArray());
+ keyStore.setKeyEntry(
+ "ECDSA", kp.getPrivate(),
+ ECDSA_JKS_PASSWORD.toCharArray(), new java.security.cert.Certificate[]{x509}
+ );
+ keyStore.store(
+ new java.io.FileOutputStream(ECDSA_JKS), ECDSA_JKS_PASSWORD.toCharArray()
+ );
+
+ }
+ */
+
+}
Propchange: xml/security/trunk/src_unitTests/org/apache/xml/security/test/signature/ECDSASignatureTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: xml/security/trunk/src_unitTests/org/apache/xml/security/test/signature/ECDSASignatureTest.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
Added: xml/security/trunk/src_unitTests/org/apache/xml/security/test/signature/IndexedDocument.java
URL: http://svn.apache.org/viewvc/xml/security/trunk/src_unitTests/org/apache/xml/security/test/signature/IndexedDocument.java?rev=793853&view=auto
==============================================================================
--- xml/security/trunk/src_unitTests/org/apache/xml/security/test/signature/IndexedDocument.java (added)
+++ xml/security/trunk/src_unitTests/org/apache/xml/security/test/signature/IndexedDocument.java Tue Jul 14 11:10:03 2009
@@ -0,0 +1,72 @@
+/*
+ * Copyright 1999-2009 The Apache Software Foundation.
+ *
+ * Licensed 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.apache.xml.security.test.signature;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.xerces.dom.DocumentImpl;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+/**
+ * A quick and dirty document implementation, that
+ * implements the getElementById function by looking at "Id" attributes.
+ *
+ * @author wglas
+ */
+public class IndexedDocument extends DocumentImpl
+{
+ private static final long serialVersionUID = -1342041999864449753L;
+
+ private static final String ID_ATTR = "Id";
+
+ private Map idMap;
+
+ private void addToIdMap(Element element)
+ {
+ String id = element.getAttribute(ID_ATTR);
+
+ if (id != null)
+ this.idMap.put(id,element);
+
+ for (Node node = element.getFirstChild(); node != null; node = node.getNextSibling())
+ {
+ if (node instanceof Element)
+ {
+ Element e = (Element) node;
+ this.addToIdMap(e);
+ }
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.xerces.dom.CoreDocumentImpl#getElementById(java.lang.String)
+ */
+ public Element getElementById(String id)
+ {
+ if (this.idMap == null)
+ {
+ this.idMap = new HashMap();
+ this.addToIdMap(this.getDocumentElement());
+ }
+
+ return (Element)this.idMap.get(id);
+ }
+
+}
Propchange: xml/security/trunk/src_unitTests/org/apache/xml/security/test/signature/IndexedDocument.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: xml/security/trunk/src_unitTests/org/apache/xml/security/test/signature/IndexedDocument.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
Added: xml/security/trunk/src_unitTests/org/apache/xml/security/test/signature/XPointerResourceResolver.java
URL: http://svn.apache.org/viewvc/xml/security/trunk/src_unitTests/org/apache/xml/security/test/signature/XPointerResourceResolver.java?rev=793853&view=auto
==============================================================================
--- xml/security/trunk/src_unitTests/org/apache/xml/security/test/signature/XPointerResourceResolver.java (added)
+++ xml/security/trunk/src_unitTests/org/apache/xml/security/test/signature/XPointerResourceResolver.java Tue Jul 14 11:10:03 2009
@@ -0,0 +1,242 @@
+/*
+ * Copyright 1999-2009 The Apache Software Foundation.
+ *
+ * Licensed 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.apache.xml.security.test.signature;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import javax.xml.transform.TransformerException;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.xml.security.signature.XMLSignatureInput;
+import org.apache.xml.security.utils.resolver.ResourceResolverException;
+import org.apache.xml.security.utils.resolver.ResourceResolverSpi;
+import org.apache.xml.utils.PrefixResolverDefault;
+import org.apache.xpath.XPathAPI;
+import org.apache.xpath.axes.NodeSequence;
+import org.apache.xpath.objects.XObject;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+/**
+ * An implementation of a resource resolver, which evaluates xpointer expressions.
+ *
+ * @author wglas
+ */
+public class XPointerResourceResolver extends ResourceResolverSpi
+{
+ private static Log log = LogFactory.getLog(XPointerResourceResolver.class);
+
+ private static final String XP_OPEN = "xpointer(";
+ private static final String XNS_OPEN = "xmlns(";
+
+ private Node baseNode;
+
+ public XPointerResourceResolver(Node baseNode)
+ {
+ this.baseNode = baseNode;
+ }
+
+ private static class XPointerPrefixResolver extends PrefixResolverDefault
+ {
+ private Map extraPrefixes;
+
+ public XPointerPrefixResolver(Node node)
+ {
+ super(node);
+ this.extraPrefixes = new HashMap();
+ }
+
+ public void addExtraPrefix (String pfx, String nsURI)
+ {
+ this.extraPrefixes.put(pfx,nsURI);
+ }
+
+ public String getNamespaceForPrefix(String pfx)
+ {
+ String nsURI = (String)this.extraPrefixes.get(pfx);
+
+ if (nsURI != null) return nsURI;
+
+ return super.getNamespaceForPrefix(pfx);
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.xml.security.utils.resolver.ResourceResolverSpi#engineCanResolve(org.w3c.dom.Attr, java.lang.String)
+ */
+ public boolean engineCanResolve(Attr uri, String BaseURI)
+ {
+ String v = uri.getNodeValue();
+
+ if (v==null || v.length() <= 0) return false;
+
+ if (v.charAt(0) != '#')
+ return false;
+
+ String xpURI;
+ try
+ {
+ xpURI = URLDecoder.decode(v, "utf-8");
+ } catch (UnsupportedEncodingException e)
+ {
+ log.warn("utf-8 not a valid encoding",e);
+ return false;
+ }
+
+ String parts[] = xpURI.substring(1).split("\\s");
+
+ // plain ID reference.
+ if (parts.length == 1 && !parts[0].startsWith(XNS_OPEN))
+ return true;
+
+ int i=0;
+
+ for (;i<parts.length-1;++i)
+ if (!parts[i].endsWith(")") || !parts[i].startsWith(XNS_OPEN))
+ return false;
+
+ if (!parts[i].endsWith(")") || !parts[i].startsWith(XP_OPEN))
+ return false;
+
+ log.debug("xpURI="+xpURI);
+ log.debug("BaseURI="+BaseURI);
+
+ return true;
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.xml.security.utils.resolver.ResourceResolverSpi#engineResolve(org.w3c.dom.Attr, java.lang.String)
+ */
+ public XMLSignatureInput engineResolve(Attr uri, String BaseURI) throws ResourceResolverException
+ {
+ String v = uri.getNodeValue();
+
+ if (v.charAt(0) != '#')
+ return null;
+
+ String xpURI;
+ try
+ {
+ xpURI = URLDecoder.decode(v, "utf-8");
+ } catch (UnsupportedEncodingException e)
+ {
+ log.warn("utf-8 not a valid encoding",e);
+ return null;
+ }
+
+ String parts[] = xpURI.substring(1).split("\\s");
+
+ int i=0;
+
+ XPointerPrefixResolver nsContext=null;
+
+ if (parts.length > 1)
+ {
+ nsContext= new XPointerPrefixResolver(this.baseNode);
+
+ for (;i<parts.length-1;++i)
+ {
+ if (!parts[i].endsWith(")") || !parts[i].startsWith(XNS_OPEN))
+ return null;
+
+ String mapping = parts[i].substring(XNS_OPEN.length(),parts[i].length()-1);
+
+ int pos = mapping.indexOf('=');
+
+ if (pos <= 0 || pos >= mapping.length()-1)
+ throw new ResourceResolverException("malformed namespace part of XPointer expression",uri,BaseURI);
+
+ nsContext.addExtraPrefix(mapping.substring(0,pos),
+ mapping.substring(pos+1));
+ }
+ }
+
+ try
+ {
+ Node node = null;
+ NodeList nodes=null;
+
+ // plain ID reference.
+ if (i==0 && !parts[i].startsWith(XP_OPEN))
+ {
+ node = this.baseNode.getOwnerDocument().getElementById(parts[i]);
+ }
+ else
+ {
+ if (!parts[i].endsWith(")") || !parts[i].startsWith(XP_OPEN))
+ return null;
+
+ String xpathExpr = parts[i].substring(XP_OPEN.length(),parts[i].length()-1);
+
+ XObject xo;
+
+ if (nsContext != null)
+ xo = XPathAPI.eval(this.baseNode, xpathExpr,nsContext);
+ else
+ xo = XPathAPI.eval(this.baseNode, xpathExpr);
+
+
+ if (!(xo instanceof NodeSequence)) return null;
+
+ nodes = ((NodeSequence)xo).nodelist();
+
+ if (nodes.getLength() == 0) return null;
+ if (nodes.getLength() == 1)
+ node = nodes.item(0);
+ }
+
+ XMLSignatureInput result = null;
+
+ if (node != null)
+ {
+ result = new XMLSignatureInput(node);
+ }
+ else if (nodes !=null)
+ {
+ Set nodeSet = new HashSet(nodes.getLength());
+
+ for (int j=0 ; j<nodes.getLength(); ++j)
+ {
+ nodeSet.add(nodes.item(j));
+ }
+
+ result = new XMLSignatureInput(nodeSet);
+ }
+ else
+ return null;
+
+ result.setMIMEType("text/xml");
+ result.setExcludeComments(true);
+ result.setSourceURI((BaseURI != null) ? BaseURI.concat(v):v);
+
+ return result;
+
+ } catch (TransformerException e)
+ {
+ throw new ResourceResolverException("TransformerException inside XPointer expression",e,uri,BaseURI);
+ }
+ }
+
+}
Propchange: xml/security/trunk/src_unitTests/org/apache/xml/security/test/signature/XPointerResourceResolver.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: xml/security/trunk/src_unitTests/org/apache/xml/security/test/signature/XPointerResourceResolver.java
------------------------------------------------------------------------------
svn:keywords = Rev Date