mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 06:45:07 +02:00
8269039: Disable SHA-1 Signed JARs
Reviewed-by: weijun
This commit is contained in:
parent
42d5d2abaa
commit
6d91a3eb7b
27 changed files with 457 additions and 357 deletions
|
@ -56,6 +56,7 @@ import jdk.security.jarsigner.JarSigner;
|
|||
import jdk.security.jarsigner.JarSignerException;
|
||||
import sun.security.pkcs.PKCS7;
|
||||
import sun.security.pkcs.SignerInfo;
|
||||
import sun.security.provider.certpath.CertPathConstraintsParameters;
|
||||
import sun.security.timestamp.TimestampToken;
|
||||
import sun.security.tools.KeyStoreUtil;
|
||||
import sun.security.validator.Validator;
|
||||
|
@ -972,7 +973,8 @@ public class Main {
|
|||
String history;
|
||||
try {
|
||||
SignerInfo si = p7.getSignerInfos()[0];
|
||||
X509Certificate signer = si.getCertificate(p7);
|
||||
ArrayList<X509Certificate> chain = si.getCertificateChain(p7);
|
||||
X509Certificate signer = chain.get(0);
|
||||
String digestAlg = digestMap.get(s);
|
||||
String sigAlg = SignerInfo.makeSigAlg(
|
||||
si.getDigestAlgorithmId(),
|
||||
|
@ -996,26 +998,31 @@ public class Main {
|
|||
TimeZone.getTimeZone("UTC"),
|
||||
Locale.getDefault(Locale.Category.FORMAT));
|
||||
c.setTime(tsTokenInfo.getDate());
|
||||
JarConstraintsParameters jcp =
|
||||
new JarConstraintsParameters(chain, si.getTimestamp());
|
||||
history = String.format(
|
||||
rb.getString("history.with.ts"),
|
||||
signer.getSubjectX500Principal(),
|
||||
verifyWithWeak(digestAlg, DIGEST_PRIMITIVE_SET, false),
|
||||
verifyWithWeak(sigAlg, SIG_PRIMITIVE_SET, false),
|
||||
verifyWithWeak(key),
|
||||
verifyWithWeak(digestAlg, DIGEST_PRIMITIVE_SET, false, jcp),
|
||||
verifyWithWeak(sigAlg, SIG_PRIMITIVE_SET, false, jcp),
|
||||
verifyWithWeak(key, jcp),
|
||||
c,
|
||||
tsSigner.getSubjectX500Principal(),
|
||||
verifyWithWeak(tsDigestAlg, DIGEST_PRIMITIVE_SET, true),
|
||||
verifyWithWeak(tsSigAlg, SIG_PRIMITIVE_SET, true),
|
||||
verifyWithWeak(tsKey));
|
||||
verifyWithWeak(tsDigestAlg, DIGEST_PRIMITIVE_SET, true, jcp),
|
||||
verifyWithWeak(tsSigAlg, SIG_PRIMITIVE_SET, true, jcp),
|
||||
verifyWithWeak(tsKey, jcp));
|
||||
} else {
|
||||
JarConstraintsParameters jcp =
|
||||
new JarConstraintsParameters(chain, null);
|
||||
history = String.format(
|
||||
rb.getString("history.without.ts"),
|
||||
signer.getSubjectX500Principal(),
|
||||
verifyWithWeak(digestAlg, DIGEST_PRIMITIVE_SET, false),
|
||||
verifyWithWeak(sigAlg, SIG_PRIMITIVE_SET, false),
|
||||
verifyWithWeak(key));
|
||||
verifyWithWeak(digestAlg, DIGEST_PRIMITIVE_SET, false, jcp),
|
||||
verifyWithWeak(sigAlg, SIG_PRIMITIVE_SET, false, jcp),
|
||||
verifyWithWeak(key, jcp));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
// The only usage of sigNameMap, remember the name
|
||||
// of the block file if it's invalid.
|
||||
history = String.format(
|
||||
|
@ -1339,56 +1346,67 @@ public class Main {
|
|||
}
|
||||
}
|
||||
|
||||
private String verifyWithWeak(String alg, Set<CryptoPrimitive> primitiveSet, boolean tsa) {
|
||||
if (JAR_DISABLED_CHECK.permits(primitiveSet, alg, null)) {
|
||||
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 {
|
||||
private String verifyWithWeak(String alg, Set<CryptoPrimitive> primitiveSet,
|
||||
boolean tsa, JarConstraintsParameters jcp) {
|
||||
|
||||
try {
|
||||
JAR_DISABLED_CHECK.permits(alg, jcp);
|
||||
} catch (CertPathValidatorException e) {
|
||||
disabledAlgFound = true;
|
||||
return String.format(rb.getString("with.disabled"), alg);
|
||||
}
|
||||
}
|
||||
|
||||
private String verifyWithWeak(PublicKey key) {
|
||||
int kLen = KeyUtil.getKeySize(key);
|
||||
if (JAR_DISABLED_CHECK.permits(SIG_PRIMITIVE_SET, key)) {
|
||||
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");
|
||||
}
|
||||
try {
|
||||
LEGACY_CHECK.permits(alg, jcp);
|
||||
return alg;
|
||||
} catch (CertPathValidatorException e) {
|
||||
if (primitiveSet == SIG_PRIMITIVE_SET) {
|
||||
legacyAlg |= 2;
|
||||
legacySigAlg = alg;
|
||||
} else {
|
||||
weakPublicKey = key;
|
||||
legacyAlg |= 8;
|
||||
return String.format(rb.getString("key.bit.weak"), kLen);
|
||||
if (tsa) {
|
||||
legacyAlg |= 4;
|
||||
legacyTsaDigestAlg = alg;
|
||||
} else {
|
||||
legacyAlg |= 1;
|
||||
legacyDigestAlg = alg;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
disabledAlgFound = true;
|
||||
return String.format(rb.getString("key.bit.disabled"), kLen);
|
||||
return String.format(rb.getString("with.weak"), alg);
|
||||
}
|
||||
}
|
||||
|
||||
private void checkWeakSign(String alg, Set<CryptoPrimitive> primitiveSet, boolean tsa) {
|
||||
if (JAR_DISABLED_CHECK.permits(primitiveSet, alg, null)) {
|
||||
if (!LEGACY_CHECK.permits(primitiveSet, alg, null)) {
|
||||
private String verifyWithWeak(PublicKey key, JarConstraintsParameters jcp) {
|
||||
int kLen = KeyUtil.getKeySize(key);
|
||||
try {
|
||||
JAR_DISABLED_CHECK.permits(key.getAlgorithm(), jcp);
|
||||
} catch (CertPathValidatorException e) {
|
||||
disabledAlgFound = true;
|
||||
return String.format(rb.getString("key.bit.disabled"), kLen);
|
||||
}
|
||||
try {
|
||||
LEGACY_CHECK.permits(key.getAlgorithm(), jcp);
|
||||
if (kLen >= 0) {
|
||||
return String.format(rb.getString("key.bit"), kLen);
|
||||
} else {
|
||||
return rb.getString("unknown.size");
|
||||
}
|
||||
} catch (CertPathValidatorException e) {
|
||||
weakPublicKey = key;
|
||||
legacyAlg |= 8;
|
||||
return String.format(rb.getString("key.bit.weak"), kLen);
|
||||
}
|
||||
}
|
||||
|
||||
private void checkWeakSign(String alg, Set<CryptoPrimitive> primitiveSet,
|
||||
boolean tsa, JarConstraintsParameters jcp) {
|
||||
|
||||
try {
|
||||
JAR_DISABLED_CHECK.permits(alg, jcp);
|
||||
try {
|
||||
LEGACY_CHECK.permits(alg, jcp);
|
||||
} catch (CertPathValidatorException e) {
|
||||
if (primitiveSet == SIG_PRIMITIVE_SET) {
|
||||
legacyAlg |= 2;
|
||||
legacyAlg |= 2;
|
||||
} else {
|
||||
if (tsa) {
|
||||
legacyAlg |= 4;
|
||||
|
@ -1397,7 +1415,7 @@ public class Main {
|
|||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
} catch (CertPathValidatorException e) {
|
||||
if (primitiveSet == SIG_PRIMITIVE_SET) {
|
||||
disabledAlg |= 2;
|
||||
} else {
|
||||
|
@ -1410,43 +1428,50 @@ public class Main {
|
|||
}
|
||||
}
|
||||
|
||||
private void checkWeakSign(PrivateKey key) {
|
||||
if (JAR_DISABLED_CHECK.permits(SIG_PRIMITIVE_SET, key)) {
|
||||
if (!LEGACY_CHECK.permits(SIG_PRIMITIVE_SET, key)) {
|
||||
private void checkWeakSign(PrivateKey key, JarConstraintsParameters jcp) {
|
||||
try {
|
||||
JAR_DISABLED_CHECK.permits(key.getAlgorithm(), jcp);
|
||||
try {
|
||||
LEGACY_CHECK.permits(key.getAlgorithm(), jcp);
|
||||
} catch (CertPathValidatorException e) {
|
||||
legacyAlg |= 8;
|
||||
}
|
||||
} else {
|
||||
} catch (CertPathValidatorException e) {
|
||||
disabledAlg |= 8;
|
||||
}
|
||||
}
|
||||
|
||||
private static String checkWeakKey(PublicKey key) {
|
||||
private static String checkWeakKey(PublicKey key, CertPathConstraintsParameters cpcp) {
|
||||
int kLen = KeyUtil.getKeySize(key);
|
||||
if (CERTPATH_DISABLED_CHECK.permits(SIG_PRIMITIVE_SET, key)) {
|
||||
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");
|
||||
}
|
||||
try {
|
||||
CERTPATH_DISABLED_CHECK.permits(key.getAlgorithm(), cpcp);
|
||||
} catch (CertPathValidatorException e) {
|
||||
return String.format(rb.getString("key.bit.disabled"), kLen);
|
||||
}
|
||||
try {
|
||||
LEGACY_CHECK.permits(key.getAlgorithm(), cpcp);
|
||||
if (kLen >= 0) {
|
||||
return String.format(rb.getString("key.bit"), kLen);
|
||||
} else {
|
||||
return String.format(rb.getString("key.bit.weak"), kLen);
|
||||
return rb.getString("unknown.size");
|
||||
}
|
||||
} else {
|
||||
return String.format(rb.getString("key.bit.disabled"), kLen);
|
||||
} catch (CertPathValidatorException e) {
|
||||
return String.format(rb.getString("key.bit.weak"), kLen);
|
||||
}
|
||||
}
|
||||
|
||||
private static String checkWeakAlg(String alg) {
|
||||
if (CERTPATH_DISABLED_CHECK.permits(SIG_PRIMITIVE_SET, alg, null)) {
|
||||
if (LEGACY_CHECK.permits(SIG_PRIMITIVE_SET, alg, null)) {
|
||||
return alg;
|
||||
} else {
|
||||
return String.format(rb.getString("with.weak"), alg);
|
||||
}
|
||||
} else {
|
||||
private static String checkWeakAlg(String alg, CertPathConstraintsParameters cpcp) {
|
||||
try {
|
||||
CERTPATH_DISABLED_CHECK.permits(alg, cpcp);
|
||||
} catch (CertPathValidatorException e) {
|
||||
return String.format(rb.getString("with.disabled"), alg);
|
||||
}
|
||||
try {
|
||||
LEGACY_CHECK.permits(alg, cpcp);
|
||||
return alg;
|
||||
} catch (CertPathValidatorException e) {
|
||||
return String.format(rb.getString("with.weak"), alg);
|
||||
}
|
||||
}
|
||||
|
||||
private static MessageFormat validityTimeForm = null;
|
||||
|
@ -1471,7 +1496,7 @@ public class Main {
|
|||
* @param checkUsage true to check code signer keyUsage
|
||||
*/
|
||||
String printCert(boolean isTsCert, String tab, Certificate c,
|
||||
Date timestamp, boolean checkUsage) throws Exception {
|
||||
Date timestamp, boolean checkUsage, CertPathConstraintsParameters cpcp) throws Exception {
|
||||
|
||||
StringBuilder certStr = new StringBuilder();
|
||||
String space = rb.getString("SPACE");
|
||||
|
@ -1504,16 +1529,16 @@ public class Main {
|
|||
.append("Signature algorithm: ")
|
||||
.append(sigalg)
|
||||
.append(rb.getString("COMMA"))
|
||||
.append(checkWeakKey(key));
|
||||
.append(checkWeakKey(key, cpcp));
|
||||
|
||||
certStr.append("\n").append(tab).append("[");
|
||||
certStr.append(rb.getString("trusted.certificate"));
|
||||
} else {
|
||||
certStr.append("\n").append(tab)
|
||||
.append("Signature algorithm: ")
|
||||
.append(checkWeakAlg(sigalg))
|
||||
.append(checkWeakAlg(sigalg, cpcp))
|
||||
.append(rb.getString("COMMA"))
|
||||
.append(checkWeakKey(key));
|
||||
.append(checkWeakKey(key, cpcp));
|
||||
|
||||
certStr.append("\n").append(tab).append("[");
|
||||
|
||||
|
@ -1694,19 +1719,21 @@ public class Main {
|
|||
if (digestalg == null) {
|
||||
digestalg = JarSigner.Builder.getDefaultDigestAlgorithm();
|
||||
}
|
||||
checkWeakSign(digestalg, DIGEST_PRIMITIVE_SET, false);
|
||||
JarConstraintsParameters jcp =
|
||||
new JarConstraintsParameters(Arrays.asList(certChain), null);
|
||||
checkWeakSign(digestalg, DIGEST_PRIMITIVE_SET, false, jcp);
|
||||
|
||||
if (tSADigestAlg == null) {
|
||||
tSADigestAlg = JarSigner.Builder.getDefaultDigestAlgorithm();
|
||||
}
|
||||
checkWeakSign(tSADigestAlg, DIGEST_PRIMITIVE_SET, true);
|
||||
checkWeakSign(tSADigestAlg, DIGEST_PRIMITIVE_SET, true, jcp);
|
||||
|
||||
if (sigalg == null) {
|
||||
sigalg = JarSigner.Builder.getDefaultSignatureAlgorithm(privateKey);
|
||||
}
|
||||
checkWeakSign(sigalg, SIG_PRIMITIVE_SET, false);
|
||||
checkWeakSign(sigalg, SIG_PRIMITIVE_SET, false, jcp);
|
||||
|
||||
checkWeakSign(privateKey);
|
||||
checkWeakSign(privateKey, jcp);
|
||||
|
||||
boolean aliasUsed = false;
|
||||
X509Certificate tsaCert = null;
|
||||
|
@ -1804,8 +1831,10 @@ public class Main {
|
|||
if (tsaUrl != null) {
|
||||
System.out.println(rb.getString("TSA.location.") + tsaUrl);
|
||||
} else if (tsaCert != null) {
|
||||
CertPathConstraintsParameters cpcp =
|
||||
new CertPathConstraintsParameters(tsaCert, Validator.VAR_TSA_SERVER, null, null);
|
||||
System.out.println(rb.getString("TSA.certificate.") +
|
||||
printCert(true, "", tsaCert, null, false));
|
||||
printCert(true, "", tsaCert, null, false, cpcp));
|
||||
}
|
||||
}
|
||||
builder.tsa(tsaURI);
|
||||
|
@ -2015,8 +2044,13 @@ public class Main {
|
|||
boolean first = true;
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(tab1).append(rb.getString("...Signer")).append('\n');
|
||||
@SuppressWarnings("unchecked")
|
||||
List<X509Certificate> chain = (List<X509Certificate>)certs;
|
||||
TrustAnchor anchor = findTrustAnchor(chain);
|
||||
for (Certificate c : certs) {
|
||||
sb.append(printCert(false, tab2, c, timestamp, first));
|
||||
CertPathConstraintsParameters cpcp =
|
||||
new CertPathConstraintsParameters((X509Certificate)c, Validator.VAR_CODE_SIGNING, anchor, timestamp);
|
||||
sb.append(printCert(false, tab2, c, timestamp, first, cpcp));
|
||||
sb.append('\n');
|
||||
first = false;
|
||||
}
|
||||
|
@ -2029,9 +2063,15 @@ public class Main {
|
|||
.append(e.getLocalizedMessage()).append("]\n");
|
||||
}
|
||||
if (ts != null) {
|
||||
List<? extends Certificate> tscerts = ts.getSignerCertPath().getCertificates();
|
||||
@SuppressWarnings("unchecked")
|
||||
List<X509Certificate> tschain = (List<X509Certificate>)tscerts;
|
||||
anchor = findTrustAnchor(chain);
|
||||
sb.append(tab1).append(rb.getString("...TSA")).append('\n');
|
||||
for (Certificate c : ts.getSignerCertPath().getCertificates()) {
|
||||
sb.append(printCert(true, tab2, c, null, false));
|
||||
for (Certificate c : tschain) {
|
||||
CertPathConstraintsParameters cpcp =
|
||||
new CertPathConstraintsParameters((X509Certificate)c, Validator.VAR_TSA_SERVER, anchor, timestamp);
|
||||
sb.append(printCert(true, tab2, c, null, false, cpcp));
|
||||
sb.append('\n');
|
||||
}
|
||||
try {
|
||||
|
@ -2052,6 +2092,15 @@ public class Main {
|
|||
return sb.toString();
|
||||
}
|
||||
|
||||
private TrustAnchor findTrustAnchor(List<X509Certificate> chain) {
|
||||
X509Certificate last = chain.get(chain.size() - 1);
|
||||
Optional<X509Certificate> trusted =
|
||||
trustedCerts.stream()
|
||||
.filter(c -> c.getSubjectX500Principal().equals(last.getIssuerX500Principal()))
|
||||
.findFirst();
|
||||
return trusted.isPresent() ? new TrustAnchor(trusted.get(), null) : null;
|
||||
}
|
||||
|
||||
void loadKeyStore(String keyStoreName, boolean prompt) {
|
||||
|
||||
if (!nullStream && keyStoreName == null) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue