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