JDK-8016557 : Cannot set certificates for an OCSP responder
  • Type: Bug
  • Component: security-libs
  • Sub-Component: java.security
  • Affected Version: 7u5
  • Priority: P3
  • Status: Closed
  • Resolution: Duplicate
  • Submitted: 2013-04-04
  • Updated: 2014-11-17
  • Resolved: 2014-05-02
Related Reports
Duplicate :  
Description
FULL PRODUCT VERSION :
java version  " 1.7.0_05 " 
Java(TM) SE Runtime Environment (build 1.7.0_05-b05)
Java HotSpot(TM) 64-Bit Server VM (build 23.1-b03, mixed mode)


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 :
An OCSP responder is validating two different types of certificates (certificates issued by the same authority the OCSP responder belongs to, and certificates issued by a partner CA). The responses are signed the following way:

-> If the certificate to check is issued by the same CA, the response is signed by the same CA that issued the certificate.
-> If the certificate is from the partner CA it is signed by another certificate (OCSP certificate) issued by the partner CA.

It's impossible to use PKIX to validate both types of certificate at the same time. If  " ocsp.responderCertSubjectName "  is set with the special certificate only partner certificates are validated, if the option is not set only local certificates are validated. The error in both cases is  " java.security.cert.CertPathValidatorException: Responder's certificate is not authorized to sign OCSP responses " .

Checking wikipedia I think the OCSP responder behavior is valid (a responder can sign certificates from another CA, delegation).

The simple way of fixing this issue is always accepting the sign of the issuer and just use the responderCertSubjectName in case another certificate is used. Obviously it not covers all the possible cases but it is more reasonable to always accept the default option.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Sorry but there is no access to the OCSP server from the outside.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
PKIX should support OCSP protocol completely.
ACTUAL -
Just one of the two types of certificate can be validated (not both at the same time).

ERROR MESSAGES/STACK TRACES THAT OCCUR :
Exception in thread  " main "  java.security.cert.CertPathValidatorException: Responder's certificate is not authorized to sign OCSP responses
at sun.security.provider.certpath.PKIXMasterCertPathValidator.validate(PKIXMasterCertPathValidator.java:159)
at sun.security.provider.certpath.PKIXCertPathValidator.doValidate(PKIXCertPathValidator.java:351)
at sun.security.provider.certpath.PKIXCertPathValidator.engineValidate(PKIXCertPathValidator.java:191)
at java.security.cert.CertPathValidator.validate(CertPathValidator.java:279)
at CertificateChecker.main(CertificateChecker.java:44)


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 != 3) {
      throw new IllegalArgumentException( " Usage: java CertificateChecker <cert_file> <trusted_ca.jks> <trusted_ca_password> " );
    }
    String certFile = args[0];
    String cacertsFile = args[1];
    String cacertsPassword = args[2];
    // set security options to ocsp validation
    Security.setProperty( " ocsp.enable " ,  " true " );
    System.setProperty( " com.sun.security.enableCRLDP " ,  " false " );
    Security.setProperty( " ocsp.responderURL " ,  " http://xxxxxxx:80 " );
    //Security.setProperty( " ocsp.responderCertSubjectName " ,  "  " );
    // 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 ----------