1 /*
2  * Copyright (c) 2005, 2019, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20  * or visit www.oracle.com if you need additional information or have any
21  * questions.
22  */
23 
24 /**
25  * @test
26  * @bug 4635230 6283345 6303830 6824440 6867348 7094155 8038184 8038349 8046949
27  *      8046724 8079693 8177334 8205507 8210736 8217878
28  * @summary Basic unit tests for generating XML Signatures with JSR 105
29  * @modules java.base/sun.security.util
30  *          java.base/sun.security.x509
31  *          java.xml.crypto/org.jcp.xml.dsig.internal.dom
32  *          jdk.httpserver/com.sun.net.httpserver
33  * @compile -XDignore.symbol.file KeySelectors.java SignatureValidator.java
34  *     X509KeySelector.java GenerationTests.java
35  * @run main/othervm/timeout=300 -Dsun.net.httpserver.nodelay=true GenerationTests
36  * @author Sean Mullan
37  */
38 
39 import com.sun.net.httpserver.HttpExchange;
40 import com.sun.net.httpserver.HttpHandler;
41 import com.sun.net.httpserver.HttpServer;
42 import java.io.*;
43 import java.lang.reflect.Modifier;
44 import java.math.BigInteger;
45 import java.net.InetSocketAddress;
46 import java.security.Key;
47 import java.security.KeyFactory;
48 import java.security.KeyPair;
49 import java.security.KeyPairGenerator;
50 import java.security.KeyStore;
51 import java.security.NoSuchAlgorithmException;
52 import java.security.PrivateKey;
53 import java.security.PublicKey;
54 import java.security.SecureRandom;
55 import java.security.cert.Certificate;
56 import java.security.cert.CertificateFactory;
57 import java.security.cert.X509CRL;
58 import java.security.spec.KeySpec;
59 import java.security.spec.DSAPrivateKeySpec;
60 import java.security.spec.DSAPublicKeySpec;
61 import java.security.spec.ECField;
62 import java.security.spec.ECFieldFp;
63 import java.security.spec.ECParameterSpec;
64 import java.security.spec.ECPoint;
65 import java.security.spec.ECPrivateKeySpec;
66 import java.security.spec.ECPublicKeySpec;
67 import java.security.spec.EllipticCurve;
68 import java.security.spec.RSAPrivateKeySpec;
69 import java.security.spec.RSAPublicKeySpec;
70 import java.util.*;
71 import java.util.stream.Stream;
72 import javax.crypto.KeyGenerator;
73 import javax.crypto.SecretKey;
74 import javax.xml.XMLConstants;
75 import javax.xml.parsers.*;
76 import javax.xml.crypto.Data;
77 import javax.xml.crypto.KeySelector;
78 import javax.xml.crypto.OctetStreamData;
79 import javax.xml.crypto.URIDereferencer;
80 import javax.xml.crypto.URIReference;
81 import javax.xml.crypto.URIReferenceException;
82 import javax.xml.crypto.XMLCryptoContext;
83 import javax.xml.crypto.XMLStructure;
84 import javax.xml.crypto.dsig.*;
85 import javax.xml.crypto.dom.*;
86 import javax.xml.crypto.dsig.dom.DOMSignContext;
87 import javax.xml.crypto.dsig.dom.DOMValidateContext;
88 import javax.xml.crypto.dsig.keyinfo.*;
89 import javax.xml.crypto.dsig.spec.*;
90 import javax.xml.transform.*;
91 import javax.xml.transform.dom.DOMSource;
92 import javax.xml.transform.stream.StreamResult;
93 import org.w3c.dom.*;
94 
95 /**
96  * Test that recreates merlin-xmldsig-twenty-three test vectors (and more)
97  * but with different keys and X.509 data.
98  */
99 public class GenerationTests {
100 
101     private static XMLSignatureFactory fac;
102     private static KeyInfoFactory kifac;
103     private static DocumentBuilder db;
104     private static CanonicalizationMethod withoutComments;
105     private static SignatureMethod dsaSha1, dsaSha256,
106             rsaSha1, rsaSha224, rsaSha256, rsaSha384, rsaSha512,
107             ecdsaSha1, ecdsaSha224, ecdsaSha256, ecdsaSha384, ecdsaSha512,
108             hmacSha1, hmacSha224, hmacSha256, hmacSha384, hmacSha512,
109             rsaSha1mgf1, rsaSha224mgf1, rsaSha256mgf1, rsaSha384mgf1, rsaSha512mgf1;
110     private static DigestMethod sha1, sha224, sha256, sha384, sha512,
111                                 sha3_224, sha3_256, sha3_384, sha3_512;
112     private static KeyInfo dsa1024, dsa2048, rsa, rsa1024, rsa2048,
113                            p256ki, p384ki, p521ki;
114     private static KeySelector kvks = new KeySelectors.KeyValueKeySelector();
115     private static KeySelector sks;
116     private static Key signingKey;
117     private static PublicKey validatingKey;
118     private static Certificate signingCert;
119     private static KeyStore ks;
120     private final static String DIR = System.getProperty("test.src", ".");
121 //    private final static String DIR = ".";
122     private final static String DATA_DIR =
123         DIR + System.getProperty("file.separator") + "data";
124     private final static String KEYSTORE =
125         DATA_DIR + System.getProperty("file.separator") + "certs" +
126         System.getProperty("file.separator") + "test.jks";
127     private final static String CRL =
128         DATA_DIR + System.getProperty("file.separator") + "certs" +
129         System.getProperty("file.separator") + "crl";
130     // XML Document with a DOCTYPE declaration
131     private final static String ENVELOPE =
132         DATA_DIR + System.getProperty("file.separator") + "envelope.xml";
133     // XML Document without a DOCTYPE declaration
134     private final static String ENVELOPE2 =
135         DATA_DIR + System.getProperty("file.separator") + "envelope2.xml";
136     private static URIDereferencer httpUd = null;
137     private final static String STYLESHEET =
138         "http://www.w3.org/TR/xml-stylesheet";
139     private final static String STYLESHEET_B64 =
140         "http://www.w3.org/Signature/2002/04/xml-stylesheet.b64";
141     private final static String DSA_SHA256 =
142         "http://www.w3.org/2009/xmldsig11#dsa-sha256";
143 
144     private static final String BOGUS = "bogus";
145 
146     private static final  String xslt = ""
147           + "<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform'\n"
148           + "            xmlns='http://www.w3.org/TR/xhtml1/strict' \n"
149           + "            exclude-result-prefixes='foo' \n"
150           + "            version='1.0'>\n"
151           + "  <xsl:output encoding='UTF-8' \n"
152           + "           indent='no' \n"
153           + "           method='xml' />\n"
154           + "  <xsl:template match='/'>\n"
155           + "    <html>\n"
156           + "   <head>\n"
157           + "    <title>Notaries</title>\n"
158           + "   </head>\n"
159           + "   <body>\n"
160           + "    <table>\n"
161           + "      <xsl:for-each select='Notaries/Notary'>\n"
162           + "           <tr>\n"
163           + "           <th>\n"
164           + "            <xsl:value-of select='@name' />\n"
165           + "           </th>\n"
166           + "           </tr>\n"
167           + "      </xsl:for-each>\n"
168           + "    </table>\n"
169           + "   </body>\n"
170           + "    </html>\n"
171           + "  </xsl:template>\n"
172           + "</xsl:stylesheet>\n";
173 
174     private static final String[] canonicalizationMethods = new String[] {
175         CanonicalizationMethod.EXCLUSIVE,
176         CanonicalizationMethod.EXCLUSIVE_WITH_COMMENTS,
177         CanonicalizationMethod.INCLUSIVE,
178         CanonicalizationMethod.INCLUSIVE_WITH_COMMENTS
179     };
180 
181     private static final String[] xml_transforms = new String[] {
182         Transform.XSLT,
183         Transform.XPATH,
184         Transform.XPATH2,
185         CanonicalizationMethod.EXCLUSIVE,
186         CanonicalizationMethod.EXCLUSIVE_WITH_COMMENTS,
187         CanonicalizationMethod.INCLUSIVE,
188         CanonicalizationMethod.INCLUSIVE_WITH_COMMENTS,
189     };
190 
191     private static final String[] non_xml_transforms = new String[] {
192         null, Transform.BASE64
193     };
194 
195     // It will be too time consuming to test all combinations of
196     // all digest methods and signature methods. So we pick some
197     // majors one and only test a combination when a major method
198     // (either digest or signature) is included.
199     //
200     //              *  *  *
201     //              *  *  *
202     //              *  *  *
203     //     *  *  *  *  *  *  *  *  *
204     //     *  *  *  *  *  *  *  *  *
205     //     *  *  *  *  *  *  *  *  *
206     //              *  *  *
207     //              *  *  *
208     //              *  *  *
209 
210     private static List<String> majorSignatureMethods = List.of(
211             SignatureMethod.DSA_SHA256,
212             SignatureMethod.RSA_SHA256,
213             SignatureMethod.ECDSA_SHA256,
214             SignatureMethod.HMAC_SHA256,
215             SignatureMethod.SHA256_RSA_MGF1);
216 
217     private static final String[] allSignatureMethods
218             = Stream.of(SignatureMethod.class.getDeclaredFields())
219                 .filter(f -> Modifier.isStatic(f.getModifiers()))
220                 .map(f -> {
221                     try {
222                         return (String)f.get(null);
223                     } catch (Exception e) {
224                         throw new Error("should not happen");
225                     }
226                 })
227                 .toArray(String[]::new);
228 
229     private static final List<String> majorDigestMethods = List.of(
230             DigestMethod.SHA1,
231             DigestMethod.SHA256,
232             DigestMethod.SHA3_256);
233 
234     private static final String[] allDigestMethods
235             = Stream.of(DigestMethod.class.getDeclaredFields())
236                 .filter(f -> Modifier.isStatic(f.getModifiers())
237                                 && !f.getName().equals("RIPEMD160"))
238                 .map(f -> {
239                     try {
240                         return (String)f.get(null);
241                     } catch (Exception e) {
242                         throw new Error("should not happen");
243                     }
244                 })
245                 .toArray(String[]::new);
246 
247     // As of JDK 11, the number of defined algorithms are...
248     static {
249         if (allSignatureMethods.length != 22
250                 || allDigestMethods.length != 9) {
Arrays.toString(allSignatureMethods)251             System.out.println(Arrays.toString(allSignatureMethods));
Arrays.toString(allDigestMethods)252             System.out.println(Arrays.toString(allDigestMethods));
253             throw new AssertionError("Not all methods are counted");
254         }
255     }
256 
257     private static enum Content {
258         Xml, Text, Base64, NotExisitng
259     }
260 
261     private static enum KeyInfoType {
262         KeyValue, x509data, KeyName
263     }
264 
265     // cached keys (for performance) used by test_create_detached_signature().
266     private static HashMap<String,Key[]> cachedKeys = new HashMap<>();
267 
268     // Load cachedKeys persisted in a file to reproduce a failure.
269     // The keys are always saved to "cached-keys" but you can rename
270     // it to a different file name and load it here. Note: The keys will
271     // always be persisted so renaming is a good idea although the
272     // content might not change.
273     static {
274         String cacheFile = System.getProperty("use.cached.keys");
275         if (cacheFile != null) {
try(FileInputStream fis = new FileInputStream(cacheFile); ObjectInputStream ois = new ObjectInputStream(fis))276             try (FileInputStream fis = new FileInputStream(cacheFile);
277                  ObjectInputStream ois = new ObjectInputStream(fis)) {
278                 cachedKeys = (HashMap<String,Key[]>) ois.readObject();
279             } catch (Exception e) {
280                 throw new AssertionError("Cannot read " + cacheFile, e);
281             }
282         }
283     }
284 
285     private static boolean result = true;
286 
main(String args[])287     public static void main(String args[]) throws Exception {
288         setup();
289         test_create_signature_enveloped_dsa(1024);
290         test_create_signature_enveloped_dsa(2048);
291         test_create_signature_enveloping_b64_dsa();
292         test_create_signature_enveloping_dsa();
293         test_create_signature_enveloping_hmac_sha1_40();
294         test_create_signature_enveloping_hmac_sha256();
295         test_create_signature_enveloping_hmac_sha224();
296         test_create_signature_enveloping_hmac_sha384();
297         test_create_signature_enveloping_hmac_sha512();
298         test_create_signature_enveloping_rsa();
299         test_create_signature_enveloping_p256_sha1();
300         test_create_signature_enveloping_p256_sha224();
301         test_create_signature_enveloping_p256_sha256();
302         test_create_signature_enveloping_p256_sha384();
303         test_create_signature_enveloping_p256_sha512();
304         test_create_signature_enveloping_p384_sha1();
305         test_create_signature_enveloping_p521_sha1();
306         test_create_signature_external_b64_dsa();
307         test_create_signature_external_dsa();
308         test_create_signature_keyname();
309         test_create_signature_retrievalmethod_rawx509crt();
310         test_create_signature_x509_crt_crl();
311         test_create_signature_x509_crt();
312         test_create_signature_x509_is();
313         test_create_signature_x509_ski();
314         test_create_signature_x509_sn();
315         test_create_signature();
316         test_create_exc_signature();
317         test_create_sign_spec();
318         test_create_signature_enveloping_sha256_dsa();
319         test_create_signature_enveloping_sha384_rsa_sha256();
320         test_create_signature_enveloping_sha224_rsa_sha256();
321         test_create_signature_enveloping_sha3_224_rsa_sha256();
322         test_create_signature_enveloping_sha3_256_rsa_sha256();
323         test_create_signature_enveloping_sha3_384_rsa_sha256();
324         test_create_signature_enveloping_sha3_512_rsa_sha256();
325         test_create_signature_enveloping_sha512_rsa_sha384();
326         test_create_signature_enveloping_sha512_rsa_sha224();
327         test_create_signature_enveloping_sha512_rsa_sha512();
328         test_create_signature_enveloping_sha512_rsa_sha1_mgf1();
329         test_create_signature_enveloping_sha512_rsa_sha224_mgf1();
330         test_create_signature_enveloping_sha512_rsa_sha256_mgf1();
331         test_create_signature_enveloping_sha512_rsa_sha384_mgf1();
332         test_create_signature_enveloping_sha512_rsa_sha512_mgf1();
333         test_create_signature_reference_dependency();
334         test_create_signature_with_attr_in_no_namespace();
335         test_create_signature_with_empty_id();
336         test_create_signature_enveloping_over_doc(ENVELOPE, true);
337         test_create_signature_enveloping_over_doc(ENVELOPE2, true);
338         test_create_signature_enveloping_over_doc(ENVELOPE, false);
339         test_create_signature_enveloping_dom_level1();
340 
341         // run tests for detached signatures with local http server
342         try (Http server = Http.startServer()) {
343             server.start();
344 
345             // tests for XML documents
346             Arrays.stream(canonicalizationMethods).forEach(c ->
347                 Arrays.stream(allSignatureMethods).forEach(s ->
348                     Arrays.stream(allDigestMethods).forEach(d ->
349                         Arrays.stream(xml_transforms).forEach(t ->
350                             Arrays.stream(KeyInfoType.values()).forEach(k -> {
351                                 if (isMajor(s, d)) {
352                                     test_create_detached_signature(c, s, d, t, k,
353                                             Content.Xml, server.getPort(), false, null);
354                                 }
355                         })))));
356 
357             // tests for text data with no transform
358             Arrays.stream(canonicalizationMethods).forEach(c ->
359                 Arrays.stream(allSignatureMethods).forEach(s ->
360                     Arrays.stream(allDigestMethods).forEach(d ->
361                         Arrays.stream(KeyInfoType.values()).forEach(k -> {
362                             if (isMajor(s, d)) {
363                                 test_create_detached_signature(c, s, d, null, k,
364                                         Content.Text, server.getPort(), false, null);
365                             }
366                         }))));
367 
368             // tests for base64 data
369             Arrays.stream(canonicalizationMethods).forEach(c ->
370                 Arrays.stream(allSignatureMethods).forEach(s ->
371                     Arrays.stream(allDigestMethods).forEach(d ->
372                         Arrays.stream(non_xml_transforms).forEach(t ->
373                             Arrays.stream(KeyInfoType.values()).forEach(k -> {
374                                 if (isMajor(s, d)) {
375                                     test_create_detached_signature(c, s, d, t, k,
376                                             Content.Base64, server.getPort(),
377                                             false, null);
378                                 }
379                         })))));
380 
381             // negative tests
382 
383             // unknown CanonicalizationMethod
384             test_create_detached_signature(
385                     CanonicalizationMethod.EXCLUSIVE + BOGUS,
386                     SignatureMethod.DSA_SHA1,
387                     DigestMethod.SHA1,
388                     CanonicalizationMethod.INCLUSIVE,
389                     KeyInfoType.KeyName,
390                     Content.Xml,
391                     server.getPort(),
392                     true,
393                     NoSuchAlgorithmException.class);
394 
395             // unknown SignatureMethod
396             test_create_detached_signature(
397                     CanonicalizationMethod.EXCLUSIVE,
398                     SignatureMethod.DSA_SHA1 + BOGUS,
399                     DigestMethod.SHA1,
400                     CanonicalizationMethod.INCLUSIVE,
401                     KeyInfoType.KeyName, Content.Xml,
402                     server.getPort(),
403                     true,
404                     NoSuchAlgorithmException.class);
405 
406             // unknown DigestMethod
407             test_create_detached_signature(
408                     CanonicalizationMethod.EXCLUSIVE,
409                     SignatureMethod.DSA_SHA1,
410                     DigestMethod.SHA1 + BOGUS,
411                     CanonicalizationMethod.INCLUSIVE,
412                     KeyInfoType.KeyName, Content.Xml,
413                     server.getPort(),
414                     true,
415                     NoSuchAlgorithmException.class);
416 
417             // unknown Transform
418             test_create_detached_signature(
419                     CanonicalizationMethod.EXCLUSIVE,
420                     SignatureMethod.DSA_SHA1,
421                     DigestMethod.SHA1,
422                     CanonicalizationMethod.INCLUSIVE + BOGUS,
423                     KeyInfoType.KeyName, Content.Xml,
424                     server.getPort(),
425                     true,
426                     NoSuchAlgorithmException.class);
427 
428             // no source document
429             test_create_detached_signature(
430                     CanonicalizationMethod.EXCLUSIVE,
431                     SignatureMethod.DSA_SHA1,
432                     DigestMethod.SHA1,
433                     CanonicalizationMethod.INCLUSIVE,
434                     KeyInfoType.KeyName,
435                     Content.NotExisitng,
436                     server.getPort(),
437                     true,
438                     XMLSignatureException.class);
439 
440             // wrong transform for text data
441             test_create_detached_signature(
442                     CanonicalizationMethod.EXCLUSIVE,
443                     SignatureMethod.DSA_SHA1,
444                     DigestMethod.SHA1,
445                     CanonicalizationMethod.INCLUSIVE,
446                     KeyInfoType.KeyName,
447                     Content.Text,
448                     server.getPort(),
449                     true,
450                     XMLSignatureException.class);
451         }
452 
453         // persist cached keys to a file.
454         try (FileOutputStream fos = new FileOutputStream("cached-keys", true);
455              ObjectOutputStream oos = new ObjectOutputStream(fos)) {
456             oos.writeObject(cachedKeys);
457         }
458 
459         if (!result) {
460             throw new RuntimeException("At least one test case failed");
461         }
462     }
463 
464     // Do not test on all combinations.
isMajor(String signatureMethod, String digestMethod)465     private static boolean isMajor(String signatureMethod, String digestMethod) {
466         return majorDigestMethods.contains(digestMethod)
467                 || majorSignatureMethods.contains(signatureMethod);
468     }
469 
setup()470     private static void setup() throws Exception {
471         fac = XMLSignatureFactory.getInstance();
472         kifac = fac.getKeyInfoFactory();
473         DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
474         dbf.setNamespaceAware(true);
475         db = dbf.newDocumentBuilder();
476 
477         // get key & self-signed certificate from keystore
478         FileInputStream fis = new FileInputStream(KEYSTORE);
479         ks = KeyStore.getInstance("JKS");
480         ks.load(fis, "changeit".toCharArray());
481         signingKey = ks.getKey("user", "changeit".toCharArray());
482         signingCert = ks.getCertificate("user");
483         validatingKey = signingCert.getPublicKey();
484 
485         // create common objects
486         withoutComments = fac.newCanonicalizationMethod
487             (CanonicalizationMethod.INCLUSIVE, (C14NMethodParameterSpec)null);
488         dsaSha1 = fac.newSignatureMethod(SignatureMethod.DSA_SHA1, null);
489         dsaSha256 = fac.newSignatureMethod(DSA_SHA256, null);
490 
491         sha1 = fac.newDigestMethod(DigestMethod.SHA1, null);
492         sha224 = fac.newDigestMethod(DigestMethod.SHA224, null);
493         sha256 = fac.newDigestMethod(DigestMethod.SHA256, null);
494         sha384 = fac.newDigestMethod(DigestMethod.SHA384, null);
495         sha512 = fac.newDigestMethod(DigestMethod.SHA512, null);
496         sha3_224 = fac.newDigestMethod(DigestMethod.SHA3_224, null);
497         sha3_256 = fac.newDigestMethod(DigestMethod.SHA3_256, null);
498         sha3_384 = fac.newDigestMethod(DigestMethod.SHA3_384, null);
499         sha3_512 = fac.newDigestMethod(DigestMethod.SHA3_512, null);
500 
501         dsa1024 = kifac.newKeyInfo(Collections.singletonList
502             (kifac.newKeyValue(validatingKey)));
503         dsa2048 = kifac.newKeyInfo(Collections.singletonList
504             (kifac.newKeyValue(getPublicKey("DSA", 2048))));
505         rsa = kifac.newKeyInfo(Collections.singletonList
506             (kifac.newKeyValue(getPublicKey("RSA", 512))));
507         rsa1024 = kifac.newKeyInfo(Collections.singletonList
508             (kifac.newKeyValue(getPublicKey("RSA", 1024))));
509         rsa2048 = kifac.newKeyInfo(Collections.singletonList
510                 (kifac.newKeyValue(getPublicKey("RSA", 2048))));
511         p256ki = kifac.newKeyInfo(Collections.singletonList
512             (kifac.newKeyValue(getECPublicKey("P256"))));
513         p384ki = kifac.newKeyInfo(Collections.singletonList
514             (kifac.newKeyValue(getECPublicKey("P384"))));
515         p521ki = kifac.newKeyInfo(Collections.singletonList
516             (kifac.newKeyValue(getECPublicKey("P521"))));
517 
518         rsaSha1 = fac.newSignatureMethod(SignatureMethod.RSA_SHA1, null);
519         rsaSha224 = fac.newSignatureMethod(SignatureMethod.RSA_SHA224, null);
520         rsaSha256 = fac.newSignatureMethod(SignatureMethod.RSA_SHA256, null);
521         rsaSha384 = fac.newSignatureMethod(SignatureMethod.RSA_SHA384, null);
522         rsaSha512 = fac.newSignatureMethod(SignatureMethod.RSA_SHA512, null);
523 
524         rsaSha1mgf1 = fac.newSignatureMethod(SignatureMethod.SHA1_RSA_MGF1, null);
525         rsaSha224mgf1 = fac.newSignatureMethod(SignatureMethod.SHA224_RSA_MGF1, null);
526         rsaSha256mgf1 = fac.newSignatureMethod(SignatureMethod.SHA256_RSA_MGF1, null);
527         rsaSha384mgf1 = fac.newSignatureMethod(SignatureMethod.SHA384_RSA_MGF1, null);
528         rsaSha512mgf1 = fac.newSignatureMethod(SignatureMethod.SHA512_RSA_MGF1, null);
529 
530         ecdsaSha1 = fac.newSignatureMethod(SignatureMethod.ECDSA_SHA1, null);
531         ecdsaSha224 = fac.newSignatureMethod(SignatureMethod.ECDSA_SHA224, null);
532         ecdsaSha256 = fac.newSignatureMethod(SignatureMethod.ECDSA_SHA256, null);
533         ecdsaSha384 = fac.newSignatureMethod(SignatureMethod.ECDSA_SHA384, null);
534         ecdsaSha512 = fac.newSignatureMethod(SignatureMethod.ECDSA_SHA512, null);
535 
536         hmacSha1 = fac.newSignatureMethod(SignatureMethod.HMAC_SHA1, null);
537         hmacSha224 = fac.newSignatureMethod(SignatureMethod.HMAC_SHA224, null);
538         hmacSha256 = fac.newSignatureMethod(SignatureMethod.HMAC_SHA256, null);
539         hmacSha384 = fac.newSignatureMethod(SignatureMethod.HMAC_SHA384, null);
540         hmacSha512 = fac.newSignatureMethod(SignatureMethod.HMAC_SHA512, null);
541 
542         sks = new KeySelectors.SecretKeySelector("secret".getBytes("ASCII"));
543 
544         httpUd = new HttpURIDereferencer();
545     }
546 
test_create_signature_enveloped_dsa(int size)547     static void test_create_signature_enveloped_dsa(int size) throws Exception {
548         System.out.println("* Generating signature-enveloped-dsa-"
549                            + size + ".xml");
550         SignatureMethod sm = null;
551         KeyInfo ki = null;
552         Key privKey;
553         if (size == 1024) {
554             sm = dsaSha1;
555             ki = dsa1024;
556             privKey = signingKey;
557         } else if (size == 2048) {
558             sm = dsaSha256;
559             ki = dsa2048;
560             privKey = getPrivateKey("DSA", 2048);
561         } else throw new RuntimeException("unsupported keysize:" + size);
562 
563         // create SignedInfo
564         SignedInfo si = fac.newSignedInfo
565             (withoutComments, sm, Collections.singletonList
566                 (fac.newReference
567                     ("", sha1, Collections.singletonList
568                         (fac.newTransform(Transform.ENVELOPED,
569                             (TransformParameterSpec) null)),
570                  null, null)));
571 
572         // create XMLSignature
573         XMLSignature sig = fac.newXMLSignature(si, ki);
574 
575         Document doc = db.newDocument();
576         Element envelope = doc.createElementNS
577             ("http://example.org/envelope", "Envelope");
578         envelope.setAttributeNS(XMLConstants.XMLNS_ATTRIBUTE_NS_URI,
579             "xmlns", "http://example.org/envelope");
580         doc.appendChild(envelope);
581 
582         DOMSignContext dsc = new DOMSignContext(privKey, envelope);
583 
584         sig.sign(dsc);
585 //        StringWriter sw = new StringWriter();
586 //        dumpDocument(doc, sw);
587 //        System.out.println(sw.toString());
588 
589         DOMValidateContext dvc = new DOMValidateContext
590             (kvks, envelope.getFirstChild());
591         XMLSignature sig2 = fac.unmarshalXMLSignature(dvc);
592 
593         if (sig.equals(sig2) == false) {
594             throw new Exception
595                 ("Unmarshalled signature is not equal to generated signature");
596         }
597 
598         if (sig2.validate(dvc) == false) {
599             throw new Exception("Validation of generated signature failed");
600         }
601         System.out.println();
602     }
603 
test_create_signature_enveloping_b64_dsa()604     static void test_create_signature_enveloping_b64_dsa() throws Exception {
605         System.out.println("* Generating signature-enveloping-b64-dsa.xml");
606         test_create_signature_enveloping
607             (sha1, dsaSha1, dsa1024, signingKey, kvks, true);
608         System.out.println();
609     }
610 
test_create_signature_enveloping_dsa()611     static void test_create_signature_enveloping_dsa() throws Exception {
612         System.out.println("* Generating signature-enveloping-dsa.xml");
613         test_create_signature_enveloping
614             (sha1, dsaSha1, dsa1024, signingKey, kvks, false);
615         System.out.println();
616     }
617 
test_create_signature_enveloping_sha256_dsa()618     static void test_create_signature_enveloping_sha256_dsa() throws Exception {
619         System.out.println("* Generating signature-enveloping-sha256-dsa.xml");
620         test_create_signature_enveloping
621             (sha256, dsaSha1, dsa1024, signingKey, kvks, false);
622         System.out.println();
623     }
624 
test_create_signature_enveloping_hmac_sha1_40()625     static void test_create_signature_enveloping_hmac_sha1_40()
626         throws Exception {
627         System.out.println("* Generating signature-enveloping-hmac-sha1-40.xml");
628         try {
629             test_create_signature_enveloping(sha1, hmacSha1, null,
630                 getSecretKey("secret".getBytes("ASCII")), sks, false);
631         } catch (Exception e) {
632             if (!(e instanceof XMLSignatureException)) {
633                 throw e;
634             }
635         }
636         System.out.println();
637     }
638 
test_create_signature_enveloping_hmac_sha256()639     static void test_create_signature_enveloping_hmac_sha256()
640         throws Exception {
641         System.out.println("* Generating signature-enveloping-hmac-sha256.xml");
642         test_create_signature_enveloping(sha1, hmacSha256, null,
643             getSecretKey("secret".getBytes("ASCII")), sks, false);
644         System.out.println();
645     }
646 
test_create_signature_enveloping_hmac_sha224()647     static void test_create_signature_enveloping_hmac_sha224()
648             throws Exception {
649         System.out.println("* Generating signature-enveloping-hmac-sha224.xml");
650         test_create_signature_enveloping(sha1, hmacSha224, null,
651                 getSecretKey("secret".getBytes("ASCII")), sks, false);
652         System.out.println();
653     }
654 
test_create_signature_enveloping_hmac_sha384()655     static void test_create_signature_enveloping_hmac_sha384()
656         throws Exception {
657         System.out.println("* Generating signature-enveloping-hmac-sha384.xml");
658         test_create_signature_enveloping(sha1, hmacSha384, null,
659             getSecretKey("secret".getBytes("ASCII")), sks, false);
660         System.out.println();
661     }
662 
test_create_signature_enveloping_hmac_sha512()663     static void test_create_signature_enveloping_hmac_sha512()
664         throws Exception {
665         System.out.println("* Generating signature-enveloping-hmac-sha512.xml");
666         test_create_signature_enveloping(sha1, hmacSha512, null,
667             getSecretKey("secret".getBytes("ASCII")), sks, false);
668         System.out.println();
669     }
670 
test_create_signature_enveloping_rsa()671     static void test_create_signature_enveloping_rsa() throws Exception {
672         System.out.println("* Generating signature-enveloping-rsa.xml");
673         test_create_signature_enveloping(sha1, rsaSha1, rsa,
674             getPrivateKey("RSA", 512), kvks, false);
675         System.out.println();
676     }
677 
test_create_signature_enveloping_sha384_rsa_sha256()678     static void test_create_signature_enveloping_sha384_rsa_sha256()
679         throws Exception {
680         System.out.println("* Generating signature-enveloping-sha384-rsa_sha256.xml");
681         test_create_signature_enveloping(sha384, rsaSha256, rsa,
682             getPrivateKey("RSA", 512), kvks, false);
683         System.out.println();
684     }
685 
test_create_signature_enveloping_sha224_rsa_sha256()686     static void test_create_signature_enveloping_sha224_rsa_sha256()
687             throws Exception {
688         System.out.println("* Generating signature-enveloping-sha224-rsa_sha256.xml");
689         test_create_signature_enveloping(sha224, rsaSha256, rsa,
690                 getPrivateKey("RSA", 512), kvks, false);
691         System.out.println();
692     }
693 
test_create_signature_enveloping_sha3_224_rsa_sha256()694     static void test_create_signature_enveloping_sha3_224_rsa_sha256()
695             throws Exception {
696         System.out.println("* Generating signature-enveloping-sha3_224-rsa_sha256.xml");
697         test_create_signature_enveloping(sha3_224, rsaSha256, rsa,
698                 getPrivateKey("RSA", 512), kvks, false);
699         System.out.println();
700     }
701 
test_create_signature_enveloping_sha3_256_rsa_sha256()702     static void test_create_signature_enveloping_sha3_256_rsa_sha256()
703             throws Exception {
704         System.out.println("* Generating signature-enveloping-sha3_256-rsa_sha256.xml");
705         test_create_signature_enveloping(sha3_256, rsaSha256, rsa,
706                 getPrivateKey("RSA", 512), kvks, false);
707         System.out.println();
708     }
709 
test_create_signature_enveloping_sha3_384_rsa_sha256()710     static void test_create_signature_enveloping_sha3_384_rsa_sha256()
711             throws Exception {
712         System.out.println("* Generating signature-enveloping-sha3_384-rsa_sha256.xml");
713         test_create_signature_enveloping(sha3_384, rsaSha256, rsa,
714                 getPrivateKey("RSA", 512), kvks, false);
715         System.out.println();
716     }
717 
test_create_signature_enveloping_sha3_512_rsa_sha256()718     static void test_create_signature_enveloping_sha3_512_rsa_sha256()
719             throws Exception {
720         System.out.println("* Generating signature-enveloping-sha3_512-rsa_sha256.xml");
721         test_create_signature_enveloping(sha3_512, rsaSha256, rsa,
722                 getPrivateKey("RSA", 512), kvks, false);
723         System.out.println();
724     }
725 
test_create_signature_enveloping_sha512_rsa_sha384()726     static void test_create_signature_enveloping_sha512_rsa_sha384()
727         throws Exception {
728         System.out.println("* Generating signature-enveloping-sha512-rsa_sha384.xml");
729         test_create_signature_enveloping(sha512, rsaSha384, rsa1024,
730             getPrivateKey("RSA", 1024), kvks, false);
731         System.out.println();
732     }
733 
test_create_signature_enveloping_sha512_rsa_sha224()734     static void test_create_signature_enveloping_sha512_rsa_sha224()
735             throws Exception {
736         System.out.println("* Generating signature-enveloping-sha512-rsa_sha224.xml");
737         test_create_signature_enveloping(sha512, rsaSha224, rsa1024,
738                 getPrivateKey("RSA", 1024), kvks, false);
739         System.out.println();
740     }
741 
test_create_signature_enveloping_sha512_rsa_sha512()742     static void test_create_signature_enveloping_sha512_rsa_sha512()
743         throws Exception {
744         System.out.println("* Generating signature-enveloping-sha512-rsa_sha512.xml");
745         test_create_signature_enveloping(sha512, rsaSha512, rsa1024,
746             getPrivateKey("RSA", 1024), kvks, false);
747         System.out.println();
748     }
749 
test_create_signature_enveloping_sha512_rsa_sha1_mgf1()750     static void test_create_signature_enveloping_sha512_rsa_sha1_mgf1()
751             throws Exception {
752         System.out.println("* Generating signature-enveloping-sha512-rsa_sha1_mgf1.xml");
753         test_create_signature_enveloping(sha512, rsaSha1mgf1, rsa1024,
754                 getPrivateKey("RSA", 1024), kvks, false);
755         System.out.println();
756     }
757 
test_create_signature_enveloping_sha512_rsa_sha224_mgf1()758     static void test_create_signature_enveloping_sha512_rsa_sha224_mgf1()
759             throws Exception {
760         System.out.println("* Generating signature-enveloping-sha512-rsa_sha224_mgf1.xml");
761         test_create_signature_enveloping(sha512, rsaSha224mgf1, rsa1024,
762                 getPrivateKey("RSA", 1024), kvks, false);
763         System.out.println();
764     }
765 
test_create_signature_enveloping_sha512_rsa_sha256_mgf1()766     static void test_create_signature_enveloping_sha512_rsa_sha256_mgf1()
767             throws Exception {
768         System.out.println("* Generating signature-enveloping-sha512-rsa_sha256_mgf1.xml");
769         test_create_signature_enveloping(sha512, rsaSha256mgf1, rsa1024,
770                 getPrivateKey("RSA", 1024), kvks, false);
771         System.out.println();
772     }
773 
test_create_signature_enveloping_sha512_rsa_sha384_mgf1()774     static void test_create_signature_enveloping_sha512_rsa_sha384_mgf1()
775             throws Exception {
776         System.out.println("* Generating signature-enveloping-sha512-rsa_sha384_mgf1.xml");
777         test_create_signature_enveloping(sha512, rsaSha384mgf1, rsa1024,
778                 getPrivateKey("RSA", 1024), kvks, false);
779         System.out.println();
780     }
781 
test_create_signature_enveloping_sha512_rsa_sha512_mgf1()782     static void test_create_signature_enveloping_sha512_rsa_sha512_mgf1()
783             throws Exception {
784         System.out.println("* Generating signature-enveloping-sha512-rsa_sha512_mgf1.xml");
785         test_create_signature_enveloping(sha512, rsaSha512mgf1, rsa2048,
786                 getPrivateKey("RSA", 2048), kvks, false);
787         System.out.println();
788     }
789 
test_create_signature_enveloping_p256_sha1()790     static void test_create_signature_enveloping_p256_sha1() throws Exception {
791         System.out.println("* Generating signature-enveloping-p256-sha1.xml");
792         test_create_signature_enveloping(sha1, ecdsaSha1, p256ki,
793             getECPrivateKey("P256"), kvks, false);
794         System.out.println();
795     }
796 
test_create_signature_enveloping_p256_sha224()797     static void test_create_signature_enveloping_p256_sha224() throws Exception {
798         System.out.println("* Generating signature-enveloping-p256-sha224.xml");
799         test_create_signature_enveloping(sha1, ecdsaSha224, p256ki,
800                 getECPrivateKey("P256"), kvks, false);
801         System.out.println();
802     }
803 
test_create_signature_enveloping_p256_sha256()804     static void test_create_signature_enveloping_p256_sha256() throws Exception {
805         System.out.println("* Generating signature-enveloping-p256-sha256.xml");
806         test_create_signature_enveloping(sha1, ecdsaSha256, p256ki,
807                 getECPrivateKey("P256"), kvks, false);
808         System.out.println();
809     }
810 
test_create_signature_enveloping_p256_sha384()811     static void test_create_signature_enveloping_p256_sha384() throws Exception {
812         System.out.println("* Generating signature-enveloping-p256-sha384.xml");
813         test_create_signature_enveloping(sha1, ecdsaSha384, p256ki,
814                 getECPrivateKey("P256"), kvks, false);
815         System.out.println();
816     }
817 
test_create_signature_enveloping_p256_sha512()818     static void test_create_signature_enveloping_p256_sha512() throws Exception {
819         System.out.println("* Generating signature-enveloping-p256-sha512.xml");
820         test_create_signature_enveloping(sha1, ecdsaSha512, p256ki,
821                 getECPrivateKey("P256"), kvks, false);
822         System.out.println();
823     }
824 
test_create_signature_enveloping_p384_sha1()825     static void test_create_signature_enveloping_p384_sha1() throws Exception {
826         System.out.println("* Generating signature-enveloping-p384-sha1.xml");
827         test_create_signature_enveloping(sha1, ecdsaSha1, p384ki,
828             getECPrivateKey("P384"), kvks, false);
829         System.out.println();
830     }
831 
test_create_signature_enveloping_p521_sha1()832     static void test_create_signature_enveloping_p521_sha1() throws Exception {
833         System.out.println("* Generating signature-enveloping-p521-sha1.xml");
834         test_create_signature_enveloping(sha1, ecdsaSha1, p521ki,
835             getECPrivateKey("P521"), kvks, false);
836         System.out.println();
837     }
838 
test_create_signature_external_b64_dsa()839     static void test_create_signature_external_b64_dsa() throws Exception {
840         System.out.println("* Generating signature-external-b64-dsa.xml");
841         test_create_signature_external(dsaSha1, dsa1024, signingKey, kvks, true);
842         System.out.println();
843     }
844 
test_create_signature_external_dsa()845     static void test_create_signature_external_dsa() throws Exception {
846         System.out.println("* Generating signature-external-dsa.xml");
847         test_create_signature_external(dsaSha1, dsa1024, signingKey, kvks, false);
848         System.out.println();
849     }
850 
test_create_signature_keyname()851     static void test_create_signature_keyname() throws Exception {
852         System.out.println("* Generating signature-keyname.xml");
853         KeyInfo kn = kifac.newKeyInfo(Collections.singletonList
854             (kifac.newKeyName("user")));
855         test_create_signature_external(dsaSha1, kn, signingKey,
856             new X509KeySelector(ks), false);
857         System.out.println();
858     }
859 
test_create_signature_retrievalmethod_rawx509crt()860     static void test_create_signature_retrievalmethod_rawx509crt()
861         throws Exception {
862         System.out.println(
863             "* Generating signature-retrievalmethod-rawx509crt.xml");
864         KeyInfo rm = kifac.newKeyInfo(Collections.singletonList
865             (kifac.newRetrievalMethod
866             ("certs/user.crt", X509Data.RAW_X509_CERTIFICATE_TYPE, null)));
867         test_create_signature_external(dsaSha1, rm, signingKey,
868             new X509KeySelector(ks), false);
869         System.out.println();
870     }
871 
test_create_signature_x509_crt_crl()872     static void test_create_signature_x509_crt_crl() throws Exception {
873         System.out.println("* Generating signature-x509-crt-crl.xml");
874         List<Object> xds = new ArrayList<>();
875         CertificateFactory cf = CertificateFactory.getInstance("X.509");
876         xds.add(signingCert);
877         FileInputStream fis = new FileInputStream(CRL);
878         X509CRL crl = (X509CRL) cf.generateCRL(fis);
879         fis.close();
880         xds.add(crl);
881         KeyInfo crt_crl = kifac.newKeyInfo(Collections.singletonList
882             (kifac.newX509Data(xds)));
883 
884         test_create_signature_external(dsaSha1, crt_crl, signingKey,
885             new X509KeySelector(ks), false);
886         System.out.println();
887     }
888 
test_create_signature_x509_crt()889     static void test_create_signature_x509_crt() throws Exception {
890         System.out.println("* Generating signature-x509-crt.xml");
891         KeyInfo crt = kifac.newKeyInfo(Collections.singletonList
892             (kifac.newX509Data(Collections.singletonList(signingCert))));
893 
894         test_create_signature_external(dsaSha1, crt, signingKey,
895             new X509KeySelector(ks), false);
896         System.out.println();
897     }
898 
test_create_signature_x509_is()899     static void test_create_signature_x509_is() throws Exception {
900         System.out.println("* Generating signature-x509-is.xml");
901         KeyInfo is = kifac.newKeyInfo(Collections.singletonList
902             (kifac.newX509Data(Collections.singletonList
903             (kifac.newX509IssuerSerial
904             ("CN=User", new BigInteger("45ef2729", 16))))));
905         test_create_signature_external(dsaSha1, is, signingKey,
906             new X509KeySelector(ks), false);
907         System.out.println();
908     }
909 
test_create_signature_x509_ski()910     static void test_create_signature_x509_ski() throws Exception {
911         System.out.println("* Generating signature-x509-ski.xml");
912         KeyInfo ski = kifac.newKeyInfo(Collections.singletonList
913             (kifac.newX509Data(Collections.singletonList
914             ("keyid".getBytes("ASCII")))));
915 
916         test_create_signature_external(dsaSha1, ski, signingKey,
917             KeySelector.singletonKeySelector(validatingKey), false);
918         System.out.println();
919     }
920 
test_create_signature_x509_sn()921     static void test_create_signature_x509_sn() throws Exception {
922         System.out.println("* Generating signature-x509-sn.xml");
923         KeyInfo sn = kifac.newKeyInfo(Collections.singletonList
924             (kifac.newX509Data(Collections.singletonList("CN=User"))));
925 
926         test_create_signature_external(dsaSha1, sn, signingKey,
927             new X509KeySelector(ks), false);
928         System.out.println();
929     }
930 
test_create_signature_reference_dependency()931     static void test_create_signature_reference_dependency() throws Exception {
932         System.out.println("* Generating signature-reference-dependency.xml");
933         // create references
934         List<Reference> refs = Collections.singletonList
935             (fac.newReference("#object-1", sha1));
936 
937         // create SignedInfo
938         SignedInfo si = fac.newSignedInfo(withoutComments, rsaSha1, refs);
939 
940         // create objects
941         List<XMLObject> objs = new ArrayList<>();
942 
943         // Object 1
944         List<Reference> manRefs = Collections.singletonList
945             (fac.newReference("#object-2", sha1));
946         objs.add(fac.newXMLObject(Collections.singletonList
947             (fac.newManifest(manRefs, "manifest-1")), "object-1", null, null));
948 
949         // Object 2
950         Document doc = db.newDocument();
951         Element nc = doc.createElementNS(null, "NonCommentandus");
952         nc.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns", "");
953         nc.appendChild(doc.createComment(" Commentandum "));
954         objs.add(fac.newXMLObject(Collections.singletonList
955             (new DOMStructure(nc)), "object-2", null, null));
956 
957         // create XMLSignature
958         XMLSignature sig = fac.newXMLSignature(si, rsa, objs, "signature", null);
959         DOMSignContext dsc = new DOMSignContext(getPrivateKey("RSA", 512), doc);
960 
961         sig.sign(dsc);
962 
963 //      dumpDocument(doc, new PrintWriter(System.out));
964 
965         DOMValidateContext dvc = new DOMValidateContext
966             (kvks, doc.getDocumentElement());
967         XMLSignature sig2 = fac.unmarshalXMLSignature(dvc);
968 
969         if (sig.equals(sig2) == false) {
970             throw new Exception
971                 ("Unmarshalled signature is not equal to generated signature");
972         }
973         if (sig2.validate(dvc) == false) {
974             throw new Exception("Validation of generated signature failed");
975         }
976 
977         System.out.println();
978     }
979 
test_create_signature_with_attr_in_no_namespace()980     static void test_create_signature_with_attr_in_no_namespace()
981         throws Exception
982     {
983         System.out.println
984             ("* Generating signature-with-attr-in-no-namespace.xml");
985 
986         // create references
987         List<Reference> refs = Collections.singletonList
988             (fac.newReference("#unknown", sha1));
989 
990         // create SignedInfo
991         SignedInfo si = fac.newSignedInfo(withoutComments, rsaSha1, refs);
992 
993         // create object-1
994         Document doc = db.newDocument();
995         Element nc = doc.createElementNS(null, "NonCommentandus");
996         // add attribute with no namespace
997         nc.setAttribute("Id", "unknown");
998         XMLObject obj = fac.newXMLObject(Collections.singletonList
999             (new DOMStructure(nc)), "object-1", null, null);
1000 
1001         // create XMLSignature
1002         XMLSignature sig = fac.newXMLSignature(si, rsa,
1003                                                Collections.singletonList(obj),
1004                                                "signature", null);
1005         DOMSignContext dsc = new DOMSignContext(getPrivateKey("RSA", 512), doc);
1006         dsc.setIdAttributeNS(nc, null, "Id");
1007 
1008         sig.sign(dsc);
1009 
1010 //      dumpDocument(doc, new PrintWriter(System.out));
1011 
1012         DOMValidateContext dvc = new DOMValidateContext
1013             (kvks, doc.getDocumentElement());
1014         dvc.setIdAttributeNS(nc, null, "Id");
1015         XMLSignature sig2 = fac.unmarshalXMLSignature(dvc);
1016 
1017         if (sig.equals(sig2) == false) {
1018             throw new Exception
1019                 ("Unmarshalled signature is not equal to generated signature");
1020         }
1021         if (sig2.validate(dvc) == false) {
1022             throw new Exception("Validation of generated signature failed");
1023         }
1024 
1025         System.out.println();
1026     }
1027 
test_create_signature_with_empty_id()1028     static void test_create_signature_with_empty_id() throws Exception {
1029         System.out.println("* Generating signature-with-empty-id.xml");
1030 
1031         // create references
1032         List<Reference> refs = Collections.singletonList
1033             (fac.newReference("#", sha1));
1034 
1035         // create SignedInfo
1036         SignedInfo si = fac.newSignedInfo(withoutComments, rsaSha1, refs);
1037 
1038         // create object with empty id
1039         Document doc = db.newDocument();
1040         XMLObject obj = fac.newXMLObject(Collections.singletonList
1041             (new DOMStructure(doc.createTextNode("I am the text."))),
1042             "", "text/plain", null);
1043 
1044         // create XMLSignature
1045         XMLSignature sig = fac.newXMLSignature(si, rsa,
1046                                                Collections.singletonList(obj),
1047                                                "signature", null);
1048         DOMSignContext dsc = new DOMSignContext(getPrivateKey("RSA", 512), doc);
1049         sig.sign(dsc);
1050 
1051         System.out.println();
1052     }
1053 
test_create_signature_enveloping_over_doc(String filename, boolean pass)1054     static void test_create_signature_enveloping_over_doc(String filename,
1055         boolean pass) throws Exception
1056     {
1057         System.out.println("* Generating signature-enveloping-over-doc.xml");
1058 
1059         // create reference
1060         Reference ref = fac.newReference("#object", sha256);
1061 
1062         // create SignedInfo
1063         SignedInfo si = fac.newSignedInfo(withoutComments, rsaSha256,
1064             Collections.singletonList(ref));
1065 
1066         // create object
1067         Document doc = null;
1068         try (FileInputStream fis = new FileInputStream(filename)) {
1069             doc = db.parse(fis);
1070         }
1071         DOMStructure ds = pass ? new DOMStructure(doc.getDocumentElement())
1072                                : new DOMStructure(doc);
1073         XMLObject obj = fac.newXMLObject(Collections.singletonList(ds),
1074             "object", null, "UTF-8");
1075 
1076         // This creates an enveloping signature over the entire XML Document
1077         XMLSignature sig = fac.newXMLSignature(si, rsa,
1078                                                Collections.singletonList(obj),
1079                                                "signature", null);
1080         DOMSignContext dsc = new DOMSignContext(getPrivateKey("RSA", 1024), doc);
1081         try {
1082             sig.sign(dsc);
1083             if (!pass) {
1084                 // A Document node can only exist at the root of the doc so this
1085                 // should fail
1086                 throw new Exception("Test unexpectedly passed");
1087             }
1088         } catch (Exception e) {
1089             if (!pass) {
1090                 System.out.println("Test failed as expected: " + e);
1091             } else {
1092                 throw e;
1093             }
1094         }
1095 
1096         if (pass) {
1097             DOMValidateContext dvc = new DOMValidateContext
1098                 (getPublicKey("RSA", 1024), doc.getDocumentElement());
1099             XMLSignature sig2 = fac.unmarshalXMLSignature(dvc);
1100 
1101             if (sig.equals(sig2) == false) {
1102                 throw new Exception
1103                     ("Unmarshalled signature is not equal to generated signature");
1104             }
1105             if (sig2.validate(dvc) == false) {
1106                 throw new Exception("Validation of generated signature failed");
1107             }
1108         }
1109 
1110         System.out.println();
1111     }
1112 
test_create_signature_enveloping_dom_level1()1113     static void test_create_signature_enveloping_dom_level1() throws Exception {
1114         System.out.println("* Generating signature-enveloping-dom-level1.xml");
1115 
1116         // create reference
1117         Reference ref = fac.newReference("#object", sha256);
1118 
1119         // create SignedInfo
1120         SignedInfo si = fac.newSignedInfo(withoutComments, rsaSha256,
1121             Collections.singletonList(ref));
1122 
1123         // create object using DOM Level 1 methods
1124         Document doc = db.newDocument();
1125         Element child = doc.createElement("Child");
1126         child.setAttribute("Version", "1.0");
1127         child.setAttribute("Id", "child");
1128         child.setIdAttribute("Id", true);
1129         child.appendChild(doc.createComment("Comment"));
1130         XMLObject obj = fac.newXMLObject(
1131             Collections.singletonList(new DOMStructure(child)),
1132             "object", null, "UTF-8");
1133 
1134         XMLSignature sig = fac.newXMLSignature(si, rsa,
1135                                                Collections.singletonList(obj),
1136                                                "signature", null);
1137         DOMSignContext dsc = new DOMSignContext(getPrivateKey("RSA", 1024), doc);
1138         sig.sign(dsc);
1139 
1140         DOMValidateContext dvc = new DOMValidateContext
1141             (getPublicKey("RSA", 1024), doc.getDocumentElement());
1142         XMLSignature sig2 = fac.unmarshalXMLSignature(dvc);
1143 
1144         if (sig.equals(sig2) == false) {
1145             throw new Exception
1146                 ("Unmarshalled signature is not equal to generated signature");
1147         }
1148         if (sig2.validate(dvc) == false) {
1149             throw new Exception("Validation of generated signature failed");
1150         }
1151 
1152         System.out.println();
1153     }
1154 
test_create_signature()1155     static void test_create_signature() throws Exception {
1156         System.out.println("* Generating signature.xml");
1157 
1158         // create references
1159         List<Reference> refs = new ArrayList<>();
1160 
1161         // Reference 1
1162         refs.add(fac.newReference(STYLESHEET, sha1));
1163 
1164         // Reference 2
1165         refs.add(fac.newReference
1166             (STYLESHEET_B64,
1167             sha1, Collections.singletonList
1168             (fac.newTransform(Transform.BASE64,
1169                 (TransformParameterSpec) null)), null, null));
1170 
1171         // Reference 3
1172         refs.add(fac.newReference("#object-1", sha1, Collections.singletonList
1173             (fac.newTransform(Transform.XPATH,
1174             new XPathFilterParameterSpec("self::text()"))),
1175             XMLObject.TYPE, null));
1176 
1177         // Reference 4
1178         String expr = "\n"
1179           + " ancestor-or-self::dsig:SignedInfo                  " + "\n"
1180           + "  and                                               " + "\n"
1181           + " count(ancestor-or-self::dsig:Reference |           " + "\n"
1182           + "      here()/ancestor::dsig:Reference[1]) >         " + "\n"
1183           + " count(ancestor-or-self::dsig:Reference)            " + "\n"
1184           + "  or                                                " + "\n"
1185           + " count(ancestor-or-self::node() |                   " + "\n"
1186           + "      id('notaries')) =                             " + "\n"
1187           + " count(ancestor-or-self::node())                    " + "\n";
1188 
1189         XPathFilterParameterSpec xfp = new XPathFilterParameterSpec(expr,
1190             Collections.singletonMap("dsig", XMLSignature.XMLNS));
1191         refs.add(fac.newReference("", sha1, Collections.singletonList
1192             (fac.newTransform(Transform.XPATH, xfp)),
1193             XMLObject.TYPE, null));
1194 
1195         // Reference 5
1196         refs.add(fac.newReference("#object-2", sha1, Collections.singletonList
1197             (fac.newTransform
1198                 (Transform.BASE64, (TransformParameterSpec) null)),
1199             XMLObject.TYPE, null));
1200 
1201         // Reference 6
1202         refs.add(fac.newReference
1203             ("#manifest-1", sha1, null, Manifest.TYPE, null));
1204 
1205         // Reference 7
1206         refs.add(fac.newReference("#signature-properties-1", sha1, null,
1207             SignatureProperties.TYPE, null));
1208 
1209         // Reference 8
1210         List<Transform> transforms = new ArrayList<>();
1211         transforms.add(fac.newTransform
1212             (Transform.ENVELOPED, (TransformParameterSpec) null));
1213         refs.add(fac.newReference("", sha1, transforms, null, null));
1214 
1215         // Reference 9
1216         transforms.add(fac.newTransform
1217             (CanonicalizationMethod.INCLUSIVE_WITH_COMMENTS,
1218                 (TransformParameterSpec) null));
1219         refs.add(fac.newReference("", sha1, transforms, null, null));
1220 
1221         // Reference 10
1222         Transform env = fac.newTransform
1223             (Transform.ENVELOPED, (TransformParameterSpec) null);
1224         refs.add(fac.newReference("#xpointer(/)",
1225             sha1, Collections.singletonList(env), null, null));
1226 
1227         // Reference 11
1228         transforms.clear();
1229         transforms.add(fac.newTransform
1230             (Transform.ENVELOPED, (TransformParameterSpec) null));
1231         transforms.add(fac.newTransform
1232             (CanonicalizationMethod.INCLUSIVE_WITH_COMMENTS,
1233              (TransformParameterSpec) null));
1234         refs.add(fac.newReference("#xpointer(/)", sha1, transforms,
1235             null, null));
1236 
1237         // Reference 12
1238         refs.add
1239             (fac.newReference("#object-3", sha1, null, XMLObject.TYPE, null));
1240 
1241         // Reference 13
1242         Transform withComments = fac.newTransform
1243             (CanonicalizationMethod.INCLUSIVE_WITH_COMMENTS,
1244              (TransformParameterSpec) null);
1245         refs.add(fac.newReference("#object-3", sha1,
1246             Collections.singletonList(withComments), XMLObject.TYPE, null));
1247 
1248         // Reference 14
1249         refs.add(fac.newReference("#xpointer(id('object-3'))", sha1, null,
1250             XMLObject.TYPE, null));
1251 
1252         // Reference 15
1253         withComments = fac.newTransform
1254             (CanonicalizationMethod.INCLUSIVE_WITH_COMMENTS,
1255              (TransformParameterSpec) null);
1256         refs.add(fac.newReference("#xpointer(id('object-3'))", sha1,
1257             Collections.singletonList(withComments), XMLObject.TYPE, null));
1258 
1259         // Reference 16
1260         refs.add(fac.newReference("#reference-2", sha1));
1261 
1262         // Reference 17
1263         refs.add(fac.newReference("#manifest-reference-1", sha1, null,
1264             null, "reference-1"));
1265 
1266         // Reference 18
1267         refs.add(fac.newReference("#reference-1", sha1, null, null,
1268             "reference-2"));
1269 
1270         // create SignedInfo
1271         SignedInfo si = fac.newSignedInfo(withoutComments, dsaSha1, refs);
1272 
1273         // create keyinfo
1274         XPathFilterParameterSpec xpf = new XPathFilterParameterSpec(
1275             "ancestor-or-self::dsig:X509Data",
1276             Collections.singletonMap("dsig", XMLSignature.XMLNS));
1277         RetrievalMethod rm = kifac.newRetrievalMethod("#object-4",
1278             X509Data.TYPE, Collections.singletonList(fac.newTransform
1279             (Transform.XPATH, xpf)));
1280         KeyInfo ki = kifac.newKeyInfo(Collections.singletonList(rm), null);
1281 
1282         Document doc = db.newDocument();
1283 
1284         // create objects
1285         List<XMLObject> objs = new ArrayList<>();
1286 
1287         // Object 1
1288         objs.add(fac.newXMLObject(Collections.singletonList
1289             (new DOMStructure(doc.createTextNode("I am the text."))),
1290             "object-1", "text/plain", null));
1291 
1292         // Object 2
1293         objs.add(fac.newXMLObject(Collections.singletonList
1294             (new DOMStructure(doc.createTextNode("SSBhbSB0aGUgdGV4dC4="))),
1295             "object-2", "text/plain", Transform.BASE64));
1296 
1297         // Object 3
1298         Element nc = doc.createElementNS(null, "NonCommentandus");
1299         nc.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns", "");
1300         nc.appendChild(doc.createComment(" Commentandum "));
1301         objs.add(fac.newXMLObject(Collections.singletonList
1302             (new DOMStructure(nc)), "object-3", null, null));
1303 
1304         // Manifest
1305         List<Reference> manRefs = new ArrayList<>();
1306 
1307         // Manifest Reference 1
1308         manRefs.add(fac.newReference(STYLESHEET,
1309             sha1, null, null, "manifest-reference-1"));
1310 
1311         // Manifest Reference 2
1312         manRefs.add(fac.newReference("#reference-1", sha1));
1313 
1314         // Manifest Reference 3
1315         List<Transform> manTrans = new ArrayList<>();
1316         Document docxslt = db.parse(new ByteArrayInputStream(xslt.getBytes()));
1317         Node xslElem = docxslt.getDocumentElement();
1318 
1319         manTrans.add(fac.newTransform(Transform.XSLT,
1320             new XSLTTransformParameterSpec(new DOMStructure(xslElem))));
1321         manTrans.add(fac.newTransform(CanonicalizationMethod.INCLUSIVE,
1322             (TransformParameterSpec) null));
1323         manRefs.add(fac.newReference("#notaries", sha1, manTrans, null, null));
1324 
1325         objs.add(fac.newXMLObject(Collections.singletonList
1326             (fac.newManifest(manRefs, "manifest-1")), null, null, null));
1327 
1328         // SignatureProperties
1329         Element sa = doc.createElementNS("urn:demo", "SignerAddress");
1330         sa.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns", "urn:demo");
1331         Element ip = doc.createElementNS("urn:demo", "IP");
1332         ip.appendChild(doc.createTextNode("192.168.21.138"));
1333         sa.appendChild(ip);
1334         SignatureProperty sp = fac.newSignatureProperty
1335             (Collections.singletonList(new DOMStructure(sa)),
1336             "#signature", null);
1337         SignatureProperties sps = fac.newSignatureProperties
1338             (Collections.singletonList(sp), "signature-properties-1");
1339         objs.add(fac.newXMLObject(Collections.singletonList(sps), null,
1340             null, null));
1341 
1342         // Object 4
1343         List<Object> xds = new ArrayList<>();
1344         xds.add("CN=User");
1345         xds.add(kifac.newX509IssuerSerial
1346             ("CN=User", new BigInteger("45ef2729", 16)));
1347         xds.add(signingCert);
1348         objs.add(fac.newXMLObject(Collections.singletonList
1349             (kifac.newX509Data(xds)), "object-4", null, null));
1350 
1351         // create XMLSignature
1352         XMLSignature sig = fac.newXMLSignature(si, ki, objs, "signature", null);
1353 
1354         DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
1355         dbf.setNamespaceAware(true);
1356         dbf.setValidating(false);
1357         Document envDoc = dbf.newDocumentBuilder().parse
1358             (new FileInputStream(ENVELOPE));
1359         Element ys = (Element)
1360             envDoc.getElementsByTagName("YoursSincerely").item(0);
1361 
1362         DOMSignContext dsc = new DOMSignContext(signingKey, ys);
1363         dsc.setURIDereferencer(httpUd);
1364 
1365         sig.sign(dsc);
1366 
1367 //      StringWriter sw = new StringWriter();
1368 //        dumpDocument(envDoc, sw);
1369 
1370         NodeList nl =
1371             envDoc.getElementsByTagNameNS(XMLSignature.XMLNS, "Signature");
1372         if (nl.getLength() == 0) {
1373             throw new Exception("Couldn't find signature Element");
1374         }
1375         Element sigElement = (Element) nl.item(0);
1376 
1377         DOMValidateContext dvc = new DOMValidateContext
1378             (new X509KeySelector(ks), sigElement);
1379         dvc.setURIDereferencer(httpUd);
1380         File f = new File(
1381             System.getProperty("dir.test.vector.baltimore") +
1382             System.getProperty("file.separator") +
1383             "merlin-xmldsig-twenty-three" +
1384             System.getProperty("file.separator"));
1385         dvc.setBaseURI(f.toURI().toString());
1386 
1387         XMLSignature sig2 = fac.unmarshalXMLSignature(dvc);
1388 
1389         if (sig.equals(sig2) == false) {
1390             throw new Exception
1391                 ("Unmarshalled signature is not equal to generated signature");
1392         }
1393         if (sig2.validate(dvc) == false) {
1394             throw new Exception("Validation of generated signature failed");
1395         }
1396         System.out.println();
1397     }
1398 
dumpDocument(Document doc, Writer w)1399     private static void dumpDocument(Document doc, Writer w) throws Exception {
1400         TransformerFactory tf = TransformerFactory.newInstance();
1401         Transformer trans = tf.newTransformer();
1402 //      trans.setOutputProperty(OutputKeys.INDENT, "yes");
1403         trans.transform(new DOMSource(doc), new StreamResult(w));
1404     }
1405 
test_create_signature_external(SignatureMethod sm, KeyInfo ki, Key signingKey, KeySelector ks, boolean b64)1406     private static void test_create_signature_external
1407         (SignatureMethod sm, KeyInfo ki, Key signingKey, KeySelector ks,
1408         boolean b64) throws Exception {
1409 
1410         // create reference
1411         Reference ref;
1412         if (b64) {
1413             ref = fac.newReference
1414                 (STYLESHEET_B64,
1415                 sha1, Collections.singletonList
1416                 (fac.newTransform(Transform.BASE64,
1417                  (TransformParameterSpec) null)), null, null);
1418         } else {
1419             ref = fac.newReference(STYLESHEET, sha1);
1420         }
1421 
1422         // create SignedInfo
1423         SignedInfo si = fac.newSignedInfo(withoutComments, sm,
1424             Collections.singletonList(ref));
1425 
1426         Document doc = db.newDocument();
1427 
1428         // create XMLSignature
1429         XMLSignature sig = fac.newXMLSignature(si, ki);
1430 
1431         DOMSignContext dsc = new DOMSignContext(signingKey, doc);
1432         dsc.setURIDereferencer(httpUd);
1433 
1434         sig.sign(dsc);
1435 
1436         DOMValidateContext dvc = new DOMValidateContext
1437             (ks, doc.getDocumentElement());
1438         File f = new File(DATA_DIR);
1439         dvc.setURIDereferencer(httpUd);
1440 
1441         XMLSignature sig2 = fac.unmarshalXMLSignature(dvc);
1442 
1443         if (sig.equals(sig2) == false) {
1444             throw new Exception
1445                 ("Unmarshalled signature is not equal to generated signature");
1446         }
1447         if (sig2.validate(dvc) == false) {
1448             throw new Exception("Validation of generated signature failed");
1449         }
1450     }
1451 
test_create_signature_enveloping(DigestMethod dm, SignatureMethod sm, KeyInfo ki, Key signingKey, KeySelector ks, boolean b64)1452     private static void test_create_signature_enveloping
1453         (DigestMethod dm, SignatureMethod sm, KeyInfo ki, Key signingKey,
1454          KeySelector ks, boolean b64) throws Exception {
1455 
1456         // create reference
1457         Reference ref;
1458         if (b64) {
1459             ref = fac.newReference("#object", dm, Collections.singletonList
1460                 (fac.newTransform(Transform.BASE64,
1461                  (TransformParameterSpec) null)), null, null);
1462         } else {
1463             ref = fac.newReference("#object", dm);
1464         }
1465 
1466         // create SignedInfo
1467         SignedInfo si = fac.newSignedInfo(withoutComments, sm,
1468             Collections.singletonList(ref));
1469 
1470         Document doc = db.newDocument();
1471         // create Objects
1472         String text = b64 ? "c29tZSB0ZXh0" : "some text";
1473         XMLObject obj = fac.newXMLObject(Collections.singletonList
1474             (new DOMStructure(doc.createTextNode(text))),
1475             "object", null, null);
1476 
1477         // create XMLSignature
1478         XMLSignature sig = fac.newXMLSignature
1479             (si, ki, Collections.singletonList(obj), null, null);
1480 
1481         DOMSignContext dsc = new DOMSignContext(signingKey, doc);
1482 
1483         sig.sign(dsc);
1484 
1485 //        dumpDocument(doc, new FileWriter("/tmp/foo.xml"));
1486 
1487         DOMValidateContext dvc = new DOMValidateContext
1488             (ks, doc.getDocumentElement());
1489         XMLSignature sig2 = fac.unmarshalXMLSignature(dvc);
1490 
1491         if (sig.equals(sig2) == false) {
1492             throw new Exception
1493                 ("Unmarshalled signature is not equal to generated signature");
1494         }
1495         if (sig2.validate(dvc) == false) {
1496             throw new Exception("Validation of generated signature failed");
1497         }
1498     }
1499 
test_create_exc_signature()1500     static void test_create_exc_signature() throws Exception {
1501         System.out.println("* Generating exc_signature.xml");
1502         List<Reference> refs = new ArrayList<>(4);
1503 
1504         // create reference 1
1505         refs.add(fac.newReference
1506             ("#xpointer(id('to-be-signed'))", sha1,
1507              Collections.singletonList
1508                 (fac.newTransform(CanonicalizationMethod.EXCLUSIVE,
1509                  (TransformParameterSpec) null)),
1510              null, null));
1511 
1512         // create reference 2
1513         List<String> prefixList = new ArrayList<>(2);
1514         prefixList.add("bar");
1515         prefixList.add("#default");
1516         ExcC14NParameterSpec params = new ExcC14NParameterSpec(prefixList);
1517         refs.add(fac.newReference
1518             ("#xpointer(id('to-be-signed'))", sha1,
1519              Collections.singletonList
1520                 (fac.newTransform(CanonicalizationMethod.EXCLUSIVE, params)),
1521              null, null));
1522 
1523         // create reference 3
1524         refs.add(fac.newReference
1525             ("#xpointer(id('to-be-signed'))", sha1,
1526              Collections.singletonList(fac.newTransform
1527                 (CanonicalizationMethod.EXCLUSIVE_WITH_COMMENTS,
1528                  (TransformParameterSpec) null)),
1529              null, null));
1530 
1531         // create reference 4
1532         prefixList = new ArrayList<>(2);
1533         prefixList.add("bar");
1534         prefixList.add("#default");
1535         params = new ExcC14NParameterSpec(prefixList);
1536         refs.add(fac.newReference
1537             ("#xpointer(id('to-be-signed'))", sha1,
1538              Collections.singletonList(fac.newTransform
1539                 (CanonicalizationMethod.EXCLUSIVE_WITH_COMMENTS, params)),
1540              null, null));
1541 
1542         // create SignedInfo
1543         SignedInfo si = fac.newSignedInfo(
1544             fac.newCanonicalizationMethod
1545                 (CanonicalizationMethod.EXCLUSIVE,
1546                  (C14NMethodParameterSpec) null),
1547                     dsaSha1, refs);
1548 
1549         // create KeyInfo
1550         List<XMLStructure> kits = new ArrayList<>(2);
1551         kits.add(kifac.newKeyValue(validatingKey));
1552         KeyInfo ki = kifac.newKeyInfo(kits);
1553 
1554         // create Objects
1555         Document doc = db.newDocument();
1556         Element baz = doc.createElementNS("urn:bar", "bar:Baz");
1557         Comment com = doc.createComment(" comment ");
1558         baz.appendChild(com);
1559         XMLObject obj = fac.newXMLObject(Collections.singletonList
1560             (new DOMStructure(baz)), "to-be-signed", null, null);
1561 
1562         // create XMLSignature
1563         XMLSignature sig = fac.newXMLSignature
1564             (si, ki, Collections.singletonList(obj), null, null);
1565 
1566         Element foo = doc.createElementNS("urn:foo", "Foo");
1567         foo.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns", "urn:foo");
1568         foo.setAttributeNS
1569             ("http://www.w3.org/2000/xmlns/", "xmlns:bar", "urn:bar");
1570         doc.appendChild(foo);
1571 
1572         DOMSignContext dsc = new DOMSignContext(signingKey, foo);
1573         dsc.putNamespacePrefix(XMLSignature.XMLNS, "dsig");
1574 
1575         sig.sign(dsc);
1576 
1577 //      dumpDocument(doc, new FileWriter("/tmp/foo.xml"));
1578 
1579         DOMValidateContext dvc = new DOMValidateContext
1580             (new KeySelectors.KeyValueKeySelector(), foo.getLastChild());
1581         XMLSignature sig2 = fac.unmarshalXMLSignature(dvc);
1582 
1583         if (sig.equals(sig2) == false) {
1584             throw new Exception
1585                 ("Unmarshalled signature is not equal to generated signature");
1586         }
1587         if (sig2.validate(dvc) == false) {
1588             throw new Exception("Validation of generated signature failed");
1589         }
1590         System.out.println();
1591     }
1592 
test_create_sign_spec()1593     static void test_create_sign_spec() throws Exception {
1594         System.out.println("* Generating sign-spec.xml");
1595         List<Reference> refs = new ArrayList<>(2);
1596 
1597         // create reference 1
1598         List<XPathType> types = new ArrayList<>(3);
1599         types.add(new XPathType(" //ToBeSigned ", XPathType.Filter.INTERSECT));
1600         types.add(new XPathType(" //NotToBeSigned ",
1601             XPathType.Filter.SUBTRACT));
1602         types.add(new XPathType(" //ReallyToBeSigned ",
1603             XPathType.Filter.UNION));
1604         XPathFilter2ParameterSpec xp1 = new XPathFilter2ParameterSpec(types);
1605         refs.add(fac.newReference("", sha1,
1606              Collections.singletonList(fac.newTransform(Transform.XPATH2, xp1)),
1607              null, null));
1608 
1609         // create reference 2
1610         List<Transform> trans2 = new ArrayList<>(2);
1611         trans2.add(fac.newTransform(Transform.ENVELOPED,
1612             (TransformParameterSpec) null));
1613         XPathFilter2ParameterSpec xp2 = new XPathFilter2ParameterSpec
1614             (Collections.singletonList
1615                 (new XPathType(" / ", XPathType.Filter.UNION)));
1616         trans2.add(fac.newTransform(Transform.XPATH2, xp2));
1617         refs.add(fac.newReference("#signature-value", sha1, trans2, null, null));
1618 
1619         // create SignedInfo
1620         SignedInfo si = fac.newSignedInfo(
1621             fac.newCanonicalizationMethod
1622                 (CanonicalizationMethod.INCLUSIVE,
1623                  (C14NMethodParameterSpec) null),
1624                     dsaSha1, refs);
1625 
1626         // create KeyInfo
1627         List<XMLStructure> kits = new ArrayList<>(2);
1628         kits.add(kifac.newKeyValue(validatingKey));
1629         List<Object> xds = new ArrayList<>(2);
1630         xds.add("CN=User");
1631         xds.add(signingCert);
1632         kits.add(kifac.newX509Data(xds));
1633         KeyInfo ki = kifac.newKeyInfo(kits);
1634 
1635         // create XMLSignature
1636         XMLSignature sig = fac.newXMLSignature
1637             (si, ki, null, null, "signature-value");
1638 
1639         Document doc = db.newDocument();
1640         Element tbs1 = doc.createElementNS(null, "ToBeSigned");
1641         Comment tbs1Com = doc.createComment(" comment ");
1642         Element tbs1Data = doc.createElementNS(null, "Data");
1643         Element tbs1ntbs = doc.createElementNS(null, "NotToBeSigned");
1644         Element tbs1rtbs = doc.createElementNS(null, "ReallyToBeSigned");
1645         Comment tbs1rtbsCom = doc.createComment(" comment ");
1646         Element tbs1rtbsData = doc.createElementNS(null, "Data");
1647         tbs1rtbs.appendChild(tbs1rtbsCom);
1648         tbs1rtbs.appendChild(tbs1rtbsData);
1649         tbs1ntbs.appendChild(tbs1rtbs);
1650         tbs1.appendChild(tbs1Com);
1651         tbs1.appendChild(tbs1Data);
1652         tbs1.appendChild(tbs1ntbs);
1653 
1654         Element tbs2 = doc.createElementNS(null, "ToBeSigned");
1655         Element tbs2Data = doc.createElementNS(null, "Data");
1656         Element tbs2ntbs = doc.createElementNS(null, "NotToBeSigned");
1657         Element tbs2ntbsData = doc.createElementNS(null, "Data");
1658         tbs2ntbs.appendChild(tbs2ntbsData);
1659         tbs2.appendChild(tbs2Data);
1660         tbs2.appendChild(tbs2ntbs);
1661 
1662         Element document = doc.createElementNS(null, "Document");
1663         document.appendChild(tbs1);
1664         document.appendChild(tbs2);
1665         doc.appendChild(document);
1666 
1667         DOMSignContext dsc = new DOMSignContext(signingKey, document);
1668 
1669         sig.sign(dsc);
1670 
1671 //      dumpDocument(doc, new FileWriter("/tmp/foo.xml"));
1672 
1673         DOMValidateContext dvc = new DOMValidateContext
1674             (new KeySelectors.KeyValueKeySelector(), document.getLastChild());
1675         XMLSignature sig2 = fac.unmarshalXMLSignature(dvc);
1676 
1677         if (sig.equals(sig2) == false) {
1678             throw new Exception
1679                 ("Unmarshalled signature is not equal to generated signature");
1680         }
1681         if (sig2.validate(dvc) == false) {
1682             throw new Exception("Validation of generated signature failed");
1683         }
1684         System.out.println();
1685     }
1686 
1687     // Only print if there is an error.
test_create_detached_signature( String canonicalizationMethod, String signatureMethod, String digestMethod, String transform, KeyInfoType keyInfo, Content contentType, int port, boolean expectedFailure, Class expectedException)1688     static void test_create_detached_signature(
1689             String canonicalizationMethod, String signatureMethod,
1690             String digestMethod, String transform, KeyInfoType keyInfo,
1691             Content contentType, int port, boolean expectedFailure,
1692             Class expectedException) {
1693 
1694         String title = "\nTest detached signature:"
1695                 + "\n    Canonicalization method: " + canonicalizationMethod
1696                 + "\n    Signature method: " + signatureMethod
1697                 + "\n    Transform: " + transform
1698                 + "\n    Digest method: " + digestMethod
1699                 + "\n    KeyInfoType: " + keyInfo
1700                 + "\n    Content type: " + contentType
1701                 + "\n    Expected failure: " + (expectedFailure ? "yes" : "no")
1702                 + "\n    Expected exception: " + (expectedException == null ?
1703                             "no" : expectedException.getName());
1704 
1705         try {
1706             boolean success = test_create_detached_signature0(
1707                     canonicalizationMethod,
1708                     signatureMethod,
1709                     digestMethod,
1710                     transform,
1711                     keyInfo,
1712                     contentType,
1713                     port);
1714 
1715             if (success && expectedFailure) {
1716                 System.out.println(title);
1717                 System.out.println("Signature validation unexpectedly passed");
1718                 result = false;
1719             } else if (!success && !expectedFailure) {
1720                 System.out.println(title);
1721                 System.out.println("Signature validation unexpectedly failed");
1722                 result = false;
1723             } else if (expectedException != null) {
1724                 System.out.println(title);
1725                 System.out.println("Expected " + expectedException
1726                         + " not thrown");
1727                 result = false;
1728             }
1729         } catch (Exception e) {
1730             if (expectedException == null
1731                     || !e.getClass().isAssignableFrom(expectedException)) {
1732                 System.out.println(title);
1733                 System.out.println("Unexpected exception: " + e);
1734                 e.printStackTrace(System.out);
1735                 result = false;
1736             }
1737         }
1738     }
1739 
1740     // Print out as little as possible. This method will be called many times.
test_create_detached_signature0(String canonicalizationMethod, String signatureMethod, String digestMethod, String transform, KeyInfoType keyInfo, Content contentType, int port)1741     static boolean test_create_detached_signature0(String canonicalizationMethod,
1742             String signatureMethod, String digestMethod, String transform,
1743             KeyInfoType keyInfo, Content contentType, int port)
1744             throws Exception {
1745 
1746         System.out.print("-S");
1747 
1748         DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
1749         dbf.setNamespaceAware(true);
1750         dbf.setValidating(false);
1751 
1752         // Create SignedInfo
1753         DigestMethod dm = fac.newDigestMethod(digestMethod, null);
1754 
1755         List transformList = null;
1756         if (transform != null) {
1757             TransformParameterSpec params = null;
1758             switch (transform) {
1759                 case Transform.XPATH:
1760                     params = new XPathFilterParameterSpec("//.");
1761                     break;
1762                 case Transform.XPATH2:
1763                     params = new XPathFilter2ParameterSpec(
1764                             Collections.singletonList(new XPathType("//.",
1765                                     XPathType.Filter.INTERSECT)));
1766                     break;
1767                 case Transform.XSLT:
1768                     Element element = dbf.newDocumentBuilder()
1769                             .parse(new ByteArrayInputStream(xslt.getBytes()))
1770                             .getDocumentElement();
1771                     DOMStructure stylesheet = new DOMStructure(element);
1772                     params = new XSLTTransformParameterSpec(stylesheet);
1773                     break;
1774             }
1775             transformList = Collections.singletonList(fac.newTransform(
1776                     transform, params));
1777         }
1778 
1779         String url = String.format("http://localhost:%d/%s", port, contentType);
1780         List refs = Collections.singletonList(fac.newReference(url, dm,
1781                 transformList, null, null));
1782 
1783         CanonicalizationMethod cm = fac.newCanonicalizationMethod(
1784                 canonicalizationMethod, (C14NMethodParameterSpec) null);
1785 
1786         SignatureMethod sm = fac.newSignatureMethod(signatureMethod, null);
1787 
1788         Key[] pair = getCachedKeys(signatureMethod);
1789         Key signingKey = pair[0];
1790         Key validationKey = pair[1];
1791 
1792         SignedInfo si = fac.newSignedInfo(cm, sm, refs, null);
1793 
1794         // Create KeyInfo
1795         KeyInfoFactory kif = fac.getKeyInfoFactory();
1796         List list = null;
1797         if (keyInfo == KeyInfoType.KeyValue) {
1798             if (validationKey instanceof PublicKey) {
1799                 KeyValue kv = kif.newKeyValue((PublicKey) validationKey);
1800                 list = Collections.singletonList(kv);
1801             }
1802         } else if (keyInfo == KeyInfoType.x509data) {
1803             list = Collections.singletonList(
1804                     kif.newX509Data(Collections.singletonList("cn=Test")));
1805         } else if (keyInfo == KeyInfoType.KeyName) {
1806             list = Collections.singletonList(kif.newKeyName("Test"));
1807         } else {
1808             throw new RuntimeException("Unexpected KeyInfo: " + keyInfo);
1809         }
1810         KeyInfo ki = list != null ? kif.newKeyInfo(list) : null;
1811 
1812         // Create an empty doc for detached signature
1813         Document doc = dbf.newDocumentBuilder().newDocument();
1814         DOMSignContext xsc = new DOMSignContext(signingKey, doc);
1815 
1816         // Generate signature
1817         XMLSignature signature = fac.newXMLSignature(si, ki);
1818         signature.sign(xsc);
1819 
1820         // Save signature
1821         String signatureString;
1822         try (StringWriter writer = new StringWriter()) {
1823             TransformerFactory tf = TransformerFactory.newInstance();
1824             Transformer trans = tf.newTransformer();
1825             Node parent = xsc.getParent();
1826             trans.transform(new DOMSource(parent), new StreamResult(writer));
1827             signatureString = writer.toString();
1828         }
1829 
1830         System.out.print("V");
1831         try (ByteArrayInputStream bis = new ByteArrayInputStream(
1832                 signatureString.getBytes())) {
1833             doc = dbf.newDocumentBuilder().parse(bis);
1834         }
1835 
1836         NodeList nodeLst = doc.getElementsByTagName("Signature");
1837         Node node = nodeLst.item(0);
1838         if (node == null) {
1839             throw new RuntimeException("Couldn't find Signature element");
1840         }
1841         if (!(node instanceof Element)) {
1842             throw new RuntimeException("Unexpected node type");
1843         }
1844         Element sig = (Element) node;
1845 
1846         // Validate signature
1847         DOMValidateContext vc = new DOMValidateContext(validationKey, sig);
1848         vc.setProperty("org.jcp.xml.dsig.secureValidation", Boolean.FALSE);
1849         signature = fac.unmarshalXMLSignature(vc);
1850 
1851         boolean success = signature.validate(vc);
1852         if (!success) {
1853             System.out.print("x");
1854             return false;
1855         }
1856 
1857         success = signature.getSignatureValue().validate(vc);
1858         if (!success) {
1859             System.out.print("X");
1860             return false;
1861         }
1862 
1863         return true;
1864     }
1865 
getCachedKeys(String signatureMethod)1866     private static Key[] getCachedKeys(String signatureMethod) {
1867         return cachedKeys.computeIfAbsent(signatureMethod, sm -> {
1868             try {
1869                 System.out.print("<create keys for " + sm + ">");
1870                 System.out.flush();
1871                 if (sm.contains("#hmac-")) {
1872                     // http://...#hmac-sha1 -> hmac-sha1 -> hmacsha1
1873                     String algName = sm
1874                             .substring(sm.indexOf('#') + 1)
1875                             .replace("-", "");
1876                     KeyGenerator kg = KeyGenerator.getInstance(algName);
1877                     Key signingKey = kg.generateKey();
1878                     return new Key[] { signingKey, signingKey};
1879                 } else {
1880                     KeyPairGenerator kpg;
1881                     if (sm.contains("#rsa-")
1882                             || sm.contains("-rsa-MGF1")) {
1883                         kpg = KeyPairGenerator.getInstance("RSA");
1884                         kpg.initialize(
1885                                 sm.contains("#sha512-rsa-MGF1") ? 2048 : 1024);
1886                     } else if (sm.contains("#dsa-")) {
1887                         kpg = KeyPairGenerator.getInstance("DSA");
1888                         kpg.initialize(1024);
1889                     } else if (sm.contains("#ecdsa-")) {
1890                         kpg = KeyPairGenerator.getInstance("EC");
1891                         kpg.initialize(256);
1892                     } else {
1893                         throw new RuntimeException("Unsupported signature algorithm");
1894                     }
1895                     KeyPair kp = kpg.generateKeyPair();
1896                     return new Key[] { kp.getPrivate(), kp.getPublic()};
1897                 }
1898             } catch (NoSuchAlgorithmException e) {
1899                 throw new AssertionError("Should not happen", e);
1900             }
1901         });
1902     }
1903 
1904     private static final String DSA_Y =
1905         "070662842167565771936588335128634396171789331656318483584455493822" +
1906         "400811200853331373030669235424928346190274044631949560438023934623" +
1907         "71310375123430985057160";
1908     private static final String DSA_P =
1909         "013232376895198612407547930718267435757728527029623408872245156039" +
1910         "757713029036368719146452186041204237350521785240337048752071462798" +
1911         "273003935646236777459223";
1912     private static final String DSA_Q =
1913         "0857393771208094202104259627990318636601332086981";
1914     private static final String DSA_G =
1915         "054216440574364751416096484883257051280474283943804743768346673007" +
1916         "661082626139005426812890807137245973106730741193551360857959820973" +
1917         "90670890367185141189796";
1918     private static final String DSA_X =
1919         "0527140396812450214498055937934275626078768840117";
1920     private static final String DSA_2048_Y =
1921         "15119007057343785981993995134621348945077524760182795513668325877793414638620983617627033248732235626178802906346261435991040697338468329634416089753032362617771631199351767336660070462291411472735835843440140283101463231807789628656218830720378705090795271104661936237385140354825159080766174663596286149653433914842868551355716015585570827642835307073681358328172009941968323702291677280809277843998510864653406122348712345584706761165794179850728091522094227603562280855104749858249588234915206290448353957550635709520273178475097150818955098638774564910092913714625772708285992586894795017709678223469405896699928";
1922     private static final String DSA_2048_P =
1923         "18111848663142005571178770624881214696591339256823507023544605891411707081617152319519180201250440615163700426054396403795303435564101919053459832890139496933938670005799610981765220283775567361483662648340339405220348871308593627647076689407931875483406244310337925809427432681864623551598136302441690546585427193224254314088256212718983105131138772434658820375111735710449331518776858786793875865418124429269409118756812841019074631004956409706877081612616347900606555802111224022921017725537417047242635829949739109274666495826205002104010355456981211025738812433088757102520562459649777989718122219159982614304359";
1924     private static final String DSA_2048_Q =
1925         "19689526866605154788513693571065914024068069442724893395618704484701";
1926     private static final String DSA_2048_G =
1927         "2859278237642201956931085611015389087970918161297522023542900348087718063098423976428252369340967506010054236052095950169272612831491902295835660747775572934757474194739347115870723217560530672532404847508798651915566434553729839971841903983916294692452760249019857108409189016993380919900231322610083060784269299257074905043636029708121288037909739559605347853174853410208334242027740275688698461842637641566056165699733710043802697192696426360843173620679214131951400148855611740858610821913573088059404459364892373027492936037789337011875710759208498486908611261954026964574111219599568903257472567764789616958430";
1928     private static final String DSA_2048_X =
1929         "14562787764977288900757387442281559936279834964901963465277698843172";
1930     private static final String RSA_MOD =
1931         "010800185049102889923150759252557522305032794699952150943573164381" +
1932         "936603255999071981574575044810461362008102247767482738822150129277" +
1933         "490998033971789476107463";
1934     private static final String RSA_PRIV =
1935         "016116973584421969795445996229612671947635798429212816611707210835" +
1936         "915586591340598683996088487065438751488342251960069575392056288063" +
1937         "6800379454345804879553";
1938     private static final String RSA_PUB = "065537";
1939     private static final String RSA_1024_MOD = "098871307553789439961130765" +
1940         "909423744508062468450669519128736624058048856940468016843888594585" +
1941         "322862378444314635412341974900625010364163960238734457710620107530" +
1942         "573945081856371709138380902553309075505688814637544923038853658690" +
1943         "857672483016239697038853418682988686871489963827000080098971762923" +
1944         "833614557257607521";
1945     private static final String RSA_1024_PRIV = "03682574144968491431483287" +
1946         "297021581096848810374110568017963075809477047466189822987258068867" +
1947         "704855380407747867998863645890602646601140183818953428006646987710" +
1948         "237008997971129772408397621801631622129297063463868593083106979716" +
1949         "204903524890556839550490384015324575598723478554854070823335021842" +
1950         "210112348400928769";
1951     private static final String RSA_2048_MOD = "243987087691547796017401146540"
1952         + "9844666035826535295137885613771811531602666348704672255163984907599"
1953         + "4298308997053582963763109207465354916871136820987101812436158377530"
1954         + "6117270010853232249007544652859474372258057062943608962079402484091"
1955         + "8121307687901225514249308620012025884376216406019656605767311580224"
1956         + "4715304950770504195751384382230005665573033547124060755957932161045"
1957         + "7288008201789401237690181537646952377591671113513382933711547044631"
1958         + "6055957820531234310030119265612054594720774653570278810236807313332"
1959         + "5293876225940483622056721445101719346295263740434720907474414905706"
1960         + "086605825077661246082956613711071075569880930102141";
1961     private static final String RSA_2048_PRIV = "12265063405401593206575340300"
1962         + "5824698296458954796982342251774894076489082263237675553422307220014"
1963         + "4395010131540855227949365446755185799985229111139387016816011165826"
1964         + "5498929552020323994756478872375078784799489891112924298115119573429"
1965         + "3677627114115546751555523555375278381312502020990154549150867571006"
1966         + "4470674155961982582802981649643127000520693025433874996570667724459"
1967         + "3395670697152709457274026580106078581585077146782827694403672461289"
1968         + "9143004401242754355097671446183871158504602884373174300123820136505"
1969         + "6449932139773607305129273545117363975014750743804523418307647791195"
1970         + "6408859873123458434820062206102268853256685162004893";
1971     private static final String EC_P256_X =
1972         "335863644451761614592446380116804721648611739647823420286081723541" +
1973         "6166183710";
1974     private static final String EC_P256_Y =
1975         "951559601159729477487064127150143688502130342917782252098602422796" +
1976         "95457910701";
1977     private static final String EC_P256_S =
1978         "425976209773168452211813225517384419928639977904006759709292218082" +
1979         "7440083936";
1980     private static final ECParameterSpec EC_P256_PARAMS = initECParams(
1981         "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF",
1982         "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC",
1983         "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B",
1984         "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296",
1985         "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5",
1986         "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551",
1987         1
1988     );
1989     private static final String EC_P384_X =
1990         "12144058647679082341340699736608428955270957565259459672517275506071643671835484144490620216582303669654008841724053";
1991     private static final String EC_P384_Y =
1992         "18287745972107701566600963632634101287058332546756092926848497481238534346489545826483592906634896557151987868614320";
1993     private static final String EC_P384_S =
1994         "10307785759830534742680442271492590599236624208247590184679565032330507874096079979152605984203102224450595283943382";
1995     private static final ECParameterSpec EC_P384_PARAMS = initECParams(
1996         "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF",
1997         "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC",
1998         "B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF",
1999         "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7",
2000         "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F",
2001         "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973",
2002         1
2003     );
2004     private static final String EC_P521_X =
2005         "4157918188927862838251799402582135611021257663417126086145819679867926857146776190737187582274664373117054717389603317411991660346043842712448912355335343997";
2006     private static final String EC_P521_Y =
2007         "4102838062751704796157456866854813794620023146924181568434486703918224542844053923233919899911519054998554969832861957437850996213216829205401947264294066288";
2008     private static final String EC_P521_S =
2009         "4857798533181496041050215963883119936300918353498701880968530610687256097257307590162398707429640390843595868713096292822034014722985178583665959048714417342";
2010     private static final ECParameterSpec EC_P521_PARAMS = initECParams(
2011         "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
2012         "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC",
2013         "0051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00",
2014         "00C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66",
2015         "011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650",
2016         "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409",
2017         1
2018     );
2019 
2020     private static ECParameterSpec initECParams(
2021             String sfield, String a, String b, String gx, String gy,
2022             String n, int h) {
2023         ECField field = new ECFieldFp(bigInt(sfield));
2024         EllipticCurve curve = new EllipticCurve(field,
2025                                                 bigInt(a), bigInt(b));
2026         ECPoint g = new ECPoint(bigInt(gx), bigInt(gy));
2027         return new ECParameterSpec(curve, g, bigInt(n), h);
2028     }
2029 
2030     private static BigInteger bigInt(String s) {
2031         return new BigInteger(s, 16);
2032     }
2033     private static PublicKey getPublicKey(String algo, int keysize)
2034         throws Exception {
2035         KeyFactory kf = KeyFactory.getInstance(algo);
2036         KeySpec kspec;
2037         if (algo.equalsIgnoreCase("DSA")) {
2038             if (keysize == 1024) {
2039                 kspec = new DSAPublicKeySpec(new BigInteger(DSA_Y),
2040                                              new BigInteger(DSA_P),
2041                                              new BigInteger(DSA_Q),
2042                                              new BigInteger(DSA_G));
2043             } else if (keysize == 2048) {
2044                 kspec = new DSAPublicKeySpec(new BigInteger(DSA_2048_Y),
2045                                              new BigInteger(DSA_2048_P),
2046                                              new BigInteger(DSA_2048_Q),
2047                                              new BigInteger(DSA_2048_G));
2048             } else throw new RuntimeException("Unsupported keysize:" + keysize);
2049         } else if (algo.equalsIgnoreCase("RSA")) {
2050             if (keysize == 512) {
2051                 kspec = new RSAPublicKeySpec(new BigInteger(RSA_MOD),
2052                                              new BigInteger(RSA_PUB));
2053             } else if (keysize == 1024) {
2054                 kspec = new RSAPublicKeySpec(new BigInteger(RSA_1024_MOD),
2055                                              new BigInteger(RSA_PUB));
2056             } else if (keysize == 2048) {
2057                 kspec = new RSAPublicKeySpec(new BigInteger(RSA_2048_MOD),
2058                                              new BigInteger(RSA_PUB));
2059             } else throw new RuntimeException("Unsupported keysize:" + keysize);
2060         } else throw new RuntimeException("Unsupported key algorithm " + algo);
2061         return kf.generatePublic(kspec);
2062     }
2063 
2064     private static PublicKey getECPublicKey(String curve) throws Exception {
2065         KeyFactory kf = KeyFactory.getInstance("EC");
2066         String x, y;
2067         ECParameterSpec params;
2068         switch (curve) {
2069             case "P256":
2070                 x = EC_P256_X;
2071                 y = EC_P256_Y;
2072                 params = EC_P256_PARAMS;
2073                 break;
2074             case "P384":
2075                 x = EC_P384_X;
2076                 y = EC_P384_Y;
2077                 params = EC_P384_PARAMS;
2078                 break;
2079             case "P521":
2080                 x = EC_P521_X;
2081                 y = EC_P521_Y;
2082                 params = EC_P521_PARAMS;
2083                 break;
2084             default:
2085                 throw new Exception("Unsupported curve: " + curve);
2086         }
2087         KeySpec kspec = new ECPublicKeySpec(new ECPoint(new BigInteger(x),
2088                                                         new BigInteger(y)),
2089                                             params);
2090         return kf.generatePublic(kspec);
2091     }
2092 
2093     private static PrivateKey getPrivateKey(String algo, int keysize)
2094         throws Exception {
2095         KeyFactory kf = KeyFactory.getInstance(algo);
2096         KeySpec kspec;
2097         if (algo.equalsIgnoreCase("DSA")) {
2098             if (keysize == 1024) {
2099                 kspec = new DSAPrivateKeySpec
2100                     (new BigInteger(DSA_X), new BigInteger(DSA_P),
2101                      new BigInteger(DSA_Q), new BigInteger(DSA_G));
2102             } else if (keysize == 2048) {
2103                 kspec = new DSAPrivateKeySpec
2104                     (new BigInteger(DSA_2048_X), new BigInteger(DSA_2048_P),
2105                      new BigInteger(DSA_2048_Q), new BigInteger(DSA_2048_G));
2106             } else throw new RuntimeException("Unsupported keysize:" + keysize);
2107         } else if (algo.equalsIgnoreCase("RSA")) {
2108             if (keysize == 512) {
2109                 kspec = new RSAPrivateKeySpec
2110                     (new BigInteger(RSA_MOD), new BigInteger(RSA_PRIV));
2111             } else if (keysize == 1024) {
2112                 kspec = new RSAPrivateKeySpec(new BigInteger(RSA_1024_MOD),
2113                         new BigInteger(RSA_1024_PRIV));
2114             } else if (keysize == 2048) {
2115                 kspec = new RSAPrivateKeySpec(new BigInteger(RSA_2048_MOD),
2116                         new BigInteger(RSA_2048_PRIV));
2117             } else throw new RuntimeException("Unsupported key algorithm " + algo);
2118         } else throw new RuntimeException("Unsupported key algorithm " + algo);
2119         return kf.generatePrivate(kspec);
2120     }
2121 
2122     private static PrivateKey getECPrivateKey(String curve) throws Exception {
2123         String s;
2124         ECParameterSpec params;
2125         switch (curve) {
2126             case "P256":
2127                 s = EC_P256_S;
2128                 params = EC_P256_PARAMS;
2129                 break;
2130             case "P384":
2131                 s = EC_P384_S;
2132                 params = EC_P384_PARAMS;
2133                 break;
2134             case "P521":
2135                 s = EC_P521_S;
2136                 params = EC_P521_PARAMS;
2137                 break;
2138             default:
2139                 throw new Exception("Unsupported curve: " + curve);
2140         }
2141         KeyFactory kf = KeyFactory.getInstance("EC");
2142         KeySpec kspec = new ECPrivateKeySpec(new BigInteger(s), params);
2143         return kf.generatePrivate(kspec);
2144     }
2145 
2146     private static SecretKey getSecretKey(final byte[] secret) {
2147         return new SecretKey() {
2148             public String getFormat()   { return "RAW"; }
2149             public byte[] getEncoded()  { return secret; }
2150             public String getAlgorithm(){ return "SECRET"; }
2151         };
2152     }
2153 
2154     /**
2155      * This URIDereferencer returns locally cached copies of http content to
2156      * avoid test failures due to network glitches, etc.
2157      */
2158     private static class HttpURIDereferencer implements URIDereferencer {
2159         private URIDereferencer defaultUd;
2160 
2161         HttpURIDereferencer() {
2162             defaultUd = XMLSignatureFactory.getInstance().getURIDereferencer();
2163         }
2164 
2165         public Data dereference(final URIReference ref, XMLCryptoContext ctx)
2166         throws URIReferenceException {
2167             String uri = ref.getURI();
2168             if (uri.equals(STYLESHEET) || uri.equals(STYLESHEET_B64)) {
2169                 try {
2170                     FileInputStream fis = new FileInputStream(new File
2171                         (DATA_DIR, uri.substring(uri.lastIndexOf('/'))));
2172                     return new OctetStreamData(fis,ref.getURI(),ref.getType());
2173                 } catch (Exception e) { throw new URIReferenceException(e); }
2174             } else if (uri.startsWith("certs/")) {
2175                 try {
2176                     FileInputStream fis = new FileInputStream(new File
2177                             (DATA_DIR, uri));
2178                     return new OctetStreamData(fis,ref.getURI(),ref.getType());
2179                 } catch (Exception e) { throw new URIReferenceException(e); }
2180             }
2181 
2182             // fallback on builtin deref
2183             return defaultUd.dereference(ref, ctx);
2184         }
2185     }
2186 
2187     // local http server
2188     static class Http implements HttpHandler, AutoCloseable {
2189 
2190         private final HttpServer server;
2191 
2192         private Http(HttpServer server) {
2193             this.server = server;
2194         }
2195 
2196         static Http startServer() throws IOException {
2197             HttpServer server = HttpServer.create(new InetSocketAddress(0), 0);
2198             return new Http(server);
2199         }
2200 
2201         void start() {
2202             server.createContext("/", this);
2203             server.start();
2204         }
2205 
2206         void stop() {
2207             server.stop(0);
2208         }
2209 
2210         int getPort() {
2211             return server.getAddress().getPort();
2212         }
2213 
2214         @Override
2215         public void handle(HttpExchange t) throws IOException {
2216             try {
2217                 String type;
2218                 String path = t.getRequestURI().getPath();
2219                 if (path.startsWith("/")) {
2220                     type = path.substring(1);
2221                 } else {
2222                     type = path;
2223                 }
2224 
2225                 String contentTypeHeader = "";
2226                 byte[] output = new byte[] {};
2227                 int code = 200;
2228                 Content testContentType = Content.valueOf(type);
2229                 switch (testContentType) {
2230                     case Base64:
2231                         contentTypeHeader = "application/octet-stream";
2232                         output = "VGVzdA==".getBytes();
2233                         break;
2234                     case Text:
2235                         contentTypeHeader = "text/plain";
2236                         output = "Text".getBytes();
2237                         break;
2238                     case Xml:
2239                         contentTypeHeader = "application/xml";
2240                         output = "<tag>test</tag>".getBytes();
2241                         break;
2242                     case NotExisitng:
2243                         code = 404;
2244                         break;
2245                     default:
2246                         throw new IOException("Unknown test content type");
2247                 }
2248 
2249                 t.getResponseHeaders().set("Content-Type", contentTypeHeader);
2250                 t.sendResponseHeaders(code, output.length);
2251                 t.getResponseBody().write(output);
2252             } catch (IOException e) {
2253                 System.out.println("Exception: " + e);
2254                 t.sendResponseHeaders(500, 0);
2255             }
2256             t.close();
2257         }
2258 
2259         @Override
2260         public void close() {
2261             stop();
2262         }
2263     }
2264 }
2265