8066479: Better certificate chain validation

Reviewed-by: mullan
This commit is contained in:
Jason Uh 2014-12-19 14:48:56 -08:00
parent c60792dc47
commit dca06c50cb

View File

@ -716,6 +716,11 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
entry.protectedPrivKey = key.clone(); entry.protectedPrivKey = key.clone();
if (chain != null) { if (chain != null) {
// validate cert-chain
if ((chain.length > 1) && (!validateChain(chain))) {
throw new KeyStoreException("Certificate chain is "
+ "not valid");
}
entry.chain = chain.clone(); entry.chain = chain.clone();
certificateCount += chain.length; certificateCount += chain.length;
@ -1490,7 +1495,12 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
if (!(issuerDN.equals(subjectDN))) if (!(issuerDN.equals(subjectDN)))
return false; return false;
} }
return true;
// Check for loops in the chain. If there are repeated certs,
// the Set of certs in the chain will contain fewer certs than
// the chain
Set<Certificate> set = new HashSet<>(Arrays.asList(certChain));
return set.size() == certChain.length;
} }
@ -2070,7 +2080,24 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
ArrayList<X509Certificate> chain = ArrayList<X509Certificate> chain =
new ArrayList<X509Certificate>(); new ArrayList<X509Certificate>();
X509Certificate cert = findMatchedCertificate(entry); X509Certificate cert = findMatchedCertificate(entry);
mainloop:
while (cert != null) { while (cert != null) {
// Check for loops in the certificate chain
if (!chain.isEmpty()) {
for (X509Certificate chainCert : chain) {
if (cert.equals(chainCert)) {
if (debug != null) {
debug.println("Loop detected in " +
"certificate chain. Skip adding " +
"repeated cert to chain. Subject: " +
cert.getSubjectX500Principal()
.toString());
}
break mainloop;
}
}
}
chain.add(cert); chain.add(cert);
X500Principal issuerDN = cert.getIssuerX500Principal(); X500Principal issuerDN = cert.getIssuerX500Principal();
if (issuerDN.equals(cert.getSubjectX500Principal())) { if (issuerDN.equals(cert.getSubjectX500Principal())) {