1 /**
2  * Licensed to the Apache Software Foundation (ASF) under one
3  * or more contributor license agreements. See the NOTICE file
4  * distributed with this work for additional information
5  * regarding copyright ownership. The ASF licenses this file
6  * to you under the Apache License, Version 2.0 (the
7  * "License"); you may not use this file except in compliance
8  * with the License. You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing,
13  * software distributed under the License is distributed on an
14  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15  * KIND, either express or implied. See the License for the
16  * specific language governing permissions and limitations
17  * under the License.
18  */
19 /*
20  * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
21  */
22 package javax.xml.crypto.test.dsig;
23 
24 import java.io.*;
25 import java.security.*;
26 import java.security.spec.*;
27 import java.util.*;
28 import javax.crypto.SecretKey;
29 import javax.xml.crypto.dsig.*;
30 import javax.xml.crypto.dsig.dom.DOMValidateContext;
31 import javax.xml.crypto.dsig.spec.*;
32 import javax.xml.crypto.dom.*;
33 import javax.xml.crypto.*;
34 import java.math.BigInteger;
35 import javax.xml.transform.*;
36 import javax.xml.transform.dom.*;
37 import javax.xml.transform.stream.StreamResult;
38 import javax.xml.parsers.DocumentBuilder;
39 import javax.xml.parsers.DocumentBuilderFactory;
40 import org.w3c.dom.*;
41 
42 /*
43  * @author Sean Mullan
44  * @author Valerie Peng
45  */
46 public class TestUtils {
47 
48     private static final String DSA_Y =
49         "07066284216756577193658833512863439617178933165631848358445549382240081120085333137303066923542492834619027404463194956043802393462371310375123430985057160";
50     private static final String DSA_P =
51         "013232376895198612407547930718267435757728527029623408872245156039757713029036368719146452186041204237350521785240337048752071462798273003935646236777459223";
52     private static final String DSA_Q =
53         "0857393771208094202104259627990318636601332086981";
54     private static final String DSA_G =
55         "05421644057436475141609648488325705128047428394380474376834667300766108262613900542681289080713724597310673074119355136085795982097390670890367185141189796";
56     private static final String DSA_X =
57         "0527140396812450214498055937934275626078768840117";
58     private static final String RSA_MOD =
59         "010800185049102889923150759252557522305032794699952150943573164381936603255999071981574575044810461362008102247767482738822150129277490998033971789476107463";
60     private static final String RSA_PUB = "065537";
61     private static final String RSA_PRIV =
62         "0161169735844219697954459962296126719476357984292128166117072108359155865913405986839960884870654387514883422519600695753920562880636800379454345804879553";
63 
TestUtils()64     private TestUtils() {}
65 
getPublicKey(String algo)66     public static PublicKey getPublicKey(String algo)
67         throws InvalidKeySpecException, NoSuchAlgorithmException {
68         KeyFactory kf = KeyFactory.getInstance(algo);
69         KeySpec kspec;
70         if (algo.equalsIgnoreCase("DSA")) {
71             kspec = new DSAPublicKeySpec(new BigInteger(DSA_Y),
72                                          new BigInteger(DSA_P),
73                                          new BigInteger(DSA_Q),
74                                          new BigInteger(DSA_G));
75         } else if (algo.equalsIgnoreCase("RSA")) {
76             kspec = new RSAPublicKeySpec(new BigInteger(RSA_MOD),
77                                          new BigInteger(RSA_PUB));
78         } else throw new RuntimeException("Unsupported key algorithm " + algo);
79         return kf.generatePublic(kspec);
80     }
81 
getPrivateKey(String algo)82     public static PrivateKey getPrivateKey(String algo)
83         throws InvalidKeySpecException, NoSuchAlgorithmException {
84         KeyFactory kf = KeyFactory.getInstance(algo);
85         KeySpec kspec;
86         if (algo.equalsIgnoreCase("DSA")) {
87             kspec = new DSAPrivateKeySpec
88                 (new BigInteger(DSA_X), new BigInteger(DSA_P),
89                  new BigInteger(DSA_Q), new BigInteger(DSA_G));
90         } else if (algo.equalsIgnoreCase("RSA")) {
91             kspec = new RSAPrivateKeySpec
92                 (new BigInteger(RSA_MOD), new BigInteger(RSA_PRIV));
93         } else throw new RuntimeException("Unsupported key algorithm " + algo);
94         return kf.generatePrivate(kspec);
95     }
96 
getSecretKey(final byte[] secret)97     public static SecretKey getSecretKey(final byte[] secret) {
98         return new SecretKey() {
99             private static final long serialVersionUID = 5629454124145851381L;
100 
101             public String getFormat()	{ return "RAW"; }
102             public byte[] getEncoded()	{ return secret; }
103             public String getAlgorithm(){ return "SECRET"; }
104         };
105     }
106 
newDocument()107     public static Document newDocument() {
108         try {
109             DocumentBuilderFactory docFac =
110                 DocumentBuilderFactory.newInstance();
111             docFac.setNamespaceAware(true);
112             DocumentBuilder docBuilder = docFac.newDocumentBuilder();
113             return docBuilder.newDocument();
114         } catch (Exception ex) {
115             return null;
116         }
117     }
118 
119     public static class MyOwnC14nParameterSpec implements C14NMethodParameterSpec {}
120 
121     public static class MyOwnDigestMethodParameterSpec
122         implements DigestMethodParameterSpec {}
123 
124     public static class MyOwnSignatureMethodParameterSpec
125         implements SignatureMethodParameterSpec {}
126 
getXMLValidateContext(String type, File input, String tag)127     public static XMLValidateContext getXMLValidateContext(String type,
128                                                        File input,
129                                                        String tag)
130         throws Exception {
131         if (type.equalsIgnoreCase("dom")) {
132             DocumentBuilderFactory docFactory =
133                 DocumentBuilderFactory.newInstance();
134             DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
135             Document doc = docBuilder.parse(input);
136             if (tag == null) {
137                 return new DOMValidateContext
138                     (TestUtils.getPublicKey("RSA"), doc.getDocumentElement());
139             } else {
140                 NodeList list = doc.getElementsByTagName(tag);
141                 return new DOMValidateContext
142                     (TestUtils.getPublicKey("RSA"), list.item(0));
143             }
144         } else {
145             throw new Exception("Unsupported XMLValidateContext type: " +
146                                 type);
147         }
148     }
149 
150     public static class MyOwnDOMReference extends DOMStructure
151         implements Reference {
152         private String id;
153         private boolean status;
154         private byte[] digest;
155         private static MessageDigest MD;
156         private static DigestMethod DIG_METHOD;
157         private Data derefData;
158         private InputStream dis;
159         static {
160             try {
161                 MD = MessageDigest.getInstance("SHA");
162                 XMLSignatureFactory factory = XMLSignatureFactory.getInstance
163                     ("DOM", new org.apache.jcp.xml.dsig.internal.dom.XMLDSigRI());
164                 DIG_METHOD =
165                     factory.newDigestMethod(DigestMethod.SHA1, null);
166             } catch (Exception ex) {
167                 // should never be thrown
168             }
169         };
170 
MyOwnDOMReference(String id, boolean status)171         public MyOwnDOMReference(String id, boolean status) {
172             super(newDocument());
173             this.id = id;
174             this.status = status;
175             digest = null;
176         }
177 
getDigestValue()178         public byte[] getDigestValue() {
179             if (digest == null) {
180                 byte[] inBytes = id.getBytes();
181                 digest = new byte[20];
182                 if (status) {
183                     digest = MD.digest(inBytes);
184                 }
185             }
186             return digest;
187         }
188 
getCalculatedDigestValue()189         public byte[] getCalculatedDigestValue() {
190             return null;
191         }
192 
getDigestMethod()193         public DigestMethod getDigestMethod() { return DIG_METHOD; }
194 
getId()195         public String getId() {
196             return id;
197         }
198 
getType()199         public String getType() {
200             return null;
201         }
202 
getURI()203         public String getURI() {
204             return null;
205         }
206 
getTransforms()207         public List<?> getTransforms() {
208             return Collections.EMPTY_LIST;
209         }
210 
validate(XMLValidateContext vCtx)211         public boolean validate(XMLValidateContext vCtx)
212             throws XMLSignatureException {
213             this.dis = new ByteArrayInputStream(id.getBytes());
214             this.derefData = new OctetStreamData(this.dis);
215             return status;
216         }
217 
getDereferencedData()218         public Data getDereferencedData() {
219             return derefData;
220         }
221 
getDigestInputStream()222         public InputStream getDigestInputStream() {
223             return dis;
224         }
225     }
226 
227     public static class MyOwnXMLStructure implements XMLStructure {
228 
isFeatureSupported(String feature)229         public boolean isFeatureSupported(String feature)
230             throws NullPointerException {
231             if (feature == null) throw new NullPointerException();
232             return false;
233         }
234     }
235 
236     public static class OctetStreamURIDereferencer implements URIDereferencer {
237 
238         private byte[] data = null;
239 
OctetStreamURIDereferencer(byte[] in)240         public OctetStreamURIDereferencer(byte[] in) {
241             data = (byte[]) in.clone();
242         }
243 
dereference(URIReference ref, XMLCryptoContext ctxt)244         public Data dereference(URIReference ref, XMLCryptoContext ctxt) {
245             return new OctetStreamData(new ByteArrayInputStream(data));
246         }
247 
getData()248         public byte[] getData() {
249             return data;
250         }
251 
equals(Object obj)252         public boolean equals(Object obj) {
253             if (obj instanceof OctetStreamURIDereferencer) {
254                 return Arrays.equals
255                     (((OctetStreamURIDereferencer) obj).getData(), data);
256             } else {
257                 return false;
258             }
259         }
260 
hashCode()261         public int hashCode() {
262             return 5678;
263         }
264     }
265 
266     public static class NodeSetURIDereferencer implements URIDereferencer {
267 
268         private Node data = null;
269 
NodeSetURIDereferencer(Node node)270         public NodeSetURIDereferencer(Node node) {
271             data = node;
272         }
273 
dereference(URIReference ref, XMLCryptoContext ctxt)274         public Data dereference(URIReference ref, XMLCryptoContext ctxt) {
275             return new NodeSetData() {
276                 public Iterator<?> iterator() {
277                     return Collections.singletonList(data).iterator();
278                 }
279             };
280         }
281     }
282 
283     public static void dumpDocument(Document doc, String outName) throws Exception {
284         DOMSource source = new DOMSource(doc);
285         File path = new File(System.getProperty("test.dir"), outName);
286         Result result = new StreamResult(new FileOutputStream(path));
287         Transformer trans = TransformerFactory.newInstance().newTransformer();
288         trans.setOutputProperty(OutputKeys.INDENT, "yes");
289         trans.transform(source, result);
290     }
291 
292 }
293