JDK-8194307 : KeyStore#getInstance with custom LoadStoreParameter succeeds with invalid password
  • Type: Bug
  • Component: security-libs
  • Sub-Component: java.security
  • Affected Version: 9,10
  • Priority: P2
  • Status: Closed
  • Resolution: Fixed
  • Submitted: 2018-01-02
  • Updated: 2018-07-16
  • Resolved: 2018-01-19
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 10 JDK 11
10 b41Fixed 11Fixed
Related Reports
Relates :  
Relates :  
Relates :  
KeyStore#getInstance(File, LoadStoreParameter) method still does not throw IOException with  the  custom LoadStoreParameter that has a PasswordProtection with a  wrong password.

Please see the simple ���ready-to-run��� test case that I tested with JDK 10 b36 which still does not throw IOException with custom LoadStoreParameter when given a wrong password.

Please place the java file and the jck_keystore.pkcs12 keystore in a directory, go to the directory , compile the java file and
���	Run  ���java -cp . KeyStoreCustomLoadParamBug . load���    it will not throw IOException
���	Run ���java -cp . KeyStoreCustomLoadParamBug . noload��� it will throw IOException

Test case throws ���IOException��� without a LoadStoreParameter as expected however it does not throw IOException with custom LoadStoreParameter

It is verified by running the attached test (KeyStoreCustomLoadParamBug) with JDK 10 build 41.

Fix request approved for JDK 10.

Here is what is happening at a high level: 1. KeyStore.getInstance(File, LoadStoreParameter) is called with a PKCS12 KeyStore file and a custom LoadStoreParameter that encapsulates the password in a PasswordProtection object. 2. KeyStore.getInstance(File, LoadStoreParameter) opens the file and passes the stream to a PKCS12 KeyStoreSpi.engineProbe and it returns true. 3. KeyStore.getInstance(File, LoadStoreParameter) calls KeyStore.load(LoadStoreParameter) which calls KeyStoreSpi.engineLoad(LoadStoreParameter) 4. The PKCS12 KeyStore does not override KeyStoreSpi.engineLoad(LoadStoreParameter), so the default implementation of KeyStoreSpi.engineLoad(LoadStoreParameter) is used, which extracts the password from the LoadStoreParameter and then calls engineLoad(InputStream, char[]) with a *null* InputStream. 5. The PKCS12 implementation of engineLoad(InputStream, char[]) is invoked. It immediately returns when it sees that the InputStream is null as it assumes a new KeyStore is being created. Thus, it is technically working as expected, but it doesn't make sense. A PKCS12 KeyStore does not support LoadStoreParameter, but the default implementation of KeyStoreSpi.engineLoad(LoadStoreParameter) causes it to work, just not as expected. Ideally, there should be a KeyStore.load(InputStream, LoadStoreParameter) method so that file-based KeyStore implementations can support LoadStoreParameters, but we can fix this by extracting the password from the LoadStoreParameter and passing it to the existing load(InputStream, char[]) method.

Fix Request This is a tck-red bug so it is important to fix this for 10 is released. The fix is very low risk, and it contains a small amount of code changes. An existing regression test has been updated to include new tests for this issue and there is also the current tck test. Weijun Wang and Vincent Ryan have reviewed this fix. The webrev is: http://cr.openjdk.java.net/~mullan/webrevs/8194307/webrev.00/

Note that even though the KeyStore instantiation succeeds with an invalid password, you can't see anything, there are 0 entries. This is because it (incorrectly) assumes you are trying to create a brand new keystore with the invalid password as the new password.