'Why is AndroidKeyStore transforming PrivateKeyEntry into a TrustedCertifiateEntry?

Test platform is a Motorola G5, running 8.1.0; BouncyCastle 1.56

I am trying to use client certificates with the AndroidKeyStore.

Using KeyPairgenerator and KeyPairGeneratorSpec I can create a self-signed keypair with the CN of "temporary"; and behind the scenes, the library stores it in the AndroidKeyStore under the alias given to KPGS.Builder.

I later getEntry() and am given a KeyStore.PrivateKeyEntry as expceted.

I extract the key data from this, and pass it to the bouncy castle CertificationRequest class, I pass the cert to my corporate CA, and they send me back a certificate chain (two X509 keys appended; one for the DN that I created, and their self-signed cert)

(Taking the certs apart with openssl x509 … reveals nothing unexpected)

Up to here, everything works as documented.

Now comes the weirdness ...

The documentation mentions in passing that you can "replace the self-signed certificate with a 'real one' later" and I do that with the following code:

        KeyStore.PrivateKeyEntry entry = (KeyStore.PrivateKeyEntry) keyStore.getEntry(mykey,null);
        KeyStore.PrivateKeyEntry replacement = new KeyStore.PrivateKeyEntry(entry.getPrivateKey(),
                                            certs);
        keyStore.setEntry(mykey,replacement,null);
        KeyStore.Entry nowItIs = keyStore.getEntry(mykey,null);
        Log.v(TAG, String.format("After storing, the key is now a %s", 
                     nowItIs.getClass().getSimpleName()));

Here's the mysterious transformation: in theory, nowItIs should be identical to replacement ... but it's not: it is a TrustedCertificateEntry.

Someone else posted of the same problem several years ago, but there was no resolution.



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source