changeset 10616:21256885aaef

8066479: Better certificate chain validation Reviewed-by: mullan
author juh
date Fri, 19 Dec 2014 15:39:47 -0800
parents d02988beec6a
children 9505c0392cdd
files src/share/classes/sun/security/pkcs12/PKCS12KeyStore.java
diffstat 1 files changed, 28 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/sun/security/pkcs12/PKCS12KeyStore.java	Thu Dec 18 11:19:12 2014 -0800
+++ b/src/share/classes/sun/security/pkcs12/PKCS12KeyStore.java	Fri Dec 19 15:39:47 2014 -0800
@@ -707,6 +707,11 @@
 
         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;
 
@@ -1448,7 +1453,12 @@
             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<Certificate> set = new HashSet<>(Arrays.asList(certChain));
+        return set.size() == certChain.length;
     }
 
 
@@ -2022,7 +2032,24 @@
                 ArrayList<X509Certificate> chain =
                                 new ArrayList<X509Certificate>();
                 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())) {