JDK-8134708 : Certpath validation fails to load certs and CRLs if AIA and CRLDP extensions point to LDAP resources
  • Type: Bug
  • Component: security-libs
  • Sub-Component: java.security
  • Affected Version: 9
  • Priority: P2
  • Status: Closed
  • Resolution: Fixed
  • Submitted: 2015-08-28
  • Updated: 2016-08-24
  • Resolved: 2015-09-09
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 Availability Release.

To download the current JDK release, click here.
JDK 9
9 b82Fixed
Related Reports
Relates :  
Description
Certpath validation fails with the following error (with -Djava.security.debug=certpath):

certpath: LDAPCertStore.engineGetCertificates() basicConstraints: 0
certpath: LDAPCertStore.engineGetCertificates()  subject is not null
certpath: LDAPCertStore.engineGetCertificates() after getMatchingCrossCerts(subject,xsel,null),certs.size(): 0
certpath: LDAPCertStore.engineGetCertificates() after getCertificates(subject,CA_CERT,xsel),certs.size(): 0
certpath: LDAPCertStore.engineGetCertificates() about to getMatchingCrossCerts...
certpath: LDAPCertStore.engineGetCertificates() returning certs
certpath: CertStore URI:ldap://betty.nist.gov/dc=BasicLDAPURISubSubCA7,dc=testcertificates,dc=gov?cACertificate;binary,crossCertificatePair;binary
certpath: exception creating CertStore: java.security.InvalidAlgorithmParameterException: parameters must be either LDAPCertStoreParameters or URICertStoreParameters
java.security.InvalidAlgorithmParameterException: parameters must be either LDAPCertStoreParameters or URICertStoreParameters
        at sun.security.provider.certpath.ldap.LDAPCertStore.<init>(LDAPCertStore.java:139)
        at sun.security.provider.certpath.ldap.JdkLDAP$ProviderService.newInstance(JdkLDAP.java:61)
        at sun.security.jca.GetInstance.getInstance(GetInstance.java:243)
        at sun.security.jca.GetInstance.getInstance(GetInstance.java:190)
        at java.security.cert.CertStore.getInstance(CertStore.java:228)
        at sun.security.provider.certpath.URICertStore.<init>(URICertStore.java:168)
        at sun.security.provider.certpath.URICertStore.getInstance(URICertStore.java:190)
        at sun.security.provider.certpath.URICertStore.getInstance(URICertStore.java:216)
        at sun.security.provider.certpath.ForwardBuilder.getCerts(ForwardBuilder.java:376)
        at sun.security.provider.certpath.ForwardBuilder.getMatchingCACerts(ForwardBuilder.java:345)
        at sun.security.provider.certpath.ForwardBuilder.getMatchingCerts(ForwardBuilder.java:133)
        at sun.security.provider.certpath.SunCertPathBuilder.depthFirstSearchForward(SunCertPathBuilder.java:263)
        at sun.security.provider.certpath.SunCertPathBuilder.depthFirstSearchForward(SunCertPathBuilder.java:527)
        at sun.security.provider.certpath.SunCertPathBuilder.buildForward(SunCertPathBuilder.java:225)
        at sun.security.provider.certpath.SunCertPathBuilder.buildCertPath(SunCertPathBuilder.java:160)
        at sun.security.provider.certpath.SunCertPathBuilder.build(SunCertPathBuilder.java:131)
        at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:126)
        at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:280)
        at TestSuite.runTest(TestSuite.java:530)
        at TestSuite.main(TestSuite.java:507)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:504)
        at com.sun.javatest.regtest.agent.MainWrapper$MainThread.run(MainWrapper.java:92)
        at java.lang.Thread.run(Thread.java:746)

This happens because LDAPCertStore accepts only LDAPCertStoreParameters and URICertStoreParameters:

http://hg.openjdk.java.net/jdk9/dev/jdk/file/facea01d6b68/src/java.naming/share/classes/sun/security/provider/certpath/ldap/LDAPCertStore.java#l113

...
        if (params instanceof LDAPCertStoreParameters) {
            ...
        } else if (params instanceof URICertStoreParameters) {
            ...
        } else {
            throw new InvalidAlgorithmParameterException(
                "parameters must be either LDAPCertStoreParameters or " +
                "URICertStoreParameters");
        }
...

But sun.security.provider.certpath.URICertStore uses an inner static URICertStoreParameters class:

http://hg.openjdk.java.net/jdk9/dev/jdk/file/facea01d6b68/src/java.base/share/classes/sun/security/provider/certpath/URICertStore.java#l214

...
        try {
            return URICertStore.getInstance
                (new URICertStore.URICertStoreParameters(uri));
        } catch (Exception ex) {
            if (debug != null) {
                debug.println("exception creating CertStore: " + ex);
                ex.printStackTrace();
            }
            return null;
        }
... 

The same thing with DistributionPointFetcher:

http://hg.openjdk.java.net/jdk9/dev/jdk/file/facea01d6b68/src/java.base/share/classes/sun/security/provider/certpath/DistributionPointFetcher.java#l235

...
        try {
            ucs = URICertStore.getInstance
                (new URICertStore.URICertStoreParameters(uri));
        } catch (InvalidAlgorithmParameterException |
                 NoSuchAlgorithmException e) {
            if (debug != null) {
                debug.println("Can't create URICertStore: " + e.getMessage());
            }
            return null;
        }
...

As a result, certs and CRLs can't be loaded over LDAP. This may be considered as a regression of JDK-8038084 that introduced public java.security.cert.URICertStoreParameters, but URICertStore and DistributionPointFetcher still use URICertStore.URICertStoreParameters.

Test cases 4.1.2.18 and 4.1.2.19 from NIST Discovery Test Suite [1] fail due to this problem because certs have links to LDAP stores in AIA and CRLDP extensions. These test cases pass with JDK 9 b64 which doesn't have JDK-8038084.

I suppose URICertStore.URICertStoreParameters class is not needed anymore. This issue may be fixed by updating URICertStore and DistributionPointFetcher to use new java.security.cert.URICertStoreParameters:

http://cr.openjdk.java.net/~asmotrak/8134708/webrev.00/

[1] http://csrc.nist.gov/groups/ST/crypto_apps_infra/documents/PathDiscoveryTestSuite.pdf
Comments
Code review: http://mail.openjdk.java.net/pipermail/security-dev/2015-September/012742.html
01-09-2015