Discussion:
SunJSSE/BC storage differences for PKCS12 KeyStore
Ben Walding
2005-08-31 04:25:59 UTC
Permalink
(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
David Hook
2005-08-31 06:25:26 UTC
Permalink
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
Post by Ben Walding
(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
Hes Siemelink
2005-09-01 14:19:19 UTC
Permalink
Post by David Hook
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

Loading...