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