Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/test/sun/security/tools/keytool/WeakAlg.java
38853 views
1
/*
2
* Copyright (c) 2017, 2020, 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 8171319 8177569 8182879 8172404
27
* @summary keytool should print out warnings when reading or generating
28
* cert/cert req using weak algorithms
29
* @library /lib/testlibrary
30
* @run main/othervm/timeout=600 -Duser.language=en -Duser.country=US WeakAlg
31
*/
32
33
import jdk.testlibrary.Asserts;
34
import jdk.testlibrary.SecurityTools;
35
import jdk.testlibrary.OutputAnalyzer;
36
import sun.security.tools.KeyStoreUtil;
37
import sun.security.util.DisabledAlgorithmConstraints;
38
39
import java.io.ByteArrayInputStream;
40
import java.io.ByteArrayOutputStream;
41
import java.io.File;
42
import java.io.FileInputStream;
43
import java.io.IOException;
44
import java.io.InputStream;
45
import java.io.PrintStream;
46
import java.nio.file.Files;
47
import java.nio.file.Paths;
48
import java.nio.file.StandardCopyOption;
49
import java.security.CryptoPrimitive;
50
import java.security.KeyStore;
51
import java.security.cert.X509Certificate;
52
import java.util.Collections;
53
import java.util.EnumSet;
54
import java.util.Set;
55
import java.util.stream.Collectors;
56
import java.util.stream.Stream;
57
58
public class WeakAlg {
59
60
static String sep = File.separator;
61
static String cacerts_location = System.getProperty("java.home") +
62
sep + "lib" + sep + "security" + sep + "cacerts";
63
64
public static void main(String[] args) throws Throwable {
65
66
rm("ks");
67
68
// Tests for "disabled" algorithms
69
// -genkeypair, and -printcert, -list -alias, -exportcert
70
// (w/ different formats)
71
checkDisabledGenKeyPair("a", "-keyalg RSA -sigalg MD5withRSA", "MD5withRSA");
72
checkDisabledGenKeyPair("b", "-keyalg RSA -keysize 512", "512-bit RSA key");
73
checkDisabledGenKeyPair("c", "-keyalg RSA", null);
74
75
kt("-list")
76
.shouldContain("Warning:")
77
.shouldMatch("<a>.*MD5withRSA.*is disabled")
78
.shouldMatch("<b>.*512-bit RSA key.*is disabled");
79
kt("-list -v")
80
.shouldContain("Warning:")
81
.shouldMatch("<a>.*MD5withRSA.*is disabled")
82
.shouldContain("MD5withRSA (disabled)")
83
.shouldMatch("<b>.*512-bit RSA key.*is disabled")
84
.shouldContain("512-bit RSA key (disabled)");
85
86
// Multiple warnings for multiple cert in -printcert
87
// or -list or -exportcert
88
89
// -certreq, -printcertreq, -gencert
90
checkDisabledCertReq("a", "", null);
91
gencert("c-a", "")
92
.shouldNotContain("Warning"); // new sigalg is not weak
93
gencert("c-a", "-sigalg MD2withRSA")
94
.shouldContain("Warning:")
95
.shouldMatch("The generated certificate.*MD2withRSA.*is disabled");
96
97
checkDisabledCertReq("a", "-sigalg MD5withRSA", "MD5withRSA");
98
gencert("c-a", "")
99
.shouldContain("Warning:")
100
.shouldMatch("The certificate request.*MD5withRSA.*is disabled");
101
gencert("c-a", "-sigalg MD2withRSA")
102
.shouldContain("Warning:")
103
.shouldMatch("The certificate request.*MD5withRSA.*is disabled")
104
.shouldMatch("The generated certificate.*MD2withRSA.*is disabled");
105
106
checkDisabledCertReq("b", "", "512-bit RSA key");
107
gencert("c-b", "")
108
.shouldContain("Warning:")
109
.shouldMatch("The certificate request.*512-bit RSA key.*is disabled")
110
.shouldMatch("The generated certificate.*512-bit RSA key.*is disabled");
111
112
checkDisabledCertReq("c", "", null);
113
gencert("a-c", "")
114
.shouldContain("Warning:")
115
.shouldMatch("The issuer.*MD5withRSA.*is disabled");
116
117
// but the new cert is not weak
118
kt("-printcert -file a-c.cert")
119
.shouldNotContain("Warning")
120
.shouldNotContain("(disabled)");
121
122
gencert("b-c", "")
123
.shouldContain("Warning:")
124
.shouldMatch("The issuer.*512-bit RSA key.*is disabled");
125
126
// -importcert
127
checkImport();
128
129
// -importkeystore
130
checkImportKeyStore();
131
132
// -gencrl, -printcrl
133
134
checkDisabledGenCRL("a", "", null);
135
checkDisabledGenCRL("a", "-sigalg MD5withRSA", "MD5withRSA");
136
checkDisabledGenCRL("b", "", "512-bit RSA key");
137
checkDisabledGenCRL("c", "", null);
138
139
kt("-delete -alias b");
140
kt("-printcrl -file b.crl")
141
.shouldContain("WARNING: not verified");
142
143
jksTypeCheck();
144
145
checkInplaceImportKeyStore();
146
147
rm("ks");
148
149
// Tests for "legacy" algorithms
150
// -genkeypair, and -printcert, -list -alias, -exportcert
151
// (w/ different formats)
152
checkWeakGenKeyPair("x", "-keyalg RSA -sigalg SHA1withRSA", "SHA1withRSA");
153
checkWeakGenKeyPair("y", "-keyalg RSA -keysize 1024", "1024-bit RSA key");
154
checkWeakGenKeyPair("z", "-keyalg RSA", null);
155
156
kt("-list")
157
.shouldContain("Warning:")
158
.shouldMatch("<x>.*SHA1withRSA.*will be disabled")
159
.shouldMatch("<y>.*1024-bit RSA key.*will be disabled");
160
kt("-list -v")
161
.shouldContain("Warning:")
162
.shouldMatch("<x>.*SHA1withRSA.*will be disabled")
163
.shouldContain("SHA1withRSA (weak)")
164
.shouldMatch("<y>.*1024-bit RSA key.*will be disabled")
165
.shouldContain("1024-bit RSA key (weak)");
166
167
// Multiple warnings for multiple cert in -printcert
168
// or -list or -exportcert
169
170
// -certreq, -printcertreq, -gencert
171
checkWeakCertReq("x", "", null);
172
gencert("z-x", "")
173
.shouldNotContain("Warning"); // new sigalg is not weak
174
gencert("z-x", "-sigalg SHA1withRSA")
175
.shouldContain("Warning:")
176
.shouldMatch("The generated certificate.*SHA1withRSA.*will be disabled");
177
178
checkWeakCertReq("x", "-sigalg SHA1withRSA", "SHA1withRSA");
179
gencert("z-x", "")
180
.shouldContain("Warning:")
181
.shouldMatch("The certificate request.*SHA1withRSA.*will be disabled");
182
gencert("z-x", "-sigalg SHA1withRSA")
183
.shouldContain("Warning:")
184
.shouldMatch("The certificate request.*SHA1withRSA.*will be disabled")
185
.shouldMatch("The generated certificate.*SHA1withRSA.*will be disabled");
186
187
checkWeakCertReq("y", "", "1024-bit RSA key");
188
gencert("z-y", "")
189
.shouldContain("Warning:")
190
.shouldMatch("The certificate request.*1024-bit RSA key.*will be disabled")
191
.shouldMatch("The generated certificate.*1024-bit RSA key.*will be disabled");
192
193
checkWeakCertReq("z", "", null);
194
gencert("x-z", "")
195
.shouldContain("Warning:")
196
.shouldMatch("The issuer.*SHA1withRSA.*will be disabled");
197
198
// but the new cert is not weak
199
kt("-printcert -file x-z.cert")
200
.shouldNotContain("Warning")
201
.shouldNotContain("weak");
202
203
gencert("y-z", "")
204
.shouldContain("Warning:")
205
.shouldMatch("The issuer.*1024-bit RSA key.*will be disabled");
206
207
// -gencrl, -printcrl
208
checkWeakGenCRL("x", "", null);
209
checkWeakGenCRL("x", "-sigalg SHA1withRSA", "SHA1withRSA");
210
checkWeakGenCRL("y", "", "1024-bit RSA key");
211
checkWeakGenCRL("z", "", null);
212
213
kt("-delete -alias y");
214
kt("-printcrl -file y.crl")
215
.shouldContain("WARNING: not verified");
216
217
jksTypeCheck();
218
}
219
220
static void jksTypeCheck() throws Exception {
221
222
rm("ks");
223
rm("ks2");
224
225
kt("-genkeypair -alias a -storetype pkcs12 -dname CN=A")
226
.shouldNotContain("Warning:");
227
kt("-list")
228
.shouldNotContain("Warning:");
229
kt("-list -storetype jks") // no warning if PKCS12 used as JKS
230
.shouldNotContain("Warning:");
231
kt("-exportcert -alias a -file a.crt")
232
.shouldNotContain("Warning:");
233
234
// warn if migrating to JKS
235
importkeystore("ks", "ks2", "-deststoretype jks")
236
.shouldContain("JKS keystore uses a proprietary format");
237
238
rm("ks");
239
rm("ks2");
240
rm("ks3");
241
242
// no warning if all certs
243
kt("-importcert -alias b -file a.crt -storetype jks -noprompt")
244
.shouldNotContain("Warning:");
245
kt("-genkeypair -alias a -dname CN=A")
246
.shouldContain("JKS keystore uses a proprietary format");
247
kt("-list")
248
.shouldContain("JKS keystore uses a proprietary format");
249
kt("-exportcert -alias a -file a.crt")
250
.shouldContain("JKS keystore uses a proprietary format");
251
kt("-printcert -file a.crt") // no warning if keystore not touched
252
.shouldNotContain("Warning:");
253
kt("-certreq -alias a -file a.req")
254
.shouldContain("JKS keystore uses a proprietary format");
255
kt("-printcertreq -file a.req") // no warning if keystore not touched
256
.shouldNotContain("Warning:");
257
258
// Earlier than JDK 9 defaults to JKS
259
importkeystore("ks", "ks2", "")
260
.shouldContain("Warning:");
261
262
importkeystore("ks", "ks3", "-deststoretype pkcs12")
263
.shouldNotContain("Warning:");
264
265
rm("ks");
266
267
kt("-genkeypair -alias a -dname CN=A -storetype jceks")
268
.shouldContain("JCEKS keystore uses a proprietary format");
269
kt("-list -storetype jceks")
270
.shouldContain("JCEKS keystore uses a proprietary format");
271
kt("-importcert -alias b -file a.crt -noprompt -storetype jceks")
272
.shouldContain("JCEKS keystore uses a proprietary format");
273
kt("-exportcert -alias a -file a.crt -storetype jceks")
274
.shouldContain("JCEKS keystore uses a proprietary format");
275
kt("-printcert -file a.crt")
276
.shouldNotContain("Warning:");
277
kt("-certreq -alias a -file a.req -storetype jceks")
278
.shouldContain("JCEKS keystore uses a proprietary format");
279
kt("-printcertreq -file a.req")
280
.shouldNotContain("Warning:");
281
kt("-genseckey -alias c -keyalg AES -keysize 128 -storetype jceks")
282
.shouldContain("JCEKS keystore uses a proprietary format");
283
}
284
285
static void checkImportKeyStore() throws Exception {
286
287
rm("ks2");
288
rm("ks3");
289
290
importkeystore("ks", "ks2", "")
291
.shouldContain("3 entries successfully imported")
292
.shouldContain("Warning")
293
.shouldMatch("<b>.*512-bit RSA key.*is disabled")
294
.shouldMatch("<a>.*MD5withRSA.*is disabled");
295
296
importkeystore("ks", "ks3", "-srcalias a")
297
.shouldContain("Warning")
298
.shouldMatch("<a>.*MD5withRSA.*is disabled");
299
}
300
301
static void checkInplaceImportKeyStore() throws Exception {
302
303
rm("ks");
304
genkeypair("a", "");
305
306
// Same type backup
307
importkeystore("ks", "ks", "")
308
.shouldContain("Warning:")
309
.shouldMatch(".*ks.old");
310
311
importkeystore("ks", "ks", "")
312
.shouldContain("Warning:")
313
.shouldMatch(".*ks.old2");
314
315
importkeystore("ks", "ks", "-srcstoretype jks") // it knows real type
316
.shouldContain("Warning:")
317
.shouldMatch(".*ks.old3");
318
319
String cPath = new File("ks").getCanonicalPath();
320
321
importkeystore("ks", cPath, "")
322
.shouldContain("Warning:")
323
.shouldMatch(".*ks.old4");
324
325
// Migration
326
importkeystore("ks", "ks", "-deststoretype jks")
327
.shouldContain("Warning:")
328
.shouldContain("JKS keystore uses a proprietary format")
329
.shouldMatch("The original.*ks.old5");
330
331
KeyStore test_ks = KeyStore.getInstance("JKS");
332
test_ks.load(new FileInputStream(new File("ks")),
333
"changeit".toCharArray());
334
Asserts.assertEQ(
335
test_ks.getType(), "JKS");
336
337
importkeystore("ks", "ks", "-deststoretype PKCS12")
338
.shouldContain("Warning:")
339
.shouldNotContain("proprietary format")
340
.shouldMatch("Migrated.*Non.*JKS.*ks.old6");
341
342
test_ks = KeyStore.getInstance("PKCS12");
343
test_ks.load(new FileInputStream(new File("ks")),
344
"changeit".toCharArray());
345
Asserts.assertEQ(
346
test_ks.getType(), "PKCS12");
347
348
test_ks = KeyStore.getInstance("JKS");
349
test_ks.load(new FileInputStream(new File("ks.old6")),
350
"changeit".toCharArray());
351
Asserts.assertEQ(
352
test_ks.getType(), "JKS");
353
354
// One password prompt is enough for migration
355
kt0("-importkeystore -srckeystore ks -destkeystore ks", "changeit")
356
.shouldMatch("backed.*ks.old7");
357
358
// But three if importing to a different keystore
359
rm("ks2");
360
kt0("-importkeystore -srckeystore ks -destkeystore ks2",
361
"changeit")
362
.shouldContain("Keystore password is too short");
363
364
kt0("-importkeystore -srckeystore ks -destkeystore ks2",
365
"changeit", "changeit", "changeit")
366
.shouldContain("Importing keystore ks to ks2...")
367
.shouldNotContain("original")
368
.shouldNotContain("Migrated");
369
}
370
371
static void checkImport() throws Exception {
372
373
saveStore();
374
375
// add trusted cert
376
377
// cert already in
378
kt("-importcert -alias d -file a.cert", "no")
379
.shouldContain("Certificate already exists in keystore")
380
.shouldContain("Warning")
381
.shouldMatch("The input.*MD5withRSA.*is disabled")
382
.shouldContain("Do you still want to add it?");
383
kt("-importcert -alias d -file a.cert -noprompt")
384
.shouldContain("Warning")
385
.shouldMatch("The input.*MD5withRSA.*is disabled")
386
.shouldNotContain("[no]");
387
388
// cert is self-signed
389
kt("-delete -alias a");
390
kt("-delete -alias d");
391
kt("-importcert -alias d -file a.cert", "no")
392
.shouldContain("Warning")
393
.shouldContain("MD5withRSA (disabled)")
394
.shouldMatch("The input.*MD5withRSA.*is disabled")
395
.shouldContain("Trust this certificate?");
396
kt("-importcert -alias d -file a.cert -noprompt")
397
.shouldContain("Warning")
398
.shouldMatch("The input.*MD5withRSA.*is disabled")
399
.shouldNotContain("[no]");
400
401
// JDK-8177569: no warning for sigalg of trusted cert
402
String weakSigAlgCA = null;
403
KeyStore ks = KeyStoreUtil.getCacertsKeyStore();
404
if (ks != null) {
405
DisabledAlgorithmConstraints disabledCheck =
406
new DisabledAlgorithmConstraints(
407
DisabledAlgorithmConstraints.PROPERTY_CERTPATH_DISABLED_ALGS);
408
Set<CryptoPrimitive> sigPrimitiveSet = Collections
409
.unmodifiableSet(EnumSet.of(CryptoPrimitive.SIGNATURE));
410
411
for (String s : Collections.list(ks.aliases())) {
412
if (ks.isCertificateEntry(s)) {
413
X509Certificate c = (X509Certificate)ks.getCertificate(s);
414
String sigAlg = c.getSigAlgName();
415
if (!disabledCheck.permits(sigPrimitiveSet, sigAlg, null)) {
416
weakSigAlgCA = sigAlg;
417
Files.write(Paths.get("ca.cert"),
418
ks.getCertificate(s).getEncoded());
419
break;
420
}
421
}
422
}
423
}
424
if (weakSigAlgCA != null) {
425
// The following 2 commands still have a warning on why not using
426
// the -cacerts option directly.
427
kt("-list -keystore " + cacerts_location)
428
.shouldNotContain("risk");
429
kt("-list -v -keystore " + cacerts_location)
430
.shouldNotContain("risk");
431
432
// -printcert will always show warnings
433
kt("-printcert -file ca.cert")
434
.shouldContain("name: " + weakSigAlgCA + " (disabled)")
435
.shouldContain("Warning")
436
.shouldMatch("The certificate.*" + weakSigAlgCA + ".*is disabled");
437
kt("-printcert -file ca.cert -trustcacerts") // -trustcacerts useless
438
.shouldContain("name: " + weakSigAlgCA + " (disabled)")
439
.shouldContain("Warning")
440
.shouldMatch("The certificate.*" + weakSigAlgCA + ".*is disabled");
441
442
// Importing with -trustcacerts ignore CA cert's sig alg
443
kt("-delete -alias d");
444
kt("-importcert -alias d -trustcacerts -file ca.cert", "no")
445
.shouldContain("Certificate already exists in system-wide CA")
446
.shouldNotContain("risk")
447
.shouldContain("Do you still want to add it to your own keystore?");
448
kt("-importcert -alias d -trustcacerts -file ca.cert -noprompt")
449
.shouldNotContain("risk")
450
.shouldNotContain("[no]");
451
452
// but not without -trustcacerts
453
kt("-delete -alias d");
454
kt("-importcert -alias d -file ca.cert", "no")
455
.shouldContain("name: " + weakSigAlgCA + " (disabled)")
456
.shouldContain("Warning")
457
.shouldMatch("The input.*" + weakSigAlgCA + ".*is disabled")
458
.shouldContain("Trust this certificate?");
459
kt("-importcert -alias d -file ca.cert -noprompt")
460
.shouldContain("Warning")
461
.shouldMatch("The input.*" + weakSigAlgCA + ".*is disabled")
462
.shouldNotContain("[no]");
463
}
464
465
// a non self-signed weak cert
466
reStore();
467
certreq("b", "");
468
gencert("c-b", "");
469
kt("-importcert -alias d -file c-b.cert") // weak only, no prompt
470
.shouldContain("Warning")
471
.shouldNotContain("512-bit RSA key (disabled)")
472
.shouldMatch("The input.*512-bit RSA key.*is disabled")
473
.shouldNotContain("[no]");
474
475
kt("-delete -alias b");
476
kt("-delete -alias c");
477
kt("-delete -alias d");
478
479
kt("-importcert -alias d -file c-b.cert", "no") // weak and not trusted
480
.shouldContain("Warning")
481
.shouldContain("512-bit RSA key (disabled)")
482
.shouldMatch("The input.*512-bit RSA key.*is disabled")
483
.shouldContain("Trust this certificate?");
484
kt("-importcert -alias d -file c-b.cert -noprompt")
485
.shouldContain("Warning")
486
.shouldMatch("The input.*512-bit RSA key.*is disabled")
487
.shouldNotContain("[no]");
488
489
// a non self-signed strong cert
490
reStore();
491
certreq("a", "");
492
gencert("c-a", "");
493
kt("-importcert -alias d -file c-a.cert") // trusted
494
.shouldNotContain("Warning")
495
.shouldNotContain("[no]");
496
497
kt("-delete -alias a");
498
kt("-delete -alias c");
499
kt("-delete -alias d");
500
501
kt("-importcert -alias d -file c-a.cert", "no") // not trusted
502
.shouldNotContain("Warning")
503
.shouldContain("Trust this certificate?");
504
kt("-importcert -alias d -file c-a.cert -noprompt")
505
.shouldNotContain("Warning")
506
.shouldNotContain("[no]");
507
508
// install reply
509
510
reStore();
511
certreq("c", "");
512
gencert("a-c", "");
513
kt("-importcert -alias c -file a-c.cert")
514
.shouldContain("Warning")
515
.shouldMatch("Issuer <a>.*MD5withRSA.*is disabled");
516
517
// JDK-8177569: no warning for sigalg of trusted cert
518
reStore();
519
// Change a into a TrustedCertEntry
520
kt("-exportcert -alias a -file a.cert");
521
kt("-delete -alias a");
522
kt("-importcert -alias a -file a.cert -noprompt");
523
kt("-list -alias a -v")
524
.shouldNotContain("disabled")
525
.shouldNotContain("Warning");
526
// This time a is trusted and no warning on its weak sig alg
527
kt("-importcert -alias c -file a-c.cert")
528
.shouldNotContain("Warning");
529
530
reStore();
531
532
gencert("a-b", "");
533
gencert("b-c", "");
534
535
// Full chain with root
536
cat("a-a-b-c.cert", "b-c.cert", "a-b.cert", "a.cert");
537
kt("-importcert -alias c -file a-a-b-c.cert") // only weak
538
.shouldContain("Warning")
539
.shouldMatch("Reply #2 of 3.*512-bit RSA key.*is disabled")
540
.shouldMatch("Reply #3 of 3.*MD5withRSA.*is disabled")
541
.shouldNotContain("[no]");
542
543
// Without root
544
cat("a-b-c.cert", "b-c.cert", "a-b.cert");
545
kt("-importcert -alias c -file a-b-c.cert") // only weak
546
.shouldContain("Warning")
547
.shouldMatch("Reply #2 of 2.*512-bit RSA key.*is disabled")
548
.shouldMatch("Issuer <a>.*MD5withRSA.*is disabled")
549
.shouldNotContain("[no]");
550
551
reStore();
552
gencert("b-a", "");
553
554
kt("-importcert -alias a -file b-a.cert")
555
.shouldContain("Warning")
556
.shouldMatch("Issuer <b>.*512-bit RSA key.*is disabled")
557
.shouldNotContain("[no]");
558
559
kt("-importcert -alias a -file c-a.cert")
560
.shouldNotContain("Warning");
561
562
kt("-importcert -alias b -file c-b.cert")
563
.shouldContain("Warning")
564
.shouldMatch("The input.*512-bit RSA key.*is disabled")
565
.shouldNotContain("[no]");
566
567
reStore();
568
gencert("b-a", "");
569
570
cat("c-b-a.cert", "b-a.cert", "c-b.cert");
571
572
kt("-printcert -file c-b-a.cert")
573
.shouldContain("Warning")
574
.shouldMatch("The certificate #2 of 2.*512-bit RSA key.*is disabled");
575
576
kt("-delete -alias b");
577
578
kt("-importcert -alias a -file c-b-a.cert")
579
.shouldContain("Warning")
580
.shouldMatch("Reply #2 of 2.*512-bit RSA key.*is disabled")
581
.shouldNotContain("[no]");
582
583
kt("-delete -alias c");
584
kt("-importcert -alias a -file c-b-a.cert", "no")
585
.shouldContain("Top-level certificate in reply:")
586
.shouldContain("512-bit RSA key (disabled)")
587
.shouldContain("Warning")
588
.shouldMatch("Reply #2 of 2.*512-bit RSA key.*is disabled")
589
.shouldContain("Install reply anyway?");
590
kt("-importcert -alias a -file c-b-a.cert -noprompt")
591
.shouldContain("Warning")
592
.shouldMatch("Reply #2 of 2.*512-bit RSA key.*is disabled")
593
.shouldNotContain("[no]");
594
595
reStore();
596
}
597
598
private static void cat(String dest, String... src) throws IOException {
599
System.out.println("---------------------------------------------");
600
System.out.printf("$ cat ");
601
602
ByteArrayOutputStream bout = new ByteArrayOutputStream();
603
for (String s : src) {
604
System.out.printf(s + " ");
605
bout.write(Files.readAllBytes(Paths.get(s)));
606
}
607
Files.write(Paths.get(dest), bout.toByteArray());
608
System.out.println("> " + dest);
609
}
610
611
static void checkDisabledGenCRL(String alias, String options, String bad) {
612
613
OutputAnalyzer oa = kt("-gencrl -alias " + alias
614
+ " -id 1 -file " + alias + ".crl " + options);
615
if (bad == null) {
616
oa.shouldNotContain("Warning");
617
} else {
618
oa.shouldContain("Warning")
619
.shouldMatch("The generated CRL.*" + bad + ".*is disabled");
620
}
621
622
oa = kt("-printcrl -file " + alias + ".crl");
623
if (bad == null) {
624
oa.shouldNotContain("Warning")
625
.shouldContain("Verified by " + alias + " in keystore")
626
.shouldNotContain("(disabled");
627
} else {
628
oa.shouldContain("Warning:")
629
.shouldMatch("The CRL.*" + bad + ".*is disabled")
630
.shouldContain("Verified by " + alias + " in keystore")
631
.shouldContain(bad + " (disabled)");
632
}
633
}
634
635
static void checkDisabledCertReq(
636
String alias, String options, String bad) {
637
638
OutputAnalyzer oa = certreq(alias, options);
639
if (bad == null) {
640
oa.shouldNotContain("Warning");
641
} else {
642
oa.shouldContain("Warning")
643
.shouldMatch("The generated certificate request.*" + bad + ".*is disabled");
644
}
645
646
oa = kt("-printcertreq -file " + alias + ".req");
647
if (bad == null) {
648
oa.shouldNotContain("Warning")
649
.shouldNotContain("(disabled)");
650
} else {
651
oa.shouldContain("Warning")
652
.shouldMatch("The certificate request.*" + bad + ".*is disabled")
653
.shouldContain(bad + " (disabled)");
654
}
655
}
656
657
static void checkDisabledGenKeyPair(
658
String alias, String options, String bad) {
659
660
OutputAnalyzer oa = genkeypair(alias, options);
661
if (bad == null) {
662
oa.shouldNotContain("Warning");
663
} else {
664
oa.shouldContain("Warning")
665
.shouldMatch("The generated certificate.*" + bad + ".*is disabled");
666
}
667
668
oa = kt("-exportcert -alias " + alias + " -file " + alias + ".cert");
669
if (bad == null) {
670
oa.shouldNotContain("Warning");
671
} else {
672
oa.shouldContain("Warning")
673
.shouldMatch("The certificate.*" + bad + ".*is disabled");
674
}
675
676
oa = kt("-exportcert -rfc -alias " + alias + " -file " + alias + ".cert");
677
if (bad == null) {
678
oa.shouldNotContain("Warning");
679
} else {
680
oa.shouldContain("Warning")
681
.shouldMatch("The certificate.*" + bad + ".*is disabled");
682
}
683
684
oa = kt("-printcert -rfc -file " + alias + ".cert");
685
if (bad == null) {
686
oa.shouldNotContain("Warning");
687
} else {
688
oa.shouldContain("Warning")
689
.shouldMatch("The certificate.*" + bad + ".*is disabled");
690
}
691
692
oa = kt("-list -alias " + alias);
693
if (bad == null) {
694
oa.shouldNotContain("Warning");
695
} else {
696
oa.shouldContain("Warning")
697
.shouldMatch("The certificate.*" + bad + ".*is disabled");
698
}
699
700
// With cert content
701
702
oa = kt("-printcert -file " + alias + ".cert");
703
if (bad == null) {
704
oa.shouldNotContain("Warning");
705
} else {
706
oa.shouldContain("Warning")
707
.shouldContain(bad + " (disabled)")
708
.shouldMatch("The certificate.*" + bad + ".*is disabled");
709
}
710
711
oa = kt("-list -v -alias " + alias);
712
if (bad == null) {
713
oa.shouldNotContain("Warning");
714
} else {
715
oa.shouldContain("Warning")
716
.shouldContain(bad + " (disabled)")
717
.shouldMatch("The certificate.*" + bad + ".*is disabled");
718
}
719
}
720
721
static void checkWeakGenKeyPair(
722
String alias, String options, String bad) {
723
724
OutputAnalyzer oa = genkeypair(alias, options);
725
if (bad == null) {
726
oa.shouldNotContain("Warning");
727
} else {
728
oa.shouldContain("Warning")
729
.shouldMatch("The generated certificate.*" + bad + ".*will be disabled");
730
}
731
732
oa = kt("-exportcert -alias " + alias + " -file " + alias + ".cert");
733
if (bad == null) {
734
oa.shouldNotContain("Warning");
735
} else {
736
oa.shouldContain("Warning")
737
.shouldMatch("The certificate.*" + bad + ".*will be disabled");
738
}
739
740
oa = kt("-exportcert -rfc -alias " + alias + " -file " + alias + ".cert");
741
if (bad == null) {
742
oa.shouldNotContain("Warning");
743
} else {
744
oa.shouldContain("Warning")
745
.shouldMatch("The certificate.*" + bad + ".*will be disabled");
746
}
747
748
oa = kt("-printcert -rfc -file " + alias + ".cert");
749
if (bad == null) {
750
oa.shouldNotContain("Warning");
751
} else {
752
oa.shouldContain("Warning")
753
.shouldMatch("The certificate.*" + bad + ".*will be disabled");
754
}
755
756
oa = kt("-list -alias " + alias);
757
if (bad == null) {
758
oa.shouldNotContain("Warning");
759
} else {
760
oa.shouldContain("Warning")
761
.shouldMatch("The certificate.*" + bad + ".*will be disabled");
762
}
763
764
// With cert content
765
766
oa = kt("-printcert -file " + alias + ".cert");
767
if (bad == null) {
768
oa.shouldNotContain("Warning");
769
} else {
770
oa.shouldContain("Warning")
771
.shouldContain(bad + " (weak)")
772
.shouldMatch("The certificate.*" + bad + ".*will be disabled");
773
}
774
775
oa = kt("-list -v -alias " + alias);
776
if (bad == null) {
777
oa.shouldNotContain("Warning");
778
} else {
779
oa.shouldContain("Warning")
780
.shouldContain(bad + " (weak)")
781
.shouldMatch("The certificate.*" + bad + ".*will be disabled");
782
}
783
}
784
785
786
static void checkWeakGenCRL(String alias, String options, String bad) {
787
788
OutputAnalyzer oa = kt("-gencrl -alias " + alias
789
+ " -id 1 -file " + alias + ".crl " + options);
790
if (bad == null) {
791
oa.shouldNotContain("Warning");
792
} else {
793
oa.shouldContain("Warning")
794
.shouldMatch("The generated CRL.*" + bad + ".*will be disabled");
795
}
796
797
oa = kt("-printcrl -file " + alias + ".crl");
798
if (bad == null) {
799
oa.shouldNotContain("Warning")
800
.shouldContain("Verified by " + alias + " in keystore")
801
.shouldNotContain("(weak");
802
} else {
803
oa.shouldContain("Warning:")
804
.shouldMatch("The CRL.*" + bad + ".*will be disabled")
805
.shouldContain("Verified by " + alias + " in keystore")
806
.shouldContain(bad + " (weak)");
807
}
808
}
809
810
static void checkWeakCertReq(
811
String alias, String options, String bad) {
812
813
OutputAnalyzer oa = certreq(alias, options);
814
if (bad == null) {
815
oa.shouldNotContain("Warning");
816
} else {
817
oa.shouldContain("Warning")
818
.shouldMatch("The generated certificate request.*" + bad + ".*will be disabled");
819
}
820
821
oa = kt("-printcertreq -file " + alias + ".req");
822
if (bad == null) {
823
oa.shouldNotContain("Warning")
824
.shouldNotContain("(weak)");
825
} else {
826
oa.shouldContain("Warning")
827
.shouldMatch("The certificate request.*" + bad + ".*will be disabled")
828
.shouldContain(bad + " (weak)");
829
}
830
}
831
832
// This is slow, but real keytool process is launched.
833
static OutputAnalyzer kt1(String cmd, String... input) {
834
cmd = "-keystore ks -storepass changeit " +
835
"-keypass changeit " + cmd;
836
System.out.println("---------------------------------------------");
837
try {
838
SecurityTools.setResponse(input);
839
return SecurityTools.keytool(cmd);
840
} catch (Throwable e) {
841
throw new RuntimeException(e);
842
}
843
}
844
845
static OutputAnalyzer kt(String cmd, String... input) {
846
return kt0("-keystore ks -storepass changeit " +
847
"-keypass changeit " + cmd, input);
848
}
849
850
// Fast keytool execution by directly calling its main() method
851
static OutputAnalyzer kt0(String cmd, String... input) {
852
PrintStream out = System.out;
853
PrintStream err = System.err;
854
InputStream ins = System.in;
855
ByteArrayOutputStream bout = new ByteArrayOutputStream();
856
ByteArrayOutputStream berr = new ByteArrayOutputStream();
857
boolean succeed = true;
858
String sout;
859
String serr;
860
try {
861
System.out.println("---------------------------------------------");
862
System.out.println("$ keytool " + cmd);
863
System.out.println();
864
String feed = "";
865
if (input.length > 0) {
866
feed = Stream.of(input).collect(Collectors.joining("\n")) + "\n";
867
}
868
System.setIn(new ByteArrayInputStream(feed.getBytes()));
869
System.setOut(new PrintStream(bout));
870
System.setErr(new PrintStream(berr));
871
sun.security.tools.keytool.Main.main(
872
cmd.trim().split("\\s+"));
873
} catch (Exception e) {
874
// Might be a normal exception when -debug is on or
875
// SecurityException (thrown by jtreg) when System.exit() is called
876
if (!(e instanceof SecurityException)) {
877
e.printStackTrace();
878
}
879
succeed = false;
880
} finally {
881
System.setOut(out);
882
System.setErr(err);
883
System.setIn(ins);
884
sout = new String(bout.toByteArray());
885
serr = new String(berr.toByteArray());
886
System.out.println("STDOUT:\n" + sout + "\nSTDERR:\n" + serr);
887
}
888
if (!succeed) {
889
throw new RuntimeException();
890
}
891
return new OutputAnalyzer(sout, serr);
892
}
893
894
static OutputAnalyzer importkeystore(String src, String dest,
895
String options) {
896
return kt0("-importkeystore "
897
+ "-srckeystore " + src + " -destkeystore " + dest
898
+ " -srcstorepass changeit -deststorepass changeit " + options);
899
}
900
901
static OutputAnalyzer genkeypair(String alias, String options) {
902
return kt("-genkeypair -alias " + alias + " -dname CN=" + alias
903
+ " -keyalg RSA -storetype PKCS12 " + options);
904
}
905
906
static OutputAnalyzer certreq(String alias, String options) {
907
return kt("-certreq -alias " + alias
908
+ " -file " + alias + ".req " + options);
909
}
910
911
static OutputAnalyzer exportcert(String alias) {
912
return kt("-exportcert -alias " + alias + " -file " + alias + ".cert");
913
}
914
915
static OutputAnalyzer gencert(String relation, String options) {
916
int pos = relation.indexOf("-");
917
String issuer = relation.substring(0, pos);
918
String subject = relation.substring(pos + 1);
919
return kt(" -gencert -alias " + issuer + " -infile " + subject
920
+ ".req -outfile " + relation + ".cert " + options);
921
}
922
923
static void saveStore() throws IOException {
924
System.out.println("---------------------------------------------");
925
System.out.println("$ cp ks ks2");
926
Files.copy(Paths.get("ks"), Paths.get("ks2"),
927
StandardCopyOption.REPLACE_EXISTING);
928
}
929
930
static void reStore() throws IOException {
931
System.out.println("---------------------------------------------");
932
System.out.println("$ cp ks2 ks");
933
Files.copy(Paths.get("ks2"), Paths.get("ks"),
934
StandardCopyOption.REPLACE_EXISTING);
935
}
936
937
static void rm(String s) throws IOException {
938
System.out.println("---------------------------------------------");
939
System.out.println("$ rm " + s);
940
Files.deleteIfExists(Paths.get(s));
941
}
942
}
943
944