JDK-6899503 : Security code issue using Verisign root certificate
  • Type: Bug
  • Component: security-libs
  • Sub-Component: java.security
  • Affected Version: 5.0u22
  • Priority: P2
  • Status: Resolved
  • Resolution: Fixed
  • OS: linux
  • CPU: x86
  • Submitted: 2009-11-09
  • Updated: 2015-03-11
  • Resolved: 2009-11-30
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.
Other Other JDK 6 JDK 7
5.0u22-rev b07Fixed 5.0u23Fixed 6u18Fixed 7Fixed
Description
This bug reproduces on Linux (with 6u17 and 5u22), with the attached testcase (TestHttps.java). In order to reproduce this
problem, simply add attached vercert.cer to the cacerts for the JRE you are using as follows :

keytool -import -file vercert.cer -keystore cacerts 

The default keystore password is changeit. Then simply run the attached testcase.

Running the test case will result in :

javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path validation failed: java.security.cert.CertPathValidatorException: basic constraints check failed: pathLenConstraint violated - this cert must be the last cert in the certification path
       at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:174)
       at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1592)
       at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:187)
       at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:181)
       at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1044)
       at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:127)
       at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Handshaker.java:516)
       at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Handshaker.java:454)
       at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:884)
       at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1096)
       at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1123)
       at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1107)
       at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:415)
       at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:166)
       at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1049)
       at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:234)
       at TestHttps.main(TestHttps.java:18)
Caused by: sun.security.validator.ValidatorException: PKIX path validation failed: java.security.cert.CertPathValidatorException: basic constraints check failed: pathLenConstraint violated - this cert must be the last cert in the certification path
       at sun.security.validator.PKIXValidator.doValidate(PKIXValidator.java:251)
       at sun.security.validator.PKIXValidator.doValidate(PKIXValidator.java:234)
       at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:158)
       at sun.security.validator.Validator.validate(Validator.java:218)
       at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:126)
       at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:209)
       at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:249)
       at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1023)
       ... 12 more
Caused by: java.security.cert.CertPathValidatorException: basic constraints check failed: pathLenConstraint violated - this cert must be the last cert in the certification path
       at sun.security.provider.certpath.PKIXMasterCertPathValidator.validate(PKIXMasterCertPathValidator.java:139)
       at sun.security.provider.certpath.PKIXCertPathValidator.doValidate(PKIXCertPathValidator.java:328)        at sun.security.provider.certpath.PKIXCertPathValidator.engineValidate(PKIXCertPathValidator.java:178)
       at java.security.cert.CertPathValidator.validate(CertPathValidator.java:250)
       at sun.security.validator.PKIXValidator.doValidate(PKIXValidator.java:246)


If we remove this cert from the Java keystore, then validation succeeds and everything works fine.

Comments
SUGGESTED FIX $ sccs diffs src/share/classes/sun/security/validator/PKIXValidator.java ------- PKIXValidator.java ------- 4c4 < * Copyright 2004 Sun Microsystems, Inc. All rights reserved. --- > * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 121c121,123 < // check if chain contains trust anchor --- > // check that chain is in correct order and check if chain contains > // trust anchor > X500Principal prevIssuer = null; 123c125,131 < if (trustedCerts.contains(chain[i])) { --- > X509Certificate cert = chain[i]; > if (i != 0 && > !cert.getSubjectX500Principal().equals(prevIssuer)) { > // chain is not ordered correctly, call builder instead > return doBuild(chain, otherCerts); > } > if (trustedCerts.contains(cert)) { 131a140 > prevIssuer = cert.getIssuerX500Principal();225d233 225d233 <
18-11-2009

EVALUATION Technically, it isn't a bug, since VeriSign is sending an out-of-order TLS cert chain, however every browser I tested is able to fix the order, validate the chain, and make a secure connection, so we should do likewise.
18-11-2009