From dca06c50cb5a99f50923011cfe68e072a38564cf Mon Sep 17 00:00:00 2001 From: Jason Uh Date: Fri, 19 Dec 2014 14:48:56 -0800 Subject: [PATCH] 8066479: Better certificate chain validation Reviewed-by: mullan --- .../sun/security/pkcs12/PKCS12KeyStore.java | 29 ++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/jdk/src/java.base/share/classes/sun/security/pkcs12/PKCS12KeyStore.java b/jdk/src/java.base/share/classes/sun/security/pkcs12/PKCS12KeyStore.java index 354a644e37e..1f52015392c 100644 --- a/jdk/src/java.base/share/classes/sun/security/pkcs12/PKCS12KeyStore.java +++ b/jdk/src/java.base/share/classes/sun/security/pkcs12/PKCS12KeyStore.java @@ -716,6 +716,11 @@ public final class PKCS12KeyStore extends KeyStoreSpi { entry.protectedPrivKey = key.clone(); if (chain != null) { + // validate cert-chain + if ((chain.length > 1) && (!validateChain(chain))) { + throw new KeyStoreException("Certificate chain is " + + "not valid"); + } entry.chain = chain.clone(); certificateCount += chain.length; @@ -1490,7 +1495,12 @@ public final class PKCS12KeyStore extends KeyStoreSpi { if (!(issuerDN.equals(subjectDN))) 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 set = new HashSet<>(Arrays.asList(certChain)); + return set.size() == certChain.length; } @@ -2070,7 +2080,24 @@ public final class PKCS12KeyStore extends KeyStoreSpi { ArrayList chain = new ArrayList(); X509Certificate cert = findMatchedCertificate(entry); + + mainloop: 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); X500Principal issuerDN = cert.getIssuerX500Principal(); if (issuerDN.equals(cert.getSubjectX500Principal())) {