SunJSSE/BC storage differences for PKCS12 KeyStore

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

SunJSSE/BC storage differences for PKCS12 KeyStore

bwalding
(This is all in relation to PKCS12 KeyStore objects)

I was recently converting some existing code that was half SunJSSE/half BC across to use BC across the board.

One of our routines "getOnlyAlias" attempts to retrieve the only alias of a PKCS12 KeyStore.

Our code creates a PKCS12 keystore, and then inserts a single entry containing 2 certificates in an array (the client cert and the public CA cert). Later on we reopen the keystore to perform other operations on it.

With the JSSE, reopening this KeyStore yields a keystore with only 1 alias - the alias we created.  However when using the BouncyCastle provider, we end up with a keystore that contains 2 aliases - quite surprising.

I have attached some test code that demonstrates this behaviour.


The output I get from this code is as follows -
----------------------------------------------------------
Using provider : SunJSSE
Saving CA keystore...
 KeyStore Class: java.security.KeyStore
 KeyStore Type: PKCS12
 KeyStore Provider: SunJSSE version 1.5
  Alias: cn=authority
   Certificate: CN=Authority
Loaded CA keystore
 KeyStore Class: java.security.KeyStore
 KeyStore Type: PKCS12
 KeyStore Provider: SunJSSE version 1.5
  Alias: cn=authority
   Certificate: CN=Authority
Creating client keystore
 KeyStore Class: java.security.KeyStore
 KeyStore Type: PKCS12
 KeyStore Provider: SunJSSE version 1.5
  Alias: cn=client
   Certificate: CN=Client
   Certificate: CN=Authority
Loaded client keystore
 KeyStore Class: java.security.KeyStore
 KeyStore Type: PKCS12
 KeyStore Provider: SunJSSE version 1.5
  Alias: cn=client
   Certificate: CN=Client
   Certificate: CN=Authority
----------------------------------------------------------
Using provider : BC
Saving CA keystore...
 KeyStore Class: java.security.KeyStore
 KeyStore Type: PKCS12
 KeyStore Provider: BC version 1.29
  Alias: CN=Authority
   Certificate: CN=Authority
Loaded CA keystore
 KeyStore Class: java.security.KeyStore
 KeyStore Type: PKCS12
 KeyStore Provider: BC version 1.29
  Alias: CN=Authority
   Certificate: CN=Authority
Creating client keystore
 KeyStore Class: java.security.KeyStore
 KeyStore Type: PKCS12
 KeyStore Provider: BC version 1.29
  Alias: CN=Client
   Certificate: CN=Client
   Certificate: CN=Authority
Loaded client keystore
 KeyStore Class: java.security.KeyStore
 KeyStore Type: PKCS12
 KeyStore Provider: BC version 1.29
  Alias: CN=Client
   Certificate: CN=Client
   Certificate: CN=Authority
  Alias: CN=Authority
   Certificate: CN=Authority


----------------------------------------------------------
Note the 2 alias entries in the last section (last 5 lines)

My question is this: is this behaviour (store a KeyStore with 1 alias, will load back with 2) by design?

Cheers,

Ben


