Skip to content

Commit c7e2174

Browse files
Hai-May Chaowangweij
authored andcommitted
8259401: Add checking to jarsigner to warn weak algorithms used in signer’s cert chain
Reviewed-by: mullan, weijun, rhalade
1 parent ccdf171 commit c7e2174

File tree

2 files changed

+143
-3
lines changed

2 files changed

+143
-3
lines changed

src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Main.java

Lines changed: 51 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -1401,6 +1401,35 @@ private void checkWeakSign(PrivateKey key) {
14011401
}
14021402
}
14031403

1404+
private static String checkWeakKey(PublicKey key) {
1405+
int kLen = KeyUtil.getKeySize(key);
1406+
if (DISABLED_CHECK.permits(SIG_PRIMITIVE_SET, key)) {
1407+
if (LEGACY_CHECK.permits(SIG_PRIMITIVE_SET, key)) {
1408+
if (kLen >= 0) {
1409+
return String.format(rb.getString("key.bit"), kLen);
1410+
} else {
1411+
return rb.getString("unknown.size");
1412+
}
1413+
} else {
1414+
return String.format(rb.getString("key.bit.weak"), kLen);
1415+
}
1416+
} else {
1417+
return String.format(rb.getString("key.bit.disabled"), kLen);
1418+
}
1419+
}
1420+
1421+
private static String checkWeakAlg(String alg) {
1422+
if (DISABLED_CHECK.permits(SIG_PRIMITIVE_SET, alg, null)) {
1423+
if (LEGACY_CHECK.permits(SIG_PRIMITIVE_SET, alg, null)) {
1424+
return alg;
1425+
} else {
1426+
return String.format(rb.getString("with.weak"), alg);
1427+
}
1428+
} else {
1429+
return String.format(rb.getString("with.disabled"), alg);
1430+
}
1431+
}
1432+
14041433
private static MessageFormat validityTimeForm = null;
14051434
private static MessageFormat notYetTimeForm = null;
14061435
private static MessageFormat expiredTimeForm = null;
@@ -1444,12 +1473,31 @@ String printCert(boolean isTsCert, String tab, Certificate c,
14441473
}
14451474

14461475
if (x509Cert != null) {
1476+
PublicKey key = x509Cert.getPublicKey();
1477+
String sigalg = x509Cert.getSigAlgName();
14471478

1448-
certStr.append("\n").append(tab).append("[");
1449-
1479+
// Process the certificate in the signer's cert chain to see if
1480+
// weak algorithms are used, and provide warnings as needed.
14501481
if (trustedCerts.contains(x509Cert)) {
1482+
// If the cert is trusted, only check its key size, but not its
1483+
// signature algorithm.
1484+
certStr.append("\n").append(tab)
1485+
.append("Signature algorithm: ")
1486+
.append(sigalg)
1487+
.append(rb.getString("COMMA"))
1488+
.append(checkWeakKey(key));
1489+
1490+
certStr.append("\n").append(tab).append("[");
14511491
certStr.append(rb.getString("trusted.certificate"));
14521492
} else {
1493+
certStr.append("\n").append(tab)
1494+
.append("Signature algorithm: ")
1495+
.append(checkWeakAlg(sigalg))
1496+
.append(rb.getString("COMMA"))
1497+
.append(checkWeakKey(key));
1498+
1499+
certStr.append("\n").append(tab).append("[");
1500+
14531501
Date notAfter = x509Cert.getNotAfter();
14541502
try {
14551503
boolean printValidity = true;
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
/*
2+
* Copyright (c) 2021, 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 8259401
27+
* @summary Check certificates in signer's cert chain to see if warning emitted
28+
* @library /test/lib
29+
*/
30+
31+
import jdk.test.lib.SecurityTools;
32+
import jdk.test.lib.process.OutputAnalyzer;
33+
import jdk.test.lib.util.JarUtils;
34+
35+
import java.nio.file.Path;
36+
37+
public class CheckSignerCertChain {
38+
39+
static OutputAnalyzer kt(String cmd, String ks) throws Exception {
40+
return SecurityTools.keytool("-storepass changeit " + cmd +
41+
" -keystore " + ks);
42+
}
43+
44+
static void gencert(String owner, String cmd) throws Exception {
45+
kt("-certreq -alias " + owner + " -file tmp.req", "ks");
46+
kt("-gencert -infile tmp.req -outfile tmp.cert " + cmd, "ks");
47+
kt("-importcert -alias " + owner + " -file tmp.cert", "ks");
48+
}
49+
50+
public static void main(String[] args) throws Exception {
51+
52+
// root certificate using SHA1withRSA and 1024-bit key
53+
System.out.println("Generating a root cert using SHA1withRSA and 1024-bit key");
54+
kt("-genkeypair -keyalg rsa -alias ca -dname CN=CA -ext bc:c " +
55+
"-keysize 1024 -sigalg SHA1withRSA", "ks");
56+
kt("-genkeypair -keyalg rsa -alias ca1 -dname CN=CA1", "ks");
57+
kt("-genkeypair -keyalg rsa -alias e1 -dname CN=E1", "ks");
58+
59+
// intermediate certificate using SHA1withRSA and 2048-bit key
60+
System.out.println("Generating an intermediate cert using SHA1withRSA and 2048-bit key");
61+
gencert("ca1", "-alias ca -ext san=dns:ca1 -ext bc:c " +
62+
"-sigalg SHA1withRSA ");
63+
64+
// end entity certificate using SHA256withRSA and 2048-bit key
65+
System.out.println("Generating an end entity cert using SHA256withRSA and 2048-bit key");
66+
gencert("e1", "-alias ca1 -ext san=dns:e1 ");
67+
68+
JarUtils.createJarFile(Path.of("a.jar"), Path.of("."), Path.of("ks"));
69+
70+
SecurityTools.jarsigner("-keystore ks -storepass changeit " +
71+
"-signedjar signeda.jar " +
72+
"-sigalg SHA256withRSA " +
73+
"-verbose" +
74+
" a.jar e1")
75+
.shouldContain("Signature algorithm: SHA1withRSA (weak), 2048-bit key")
76+
// For trusted cert, warning should be generated for its weak 1024-bit
77+
// key, but not for its SHA1withRSA algorithm.
78+
.shouldContain("Signature algorithm: SHA1withRSA, 1024-bit key (weak)")
79+
.shouldHaveExitValue(0);
80+
81+
kt("-exportcert -alias ca -rfc -file cacert", "ks");
82+
kt("-importcert -noprompt -file cacert", "caks");
83+
84+
SecurityTools.jarsigner("-verify -certs signeda.jar " +
85+
"-keystore caks -storepass changeit -verbose -debug")
86+
.shouldContain("Signature algorithm: SHA1withRSA (weak), 2048-bit key")
87+
// For trusted cert, warning should be generated for its weak 1024-bit
88+
// key, but not for its SHA1withRSA algorithm.
89+
.shouldContain("Signature algorithm: SHA1withRSA, 1024-bit key (weak)")
90+
.shouldHaveExitValue(0);
91+
}
92+
}

0 commit comments

Comments
 (0)