Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/test/jdk/sun/security/ssl/CertPathRestrictions/TLSRestrictions.java
41152 views
1
/*
2
* Copyright (c) 2017, 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.ByteArrayInputStream;
25
import java.io.IOException;
26
import java.io.InputStream;
27
import java.net.SocketTimeoutException;
28
import java.nio.file.Files;
29
import java.nio.file.Path;
30
import java.nio.file.Paths;
31
import java.security.KeyFactory;
32
import java.security.KeyStore;
33
import java.security.PrivateKey;
34
import java.security.Security;
35
import java.security.cert.Certificate;
36
import java.security.cert.CertificateFactory;
37
import java.security.spec.PKCS8EncodedKeySpec;
38
import java.util.Base64;
39
import java.util.concurrent.ExecutorService;
40
import java.util.concurrent.Executors;
41
import java.util.concurrent.Future;
42
import java.util.concurrent.TimeUnit;
43
import java.util.stream.Collectors;
44
45
import javax.net.ssl.KeyManagerFactory;
46
import javax.net.ssl.SSLContext;
47
import javax.net.ssl.SSLHandshakeException;
48
import javax.net.ssl.TrustManagerFactory;
49
50
import jdk.test.lib.process.OutputAnalyzer;
51
import jdk.test.lib.process.ProcessTools;
52
53
/*
54
* @test
55
* @bug 8165367
56
* @summary Verify the restrictions for certificate path on JSSE with custom trust store.
57
* @library /test/lib
58
* @build jdk.test.lib.Utils
59
* jdk.test.lib.Asserts
60
* jdk.test.lib.JDKToolFinder
61
* jdk.test.lib.JDKToolLauncher
62
* jdk.test.lib.Platform
63
* jdk.test.lib.process.*
64
* @compile JSSEClient.java
65
* @run main/othervm -Djava.security.debug=certpath TLSRestrictions DEFAULT
66
* @run main/othervm -Djava.security.debug=certpath TLSRestrictions C1
67
* @run main/othervm -Djava.security.debug=certpath TLSRestrictions S1
68
* @run main/othervm -Djava.security.debug=certpath TLSRestrictions C2
69
* @run main/othervm -Djava.security.debug=certpath TLSRestrictions S2
70
* @run main/othervm -Djava.security.debug=certpath TLSRestrictions C3
71
* @run main/othervm -Djava.security.debug=certpath TLSRestrictions S3
72
* @run main/othervm -Djava.security.debug=certpath TLSRestrictions C4
73
* @run main/othervm -Djava.security.debug=certpath TLSRestrictions S4
74
* @run main/othervm -Djava.security.debug=certpath TLSRestrictions C5
75
* @run main/othervm -Djava.security.debug=certpath TLSRestrictions S5
76
* @run main/othervm -Djava.security.debug=certpath TLSRestrictions C6
77
* @run main/othervm -Djava.security.debug=certpath TLSRestrictions S6
78
* @run main/othervm -Djava.security.debug=certpath TLSRestrictions C7
79
* @run main/othervm -Djava.security.debug=certpath TLSRestrictions S7
80
* @run main/othervm -Djava.security.debug=certpath TLSRestrictions C8
81
* @run main/othervm -Djava.security.debug=certpath TLSRestrictions S8
82
* @run main/othervm -Djava.security.debug=certpath TLSRestrictions C9
83
* @run main/othervm -Djava.security.debug=certpath TLSRestrictions S9
84
*/
85
public class TLSRestrictions {
86
87
private static final String TEST_CLASSES = System.getProperty("test.classes");
88
private static final char[] PASSWORD = "".toCharArray();
89
private static final String CERT_DIR = System.getProperty("cert.dir",
90
System.getProperty("test.src") + "/certs");
91
92
static final String PROP = "jdk.certpath.disabledAlgorithms";
93
static final String NOSHA1 = "MD2, MD5";
94
private static final String TLSSERVER = "SHA1 usage TLSServer";
95
private static final String TLSCLIENT = "SHA1 usage TLSClient";
96
static final String JDKCATLSSERVER = "SHA1 jdkCA & usage TLSServer";
97
static final String JDKCATLSCLIENT = "SHA1 jdkCA & usage TLSClient";
98
99
// This is a space holder in command arguments, and stands for none certificate.
100
static final String NONE_CERT = "NONE_CERT";
101
102
static final String DELIMITER = ",";
103
static final int TIMEOUT = 30000;
104
105
// It checks if java.security contains constraint "SHA1 jdkCA & usage TLSServer"
106
// for jdk.certpath.disabledAlgorithms by default.
107
private static void checkDefaultConstraint() {
108
System.out.println(
109
"Case: Checks the default value of jdk.certpath.disabledAlgorithms");
110
if (!Security.getProperty(PROP).contains(JDKCATLSSERVER)) {
111
throw new RuntimeException(String.format(
112
"%s doesn't contain constraint \"%s\", the real value is \"%s\".",
113
PROP, JDKCATLSSERVER, Security.getProperty(PROP)));
114
}
115
}
116
117
/*
118
* This method creates trust store and key store with specified certificates
119
* respectively. And then it creates SSL context with the stores.
120
* If trustNames contains NONE_CERT only, it does not create a custom trust
121
* store, but the default one in JDK.
122
*
123
* @param trustNames Trust anchors, which are used to create custom trust store.
124
* If null, no custom trust store is created and the default
125
* trust store in JDK is used.
126
* @param certNames Certificate chain, which is used to create key store.
127
* It cannot be null.
128
*/
129
static SSLContext createSSLContext(String[] trustNames,
130
String[] certNames) throws Exception {
131
CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
132
133
TrustManagerFactory tmf = null;
134
if (trustNames != null && trustNames.length > 0
135
&& !trustNames[0].equals(NONE_CERT)) {
136
KeyStore trustStore = KeyStore.getInstance("JKS");
137
trustStore.load(null, null);
138
for (int i = 0; i < trustNames.length; i++) {
139
try (InputStream is = new ByteArrayInputStream(
140
loadCert(trustNames[i]).getBytes())) {
141
Certificate trustCert = certFactory.generateCertificate(is);
142
trustStore.setCertificateEntry("trustCert-" + i, trustCert);
143
}
144
}
145
146
tmf = TrustManagerFactory.getInstance("PKIX");
147
tmf.init(trustStore);
148
}
149
150
Certificate[] certChain = new Certificate[certNames.length];
151
for (int i = 0; i < certNames.length; i++) {
152
try (InputStream is = new ByteArrayInputStream(
153
loadCert(certNames[i]).getBytes())) {
154
Certificate cert = certFactory.generateCertificate(is);
155
certChain[i] = cert;
156
}
157
}
158
159
PKCS8EncodedKeySpec privKeySpec = new PKCS8EncodedKeySpec(
160
Base64.getMimeDecoder().decode(loadPrivKey(certNames[0])));
161
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
162
PrivateKey privKey = keyFactory.generatePrivate(privKeySpec);
163
164
KeyStore keyStore = KeyStore.getInstance("JKS");
165
keyStore.load(null, null);
166
keyStore.setKeyEntry("keyCert", privKey, PASSWORD, certChain);
167
168
KeyManagerFactory kmf = KeyManagerFactory.getInstance("NewSunX509");
169
kmf.init(keyStore, PASSWORD);
170
171
SSLContext context = SSLContext.getInstance("TLS");
172
context.init(kmf.getKeyManagers(),
173
tmf == null ? null : tmf.getTrustManagers(), null);
174
return context;
175
}
176
177
/*
178
* This method sets jdk.certpath.disabledAlgorithms, and then retrieves
179
* and prints its value.
180
*/
181
static void setConstraint(String side, String constraint) {
182
System.out.printf("%s: Old %s=%s%n", side, PROP,
183
Security.getProperty(PROP));
184
Security.setProperty(PROP, constraint);
185
System.out.printf("%s: New %s=%s%n", side, PROP,
186
Security.getProperty(PROP));
187
}
188
189
/*
190
* This method is used to run a variety of cases.
191
* It launches a server, and then takes a client to connect the server.
192
* Both of server and client use the same certificates.
193
*
194
* @param trustNames Trust anchors, which are used to create custom trust store.
195
* If null, the default trust store in JDK is used.
196
* @param certNames Certificate chain, which is used to create key store.
197
* It cannot be null. The first certificate is regarded as
198
* the end entity.
199
* @param serverConstraint jdk.certpath.disabledAlgorithms value on server side.
200
* @param clientConstraint jdk.certpath.disabledAlgorithms value on client side.
201
* @param needClientAuth If true, server side acquires client authentication;
202
* otherwise, false.
203
* @param pass If true, the connection should be blocked; otherwise, false.
204
*/
205
static void testConstraint(String[] trustNames, String[] certNames,
206
String serverConstraint, String clientConstraint,
207
boolean needClientAuth, boolean pass) throws Exception {
208
String trustNameStr = trustNames == null ? ""
209
: String.join(DELIMITER, trustNames);
210
String certNameStr = certNames == null ? ""
211
: String.join(DELIMITER, certNames);
212
213
System.out.printf("Case:%n"
214
+ " trustNames=%s; certNames=%s%n"
215
+ " serverConstraint=%s; clientConstraint=%s%n"
216
+ " needClientAuth=%s%n"
217
+ " pass=%s%n%n",
218
trustNameStr, certNameStr,
219
serverConstraint, clientConstraint,
220
needClientAuth,
221
pass);
222
223
ExecutorService executor = Executors.newFixedThreadPool(1);
224
try {
225
JSSEServer server = new JSSEServer(
226
createSSLContext(trustNames, certNames),
227
serverConstraint,
228
needClientAuth);
229
int port = server.getPort();
230
Future<Exception> serverFuture = executor.submit(() -> server.start());
231
232
// Run client on another JVM so that its properties cannot be in conflict
233
// with server's.
234
OutputAnalyzer outputAnalyzer = ProcessTools.executeTestJvm(
235
"-Dcert.dir=" + CERT_DIR,
236
"-Djava.security.debug=certpath",
237
"-classpath",
238
TEST_CLASSES,
239
"JSSEClient",
240
port + "",
241
trustNameStr,
242
certNameStr,
243
clientConstraint);
244
int clientExitValue = outputAnalyzer.getExitValue();
245
String clientOut = outputAnalyzer.getOutput();
246
System.out.println("---------- Client output start ----------");
247
System.out.println(clientOut);
248
System.out.println("---------- Client output end ----------");
249
250
Exception serverException = serverFuture.get(TIMEOUT, TimeUnit.MILLISECONDS);
251
if (serverException instanceof SocketTimeoutException
252
|| clientOut.contains("SocketTimeoutException")) {
253
System.out.println("The communication gets timeout and skips the test.");
254
return;
255
}
256
257
if (pass) {
258
if (serverException != null || clientExitValue != 0) {
259
throw new RuntimeException(
260
"Unexpected failure. Operation was blocked.");
261
}
262
} else {
263
if (serverException == null && clientExitValue == 0) {
264
throw new RuntimeException(
265
"Unexpected pass. Operation was allowed.");
266
}
267
268
// The test may encounter non-SSL issues, like network problem.
269
if (!(serverException instanceof SSLHandshakeException
270
|| clientOut.contains("SSLHandshakeException"))) {
271
throw new RuntimeException("Failure with unexpected exception.");
272
}
273
}
274
} finally {
275
executor.shutdown();
276
}
277
}
278
279
/*
280
* This method is used to run a variety of cases, which don't require client
281
* authentication by default.
282
*/
283
static void testConstraint(String[] trustNames, String[] certNames,
284
String serverConstraint, String clientConstraint, boolean pass)
285
throws Exception {
286
testConstraint(trustNames, certNames, serverConstraint, clientConstraint,
287
false, pass);
288
}
289
290
public static void main(String[] args) throws Exception {
291
switch (args[0]) {
292
// Case DEFAULT only checks one of default settings for
293
// jdk.certpath.disabledAlgorithms in JDK/conf/security/java.security.
294
case "DEFAULT":
295
checkDefaultConstraint();
296
break;
297
298
// Cases C1 and S1 use SHA256 root CA in trust store,
299
// and use SHA256 end entity in key store.
300
// C1 only sets constraint "SHA1 usage TLSServer" on client side;
301
// S1 only sets constraint "SHA1 usage TLSClient" on server side with client auth.
302
// The connection of the both cases should not be blocked.
303
case "C1":
304
testConstraint(
305
new String[] { "ROOT_CA_SHA256" },
306
new String[] { "INTER_CA_SHA256-ROOT_CA_SHA256" },
307
NOSHA1,
308
TLSSERVER,
309
true);
310
break;
311
case "S1":
312
testConstraint(
313
new String[] { "ROOT_CA_SHA256" },
314
new String[] { "INTER_CA_SHA256-ROOT_CA_SHA256" },
315
TLSCLIENT,
316
NOSHA1,
317
true,
318
true);
319
break;
320
321
// Cases C2 and S2 use SHA256 root CA in trust store,
322
// and use SHA1 end entity in key store.
323
// C2 only sets constraint "SHA1 usage TLSServer" on client side;
324
// S2 only sets constraint "SHA1 usage TLSClient" on server side with client auth.
325
// The connection of the both cases should be blocked.
326
case "C2":
327
testConstraint(
328
new String[] { "ROOT_CA_SHA256" },
329
new String[] { "INTER_CA_SHA1-ROOT_CA_SHA256" },
330
NOSHA1,
331
TLSSERVER,
332
false);
333
break;
334
case "S2":
335
testConstraint(
336
new String[] { "ROOT_CA_SHA256" },
337
new String[] { "INTER_CA_SHA1-ROOT_CA_SHA256" },
338
TLSCLIENT,
339
NOSHA1,
340
true,
341
false);
342
break;
343
344
// Cases C3 and S3 use SHA1 root CA in trust store,
345
// and use SHA1 end entity in key store.
346
// C3 only sets constraint "SHA1 usage TLSServer" on client side;
347
// S3 only sets constraint "SHA1 usage TLSClient" on server side with client auth.
348
// The connection of the both cases should be blocked.
349
case "C3":
350
testConstraint(
351
new String[] { "ROOT_CA_SHA1" },
352
new String[] { "INTER_CA_SHA1-ROOT_CA_SHA1" },
353
NOSHA1,
354
TLSSERVER,
355
false);
356
break;
357
case "S3":
358
testConstraint(
359
new String[] { "ROOT_CA_SHA1" },
360
new String[] { "INTER_CA_SHA1-ROOT_CA_SHA1" },
361
TLSCLIENT,
362
NOSHA1,
363
true,
364
false);
365
break;
366
367
// Cases C4 and S4 use SHA1 root CA as trust store,
368
// and use SHA256 end entity in key store.
369
// C4 only sets constraint "SHA1 usage TLSServer" on client side;
370
// S4 only sets constraint "SHA1 usage TLSClient" on server side with client auth.
371
// The connection of the both cases should not be blocked.
372
case "C4":
373
testConstraint(
374
new String[] { "ROOT_CA_SHA1" },
375
new String[] { "INTER_CA_SHA256-ROOT_CA_SHA1" },
376
NOSHA1,
377
TLSSERVER,
378
true);
379
break;
380
case "S4":
381
testConstraint(
382
new String[] { "ROOT_CA_SHA1" },
383
new String[] { "INTER_CA_SHA256-ROOT_CA_SHA1" },
384
TLSCLIENT,
385
NOSHA1,
386
true,
387
true);
388
break;
389
390
// Cases C5 and S5 use SHA1 root CA in trust store,
391
// and use SHA256 intermediate CA and SHA256 end entity in key store.
392
// C5 only sets constraint "SHA1 usage TLSServer" on client side;
393
// S5 only sets constraint "SHA1 usage TLSClient" on server side with client auth.
394
// The connection of the both cases should not be blocked.
395
case "C5":
396
testConstraint(
397
new String[] { "ROOT_CA_SHA1" },
398
new String[] {
399
"END_ENTITY_SHA256-INTER_CA_SHA256-ROOT_CA_SHA1",
400
"INTER_CA_SHA256-ROOT_CA_SHA1" },
401
NOSHA1,
402
TLSSERVER,
403
true);
404
break;
405
case "S5":
406
testConstraint(
407
new String[] { "ROOT_CA_SHA1" },
408
new String[] {
409
"END_ENTITY_SHA256-INTER_CA_SHA256-ROOT_CA_SHA1",
410
"INTER_CA_SHA256-ROOT_CA_SHA1" },
411
TLSCLIENT,
412
NOSHA1,
413
true,
414
true);
415
break;
416
417
// Cases C6 and S6 use SHA1 root CA as trust store,
418
// and use SHA1 intermediate CA and SHA256 end entity in key store.
419
// C6 only sets constraint "SHA1 usage TLSServer" on client side;
420
// S6 only sets constraint "SHA1 usage TLSClient" on server side with client auth.
421
// The connection of the both cases should be blocked.
422
case "C6":
423
testConstraint(
424
new String[] { "ROOT_CA_SHA1" },
425
new String[] {
426
"END_ENTITY_SHA256-INTER_CA_SHA1-ROOT_CA_SHA1",
427
"INTER_CA_SHA1-ROOT_CA_SHA1" },
428
NOSHA1,
429
TLSSERVER,
430
false);
431
break;
432
case "S6":
433
testConstraint(
434
new String[] { "ROOT_CA_SHA1" },
435
new String[] {
436
"END_ENTITY_SHA256-INTER_CA_SHA1-ROOT_CA_SHA1",
437
"INTER_CA_SHA1-ROOT_CA_SHA1" },
438
TLSCLIENT,
439
NOSHA1,
440
true,
441
false);
442
break;
443
444
// Cases C7 and S7 use SHA256 root CA in trust store,
445
// and use SHA256 intermediate CA and SHA1 end entity in key store.
446
// C7 only sets constraint "SHA1 usage TLSServer" on client side;
447
// S7 only sets constraint "SHA1 usage TLSClient" on server side with client auth.
448
// The connection of the both cases should be blocked.
449
case "C7":
450
testConstraint(
451
new String[] { "ROOT_CA_SHA256" },
452
new String[] {
453
"END_ENTITY_SHA1-INTER_CA_SHA256-ROOT_CA_SHA256",
454
"INTER_CA_SHA256-ROOT_CA_SHA256" },
455
NOSHA1,
456
TLSSERVER,
457
false);
458
break;
459
case "S7":
460
testConstraint(
461
new String[] { "ROOT_CA_SHA256" },
462
new String[] {
463
"END_ENTITY_SHA1-INTER_CA_SHA256-ROOT_CA_SHA256",
464
"INTER_CA_SHA256-ROOT_CA_SHA256" },
465
TLSCLIENT,
466
NOSHA1,
467
true,
468
false);
469
break;
470
471
// Cases C8 and S8 use SHA256 root CA in trust store,
472
// and use SHA1 intermediate CA and SHA256 end entity in key store.
473
// C8 only sets constraint "SHA1 usage TLSServer" on client side;
474
// S8 only sets constraint "SHA1 usage TLSClient" on server side with client auth.
475
// The connection of the both cases should be blocked.
476
case "C8":
477
testConstraint(
478
new String[] { "ROOT_CA_SHA256" },
479
new String[] {
480
"END_ENTITY_SHA256-INTER_CA_SHA1-ROOT_CA_SHA256",
481
"INTER_CA_SHA1-ROOT_CA_SHA256" },
482
NOSHA1,
483
TLSSERVER,
484
false);
485
break;
486
case "S8":
487
testConstraint(
488
new String[] { "ROOT_CA_SHA256" },
489
new String[] {
490
"END_ENTITY_SHA256-INTER_CA_SHA1-ROOT_CA_SHA256",
491
"INTER_CA_SHA1-ROOT_CA_SHA256" },
492
TLSCLIENT,
493
NOSHA1,
494
true,
495
false);
496
break;
497
498
// Cases C9 and S9 use SHA256 root CA and SHA1 intermediate CA in trust store,
499
// and use SHA256 end entity in key store.
500
// C9 only sets constraint "SHA1 usage TLSServer" on client side;
501
// S9 only sets constraint "SHA1 usage TLSClient" on server side with client auth.
502
// The connection of the both cases should not be blocked.
503
case "C9":
504
testConstraint(
505
new String[] {
506
"ROOT_CA_SHA256",
507
"INTER_CA_SHA1-ROOT_CA_SHA256" },
508
new String[] {
509
"END_ENTITY_SHA256-INTER_CA_SHA1-ROOT_CA_SHA256" },
510
NOSHA1,
511
TLSSERVER,
512
true);
513
break;
514
case "S9":
515
testConstraint(
516
new String[] {
517
"ROOT_CA_SHA256",
518
"INTER_CA_SHA1-ROOT_CA_SHA256" },
519
new String[] {
520
"END_ENTITY_SHA256-INTER_CA_SHA1-ROOT_CA_SHA256" },
521
TLSCLIENT,
522
NOSHA1,
523
true,
524
true);
525
break;
526
}
527
System.out.println("Case passed");
528
System.out.println("========================================");
529
}
530
531
private static String loadCert(String certName) {
532
try {
533
Path certFilePath = Paths.get(CERT_DIR, certName + ".cer");
534
return String.join("\n",
535
Files.lines(certFilePath).filter((String line) -> {
536
return !line.startsWith("Certificate")
537
&& !line.startsWith(" ");
538
}).collect(Collectors.toList()));
539
} catch (IOException e) {
540
throw new RuntimeException("Load certificate failed", e);
541
}
542
}
543
544
private static String loadPrivKey(String certName) {
545
Path priveKeyFilePath = Paths.get(CERT_DIR, certName + "-PRIV.key");
546
try {
547
return new String(Files.readAllBytes(priveKeyFilePath));
548
} catch (IOException e) {
549
throw new RuntimeException("Load private key failed", e);
550
}
551
}
552
}
553
554