Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/test/javax/xml/crypto/dsig/KeySelectors.java
38853 views
1
/*
2
* Copyright (c) 2005, 2018, 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
import java.io.*;
25
import java.security.Key;
26
import java.security.KeyException;
27
import java.security.PublicKey;
28
import java.security.cert.*;
29
import java.util.*;
30
import javax.crypto.SecretKey;
31
import javax.xml.crypto.*;
32
import javax.xml.crypto.dsig.*;
33
import javax.xml.crypto.dsig.keyinfo.*;
34
import sun.security.util.DerValue;
35
import sun.security.x509.X500Name;
36
37
/**
38
* This is a class which supplies several KeySelector implementations
39
*/
40
class KeySelectors {
41
42
/**
43
* KeySelector which would always return the secret key specified in its
44
* constructor.
45
*/
46
static class SecretKeySelector extends KeySelector {
47
private SecretKey key;
48
SecretKeySelector(byte[] bytes) {
49
key = wrapBytes(bytes);
50
}
51
SecretKeySelector(SecretKey key) {
52
this.key = key;
53
}
54
55
public KeySelectorResult select(KeyInfo ki,
56
KeySelector.Purpose purpose,
57
AlgorithmMethod method,
58
XMLCryptoContext context)
59
throws KeySelectorException {
60
return new SimpleKSResult(key);
61
}
62
63
private SecretKey wrapBytes(final byte[] bytes) {
64
return new SecretKey() {
65
public String getFormat() {
66
return "RAW";
67
}
68
69
public String getAlgorithm() {
70
return "Secret key";
71
}
72
73
public byte[] getEncoded() {
74
return bytes.clone();
75
}
76
};
77
}
78
}
79
80
/**
81
* KeySelector which would retrieve the X509Certificate out of the
82
* KeyInfo element and return the public key.
83
* NOTE: If there is an X509CRL in the KeyInfo element, then revoked
84
* certificate will be ignored.
85
*/
86
static class RawX509KeySelector extends KeySelector {
87
88
public KeySelectorResult select(KeyInfo keyInfo,
89
KeySelector.Purpose purpose,
90
AlgorithmMethod method,
91
XMLCryptoContext context)
92
throws KeySelectorException {
93
if (keyInfo == null) {
94
throw new KeySelectorException("Null KeyInfo object!");
95
}
96
// search for X509Data in keyinfo
97
Iterator iter = keyInfo.getContent().iterator();
98
while (iter.hasNext()) {
99
XMLStructure kiType = (XMLStructure) iter.next();
100
if (kiType instanceof X509Data) {
101
X509Data xd = (X509Data) kiType;
102
Object[] entries = xd.getContent().toArray();
103
X509CRL crl = null;
104
// Looking for CRL before finding certificates
105
for (int i = 0; (i<entries.length&&crl != null); i++) {
106
if (entries[i] instanceof X509CRL) {
107
crl = (X509CRL) entries[i];
108
}
109
}
110
Iterator xi = xd.getContent().iterator();
111
boolean hasCRL = false;
112
while (xi.hasNext()) {
113
Object o = xi.next();
114
// skip non-X509Certificate entries
115
if (o instanceof X509Certificate) {
116
if ((purpose != KeySelector.Purpose.VERIFY) &&
117
(crl != null) &&
118
crl.isRevoked((X509Certificate)o)) {
119
continue;
120
} else {
121
return new SimpleKSResult
122
(((X509Certificate)o).getPublicKey());
123
}
124
}
125
}
126
}
127
}
128
throw new KeySelectorException("No X509Certificate found!");
129
}
130
}
131
132
/**
133
* KeySelector which would retrieve the public key out of the
134
* KeyValue element and return it.
135
* NOTE: If the key algorithm doesn't match signature algorithm,
136
* then the public key will be ignored.
137
*/
138
static class KeyValueKeySelector extends KeySelector {
139
public KeySelectorResult select(KeyInfo keyInfo,
140
KeySelector.Purpose purpose,
141
AlgorithmMethod method,
142
XMLCryptoContext context)
143
throws KeySelectorException {
144
if (keyInfo == null) {
145
throw new KeySelectorException("Null KeyInfo object!");
146
}
147
SignatureMethod sm = (SignatureMethod) method;
148
List list = keyInfo.getContent();
149
150
for (int i = 0; i < list.size(); i++) {
151
XMLStructure xmlStructure = (XMLStructure) list.get(i);
152
if (xmlStructure instanceof KeyValue) {
153
PublicKey pk = null;
154
try {
155
pk = ((KeyValue)xmlStructure).getPublicKey();
156
} catch (KeyException ke) {
157
throw new KeySelectorException(ke);
158
}
159
// make sure algorithm is compatible with method
160
if (algEquals(sm.getAlgorithm(), pk.getAlgorithm())) {
161
return new SimpleKSResult(pk);
162
}
163
}
164
}
165
throw new KeySelectorException("No KeyValue element found!");
166
}
167
168
static boolean algEquals(String algURI, String algName) {
169
algName = algName.toUpperCase(Locale.ROOT);
170
return algName.equals("DSA") && algURI.contains("#dsa-")
171
|| algName.equals("RSA")
172
&& (algURI.contains("#rsa-") || algURI.contains("-rsa-MGF1"))
173
|| algName.equals("EC") && algURI.contains("#ecdsa-");
174
}
175
}
176
177
/**
178
* KeySelector which would perform special lookup as documented
179
* by the ie/baltimore/merlin-examples testcases and return the
180
* matching public key.
181
*/
182
static class CollectionKeySelector extends KeySelector {
183
private CertificateFactory cf;
184
private File certDir;
185
private Vector<X509Certificate> certs;
186
private static final int MATCH_SUBJECT = 0;
187
private static final int MATCH_ISSUER = 1;
188
private static final int MATCH_SERIAL = 2;
189
private static final int MATCH_SUBJECT_KEY_ID = 3;
190
private static final int MATCH_CERTIFICATE = 4;
191
192
CollectionKeySelector(File dir) {
193
certDir = dir;
194
try {
195
cf = CertificateFactory.getInstance("X509");
196
} catch (CertificateException ex) {
197
// not going to happen
198
}
199
certs = new Vector<X509Certificate>();
200
File[] files = new File(certDir, "certs").listFiles();
201
for (int i = 0; i < files.length; i++) {
202
try (FileInputStream fis = new FileInputStream(files[i])) {
203
certs.add((X509Certificate)cf.generateCertificate(fis));
204
} catch (Exception ex) { }
205
}
206
}
207
208
Vector<X509Certificate> match(int matchType, Object value,
209
Vector<X509Certificate> pool) {
210
Vector<X509Certificate> matchResult = new Vector<>();
211
for (int j=0; j < pool.size(); j++) {
212
X509Certificate c = pool.get(j);
213
switch (matchType) {
214
case MATCH_SUBJECT:
215
try {
216
if (c.getSubjectDN().equals(new X500Name((String)value))) {
217
matchResult.add(c);
218
}
219
} catch (IOException ioe) { }
220
break;
221
case MATCH_ISSUER:
222
try {
223
if (c.getIssuerDN().equals(new X500Name((String)value))) {
224
matchResult.add(c);
225
}
226
} catch (IOException ioe) { }
227
break;
228
case MATCH_SERIAL:
229
if (c.getSerialNumber().equals(value)) {
230
matchResult.add(c);
231
}
232
233
break;
234
case MATCH_SUBJECT_KEY_ID:
235
byte[] extension = c.getExtensionValue("2.5.29.14");
236
if (extension != null) {
237
try {
238
DerValue derValue = new DerValue(extension);
239
DerValue derValue2 = new DerValue(derValue.getOctetString());
240
byte[] extVal = derValue2.getOctetString();
241
242
if (Arrays.equals(extVal, (byte[]) value)) {
243
matchResult.add(c);
244
}
245
} catch (IOException ex) { }
246
}
247
break;
248
case MATCH_CERTIFICATE:
249
if (c.equals(value)) {
250
matchResult.add(c);
251
}
252
break;
253
}
254
}
255
return matchResult;
256
}
257
258
public KeySelectorResult select(KeyInfo keyInfo,
259
KeySelector.Purpose purpose,
260
AlgorithmMethod method,
261
XMLCryptoContext context)
262
throws KeySelectorException {
263
if (keyInfo == null) {
264
throw new KeySelectorException("Null KeyInfo object!");
265
}
266
Iterator iter = keyInfo.getContent().iterator();
267
while (iter.hasNext()) {
268
XMLStructure xmlStructure = (XMLStructure) iter.next();
269
try {
270
if (xmlStructure instanceof KeyName) {
271
String name = ((KeyName)xmlStructure).getName();
272
PublicKey pk = null;
273
File certFile = new File(new File(certDir, "certs"),
274
name.toLowerCase() + ".crt");
275
try (FileInputStream fis = new FileInputStream(certFile)) {
276
// Lookup the public key using the key name 'Xxx',
277
// i.e. the public key is in "certs/xxx.crt".
278
X509Certificate cert = (X509Certificate)
279
cf.generateCertificate(fis);
280
pk = cert.getPublicKey();
281
} catch (FileNotFoundException e) {
282
// assume KeyName contains subject DN and search
283
// collection of certs for match
284
Vector<X509Certificate> result =
285
match(MATCH_SUBJECT, name, certs);
286
int numOfMatches = (result==null? 0:result.size());
287
if (numOfMatches != 1) {
288
throw new KeySelectorException
289
((numOfMatches==0?"No":"More than one") +
290
" match found");
291
}
292
pk = result.get(0).getPublicKey();
293
}
294
return new SimpleKSResult(pk);
295
} else if (xmlStructure instanceof RetrievalMethod) {
296
// Lookup the public key using the retrievel method.
297
// NOTE: only X509Certificate type is supported.
298
RetrievalMethod rm = (RetrievalMethod) xmlStructure;
299
String type = rm.getType();
300
if (type.equals(X509Data.RAW_X509_CERTIFICATE_TYPE)) {
301
String uri = rm.getURI();
302
try (FileInputStream fis =
303
new FileInputStream(new File(certDir, uri))) {
304
X509Certificate cert = (X509Certificate)
305
cf.generateCertificate(fis);
306
return new SimpleKSResult(cert.getPublicKey());
307
}
308
} else {
309
throw new KeySelectorException
310
("Unsupported RetrievalMethod type");
311
}
312
} else if (xmlStructure instanceof X509Data) {
313
List content = ((X509Data)xmlStructure).getContent();
314
int size = content.size();
315
Vector<X509Certificate> result = null;
316
// Lookup the public key using the information
317
// specified in X509Data element, i.e. searching
318
// over the collection of certificate files under
319
// "certs" subdirectory and return those match.
320
for (int k = 0; k<size; k++) {
321
Object obj = content.get(k);
322
if (obj instanceof String) {
323
result = match(MATCH_SUBJECT, obj, certs);
324
} else if (obj instanceof byte[]) {
325
result = match(MATCH_SUBJECT_KEY_ID, obj,
326
certs);
327
} else if (obj instanceof X509Certificate) {
328
result = match(MATCH_CERTIFICATE, obj, certs);
329
} else if (obj instanceof X509IssuerSerial) {
330
X509IssuerSerial is = (X509IssuerSerial) obj;
331
result = match(MATCH_SERIAL,
332
is.getSerialNumber(), certs);
333
result = match(MATCH_ISSUER,
334
is.getIssuerName(), result);
335
} else {
336
throw new KeySelectorException("Unsupported X509Data: " + obj);
337
}
338
}
339
int numOfMatches = (result==null? 0:result.size());
340
if (numOfMatches != 1) {
341
throw new KeySelectorException
342
((numOfMatches==0?"No":"More than one") +
343
" match found");
344
}
345
return new SimpleKSResult(result.get(0).getPublicKey());
346
}
347
} catch (Exception ex) {
348
throw new KeySelectorException(ex);
349
}
350
}
351
throw new KeySelectorException("No matching key found!");
352
}
353
}
354
355
static class ByteUtil {
356
357
private static String mapping = "0123456789ABCDEF";
358
private static int numBytesPerRow = 6;
359
360
private static String getHex(byte value) {
361
int low = value & 0x0f;
362
int high = ((value >> 4) & 0x0f);
363
char[] res = new char[2];
364
res[0] = mapping.charAt(high);
365
res[1] = mapping.charAt(low);
366
return new String(res);
367
}
368
369
static String dumpArray(byte[] in) {
370
int numDumped = 0;
371
StringBuffer buf = new StringBuffer(512);
372
buf.append("{");
373
for (int i=0;i<(in.length/numBytesPerRow); i++) {
374
for (int j=0; j<(numBytesPerRow); j++) {
375
buf.append("(byte)0x" + getHex(in[i*numBytesPerRow+j]) +
376
", ");
377
}
378
numDumped += numBytesPerRow;
379
}
380
while (numDumped < in.length) {
381
buf.append("(byte)0x" + getHex(in[numDumped]) + " ");
382
numDumped += 1;
383
}
384
buf.append("}");
385
return buf.toString();
386
}
387
}
388
}
389
390
class SimpleKSResult implements KeySelectorResult {
391
private final Key key;
392
393
SimpleKSResult(Key key) { this.key = key; }
394
395
public Key getKey() { return key; }
396
}
397
398