JCETest.java (11K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: SunJSSE/BC storage differences for PKCS12 KeyStore

David Hook-4

It is by design, but what you are seeing is also a bug, although
probably not the one you are looking for. Welcome to the wonderful world
of PKCS12.

The reason for the difference in is how the attributes in the file are
interpreted. PKCS12 file entries carry "bag attributes" with them and BC
provides an interface called PKCS12BagAttributeCarrier which is
implemented both by BC generated keys and BC generated certificates. If
you use a BC implementation of PKCS12 these attributes are preserved and
will be saved with the object if it is stored in another PKCS12 file.
The most important ones of these are the friendly name and the local key
id either of which is sometimes used to link a private key with its
associated certificate (although strictly speaking this should probably
only be done using the local key id, however...)

In this case the certificate linked to the key carries two attributes,
the "friendly name" which is used as the alias for the certificate and
the id for the private key that was associated with it. Hence you're
getting two entries as in a BC keystore the friendly name on the CA
certificate is made available as an alias as well.

That being said, getCertificateChain() is only supposed to return
certificates associated with a key entry, so it should actually be
returning null when you call getCertificateChain() with the alias of the
CA certificate. This bit I'll fix.

Regards,

David

On Wed, 2005-08-31 at 14:25 +1000, Ben Walding wrote:

> (This is all in relation to PKCS12 KeyStore objects)
>
> I was recently converting some existing code that was half
> SunJSSE/half BC across to use BC across the board.
>
> One of our routines "getOnlyAlias" attempts to retrieve the only alias
> of a PKCS12 KeyStore.
>
> Our code creates a PKCS12 keystore, and then inserts a single entry
> containing 2 certificates in an array (the client cert and the public
> CA cert). Later on we reopen the keystore to perform other operations
> on it.
>
> With the JSSE, reopening this KeyStore yields a keystore with only 1
> alias - the alias we created.  However when using the BouncyCastle
> provider, we end up with a keystore that contains 2 aliases - quite
> surprising.
>
> I have attached some test code that demonstrates this behaviour.
>
>
> The output I get from this code is as follows -
> ----------------------------------------------------------
> Using provider : SunJSSE
> Saving CA keystore...
>  KeyStore Class: java.security.KeyStore
>  KeyStore Type: PKCS12
>  KeyStore Provider: SunJSSE version 1.5
>   Alias: cn=authority
>    Certificate: CN=Authority
> Loaded CA keystore
>  KeyStore Class: java.security.KeyStore
>  KeyStore Type: PKCS12
>  KeyStore Provider: SunJSSE version 1.5
>   Alias: cn=authority
>    Certificate: CN=Authority
> Creating client keystore
>  KeyStore Class: java.security.KeyStore
>  KeyStore Type: PKCS12
>  KeyStore Provider: SunJSSE version 1.5
>   Alias: cn=client
>    Certificate: CN=Client
>    Certificate: CN=Authority
> Loaded client keystore
>  KeyStore Class: java.security.KeyStore
>  KeyStore Type: PKCS12
>  KeyStore Provider: SunJSSE version 1.5
>   Alias: cn=client
>    Certificate: CN=Client
>    Certificate: CN=Authority
> ----------------------------------------------------------
> Using provider : BC
> Saving CA keystore...
>  KeyStore Class: java.security.KeyStore
>  KeyStore Type: PKCS12
>  KeyStore Provider: BC version 1.29
>   Alias: CN=Authority
>    Certificate: CN=Authority
> Loaded CA keystore
>  KeyStore Class: java.security.KeyStore
>  KeyStore Type: PKCS12
>  KeyStore Provider: BC version 1.29
>   Alias: CN=Authority
>    Certificate: CN=Authority
> Creating client keystore
>  KeyStore Class: java.security.KeyStore
>  KeyStore Type: PKCS12
>  KeyStore Provider: BC version 1.29
>   Alias: CN=Client
>    Certificate: CN=Client
>    Certificate: CN=Authority
> Loaded client keystore
>  KeyStore Class: java.security.KeyStore
>  KeyStore Type: PKCS12
>  KeyStore Provider: BC version 1.29
>   Alias: CN=Client
>    Certificate: CN=Client
>    Certificate: CN=Authority
>   Alias: CN=Authority
>    Certificate: CN=Authority
>
>
> ----------------------------------------------------------
> Note the 2 alias entries in the last section (last 5 lines)
>
> My question is this: is this behaviour (store a KeyStore with 1 alias,
> will load back with 2) by design?
>
> Cheers,
>
> Ben
>


Reply | Threaded
Open this post in threaded view
|

Re: SunJSSE/BC storage differences for PKCS12 KeyStore

Hes Siemelink
David Hook wrote:
> It is by design, but what you are seeing is also a bug, although
> probably not the one you are looking for. Welcome to the wonderful world
> of PKCS12.

I thought the wonderful KeyStore interface would shield us from all that ;-)

Intesting that this would pop up just now, because I am seeing something
that might be related.

Way back I made a PKCS12 keystore using Bouncy Castle (probably version
1.19).

I stored a private key with its certificate with alias "PRIVATE_KEY" and
stored the same certificate again with alias "CERTIFICATE".

I was always able to retrieve the certificate by calling
Keystore.getCertificate("CERTIFICATE").

However, today I found that this no longer works and that I need to call
Keystore.getCertificate("PRIVATE_KEY") to get hold of the certificate.

I'm running Bouncy Castle 1.28 now.

So has this changed and has a bug become a feature or vice-versa?

Cheers,

        Hes