8172404: Tools should warn if weak algorithms are used before restricting them
Reviewed-by: mullan, weijun
This commit is contained in:
parent
9735678c26
commit
f04a7e5cb4
@ -194,6 +194,10 @@ public final class Main {
|
||||
new DisabledAlgorithmConstraints(
|
||||
DisabledAlgorithmConstraints.PROPERTY_CERTPATH_DISABLED_ALGS);
|
||||
|
||||
private static final DisabledAlgorithmConstraints LEGACY_CHECK =
|
||||
new DisabledAlgorithmConstraints(
|
||||
DisabledAlgorithmConstraints.PROPERTY_SECURITY_LEGACY_ALGS);
|
||||
|
||||
private static final Set<CryptoPrimitive> SIG_PRIMITIVE_SET = Collections
|
||||
.unmodifiableSet(EnumSet.of(CryptoPrimitive.SIGNATURE));
|
||||
private boolean isPasswordlessKeyStore = false;
|
||||
@ -3320,9 +3324,13 @@ public final class Main {
|
||||
|
||||
private String withWeak(String alg) {
|
||||
if (DISABLED_CHECK.permits(SIG_PRIMITIVE_SET, alg, null)) {
|
||||
return alg;
|
||||
if (LEGACY_CHECK.permits(SIG_PRIMITIVE_SET, alg, null)) {
|
||||
return alg;
|
||||
} else {
|
||||
return String.format(rb.getString("with.weak"), alg);
|
||||
}
|
||||
} else {
|
||||
return String.format(rb.getString("with.weak"), alg);
|
||||
return String.format(rb.getString("with.disabled"), alg);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3341,13 +3349,17 @@ public final class Main {
|
||||
int kLen = KeyUtil.getKeySize(key);
|
||||
String displayAlg = fullDisplayAlgName(key);
|
||||
if (DISABLED_CHECK.permits(SIG_PRIMITIVE_SET, key)) {
|
||||
if (kLen >= 0) {
|
||||
return String.format(rb.getString("key.bit"), kLen, displayAlg);
|
||||
if (LEGACY_CHECK.permits(SIG_PRIMITIVE_SET, key)) {
|
||||
if (kLen >= 0) {
|
||||
return String.format(rb.getString("key.bit"), kLen, displayAlg);
|
||||
} else {
|
||||
return String.format(rb.getString("unknown.size.1"), displayAlg);
|
||||
}
|
||||
} else {
|
||||
return String.format(rb.getString("unknown.size.1"), displayAlg);
|
||||
return String.format(rb.getString("key.bit.weak"), kLen, displayAlg);
|
||||
}
|
||||
} else {
|
||||
return String.format(rb.getString("key.bit.weak"), kLen, displayAlg);
|
||||
return String.format(rb.getString("key.bit.disabled"), kLen, displayAlg);
|
||||
}
|
||||
}
|
||||
|
||||
@ -4651,18 +4663,28 @@ public final class Main {
|
||||
}
|
||||
|
||||
private void checkWeak(String label, String sigAlg, Key key) {
|
||||
|
||||
if (sigAlg != null && !DISABLED_CHECK.permits(
|
||||
SIG_PRIMITIVE_SET, sigAlg, null)) {
|
||||
weakWarnings.add(String.format(
|
||||
rb.getString("whose.sigalg.risk"), label, sigAlg));
|
||||
if (sigAlg != null) {
|
||||
if (!DISABLED_CHECK.permits(SIG_PRIMITIVE_SET, sigAlg, null)) {
|
||||
weakWarnings.add(String.format(
|
||||
rb.getString("whose.sigalg.disabled"), label, sigAlg));
|
||||
} else if (!LEGACY_CHECK.permits(SIG_PRIMITIVE_SET, sigAlg, null)) {
|
||||
weakWarnings.add(String.format(
|
||||
rb.getString("whose.sigalg.weak"), label, sigAlg));
|
||||
}
|
||||
}
|
||||
if (key != null && !DISABLED_CHECK.permits(SIG_PRIMITIVE_SET, key)) {
|
||||
weakWarnings.add(String.format(
|
||||
rb.getString("whose.key.risk"),
|
||||
label,
|
||||
|
||||
if (key != null) {
|
||||
if (!DISABLED_CHECK.permits(SIG_PRIMITIVE_SET, key)) {
|
||||
weakWarnings.add(String.format(
|
||||
rb.getString("whose.key.disabled"), label,
|
||||
String.format(rb.getString("key.bit"),
|
||||
KeyUtil.getKeySize(key), fullDisplayAlgName(key))));
|
||||
KeyUtil.getKeySize(key), fullDisplayAlgName(key))));
|
||||
} else if (!LEGACY_CHECK.permits(SIG_PRIMITIVE_SET, key)) {
|
||||
weakWarnings.add(String.format(
|
||||
rb.getString("whose.key.weak"), label,
|
||||
String.format(rb.getString("key.bit"),
|
||||
KeyUtil.getKeySize(key), fullDisplayAlgName(key))));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -459,8 +459,10 @@ public class Resources extends java.util.ListResourceBundle {
|
||||
{"alias.in.cacerts", "Issuer <%s> in cacerts"},
|
||||
{"alias.in.keystore", "Issuer <%s>"},
|
||||
{"with.weak", "%s (weak)"},
|
||||
{"with.disabled", "%s (disabled)"},
|
||||
{"key.bit", "%1$d-bit %2$s key"},
|
||||
{"key.bit.weak", "%1$d-bit %2$s key (weak)"},
|
||||
{"key.bit.disabled", "%1$d-bit %2$s key (disabled)"},
|
||||
{"unknown.size.1", "%s key of unknown size"},
|
||||
{".PATTERN.printX509Cert.with.weak",
|
||||
"Owner: {0}\nIssuer: {1}\nSerial number: {2}\nValid from: {3} until: {4}\nCertificate fingerprints:\n\t SHA1: {5}\n\t SHA256: {6}\nSignature algorithm name: {7}\nSubject Public Key Algorithm: {8}\nVersion: {9}"},
|
||||
@ -468,8 +470,10 @@ public class Resources extends java.util.ListResourceBundle {
|
||||
"PKCS #10 Certificate Request (Version 1.0)\n" +
|
||||
"Subject: %1$s\nFormat: %2$s\nPublic Key: %3$s\nSignature algorithm: %4$s\n"},
|
||||
{"verified.by.s.in.s.weak", "Verified by %1$s in %2$s with a %3$s"},
|
||||
{"whose.sigalg.risk", "%1$s uses the %2$s signature algorithm which is considered a security risk."},
|
||||
{"whose.key.risk", "%1$s uses a %2$s which is considered a security risk."},
|
||||
{"whose.sigalg.disabled", "%1$s uses the %2$s signature algorithm which is considered a security risk and is disabled."},
|
||||
{"whose.sigalg.weak", "%1$s uses the %2$s signature algorithm which is considered a security risk. This algorithm will be disabled in a future update."},
|
||||
{"whose.key.disabled", "%1$s uses a %2$s which is considered a security risk and is disabled."},
|
||||
{"whose.key.weak", "%1$s uses a %2$s which is considered a security risk. This key size will be disabled in a future update."},
|
||||
{"jks.storetype.warning", "The %1$s keystore uses a proprietary format. It is recommended to migrate to PKCS12 which is an industry standard format using \"keytool -importkeystore -srckeystore %2$s -destkeystore %2$s -deststoretype pkcs12\"."},
|
||||
{"migrate.keystore.warning", "Migrated \"%1$s\" to %4$s. The %2$s keystore is backed up as \"%3$s\"."},
|
||||
{"backup.keystore.warning", "The original keystore \"%1$s\" is backed up as \"%3$s\"..."},
|
||||
|
@ -63,6 +63,10 @@ public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints {
|
||||
public static final String PROPERTY_CERTPATH_DISABLED_ALGS =
|
||||
"jdk.certpath.disabledAlgorithms";
|
||||
|
||||
// Legacy algorithm security property for certificate path and jar
|
||||
public static final String PROPERTY_SECURITY_LEGACY_ALGS =
|
||||
"jdk.security.legacyAlgorithms";
|
||||
|
||||
// Disabled algorithm security property for TLS
|
||||
public static final String PROPERTY_TLS_DISABLED_ALGS =
|
||||
"jdk.tls.disabledAlgorithms";
|
||||
@ -948,4 +952,3 @@ public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -659,6 +659,26 @@ jdk.certpath.disabledAlgorithms=MD2, MD5, SHA1 jdkCA & usage TLSServer, \
|
||||
RSA keySize < 1024, DSA keySize < 1024, EC keySize < 224, \
|
||||
include jdk.disabled.namedCurves
|
||||
|
||||
#
|
||||
# Legacy algorithms for certification path (CertPath) processing and
|
||||
# signed JAR files.
|
||||
#
|
||||
# In some environments, a certain algorithm or key length may be undesirable
|
||||
# but is not yet disabled.
|
||||
#
|
||||
# Tools such as keytool and jarsigner may emit warnings when these legacy
|
||||
# algorithms are used. See the man pages for those tools for more information.
|
||||
#
|
||||
# The syntax is the same as the "jdk.certpath.disabledAlgorithms" and
|
||||
# "jdk.jar.disabledAlgorithms" security properties.
|
||||
#
|
||||
# Note: This property is currently used by the JDK Reference
|
||||
# implementation. It is not guaranteed to be examined and used by other
|
||||
# implementations.
|
||||
|
||||
jdk.security.legacyAlgorithms=SHA1, \
|
||||
RSA keySize < 2048, DSA keySize < 2048
|
||||
|
||||
#
|
||||
# Algorithm restrictions for signed JAR files
|
||||
#
|
||||
|
@ -99,6 +99,10 @@ public class Main {
|
||||
new DisabledAlgorithmConstraints(
|
||||
DisabledAlgorithmConstraints.PROPERTY_JAR_DISABLED_ALGS);
|
||||
|
||||
private static final DisabledAlgorithmConstraints LEGACY_CHECK =
|
||||
new DisabledAlgorithmConstraints(
|
||||
DisabledAlgorithmConstraints.PROPERTY_SECURITY_LEGACY_ALGS);
|
||||
|
||||
private static final Set<CryptoPrimitive> DIGEST_PRIMITIVE_SET = Collections
|
||||
.unmodifiableSet(EnumSet.of(CryptoPrimitive.MESSAGE_DIGEST));
|
||||
private static final Set<CryptoPrimitive> SIG_PRIMITIVE_SET = Collections
|
||||
@ -172,6 +176,11 @@ public class Main {
|
||||
// If there is a time stamp block inside the PKCS7 block file
|
||||
boolean hasTimestampBlock = false;
|
||||
|
||||
private PublicKey weakPublicKey = null;
|
||||
private boolean disabledAlgFound = false;
|
||||
private String legacyDigestAlg = null;
|
||||
private String legacyTsaDigestAlg = null;
|
||||
private String legacySigAlg = null;
|
||||
|
||||
// Severe warnings.
|
||||
|
||||
@ -182,7 +191,8 @@ public class Main {
|
||||
// only tsaChainNotValidated is set, i.e. has no affect on hasExpiredCert,
|
||||
// notYetValidCert, or any badXyzUsage.
|
||||
|
||||
private int weakAlg = 0; // 1. digestalg, 2. sigalg, 4. tsadigestalg
|
||||
private int legacyAlg = 0; // 1. digestalg, 2. sigalg, 4. tsadigestalg, 8. key
|
||||
private int disabledAlg = 0; // 1. digestalg, 2. sigalg, 4. tsadigestalg, 8. key
|
||||
private boolean hasExpiredCert = false;
|
||||
private boolean hasExpiredTsaCert = false;
|
||||
private boolean notYetValidCert = false;
|
||||
@ -199,8 +209,6 @@ public class Main {
|
||||
private Throwable chainNotValidatedReason = null;
|
||||
private Throwable tsaChainNotValidatedReason = null;
|
||||
|
||||
private boolean seeWeak = false;
|
||||
|
||||
PKIXBuilderParameters pkixParameters;
|
||||
Set<X509Certificate> trustedCerts = new HashSet<>();
|
||||
|
||||
@ -289,7 +297,7 @@ public class Main {
|
||||
|
||||
if (strict) {
|
||||
int exitCode = 0;
|
||||
if (weakAlg != 0 || chainNotValidated || hasExpiredCert
|
||||
if (disabledAlg != 0 || chainNotValidated || hasExpiredCert
|
||||
|| hasExpiredTsaCert || notYetValidCert || signerSelfSigned) {
|
||||
exitCode |= 4;
|
||||
}
|
||||
@ -910,7 +918,7 @@ public class Main {
|
||||
}
|
||||
|
||||
// Even if the verbose option is not specified, all out strings
|
||||
// must be generated so seeWeak can be updated.
|
||||
// must be generated so disabledAlgFound can be updated.
|
||||
if (!digestMap.isEmpty()
|
||||
|| !sigMap.isEmpty()
|
||||
|| !unparsableSignatures.isEmpty()) {
|
||||
@ -954,21 +962,21 @@ public class Main {
|
||||
history = String.format(
|
||||
rb.getString("history.with.ts"),
|
||||
signer.getSubjectX500Principal(),
|
||||
withWeak(digestAlg, DIGEST_PRIMITIVE_SET),
|
||||
withWeak(sigAlg, SIG_PRIMITIVE_SET),
|
||||
withWeak(key),
|
||||
verifyWithWeak(digestAlg, DIGEST_PRIMITIVE_SET, false),
|
||||
verifyWithWeak(sigAlg, SIG_PRIMITIVE_SET, false),
|
||||
verifyWithWeak(key),
|
||||
c,
|
||||
tsSigner.getSubjectX500Principal(),
|
||||
withWeak(tsDigestAlg, DIGEST_PRIMITIVE_SET),
|
||||
withWeak(tsSigAlg, SIG_PRIMITIVE_SET),
|
||||
withWeak(tsKey));
|
||||
verifyWithWeak(tsDigestAlg, DIGEST_PRIMITIVE_SET, true),
|
||||
verifyWithWeak(tsSigAlg, SIG_PRIMITIVE_SET, true),
|
||||
verifyWithWeak(tsKey));
|
||||
} else {
|
||||
history = String.format(
|
||||
rb.getString("history.without.ts"),
|
||||
signer.getSubjectX500Principal(),
|
||||
withWeak(digestAlg, DIGEST_PRIMITIVE_SET),
|
||||
withWeak(sigAlg, SIG_PRIMITIVE_SET),
|
||||
withWeak(key));
|
||||
verifyWithWeak(digestAlg, DIGEST_PRIMITIVE_SET, false),
|
||||
verifyWithWeak(sigAlg, SIG_PRIMITIVE_SET, false),
|
||||
verifyWithWeak(key));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// The only usage of sigNameMap, remember the name
|
||||
@ -992,8 +1000,9 @@ public class Main {
|
||||
}
|
||||
}
|
||||
System.out.println();
|
||||
|
||||
if (!anySigned) {
|
||||
if (seeWeak) {
|
||||
if (disabledAlgFound) {
|
||||
if (verbose != null) {
|
||||
System.out.println(rb.getString("jar.treated.unsigned.see.weak.verbose"));
|
||||
System.out.println("\n " +
|
||||
@ -1036,8 +1045,8 @@ public class Main {
|
||||
|
||||
if (badKeyUsage || badExtendedKeyUsage || badNetscapeCertType ||
|
||||
notYetValidCert || chainNotValidated || hasExpiredCert ||
|
||||
hasUnsignedEntry || signerSelfSigned || (weakAlg != 0) ||
|
||||
aliasNotInStore || notSignedByAlias ||
|
||||
hasUnsignedEntry || signerSelfSigned || (legacyAlg != 0) ||
|
||||
(disabledAlg != 0) || aliasNotInStore || notSignedByAlias ||
|
||||
tsaChainNotValidated ||
|
||||
(hasExpiredTsaCert && !signerNotExpired)) {
|
||||
|
||||
@ -1119,28 +1128,75 @@ public class Main {
|
||||
: rb.getString("This.jar.contains.entries.whose.signer.certificate.is.self.signed."));
|
||||
}
|
||||
|
||||
// weakAlg only detected in signing. The jar file is
|
||||
// now simply treated unsigned in verifying.
|
||||
if ((weakAlg & 1) == 1) {
|
||||
errors.add(String.format(
|
||||
rb.getString("The.1.algorithm.specified.for.the.2.option.is.considered.a.security.risk."),
|
||||
digestalg, "-digestalg"));
|
||||
}
|
||||
if (isSigning) {
|
||||
if ((legacyAlg & 1) == 1) {
|
||||
warnings.add(String.format(
|
||||
rb.getString("The.1.algorithm.specified.for.the.2.option.is.considered.a.security.risk..This.algorithm.will.be.disabled.in.a.future.update."),
|
||||
digestalg, "-digestalg"));
|
||||
}
|
||||
|
||||
if ((weakAlg & 2) == 2) {
|
||||
errors.add(String.format(
|
||||
rb.getString("The.1.algorithm.specified.for.the.2.option.is.considered.a.security.risk."),
|
||||
sigalg, "-sigalg"));
|
||||
}
|
||||
if ((weakAlg & 4) == 4) {
|
||||
errors.add(String.format(
|
||||
rb.getString("The.1.algorithm.specified.for.the.2.option.is.considered.a.security.risk."),
|
||||
tSADigestAlg, "-tsadigestalg"));
|
||||
}
|
||||
if ((weakAlg & 8) == 8) {
|
||||
errors.add(String.format(
|
||||
rb.getString("The.1.signing.key.has.a.keysize.of.2.which.is.considered.a.security.risk."),
|
||||
privateKey.getAlgorithm(), KeyUtil.getKeySize(privateKey)));
|
||||
if ((disabledAlg & 1) == 1) {
|
||||
errors.add(String.format(
|
||||
rb.getString("The.1.algorithm.specified.for.the.2.option.is.considered.a.security.risk.and.is.disabled."),
|
||||
digestalg, "-digestalg"));
|
||||
}
|
||||
|
||||
if ((legacyAlg & 2) == 2) {
|
||||
warnings.add(String.format(
|
||||
rb.getString("The.1.algorithm.specified.for.the.2.option.is.considered.a.security.risk..This.algorithm.will.be.disabled.in.a.future.update."),
|
||||
sigalg, "-sigalg"));
|
||||
}
|
||||
if ((disabledAlg & 2) == 2) {
|
||||
errors.add(String.format(
|
||||
rb.getString("The.1.algorithm.specified.for.the.2.option.is.considered.a.security.risk.and.is.disabled."),
|
||||
sigalg, "-sigalg"));
|
||||
}
|
||||
|
||||
if ((legacyAlg & 4) == 4) {
|
||||
warnings.add(String.format(
|
||||
rb.getString("The.1.algorithm.specified.for.the.2.option.is.considered.a.security.risk..This.algorithm.will.be.disabled.in.a.future.update."),
|
||||
tSADigestAlg, "-tsadigestalg"));
|
||||
}
|
||||
if ((disabledAlg & 4) == 4) {
|
||||
errors.add(String.format(
|
||||
rb.getString("The.1.algorithm.specified.for.the.2.option.is.considered.a.security.risk.and.is.disabled."),
|
||||
tSADigestAlg, "-tsadigestalg"));
|
||||
}
|
||||
|
||||
if ((legacyAlg & 8) == 8) {
|
||||
warnings.add(String.format(
|
||||
rb.getString("The.1.signing.key.has.a.keysize.of.2.which.is.considered.a.security.risk..This.key.size.will.be.disabled.in.a.future.update."),
|
||||
privateKey.getAlgorithm(), KeyUtil.getKeySize(privateKey)));
|
||||
}
|
||||
if ((disabledAlg & 8) == 8) {
|
||||
errors.add(String.format(
|
||||
rb.getString("The.1.signing.key.has.a.keysize.of.2.which.is.considered.a.security.risk.and.is.disabled."),
|
||||
privateKey.getAlgorithm(), KeyUtil.getKeySize(privateKey)));
|
||||
}
|
||||
} else {
|
||||
if ((legacyAlg & 1) != 0) {
|
||||
warnings.add(String.format(
|
||||
rb.getString("The.digest.algorithm.1.is.considered.a.security.risk..This.algorithm.will.be.disabled.in.a.future.update."),
|
||||
legacyDigestAlg));
|
||||
}
|
||||
|
||||
if ((legacyAlg & 2) == 2) {
|
||||
warnings.add(String.format(
|
||||
rb.getString("The.signature.algorithm.1.is.considered.a.security.risk..This.algorithm.will.be.disabled.in.a.future.update."),
|
||||
legacySigAlg));
|
||||
}
|
||||
|
||||
if ((legacyAlg & 4) != 0) {
|
||||
warnings.add(String.format(
|
||||
rb.getString("The.digest.algorithm.1.is.considered.a.security.risk..This.algorithm.will.be.disabled.in.a.future.update."),
|
||||
legacyTsaDigestAlg));
|
||||
}
|
||||
|
||||
if ((legacyAlg & 8) == 8) {
|
||||
warnings.add(String.format(
|
||||
rb.getString("The.1.signing.key.has.a.keysize.of.2.which.is.considered.a.security.risk..This.key.size.will.be.disabled.in.a.future.update."),
|
||||
weakPublicKey.getAlgorithm(), KeyUtil.getKeySize(weakPublicKey)));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
result = isSigning ? rb.getString("jar.signed.") : rb.getString("jar.verified.");
|
||||
@ -1249,27 +1305,84 @@ public class Main {
|
||||
}
|
||||
}
|
||||
|
||||
private String withWeak(String alg, Set<CryptoPrimitive> primitiveSet) {
|
||||
private String verifyWithWeak(String alg, Set<CryptoPrimitive> primitiveSet, boolean tsa) {
|
||||
if (DISABLED_CHECK.permits(primitiveSet, alg, null)) {
|
||||
return alg;
|
||||
if (LEGACY_CHECK.permits(primitiveSet, alg, null)) {
|
||||
return alg;
|
||||
} else {
|
||||
if (primitiveSet == SIG_PRIMITIVE_SET) {
|
||||
legacyAlg |= 2;
|
||||
legacySigAlg = alg;
|
||||
} else {
|
||||
if (tsa) {
|
||||
legacyAlg |= 4;
|
||||
legacyTsaDigestAlg = alg;
|
||||
} else {
|
||||
legacyAlg |= 1;
|
||||
legacyDigestAlg = alg;
|
||||
}
|
||||
}
|
||||
return String.format(rb.getString("with.weak"), alg);
|
||||
}
|
||||
} else {
|
||||
seeWeak = true;
|
||||
return String.format(rb.getString("with.weak"), alg);
|
||||
disabledAlgFound = true;
|
||||
return String.format(rb.getString("with.disabled"), alg);
|
||||
}
|
||||
}
|
||||
|
||||
private String withWeak(PublicKey key) {
|
||||
private String verifyWithWeak(PublicKey key) {
|
||||
int kLen = KeyUtil.getKeySize(key);
|
||||
if (DISABLED_CHECK.permits(SIG_PRIMITIVE_SET, key)) {
|
||||
int kLen = KeyUtil.getKeySize(key);
|
||||
if (kLen >= 0) {
|
||||
return String.format(rb.getString("key.bit"), kLen);
|
||||
if (LEGACY_CHECK.permits(SIG_PRIMITIVE_SET, key)) {
|
||||
if (kLen >= 0) {
|
||||
return String.format(rb.getString("key.bit"), kLen);
|
||||
} else {
|
||||
return rb.getString("unknown.size");
|
||||
}
|
||||
} else {
|
||||
return rb.getString("unknown.size");
|
||||
weakPublicKey = key;
|
||||
legacyAlg |= 8;
|
||||
return String.format(rb.getString("key.bit.weak"), kLen);
|
||||
}
|
||||
} else {
|
||||
seeWeak = true;
|
||||
return String.format(
|
||||
rb.getString("key.bit.weak"), KeyUtil.getKeySize(key));
|
||||
disabledAlgFound = true;
|
||||
return String.format(rb.getString("key.bit.disabled"), kLen);
|
||||
}
|
||||
}
|
||||
|
||||
private void checkWeakSign(String alg, Set<CryptoPrimitive> primitiveSet, boolean tsa) {
|
||||
if (DISABLED_CHECK.permits(primitiveSet, alg, null)) {
|
||||
if (!LEGACY_CHECK.permits(primitiveSet, alg, null)) {
|
||||
if (primitiveSet == SIG_PRIMITIVE_SET) {
|
||||
legacyAlg |= 2;
|
||||
} else {
|
||||
if (tsa) {
|
||||
legacyAlg |= 4;
|
||||
} else {
|
||||
legacyAlg |= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (primitiveSet == SIG_PRIMITIVE_SET) {
|
||||
disabledAlg |= 2;
|
||||
} else {
|
||||
if (tsa) {
|
||||
disabledAlg |= 4;
|
||||
} else {
|
||||
disabledAlg |= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void checkWeakSign(PrivateKey key) {
|
||||
if (DISABLED_CHECK.permits(SIG_PRIMITIVE_SET, key)) {
|
||||
if (!LEGACY_CHECK.permits(SIG_PRIMITIVE_SET, key)) {
|
||||
legacyAlg |= 8;
|
||||
}
|
||||
} else {
|
||||
disabledAlg |= 8;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1496,22 +1609,22 @@ public class Main {
|
||||
void signJar(String jarName, String alias)
|
||||
throws Exception {
|
||||
|
||||
if (digestalg != null && !DISABLED_CHECK.permits(
|
||||
DIGEST_PRIMITIVE_SET, digestalg, null)) {
|
||||
weakAlg |= 1;
|
||||
if (digestalg == null) {
|
||||
digestalg = JarSigner.Builder.getDefaultDigestAlgorithm();
|
||||
}
|
||||
if (tSADigestAlg != null && !DISABLED_CHECK.permits(
|
||||
DIGEST_PRIMITIVE_SET, tSADigestAlg, null)) {
|
||||
weakAlg |= 4;
|
||||
checkWeakSign(digestalg, DIGEST_PRIMITIVE_SET, false);
|
||||
|
||||
if (tSADigestAlg == null) {
|
||||
tSADigestAlg = JarSigner.Builder.getDefaultDigestAlgorithm();
|
||||
}
|
||||
if (sigalg != null && !DISABLED_CHECK.permits(
|
||||
SIG_PRIMITIVE_SET , sigalg, null)) {
|
||||
weakAlg |= 2;
|
||||
}
|
||||
if (!DISABLED_CHECK.permits(
|
||||
SIG_PRIMITIVE_SET, privateKey)) {
|
||||
weakAlg |= 8;
|
||||
checkWeakSign(tSADigestAlg, DIGEST_PRIMITIVE_SET, true);
|
||||
|
||||
if (sigalg == null) {
|
||||
sigalg = JarSigner.Builder.getDefaultSignatureAlgorithm(privateKey);
|
||||
}
|
||||
checkWeakSign(sigalg, SIG_PRIMITIVE_SET, false);
|
||||
|
||||
checkWeakSign(privateKey);
|
||||
|
||||
boolean aliasUsed = false;
|
||||
X509Certificate tsaCert = null;
|
||||
@ -1748,7 +1861,6 @@ public class Main {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
displayMessagesAndResult(true);
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -163,8 +163,10 @@ public class Resources extends java.util.ListResourceBundle {
|
||||
{"history.nobk", "- Missing block file for signature-related file META-INF/%s.SF"},
|
||||
|
||||
{"with.weak", "%s (weak)"},
|
||||
{"with.disabled", "%s (disabled)"},
|
||||
{"key.bit", "%d-bit key"},
|
||||
{"key.bit.weak", "%d-bit key (weak)"},
|
||||
{"key.bit.disabled", "%d-bit key (disabled)"},
|
||||
{"unknown.size", "unknown size"},
|
||||
|
||||
{"jarsigner.", "jarsigner: "},
|
||||
@ -274,10 +276,18 @@ public class Resources extends java.util.ListResourceBundle {
|
||||
"The TSA certificate chain is invalid. Reason: %s"},
|
||||
{"The.signer.s.certificate.is.self.signed.",
|
||||
"The signer's certificate is self-signed."},
|
||||
{"The.1.algorithm.specified.for.the.2.option.is.considered.a.security.risk.",
|
||||
"The %1$s algorithm specified for the %2$s option is considered a security risk."},
|
||||
{"The.1.signing.key.has.a.keysize.of.2.which.is.considered.a.security.risk.",
|
||||
"The %1$s signing key has a keysize of %2$d which is considered a security risk."},
|
||||
{"The.1.algorithm.specified.for.the.2.option.is.considered.a.security.risk..This.algorithm.will.be.disabled.in.a.future.update.",
|
||||
"The %1$s algorithm specified for the %2$s option is considered a security risk. This algorithm will be disabled in a future update."},
|
||||
{"The.1.algorithm.specified.for.the.2.option.is.considered.a.security.risk.and.is.disabled.",
|
||||
"The %1$s algorithm specified for the %2$s option is considered a security risk and is disabled."},
|
||||
{"The.digest.algorithm.1.is.considered.a.security.risk..This.algorithm.will.be.disabled.in.a.future.update.",
|
||||
"The %1$s digest algorithm is considered a security risk. This algorithm will be disabled in a future update."},
|
||||
{"The.signature.algorithm.1.is.considered.a.security.risk..This.algorithm.will.be.disabled.in.a.future.update.",
|
||||
"The %1$s signature algorithm is considered a security risk. This algorithm will be disabled in a future update."},
|
||||
{"The.1.signing.key.has.a.keysize.of.2.which.is.considered.a.security.risk..This.key.size.will.be.disabled.in.a.future.update.",
|
||||
"The %1$s signing key has a keysize of %2$d which is considered a security risk. This key size will be disabled in a future update."},
|
||||
{"The.1.signing.key.has.a.keysize.of.2.which.is.considered.a.security.risk.and.is.disabled.",
|
||||
"The %1$s signing key has a keysize of %2$d which is considered a security risk and is disabled."},
|
||||
{"This.jar.contains.entries.whose.certificate.chain.is.invalid.reason.1",
|
||||
"This jar contains entries whose certificate chain is invalid. Reason: %s"},
|
||||
{"This.jar.contains.entries.whose.tsa.certificate.chain.is.invalid.reason.1",
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2009, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -41,10 +41,10 @@ import java.util.List;
|
||||
public class ConciseJarsigner {
|
||||
|
||||
static OutputAnalyzer kt(String cmd) throws Exception {
|
||||
// Choose 1024-bit RSA to make sure it runs fine and fast. In
|
||||
// Choose 2048-bit RSA to make sure it runs fine and fast. In
|
||||
// fact, every keyalg/keysize combination is OK for this test.
|
||||
return SecurityTools.keytool("-storepass changeit -keypass changeit "
|
||||
+ "-keystore ks -keyalg rsa -keysize 1024 " + cmd);
|
||||
+ "-keystore ks -keyalg rsa -keysize 2048 " + cmd);
|
||||
}
|
||||
|
||||
static void gencert(String owner, String cmd) throws Exception {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2014, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -68,7 +68,7 @@ public class DefaultOptions {
|
||||
Files.write(Path.of("js.conf"), List.of(
|
||||
"jarsigner.all = -keystore ${user.dir}/ks -storepass:env PASS "
|
||||
+ "-debug -strict",
|
||||
"jarsigner.sign = -digestalg SHA1",
|
||||
"jarsigner.sign = -digestalg SHA-512",
|
||||
"jarsigner.verify = -verbose:summary"));
|
||||
|
||||
JarUtils.createJarFile(Path.of("a.jar"), Path.of("."),
|
||||
@ -81,7 +81,7 @@ public class DefaultOptions {
|
||||
try (JarFile jf = new JarFile("a.jar")) {
|
||||
Asserts.assertTrue(jf.getManifest().getAttributes("ks").keySet()
|
||||
.stream()
|
||||
.anyMatch(s -> s.toString().contains("SHA1-Digest")));
|
||||
.anyMatch(s -> s.toString().contains("SHA-512-Digest")));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2009, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -79,7 +79,7 @@ public class EC {
|
||||
gencert("x", "-alias ca -validity 300");
|
||||
|
||||
js("a.jar a -debug -strict").shouldHaveExitValue(0);
|
||||
js("a.jar b -debug -strict -sigalg SHA1withECDSA").shouldHaveExitValue(0);
|
||||
js("a.jar b -debug -strict -sigalg SHA256withECDSA").shouldHaveExitValue(0);
|
||||
js("a.jar c -debug -strict -sigalg SHA512withECDSA").shouldHaveExitValue(0);
|
||||
|
||||
js("-verify a.jar a -debug -strict").shouldHaveExitValue(0);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2009, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -47,9 +47,9 @@ public class NameClash {
|
||||
Files.write(Path.of("A"), List.of("A"));
|
||||
JarUtils.createJarFile(Path.of("a.jar"), Path.of("."), Path.of("A"));
|
||||
|
||||
SecurityTools.jarsigner(common + "a.jar a -digestalg SHA1")
|
||||
SecurityTools.jarsigner(common + "a.jar a -digestalg SHA-256")
|
||||
.shouldHaveExitValue(0);
|
||||
SecurityTools.jarsigner(common + "a.jar b -digestalg SHA-1")
|
||||
SecurityTools.jarsigner(common + "a.jar b -digestalg SHA-256")
|
||||
.shouldHaveExitValue(0);
|
||||
|
||||
SecurityTools.jarsigner(common + "-verify -debug -strict a.jar")
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -62,7 +62,7 @@ import sun.security.x509.X500Name;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 6543842 6543440 6939248 8009636 8024302 8163304 8169911 8180289
|
||||
* @bug 6543842 6543440 6939248 8009636 8024302 8163304 8169911 8180289 8172404
|
||||
* @summary checking response of timestamp
|
||||
* @modules java.base/sun.security.pkcs
|
||||
* java.base/sun.security.timestamp
|
||||
@ -224,7 +224,8 @@ public class TimestampCheck {
|
||||
|
||||
// Always use the same algorithm at timestamp signing
|
||||
// so it is different from the hash algorithm.
|
||||
Signature sig = Signature.getInstance("SHA1withRSA");
|
||||
String sigAlg = "SHA256withRSA";
|
||||
Signature sig = Signature.getInstance(sigAlg);
|
||||
sig.initSign((PrivateKey)(ks.getKey(
|
||||
alias, "changeit".toCharArray())));
|
||||
sig.update(tstInfo.toByteArray());
|
||||
@ -241,7 +242,9 @@ public class TimestampCheck {
|
||||
SignerInfo signerInfo = new SignerInfo(
|
||||
new X500Name(signer.getIssuerX500Principal().getName()),
|
||||
signer.getSerialNumber(),
|
||||
AlgorithmId.get("SHA-1"), AlgorithmId.get("RSA"), sig.sign());
|
||||
AlgorithmId.get(AlgorithmId.getDigAlgFromSigAlg(sigAlg)),
|
||||
AlgorithmId.get(AlgorithmId.getEncAlgFromSigAlg(sigAlg)),
|
||||
sig.sign());
|
||||
|
||||
SignerInfo[] signerInfos = {signerInfo};
|
||||
PKCS7 p7 = new PKCS7(algorithms, contentInfo,
|
||||
@ -417,47 +420,108 @@ public class TimestampCheck {
|
||||
.shouldContain("TSAPolicyID changed in timestamp token")
|
||||
.shouldHaveExitValue(1);
|
||||
|
||||
sign("sha1alg", "-tsadigestalg", "SHA")
|
||||
sign("sha384alg", "-tsadigestalg", "SHA-384")
|
||||
.shouldHaveExitValue(0);
|
||||
checkTimestamp("sha1alg.jar", defaultPolicyId, "SHA-1");
|
||||
checkTimestamp("sha384alg.jar", defaultPolicyId, "SHA-384");
|
||||
|
||||
sign("tsweak", "-digestalg", "MD5",
|
||||
// Legacy algorithms
|
||||
signVerbose(null, "unsigned.jar", "sha1alg.jar", "signer",
|
||||
"-strict", "-digestalg", "SHA-1")
|
||||
.shouldHaveExitValue(0)
|
||||
.shouldContain("jar signed, with signer errors")
|
||||
.shouldMatch("SHA-1.*-digestalg.*will be disabled");
|
||||
verify("sha1alg.jar", "-strict")
|
||||
.shouldHaveExitValue(0)
|
||||
.shouldContain("jar verified, with signer errors")
|
||||
.shouldContain("SHA-1 digest algorithm is considered a security risk")
|
||||
.shouldContain("This algorithm will be disabled in a future update")
|
||||
.shouldNotContain("is disabled");
|
||||
|
||||
sign("sha1tsaalg", "-tsadigestalg", "SHA-1", "-strict")
|
||||
.shouldHaveExitValue(0)
|
||||
.shouldContain("jar signed, with signer errors")
|
||||
.shouldMatch("SHA-1.*-tsadigestalg.*will be disabled")
|
||||
.shouldNotContain("is disabled");
|
||||
verify("sha1tsaalg.jar", "-strict")
|
||||
.shouldHaveExitValue(0)
|
||||
.shouldContain("jar verified, with signer errors")
|
||||
.shouldContain("SHA-1 digest algorithm is considered a security risk")
|
||||
.shouldNotContain("is disabled");
|
||||
|
||||
// Disabled algorithms
|
||||
sign("tsdisabled", "-digestalg", "MD5",
|
||||
"-sigalg", "MD5withRSA", "-tsadigestalg", "MD5")
|
||||
.shouldHaveExitValue(68)
|
||||
.shouldContain("The timestamp is invalid. Without a valid timestamp")
|
||||
.shouldMatch("MD5.*-digestalg.*risk")
|
||||
.shouldMatch("MD5.*-tsadigestalg.*risk")
|
||||
.shouldMatch("MD5withRSA.*-sigalg.*risk");
|
||||
checkWeak("tsweak.jar");
|
||||
.shouldMatch("MD5.*-digestalg.*is disabled")
|
||||
.shouldMatch("MD5.*-tsadigestalg.*is disabled")
|
||||
.shouldMatch("MD5withRSA.*-sigalg.*is disabled");
|
||||
checkDisabled("tsdisabled.jar");
|
||||
|
||||
signVerbose("tsweak", "unsigned.jar", "tsweak2.jar", "signer")
|
||||
signVerbose("tsdisabled", "unsigned.jar", "tsdisabled2.jar", "signer")
|
||||
.shouldHaveExitValue(64)
|
||||
.shouldContain("The timestamp is invalid. Without a valid timestamp")
|
||||
.shouldContain("TSA certificate chain is invalid");
|
||||
|
||||
// Weak timestamp is an error and jar treated unsigned
|
||||
verify("tsweak2.jar", "-verbose")
|
||||
// Disabled timestamp is an error and jar treated unsigned
|
||||
verify("tsdisabled2.jar", "-verbose")
|
||||
.shouldHaveExitValue(16)
|
||||
.shouldContain("treated as unsigned")
|
||||
.shouldMatch("Timestamp.*512.*weak");
|
||||
.shouldMatch("Timestamp.*512.*(disabled)");
|
||||
|
||||
// Algorithm used in signing is weak
|
||||
signVerbose("normal", "unsigned.jar", "halfWeak.jar", "signer",
|
||||
// Algorithm used in signing is disabled
|
||||
signVerbose("normal", "unsigned.jar", "halfDisabled.jar", "signer",
|
||||
"-digestalg", "MD5")
|
||||
.shouldContain("-digestalg option is considered a security risk")
|
||||
.shouldContain("-digestalg option is considered a security risk and is disabled")
|
||||
.shouldHaveExitValue(4);
|
||||
checkHalfWeak("halfWeak.jar");
|
||||
checkHalfDisabled("halfDisabled.jar");
|
||||
|
||||
// sign with DSA key
|
||||
signVerbose("normal", "unsigned.jar", "sign1.jar", "dsakey")
|
||||
.shouldHaveExitValue(0);
|
||||
|
||||
// sign with RSAkeysize < 1024
|
||||
signVerbose("normal", "sign1.jar", "sign2.jar", "weakkeysize")
|
||||
signVerbose("normal", "sign1.jar", "sign2.jar", "disabledkeysize")
|
||||
.shouldContain("Algorithm constraints check failed on keysize")
|
||||
.shouldHaveExitValue(4);
|
||||
checkMultiple("sign2.jar");
|
||||
|
||||
// Legacy algorithms
|
||||
sign("tsweak", "-digestalg", "SHA1",
|
||||
"-sigalg", "SHA1withRSA", "-tsadigestalg", "SHA1")
|
||||
.shouldHaveExitValue(0)
|
||||
.shouldMatch("SHA1.*-digestalg.*will be disabled")
|
||||
.shouldMatch("SHA1.*-tsadigestalg.*will be disabled")
|
||||
.shouldMatch("SHA1withRSA.*-sigalg.*will be disabled");
|
||||
checkWeak("tsweak.jar");
|
||||
|
||||
signVerbose("tsweak", "unsigned.jar", "tsweak2.jar", "signer")
|
||||
.shouldHaveExitValue(0);
|
||||
|
||||
verify("tsweak2.jar", "-verbose")
|
||||
.shouldHaveExitValue(0)
|
||||
.shouldContain("jar verified")
|
||||
.shouldMatch("Timestamp.*1024.*(weak)");
|
||||
|
||||
// Algorithm used in signing is weak
|
||||
signVerbose("normal", "unsigned.jar", "halfWeak.jar", "signer",
|
||||
"-digestalg", "SHA1")
|
||||
.shouldContain("-digestalg option is considered a security risk.")
|
||||
.shouldContain("This algorithm will be disabled in a future update.")
|
||||
.shouldHaveExitValue(0);
|
||||
checkHalfWeak("halfWeak.jar");
|
||||
|
||||
// sign with DSA key
|
||||
signVerbose("normal", "unsigned.jar", "sign1.jar", "dsakey")
|
||||
.shouldHaveExitValue(0);
|
||||
|
||||
// sign with RSAkeysize < 2048
|
||||
signVerbose("normal", "sign1.jar", "sign2.jar", "weakkeysize")
|
||||
.shouldNotContain("Algorithm constraints check failed on keysize")
|
||||
.shouldHaveExitValue(0);
|
||||
checkMultipleWeak("sign2.jar");
|
||||
|
||||
|
||||
// 8191438: jarsigner should print when a timestamp will expire
|
||||
checkExpiration();
|
||||
|
||||
@ -691,7 +755,7 @@ public class TimestampCheck {
|
||||
.shouldContain("re-run jarsigner with debug enabled");
|
||||
}
|
||||
|
||||
static void checkWeak(String file) throws Exception {
|
||||
static void checkDisabled(String file) throws Exception {
|
||||
verify(file)
|
||||
.shouldHaveExitValue(16)
|
||||
.shouldContain("treated as unsigned")
|
||||
@ -701,29 +765,29 @@ public class TimestampCheck {
|
||||
.shouldHaveExitValue(16)
|
||||
.shouldContain("treated as unsigned")
|
||||
.shouldMatch("weak algorithm that is now disabled by")
|
||||
.shouldMatch("Digest algorithm: .*weak")
|
||||
.shouldMatch("Signature algorithm: .*weak")
|
||||
.shouldMatch("Timestamp digest algorithm: .*weak")
|
||||
.shouldNotMatch("Timestamp signature algorithm: .*weak.*weak")
|
||||
.shouldMatch("Timestamp signature algorithm: .*key.*weak");
|
||||
.shouldMatch("Digest algorithm: .*(disabled)")
|
||||
.shouldMatch("Signature algorithm: .*(disabled)")
|
||||
.shouldMatch("Timestamp digest algorithm: .*(disabled)")
|
||||
.shouldNotMatch("Timestamp signature algorithm: .*(weak).*(weak)")
|
||||
.shouldMatch("Timestamp signature algorithm: .*key.*(disabled)");
|
||||
verify(file, "-J-Djava.security.debug=jar")
|
||||
.shouldHaveExitValue(16)
|
||||
.shouldMatch("SignatureException:.*disabled");
|
||||
|
||||
// For 8171319: keytool should print out warnings when reading or
|
||||
// generating cert/cert req using weak algorithms.
|
||||
// generating cert/cert req using disabled algorithms.
|
||||
// Must call keytool the command, otherwise doPrintCert() might not
|
||||
// be able to reset "jdk.certpath.disabledAlgorithms".
|
||||
String sout = SecurityTools.keytool("-printcert -jarfile " + file)
|
||||
.stderrShouldContain("The TSA certificate uses a 512-bit RSA key" +
|
||||
" which is considered a security risk.")
|
||||
" which is considered a security risk and is disabled.")
|
||||
.getStdout();
|
||||
if (sout.indexOf("weak", sout.indexOf("Timestamp:")) < 0) {
|
||||
throw new RuntimeException("timestamp not weak: " + sout);
|
||||
if (sout.indexOf("disabled", sout.indexOf("Timestamp:")) < 0) {
|
||||
throw new RuntimeException("timestamp not disabled: " + sout);
|
||||
}
|
||||
}
|
||||
|
||||
static void checkHalfWeak(String file) throws Exception {
|
||||
static void checkHalfDisabled(String file) throws Exception {
|
||||
verify(file)
|
||||
.shouldHaveExitValue(16)
|
||||
.shouldContain("treated as unsigned")
|
||||
@ -733,11 +797,14 @@ public class TimestampCheck {
|
||||
.shouldHaveExitValue(16)
|
||||
.shouldContain("treated as unsigned")
|
||||
.shouldMatch("weak algorithm that is now disabled by")
|
||||
.shouldMatch("Digest algorithm: .*weak")
|
||||
.shouldNotMatch("Signature algorithm: .*weak")
|
||||
.shouldNotMatch("Timestamp digest algorithm: .*weak")
|
||||
.shouldNotMatch("Timestamp signature algorithm: .*weak.*weak")
|
||||
.shouldNotMatch("Timestamp signature algorithm: .*key.*weak");
|
||||
.shouldMatch("Digest algorithm: .*(disabled)")
|
||||
.shouldNotMatch("Signature algorithm: .*(weak)")
|
||||
.shouldNotMatch("Signature algorithm: .*(disabled)")
|
||||
.shouldNotMatch("Timestamp digest algorithm: .*(disabled)")
|
||||
.shouldNotMatch("Timestamp signature algorithm: .*(weak).*(weak)")
|
||||
.shouldNotMatch("Timestamp signature algorithm: .*(disabled).*(disabled)")
|
||||
.shouldNotMatch("Timestamp signature algorithm: .*key.*(weak)")
|
||||
.shouldNotMatch("Timestamp signature algorithm: .*key.*(disabled)");
|
||||
}
|
||||
|
||||
static void checkMultiple(String file) throws Exception {
|
||||
@ -748,11 +815,70 @@ public class TimestampCheck {
|
||||
.shouldHaveExitValue(0)
|
||||
.shouldContain("jar verified")
|
||||
.shouldMatch("X.509.*CN=dsakey")
|
||||
.shouldNotMatch("X.509.*CN=weakkeysize")
|
||||
.shouldNotMatch("X.509.*CN=disabledkeysize")
|
||||
.shouldMatch("Signed by .*CN=dsakey")
|
||||
.shouldMatch("Signed by .*CN=disabledkeysize")
|
||||
.shouldMatch("Signature algorithm: .*key.*(disabled)");
|
||||
}
|
||||
|
||||
static void checkWeak(String file) throws Exception {
|
||||
verify(file)
|
||||
.shouldHaveExitValue(0)
|
||||
.shouldNotContain("treated as unsigned");
|
||||
verify(file, "-verbose")
|
||||
.shouldHaveExitValue(0)
|
||||
.shouldNotContain("treated as unsigned")
|
||||
.shouldMatch("Digest algorithm: .*(weak)")
|
||||
.shouldMatch("Signature algorithm: .*(weak)")
|
||||
.shouldMatch("Timestamp digest algorithm: .*(weak)")
|
||||
.shouldNotMatch("Timestamp signature algorithm: .*(weak).*(weak)")
|
||||
.shouldMatch("Timestamp signature algorithm: .*key.*(weak)");
|
||||
verify(file, "-J-Djava.security.debug=jar")
|
||||
.shouldHaveExitValue(0)
|
||||
.shouldNotMatch("SignatureException:.*disabled");
|
||||
|
||||
// keytool should print out warnings when reading or
|
||||
// generating cert/cert req using legacy algorithms.
|
||||
String sout = SecurityTools.keytool("-printcert -jarfile " + file)
|
||||
.stderrShouldContain("The TSA certificate uses a 1024-bit RSA key" +
|
||||
" which is considered a security risk." +
|
||||
" This key size will be disabled in a future update.")
|
||||
.getStdout();
|
||||
if (sout.indexOf("weak", sout.indexOf("Timestamp:")) < 0) {
|
||||
throw new RuntimeException("timestamp not weak: " + sout);
|
||||
}
|
||||
}
|
||||
|
||||
static void checkHalfWeak(String file) throws Exception {
|
||||
verify(file)
|
||||
.shouldHaveExitValue(0)
|
||||
.shouldNotContain("treated as unsigned");
|
||||
verify(file, "-verbose")
|
||||
.shouldHaveExitValue(0)
|
||||
.shouldNotContain("treated as unsigned")
|
||||
.shouldMatch("Digest algorithm: .*(weak)")
|
||||
.shouldNotMatch("Signature algorithm: .*(weak)")
|
||||
.shouldNotMatch("Signature algorithm: .*(disabled)")
|
||||
.shouldNotMatch("Timestamp digest algorithm: .*(weak)")
|
||||
.shouldNotMatch("Timestamp signature algorithm: .*(weak).*(weak)")
|
||||
.shouldNotMatch("Timestamp signature algorithm: .*(disabled).*(disabled)")
|
||||
.shouldNotMatch("Timestamp signature algorithm: .*key.*(weak)")
|
||||
.shouldNotMatch("Timestamp signature algorithm: .*key.*(disabled)");
|
||||
}
|
||||
|
||||
static void checkMultipleWeak(String file) throws Exception {
|
||||
verify(file)
|
||||
.shouldHaveExitValue(0)
|
||||
.shouldContain("jar verified");
|
||||
verify(file, "-verbose", "-certs")
|
||||
.shouldHaveExitValue(0)
|
||||
.shouldContain("jar verified")
|
||||
.shouldMatch("X.509.*CN=dsakey")
|
||||
.shouldMatch("X.509.*CN=weakkeysize")
|
||||
.shouldMatch("Signed by .*CN=dsakey")
|
||||
.shouldMatch("Signed by .*CN=weakkeysize")
|
||||
.shouldMatch("Signature algorithm: .*key.*weak");
|
||||
}
|
||||
.shouldMatch("Signature algorithm: .*key.*(weak)");
|
||||
}
|
||||
|
||||
static void checkTimestamp(String file, String policyId, String digestAlg)
|
||||
throws Exception {
|
||||
@ -822,11 +948,13 @@ public class TimestampCheck {
|
||||
keytool("-alias signer -genkeypair -ext bc -dname CN=signer");
|
||||
keytool("-alias oldsigner -genkeypair -dname CN=oldsigner");
|
||||
keytool("-alias dsakey -genkeypair -keyalg DSA -dname CN=dsakey");
|
||||
keytool("-alias weakkeysize -genkeypair -keysize 512 -dname CN=weakkeysize");
|
||||
keytool("-alias weakkeysize -genkeypair -keysize 1024 -dname CN=weakkeysize");
|
||||
keytool("-alias disabledkeysize -genkeypair -keysize 512 -dname CN=disabledkeysize");
|
||||
keytool("-alias badku -genkeypair -dname CN=badku");
|
||||
keytool("-alias ts -genkeypair -dname CN=ts");
|
||||
keytool("-alias tsold -genkeypair -dname CN=tsold");
|
||||
keytool("-alias tsweak -genkeypair -keysize 512 -dname CN=tsweak");
|
||||
keytool("-alias tsweak -genkeypair -keysize 1024 -dname CN=tsweak");
|
||||
keytool("-alias tsdisabled -genkeypair -keysize 512 -dname CN=tsdisabled");
|
||||
keytool("-alias tsbad1 -genkeypair -dname CN=tsbad1");
|
||||
keytool("-alias tsbad2 -genkeypair -dname CN=tsbad2");
|
||||
keytool("-alias tsbad3 -genkeypair -dname CN=tsbad3");
|
||||
@ -850,6 +978,7 @@ public class TimestampCheck {
|
||||
gencert("oldsigner", "-startdate -30d -validity 20");
|
||||
gencert("dsakey");
|
||||
gencert("weakkeysize");
|
||||
gencert("disabledkeysize");
|
||||
gencert("badku", "-ext ku:critical=keyAgreement");
|
||||
gencert("ts", "-ext eku:critical=ts -validity 500");
|
||||
|
||||
@ -882,6 +1011,7 @@ public class TimestampCheck {
|
||||
gencert("tsold", "-ext eku:critical=ts -startdate -40d -validity 500");
|
||||
|
||||
gencert("tsweak", "-ext eku:critical=ts");
|
||||
gencert("tsdisabled", "-ext eku:critical=ts");
|
||||
gencert("tsbad1");
|
||||
gencert("tsbad2", "-ext eku=ts");
|
||||
gencert("tsbad3", "-ext eku:critical=cs");
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -139,7 +139,7 @@ public class TsacertOptionTest extends Test {
|
||||
|
||||
// sign jar file
|
||||
// specify -tsadigestalg option because
|
||||
// TSA server uses SHA-1 digest algorithm
|
||||
// TSA server uses SHA-512 digest algorithm
|
||||
OutputAnalyzer analyzer = jarsigner(
|
||||
"-J-Dhttp.proxyHost=",
|
||||
"-J-Dhttp.proxyPort=",
|
||||
@ -150,7 +150,7 @@ public class TsacertOptionTest extends Test {
|
||||
"-keypass", PASSWORD,
|
||||
"-signedjar", SIGNED_JARFILE,
|
||||
"-tsacert", TSA_KEY_ALIAS,
|
||||
"-tsadigestalg", "SHA-1",
|
||||
"-tsadigestalg", "SHA-512",
|
||||
UNSIGNED_JARFILE,
|
||||
SIGNING_KEY_ALIAS);
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -74,12 +74,12 @@ public class Warning {
|
||||
.shouldNotContain("is self-signed");
|
||||
|
||||
run("jarsigner", "a.jar b -digestalg MD5")
|
||||
.shouldContain("-digestalg option is considered a security risk.");
|
||||
.shouldContain("-digestalg option is considered a security risk and is disabled.");
|
||||
run("jarsigner", "a.jar b -digestalg MD5 -strict")
|
||||
.shouldHaveExitValue(4)
|
||||
.shouldContain("-digestalg option is considered a security risk.");
|
||||
.shouldContain("-digestalg option is considered a security risk and is disabled.");
|
||||
run("jarsigner", "a.jar b -sigalg MD5withRSA")
|
||||
.shouldContain("-sigalg option is considered a security risk");
|
||||
.shouldContain("-sigalg option is considered a security risk and is disabled.");
|
||||
|
||||
issueCert("b", "-sigalg MD5withRSA");
|
||||
run("jarsigner", "a.jar b")
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -23,7 +23,7 @@
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8171319 8177569 8182879
|
||||
* @bug 8171319 8177569 8182879 8172404
|
||||
* @summary keytool should print out warnings when reading or generating
|
||||
* cert/cert req using weak algorithms
|
||||
* @library /test/lib
|
||||
@ -70,62 +70,63 @@ public class WeakAlg {
|
||||
|
||||
rm("ks");
|
||||
|
||||
// Tests for "disabled" algorithms
|
||||
// -genkeypair, and -printcert, -list -alias, -exportcert
|
||||
// (w/ different formats)
|
||||
checkGenKeyPair("a", "-keyalg RSA -sigalg MD5withRSA", "MD5withRSA");
|
||||
checkGenKeyPair("b", "-keyalg RSA -keysize 512", "512-bit RSA key");
|
||||
checkGenKeyPair("c", "-keyalg RSA", null);
|
||||
checkDisabledGenKeyPair("a", "-keyalg RSA -sigalg MD5withRSA", "MD5withRSA");
|
||||
checkDisabledGenKeyPair("b", "-keyalg RSA -keysize 512", "512-bit RSA key");
|
||||
checkDisabledGenKeyPair("c", "-keyalg RSA", null);
|
||||
|
||||
kt("-list")
|
||||
.shouldContain("Warning:")
|
||||
.shouldMatch("<a>.*MD5withRSA.*risk")
|
||||
.shouldMatch("<b>.*512-bit RSA key.*risk");
|
||||
.shouldMatch("<a>.*MD5withRSA.*is disabled")
|
||||
.shouldMatch("<b>.*512-bit RSA key.*is disabled");
|
||||
kt("-list -v")
|
||||
.shouldContain("Warning:")
|
||||
.shouldMatch("<a>.*MD5withRSA.*risk")
|
||||
.shouldContain("MD5withRSA (weak)")
|
||||
.shouldMatch("<b>.*512-bit RSA key.*risk")
|
||||
.shouldContain("512-bit RSA key (weak)");
|
||||
.shouldMatch("<a>.*MD5withRSA.*is disabled")
|
||||
.shouldContain("MD5withRSA (disabled)")
|
||||
.shouldMatch("<b>.*512-bit RSA key.*is disabled")
|
||||
.shouldContain("512-bit RSA key (disabled)");
|
||||
|
||||
// Multiple warnings for multiple cert in -printcert
|
||||
// or -list or -exportcert
|
||||
|
||||
// -certreq, -printcertreq, -gencert
|
||||
checkCertReq("a", "", null);
|
||||
checkDisabledCertReq("a", "", null);
|
||||
gencert("c-a", "")
|
||||
.shouldNotContain("Warning"); // new sigalg is not weak
|
||||
gencert("c-a", "-sigalg MD2withRSA")
|
||||
.shouldContain("Warning:")
|
||||
.shouldMatch("The generated certificate.*MD2withRSA.*risk");
|
||||
.shouldMatch("The generated certificate.*MD2withRSA.*is disabled");
|
||||
|
||||
checkCertReq("a", "-sigalg MD5withRSA", "MD5withRSA");
|
||||
checkDisabledCertReq("a", "-sigalg MD5withRSA", "MD5withRSA");
|
||||
gencert("c-a", "")
|
||||
.shouldContain("Warning:")
|
||||
.shouldMatch("The certificate request.*MD5withRSA.*risk");
|
||||
.shouldMatch("The certificate request.*MD5withRSA.*is disabled");
|
||||
gencert("c-a", "-sigalg MD2withRSA")
|
||||
.shouldContain("Warning:")
|
||||
.shouldMatch("The certificate request.*MD5withRSA.*risk")
|
||||
.shouldMatch("The generated certificate.*MD2withRSA.*risk");
|
||||
.shouldMatch("The certificate request.*MD5withRSA.*is disabled")
|
||||
.shouldMatch("The generated certificate.*MD2withRSA.*is disabled");
|
||||
|
||||
checkCertReq("b", "", "512-bit RSA key");
|
||||
checkDisabledCertReq("b", "", "512-bit RSA key");
|
||||
gencert("c-b", "")
|
||||
.shouldContain("Warning:")
|
||||
.shouldMatch("The certificate request.*512-bit RSA key.*risk")
|
||||
.shouldMatch("The generated certificate.*512-bit RSA key.*risk");
|
||||
.shouldMatch("The certificate request.*512-bit RSA key.*is disabled")
|
||||
.shouldMatch("The generated certificate.*512-bit RSA key.*is disabled");
|
||||
|
||||
checkCertReq("c", "", null);
|
||||
checkDisabledCertReq("c", "", null);
|
||||
gencert("a-c", "")
|
||||
.shouldContain("Warning:")
|
||||
.shouldMatch("The issuer.*MD5withRSA.*risk");
|
||||
.shouldMatch("The issuer.*MD5withRSA.*is disabled");
|
||||
|
||||
// but the new cert is not weak
|
||||
kt("-printcert -file a-c.cert")
|
||||
.shouldNotContain("Warning")
|
||||
.shouldNotContain("weak");
|
||||
.shouldNotContain("(disabled)");
|
||||
|
||||
gencert("b-c", "")
|
||||
.shouldContain("Warning:")
|
||||
.shouldMatch("The issuer.*512-bit RSA key.*risk");
|
||||
.shouldMatch("The issuer.*512-bit RSA key.*is disabled");
|
||||
|
||||
// -importcert
|
||||
checkImport();
|
||||
@ -135,10 +136,10 @@ public class WeakAlg {
|
||||
|
||||
// -gencrl, -printcrl
|
||||
|
||||
checkGenCRL("a", "", null);
|
||||
checkGenCRL("a", "-sigalg MD5withRSA", "MD5withRSA");
|
||||
checkGenCRL("b", "", "512-bit RSA key");
|
||||
checkGenCRL("c", "", null);
|
||||
checkDisabledGenCRL("a", "", null);
|
||||
checkDisabledGenCRL("a", "-sigalg MD5withRSA", "MD5withRSA");
|
||||
checkDisabledGenCRL("b", "", "512-bit RSA key");
|
||||
checkDisabledGenCRL("c", "", null);
|
||||
|
||||
kt("-delete -alias b");
|
||||
kt("-printcrl -file b.crl")
|
||||
@ -147,13 +148,85 @@ public class WeakAlg {
|
||||
jksTypeCheck();
|
||||
|
||||
checkInplaceImportKeyStore();
|
||||
|
||||
rm("ks");
|
||||
|
||||
// Tests for "legacy" algorithms
|
||||
// -genkeypair, and -printcert, -list -alias, -exportcert
|
||||
// (w/ different formats)
|
||||
checkWeakGenKeyPair("x", "-keyalg RSA -sigalg SHA1withRSA", "SHA1withRSA");
|
||||
checkWeakGenKeyPair("y", "-keyalg RSA -keysize 1024", "1024-bit RSA key");
|
||||
checkWeakGenKeyPair("z", "-keyalg RSA", null);
|
||||
|
||||
kt("-list")
|
||||
.shouldContain("Warning:")
|
||||
.shouldMatch("<x>.*SHA1withRSA.*will be disabled")
|
||||
.shouldMatch("<y>.*1024-bit RSA key.*will be disabled");
|
||||
kt("-list -v")
|
||||
.shouldContain("Warning:")
|
||||
.shouldMatch("<x>.*SHA1withRSA.*will be disabled")
|
||||
.shouldContain("SHA1withRSA (weak)")
|
||||
.shouldMatch("<y>.*1024-bit RSA key.*will be disabled")
|
||||
.shouldContain("1024-bit RSA key (weak)");
|
||||
|
||||
// Multiple warnings for multiple cert in -printcert
|
||||
// or -list or -exportcert
|
||||
|
||||
// -certreq, -printcertreq, -gencert
|
||||
checkWeakCertReq("x", "", null);
|
||||
gencert("z-x", "")
|
||||
.shouldNotContain("Warning"); // new sigalg is not weak
|
||||
gencert("z-x", "-sigalg SHA1withRSA")
|
||||
.shouldContain("Warning:")
|
||||
.shouldMatch("The generated certificate.*SHA1withRSA.*will be disabled");
|
||||
|
||||
checkWeakCertReq("x", "-sigalg SHA1withRSA", "SHA1withRSA");
|
||||
gencert("z-x", "")
|
||||
.shouldContain("Warning:")
|
||||
.shouldMatch("The certificate request.*SHA1withRSA.*will be disabled");
|
||||
gencert("z-x", "-sigalg SHA1withRSA")
|
||||
.shouldContain("Warning:")
|
||||
.shouldMatch("The certificate request.*SHA1withRSA.*will be disabled")
|
||||
.shouldMatch("The generated certificate.*SHA1withRSA.*will be disabled");
|
||||
|
||||
checkWeakCertReq("y", "", "1024-bit RSA key");
|
||||
gencert("z-y", "")
|
||||
.shouldContain("Warning:")
|
||||
.shouldMatch("The certificate request.*1024-bit RSA key.*will be disabled")
|
||||
.shouldMatch("The generated certificate.*1024-bit RSA key.*will be disabled");
|
||||
|
||||
checkWeakCertReq("z", "", null);
|
||||
gencert("x-z", "")
|
||||
.shouldContain("Warning:")
|
||||
.shouldMatch("The issuer.*SHA1withRSA.*will be disabled");
|
||||
|
||||
// but the new cert is not weak
|
||||
kt("-printcert -file x-z.cert")
|
||||
.shouldNotContain("Warning")
|
||||
.shouldNotContain("weak");
|
||||
|
||||
gencert("y-z", "")
|
||||
.shouldContain("Warning:")
|
||||
.shouldMatch("The issuer.*1024-bit RSA key.*will be disabled");
|
||||
|
||||
// -gencrl, -printcrl
|
||||
checkWeakGenCRL("x", "", null);
|
||||
checkWeakGenCRL("x", "-sigalg SHA1withRSA", "SHA1withRSA");
|
||||
checkWeakGenCRL("y", "", "1024-bit RSA key");
|
||||
checkWeakGenCRL("z", "", null);
|
||||
|
||||
kt("-delete -alias y");
|
||||
kt("-printcrl -file y.crl")
|
||||
.shouldContain("WARNING: not verified");
|
||||
|
||||
jksTypeCheck();
|
||||
}
|
||||
|
||||
static void jksTypeCheck() throws Exception {
|
||||
|
||||
// No warning for cacerts, all certs
|
||||
kt0("-cacerts -list -storepass changeit")
|
||||
.shouldNotContain("Warning:");
|
||||
.shouldNotContain("proprietary format");
|
||||
|
||||
rm("ks");
|
||||
rm("ks2");
|
||||
@ -228,12 +301,12 @@ public class WeakAlg {
|
||||
importkeystore("ks", "ks2", "")
|
||||
.shouldContain("3 entries successfully imported")
|
||||
.shouldContain("Warning")
|
||||
.shouldMatch("<b>.*512-bit RSA key.*risk")
|
||||
.shouldMatch("<a>.*MD5withRSA.*risk");
|
||||
.shouldMatch("<b>.*512-bit RSA key.*is disabled")
|
||||
.shouldMatch("<a>.*MD5withRSA.*is disabled");
|
||||
|
||||
importkeystore("ks", "ks3", "-srcalias a")
|
||||
.shouldContain("Warning")
|
||||
.shouldMatch("<a>.*MD5withRSA.*risk");
|
||||
.shouldMatch("<a>.*MD5withRSA.*is disabled");
|
||||
}
|
||||
|
||||
static void checkInplaceImportKeyStore() throws Exception {
|
||||
@ -313,11 +386,11 @@ public class WeakAlg {
|
||||
kt("-importcert -alias d -file a.cert", "no")
|
||||
.shouldContain("Certificate already exists in keystore")
|
||||
.shouldContain("Warning")
|
||||
.shouldMatch("The input.*MD5withRSA.*risk")
|
||||
.shouldMatch("The input.*MD5withRSA.*is disabled")
|
||||
.shouldContain("Do you still want to add it?");
|
||||
kt("-importcert -alias d -file a.cert -noprompt")
|
||||
.shouldContain("Warning")
|
||||
.shouldMatch("The input.*MD5withRSA.*risk")
|
||||
.shouldMatch("The input.*MD5withRSA.*is disabled")
|
||||
.shouldNotContain("[no]");
|
||||
|
||||
// cert is self-signed
|
||||
@ -325,12 +398,12 @@ public class WeakAlg {
|
||||
kt("-delete -alias d");
|
||||
kt("-importcert -alias d -file a.cert", "no")
|
||||
.shouldContain("Warning")
|
||||
.shouldContain("MD5withRSA (weak)")
|
||||
.shouldMatch("The input.*MD5withRSA.*risk")
|
||||
.shouldContain("MD5withRSA (disabled)")
|
||||
.shouldMatch("The input.*MD5withRSA.*is disabled")
|
||||
.shouldContain("Trust this certificate?");
|
||||
kt("-importcert -alias d -file a.cert -noprompt")
|
||||
.shouldContain("Warning")
|
||||
.shouldMatch("The input.*MD5withRSA.*risk")
|
||||
.shouldMatch("The input.*MD5withRSA.*is disabled")
|
||||
.shouldNotContain("[no]");
|
||||
|
||||
// JDK-8177569: no warning for sigalg of trusted cert
|
||||
@ -366,13 +439,13 @@ public class WeakAlg {
|
||||
|
||||
// -printcert will always show warnings
|
||||
kt("-printcert -file ca.cert")
|
||||
.shouldContain("name: " + weakSigAlgCA + " (weak)")
|
||||
.shouldContain("name: " + weakSigAlgCA + " (disabled)")
|
||||
.shouldContain("Warning")
|
||||
.shouldMatch("The certificate.*" + weakSigAlgCA + ".*risk");
|
||||
.shouldMatch("The certificate.*" + weakSigAlgCA + ".*is disabled");
|
||||
kt("-printcert -file ca.cert -trustcacerts") // -trustcacerts useless
|
||||
.shouldContain("name: " + weakSigAlgCA + " (weak)")
|
||||
.shouldContain("name: " + weakSigAlgCA + " (disabled)")
|
||||
.shouldContain("Warning")
|
||||
.shouldMatch("The certificate.*" + weakSigAlgCA + ".*risk");
|
||||
.shouldMatch("The certificate.*" + weakSigAlgCA + ".*is disabled");
|
||||
|
||||
// Importing with -trustcacerts ignore CA cert's sig alg
|
||||
kt("-delete -alias d");
|
||||
@ -387,13 +460,13 @@ public class WeakAlg {
|
||||
// but not without -trustcacerts
|
||||
kt("-delete -alias d");
|
||||
kt("-importcert -alias d -file ca.cert", "no")
|
||||
.shouldContain("name: " + weakSigAlgCA + " (weak)")
|
||||
.shouldContain("name: " + weakSigAlgCA + " (disabled)")
|
||||
.shouldContain("Warning")
|
||||
.shouldMatch("The input.*" + weakSigAlgCA + ".*risk")
|
||||
.shouldMatch("The input.*" + weakSigAlgCA + ".*is disabled")
|
||||
.shouldContain("Trust this certificate?");
|
||||
kt("-importcert -alias d -file ca.cert -noprompt")
|
||||
.shouldContain("Warning")
|
||||
.shouldMatch("The input.*" + weakSigAlgCA + ".*risk")
|
||||
.shouldMatch("The input.*" + weakSigAlgCA + ".*is disabled")
|
||||
.shouldNotContain("[no]");
|
||||
}
|
||||
|
||||
@ -403,8 +476,8 @@ public class WeakAlg {
|
||||
gencert("c-b", "");
|
||||
kt("-importcert -alias d -file c-b.cert") // weak only, no prompt
|
||||
.shouldContain("Warning")
|
||||
.shouldNotContain("512-bit RSA key (weak)")
|
||||
.shouldMatch("The input.*512-bit RSA key.*risk")
|
||||
.shouldNotContain("512-bit RSA key (disabled)")
|
||||
.shouldMatch("The input.*512-bit RSA key.*is disabled")
|
||||
.shouldNotContain("[no]");
|
||||
|
||||
kt("-delete -alias b");
|
||||
@ -413,12 +486,12 @@ public class WeakAlg {
|
||||
|
||||
kt("-importcert -alias d -file c-b.cert", "no") // weak and not trusted
|
||||
.shouldContain("Warning")
|
||||
.shouldContain("512-bit RSA key (weak)")
|
||||
.shouldMatch("The input.*512-bit RSA key.*risk")
|
||||
.shouldContain("512-bit RSA key (disabled)")
|
||||
.shouldMatch("The input.*512-bit RSA key.*is disabled")
|
||||
.shouldContain("Trust this certificate?");
|
||||
kt("-importcert -alias d -file c-b.cert -noprompt")
|
||||
.shouldContain("Warning")
|
||||
.shouldMatch("The input.*512-bit RSA key.*risk")
|
||||
.shouldMatch("The input.*512-bit RSA key.*is disabled")
|
||||
.shouldNotContain("[no]");
|
||||
|
||||
// a non self-signed strong cert
|
||||
@ -447,7 +520,7 @@ public class WeakAlg {
|
||||
gencert("a-c", "");
|
||||
kt("-importcert -alias c -file a-c.cert")
|
||||
.shouldContain("Warning")
|
||||
.shouldMatch("Issuer <a>.*MD5withRSA.*risk");
|
||||
.shouldMatch("Issuer <a>.*MD5withRSA.*is disabled");
|
||||
|
||||
// JDK-8177569: no warning for sigalg of trusted cert
|
||||
reStore();
|
||||
@ -456,7 +529,7 @@ public class WeakAlg {
|
||||
kt("-delete -alias a");
|
||||
kt("-importcert -alias a -file a.cert -noprompt");
|
||||
kt("-list -alias a -v")
|
||||
.shouldNotContain("weak")
|
||||
.shouldNotContain("disabled")
|
||||
.shouldNotContain("Warning");
|
||||
// This time a is trusted and no warning on its weak sig alg
|
||||
kt("-importcert -alias c -file a-c.cert")
|
||||
@ -471,16 +544,16 @@ public class WeakAlg {
|
||||
cat("a-a-b-c.cert", "b-c.cert", "a-b.cert", "a.cert");
|
||||
kt("-importcert -alias c -file a-a-b-c.cert") // only weak
|
||||
.shouldContain("Warning")
|
||||
.shouldMatch("Reply #2 of 3.*512-bit RSA key.*risk")
|
||||
.shouldMatch("Reply #3 of 3.*MD5withRSA.*risk")
|
||||
.shouldMatch("Reply #2 of 3.*512-bit RSA key.*is disabled")
|
||||
.shouldMatch("Reply #3 of 3.*MD5withRSA.*is disabled")
|
||||
.shouldNotContain("[no]");
|
||||
|
||||
// Without root
|
||||
cat("a-b-c.cert", "b-c.cert", "a-b.cert");
|
||||
kt("-importcert -alias c -file a-b-c.cert") // only weak
|
||||
.shouldContain("Warning")
|
||||
.shouldMatch("Reply #2 of 2.*512-bit RSA key.*risk")
|
||||
.shouldMatch("Issuer <a>.*MD5withRSA.*risk")
|
||||
.shouldMatch("Reply #2 of 2.*512-bit RSA key.*is disabled")
|
||||
.shouldMatch("Issuer <a>.*MD5withRSA.*is disabled")
|
||||
.shouldNotContain("[no]");
|
||||
|
||||
reStore();
|
||||
@ -488,7 +561,7 @@ public class WeakAlg {
|
||||
|
||||
kt("-importcert -alias a -file b-a.cert")
|
||||
.shouldContain("Warning")
|
||||
.shouldMatch("Issuer <b>.*512-bit RSA key.*risk")
|
||||
.shouldMatch("Issuer <b>.*512-bit RSA key.*is disabled")
|
||||
.shouldNotContain("[no]");
|
||||
|
||||
kt("-importcert -alias a -file c-a.cert")
|
||||
@ -496,7 +569,7 @@ public class WeakAlg {
|
||||
|
||||
kt("-importcert -alias b -file c-b.cert")
|
||||
.shouldContain("Warning")
|
||||
.shouldMatch("The input.*512-bit RSA key.*risk")
|
||||
.shouldMatch("The input.*512-bit RSA key.*is disabled")
|
||||
.shouldNotContain("[no]");
|
||||
|
||||
reStore();
|
||||
@ -506,25 +579,25 @@ public class WeakAlg {
|
||||
|
||||
kt("-printcert -file c-b-a.cert")
|
||||
.shouldContain("Warning")
|
||||
.shouldMatch("The certificate #2 of 2.*512-bit RSA key.*risk");
|
||||
.shouldMatch("The certificate #2 of 2.*512-bit RSA key.*is disabled");
|
||||
|
||||
kt("-delete -alias b");
|
||||
|
||||
kt("-importcert -alias a -file c-b-a.cert")
|
||||
.shouldContain("Warning")
|
||||
.shouldMatch("Reply #2 of 2.*512-bit RSA key.*risk")
|
||||
.shouldMatch("Reply #2 of 2.*512-bit RSA key.*is disabled")
|
||||
.shouldNotContain("[no]");
|
||||
|
||||
kt("-delete -alias c");
|
||||
kt("-importcert -alias a -file c-b-a.cert", "no")
|
||||
.shouldContain("Top-level certificate in reply:")
|
||||
.shouldContain("512-bit RSA key (weak)")
|
||||
.shouldContain("512-bit RSA key (disabled)")
|
||||
.shouldContain("Warning")
|
||||
.shouldMatch("Reply #2 of 2.*512-bit RSA key.*risk")
|
||||
.shouldMatch("Reply #2 of 2.*512-bit RSA key.*is disabled")
|
||||
.shouldContain("Install reply anyway?");
|
||||
kt("-importcert -alias a -file c-b-a.cert -noprompt")
|
||||
.shouldContain("Warning")
|
||||
.shouldMatch("Reply #2 of 2.*512-bit RSA key.*risk")
|
||||
.shouldMatch("Reply #2 of 2.*512-bit RSA key.*is disabled")
|
||||
.shouldNotContain("[no]");
|
||||
|
||||
reStore();
|
||||
@ -543,7 +616,7 @@ public class WeakAlg {
|
||||
System.out.println("> " + dest);
|
||||
}
|
||||
|
||||
static void checkGenCRL(String alias, String options, String bad) {
|
||||
static void checkDisabledGenCRL(String alias, String options, String bad) {
|
||||
|
||||
OutputAnalyzer oa = kt("-gencrl -alias " + alias
|
||||
+ " -id 1 -file " + alias + ".crl " + options);
|
||||
@ -551,23 +624,23 @@ public class WeakAlg {
|
||||
oa.shouldNotContain("Warning");
|
||||
} else {
|
||||
oa.shouldContain("Warning")
|
||||
.shouldMatch("The generated CRL.*" + bad + ".*risk");
|
||||
.shouldMatch("The generated CRL.*" + bad + ".*is disabled");
|
||||
}
|
||||
|
||||
oa = kt("-printcrl -file " + alias + ".crl");
|
||||
if (bad == null) {
|
||||
oa.shouldNotContain("Warning")
|
||||
.shouldContain("Verified by " + alias + " in keystore")
|
||||
.shouldNotContain("(weak");
|
||||
.shouldNotContain("(disabled");
|
||||
} else {
|
||||
oa.shouldContain("Warning:")
|
||||
.shouldMatch("The CRL.*" + bad + ".*risk")
|
||||
.shouldMatch("The CRL.*" + bad + ".*is disabled")
|
||||
.shouldContain("Verified by " + alias + " in keystore")
|
||||
.shouldContain(bad + " (weak)");
|
||||
.shouldContain(bad + " (disabled)");
|
||||
}
|
||||
}
|
||||
|
||||
static void checkCertReq(
|
||||
static void checkDisabledCertReq(
|
||||
String alias, String options, String bad) {
|
||||
|
||||
OutputAnalyzer oa = certreq(alias, options);
|
||||
@ -575,21 +648,21 @@ public class WeakAlg {
|
||||
oa.shouldNotContain("Warning");
|
||||
} else {
|
||||
oa.shouldContain("Warning")
|
||||
.shouldMatch("The generated certificate request.*" + bad + ".*risk");
|
||||
.shouldMatch("The generated certificate request.*" + bad + ".*is disabled");
|
||||
}
|
||||
|
||||
oa = kt("-printcertreq -file " + alias + ".req");
|
||||
if (bad == null) {
|
||||
oa.shouldNotContain("Warning")
|
||||
.shouldNotContain("(weak)");
|
||||
.shouldNotContain("(disabled)");
|
||||
} else {
|
||||
oa.shouldContain("Warning")
|
||||
.shouldMatch("The certificate request.*" + bad + ".*risk")
|
||||
.shouldContain(bad + " (weak)");
|
||||
.shouldMatch("The certificate request.*" + bad + ".*is disabled")
|
||||
.shouldContain(bad + " (disabled)");
|
||||
}
|
||||
}
|
||||
|
||||
static void checkGenKeyPair(
|
||||
static void checkDisabledGenKeyPair(
|
||||
String alias, String options, String bad) {
|
||||
|
||||
OutputAnalyzer oa = genkeypair(alias, options);
|
||||
@ -597,7 +670,7 @@ public class WeakAlg {
|
||||
oa.shouldNotContain("Warning");
|
||||
} else {
|
||||
oa.shouldContain("Warning")
|
||||
.shouldMatch("The generated certificate.*" + bad + ".*risk");
|
||||
.shouldMatch("The generated certificate.*" + bad + ".*is disabled");
|
||||
}
|
||||
|
||||
oa = kt("-exportcert -alias " + alias + " -file " + alias + ".cert");
|
||||
@ -605,7 +678,7 @@ public class WeakAlg {
|
||||
oa.shouldNotContain("Warning");
|
||||
} else {
|
||||
oa.shouldContain("Warning")
|
||||
.shouldMatch("The certificate.*" + bad + ".*risk");
|
||||
.shouldMatch("The certificate.*" + bad + ".*is disabled");
|
||||
}
|
||||
|
||||
oa = kt("-exportcert -rfc -alias " + alias + " -file " + alias + ".cert");
|
||||
@ -613,7 +686,7 @@ public class WeakAlg {
|
||||
oa.shouldNotContain("Warning");
|
||||
} else {
|
||||
oa.shouldContain("Warning")
|
||||
.shouldMatch("The certificate.*" + bad + ".*risk");
|
||||
.shouldMatch("The certificate.*" + bad + ".*is disabled");
|
||||
}
|
||||
|
||||
oa = kt("-printcert -rfc -file " + alias + ".cert");
|
||||
@ -621,7 +694,7 @@ public class WeakAlg {
|
||||
oa.shouldNotContain("Warning");
|
||||
} else {
|
||||
oa.shouldContain("Warning")
|
||||
.shouldMatch("The certificate.*" + bad + ".*risk");
|
||||
.shouldMatch("The certificate.*" + bad + ".*is disabled");
|
||||
}
|
||||
|
||||
oa = kt("-list -alias " + alias);
|
||||
@ -629,7 +702,71 @@ public class WeakAlg {
|
||||
oa.shouldNotContain("Warning");
|
||||
} else {
|
||||
oa.shouldContain("Warning")
|
||||
.shouldMatch("The certificate.*" + bad + ".*risk");
|
||||
.shouldMatch("The certificate.*" + bad + ".*is disabled");
|
||||
}
|
||||
|
||||
// With cert content
|
||||
|
||||
oa = kt("-printcert -file " + alias + ".cert");
|
||||
if (bad == null) {
|
||||
oa.shouldNotContain("Warning");
|
||||
} else {
|
||||
oa.shouldContain("Warning")
|
||||
.shouldContain(bad + " (disabled)")
|
||||
.shouldMatch("The certificate.*" + bad + ".*is disabled");
|
||||
}
|
||||
|
||||
oa = kt("-list -v -alias " + alias);
|
||||
if (bad == null) {
|
||||
oa.shouldNotContain("Warning");
|
||||
} else {
|
||||
oa.shouldContain("Warning")
|
||||
.shouldContain(bad + " (disabled)")
|
||||
.shouldMatch("The certificate.*" + bad + ".*is disabled");
|
||||
}
|
||||
}
|
||||
|
||||
static void checkWeakGenKeyPair(
|
||||
String alias, String options, String bad) {
|
||||
|
||||
OutputAnalyzer oa = genkeypair(alias, options);
|
||||
if (bad == null) {
|
||||
oa.shouldNotContain("Warning");
|
||||
} else {
|
||||
oa.shouldContain("Warning")
|
||||
.shouldMatch("The generated certificate.*" + bad + ".*will be disabled");
|
||||
}
|
||||
|
||||
oa = kt("-exportcert -alias " + alias + " -file " + alias + ".cert");
|
||||
if (bad == null) {
|
||||
oa.shouldNotContain("Warning");
|
||||
} else {
|
||||
oa.shouldContain("Warning")
|
||||
.shouldMatch("The certificate.*" + bad + ".*will be disabled");
|
||||
}
|
||||
|
||||
oa = kt("-exportcert -rfc -alias " + alias + " -file " + alias + ".cert");
|
||||
if (bad == null) {
|
||||
oa.shouldNotContain("Warning");
|
||||
} else {
|
||||
oa.shouldContain("Warning")
|
||||
.shouldMatch("The certificate.*" + bad + ".*will be disabled");
|
||||
}
|
||||
|
||||
oa = kt("-printcert -rfc -file " + alias + ".cert");
|
||||
if (bad == null) {
|
||||
oa.shouldNotContain("Warning");
|
||||
} else {
|
||||
oa.shouldContain("Warning")
|
||||
.shouldMatch("The certificate.*" + bad + ".*will be disabled");
|
||||
}
|
||||
|
||||
oa = kt("-list -alias " + alias);
|
||||
if (bad == null) {
|
||||
oa.shouldNotContain("Warning");
|
||||
} else {
|
||||
oa.shouldContain("Warning")
|
||||
.shouldMatch("The certificate.*" + bad + ".*will be disabled");
|
||||
}
|
||||
|
||||
// With cert content
|
||||
@ -640,7 +777,7 @@ public class WeakAlg {
|
||||
} else {
|
||||
oa.shouldContain("Warning")
|
||||
.shouldContain(bad + " (weak)")
|
||||
.shouldMatch("The certificate.*" + bad + ".*risk");
|
||||
.shouldMatch("The certificate.*" + bad + ".*will be disabled");
|
||||
}
|
||||
|
||||
oa = kt("-list -v -alias " + alias);
|
||||
@ -649,7 +786,54 @@ public class WeakAlg {
|
||||
} else {
|
||||
oa.shouldContain("Warning")
|
||||
.shouldContain(bad + " (weak)")
|
||||
.shouldMatch("The certificate.*" + bad + ".*risk");
|
||||
.shouldMatch("The certificate.*" + bad + ".*will be disabled");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void checkWeakGenCRL(String alias, String options, String bad) {
|
||||
|
||||
OutputAnalyzer oa = kt("-gencrl -alias " + alias
|
||||
+ " -id 1 -file " + alias + ".crl " + options);
|
||||
if (bad == null) {
|
||||
oa.shouldNotContain("Warning");
|
||||
} else {
|
||||
oa.shouldContain("Warning")
|
||||
.shouldMatch("The generated CRL.*" + bad + ".*will be disabled");
|
||||
}
|
||||
|
||||
oa = kt("-printcrl -file " + alias + ".crl");
|
||||
if (bad == null) {
|
||||
oa.shouldNotContain("Warning")
|
||||
.shouldContain("Verified by " + alias + " in keystore")
|
||||
.shouldNotContain("(weak");
|
||||
} else {
|
||||
oa.shouldContain("Warning:")
|
||||
.shouldMatch("The CRL.*" + bad + ".*will be disabled")
|
||||
.shouldContain("Verified by " + alias + " in keystore")
|
||||
.shouldContain(bad + " (weak)");
|
||||
}
|
||||
}
|
||||
|
||||
static void checkWeakCertReq(
|
||||
String alias, String options, String bad) {
|
||||
|
||||
OutputAnalyzer oa = certreq(alias, options);
|
||||
if (bad == null) {
|
||||
oa.shouldNotContain("Warning");
|
||||
} else {
|
||||
oa.shouldContain("Warning")
|
||||
.shouldMatch("The generated certificate request.*" + bad + ".*will be disabled");
|
||||
}
|
||||
|
||||
oa = kt("-printcertreq -file " + alias + ".req");
|
||||
if (bad == null) {
|
||||
oa.shouldNotContain("Warning")
|
||||
.shouldNotContain("(weak)");
|
||||
} else {
|
||||
oa.shouldContain("Warning")
|
||||
.shouldMatch("The certificate request.*" + bad + ".*will be disabled")
|
||||
.shouldContain(bad + " (weak)");
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user