JDK-8015571 : OCSP validation fails if ocsp.responderCertSubjectName is set
  • Type: Bug
  • Component: security-libs
  • Sub-Component: java.security
  • Affected Version: 7,8
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2013-03-15
  • Updated: 2015-12-04
  • Resolved: 2013-11-19
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availabitlity Release.

To download the current JDK release, click here.
JDK 6 JDK 8
6u95Fixed 8 b119Fixed
Related Reports
Duplicate :  
Relates :  
Relates :  
Description
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.
Comments
Release team: Approved for fixing
2013-11-19

We also need this fix in order to approve a new root CA request from IdenTrust. We currently can't check revocation using their OCSP server due to a bug that this will fix.
2013-11-15

SQE is ok with this fix going to JDK 8.
2013-11-15

Need additional SQE tests
2013-05-29