Added security-dev. With best regards. Petr.
> On Jul 29, 2014, at 12:36 PM, Florian Bruckner (3kraft) > <florian.bruck...@3kraft.com> wrote: > > Hey guys, > > any feedback on this? > > What is the process to have a patch like this accepted? > > regards, > > Florian > > On 15.07.14 10:56, Florian Bruckner (3kraft) wrote: >> To answer my own question: >> >> KeychainStore loads the private key through native code in KeystoreImpl.m. >> KeystoreImpl.m uses this osx API to retrieve a PKCS#12 bag: >> >> https://developer.apple.com/library/mac/documentation/security/Reference/keychainservices/Reference/reference.html#jumpTo_63 >> >> >> The API documentation says the PKCS#12 keystore requires a password. This is >> either supplied by the caller or the user is prompted (if a flag is set, >> which is not the case). >> >> KeychainStore then goes on to extract the private key from the returned >> PKCS#12 store and decrypts it with the password. >> >> Therefore, the password passed into engineGetKey is actually used to encrypt >> and decrypt only in the scope of this method. Therefore, the approach to >> create a dummy password for this use case is not as weird as I initially >> thought. >> >> Please consider these patches to fix this issue: >> >> For jdk7u-dev: >> >> diff -r 35aabd00a534 src/macosx/classes/apple/security/KeychainStore.java >> --- a/src/macosx/classes/apple/security/KeychainStore.java Tue Jul 15 >> 02:26:55 2014 +0400 >> +++ b/src/macosx/classes/apple/security/KeychainStore.java Tue Jul 15 >> 10:52:44 2014 +0200 >> @@ -134,7 +134,7 @@ >> * password to recover it. >> * >> * @param alias the alias name >> - * @param password the password for recovering the key >> + * @param password the password for recovering the key. This password >> is not used to access the private key in KeyChain, it is used internally >> only. >> * >> * @return the requested key, or null if the given alias does not exist >> * or does not identify a <i>key entry</i>. >> @@ -148,6 +148,16 @@ >> throws NoSuchAlgorithmException, UnrecoverableKeyException >> { >> permissionCheck(); >> + // An empty password is rejected by MacOS API, no private key data >> + // is exported. If no password is passed (as is the case when >> + // this implementation is used as browser keystore in various >> + // deployment scenarios like webstart, JFX and applets), create >> + // a dummy password to MacOS API is happy. >> + if (password == null || password.length ==0) { >> + // Must not be a char array with only a 0, as this is an empty >> + // string. Therefore use a single character. >> + password = new char[]{'A'} >> + } >> >> Object entry = entries.get(alias.toLowerCase()); >> >> >> >> For jdk8u-dev: >> >> diff -r baec3649f6c0 src/macosx/classes/apple/security/KeychainStore.java >> --- a/src/macosx/classes/apple/security/KeychainStore.java Tue Jul 15 >> 02:00:52 2014 +0400 >> +++ b/src/macosx/classes/apple/security/KeychainStore.java Tue Jul 15 >> 10:54:45 2014 +0200 >> @@ -140,7 +140,7 @@ >> * password to recover it. >> * >> * @param alias the alias name >> - * @param password the password for recovering the key >> + * @param password the password for recovering the key. This password >> is not used to access the private key in KeyChain, it is used internally >> only. >> * >> * @return the requested key, or null if the given alias does not exist >> * or does not identify a <i>key entry</i>. >> @@ -154,7 +154,16 @@ >> throws NoSuchAlgorithmException, UnrecoverableKeyException >> { >> permissionCheck(); >> - >> + // An empty password is rejected by MacOS API, no private key data >> + // is exported. If no password is passed (as is the case when >> + // this implementation is used as browser keystore in various >> + // deployment scenarios like webstart, JFX and applets), create >> + // a dummy password to MacOS API is happy. >> + if (password == null || password.length ==0) { >> + // Must not be a char array with only a 0, as this is an empty >> + // string. Therefore use a single character. >> + password = new char[]{'A'} >> + } >> Object entry = entries.get(alias.toLowerCase()); >> >> if (entry == null || !(entry instanceof KeyEntry)) { >> >> >> With best regards, >> >> Florian >> >