JDK-8129988 introduces a new behavior when reading the javax.net.ssl.trustStore property.

Alvarez, David alvdavi at amazon.com
Fri Aug 9 19:52:15 UTC 2019


We have detected that JDK-8219988 [1], that has been included in OpenJDK 8u222
included a non-documented change in the behavior of the
javax.net.ssl.trustStore property. In previous versions, should this property
point to a non-existent file, an empty KeyStore would be used instead. [2]

In newer versions, if the value of the property contains an invalid URL, the
code will instead fall back and use the lib/security/cacerts file. [3]

However, there are two things about that change that caught our attention:
- Whenever there is no javax.net.ssl.trustStore property set, the code will
first look for lib/security/jssecacerts. If that file does not exist, then it
will look for lib/security/cacerts. However, when the property is set to an
invalid file, the fallback mechanism jumps directly to lib/security/cacerts,
never checking lib/security/jssecacerts.

- This fallback mechanism for invalid javax.net.ssl.trustStore values reuses the
value of javax.net.ssl.trustStorePassword. If that property is set in
conjunction with an invalid value in javax.net.ssl.trustStore the specified
password will be used when attempting to read the lib/security/cacerts store.
It seems unclear why this path of action is chosen here.

If the lib/security/cacerts has no password (and as far as I'm aware, that is
the case in the majority of OpenJDK distributions, if not all), the operation
will raise an exception. This exception mentions that 'Password verification
failed', hiding the underlying cause (the property pointing to a bad store).[4]

Although the new behavior isn't necessarily wrong, I think there is room for
Improvement. Suggestions:

- Make sure lib/security/jssecacerts is checked during the fallback process.
- Ignore the value of javax.net.ssl.trustStorePassword when we fallback to use
the bundled jssecacerts or cacerts file.
- Change the exception message to avoid confusion.

I would like to have your opinion on this.


[1] https://bugs.openjdk.java.net/browse/JDK-8129988
[2] http://hg.openjdk.java.net/jdk8u/jdk8u/jdk/file/ac2ef877d3e8/src/share/classes/sun/security/ssl/TrustManagerFactoryImpl.java#l132
[3] http://hg.openjdk.java.net/jdk8u/jdk8u/jdk/file/2a9bea6e5e03/src/share/classes/sun/security/ssl/TrustStoreManager.java#l128
[4] Here is a copy of the exception:
Caused by: java.io.IOException: Keystore was tampered with, or password was incorrect
    at sun.security.provider.JavaKeyStore.engineLoad(JavaKeyStore.java:785)
    at sun.security.provider.JavaKeyStore$JKS.engineLoad(JavaKeyStore.java:56)
    at sun.security.provider.KeyStoreDelegator.engineLoad(KeyStoreDelegator.java:224)
    at sun.security.provider.JavaKeyStore$DualFormatJKS.engineLoad(JavaKeyStore.java:70)
    at java.security.KeyStore.load(KeyStore.java:1445)
    at sun.security.ssl.TrustStoreManager$TrustAnchorManager.loadKeyStore(TrustStoreManager.java:367)
    at sun.security.ssl.TrustStoreManager$TrustAnchorManager.getTrustedCerts(TrustStoreManager.java:315)
    at sun.security.ssl.TrustStoreManager.getTrustedCerts(TrustStoreManager.java:59)
    at sun.security.ssl.TrustManagerFactoryImpl.engineInit(TrustManagerFactoryImpl.java:51)
Caused by: java.security.UnrecoverableKeyException: Password verification failed
    at sun.security.provider.JavaKeyStore.engineLoad(JavaKeyStore.java:783)

More information about the jdk8u-dev mailing list