blob: dea5335d29ab3b9ab047d3d8fd7537f09a8b8634 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 2005-2007 Sun Microsystems, Inc. All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
20 * CA 95054 USA or visit www.sun.com if you need additional information or
21 * have any questions.
22 */
23
24/**
25 * @test
26 * @bug 4635230
27 * @bug 6283345
28 * @bug 6303830
29 * @summary Basic unit tests for generating XML Signatures with JSR 105
30 * @compile -XDignore.symbol.file KeySelectors.java SignatureValidator.java
31 * X509KeySelector.java GenerationTests.java
32 * @run main GenerationTests
33 * @author Sean Mullan
34 */
35
36import java.io.*;
37import java.math.BigInteger;
38import java.security.Key;
39import java.security.KeyFactory;
40import java.security.KeyStore;
41import java.security.PrivateKey;
42import java.security.PublicKey;
43import java.security.cert.Certificate;
44import java.security.cert.CertificateFactory;
45import java.security.cert.X509Certificate;
46import java.security.cert.X509CRL;
47import java.security.spec.KeySpec;
48import java.security.spec.DSAPrivateKeySpec;
49import java.security.spec.DSAPublicKeySpec;
50import java.security.spec.RSAPrivateKeySpec;
51import java.security.spec.RSAPublicKeySpec;
52import java.util.*;
53import javax.crypto.SecretKey;
54import javax.xml.XMLConstants;
55import javax.xml.parsers.*;
56import org.w3c.dom.*;
57import javax.xml.crypto.Data;
58import javax.xml.crypto.KeySelector;
59import javax.xml.crypto.OctetStreamData;
60import javax.xml.crypto.URIDereferencer;
61import javax.xml.crypto.URIReference;
62import javax.xml.crypto.URIReferenceException;
63import javax.xml.crypto.XMLCryptoContext;
64import javax.xml.crypto.XMLStructure;
65import javax.xml.crypto.dsig.*;
66import javax.xml.crypto.dom.*;
67import javax.xml.crypto.dsig.dom.DOMSignContext;
68import javax.xml.crypto.dsig.dom.DOMValidateContext;
69import javax.xml.crypto.dsig.keyinfo.*;
70import javax.xml.crypto.dsig.spec.*;
71import javax.xml.transform.*;
72import javax.xml.transform.dom.DOMSource;
73import javax.xml.transform.stream.StreamResult;
74
75/**
76 * Test that recreates merlin-xmldsig-twenty-three test vectors but with
77 * different keys and X.509 data.
78 */
79public class GenerationTests {
80
81 private static XMLSignatureFactory fac;
82 private static KeyInfoFactory kifac;
83 private static DocumentBuilder db;
84 private static CanonicalizationMethod withoutComments;
85 private static SignatureMethod dsaSha1, rsaSha1, rsaSha256, rsaSha384, rsaSha512;
86 private static DigestMethod sha1, sha256, sha384, sha512;
87 private static KeyInfo dsa, rsa, rsa1024;
88 private static KeySelector kvks = new KeySelectors.KeyValueKeySelector();
89 private static KeySelector sks;
90 private static Key signingKey;
91 private static PublicKey validatingKey;
92 private static Certificate signingCert;
93 private static KeyStore ks;
94 private final static String DIR = System.getProperty("test.src", ".");
95 private final static String DATA_DIR =
96 DIR + System.getProperty("file.separator") + "data";
97 private final static String KEYSTORE =
98 DATA_DIR + System.getProperty("file.separator") + "certs" +
99 System.getProperty("file.separator") + "test.jks";
100 private final static String CRL =
101 DATA_DIR + System.getProperty("file.separator") + "certs" +
102 System.getProperty("file.separator") + "crl";
103 private final static String ENVELOPE =
104 DATA_DIR + System.getProperty("file.separator") + "envelope.xml";
105 private static URIDereferencer httpUd = null;
106 private final static String STYLESHEET =
107 "http://www.w3.org/TR/xml-stylesheet";
108 private final static String STYLESHEET_B64 =
109 "http://www.w3.org/Signature/2002/04/xml-stylesheet.b64";
110
111 public static void main(String args[]) throws Exception {
112 setup();
113 test_create_signature_enveloped_dsa();
114 test_create_signature_enveloping_b64_dsa();
115 test_create_signature_enveloping_dsa();
116 test_create_signature_enveloping_hmac_sha1_40();
117 test_create_signature_enveloping_hmac_sha256();
118 test_create_signature_enveloping_hmac_sha384();
119 test_create_signature_enveloping_hmac_sha512();
120 test_create_signature_enveloping_rsa();
121 test_create_signature_external_b64_dsa();
122 test_create_signature_external_dsa();
123 test_create_signature_keyname();
124 test_create_signature_retrievalmethod_rawx509crt();
125 test_create_signature_x509_crt_crl();
126 test_create_signature_x509_crt();
127 test_create_signature_x509_is();
128 test_create_signature_x509_ski();
129 test_create_signature_x509_sn();
130// test_create_signature();
131 test_create_exc_signature();
132 test_create_sign_spec();
133 test_create_signature_enveloping_sha256_dsa();
134 test_create_signature_enveloping_sha384_rsa_sha256();
135 test_create_signature_enveloping_sha512_rsa_sha384();
136 test_create_signature_enveloping_sha512_rsa_sha512();
137 }
138
139 private static void setup() throws Exception {
140 fac = XMLSignatureFactory.getInstance();
141 kifac = fac.getKeyInfoFactory();
142 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
143 dbf.setNamespaceAware(true);
144 db = dbf.newDocumentBuilder();
145
146 // get key & self-signed certificate from keystore
147 FileInputStream fis = new FileInputStream(KEYSTORE);
148 ks = KeyStore.getInstance("JKS");
149 ks.load(fis, "changeit".toCharArray());
150 signingKey = ks.getKey("user", "changeit".toCharArray());
151 signingCert = ks.getCertificate("user");
152 validatingKey = signingCert.getPublicKey();
153
154 // create common objects
155 withoutComments = fac.newCanonicalizationMethod
156 (CanonicalizationMethod.INCLUSIVE, (C14NMethodParameterSpec)null);
157 dsaSha1 = fac.newSignatureMethod(SignatureMethod.DSA_SHA1, null);
158 sha1 = fac.newDigestMethod(DigestMethod.SHA1, null);
159 sha256 = fac.newDigestMethod(DigestMethod.SHA256, null);
160 sha384 = fac.newDigestMethod
161 ("http://www.w3.org/2001/04/xmldsig-more#sha384", null);
162 sha512 = fac.newDigestMethod(DigestMethod.SHA512, null);
163 dsa = kifac.newKeyInfo(Collections.singletonList
164 (kifac.newKeyValue(validatingKey)));
165 rsa = kifac.newKeyInfo(Collections.singletonList
166 (kifac.newKeyValue(getPublicKey("RSA"))));
167 rsa1024 = kifac.newKeyInfo(Collections.singletonList
168 (kifac.newKeyValue(getPublicKey("RSA", 1024))));
169 rsaSha1 = fac.newSignatureMethod(SignatureMethod.RSA_SHA1, null);
170 rsaSha256 = fac.newSignatureMethod
171 ("http://www.w3.org/2001/04/xmldsig-more#rsa-sha256", null);
172 rsaSha384 = fac.newSignatureMethod
173 ("http://www.w3.org/2001/04/xmldsig-more#rsa-sha384", null);
174 rsaSha512 = fac.newSignatureMethod
175 ("http://www.w3.org/2001/04/xmldsig-more#rsa-sha512", null);
176 sks = new KeySelectors.SecretKeySelector("secret".getBytes("ASCII"));
177
178 httpUd = new HttpURIDereferencer();
179 }
180
181 static void test_create_signature_enveloped_dsa() throws Exception {
182 System.out.println("* Generating signature-enveloped-dsa.xml");
183 // create SignedInfo
184 SignedInfo si = fac.newSignedInfo
185 (withoutComments, dsaSha1, Collections.singletonList
186 (fac.newReference
187 ("", sha1, Collections.singletonList
188 (fac.newTransform(Transform.ENVELOPED,
189 (TransformParameterSpec) null)),
190 null, null)));
191
192 // create XMLSignature
193 XMLSignature sig = fac.newXMLSignature(si, dsa);
194
195 Document doc = db.newDocument();
196 Element envelope = doc.createElementNS
197 ("http://example.org/envelope", "Envelope");
198 envelope.setAttributeNS(XMLConstants.XMLNS_ATTRIBUTE_NS_URI,
199 "xmlns", "http://example.org/envelope");
200 doc.appendChild(envelope);
201
202 DOMSignContext dsc = new DOMSignContext(signingKey, envelope);
203
204 sig.sign(dsc);
205
206 DOMValidateContext dvc = new DOMValidateContext
207 (kvks, envelope.getFirstChild());
208 XMLSignature sig2 = fac.unmarshalXMLSignature(dvc);
209
210 if (sig.equals(sig2) == false) {
211 throw new Exception
212 ("Unmarshalled signature is not equal to generated signature");
213 }
214
215 if (sig2.validate(dvc) == false) {
216 throw new Exception("Validation of generated signature failed");
217 }
218 System.out.println();
219 }
220
221 static void test_create_signature_enveloping_b64_dsa() throws Exception {
222 System.out.println("* Generating signature-enveloping-b64-dsa.xml");
223 test_create_signature_enveloping
224 (sha1, dsaSha1, dsa, signingKey, kvks, true);
225 System.out.println();
226 }
227
228 static void test_create_signature_enveloping_dsa() throws Exception {
229 System.out.println("* Generating signature-enveloping-dsa.xml");
230 test_create_signature_enveloping
231 (sha1, dsaSha1, dsa, signingKey, kvks, false);
232 System.out.println();
233 }
234
235 static void test_create_signature_enveloping_sha256_dsa() throws Exception {
236 System.out.println("* Generating signature-enveloping-sha256-dsa.xml");
237 test_create_signature_enveloping
238 (sha256, dsaSha1, dsa, signingKey, kvks, false);
239 System.out.println();
240 }
241
242 static void test_create_signature_enveloping_hmac_sha1_40()
243 throws Exception {
244 System.out.println("* Generating signature-enveloping-hmac-sha1-40.xml");
245 SignatureMethod hmacSha1 = fac.newSignatureMethod
246 (SignatureMethod.HMAC_SHA1, new HMACParameterSpec(40));
247 test_create_signature_enveloping(sha1, hmacSha1, null,
248 getSecretKey("secret".getBytes("ASCII")), sks, false);
249 System.out.println();
250 }
251
252 static void test_create_signature_enveloping_hmac_sha256()
253 throws Exception {
254 System.out.println("* Generating signature-enveloping-hmac-sha256.xml");
255 SignatureMethod hmacSha256 = fac.newSignatureMethod
256 ("http://www.w3.org/2001/04/xmldsig-more#hmac-sha256", null);
257 test_create_signature_enveloping(sha1, hmacSha256, null,
258 getSecretKey("secret".getBytes("ASCII")), sks, false);
259 System.out.println();
260 }
261
262 static void test_create_signature_enveloping_hmac_sha384()
263 throws Exception {
264 System.out.println("* Generating signature-enveloping-hmac-sha384.xml");
265 SignatureMethod hmacSha384 = fac.newSignatureMethod
266 ("http://www.w3.org/2001/04/xmldsig-more#hmac-sha384", null);
267 test_create_signature_enveloping(sha1, hmacSha384, null,
268 getSecretKey("secret".getBytes("ASCII")), sks, false);
269 System.out.println();
270 }
271
272 static void test_create_signature_enveloping_hmac_sha512()
273 throws Exception {
274 System.out.println("* Generating signature-enveloping-hmac-sha512.xml");
275 SignatureMethod hmacSha512 = fac.newSignatureMethod
276 ("http://www.w3.org/2001/04/xmldsig-more#hmac-sha512", null);
277 test_create_signature_enveloping(sha1, hmacSha512, null,
278 getSecretKey("secret".getBytes("ASCII")), sks, false);
279 System.out.println();
280 }
281
282 static void test_create_signature_enveloping_rsa() throws Exception {
283 System.out.println("* Generating signature-enveloping-rsa.xml");
284 test_create_signature_enveloping(sha1, rsaSha1, rsa,
285 getPrivateKey("RSA"), kvks, false);
286 System.out.println();
287 }
288
289 static void test_create_signature_enveloping_sha384_rsa_sha256()
290 throws Exception {
291 System.out.println("* Generating signature-enveloping-sha384-rsa_sha256.xml");
292 test_create_signature_enveloping(sha384, rsaSha256, rsa,
293 getPrivateKey("RSA"), kvks, false);
294 System.out.println();
295 }
296
297 static void test_create_signature_enveloping_sha512_rsa_sha384()
298 throws Exception {
299 System.out.println("* Generating signature-enveloping-sha512-rsa_sha384.xml");
300 test_create_signature_enveloping(sha512, rsaSha384, rsa1024,
301 getPrivateKey("RSA", 1024), kvks, false);
302 System.out.println();
303 }
304
305 static void test_create_signature_enveloping_sha512_rsa_sha512()
306 throws Exception {
307 System.out.println("* Generating signature-enveloping-sha512-rsa_sha512.xml");
308 test_create_signature_enveloping(sha512, rsaSha512, rsa1024,
309 getPrivateKey("RSA", 1024), kvks, false);
310 System.out.println();
311 }
312
313 static void test_create_signature_external_b64_dsa() throws Exception {
314 System.out.println("* Generating signature-external-b64-dsa.xml");
315 test_create_signature_external(dsaSha1, dsa, signingKey, kvks, true);
316 System.out.println();
317 }
318
319 static void test_create_signature_external_dsa() throws Exception {
320 System.out.println("* Generating signature-external-dsa.xml");
321 test_create_signature_external(dsaSha1, dsa, signingKey, kvks, false);
322 System.out.println();
323 }
324
325 static void test_create_signature_keyname() throws Exception {
326 System.out.println("* Generating signature-keyname.xml");
327 KeyInfo kn = kifac.newKeyInfo(Collections.singletonList
328 (kifac.newKeyName("user")));
329 test_create_signature_external(dsaSha1, kn, signingKey,
330 new X509KeySelector(ks), false);
331 System.out.println();
332 }
333
334 static void test_create_signature_retrievalmethod_rawx509crt()
335 throws Exception {
336 System.out.println(
337 "* Generating signature-retrievalmethod-rawx509crt.xml");
338 KeyInfo rm = kifac.newKeyInfo(Collections.singletonList
339 (kifac.newRetrievalMethod
340 ("certs/user.crt", X509Data.RAW_X509_CERTIFICATE_TYPE, null)));
341 test_create_signature_external(dsaSha1, rm, signingKey,
342 new X509KeySelector(ks), false);
343 System.out.println();
344 }
345
346 static void test_create_signature_x509_crt_crl() throws Exception {
347 System.out.println("* Generating signature-x509-crt-crl.xml");
348 List<Object> xds = new ArrayList<Object>();
349 CertificateFactory cf = CertificateFactory.getInstance("X.509");
350 xds.add(signingCert);
351 FileInputStream fis = new FileInputStream(CRL);
352 X509CRL crl = (X509CRL) cf.generateCRL(fis);
353 fis.close();
354 xds.add(crl);
355 KeyInfo crt_crl = kifac.newKeyInfo(Collections.singletonList
356 (kifac.newX509Data(xds)));
357
358 test_create_signature_external(dsaSha1, crt_crl, signingKey,
359 new X509KeySelector(ks), false);
360 System.out.println();
361 }
362
363 static void test_create_signature_x509_crt() throws Exception {
364 System.out.println("* Generating signature-x509-crt.xml");
365 KeyInfo crt = kifac.newKeyInfo(Collections.singletonList
366 (kifac.newX509Data(Collections.singletonList(signingCert))));
367
368 test_create_signature_external(dsaSha1, crt, signingKey,
369 new X509KeySelector(ks), false);
370 System.out.println();
371 }
372
373 static void test_create_signature_x509_is() throws Exception {
374 System.out.println("* Generating signature-x509-is.xml");
375 KeyInfo is = kifac.newKeyInfo(Collections.singletonList
376 (kifac.newX509Data(Collections.singletonList
377 (kifac.newX509IssuerSerial
378 ("CN=User", new BigInteger("45ef2729", 16))))));
379 test_create_signature_external(dsaSha1, is, signingKey,
380 new X509KeySelector(ks), false);
381 System.out.println();
382 }
383
384 static void test_create_signature_x509_ski() throws Exception {
385 System.out.println("* Generating signature-x509-ski.xml");
386 KeyInfo ski = kifac.newKeyInfo(Collections.singletonList
387 (kifac.newX509Data(Collections.singletonList
388 ("keyid".getBytes("ASCII")))));
389
390 test_create_signature_external(dsaSha1, ski, signingKey,
391 KeySelector.singletonKeySelector(validatingKey), false);
392 System.out.println();
393 }
394
395 static void test_create_signature_x509_sn() throws Exception {
396 System.out.println("* Generating signature-x509-sn.xml");
397 KeyInfo sn = kifac.newKeyInfo(Collections.singletonList
398 (kifac.newX509Data(Collections.singletonList("CN=User"))));
399
400 test_create_signature_external(dsaSha1, sn, signingKey,
401 new X509KeySelector(ks), false);
402 System.out.println();
403 }
404
405 static void test_create_signature() throws Exception {
406 System.out.println("* Generating signature.xml");
407
408 // create references
409 List<Reference> refs = new ArrayList<Reference>();
410
411 // Reference 1
412 refs.add(fac.newReference(STYLESHEET, sha1));
413
414 // Reference 2
415 refs.add(fac.newReference
416 (STYLESHEET_B64,
417 sha1, Collections.singletonList
418 (fac.newTransform(Transform.BASE64,
419 (TransformParameterSpec) null)), null, null));
420
421 // Reference 3
422 refs.add(fac.newReference("#object-1", sha1, Collections.singletonList
423 (fac.newTransform(Transform.XPATH,
424 new XPathFilterParameterSpec("self::text()"))),
425 XMLObject.TYPE, null));
426
427 // Reference 4
428 String expr = "\n"
429 + " ancestor-or-self::dsig:SignedInfo " + "\n"
430 + " and " + "\n"
431 + " count(ancestor-or-self::dsig:Reference | " + "\n"
432 + " here()/ancestor::dsig:Reference[1]) > " + "\n"
433 + " count(ancestor-or-self::dsig:Reference) " + "\n"
434 + " or " + "\n"
435 + " count(ancestor-or-self::node() | " + "\n"
436 + " id('notaries')) = " + "\n"
437 + " count(ancestor-or-self::node()) " + "\n";
438
439 XPathFilterParameterSpec xfp = new XPathFilterParameterSpec(expr,
440 Collections.singletonMap("dsig", XMLSignature.XMLNS));
441 refs.add(fac.newReference("", sha1, Collections.singletonList
442 (fac.newTransform(Transform.XPATH, xfp)),
443 XMLObject.TYPE, null));
444
445 // Reference 5
446 refs.add(fac.newReference("#object-2", sha1, Collections.singletonList
447 (fac.newTransform
448 (Transform.BASE64, (TransformParameterSpec) null)),
449 XMLObject.TYPE, null));
450
451 // Reference 6
452 refs.add(fac.newReference
453 ("#manifest-1", sha1, null, Manifest.TYPE, null));
454
455 // Reference 7
456 refs.add(fac.newReference("#signature-properties-1", sha1, null,
457 SignatureProperties.TYPE, null));
458
459 // Reference 8
460 List<Transform> transforms = new ArrayList<Transform>();
461 transforms.add(fac.newTransform
462 (Transform.ENVELOPED, (TransformParameterSpec) null));
463 refs.add(fac.newReference("", sha1, transforms, null, null));
464
465 // Reference 9
466 transforms.add(fac.newTransform
467 (CanonicalizationMethod.INCLUSIVE_WITH_COMMENTS,
468 (TransformParameterSpec) null));
469 refs.add(fac.newReference("", sha1, transforms, null, null));
470
471 // Reference 10
472 Transform env = fac.newTransform
473 (Transform.ENVELOPED, (TransformParameterSpec) null);
474 refs.add(fac.newReference("#xpointer(/)",
475 sha1, Collections.singletonList(env), null, null));
476
477 // Reference 11
478 transforms.clear();
479 transforms.add(fac.newTransform
480 (Transform.ENVELOPED, (TransformParameterSpec) null));
481 transforms.add(fac.newTransform
482 (CanonicalizationMethod.INCLUSIVE_WITH_COMMENTS,
483 (TransformParameterSpec) null));
484 refs.add(fac.newReference("#xpointer(/)", sha1, transforms,
485 null, null));
486
487 // Reference 12
488 refs.add
489 (fac.newReference("#object-3", sha1, null, XMLObject.TYPE, null));
490
491 // Reference 13
492 Transform withComments = fac.newTransform
493 (CanonicalizationMethod.INCLUSIVE_WITH_COMMENTS,
494 (TransformParameterSpec) null);
495 refs.add(fac.newReference("#object-3", sha1,
496 Collections.singletonList(withComments), XMLObject.TYPE, null));
497
498 // Reference 14
499 refs.add(fac.newReference("#xpointer(id('object-3'))", sha1, null,
500 XMLObject.TYPE, null));
501
502 // Reference 15
503 withComments = fac.newTransform
504 (CanonicalizationMethod.INCLUSIVE_WITH_COMMENTS,
505 (TransformParameterSpec) null);
506 refs.add(fac.newReference("#xpointer(id('object-3'))", sha1,
507 Collections.singletonList(withComments), XMLObject.TYPE, null));
508
509 // Reference 16
510 refs.add(fac.newReference("#reference-2", sha1));
511
512 // Reference 17
513 refs.add(fac.newReference("#manifest-reference-1", sha1, null,
514 null, "reference-1"));
515
516 // Reference 18
517 refs.add(fac.newReference("#reference-1", sha1, null, null,
518 "reference-2"));
519
520 // create SignedInfo
521 SignedInfo si = fac.newSignedInfo(withoutComments, dsaSha1, refs);
522
523 // create keyinfo
524 XPathFilterParameterSpec xpf = new XPathFilterParameterSpec(
525 "ancestor-or-self::dsig:X509Data",
526 Collections.singletonMap("dsig", XMLSignature.XMLNS));
527 RetrievalMethod rm = kifac.newRetrievalMethod("#object-4",
528 X509Data.TYPE, Collections.singletonList(fac.newTransform
529 (Transform.XPATH, xpf)));
530 KeyInfo ki = kifac.newKeyInfo(Collections.singletonList(rm), null);
531
532 Document doc = db.newDocument();
533
534 // create objects
535 List<XMLStructure> objs = new ArrayList<XMLStructure>();
536
537 // Object 1
538 objs.add(fac.newXMLObject(Collections.singletonList
539 (new DOMStructure(doc.createTextNode("I am the text."))),
540 "object-1", "text/plain", null));
541
542 // Object 2
543 objs.add(fac.newXMLObject(Collections.singletonList
544 (new DOMStructure(doc.createTextNode("SSBhbSB0aGUgdGV4dC4="))),
545 "object-2", "text/plain", Transform.BASE64));
546
547 // Object 3
548 Element nc = doc.createElementNS(null, "NonCommentandus");
549 nc.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns", "");
550 nc.appendChild(doc.createComment(" Commentandum "));
551 objs.add(fac.newXMLObject(Collections.singletonList
552 (new DOMStructure(nc)), "object-3", null, null));
553
554 // Manifest
555 List<Reference> manRefs = new ArrayList<Reference>();
556
557 // Manifest Reference 1
558 manRefs.add(fac.newReference(STYLESHEET,
559 sha1, null, null, "manifest-reference-1"));
560
561 // Manifest Reference 2
562 manRefs.add(fac.newReference("#reference-1", sha1));
563
564 // Manifest Reference 3
565 List<Transform> manTrans = new ArrayList<Transform>();
566 String xslt = ""
567 + "<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform'\n"
568 + " xmlns='http://www.w3.org/TR/xhtml1/strict' \n"
569 + " exclude-result-prefixes='foo' \n"
570 + " version='1.0'>\n"
571 + " <xsl:output encoding='UTF-8' \n"
572 + " indent='no' \n"
573 + " method='xml' />\n"
574 + " <xsl:template match='/'>\n"
575 + " <html>\n"
576 + " <head>\n"
577 + " <title>Notaries</title>\n"
578 + " </head>\n"
579 + " <body>\n"
580 + " <table>\n"
581 + " <xsl:for-each select='Notaries/Notary'>\n"
582 + " <tr>\n"
583 + " <th>\n"
584 + " <xsl:value-of select='@name' />\n"
585 + " </th>\n"
586 + " </tr>\n"
587 + " </xsl:for-each>\n"
588 + " </table>\n"
589 + " </body>\n"
590 + " </html>\n"
591 + " </xsl:template>\n"
592 + "</xsl:stylesheet>\n";
593 Document docxslt = db.parse(new ByteArrayInputStream(xslt.getBytes()));
594 Node xslElem = docxslt.getDocumentElement();
595
596 manTrans.add(fac.newTransform(Transform.XSLT,
597 new XSLTTransformParameterSpec(new DOMStructure(xslElem))));
598 manTrans.add(fac.newTransform(CanonicalizationMethod.INCLUSIVE,
599 (TransformParameterSpec) null));
600 manRefs.add(fac.newReference("#notaries", sha1, manTrans, null, null));
601
602 objs.add(fac.newXMLObject(Collections.singletonList
603 (fac.newManifest(manRefs, "manifest-1")), null, null, null));
604
605 // SignatureProperties
606 Element sa = doc.createElementNS("urn:demo", "SignerAddress");
607 sa.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns", "urn:demo");
608 Element ip = doc.createElementNS("urn:demo", "IP");
609 ip.appendChild(doc.createTextNode("192.168.21.138"));
610 sa.appendChild(ip);
611 SignatureProperty sp = fac.newSignatureProperty
612 (Collections.singletonList(new DOMStructure(sa)),
613 "#signature", null);
614 SignatureProperties sps = fac.newSignatureProperties
615 (Collections.singletonList(sp), "signature-properties-1");
616 objs.add(fac.newXMLObject(Collections.singletonList(sps), null,
617 null, null));
618
619 // Object 4
620 List<Object> xds = new ArrayList<Object>();
621 xds.add("CN=User");
622 xds.add(kifac.newX509IssuerSerial
623 ("CN=User", new BigInteger("45ef2729", 16)));
624 xds.add(signingCert);
625 objs.add(fac.newXMLObject(Collections.singletonList
626 (kifac.newX509Data(xds)), "object-4", null, null));
627
628 // create XMLSignature
629 XMLSignature sig = fac.newXMLSignature(si, ki, objs, "signature", null);
630
631 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
632 dbf.setNamespaceAware(true);
633 dbf.setValidating(false);
634 Document envDoc = dbf.newDocumentBuilder().parse
635 (new FileInputStream(ENVELOPE));
636 Element ys = (Element)
637 envDoc.getElementsByTagName("YoursSincerely").item(0);
638
639 DOMSignContext dsc = new DOMSignContext(signingKey, ys);
640
641 sig.sign(dsc);
642
643// StringWriter sw = new StringWriter();
644// dumpDocument(envDoc, sw);
645
646 NodeList nl =
647 envDoc.getElementsByTagNameNS(XMLSignature.XMLNS, "Signature");
648 if (nl.getLength() == 0) {
649 throw new Exception("Couldn't find signature Element");
650 }
651 Element sigElement = (Element) nl.item(0);
652
653 DOMValidateContext dvc = new DOMValidateContext
654 (new X509KeySelector(ks), sigElement);
655 File f = new File(
656 System.getProperty("dir.test.vector.baltimore") +
657 System.getProperty("file.separator") +
658 "merlin-xmldsig-twenty-three" +
659 System.getProperty("file.separator"));
660 dvc.setBaseURI(f.toURI().toString());
661
662 XMLSignature sig2 = fac.unmarshalXMLSignature(dvc);
663
664 if (sig.equals(sig2) == false) {
665 throw new Exception
666 ("Unmarshalled signature is not equal to generated signature");
667 }
668 if (sig2.validate(dvc) == false) {
669 throw new Exception("Validation of generated signature failed");
670 }
671 System.out.println();
672 }
673
674 private static void dumpDocument(Document doc, Writer w) throws Exception {
675 TransformerFactory tf = TransformerFactory.newInstance();
676 Transformer trans = tf.newTransformer();
677// trans.setOutputProperty(OutputKeys.INDENT, "yes");
678 trans.transform(new DOMSource(doc), new StreamResult(w));
679 }
680
681 private static void test_create_signature_external
682 (SignatureMethod sm, KeyInfo ki, Key signingKey, KeySelector ks,
683 boolean b64) throws Exception {
684
685 // create reference
686 Reference ref;
687 if (b64) {
688 ref = fac.newReference
689 (STYLESHEET_B64,
690 sha1, Collections.singletonList
691 (fac.newTransform(Transform.BASE64,
692 (TransformParameterSpec) null)), null, null);
693 } else {
694 ref = fac.newReference(STYLESHEET, sha1);
695 }
696
697 // create SignedInfo
698 SignedInfo si = fac.newSignedInfo(withoutComments, sm,
699 Collections.singletonList(ref));
700
701 Document doc = db.newDocument();
702
703 // create XMLSignature
704 XMLSignature sig = fac.newXMLSignature(si, ki);
705
706 DOMSignContext dsc = new DOMSignContext(signingKey, doc);
707 dsc.setURIDereferencer(httpUd);
708
709 sig.sign(dsc);
710
711 DOMValidateContext dvc = new DOMValidateContext
712 (ks, doc.getDocumentElement());
713 File f = new File(DATA_DIR);
714 dvc.setBaseURI(f.toURI().toString());
715 dvc.setURIDereferencer(httpUd);
716
717 XMLSignature sig2 = fac.unmarshalXMLSignature(dvc);
718
719 if (sig.equals(sig2) == false) {
720 throw new Exception
721 ("Unmarshalled signature is not equal to generated signature");
722 }
723 if (sig2.validate(dvc) == false) {
724 throw new Exception("Validation of generated signature failed");
725 }
726 }
727
728 private static void test_create_signature_enveloping
729 (DigestMethod dm, SignatureMethod sm, KeyInfo ki, Key signingKey,
730 KeySelector ks, boolean b64) throws Exception {
731
732 // create reference
733 Reference ref;
734 if (b64) {
735 ref = fac.newReference("#object", dm, Collections.singletonList
736 (fac.newTransform(Transform.BASE64,
737 (TransformParameterSpec) null)), null, null);
738 } else {
739 ref = fac.newReference("#object", dm);
740 }
741
742 // create SignedInfo
743 SignedInfo si = fac.newSignedInfo(withoutComments, sm,
744 Collections.singletonList(ref));
745
746 Document doc = db.newDocument();
747 // create Objects
748 String text = b64 ? "c29tZSB0ZXh0" : "some text";
749 XMLObject obj = fac.newXMLObject(Collections.singletonList
750 (new DOMStructure(doc.createTextNode(text))),
751 "object", null, null);
752
753 // create XMLSignature
754 XMLSignature sig = fac.newXMLSignature
755 (si, ki, Collections.singletonList(obj), null, null);
756
757 DOMSignContext dsc = new DOMSignContext(signingKey, doc);
758
759 sig.sign(dsc);
760
761// dumpDocument(doc, new FileWriter("/tmp/foo.xml"));
762
763 DOMValidateContext dvc = new DOMValidateContext
764 (ks, doc.getDocumentElement());
765 XMLSignature sig2 = fac.unmarshalXMLSignature(dvc);
766
767 if (sig.equals(sig2) == false) {
768 throw new Exception
769 ("Unmarshalled signature is not equal to generated signature");
770 }
771 if (sig2.validate(dvc) == false) {
772 throw new Exception("Validation of generated signature failed");
773 }
774 }
775
776 static void test_create_exc_signature() throws Exception {
777 System.out.println("* Generating exc_signature.xml");
778 List<Reference> refs = new ArrayList<Reference>(4);
779
780 // create reference 1
781 refs.add(fac.newReference
782 ("#xpointer(id('to-be-signed'))",
783 fac.newDigestMethod(DigestMethod.SHA1, null),
784 Collections.singletonList
785 (fac.newTransform(CanonicalizationMethod.EXCLUSIVE,
786 (TransformParameterSpec) null)),
787 null, null));
788
789 // create reference 2
790 List<String> prefixList = new ArrayList<String>(2);
791 prefixList.add("bar");
792 prefixList.add("#default");
793 ExcC14NParameterSpec params = new ExcC14NParameterSpec(prefixList);
794 refs.add(fac.newReference
795 ("#xpointer(id('to-be-signed'))",
796 fac.newDigestMethod(DigestMethod.SHA1, null),
797 Collections.singletonList
798 (fac.newTransform(CanonicalizationMethod.EXCLUSIVE, params)),
799 null, null));
800
801 // create reference 3
802 refs.add(fac.newReference
803 ("#xpointer(id('to-be-signed'))",
804 fac.newDigestMethod(DigestMethod.SHA1, null),
805 Collections.singletonList(fac.newTransform
806 (CanonicalizationMethod.EXCLUSIVE_WITH_COMMENTS,
807 (TransformParameterSpec) null)),
808 null, null));
809
810 // create reference 4
811 prefixList = new ArrayList<String>(2);
812 prefixList.add("bar");
813 prefixList.add("#default");
814 params = new ExcC14NParameterSpec(prefixList);
815 refs.add(fac.newReference
816 ("#xpointer(id('to-be-signed'))",
817 fac.newDigestMethod(DigestMethod.SHA1, null),
818 Collections.singletonList(fac.newTransform
819 (CanonicalizationMethod.EXCLUSIVE_WITH_COMMENTS, params)),
820 null, null));
821
822 // create SignedInfo
823 SignedInfo si = fac.newSignedInfo(
824 fac.newCanonicalizationMethod
825 (CanonicalizationMethod.EXCLUSIVE,
826 (C14NMethodParameterSpec) null),
827 fac.newSignatureMethod(SignatureMethod.DSA_SHA1, null), refs);
828
829 // create KeyInfo
830 List<XMLStructure> kits = new ArrayList<XMLStructure>(2);
831 kits.add(kifac.newKeyValue(validatingKey));
832 KeyInfo ki = kifac.newKeyInfo(kits);
833
834 // create Objects
835 Document doc = db.newDocument();
836 Element baz = doc.createElementNS("urn:bar", "bar:Baz");
837 Comment com = doc.createComment(" comment ");
838 baz.appendChild(com);
839 XMLObject obj = fac.newXMLObject(Collections.singletonList
840 (new DOMStructure(baz)), "to-be-signed", null, null);
841
842 // create XMLSignature
843 XMLSignature sig = fac.newXMLSignature
844 (si, ki, Collections.singletonList(obj), null, null);
845
846 Element foo = doc.createElementNS("urn:foo", "Foo");
847 foo.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns", "urn:foo");
848 foo.setAttributeNS
849 ("http://www.w3.org/2000/xmlns/", "xmlns:bar", "urn:bar");
850 doc.appendChild(foo);
851
852 DOMSignContext dsc = new DOMSignContext(signingKey, foo);
853 dsc.putNamespacePrefix(XMLSignature.XMLNS, "dsig");
854
855 sig.sign(dsc);
856
857// dumpDocument(doc, new FileWriter("/tmp/foo.xml"));
858
859 DOMValidateContext dvc = new DOMValidateContext
860 (new KeySelectors.KeyValueKeySelector(), foo.getLastChild());
861 XMLSignature sig2 = fac.unmarshalXMLSignature(dvc);
862
863 if (sig.equals(sig2) == false) {
864 throw new Exception
865 ("Unmarshalled signature is not equal to generated signature");
866 }
867 if (sig2.validate(dvc) == false) {
868 throw new Exception("Validation of generated signature failed");
869 }
870 System.out.println();
871 }
872
873 static void test_create_sign_spec() throws Exception {
874 System.out.println("* Generating sign-spec.xml");
875 List<Reference> refs = new ArrayList<Reference>(2);
876
877 // create reference 1
878 List<XPathType> types = new ArrayList<XPathType>(3);
879 types.add(new XPathType(" //ToBeSigned ", XPathType.Filter.INTERSECT));
880 types.add(new XPathType(" //NotToBeSigned ",
881 XPathType.Filter.SUBTRACT));
882 types.add(new XPathType(" //ReallyToBeSigned ",
883 XPathType.Filter.UNION));
884 XPathFilter2ParameterSpec xp1 = new XPathFilter2ParameterSpec(types);
885 refs.add(fac.newReference
886 ("", fac.newDigestMethod(DigestMethod.SHA1, null),
887 Collections.singletonList(fac.newTransform(Transform.XPATH2, xp1)),
888 null, null));
889
890 // create reference 2
891 List<Transform> trans2 = new ArrayList<Transform>(2);
892 trans2.add(fac.newTransform(Transform.ENVELOPED,
893 (TransformParameterSpec) null));
894 XPathFilter2ParameterSpec xp2 = new XPathFilter2ParameterSpec
895 (Collections.singletonList
896 (new XPathType(" / ", XPathType.Filter.UNION)));
897 trans2.add(fac.newTransform(Transform.XPATH2, xp2));
898 refs.add(fac.newReference("#signature-value",
899 fac.newDigestMethod(DigestMethod.SHA1, null), trans2, null, null));
900
901 // create SignedInfo
902 SignedInfo si = fac.newSignedInfo(
903 fac.newCanonicalizationMethod
904 (CanonicalizationMethod.INCLUSIVE,
905 (C14NMethodParameterSpec) null),
906 fac.newSignatureMethod(SignatureMethod.DSA_SHA1, null), refs);
907
908 // create KeyInfo
909 List<XMLStructure> kits = new ArrayList<XMLStructure>(2);
910 kits.add(kifac.newKeyValue(validatingKey));
911 List<Object> xds = new ArrayList<Object>(2);
912 xds.add("CN=User");
913 xds.add(signingCert);
914 kits.add(kifac.newX509Data(xds));
915 KeyInfo ki = kifac.newKeyInfo(kits);
916
917 // create XMLSignature
918 XMLSignature sig = fac.newXMLSignature
919 (si, ki, null, null, "signature-value");
920
921 Document doc = db.newDocument();
922 Element tbs1 = doc.createElementNS(null, "ToBeSigned");
923 Comment tbs1Com = doc.createComment(" comment ");
924 Element tbs1Data = doc.createElementNS(null, "Data");
925 Element tbs1ntbs = doc.createElementNS(null, "NotToBeSigned");
926 Element tbs1rtbs = doc.createElementNS(null, "ReallyToBeSigned");
927 Comment tbs1rtbsCom = doc.createComment(" comment ");
928 Element tbs1rtbsData = doc.createElementNS(null, "Data");
929 tbs1rtbs.appendChild(tbs1rtbsCom);
930 tbs1rtbs.appendChild(tbs1rtbsData);
931 tbs1ntbs.appendChild(tbs1rtbs);
932 tbs1.appendChild(tbs1Com);
933 tbs1.appendChild(tbs1Data);
934 tbs1.appendChild(tbs1ntbs);
935
936 Element tbs2 = doc.createElementNS(null, "ToBeSigned");
937 Element tbs2Data = doc.createElementNS(null, "Data");
938 Element tbs2ntbs = doc.createElementNS(null, "NotToBeSigned");
939 Element tbs2ntbsData = doc.createElementNS(null, "Data");
940 tbs2ntbs.appendChild(tbs2ntbsData);
941 tbs2.appendChild(tbs2Data);
942 tbs2.appendChild(tbs2ntbs);
943
944 Element document = doc.createElementNS(null, "Document");
945 document.appendChild(tbs1);
946 document.appendChild(tbs2);
947 doc.appendChild(document);
948
949 DOMSignContext dsc = new DOMSignContext(signingKey, document);
950
951 sig.sign(dsc);
952
953// dumpDocument(doc, new FileWriter("/tmp/foo.xml"));
954
955 DOMValidateContext dvc = new DOMValidateContext
956 (new KeySelectors.KeyValueKeySelector(), document.getLastChild());
957 XMLSignature sig2 = fac.unmarshalXMLSignature(dvc);
958
959 if (sig.equals(sig2) == false) {
960 throw new Exception
961 ("Unmarshalled signature is not equal to generated signature");
962 }
963 if (sig2.validate(dvc) == false) {
964 throw new Exception("Validation of generated signature failed");
965 }
966 System.out.println();
967 }
968
969 private static final String DSA_Y =
970 "070662842167565771936588335128634396171789331656318483584455493822" +
971 "400811200853331373030669235424928346190274044631949560438023934623" +
972 "71310375123430985057160";
973 private static final String DSA_P =
974 "013232376895198612407547930718267435757728527029623408872245156039" +
975 "757713029036368719146452186041204237350521785240337048752071462798" +
976 "273003935646236777459223";
977 private static final String DSA_Q =
978 "0857393771208094202104259627990318636601332086981";
979 private static final String DSA_G =
980 "054216440574364751416096484883257051280474283943804743768346673007" +
981 "661082626139005426812890807137245973106730741193551360857959820973" +
982 "90670890367185141189796";
983 private static final String DSA_X =
984 "0527140396812450214498055937934275626078768840117";
985 private static final String RSA_MOD =
986 "010800185049102889923150759252557522305032794699952150943573164381" +
987 "936603255999071981574575044810461362008102247767482738822150129277" +
988 "490998033971789476107463";
989 private static final String RSA_PRIV =
990 "016116973584421969795445996229612671947635798429212816611707210835" +
991 "915586591340598683996088487065438751488342251960069575392056288063" +
992 "6800379454345804879553";
993 private static final String RSA_PUB = "065537";
994 private static final String RSA_1024_MOD = "098871307553789439961130765" +
995 "909423744508062468450669519128736624058048856940468016843888594585" +
996 "322862378444314635412341974900625010364163960238734457710620107530" +
997 "573945081856371709138380902553309075505688814637544923038853658690" +
998 "857672483016239697038853418682988686871489963827000080098971762923" +
999 "833614557257607521";
1000 private static final String RSA_1024_PRIV = "03682574144968491431483287" +
1001 "297021581096848810374110568017963075809477047466189822987258068867" +
1002 "704855380407747867998863645890602646601140183818953428006646987710" +
1003 "237008997971129772408397621801631622129297063463868593083106979716" +
1004 "204903524890556839550490384015324575598723478554854070823335021842" +
1005 "210112348400928769";
1006
1007 private static PublicKey getPublicKey(String algo) throws Exception {
1008 return getPublicKey(algo, 512);
1009 }
1010
1011 private static PublicKey getPublicKey(String algo, int keysize)
1012 throws Exception {
1013 KeyFactory kf = KeyFactory.getInstance(algo);
1014 KeySpec kspec;
1015 if (algo.equalsIgnoreCase("DSA")) {
1016 kspec = new DSAPublicKeySpec(new BigInteger(DSA_Y),
1017 new BigInteger(DSA_P),
1018 new BigInteger(DSA_Q),
1019 new BigInteger(DSA_G));
1020 } else if (algo.equalsIgnoreCase("RSA")) {
1021 if (keysize == 512) {
1022 kspec = new RSAPublicKeySpec(new BigInteger(RSA_MOD),
1023 new BigInteger(RSA_PUB));
1024 } else {
1025 kspec = new RSAPublicKeySpec(new BigInteger(RSA_1024_MOD),
1026 new BigInteger(RSA_PUB));
1027 }
1028 } else throw new RuntimeException("Unsupported key algorithm " + algo);
1029 return kf.generatePublic(kspec);
1030 }
1031
1032 private static PrivateKey getPrivateKey(String algo) throws Exception {
1033 return getPrivateKey(algo, 512);
1034 }
1035
1036 private static PrivateKey getPrivateKey(String algo, int keysize)
1037 throws Exception {
1038 KeyFactory kf = KeyFactory.getInstance(algo);
1039 KeySpec kspec;
1040 if (algo.equalsIgnoreCase("DSA")) {
1041 kspec = new DSAPrivateKeySpec
1042 (new BigInteger(DSA_X), new BigInteger(DSA_P),
1043 new BigInteger(DSA_Q), new BigInteger(DSA_G));
1044 } else if (algo.equalsIgnoreCase("RSA")) {
1045 if (keysize == 512) {
1046 kspec = new RSAPrivateKeySpec
1047 (new BigInteger(RSA_MOD), new BigInteger(RSA_PRIV));
1048 } else {
1049 kspec = new RSAPrivateKeySpec(new BigInteger(RSA_1024_MOD),
1050 new BigInteger(RSA_1024_PRIV));
1051 }
1052 } else throw new RuntimeException("Unsupported key algorithm " + algo);
1053 return kf.generatePrivate(kspec);
1054 }
1055
1056 private static SecretKey getSecretKey(final byte[] secret) {
1057 return new SecretKey() {
1058 public String getFormat() { return "RAW"; }
1059 public byte[] getEncoded() { return secret; }
1060 public String getAlgorithm(){ return "SECRET"; }
1061 };
1062 }
1063
1064 /**
1065 * This URIDereferencer returns locally cached copies of http content to
1066 * avoid test failures due to network glitches, etc.
1067 */
1068 private static class HttpURIDereferencer implements URIDereferencer {
1069 private URIDereferencer defaultUd;
1070
1071 HttpURIDereferencer() {
1072 defaultUd = XMLSignatureFactory.getInstance().getURIDereferencer();
1073 }
1074
1075 public Data dereference(final URIReference ref, XMLCryptoContext ctx)
1076 throws URIReferenceException {
1077 String uri = ref.getURI();
1078 if (uri.equals(STYLESHEET) || uri.equals(STYLESHEET_B64)) {
1079 try {
1080 FileInputStream fis = new FileInputStream(new File
1081 (DATA_DIR, uri.substring(uri.lastIndexOf('/'))));
1082 return new OctetStreamData(fis,ref.getURI(),ref.getType());
1083 } catch (Exception e) { throw new URIReferenceException(e); }
1084 }
1085
1086 // fallback on builtin deref
1087 return defaultUd.dereference(ref, ctx);
1088 }
1089 }
1090}