< prev index next >

src/share/classes/sun/security/provider/certpath/RevocationChecker.java

Print this page

        

@@ -1,7 +1,7 @@
 /*
- * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 only, as
  * published by the Free Software Foundation.  Oracle designates this

@@ -41,11 +41,10 @@
 import java.util.*;
 import javax.security.auth.x500.X500Principal;
 
 import static sun.security.provider.certpath.OCSP.*;
 import static sun.security.provider.certpath.PKIX.*;
-import sun.security.action.GetPropertyAction;
 import sun.security.x509.*;
 import static sun.security.x509.PKIXExtensions.*;
 import sun.security.util.Debug;
 
 class RevocationChecker extends PKIXRevocationChecker {

@@ -60,16 +59,16 @@
     private URI responderURI;
     private X509Certificate responderCert;
     private List<CertStore> certStores;
     private Map<X509Certificate, byte[]> ocspResponses;
     private List<Extension> ocspExtensions;
-    private boolean legacy;
+    private final boolean legacy;
     private LinkedList<CertPathValidatorException> softFailExceptions =
         new LinkedList<>();
 
     // state variables
-    private X509Certificate issuerCert;
+    private OCSPResponse.IssuerInfo issuerInfo;
     private PublicKey prevPubKey;
     private boolean crlSignFlag;
     private int certIndex;
 
     private enum Mode { PREFER_OCSP, PREFER_CRLS, ONLY_CRLS, ONLY_OCSP };

@@ -300,13 +299,13 @@
         if (forward) {
             throw new
                 CertPathValidatorException("forward checking not supported");
         }
         if (anchor != null) {
-            issuerCert = anchor.getTrustedCert();
-            prevPubKey = (issuerCert != null) ? issuerCert.getPublicKey()
-                                              : anchor.getCAPublicKey();
+            issuerInfo = new OCSPResponse.IssuerInfo(anchor);
+            prevPubKey = issuerInfo.getPublicKey();
+
         }
         crlSignFlag = true;
         if (params != null && params.certPath() != null) {
             certIndex = params.certPath().getCertificates().size() - 1;
         } else {

@@ -436,11 +435,11 @@
     }
 
     private void updateState(X509Certificate cert)
         throws CertPathValidatorException
     {
-        issuerCert = cert;
+        issuerInfo = new OCSPResponse.IssuerInfo(anchor, cert);
 
         // Make new public key if parameters are missing
         PublicKey pubKey = cert.getPublicKey();
         if (PKIX.isDSAPublicKeyWithoutParams(pubKey)) {
             // pubKey needs to inherit DSA parameters from prev key

@@ -464,10 +463,38 @@
     {
         checkCRLs(cert, pubKey, null, signFlag, true,
                   stackedCerts, params.trustAnchors());
     }
 
+    static boolean isCausedByNetworkIssue(String type, CertStoreException cse) {
+        boolean result;
+        Throwable t = cse.getCause();
+
+        switch (type) {
+            case "LDAP":
+                if (t != null) {
+                    // These two exception classes are inside java.naming module
+                    String cn = t.getClass().getName();
+                    result = (cn.equals("javax.naming.ServiceUnavailableException") ||
+                        cn.equals("javax.naming.CommunicationException"));
+                } else {
+                    result = false;
+                }
+                break;
+            case "SSLServer":
+                result = (t != null && t instanceof IOException);
+                break;
+            case "URI":
+                result = (t != null && t instanceof IOException);
+                break;
+            default:
+                // we don't know about any other remote CertStore types
+                return false;
+        }
+        return result;
+    }
+
     private void checkCRLs(X509Certificate cert, PublicKey prevKey,
                            X509Certificate prevCert, boolean signFlag,
                            boolean allowSeparateKey,
                            Set<X509Certificate> stackedCerts,
                            Set<TrustAnchor> anchors)

@@ -476,13 +503,13 @@
         if (debug != null) {
             debug.println("RevocationChecker.checkCRLs()" +
                           " ---checking revocation status ...");
         }
 
-        // reject circular dependencies - RFC 3280 is not explicit on how
-        // to handle this, so we feel it is safest to reject them until
-        // the issue is resolved in the PKIX WG.
+        // Reject circular dependencies - RFC 5280 is not explicit on how
+        // to handle this, but does suggest that they can be a security
+        // risk and can create unresolvable dependencies
         if (stackedCerts != null && stackedCerts.contains(cert)) {
             if (debug != null) {
                 debug.println("RevocationChecker.checkCRLs()" +
                               " circular dependency");
             }

@@ -508,11 +535,11 @@
                 if (debug != null) {
                     debug.println("RevocationChecker.checkCRLs() " +
                                   "CertStoreException: " + e.getMessage());
                 }
                 if (networkFailureException == null &&
-                    CertStoreHelper.isCausedByNetworkIssue(store.getType(),e)) {
+                    isCausedByNetworkIssue(store.getType(),e)) {
                     // save this exception, we may need to throw it later
                     networkFailureException = new CertPathValidatorException(
                         "Unable to determine revocation status due to " +
                         "network error", e, null, -1,
                         BasicReason.UNDETERMINED_REVOCATION_STATUS);

@@ -549,18 +576,17 @@
             // all CRLs returned by the DP Fetcher have also been verified
             try {
                 if (crlDP) {
                     approvedCRLs.addAll(DistributionPointFetcher.getCRLs(
                                         sel, signFlag, prevKey, prevCert,
-                                        params.sigProvider(), certStores,
-                                        reasonsMask, anchors, null));
+                            params.sigProvider(), certStores, reasonsMask,
+                            anchors, null, params.variant()));
                 }
             } catch (CertStoreException e) {
                 if (e instanceof CertStoreTypeException) {
                     CertStoreTypeException cste = (CertStoreTypeException)e;
-                    if (CertStoreHelper.isCausedByNetworkIssue(cste.getType(),
-                                                               e)) {
+                    if (isCausedByNetworkIssue(cste.getType(), e)) {
                         throw new CertPathValidatorException(
                             "Unable to determine revocation status due to " +
                             "network error", e, null, -1,
                             BasicReason.UNDETERMINED_REVOCATION_STATUS);
                     }

@@ -632,11 +658,11 @@
                 }
 
                 /*
                  * Abort CRL validation and throw exception if there are any
                  * unrecognized critical CRL entry extensions (see section
-                 * 5.3 of RFC 3280).
+                 * 5.3 of RFC 5280).
                  */
                 Set<String> unresCritExts = entry.getCriticalExtensionOIDs();
                 if (unresCritExts != null && !unresCritExts.isEmpty()) {
                     /* remove any that we will process */
                     unresCritExts.remove(ReasonCode_Id.toString());

@@ -680,18 +706,12 @@
         // checked when the responder's certificate is validated.
 
         OCSPResponse response = null;
         CertId certId = null;
         try {
-            if (issuerCert != null) {
-                certId = new CertId(issuerCert,
+            certId = new CertId(issuerInfo.getName(), issuerInfo.getPublicKey(),
                                     currCert.getSerialNumberObject());
-            } else {
-                // must be an anchor name and key
-                certId = new CertId(anchor.getCA(), anchor.getCAPublicKey(),
-                                    currCert.getSerialNumberObject());
-            }
 
             // check if there is a cached OCSP response available
             byte[] responseBytes = ocspResponses.get(cert);
             if (responseBytes != null) {
                 if (debug != null) {

@@ -704,12 +724,12 @@
                 for (Extension ext : ocspExtensions) {
                     if (ext.getId().equals("1.3.6.1.5.5.7.48.1.2")) {
                         nonce = ext.getValue();
                     }
                 }
-                response.verify(Collections.singletonList(certId), issuerCert,
-                                responderCert, params.date(), nonce);
+                response.verify(Collections.singletonList(certId), issuerInfo,
+                        responderCert, params.date(), nonce, params.variant());
 
             } else {
                 URI responderURI = (this.responderURI != null)
                                    ? this.responderURI
                                    : OCSP.getResponderURI(currCert);

@@ -718,12 +738,12 @@
                         "Certificate does not specify OCSP responder", null,
                         null, -1);
                 }
 
                 response = OCSP.check(Collections.singletonList(certId),
-                                      responderURI, issuerCert, responderCert,
-                                      null, ocspExtensions);
+                        responderURI, issuerInfo, responderCert, null,
+                        ocspExtensions, params.variant());
             }
         } catch (IOException e) {
             throw new CertPathValidatorException(
                 "Unable to determine revocation status due to network error",
                 e, null, -1, BasicReason.UNDETERMINED_REVOCATION_STATUS);

@@ -831,11 +851,11 @@
             for (DistributionPoint point : points) {
                 for (X509CRL crl : crls) {
                     if (DistributionPointFetcher.verifyCRL(
                             certImpl, point, crl, reasonsMask, signFlag,
                             prevKey, null, params.sigProvider(), anchors,
-                            certStores, params.date()))
+                            certStores, params.date(), params.variant()))
                     {
                         results.add(crl);
                     }
                 }
                 if (Arrays.equals(reasonsMask, ALL_REASONS))

@@ -884,13 +904,13 @@
             debug.println(
                 "RevocationChecker.verifyWithSeparateSigningKey()" +
                 " ---checking " + msg + "...");
         }
 
-        // reject circular dependencies - RFC 3280 is not explicit on how
-        // to handle this, so we feel it is safest to reject them until
-        // the issue is resolved in the PKIX WG.
+        // Reject circular dependencies - RFC 5280 is not explicit on how
+        // to handle this, but does suggest that they can be a security
+        // risk and can create unresolvable dependencies
         if ((stackedCerts != null) && stackedCerts.contains(cert)) {
             if (debug != null) {
                 debug.println(
                     "RevocationChecker.verifyWithSeparateSigningKey()" +
                     " circular dependency");
< prev index next >