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

Andrew John Hughes gnu.andrew at redhat.com
Mon Aug 12 14:09:22 UTC 2019

Forwarding to security-dev as this was backported from later JDK versions:

On 09/08/2019 20:52, Alvarez, David wrote:
> Hello,
> 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.
> Thanks,
> David
> --
> [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)
Andrew :)

Senior Free Java Software Engineer
Red Hat, Inc. (http://www.redhat.com)

PGP Key: ed25519/0xCFDA0F9B35964222 (hkp://keys.gnupg.net)
Fingerprint = 5132 579D D154 0ED2 3E04  C5A0 CFDA 0F9B 3596 4222

More information about the jdk8u-dev mailing list