aboutsummaryrefslogtreecommitdiff
path: root/src/share/classes/sun/security/validator/PKIXValidator.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/share/classes/sun/security/validator/PKIXValidator.java')
-rw-r--r--src/share/classes/sun/security/validator/PKIXValidator.java45
1 files changed, 32 insertions, 13 deletions
diff --git a/src/share/classes/sun/security/validator/PKIXValidator.java b/src/share/classes/sun/security/validator/PKIXValidator.java
index 8068a9db8..59daa9eef 100644
--- a/src/share/classes/sun/security/validator/PKIXValidator.java
+++ b/src/share/classes/sun/security/validator/PKIXValidator.java
@@ -53,7 +53,7 @@ public final class PKIXValidator extends Validator {
private int certPathLength = -1;
// needed only for the validator
- private Map<X500Principal, X509Certificate> trustedSubjects;
+ private Map<X500Principal, List<PublicKey>> trustedSubjects;
private CertificateFactory factory;
private boolean plugin = false;
@@ -95,9 +95,17 @@ public final class PKIXValidator extends Validator {
if (TRY_VALIDATOR == false) {
return;
}
- trustedSubjects = new HashMap<X500Principal, X509Certificate>();
+ trustedSubjects = new HashMap<X500Principal, List<PublicKey>>();
for (X509Certificate cert : trustedCerts) {
- trustedSubjects.put(cert.getSubjectX500Principal(), cert);
+ X500Principal dn = cert.getSubjectX500Principal();
+ List<PublicKey> keys;
+ if (trustedSubjects.containsKey(dn)) {
+ keys = trustedSubjects.get(dn);
+ } else {
+ keys = new ArrayList<PublicKey>();
+ trustedSubjects.put(dn, keys);
+ }
+ keys.add(cert.getPublicKey());
}
try {
factory = CertificateFactory.getInstance("X.509");
@@ -161,13 +169,21 @@ public final class PKIXValidator extends Validator {
// chain is not ordered correctly, call builder instead
return doBuild(chain, otherCerts);
}
- if (trustedSubjects.containsKey(dn)
- && trustedSubjects.get(dn).getPublicKey()
- .equals(cert.getPublicKey())) {
+
+ // Check if chain[i] is already trusted. It may be inside
+ // trustedCerts, or has the same dn and public key as a cert
+ // inside trustedCerts. The latter happens when a CA has
+ // updated its cert with a stronger signature algorithm in JRE
+ // but the weak one is still in circulation.
+
+ if (trustedCerts.contains(cert) || // trusted cert
+ (trustedSubjects.containsKey(dn) && // replacing ...
+ trustedSubjects.get(dn).contains( // ... weak cert
+ cert.getPublicKey()))) {
if (i == 0) {
return new X509Certificate[] {chain[0]};
}
- // Remove and call validator
+ // Remove and call validator on partial chain [0 .. i-1]
X509Certificate[] newChain = new X509Certificate[i];
System.arraycopy(chain, 0, newChain, 0, i);
return doValidate(newChain);
@@ -217,14 +233,17 @@ public final class PKIXValidator extends Validator {
return doBuild(chain, otherCerts);
}
- private boolean isSignatureValid(X509Certificate iss, X509Certificate sub) {
+ private boolean isSignatureValid(List<PublicKey> keys, X509Certificate sub) {
if (plugin) {
- try {
- sub.verify(iss.getPublicKey());
- } catch (Exception ex) {
- return false;
+ for (PublicKey key: keys) {
+ try {
+ sub.verify(key);
+ return true;
+ } catch (Exception ex) {
+ continue;
+ }
}
- return true;
+ return false;
}
return true; // only check if PLUGIN is set
}