Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8015571

OCSP validation fails if ocsp.responderCertSubjectName is set

XMLWordPrintable

        FULL PRODUCT VERSION :
        $ java -version
        java version " 1.6.0_24 "
        OpenJDK Runtime Environment (IcedTea6 1.11.5) (6b24-1.11.5-1)
        OpenJDK 64-Bit Server VM (build 20.0-b12, mixed mode)

        It also happens with Sun JVM 6 and 7.

        ADDITIONAL OS VERSION INFORMATION :
        Linux 3.2.0-4-amd64 #1 SMP Debian 3.2.35-2 x86_64 GNU/Linux

        A DESCRIPTION OF THE PROBLEM :
        When a OCSP responder mixes the certificate used to sign responses Java has no valid way of configuring the JVM in order to work with all the responses.

        If the responder signs responses using two strategies:

        1.- Some responses are signed by the same certificate that issued the certificate that is being check.
        2.- Other responses are signed with a fixed certificate (the requester should trust on it).

        The JVM doesn't cover this situation, if ocsp.responderCertSubjectName (or any other property that specifies the certificate of the responder) is set only case 2 is executed successfully. If the property is not set only case 1 works.

        The exceptions shown are the following:

        java.security.cert.CertPathValidatorException: Error verifying OCSP Responder's signature
         java.security.cert.CertPathValidatorException: Responder's certificate not valid for signing OCSP responses

        I am not absolutely sure if rfc2560 covers that situation but I think an OCSP with the commented behaviour is standard. Please see this link for more information:

        http://blogs.nologin.es/rickyepoderi/index.php?/archives/77-BUG-in-Java-OCSP-Implementation-PKIX.html

        NOTE: I opened a BUG before but I have not yet understand the problem completely, forget it and sorry

        STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
        You have a detailed explanation and a tentative patch here:

        http://blogs.nologin.es/rickyepoderi/index.php?/archives/77-BUG-in-Java-OCSP-Implementation-PKIX.html

        I tested it using openssl ocsp implementation.

        EXPECTED VERSUS ACTUAL BEHAVIOR :
        EXPECTED -
        I expected that Java could be configured in such a way that it can validate certificates against an OCSP which mixes the three scenarios the RFC explains:

         " All definitive response messages SHALL be digitally signed. The key used to sign the response MUST belong to one of the following:
         * the CA who issued the certificate in question
         * a Trusted Responder whose public key is trusted by the requester
         * a CA Designated Responder (Authorized Responder) who holds a specially marked certificate issued directly by the CA, indicating that the responder may issue OCSP responses for that CA "

        ERROR MESSAGES/STACK TRACES THAT OCCUR :
        * When ocsp.responderCertSubjectName is set but the response is signed by the issuer:

        java.security.cert.CertPathValidatorException: Error verifying OCSP Responder's signature

        * When ocsp.responderCertSubjectName is not set but the response is signed by the a specific certificate:
         
         java.security.cert.CertPathValidatorException: Responder's certificate not valid for signing OCSP responses

        REPRODUCIBILITY :
        This bug can be reproduced always.

        ---------- BEGIN SOURCE ----------
        import java.util.List;
        import java.util.ArrayList;
        import java.io.FileInputStream;
        import java.security.Security;
        import java.security.KeyStore;
        import java.security.cert.X509Certificate;
        import java.security.cert.CertificateFactory;
        import java.security.cert.CertPath;
        import java.security.cert.CertPathValidator;
        import java.security.cert.PKIXCertPathValidatorResult;
        import java.security.cert.PKIXParameters;

        public class CertificateChecker {

          public static void main(String[] args) throws Exception {
            if (args.length != 4 && args.length != 5) {
              throw new IllegalArgumentException( " Usage: java CertificateChecker <cert_file> <trusted_ca.jks> <trusted_ca_password> <responder_url> {responder_cert_dn} " );
            }
            String certFile = args[0];
            String cacertsFile = args[1];
            String cacertsPassword = args[2];
            String responderUrl = args[3];
            // set security options to ocsp validation
            Security.setProperty( " ocsp.enable " , " true " );
            System.setProperty( " com.sun.security.enableCRLDP " , " false " );
            Security.setProperty( " ocsp.responderURL " , responderUrl);
            if (args.length == 5) {
              Security.setProperty( " ocsp.responderCertSubjectName " , args[4]);
            }
            // read the certificate from the file
            System.out.println( " Loading certificate... " );
            FileInputStream is = new FileInputStream(certFile);
            CertificateFactory cf = CertificateFactory.getInstance( " X.509 " );
            X509Certificate cert = (X509Certificate) cf.generateCertificate(is);
            // read the cacerts keystore to check signature
            System.out.println( " Loading cacerts... " );
            KeyStore cacerts = KeyStore.getInstance(KeyStore.getDefaultType());
            cacerts.load(new FileInputStream(cacertsFile), cacertsPassword.toCharArray());
            // check the certpath with PKIX
            List<X509Certificate> certs = new ArrayList<X509Certificate>();
            certs.add(cert);
            CertPath certPath = cf.generateCertPath(certs);
            CertPathValidator cpv = CertPathValidator.getInstance( " PKIX " );
            PKIXParameters params = new PKIXParameters(cacerts);
            //params.setRevocationEnabled(false);
            System.out.println( " Performing PKIX validation... " );
            PKIXCertPathValidatorResult cpvResult =
              (PKIXCertPathValidatorResult) cpv.validate(certPath, params);
            System.out.println( " Result: OK " );
          }

        }

        ---------- END SOURCE ----------

        CUSTOMER SUBMITTED WORKAROUND :
        There's no workaround, you cannot cover both types of responses at the same time.

              vinnie Vincent Ryan
              webbuggrp Webbug Group
              Votes:
              0 Vote for this issue
              Watchers:
              15 Start watching this issue

                Created:
                Updated:
                Resolved: