1and1 / CompositeJKS

Load a custom Java Keystore into the SSL Context without replacing the system CA list.
MIT License
30 stars 9 forks source link

SslContextUtils methods fail when the indicated KeyStore contains PrivateKeyEntry objects #1

Open criege opened 8 years ago

criege commented 8 years ago

I haven't tested this extensively yet but in a nutshell, lets assume there is a KeyStore holding two entries, one of type PrivateKeyEntry and the other of trustedCertEntry. Additionally the store is protected by a password.

Retrieving the KeyStore by calling one of the methods on KeyStoreLoader that takes a password everything works as expected.

However once trying to call SslContextUtils.buildMergedWithSystem(KeyStore) the method fails due to a missing password – namely the password of the PrivateKeyEntry (which happens to be different from the store password). Here's the stack:

Exception in thread "main" java.security.UnrecoverableKeyException: Cannot recover key
    at sun.security.provider.KeyProtector.recover(KeyProtector.java:328)
    at sun.security.provider.JavaKeyStore.engineGetKey(JavaKeyStore.java:146)
    at sun.security.provider.JavaKeyStore$JKS.engineGetKey(JavaKeyStore.java:56)
    at sun.security.provider.KeyStoreDelegator.engineGetKey(KeyStoreDelegator.java:96)
    at sun.security.provider.JavaKeyStore$DualFormatJKS.engineGetKey(JavaKeyStore.java:70)
    at java.security.KeyStore.getKey(KeyStore.java:1023)
    at sun.security.ssl.SunX509KeyManagerImpl.<init>(SunX509KeyManagerImpl.java:133)
    at sun.security.ssl.KeyManagerFactoryImpl$SunX509.engineInit(KeyManagerFactoryImpl.java:70)
    at javax.net.ssl.KeyManagerFactory.init(KeyManagerFactory.java:256)
    at com.oneandone.compositejks.SslContextUtils.getSystemKeyManager(SslContextUtils.java:86)

I've fixed this locally by not using CompositeX509KeyManager but just the default system key manager. But I'm not sure if this is to your intention :). If you want I'll make a PR …

bastianeicher commented 8 years ago

Thanks for the feedback. :)

Just to clarify: Your code falls back to the default system key manager specifically when the passphrase is missing? Sure, a pull request would be great. Perhaps I could later add an overload for buildMergedWithSystem() that takes a passphrase.