mirror of
https://github.com/openjdk/jdk.git
synced 2026-05-12 22:50:08 +00:00
8172529: Use PKIXValidator in jarsigner
Reviewed-by: xuelei, mullan, alanb
This commit is contained in:
parent
842350c666
commit
f82a7d2bdd
@ -290,6 +290,8 @@ module java.base {
|
||||
jdk.crypto.token,
|
||||
jdk.jartool,
|
||||
jdk.security.auth;
|
||||
exports sun.security.validator to
|
||||
jdk.jartool;
|
||||
exports sun.text.resources to
|
||||
jdk.localedata;
|
||||
exports sun.util.cldr to
|
||||
|
||||
@ -26,6 +26,8 @@
|
||||
package sun.security.tools.jarsigner;
|
||||
|
||||
import java.io.*;
|
||||
import java.security.cert.CertPathValidatorException;
|
||||
import java.security.cert.PKIXBuilderParameters;
|
||||
import java.util.*;
|
||||
import java.util.zip.*;
|
||||
import java.util.jar.*;
|
||||
@ -40,11 +42,9 @@ import java.security.*;
|
||||
import java.net.SocketTimeoutException;
|
||||
import java.net.URL;
|
||||
import java.security.cert.CertPath;
|
||||
import java.security.cert.CertPathValidator;
|
||||
import java.security.cert.CertificateExpiredException;
|
||||
import java.security.cert.CertificateFactory;
|
||||
import java.security.cert.CertificateNotYetValidException;
|
||||
import java.security.cert.PKIXParameters;
|
||||
import java.security.cert.TrustAnchor;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
@ -54,6 +54,8 @@ import sun.security.pkcs.PKCS7;
|
||||
import sun.security.pkcs.SignerInfo;
|
||||
import sun.security.timestamp.TimestampToken;
|
||||
import sun.security.tools.KeyStoreUtil;
|
||||
import sun.security.validator.Validator;
|
||||
import sun.security.validator.ValidatorException;
|
||||
import sun.security.x509.*;
|
||||
import sun.security.util.*;
|
||||
|
||||
@ -177,9 +179,7 @@ public class Main {
|
||||
|
||||
private boolean seeWeak = false;
|
||||
|
||||
CertificateFactory certificateFactory;
|
||||
CertPathValidator validator;
|
||||
PKIXParameters pkixParameters;
|
||||
PKIXBuilderParameters pkixParameters;
|
||||
|
||||
public void run(String args[]) {
|
||||
try {
|
||||
@ -1623,19 +1623,10 @@ public class Main {
|
||||
try {
|
||||
validateCertChain(certs);
|
||||
} catch (Exception e) {
|
||||
if (debug) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (e.getCause() != null &&
|
||||
(e.getCause() instanceof CertificateExpiredException ||
|
||||
e.getCause() instanceof CertificateNotYetValidException)) {
|
||||
// No more warning, we alreay have hasExpiredCert or notYetValidCert
|
||||
} else {
|
||||
chainNotValidated = true;
|
||||
chainNotValidatedReason = e;
|
||||
sb.append(tab).append(rb.getString(".CertPath.not.validated."))
|
||||
.append(e.getLocalizedMessage()).append("]\n"); // TODO
|
||||
}
|
||||
chainNotValidated = true;
|
||||
chainNotValidatedReason = e;
|
||||
sb.append(tab).append(rb.getString(".CertPath.not.validated."))
|
||||
.append(e.getLocalizedMessage()).append("]\n"); // TODO
|
||||
}
|
||||
if (certs.size() == 1
|
||||
&& KeyStoreUtil.isSelfSigned((X509Certificate)certs.get(0))) {
|
||||
@ -1654,9 +1645,6 @@ public class Main {
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
certificateFactory = CertificateFactory.getInstance("X.509");
|
||||
validator = CertPathValidator.getInstance("PKIX");
|
||||
Set<TrustAnchor> tas = new HashSet<>();
|
||||
try {
|
||||
KeyStore caks = KeyStoreUtil.getCacertsKeyStore();
|
||||
@ -1732,7 +1720,7 @@ public class Main {
|
||||
}
|
||||
} finally {
|
||||
try {
|
||||
pkixParameters = new PKIXParameters(tas);
|
||||
pkixParameters = new PKIXBuilderParameters(tas, null);
|
||||
pkixParameters.setRevocationEnabled(false);
|
||||
} catch (InvalidAlgorithmParameterException ex) {
|
||||
// Only if tas is empty
|
||||
@ -1899,17 +1887,8 @@ public class Main {
|
||||
try {
|
||||
validateCertChain(Arrays.asList(certChain));
|
||||
} catch (Exception e) {
|
||||
if (debug) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (e.getCause() != null &&
|
||||
(e.getCause() instanceof CertificateExpiredException ||
|
||||
e.getCause() instanceof CertificateNotYetValidException)) {
|
||||
// No more warning, we already have hasExpiredCert or notYetValidCert
|
||||
} else {
|
||||
chainNotValidated = true;
|
||||
chainNotValidatedReason = e;
|
||||
}
|
||||
chainNotValidated = true;
|
||||
chainNotValidatedReason = e;
|
||||
}
|
||||
|
||||
if (KeyStoreUtil.isSelfSigned(certChain[0])) {
|
||||
@ -1966,18 +1945,40 @@ public class Main {
|
||||
}
|
||||
|
||||
void validateCertChain(List<? extends Certificate> certs) throws Exception {
|
||||
int cpLen = 0;
|
||||
out: for (; cpLen<certs.size(); cpLen++) {
|
||||
for (TrustAnchor ta: pkixParameters.getTrustAnchors()) {
|
||||
if (ta.getTrustedCert().equals(certs.get(cpLen))) {
|
||||
break out;
|
||||
try {
|
||||
Validator.getInstance(Validator.TYPE_PKIX,
|
||||
Validator.VAR_CODE_SIGNING,
|
||||
pkixParameters)
|
||||
.validate(certs.toArray(new X509Certificate[certs.size()]));
|
||||
} catch (Exception e) {
|
||||
if (debug) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (e instanceof ValidatorException) {
|
||||
// Throw cause if it's CertPathValidatorException,
|
||||
if (e.getCause() != null &&
|
||||
e.getCause() instanceof CertPathValidatorException) {
|
||||
e = (Exception) e.getCause();
|
||||
Throwable t = e.getCause();
|
||||
if ((t instanceof CertificateExpiredException &&
|
||||
hasExpiredCert) ||
|
||||
(t instanceof CertificateNotYetValidException &&
|
||||
notYetValidCert)) {
|
||||
// we already have hasExpiredCert and notYetValidCert
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (e instanceof ValidatorException) {
|
||||
ValidatorException ve = (ValidatorException)e;
|
||||
if (ve.getErrorType() == ValidatorException.T_EE_EXTENSIONS &&
|
||||
(badKeyUsage || badExtendedKeyUsage || badNetscapeCertType)) {
|
||||
// We already have badKeyUsage, badExtendedKeyUsage
|
||||
// and badNetscapeCertType
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (cpLen > 0) {
|
||||
CertPath cp = certificateFactory.generateCertPath(
|
||||
(cpLen == certs.size())? certs: certs.subList(0, cpLen));
|
||||
validator.validate(cp, pkixParameters);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -22,7 +22,7 @@
|
||||
#
|
||||
|
||||
# @test
|
||||
# @bug 6802846
|
||||
# @bug 6802846 8172529
|
||||
# @summary jarsigner needs enhanced cert validation(options)
|
||||
#
|
||||
# @run shell/timeout=240 concise_jarsigner.sh
|
||||
@ -52,7 +52,7 @@ TESTTOOLVMOPTS="$TESTTOOLVMOPTS -J-Duser.language=en -J-Duser.country=US"
|
||||
KS=js.ks
|
||||
KT="$TESTJAVA${FS}bin${FS}keytool ${TESTTOOLVMOPTS} -storepass changeit -keypass changeit -keystore $KS -keyalg rsa -keysize 1024"
|
||||
JAR="$TESTJAVA${FS}bin${FS}jar ${TESTTOOLVMOPTS}"
|
||||
JARSIGNER="$TESTJAVA${FS}bin${FS}jarsigner ${TESTTOOLVMOPTS}"
|
||||
JARSIGNER="$TESTJAVA${FS}bin${FS}jarsigner ${TESTTOOLVMOPTS} -debug"
|
||||
JAVAC="$TESTJAVA${FS}bin${FS}javac ${TESTTOOLVMOPTS} ${TESTJAVACOPTS}"
|
||||
|
||||
rm $KS
|
||||
@ -138,7 +138,7 @@ LINES=`$JARSIGNER -verify a.jar -verbose:summary -certs | grep "more)" | wc -l`
|
||||
[ $LINES = 4 ] || exit $LINENO
|
||||
|
||||
# ==========================================================
|
||||
# Second part: exit code 2, 4, 8
|
||||
# Second part: exit code 2, 4, 8.
|
||||
# 16 and 32 already covered in the first part
|
||||
# ==========================================================
|
||||
|
||||
@ -174,11 +174,14 @@ $JARSIGNER -strict -keystore $KS -storepass changeit a.jar goodku
|
||||
$JARSIGNER -strict -keystore $KS -storepass changeit a.jar goodeku
|
||||
[ $? = 0 ] || exit $LINENO
|
||||
|
||||
# badchain signed by ca, but ca is removed later
|
||||
# badchain signed by ca1, but ca1 is removed later
|
||||
$KT -genkeypair -alias badchain -dname CN=badchain -validity 365
|
||||
$KT -certreq -alias badchain | $KT -gencert -alias ca -validity 365 | \
|
||||
$KT -genkeypair -alias ca1 -dname CN=ca1 -ext bc -validity 365
|
||||
$KT -certreq -alias badchain | $KT -gencert -alias ca1 -validity 365 | \
|
||||
$KT -importcert -alias badchain
|
||||
$KT -delete -alias ca
|
||||
# save ca1.cert for easy replay
|
||||
$KT -exportcert -file ca1.cert -alias ca1
|
||||
$KT -delete -alias ca1
|
||||
|
||||
$JARSIGNER -strict -keystore $KS -storepass changeit a.jar badchain
|
||||
[ $? = 4 ] || exit $LINENO
|
||||
@ -204,13 +207,41 @@ $JARSIGNER -strict -keystore $KS -storepass changeit a.jar altchain
|
||||
$JARSIGNER -strict -keystore $KS -storepass changeit -certchain certchain a.jar altchain
|
||||
[ $? = 0 ] || exit $LINENO
|
||||
|
||||
# but if ca2 is removed, -certchain does not work
|
||||
# if ca2 is removed, -certchain still work because altchain is a self-signed entry and
|
||||
# it is trusted by jarsigner
|
||||
# save ca2.cert for easy replay
|
||||
$KT -exportcert -file ca2.cert -alias ca2
|
||||
$KT -delete -alias ca2
|
||||
$JARSIGNER -strict -keystore $KS -storepass changeit -certchain certchain a.jar altchain
|
||||
[ $? = 0 ] || exit $LINENO
|
||||
|
||||
# if cert is imported, -certchain won't work because this certificate entry is not trusted
|
||||
$KT -importcert -file certchain -alias altchain -noprompt
|
||||
$JARSIGNER -strict -keystore $KS -storepass changeit -certchain certchain a.jar altchain
|
||||
[ $? = 4 ] || exit $LINENO
|
||||
|
||||
$JARSIGNER -verify a.jar
|
||||
[ $? = 0 ] || exit $LINENO
|
||||
|
||||
# ==========================================================
|
||||
# 8172529
|
||||
# ==========================================================
|
||||
|
||||
$KT -genkeypair -alias ee -dname CN=ee
|
||||
$KT -genkeypair -alias caone -dname CN=caone
|
||||
$KT -genkeypair -alias catwo -dname CN=catwo
|
||||
|
||||
$KT -certreq -alias ee | $KT -gencert -alias catwo -rfc > ee.cert
|
||||
$KT -certreq -alias catwo | $KT -gencert -alias caone -sigalg MD5withRSA -rfc > catwo.cert
|
||||
|
||||
# This certchain contains a cross-signed weak catwo.cert
|
||||
cat ee.cert catwo.cert | $KT -importcert -alias ee
|
||||
|
||||
$JAR cvf a.jar A1.class
|
||||
$JARSIGNER -strict -keystore $KS -storepass changeit a.jar ee
|
||||
[ $? = 0 ] || exit $LINENO
|
||||
$JARSIGNER -strict -keystore $KS -storepass changeit -verify a.jar
|
||||
[ $? = 0 ] || exit $LINENO
|
||||
|
||||
echo OK
|
||||
exit 0
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user