mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-26 14:24:46 +02:00
8273236: keytool does not accurately warn about algorithms that are disabled but have additional constraints
Reviewed-by: mullan
This commit is contained in:
parent
16e0ad0ad0
commit
c2ee1b33c3
3 changed files with 433 additions and 56 deletions
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -31,10 +31,14 @@ import java.nio.file.Path;
|
||||||
import java.security.*;
|
import java.security.*;
|
||||||
import java.security.cert.Certificate;
|
import java.security.cert.Certificate;
|
||||||
import java.security.cert.CertificateFactory;
|
import java.security.cert.CertificateFactory;
|
||||||
|
import java.security.cert.CertPathValidatorException;
|
||||||
|
import java.security.cert.CertPathValidatorException.BasicReason;
|
||||||
import java.security.cert.CertStoreException;
|
import java.security.cert.CertStoreException;
|
||||||
import java.security.cert.CRL;
|
import java.security.cert.CRL;
|
||||||
import java.security.cert.X509Certificate;
|
import java.security.cert.X509Certificate;
|
||||||
import java.security.cert.CertificateException;
|
import java.security.cert.CertificateException;
|
||||||
|
import java.security.cert.CertificateParsingException;
|
||||||
|
import java.security.cert.TrustAnchor;
|
||||||
import java.security.cert.URICertStoreParameters;
|
import java.security.cert.URICertStoreParameters;
|
||||||
|
|
||||||
|
|
||||||
|
@ -43,6 +47,8 @@ import java.security.interfaces.EdECKey;
|
||||||
import java.security.spec.ECParameterSpec;
|
import java.security.spec.ECParameterSpec;
|
||||||
import java.text.Collator;
|
import java.text.Collator;
|
||||||
import java.text.MessageFormat;
|
import java.text.MessageFormat;
|
||||||
|
import java.text.ParseException;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.function.BiFunction;
|
import java.util.function.BiFunction;
|
||||||
import java.util.jar.JarEntry;
|
import java.util.jar.JarEntry;
|
||||||
|
@ -60,6 +66,7 @@ import javax.security.auth.x500.X500Principal;
|
||||||
import java.util.Base64;
|
import java.util.Base64;
|
||||||
|
|
||||||
import sun.security.pkcs12.PKCS12KeyStore;
|
import sun.security.pkcs12.PKCS12KeyStore;
|
||||||
|
import sun.security.provider.certpath.CertPathConstraintsParameters;
|
||||||
import sun.security.util.ECKeySizeParameterSpec;
|
import sun.security.util.ECKeySizeParameterSpec;
|
||||||
import sun.security.util.KeyUtil;
|
import sun.security.util.KeyUtil;
|
||||||
import sun.security.util.NamedCurve;
|
import sun.security.util.NamedCurve;
|
||||||
|
@ -83,6 +90,7 @@ import sun.security.tools.KeyStoreUtil;
|
||||||
import sun.security.tools.PathList;
|
import sun.security.tools.PathList;
|
||||||
import sun.security.util.DerValue;
|
import sun.security.util.DerValue;
|
||||||
import sun.security.util.Pem;
|
import sun.security.util.Pem;
|
||||||
|
import sun.security.validator.Validator;
|
||||||
import sun.security.x509.*;
|
import sun.security.x509.*;
|
||||||
|
|
||||||
import static java.security.KeyStore.*;
|
import static java.security.KeyStore.*;
|
||||||
|
@ -178,6 +186,8 @@ public final class Main {
|
||||||
// Warnings on weak algorithms etc
|
// Warnings on weak algorithms etc
|
||||||
private List<String> weakWarnings = new ArrayList<>();
|
private List<String> weakWarnings = new ArrayList<>();
|
||||||
|
|
||||||
|
private Set<X509Certificate> trustedCerts = new HashSet<>();
|
||||||
|
|
||||||
private static final DisabledAlgorithmConstraints DISABLED_CHECK =
|
private static final DisabledAlgorithmConstraints DISABLED_CHECK =
|
||||||
new DisabledAlgorithmConstraints(
|
new DisabledAlgorithmConstraints(
|
||||||
DisabledAlgorithmConstraints.PROPERTY_CERTPATH_DISABLED_ALGS);
|
DisabledAlgorithmConstraints.PROPERTY_CERTPATH_DISABLED_ALGS);
|
||||||
|
@ -1118,6 +1128,7 @@ public final class Main {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
KeyStore cakstore = buildTrustedCerts();
|
||||||
// -trustcacerts can be specified on -importcert, -printcert or -printcrl.
|
// -trustcacerts can be specified on -importcert, -printcert or -printcrl.
|
||||||
// Reset it so that warnings on CA cert will remain for other command.
|
// Reset it so that warnings on CA cert will remain for other command.
|
||||||
if (command != IMPORTCERT && command != PRINTCERT
|
if (command != IMPORTCERT && command != PRINTCERT
|
||||||
|
@ -1126,7 +1137,13 @@ public final class Main {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (trustcacerts) {
|
if (trustcacerts) {
|
||||||
caks = KeyStoreUtil.getCacertsKeyStore();
|
if (cakstore != null) {
|
||||||
|
caks = cakstore;
|
||||||
|
} else {
|
||||||
|
// try to load cacerts again, and let exception propagate
|
||||||
|
// if it cannot be loaded
|
||||||
|
caks = KeyStoreUtil.getCacertsKeyStore();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Perform the specified command
|
// Perform the specified command
|
||||||
|
@ -1485,7 +1502,9 @@ public final class Main {
|
||||||
byte[] rawReq = Pem.decode(new String(sb));
|
byte[] rawReq = Pem.decode(new String(sb));
|
||||||
PKCS10 req = new PKCS10(rawReq);
|
PKCS10 req = new PKCS10(rawReq);
|
||||||
|
|
||||||
checkWeak(rb.getString("the.certificate.request"), req);
|
CertPathConstraintsParameters cpcp = new CertPathConstraintsParameters(
|
||||||
|
req.getSubjectPublicKeyInfo(), null, null, null);
|
||||||
|
checkWeakConstraint(rb.getString("the.certificate.request"), req, cpcp);
|
||||||
|
|
||||||
info.set(X509CertInfo.KEY, new CertificateX509Key(req.getSubjectPublicKeyInfo()));
|
info.set(X509CertInfo.KEY, new CertificateX509Key(req.getSubjectPublicKeyInfo()));
|
||||||
info.set(X509CertInfo.SUBJECT,
|
info.set(X509CertInfo.SUBJECT,
|
||||||
|
@ -1542,8 +1561,11 @@ public final class Main {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
checkWeak(rb.getString("the.issuer"), keyStore.getCertificateChain(alias));
|
checkWeakConstraint(rb.getString("the.issuer"),
|
||||||
checkWeak(rb.getString("the.generated.certificate"), cert);
|
keyStore.getCertificateChain(alias));
|
||||||
|
cpcp = buildCertPathConstraint(cert, null);
|
||||||
|
checkWeakConstraint(rb.getString("the.generated.certificate"),
|
||||||
|
cert, cpcp);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void doGenCRL(PrintStream out)
|
private void doGenCRL(PrintStream out)
|
||||||
|
@ -1592,7 +1614,10 @@ public final class Main {
|
||||||
} else {
|
} else {
|
||||||
out.write(crl.getEncodedInternal());
|
out.write(crl.getEncodedInternal());
|
||||||
}
|
}
|
||||||
checkWeak(rb.getString("the.generated.crl"), crl, privateKey);
|
CertPathConstraintsParameters cpcp = new CertPathConstraintsParameters(
|
||||||
|
privateKey, null, null, null);
|
||||||
|
checkWeakConstraint(rb.getString("the.generated.crl"), crl, privateKey,
|
||||||
|
cpcp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1638,7 +1663,10 @@ public final class Main {
|
||||||
request.encodeAndSign(subject, privKey, sigAlgName);
|
request.encodeAndSign(subject, privKey, sigAlgName);
|
||||||
request.print(out);
|
request.print(out);
|
||||||
|
|
||||||
checkWeak(rb.getString("the.generated.certificate.request"), request);
|
CertPathConstraintsParameters cpcp = new CertPathConstraintsParameters(
|
||||||
|
request.getSubjectPublicKeyInfo(), null, null, null);
|
||||||
|
checkWeakConstraint(rb.getString("the.generated.certificate.request"),
|
||||||
|
request, cpcp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1683,7 +1711,9 @@ public final class Main {
|
||||||
throw new Exception(form.format(source));
|
throw new Exception(form.format(source));
|
||||||
}
|
}
|
||||||
dumpCert(cert, out);
|
dumpCert(cert, out);
|
||||||
checkWeak(rb.getString("the.certificate"), cert);
|
CertPathConstraintsParameters cpcp =
|
||||||
|
buildCertPathConstraint(cert, null);
|
||||||
|
checkWeakConstraint(rb.getString("the.certificate"), cert, cpcp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2021,7 +2051,8 @@ public final class Main {
|
||||||
} else {
|
} else {
|
||||||
finalChain = new Certificate[] { newCert };
|
finalChain = new Certificate[] { newCert };
|
||||||
}
|
}
|
||||||
checkWeak(rb.getString("the.generated.certificate"), finalChain);
|
checkWeakConstraint(rb.getString("the.generated.certificate"),
|
||||||
|
finalChain);
|
||||||
keyStore.setKeyEntry(alias, privKey, keyPass, finalChain);
|
keyStore.setKeyEntry(alias, privKey, keyPass, finalChain);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2114,6 +2145,7 @@ public final class Main {
|
||||||
private void doPrintEntry(String label, String alias, PrintStream out)
|
private void doPrintEntry(String label, String alias, PrintStream out)
|
||||||
throws Exception
|
throws Exception
|
||||||
{
|
{
|
||||||
|
CertPathConstraintsParameters cpcp;
|
||||||
if (keyStore.containsAlias(alias) == false) {
|
if (keyStore.containsAlias(alias) == false) {
|
||||||
MessageFormat form = new MessageFormat
|
MessageFormat form = new MessageFormat
|
||||||
(rb.getString("Alias.alias.does.not.exist"));
|
(rb.getString("Alias.alias.does.not.exist"));
|
||||||
|
@ -2170,6 +2202,10 @@ public final class Main {
|
||||||
if (verbose || rfc || debug) {
|
if (verbose || rfc || debug) {
|
||||||
out.println(rb.getString
|
out.println(rb.getString
|
||||||
("Certificate.chain.length.") + chain.length);
|
("Certificate.chain.length.") + chain.length);
|
||||||
|
|
||||||
|
X509Certificate[] xcerts = convertCerts(chain);
|
||||||
|
List<X509Certificate> certs = Arrays.asList(xcerts);
|
||||||
|
TrustAnchor anchor = findTrustAnchor(certs);
|
||||||
for (int i = 0; i < chain.length; i ++) {
|
for (int i = 0; i < chain.length; i ++) {
|
||||||
MessageFormat form = new MessageFormat
|
MessageFormat form = new MessageFormat
|
||||||
(rb.getString("Certificate.i.1."));
|
(rb.getString("Certificate.i.1."));
|
||||||
|
@ -2182,14 +2218,26 @@ public final class Main {
|
||||||
} else {
|
} else {
|
||||||
dumpCert(chain[i], out);
|
dumpCert(chain[i], out);
|
||||||
}
|
}
|
||||||
checkWeak(label, chain[i]);
|
|
||||||
|
if (i == 0 &&
|
||||||
|
((X509Certificate)chain[0]).
|
||||||
|
getBasicConstraints() == -1) {
|
||||||
|
// this is an EE
|
||||||
|
cpcp = buildCertPathConstraint((X509Certificate) chain[i], anchor);
|
||||||
|
} else {
|
||||||
|
cpcp = new CertPathConstraintsParameters(
|
||||||
|
(X509Certificate)chain[i], null, anchor,
|
||||||
|
null);
|
||||||
|
}
|
||||||
|
|
||||||
|
checkWeakConstraint(label, chain[i], cpcp);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Print the digest of the user cert only
|
// Print the digest of the user cert only
|
||||||
out.println
|
out.println
|
||||||
(rb.getString("Certificate.fingerprint.SHA.256.") +
|
(rb.getString("Certificate.fingerprint.SHA.256.") +
|
||||||
getCertFingerPrint("SHA-256", chain[0]));
|
getCertFingerPrint("SHA-256", chain[0]));
|
||||||
checkWeak(label, chain);
|
checkWeakConstraint(label, chain);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
out.println(rb.getString
|
out.println(rb.getString
|
||||||
|
@ -2215,7 +2263,8 @@ public final class Main {
|
||||||
out.println(rb.getString("Certificate.fingerprint.SHA.256.")
|
out.println(rb.getString("Certificate.fingerprint.SHA.256.")
|
||||||
+ getCertFingerPrint("SHA-256", cert));
|
+ getCertFingerPrint("SHA-256", cert));
|
||||||
}
|
}
|
||||||
checkWeak(label, cert);
|
cpcp = buildCertPathConstraint((X509Certificate)cert, null);
|
||||||
|
checkWeakConstraint(label, cert, cpcp);
|
||||||
} else {
|
} else {
|
||||||
out.println(rb.getString("Unknown.Entry.Type"));
|
out.println(rb.getString("Unknown.Entry.Type"));
|
||||||
}
|
}
|
||||||
|
@ -2442,7 +2491,9 @@ public final class Main {
|
||||||
try {
|
try {
|
||||||
Certificate c = srckeystore.getCertificate(alias);
|
Certificate c = srckeystore.getCertificate(alias);
|
||||||
if (c != null) {
|
if (c != null) {
|
||||||
checkWeak("<" + newAlias + ">", c);
|
CertPathConstraintsParameters cpcp =
|
||||||
|
buildCertPathConstraint((X509Certificate)c, null);
|
||||||
|
checkWeakConstraint("<" + newAlias + ">", c, cpcp);
|
||||||
}
|
}
|
||||||
keyStore.setEntry(newAlias, entry, pp);
|
keyStore.setEntry(newAlias, entry, pp);
|
||||||
// Place the check so that only successful imports are blocked.
|
// Place the check so that only successful imports are blocked.
|
||||||
|
@ -2639,11 +2690,14 @@ public final class Main {
|
||||||
issuer = verifyCRL(caks, crl);
|
issuer = verifyCRL(caks, crl);
|
||||||
if (issuer != null) {
|
if (issuer != null) {
|
||||||
signer = caks.getCertificate(issuer);
|
signer = caks.getCertificate(issuer);
|
||||||
|
CertPathConstraintsParameters cpcp =
|
||||||
|
buildCertPathConstraint((X509Certificate)signer,
|
||||||
|
null);
|
||||||
out.printf(rb.getString(
|
out.printf(rb.getString(
|
||||||
"verified.by.s.in.s.weak"),
|
"verified.by.s.in.s.weak"),
|
||||||
issuer,
|
issuer,
|
||||||
"cacerts",
|
"cacerts",
|
||||||
withWeak(signer.getPublicKey()));
|
withWeakConstraint(signer.getPublicKey(), cpcp));
|
||||||
out.println();
|
out.println();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2651,11 +2705,14 @@ public final class Main {
|
||||||
issuer = verifyCRL(keyStore, crl);
|
issuer = verifyCRL(keyStore, crl);
|
||||||
if (issuer != null) {
|
if (issuer != null) {
|
||||||
signer = keyStore.getCertificate(issuer);
|
signer = keyStore.getCertificate(issuer);
|
||||||
|
CertPathConstraintsParameters cpcp =
|
||||||
|
buildCertPathConstraint((X509Certificate)signer,
|
||||||
|
null);
|
||||||
out.printf(rb.getString(
|
out.printf(rb.getString(
|
||||||
"verified.by.s.in.s.weak"),
|
"verified.by.s.in.s.weak"),
|
||||||
issuer,
|
issuer,
|
||||||
"keystore",
|
"keystore",
|
||||||
withWeak(signer.getPublicKey()));
|
withWeakConstraint(signer.getPublicKey(), cpcp));
|
||||||
out.println();
|
out.println();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2672,7 +2729,15 @@ public final class Main {
|
||||||
out.println(rb.getString
|
out.println(rb.getString
|
||||||
("STARNN"));
|
("STARNN"));
|
||||||
}
|
}
|
||||||
checkWeak(rb.getString("the.crl"), crl, signer == null ? null : signer.getPublicKey());
|
|
||||||
|
if (signer != null) {
|
||||||
|
CertPathConstraintsParameters cpcp =
|
||||||
|
buildCertPathConstraint((X509Certificate)signer, null);
|
||||||
|
checkWeakConstraint(rb.getString("the.crl"), crl,
|
||||||
|
signer.getPublicKey(), cpcp);
|
||||||
|
} else {
|
||||||
|
checkWeak(rb.getString("the.crl"), crl, null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2718,10 +2783,12 @@ public final class Main {
|
||||||
PKCS10 req = new PKCS10(Pem.decode(new String(sb)));
|
PKCS10 req = new PKCS10(Pem.decode(new String(sb)));
|
||||||
|
|
||||||
PublicKey pkey = req.getSubjectPublicKeyInfo();
|
PublicKey pkey = req.getSubjectPublicKeyInfo();
|
||||||
|
CertPathConstraintsParameters cpcp =
|
||||||
|
new CertPathConstraintsParameters(pkey, null, null, null);
|
||||||
out.printf(rb.getString("PKCS.10.with.weak"),
|
out.printf(rb.getString("PKCS.10.with.weak"),
|
||||||
req.getSubjectName(),
|
req.getSubjectName(),
|
||||||
pkey.getFormat(),
|
pkey.getFormat(),
|
||||||
withWeak(pkey),
|
withWeakConstraint(pkey, cpcp),
|
||||||
withWeak(req.getSigAlg()));
|
withWeak(req.getSigAlg()));
|
||||||
for (PKCS10Attribute attr: req.getAttributes().getAttributes()) {
|
for (PKCS10Attribute attr: req.getAttributes().getAttributes()) {
|
||||||
ObjectIdentifier oid = attr.getAttributeId();
|
ObjectIdentifier oid = attr.getAttributeId();
|
||||||
|
@ -2745,7 +2812,12 @@ public final class Main {
|
||||||
if (debug) {
|
if (debug) {
|
||||||
out.println(req); // Just to see more, say, public key length...
|
out.println(req); // Just to see more, say, public key length...
|
||||||
}
|
}
|
||||||
checkWeak(rb.getString("the.certificate.request"), req);
|
|
||||||
|
CertPathConstraintsParameters cpcp1 =
|
||||||
|
new CertPathConstraintsParameters(
|
||||||
|
req.getSubjectPublicKeyInfo(), null, null, null);
|
||||||
|
checkWeakConstraint(rb.getString("the.certificate.request"), req,
|
||||||
|
cpcp1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2765,6 +2837,9 @@ public final class Main {
|
||||||
throw new Exception(rb.getString("Empty.input"));
|
throw new Exception(rb.getString("Empty.input"));
|
||||||
}
|
}
|
||||||
Certificate[] certs = c.toArray(new Certificate[c.size()]);
|
Certificate[] certs = c.toArray(new Certificate[c.size()]);
|
||||||
|
X509Certificate[] xcerts = convertCerts(certs);
|
||||||
|
List<X509Certificate> chain = Arrays.asList(xcerts);
|
||||||
|
TrustAnchor anchor = findTrustAnchor(chain);
|
||||||
for (int i=0; i<certs.length; i++) {
|
for (int i=0; i<certs.length; i++) {
|
||||||
X509Certificate x509Cert = null;
|
X509Certificate x509Cert = null;
|
||||||
try {
|
try {
|
||||||
|
@ -2785,7 +2860,17 @@ public final class Main {
|
||||||
if (i < (certs.length-1)) {
|
if (i < (certs.length-1)) {
|
||||||
out.println();
|
out.println();
|
||||||
}
|
}
|
||||||
checkWeak(oneInMany(rb.getString("the.certificate"), i, certs.length), x509Cert);
|
CertPathConstraintsParameters cpcp;
|
||||||
|
if (i == 0 &&
|
||||||
|
x509Cert.getBasicConstraints() == -1) {
|
||||||
|
// this is an EE
|
||||||
|
cpcp = buildCertPathConstraint(x509Cert, anchor);
|
||||||
|
} else {
|
||||||
|
cpcp = new CertPathConstraintsParameters(x509Cert,
|
||||||
|
null, anchor, null);
|
||||||
|
}
|
||||||
|
checkWeakConstraint(oneInMany(rb.getString("the.certificate"),
|
||||||
|
i, certs.length), x509Cert, cpcp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2901,6 +2986,11 @@ public final class Main {
|
||||||
|
|
||||||
List<? extends Certificate> certs
|
List<? extends Certificate> certs
|
||||||
= signer.getSignerCertPath().getCertificates();
|
= signer.getSignerCertPath().getCertificates();
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
List<X509Certificate> chain =
|
||||||
|
(List<X509Certificate>)certs;
|
||||||
|
TrustAnchor anchor = findTrustAnchor(chain);
|
||||||
|
CertPathConstraintsParameters cpcp;
|
||||||
int cc = 0;
|
int cc = 0;
|
||||||
for (Certificate cert: certs) {
|
for (Certificate cert: certs) {
|
||||||
out.printf(rb.getString("Certificate.d."), ++cc);
|
out.printf(rb.getString("Certificate.d."), ++cc);
|
||||||
|
@ -2913,16 +3003,27 @@ public final class Main {
|
||||||
printX509Cert(x, out);
|
printX509Cert(x, out);
|
||||||
}
|
}
|
||||||
out.println();
|
out.println();
|
||||||
checkWeak(oneInManys(rb.getString(
|
if (cc == 0 && x.getBasicConstraints() == -1) {
|
||||||
|
// this is an EE
|
||||||
|
cpcp = buildCertPathConstraint(x, anchor);
|
||||||
|
} else {
|
||||||
|
cpcp = new CertPathConstraintsParameters(
|
||||||
|
x, null, anchor, null);
|
||||||
|
}
|
||||||
|
checkWeakConstraint(oneInManys(rb.getString(
|
||||||
"the.certificate"), cc,
|
"the.certificate"), cc,
|
||||||
certs.size(), pos,
|
certs.size(), pos,
|
||||||
ss.size()), x);
|
ss.size()), x, cpcp);
|
||||||
}
|
}
|
||||||
Timestamp ts = signer.getTimestamp();
|
Timestamp ts = signer.getTimestamp();
|
||||||
if (ts != null) {
|
if (ts != null) {
|
||||||
out.println(rb.getString("Timestamp."));
|
out.println(rb.getString("Timestamp."));
|
||||||
out.println();
|
out.println();
|
||||||
certs = ts.getSignerCertPath().getCertificates();
|
certs = ts.getSignerCertPath().getCertificates();
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
List<X509Certificate> tschain =
|
||||||
|
(List<X509Certificate>)certs;
|
||||||
|
anchor = findTrustAnchor(tschain);
|
||||||
cc = 0;
|
cc = 0;
|
||||||
for (Certificate cert: certs) {
|
for (Certificate cert: certs) {
|
||||||
out.printf(rb.getString("Certificate.d."), ++cc);
|
out.printf(rb.getString("Certificate.d."), ++cc);
|
||||||
|
@ -2935,10 +3036,18 @@ public final class Main {
|
||||||
printX509Cert(x, out);
|
printX509Cert(x, out);
|
||||||
}
|
}
|
||||||
out.println();
|
out.println();
|
||||||
checkWeak(oneInManys(rb.getString(
|
if (cc == 0 &&
|
||||||
|
x.getBasicConstraints() == -1) {
|
||||||
|
// this is an EE
|
||||||
|
cpcp = buildCertPathConstraint(x, anchor);
|
||||||
|
} else {
|
||||||
|
cpcp = new CertPathConstraintsParameters(
|
||||||
|
x, null, anchor, null);
|
||||||
|
}
|
||||||
|
checkWeakConstraint(oneInManys(rb.getString(
|
||||||
"the.tsa.certificate"), cc,
|
"the.tsa.certificate"), cc,
|
||||||
certs.size(), pos,
|
certs.size(), pos,
|
||||||
ss.size()), x);
|
ss.size()), x, cpcp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2968,6 +3077,9 @@ public final class Main {
|
||||||
}
|
}
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
List<X509Certificate> xcerts = (List<X509Certificate>)chain;
|
||||||
|
TrustAnchor anchor = findTrustAnchor(xcerts);
|
||||||
for (Certificate cert : chain) {
|
for (Certificate cert : chain) {
|
||||||
try {
|
try {
|
||||||
if (rfc) {
|
if (rfc) {
|
||||||
|
@ -2978,7 +3090,17 @@ public final class Main {
|
||||||
printX509Cert((X509Certificate)cert, out);
|
printX509Cert((X509Certificate)cert, out);
|
||||||
out.println();
|
out.println();
|
||||||
}
|
}
|
||||||
checkWeak(oneInMany(rb.getString("the.certificate"), i++, chain.size()), cert);
|
X509Certificate x = (X509Certificate)cert;
|
||||||
|
CertPathConstraintsParameters cpcp;
|
||||||
|
if (i == 0 && x.getBasicConstraints() == -1) {
|
||||||
|
// this is an EE
|
||||||
|
cpcp = buildCertPathConstraint(x, anchor);
|
||||||
|
} else {
|
||||||
|
cpcp = new CertPathConstraintsParameters(
|
||||||
|
x, null, anchor, null);
|
||||||
|
}
|
||||||
|
checkWeakConstraint(oneInMany(rb.getString(
|
||||||
|
"the.certificate"), i++, chain.size()), x, cpcp);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
if (debug) {
|
if (debug) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
@ -3202,8 +3324,11 @@ public final class Main {
|
||||||
throw new Exception(rb.getString("Input.not.an.X.509.certificate"));
|
throw new Exception(rb.getString("Input.not.an.X.509.certificate"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CertPathConstraintsParameters cpcp =
|
||||||
|
buildCertPathConstraint(cert, null);
|
||||||
|
|
||||||
if (noprompt) {
|
if (noprompt) {
|
||||||
checkWeak(rb.getString("the.input"), cert);
|
checkWeakConstraint(rb.getString("the.input"), cert, cpcp);
|
||||||
keyStore.setCertificateEntry(alias, cert);
|
keyStore.setCertificateEntry(alias, cert);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -3223,7 +3348,7 @@ public final class Main {
|
||||||
("Certificate.already.exists.in.keystore.under.alias.trustalias."));
|
("Certificate.already.exists.in.keystore.under.alias.trustalias."));
|
||||||
Object[] source = {trustalias};
|
Object[] source = {trustalias};
|
||||||
System.err.println(form.format(source));
|
System.err.println(form.format(source));
|
||||||
checkWeak(rb.getString("the.input"), cert);
|
checkWeakConstraint(rb.getString("the.input"), cert, cpcp);
|
||||||
printWeakWarnings(true);
|
printWeakWarnings(true);
|
||||||
reply = getYesNoReply
|
reply = getYesNoReply
|
||||||
(rb.getString("Do.you.still.want.to.add.it.no."));
|
(rb.getString("Do.you.still.want.to.add.it.no."));
|
||||||
|
@ -3234,7 +3359,7 @@ public final class Main {
|
||||||
("Certificate.already.exists.in.system.wide.CA.keystore.under.alias.trustalias."));
|
("Certificate.already.exists.in.system.wide.CA.keystore.under.alias.trustalias."));
|
||||||
Object[] source = {trustalias};
|
Object[] source = {trustalias};
|
||||||
System.err.println(form.format(source));
|
System.err.println(form.format(source));
|
||||||
checkWeak(rb.getString("the.input"), cert);
|
checkWeakConstraint(rb.getString("the.input"), cert, cpcp);
|
||||||
printWeakWarnings(true);
|
printWeakWarnings(true);
|
||||||
reply = getYesNoReply
|
reply = getYesNoReply
|
||||||
(rb.getString("Do.you.still.want.to.add.it.to.your.own.keystore.no."));
|
(rb.getString("Do.you.still.want.to.add.it.to.your.own.keystore.no."));
|
||||||
|
@ -3243,7 +3368,7 @@ public final class Main {
|
||||||
// Print the cert and ask user if they really want to add
|
// Print the cert and ask user if they really want to add
|
||||||
// it to their keystore
|
// it to their keystore
|
||||||
printX509Cert(cert, System.out);
|
printX509Cert(cert, System.out);
|
||||||
checkWeak(rb.getString("the.input"), cert);
|
checkWeakConstraint(rb.getString("the.input"), cert, cpcp);
|
||||||
printWeakWarnings(true);
|
printWeakWarnings(true);
|
||||||
reply = getYesNoReply
|
reply = getYesNoReply
|
||||||
(rb.getString("Trust.this.certificate.no."));
|
(rb.getString("Trust.this.certificate.no."));
|
||||||
|
@ -3270,7 +3395,7 @@ public final class Main {
|
||||||
// Print the cert and ask user if they really want to add it to
|
// Print the cert and ask user if they really want to add it to
|
||||||
// their keystore
|
// their keystore
|
||||||
printX509Cert(cert, System.out);
|
printX509Cert(cert, System.out);
|
||||||
checkWeak(rb.getString("the.input"), cert);
|
checkWeakConstraint(rb.getString("the.input"), cert, cpcp);
|
||||||
printWeakWarnings(true);
|
printWeakWarnings(true);
|
||||||
reply = getYesNoReply
|
reply = getYesNoReply
|
||||||
(rb.getString("Trust.this.certificate.no."));
|
(rb.getString("Trust.this.certificate.no."));
|
||||||
|
@ -3410,6 +3535,21 @@ public final class Main {
|
||||||
return keyPass;
|
return keyPass;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String withWeakConstraint(String alg,
|
||||||
|
CertPathConstraintsParameters cpcp) {
|
||||||
|
try {
|
||||||
|
DISABLED_CHECK.permits(alg, cpcp, false);
|
||||||
|
} catch (CertPathValidatorException e) {
|
||||||
|
return String.format(rb.getString("with.disabled"), alg);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
LEGACY_CHECK.permits(alg, cpcp, false);
|
||||||
|
return alg;
|
||||||
|
} catch (CertPathValidatorException e) {
|
||||||
|
return String.format(rb.getString("with.weak"), alg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private String withWeak(String alg) {
|
private String withWeak(String alg) {
|
||||||
if (DISABLED_CHECK.permits(SIG_PRIMITIVE_SET, alg, null)) {
|
if (DISABLED_CHECK.permits(SIG_PRIMITIVE_SET, alg, null)) {
|
||||||
if (LEGACY_CHECK.permits(SIG_PRIMITIVE_SET, alg, null)) {
|
if (LEGACY_CHECK.permits(SIG_PRIMITIVE_SET, alg, null)) {
|
||||||
|
@ -3436,22 +3576,25 @@ public final class Main {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String withWeak(Key key) {
|
private String withWeakConstraint(Key key,
|
||||||
|
CertPathConstraintsParameters cpcp) {
|
||||||
int kLen = KeyUtil.getKeySize(key);
|
int kLen = KeyUtil.getKeySize(key);
|
||||||
String displayAlg = fullDisplayAlgName(key);
|
String displayAlg = fullDisplayAlgName(key);
|
||||||
if (DISABLED_CHECK.permits(SIG_PRIMITIVE_SET, key)) {
|
try {
|
||||||
if (LEGACY_CHECK.permits(SIG_PRIMITIVE_SET, key)) {
|
DISABLED_CHECK.permits(key.getAlgorithm(), cpcp, true);
|
||||||
if (kLen >= 0) {
|
} catch (CertPathValidatorException e) {
|
||||||
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("key.bit.weak"), kLen, displayAlg);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return String.format(rb.getString("key.bit.disabled"), kLen, displayAlg);
|
return String.format(rb.getString("key.bit.disabled"), kLen, displayAlg);
|
||||||
}
|
}
|
||||||
|
try {
|
||||||
|
LEGACY_CHECK.permits(key.getAlgorithm(), cpcp, true);
|
||||||
|
if (kLen >= 0) {
|
||||||
|
return String.format(rb.getString("key.bit"), kLen, displayAlg);
|
||||||
|
} else {
|
||||||
|
return String.format(rb.getString("unknown.size.1"), displayAlg);
|
||||||
|
}
|
||||||
|
} catch (CertPathValidatorException e) {
|
||||||
|
return String.format(rb.getString("key.bit.weak"), kLen, displayAlg);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -3465,9 +3608,11 @@ public final class Main {
|
||||||
(rb.getString(".PATTERN.printX509Cert.with.weak"));
|
(rb.getString(".PATTERN.printX509Cert.with.weak"));
|
||||||
PublicKey pkey = cert.getPublicKey();
|
PublicKey pkey = cert.getPublicKey();
|
||||||
String sigName = cert.getSigAlgName();
|
String sigName = cert.getSigAlgName();
|
||||||
|
CertPathConstraintsParameters cpcp =
|
||||||
|
buildCertPathConstraint(cert, null);
|
||||||
// No need to warn about sigalg of a trust anchor
|
// No need to warn about sigalg of a trust anchor
|
||||||
if (!isTrustedCert(cert)) {
|
if (!isTrustedCert(cert)) {
|
||||||
sigName = withWeak(sigName);
|
sigName = withWeakConstraint(sigName, cpcp);
|
||||||
}
|
}
|
||||||
Object[] source = {cert.getSubjectX500Principal().toString(),
|
Object[] source = {cert.getSubjectX500Principal().toString(),
|
||||||
cert.getIssuerX500Principal().toString(),
|
cert.getIssuerX500Principal().toString(),
|
||||||
|
@ -3477,7 +3622,7 @@ public final class Main {
|
||||||
getCertFingerPrint("SHA-1", cert),
|
getCertFingerPrint("SHA-1", cert),
|
||||||
getCertFingerPrint("SHA-256", cert),
|
getCertFingerPrint("SHA-256", cert),
|
||||||
sigName,
|
sigName,
|
||||||
withWeak(pkey),
|
withWeakConstraint(pkey, cpcp),
|
||||||
cert.getVersion()
|
cert.getVersion()
|
||||||
};
|
};
|
||||||
out.println(form.format(source));
|
out.println(form.format(source));
|
||||||
|
@ -3801,7 +3946,7 @@ public final class Main {
|
||||||
throws Exception
|
throws Exception
|
||||||
{
|
{
|
||||||
|
|
||||||
checkWeak(rb.getString("reply"), replyCerts);
|
checkWeakConstraint(rb.getString("reply"), replyCerts);
|
||||||
|
|
||||||
// order the certs in the reply (bottom-up).
|
// order the certs in the reply (bottom-up).
|
||||||
// we know that all certs in the reply are of type X.509, because
|
// we know that all certs in the reply are of type X.509, because
|
||||||
|
@ -3883,11 +4028,14 @@ public final class Main {
|
||||||
replyCerts.length);
|
replyCerts.length);
|
||||||
tmpCerts[tmpCerts.length-1] = root.snd;
|
tmpCerts[tmpCerts.length-1] = root.snd;
|
||||||
replyCerts = tmpCerts;
|
replyCerts = tmpCerts;
|
||||||
checkWeak(String.format(fromKeyStore
|
CertPathConstraintsParameters cpcp =
|
||||||
|
buildCertPathConstraint((X509Certificate)root.snd,
|
||||||
|
null);
|
||||||
|
checkWeakConstraint(String.format(fromKeyStore
|
||||||
? rb.getString("alias.in.keystore")
|
? rb.getString("alias.in.keystore")
|
||||||
: rb.getString("alias.in.cacerts"),
|
: rb.getString("alias.in.cacerts"),
|
||||||
root.fst),
|
root.fst),
|
||||||
root.snd);
|
root.snd, cpcp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return replyCerts;
|
return replyCerts;
|
||||||
|
@ -3952,7 +4100,9 @@ public final class Main {
|
||||||
(X509Certificate) certToVerify),
|
(X509Certificate) certToVerify),
|
||||||
chain, certs)) {
|
chain, certs)) {
|
||||||
for (Pair<String,X509Certificate> p : chain) {
|
for (Pair<String,X509Certificate> p : chain) {
|
||||||
checkWeak(p.fst, p.snd);
|
CertPathConstraintsParameters cpcp =
|
||||||
|
buildCertPathConstraint(p.snd, null);
|
||||||
|
checkWeakConstraint(p.fst, p.snd, cpcp);
|
||||||
}
|
}
|
||||||
Certificate[] newChain =
|
Certificate[] newChain =
|
||||||
new Certificate[chain.size()];
|
new Certificate[chain.size()];
|
||||||
|
@ -4748,6 +4898,78 @@ public final class Main {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void checkWeakConstraint(String label, String sigAlg, Key key,
|
||||||
|
CertPathConstraintsParameters cpcp) throws Exception {
|
||||||
|
if (sigAlg != null) {
|
||||||
|
try {
|
||||||
|
DISABLED_CHECK.permits(sigAlg, cpcp, false);
|
||||||
|
try {
|
||||||
|
LEGACY_CHECK.permits(sigAlg, cpcp, false);
|
||||||
|
} catch (CertPathValidatorException e) {
|
||||||
|
weakWarnings.add(String.format(
|
||||||
|
rb.getString("whose.sigalg.weak"), label, sigAlg));
|
||||||
|
}
|
||||||
|
} catch (CertPathValidatorException e) {
|
||||||
|
String eMessage = e.getMessage();
|
||||||
|
if (eMessage.contains("denyAfter constraint check failed") &&
|
||||||
|
e.getReason() == BasicReason.ALGORITHM_CONSTRAINED) {
|
||||||
|
String startSeparator = "Constraint date: ";
|
||||||
|
int startSepPos = eMessage.indexOf(startSeparator);
|
||||||
|
String endSeparator = "; params date";
|
||||||
|
int endSepPos = eMessage.indexOf(endSeparator);
|
||||||
|
String denyAfterDate = null;
|
||||||
|
try {
|
||||||
|
denyAfterDate = eMessage.substring(startSepPos + startSeparator.length(),
|
||||||
|
endSepPos);
|
||||||
|
} catch (IndexOutOfBoundsException e1) {
|
||||||
|
throw new Exception(rb.getString(
|
||||||
|
"Unable.to.parse.denyAfter.string.in.exception.message"));
|
||||||
|
}
|
||||||
|
|
||||||
|
SimpleDateFormat formatter = new SimpleDateFormat("EEE MMM dd HH:mm:ss Z yyyy");
|
||||||
|
Date dateObj = null;
|
||||||
|
try {
|
||||||
|
dateObj = formatter.parse(denyAfterDate);
|
||||||
|
} catch (ParseException e2) {
|
||||||
|
throw new Exception(rb.getString(
|
||||||
|
"Unable.to.parse.denyAfter.string.in.exception.message"));
|
||||||
|
}
|
||||||
|
formatter = new SimpleDateFormat("yyyy-MM-dd");
|
||||||
|
denyAfterDate = formatter.format(dateObj);
|
||||||
|
|
||||||
|
weakWarnings.add(String.format(
|
||||||
|
rb.getString("whose.sigalg.usagesignedjar"), label, sigAlg,
|
||||||
|
denyAfterDate));
|
||||||
|
} else {
|
||||||
|
weakWarnings.add(String.format(
|
||||||
|
rb.getString("whose.sigalg.disabled"), label, sigAlg));
|
||||||
|
}
|
||||||
|
if (debug) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (key != null) {
|
||||||
|
try {
|
||||||
|
DISABLED_CHECK.permits(key.getAlgorithm(), cpcp, true);
|
||||||
|
try {
|
||||||
|
LEGACY_CHECK.permits(key.getAlgorithm(), cpcp, true);
|
||||||
|
} catch (CertPathValidatorException e) {
|
||||||
|
weakWarnings.add(String.format(
|
||||||
|
rb.getString("whose.key.weak"), label,
|
||||||
|
String.format(rb.getString("key.bit"),
|
||||||
|
KeyUtil.getKeySize(key), fullDisplayAlgName(key))));
|
||||||
|
}
|
||||||
|
} catch (CertPathValidatorException e) {
|
||||||
|
weakWarnings.add(String.format(
|
||||||
|
rb.getString("whose.key.disabled"), label,
|
||||||
|
String.format(rb.getString("key.bit"),
|
||||||
|
KeyUtil.getKeySize(key), fullDisplayAlgName(key))));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void checkWeak(String label, String sigAlg, Key key) {
|
private void checkWeak(String label, String sigAlg, Key key) {
|
||||||
if (sigAlg != null) {
|
if (sigAlg != null) {
|
||||||
if (!DISABLED_CHECK.permits(SIG_PRIMITIVE_SET, sigAlg, null)) {
|
if (!DISABLED_CHECK.permits(SIG_PRIMITIVE_SET, sigAlg, null)) {
|
||||||
|
@ -4774,8 +4996,11 @@ public final class Main {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkWeak(String label, Certificate[] certs)
|
private void checkWeakConstraint(String label, Certificate[] certs)
|
||||||
throws KeyStoreException {
|
throws KeyStoreException, Exception {
|
||||||
|
X509Certificate[] xcerts = convertCerts(certs);
|
||||||
|
List<X509Certificate> chain = Arrays.asList(xcerts);
|
||||||
|
TrustAnchor anchor = findTrustAnchor(chain);
|
||||||
for (int i = 0; i < certs.length; i++) {
|
for (int i = 0; i < certs.length; i++) {
|
||||||
Certificate cert = certs[i];
|
Certificate cert = certs[i];
|
||||||
if (cert instanceof X509Certificate) {
|
if (cert instanceof X509Certificate) {
|
||||||
|
@ -4784,23 +5009,43 @@ public final class Main {
|
||||||
if (certs.length > 1) {
|
if (certs.length > 1) {
|
||||||
fullLabel = oneInMany(label, i, certs.length);
|
fullLabel = oneInMany(label, i, certs.length);
|
||||||
}
|
}
|
||||||
checkWeak(fullLabel, xc);
|
|
||||||
|
CertPathConstraintsParameters cpcp = null;
|
||||||
|
if (i == 0 && xc.getBasicConstraints() == -1) {
|
||||||
|
// this is an EE
|
||||||
|
cpcp = buildCertPathConstraint(xc, anchor);
|
||||||
|
} else {
|
||||||
|
cpcp = new CertPathConstraintsParameters(
|
||||||
|
xc, null, anchor, null);
|
||||||
|
}
|
||||||
|
checkWeakConstraint(fullLabel, xc, cpcp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkWeak(String label, Certificate cert)
|
private void checkWeakConstraint(String label, Certificate cert,
|
||||||
throws KeyStoreException {
|
CertPathConstraintsParameters cpcp)
|
||||||
|
throws KeyStoreException, Exception {
|
||||||
if (cert instanceof X509Certificate) {
|
if (cert instanceof X509Certificate) {
|
||||||
X509Certificate xc = (X509Certificate)cert;
|
X509Certificate xc = (X509Certificate)cert;
|
||||||
// No need to check the sigalg of a trust anchor
|
// No need to check the sigalg of a trust anchor
|
||||||
String sigAlg = isTrustedCert(cert) ? null : xc.getSigAlgName();
|
String sigAlg = isTrustedCert(cert) ? null : xc.getSigAlgName();
|
||||||
checkWeak(label, sigAlg, xc.getPublicKey());
|
checkWeakConstraint(label, sigAlg, xc.getPublicKey(), cpcp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkWeak(String label, PKCS10 p10) {
|
private void checkWeakConstraint(String label, PKCS10 p10,
|
||||||
checkWeak(label, p10.getSigAlg(), p10.getSubjectPublicKeyInfo());
|
CertPathConstraintsParameters cpcp) throws Exception {
|
||||||
|
checkWeakConstraint(label, p10.getSigAlg(),
|
||||||
|
p10.getSubjectPublicKeyInfo(), cpcp);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkWeakConstraint(String label, CRL crl, Key key,
|
||||||
|
CertPathConstraintsParameters cpcp) throws Exception {
|
||||||
|
if (crl instanceof X509CRLImpl) {
|
||||||
|
X509CRLImpl impl = (X509CRLImpl)crl;
|
||||||
|
checkWeakConstraint(label, impl.getSigAlgName(), key, cpcp);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkWeak(String label, CRL crl, Key key) {
|
private void checkWeak(String label, CRL crl, Key key) {
|
||||||
|
@ -4810,6 +5055,76 @@ public final class Main {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private KeyStore buildTrustedCerts() {
|
||||||
|
KeyStore caks = null;
|
||||||
|
try {
|
||||||
|
caks = KeyStoreUtil.getCacertsKeyStore();
|
||||||
|
if (caks != null) {
|
||||||
|
Enumeration<String> aliases = caks.aliases();
|
||||||
|
while (aliases.hasMoreElements()) {
|
||||||
|
String a = aliases.nextElement();
|
||||||
|
try {
|
||||||
|
trustedCerts.add((X509Certificate)caks.getCertificate(a));
|
||||||
|
} catch (Exception e2) {
|
||||||
|
// ignore, if the keystore has not been loaded/initialized properly
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
// Ignore, if cacerts cannot be loaded
|
||||||
|
}
|
||||||
|
return caks;
|
||||||
|
}
|
||||||
|
|
||||||
|
private TrustAnchor findTrustAnchor(List<X509Certificate> chain) {
|
||||||
|
if (chain.isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
private X509Certificate[] convertCerts(Certificate[] certs) {
|
||||||
|
X509Certificate[] xcerts = new X509Certificate[certs.length];
|
||||||
|
|
||||||
|
for (int i = 0; i < certs.length; i++) {
|
||||||
|
if (certs[i] instanceof X509Certificate) {
|
||||||
|
xcerts[i] = (X509Certificate) certs[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return xcerts;
|
||||||
|
}
|
||||||
|
|
||||||
|
private CertPathConstraintsParameters buildCertPathConstraint(
|
||||||
|
X509Certificate xcert, TrustAnchor anchor) throws Exception{
|
||||||
|
List<String> eku = xcert.getExtendedKeyUsage();
|
||||||
|
if (eku == null) {
|
||||||
|
return new CertPathConstraintsParameters(xcert, null,
|
||||||
|
anchor, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (eku.contains(KnownOIDs.codeSigning.value())) {
|
||||||
|
return new CertPathConstraintsParameters(xcert,
|
||||||
|
Validator.VAR_CODE_SIGNING, anchor, null);
|
||||||
|
} else if (eku.contains(KnownOIDs.clientAuth.value())) {
|
||||||
|
return new CertPathConstraintsParameters(xcert,
|
||||||
|
Validator.VAR_TLS_CLIENT, anchor, null);
|
||||||
|
} else if (eku.contains(KnownOIDs.serverAuth.value())) {
|
||||||
|
return new CertPathConstraintsParameters(xcert,
|
||||||
|
Validator.VAR_TLS_SERVER, anchor, null);
|
||||||
|
} else if (eku.contains(KnownOIDs.KP_TimeStamping.value())) {
|
||||||
|
return new CertPathConstraintsParameters(xcert,
|
||||||
|
Validator.VAR_TSA_SERVER, anchor, null);
|
||||||
|
}
|
||||||
|
return new CertPathConstraintsParameters(xcert, Validator.VAR_GENERIC,
|
||||||
|
anchor, null);
|
||||||
|
}
|
||||||
|
|
||||||
private void printWeakWarnings(boolean newLine) {
|
private void printWeakWarnings(boolean newLine) {
|
||||||
if (!weakWarnings.isEmpty() && !nowarn) {
|
if (!weakWarnings.isEmpty() && !nowarn) {
|
||||||
System.err.println("\nWarning:");
|
System.err.println("\nWarning:");
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2000, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -483,6 +483,8 @@ public class Resources extends java.util.ListResourceBundle {
|
||||||
"Subject: %1$s\nFormat: %2$s\nPublic Key: %3$s\nSignature algorithm: %4$s\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"},
|
{"verified.by.s.in.s.weak", "Verified by %1$s in %2$s with a %3$s"},
|
||||||
{"whose.sigalg.disabled", "%1$s uses the %2$s signature algorithm which is considered a security risk and is disabled."},
|
{"whose.sigalg.disabled", "%1$s uses the %2$s signature algorithm which is considered a security risk and is disabled."},
|
||||||
|
{"whose.sigalg.usagesignedjar", "%1$s uses the %2$s signature algorithm which is considered a security risk and cannot be used to sign JARs after %3$s."},
|
||||||
|
{"Unable.to.parse.denyAfter.string.in.exception.message", "Unable to parse denyAfter date string in exception message"},
|
||||||
{"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.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.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."},
|
{"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."},
|
||||||
|
|
60
test/jdk/sun/security/tools/keytool/TestSha1Usage.java
Normal file
60
test/jdk/sun/security/tools/keytool/TestSha1Usage.java
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022, 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
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @test
|
||||||
|
* @bug 8273236
|
||||||
|
* @summary Test SHA1 usage SignedJAR
|
||||||
|
* @library /test/lib
|
||||||
|
*/
|
||||||
|
|
||||||
|
import jdk.test.lib.SecurityTools;
|
||||||
|
import jdk.test.lib.process.OutputAnalyzer;
|
||||||
|
|
||||||
|
public class TestSha1Usage {
|
||||||
|
|
||||||
|
static OutputAnalyzer kt(String cmd, String ks) throws Exception {
|
||||||
|
return SecurityTools.keytool("-storepass changeit " + cmd +
|
||||||
|
" -keystore " + ks);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
|
||||||
|
SecurityTools.keytool("-keystore ks -storepass changeit " +
|
||||||
|
"-genkeypair -keyalg rsa -alias ca -dname CN=CA " +
|
||||||
|
"-ext eku=codeSigning -sigalg SHA1withRSA")
|
||||||
|
.shouldContain("Warning:")
|
||||||
|
.shouldMatch("The generated certificate.*SHA1withRSA.*considered a security risk")
|
||||||
|
.shouldMatch("cannot be used to sign JARs")
|
||||||
|
.shouldHaveExitValue(0);
|
||||||
|
|
||||||
|
kt("-genkeypair -keyalg rsa -alias e1 -dname CN=E1", "ks");
|
||||||
|
kt("-certreq -alias e1 -file tmp.req", "ks");
|
||||||
|
SecurityTools.keytool("-keystore ks -storepass changeit " +
|
||||||
|
"-gencert -alias ca -infile tmp.req -outfile tmp.cert")
|
||||||
|
.shouldContain("Warning:")
|
||||||
|
.shouldMatch("The issuer.*SHA1withRSA.*considered a security risk")
|
||||||
|
.shouldMatch("cannot be used to sign JARs")
|
||||||
|
.shouldHaveExitValue(0);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue