apple.security.KeychainStore does not load private key (when called from javaws)

Sean Mullan sean.mullan at oracle.com
Tue Aug 5 19:47:50 UTC 2014


On 08/04/2014 11:10 AM, Florian Bruckner (3kraft) wrote:
> Hey guys,
>
> any feedback/comments on this?

This seems like a reasonable change to me. In order to proceed with 
accepting your patch, you will first need to sign an OCA. See step 0 of 
http://openjdk.java.net/contribute/

Thanks,
Sean

>
> Just to summarize again:
>
> KeychainStore does not load private keys when not called with a
> passphrase. This is the case in various deployment scenarios (like
> javaws), as a consequence identity certificates stored in Apple Keychain
> are not available (i.e. being offered for selection like on Windows).
>
> The reason for this is the implementation of KeychainStore, which uses
> this API to retrieve a PKCS#12 container from apple keychain:
>
> https://developer.apple.com/library/mac/documentation/security/Reference/keychainservices/Reference/reference.html#jumpTo_63
>
>
> The API documentation says the PKCS#12 keystore being generated with
> this call 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 is to create a dummy password for this use case.
>
> 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
>



More information about the security-dev mailing list