Search code examples
javaandroidbouncycastle

Casting bouncy castle X509Certificate to Java.security.cert.Certificate[]


I have generated an RSA x509 certificate using bouncy castle in java. The code is below:

public static X509Certificate generateCert()
{
    try
    {
        Security.addProvider(new BouncyCastleProvider());
        // generate a key pair
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA", "BC");
        KeyPair keyPair = keyPairGenerator.generateKeyPair();

        // build a certificate generator
        X509V3CertificateGenerator certGen = new X509V3CertificateGenerator();
        X500Principal dnName = new X500Principal("cn=example");
        // add some options
        certGen.setSerialNumber(BigInteger.valueOf(System.currentTimeMillis()));
        certGen.setSubjectDN(new X509Name("dc=name"));
        certGen.setIssuerDN(dnName); // use the same
        // yesterday
        certGen.setNotBefore(new Date(System.currentTimeMillis() - 24 * 60 * 60 * 1000));
        // in 2 years
        certGen.setNotAfter(new Date(System.currentTimeMillis() + 2 * 365 * 24 * 60 * 60 * 1000));
        certGen.setPublicKey(keyPair.getPublic());
        certGen.setSignatureAlgorithm("SHA256withRSA");
        certGen.addExtension(X509Extensions.ExtendedKeyUsage, true, new ExtendedKeyUsage(KeyPurposeId.id_kp_timeStamping));
        mCurrentRSAKeyPair = keyPair;
        // finally, sign the certificate with the private key of the same KeyPair
        X509Certificate cert = certGen.generate(keyPair.getPrivate(), "BC");

        return cert;
    }
    catch (Exception e)
    {
        e.printStackTrace();
        return null;
    }
}

I want to be able to cast the X509Cerificate returned into a java.security.cert Certificate[] however it says they are incompatible. I need to use this certificate array for an android keystore:

public RSA(char[] password) throws Exception
{
    KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
    ks.load(null);
    Enumeration<String> aliases = ks.aliases();
    if(!aliases.hasMoreElements())
    {
        //mCurrentCertificate is the X509Certificate
        mCurrentCertificate = generateCert();
        //Store the new keypair
        FileInputStream fs = null;
        ks.load(fs, password);

        KeyStore.ProtectionParameter protParam =
                new KeyStore.PasswordProtection(password);

        Object cert = mCurrentCertificate.getEncoded();

        java.security.cert.Certificate[] myCert = (java.security.cert.Certificate[]) cert; //CAST HERE

        KeyStore.PrivateKeyEntry pkEntry =
                new KeyStore.PrivateKeyEntry(mCurrentRSAKeyPair.getPrivate(),
                        myCert);

        ks.setEntry("UserKey", pkEntry, protParam);
    }
}

Solution

  • myCert is an array of certificates, and cert is an array of bytes (as returned by getEncoded()).

    You should put your mCurrentCertificate variable inside an array:

    java.security.cert.Certificate[] myCert = new java.security.cert.Certificate[] { (java.security.cert.Certificate) mCurrentCertificate};
    // not sure if needs to cast mCurrentCertificate