--- a/jdk/src/java.base/share/classes/sun/security/pkcs12/PKCS12KeyStore.java Thu Dec 18 10:45:45 2014 -0800
+++ b/jdk/src/java.base/share/classes/sun/security/pkcs12/PKCS12KeyStore.java Fri Dec 19 14:48:56 2014 -0800
@@ -716,6 +716,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;
@@ -1490,7 +1495,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;
}
@@ -2070,7 +2080,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())) {