FileDocCategorySizeDatePackage
AndroidKeyStoreTest.javaAPI DocAndroid 5.1 API154732Thu Mar 12 22:22:30 GMT 2015android.security

AndroidKeyStoreTest

public class AndroidKeyStoreTest extends android.test.AndroidTestCase

Fields Summary
private android.security.KeyStore
mAndroidKeyStore
private KeyStore
mKeyStore
private static final String
TEST_ALIAS_1
private static final String
TEST_ALIAS_2
private static final String
TEST_ALIAS_3
private static final X500Principal
TEST_DN_1
private static final X500Principal
TEST_DN_2
private static final BigInteger
TEST_SERIAL_1
private static final BigInteger
TEST_SERIAL_2
private static final long
NOW_MILLIS
private static final Date
NOW
private static final Date
NOW_PLUS_10_YEARS
private static final byte[]
FAKE_RSA_CA_1
Generated from above and converted with: openssl x509 -outform d -in cacert.pem | xxd -i | sed 's/0x/(byte) 0x/g'
private static final byte[]
FAKE_RSA_KEY_1
Generated from above and converted with: openssl pkcs8 -topk8 -outform d -in userkey.pem -nocrypt | xxd -i | sed 's/0x/(byte) 0x/g'
private static final byte[]
FAKE_RSA_USER_1
Generated from above and converted with: openssl x509 -outform d -in usercert.pem | xxd -i | sed 's/0x/(byte) 0x/g'
private static final byte[]
FAKE_EC_CA_1
Generated from above and converted with: openssl x509 -outform d -in cacert.pem | xxd -i | sed 's/0x/(byte) 0x/g'
private static final byte[]
FAKE_EC_KEY_1
Generated from above and converted with: openssl pkcs8 -topk8 -outform d -in userkey.pem -nocrypt | xxd -i | sed 's/0x/(byte) 0x/g'
private static final byte[]
FAKE_EC_USER_1
Generated from above and converted with: openssl x509 -outform d -in usercert.pem | xxd -i | sed 's/0x/(byte) 0x/g'
private static final byte[]
FAKE_DSA_CA_1
Generated from above and converted with: openssl x509 -outform d -in cacert.pem | xxd -i | sed 's/0x/(byte) 0x/g'
private static final byte[]
FAKE_DSA_KEY_1
Generated from above and converted with: openssl pkcs8 -topk8 -outform d -in userkey.pem -nocrypt | xxd -i | sed 's/0x/(byte) 0x/g'
private static final byte[]
FAKE_DSA_USER_1
Generated from above and converted with: openssl x509 -outform d -in usercert.pem | xxd -i | sed 's/0x/(byte) 0x/g'
private static final long
SLOP_TIME_MILLIS
The amount of time to allow before and after expected time for variance in timing tests.
Constructors Summary
Methods Summary
private voidassertAliases(java.lang.String[] expectedAliases)

        final Enumeration<String> aliases = mKeyStore.aliases();
        int count = 0;

        final Set<String> expectedSet = new HashSet<String>();
        expectedSet.addAll(Arrays.asList(expectedAliases));

        while (aliases.hasMoreElements()) {
            count++;
            final String alias = aliases.nextElement();
            assertTrue("The alias should be in the expected set", expectedSet.contains(alias));
            expectedSet.remove(alias);
        }
        assertTrue("The expected set and actual set should be exactly equal", expectedSet.isEmpty());
        assertEquals("There should be the correct number of keystore entries",
                expectedAliases.length, count);
    
private voidassertPrivateKeyEntryEquals(java.security.KeyStore.PrivateKeyEntry keyEntry, java.lang.String keyType, byte[] key, byte[] cert, byte[] ca)

        KeyFactory keyFact = KeyFactory.getInstance(keyType);
        PrivateKey expectedKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(key));

        CertificateFactory certFact = CertificateFactory.getInstance("X.509");
        Certificate expectedCert = certFact.generateCertificate(new ByteArrayInputStream(cert));

        final Collection<Certificate> expectedChain;
        if (ca != null) {
            expectedChain = (Collection<Certificate>) certFact
                    .generateCertificates(new ByteArrayInputStream(ca));
        } else {
            expectedChain = null;
        }

        assertPrivateKeyEntryEquals(keyEntry, expectedKey, expectedCert, expectedChain);
    
private voidassertPrivateKeyEntryEquals(java.security.KeyStore.PrivateKeyEntry keyEntry, java.security.PrivateKey expectedKey, java.security.cert.Certificate expectedCert, java.util.Collection expectedChain)

        if (expectedKey instanceof DSAPrivateKey) {
            assertEquals("Returned PrivateKey should be what we inserted",
                    ((DSAPrivateKey) expectedKey).getParams(),
                    ((DSAPublicKey) keyEntry.getCertificate().getPublicKey()).getParams());
        } else if (expectedKey instanceof ECPrivateKey) {
            assertEquals("Returned PrivateKey should be what we inserted",
                    ((ECPrivateKey) expectedKey).getParams().getCurve(),
                    ((ECPublicKey) keyEntry.getCertificate().getPublicKey()).getParams().getCurve());
        } else if (expectedKey instanceof RSAPrivateKey) {
            assertEquals("Returned PrivateKey should be what we inserted",
                    ((RSAPrivateKey) expectedKey).getModulus(),
                    ((RSAPrivateKey) keyEntry.getPrivateKey()).getModulus());
        }

        assertEquals("Returned Certificate should be what we inserted", expectedCert,
                keyEntry.getCertificate());

        Certificate[] actualChain = keyEntry.getCertificateChain();

        assertEquals("First certificate in chain should be user cert", expectedCert, actualChain[0]);

        if (expectedChain == null) {
            assertEquals("Certificate chain should not include CAs", 1, actualChain.length);
        } else {
            int i = 1;
            final Iterator<Certificate> it = expectedChain.iterator();
            while (it.hasNext()) {
                assertEquals("CA chain certificate should equal what we put in", it.next(),
                        actualChain[i++]);
            }
        }
    
private static java.security.cert.X509CertificategenerateCertificate(android.security.KeyStore keyStore, java.lang.String alias, java.math.BigInteger serialNumber, javax.security.auth.x500.X500Principal subjectDN, java.util.Date notBefore, java.util.Date notAfter)

        final String privateKeyAlias = Credentials.USER_PRIVATE_KEY + alias;

        final PrivateKey privKey;
        final OpenSSLEngine engine = OpenSSLEngine.getInstance("keystore");
        try {
            privKey = engine.getPrivateKeyById(privateKeyAlias);
        } catch (InvalidKeyException e) {
            throw new RuntimeException("Can't get key", e);
        }

        final byte[] pubKeyBytes = keyStore.getPubkey(privateKeyAlias);

        final PublicKey pubKey;
        try {
            final KeyFactory keyFact = KeyFactory.getInstance("RSA");
            pubKey = keyFact.generatePublic(new X509EncodedKeySpec(pubKeyBytes));
        } catch (NoSuchAlgorithmException e) {
            throw new IllegalStateException("Can't instantiate RSA key generator", e);
        } catch (InvalidKeySpecException e) {
            throw new IllegalStateException("keystore returned invalid key encoding", e);
        }

        final X509V3CertificateGenerator certGen = new X509V3CertificateGenerator();
        certGen.setPublicKey(pubKey);
        certGen.setSerialNumber(serialNumber);
        certGen.setSubjectDN(subjectDN);
        certGen.setIssuerDN(subjectDN);
        certGen.setNotBefore(notBefore);
        certGen.setNotAfter(notAfter);
        certGen.setSignatureAlgorithm("sha1WithRSA");

        final X509Certificate cert = certGen.generate(privKey);

        return cert;
    
protected voidsetUp()


    
         
        mAndroidKeyStore = android.security.KeyStore.getInstance();

        assertTrue(mAndroidKeyStore.reset());
        assertFalse(mAndroidKeyStore.isUnlocked());

        mKeyStore = java.security.KeyStore.getInstance("AndroidKeyStore");
    
private voidsetupKey()

        final String privateKeyAlias = Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1;
        assertTrue(mAndroidKeyStore
                .generate(privateKeyAlias, KeyStore.UID_SELF, NativeCrypto.EVP_PKEY_RSA, 1024,
                        KeyStore.FLAG_ENCRYPTED, null));

        X509Certificate cert = generateCertificate(mAndroidKeyStore, TEST_ALIAS_1, TEST_SERIAL_1,
                TEST_DN_1, NOW, NOW_PLUS_10_YEARS);

        assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1,
                cert.getEncoded(), KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
    
private voidsetupPassword()

        assertTrue(mAndroidKeyStore.password("1111"));
        assertTrue(mAndroidKeyStore.isUnlocked());

        assertEquals(0, mAndroidKeyStore.saw("").length);
    
public voidtestKeyStore_Aliases_Encrypted_Success()

        setupPassword();

        mKeyStore.load(null, null);

        assertAliases(new String[] {});

        assertTrue(mAndroidKeyStore.generate(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
                KeyStore.UID_SELF, NativeCrypto.EVP_PKEY_RSA, 1024, KeyStore.FLAG_ENCRYPTED,
                null));

        assertAliases(new String[] { TEST_ALIAS_1 });

        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_2, FAKE_RSA_CA_1,
                KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));

        assertAliases(new String[] { TEST_ALIAS_1, TEST_ALIAS_2 });
    
public voidtestKeyStore_Aliases_NotInitialized_Encrypted_Failure()

        setupPassword();

        try {
            mKeyStore.aliases();
            fail("KeyStore should throw exception when not initialized");
        } catch (KeyStoreException success) {
        }
    
public voidtestKeyStore_ContainsAliases_CAOnly_Encrypted_Success()

        setupPassword();

        mKeyStore.load(null, null);

        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_2, FAKE_RSA_CA_1,
                KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));

        assertTrue("Should contain added CA certificate", mKeyStore.containsAlias(TEST_ALIAS_2));
    
public voidtestKeyStore_ContainsAliases_NonExistent_Encrypted_Failure()

        setupPassword();

        mKeyStore.load(null, null);

        assertFalse("Should contain added CA certificate", mKeyStore.containsAlias(TEST_ALIAS_1));
    
public voidtestKeyStore_ContainsAliases_PrivateAndCA_Encrypted_Success()

        setupPassword();

        mKeyStore.load(null, null);

        assertAliases(new String[] {});

        assertTrue(mAndroidKeyStore.generate(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
                KeyStore.UID_SELF, NativeCrypto.EVP_PKEY_RSA, 1024, KeyStore.FLAG_ENCRYPTED,
                null));

        assertTrue("Should contain generated private key", mKeyStore.containsAlias(TEST_ALIAS_1));

        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_2, FAKE_RSA_CA_1,
                KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));

        assertTrue("Should contain added CA certificate", mKeyStore.containsAlias(TEST_ALIAS_2));

        assertFalse("Should not contain unadded certificate alias",
                mKeyStore.containsAlias(TEST_ALIAS_3));
    
public voidtestKeyStore_DeleteEntry_EmptyStore_Encrypted_Success()

        setupPassword();

        mKeyStore.load(null, null);

        // Should not throw when a non-existent entry is requested for delete.
        mKeyStore.deleteEntry(TEST_ALIAS_1);
    
public voidtestKeyStore_DeleteEntry_Encrypted_Success()

        setupPassword();

        mKeyStore.load(null, null);

        // TEST_ALIAS_1
        assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
                FAKE_RSA_KEY_1, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
        assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1, FAKE_RSA_USER_1,
                KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_RSA_CA_1,
                KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));

        // TEST_ALIAS_2
        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_2, FAKE_RSA_CA_1,
                KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));

        // TEST_ALIAS_3
        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_3, FAKE_RSA_CA_1,
                KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));

        assertAliases(new String[] { TEST_ALIAS_1, TEST_ALIAS_2, TEST_ALIAS_3 });

        mKeyStore.deleteEntry(TEST_ALIAS_1);

        assertAliases(new String[] { TEST_ALIAS_2, TEST_ALIAS_3 });

        mKeyStore.deleteEntry(TEST_ALIAS_3);

        assertAliases(new String[] { TEST_ALIAS_2 });

        mKeyStore.deleteEntry(TEST_ALIAS_2);

        assertAliases(new String[] { });
    
public voidtestKeyStore_DeleteEntry_NonExistent_Encrypted_Success()

        setupPassword();

        mKeyStore.load(null, null);

        // TEST_ALIAS_1
        assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
                FAKE_RSA_KEY_1, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
        assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1, FAKE_RSA_USER_1,
                KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_RSA_CA_1,
                KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));

        // Should not throw when a non-existent entry is requested for delete.
        mKeyStore.deleteEntry(TEST_ALIAS_2);
    
public voidtestKeyStore_GetCertificateAlias_CAEntry_Encrypted_Success()

        setupPassword();

        mKeyStore.load(null, null);

        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_RSA_CA_1,
                KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));

        CertificateFactory f = CertificateFactory.getInstance("X.509");
        Certificate actual = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_CA_1));

        assertEquals("Stored certificate alias should be found", TEST_ALIAS_1,
                mKeyStore.getCertificateAlias(actual));
    
public voidtestKeyStore_GetCertificateAlias_CAEntry_WithPrivateKeyUsingCA_Encrypted_Success()

        setupPassword();

        mKeyStore.load(null, null);

        // Insert TrustedCertificateEntry with CA name
        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_2, FAKE_RSA_CA_1,
                KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));

        // Insert PrivateKeyEntry that uses the same CA
        assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
                FAKE_RSA_KEY_1, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
        assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1, FAKE_RSA_USER_1,
                KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_RSA_CA_1,
                KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));

        CertificateFactory f = CertificateFactory.getInstance("X.509");
        Certificate actual = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_CA_1));

        assertEquals("Stored certificate alias should be found", TEST_ALIAS_2,
                mKeyStore.getCertificateAlias(actual));
    
public voidtestKeyStore_GetCertificateAlias_NonExist_Empty_Encrypted_Failure()

        setupPassword();

        mKeyStore.load(null, null);

        CertificateFactory f = CertificateFactory.getInstance("X.509");
        Certificate actual = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_CA_1));

        assertNull("Stored certificate alias should not be found",
                mKeyStore.getCertificateAlias(actual));
    
public voidtestKeyStore_GetCertificateAlias_NonExist_Encrypted_Failure()

        setupPassword();

        mKeyStore.load(null, null);

        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_RSA_CA_1,
                KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));

        CertificateFactory f = CertificateFactory.getInstance("X.509");
        Certificate userCert = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_USER_1));

        assertNull("Stored certificate alias should be found",
                mKeyStore.getCertificateAlias(userCert));
    
public voidtestKeyStore_GetCertificateAlias_PrivateKeyEntry_Encrypted_Success()

        setupPassword();

        mKeyStore.load(null, null);

        assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
                FAKE_RSA_KEY_1, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
        assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1, FAKE_RSA_USER_1,
                KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_RSA_CA_1,
                KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));

        CertificateFactory f = CertificateFactory.getInstance("X.509");
        Certificate actual = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_USER_1));

        assertEquals("Stored certificate alias should be found", TEST_ALIAS_1,
                mKeyStore.getCertificateAlias(actual));
    
public voidtestKeyStore_GetCertificateChain_NonExist_Encrypted_Failure()

        setupPassword();

        mKeyStore.load(null, null);

        assertNull("Stored certificate alias should not be found",
                mKeyStore.getCertificateChain(TEST_ALIAS_1));
    
public voidtestKeyStore_GetCertificateChain_SingleLength_Encrypted_Success()

        setupPassword();

        mKeyStore.load(null, null);

        assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
                FAKE_RSA_KEY_1, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
        assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1, FAKE_RSA_USER_1,
                KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_RSA_CA_1,
                KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));

        CertificateFactory cf = CertificateFactory.getInstance("X.509");
        Certificate[] expected = new Certificate[2];
        expected[0] = cf.generateCertificate(new ByteArrayInputStream(FAKE_RSA_USER_1));
        expected[1] = cf.generateCertificate(new ByteArrayInputStream(FAKE_RSA_CA_1));

        Certificate[] actual = mKeyStore.getCertificateChain(TEST_ALIAS_1);

        assertNotNull("Returned certificate chain should not be null", actual);
        assertEquals("Returned certificate chain should be correct size", expected.length,
                actual.length);
        assertEquals("First certificate should be user certificate", expected[0], actual[0]);
        assertEquals("Second certificate should be CA certificate", expected[1], actual[1]);

        // Negative test when keystore is populated.
        assertNull("Stored certificate alias should not be found",
                mKeyStore.getCertificateChain(TEST_ALIAS_2));
    
public voidtestKeyStore_GetCertificate_NonExist_Encrypted_Failure()

        setupPassword();

        mKeyStore.load(null, null);

        assertNull("Certificate should not exist in keystore",
                mKeyStore.getCertificate(TEST_ALIAS_1));
    
public voidtestKeyStore_GetCertificate_Single_Encrypted_Success()

        setupPassword();

        mKeyStore.load(null, null);

        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_RSA_CA_1,
                KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));

        assertAliases(new String[] { TEST_ALIAS_1 });

        assertNull("Certificate should not exist in keystore",
                mKeyStore.getCertificate(TEST_ALIAS_2));

        Certificate retrieved = mKeyStore.getCertificate(TEST_ALIAS_1);

        assertNotNull("Retrieved certificate should not be null", retrieved);

        CertificateFactory f = CertificateFactory.getInstance("X.509");
        Certificate actual = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_CA_1));

        assertEquals("Actual and retrieved certificates should be the same", actual, retrieved);
    
public voidtestKeyStore_GetCreationDate_CAEntry_Encrypted_Success()

        setupPassword();

        mKeyStore.load(null, null);

        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_RSA_CA_1,
                KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));

        Date now = new Date();
        Date actual = mKeyStore.getCreationDate(TEST_ALIAS_1);
        assertNotNull("Certificate should be found", actual);

        Date expectedAfter = new Date(now.getTime() - SLOP_TIME_MILLIS);
        Date expectedBefore = new Date(now.getTime() + SLOP_TIME_MILLIS);

        assertTrue("Time should be close to current time", actual.before(expectedBefore));
        assertTrue("Time should be close to current time", actual.after(expectedAfter));
    
public voidtestKeyStore_GetCreationDate_PrivateKeyEntry_Encrypted_Success()

        setupPassword();

        mKeyStore.load(null, null);

        assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
                FAKE_RSA_KEY_1, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
        assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1, FAKE_RSA_USER_1,
                KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_RSA_CA_1,
                KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));

        Date now = new Date();
        Date actual = mKeyStore.getCreationDate(TEST_ALIAS_1);

        Date expectedAfter = new Date(now.getTime() - SLOP_TIME_MILLIS);
        Date expectedBefore = new Date(now.getTime() + SLOP_TIME_MILLIS);

        assertTrue("Time should be close to current time", actual.before(expectedBefore));
        assertTrue("Time should be close to current time", actual.after(expectedAfter));
    
public voidtestKeyStore_GetCreationDate_PrivateKeyEntry_Unencrypted_Success()

        mKeyStore.load(null, null);

        assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
                FAKE_RSA_KEY_1, KeyStore.UID_SELF, KeyStore.FLAG_NONE));
        assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1, FAKE_RSA_USER_1,
                KeyStore.UID_SELF, KeyStore.FLAG_NONE));
        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_RSA_CA_1,
                KeyStore.UID_SELF, KeyStore.FLAG_NONE));

        Date now = new Date();
        Date actual = mKeyStore.getCreationDate(TEST_ALIAS_1);

        Date expectedAfter = new Date(now.getTime() - SLOP_TIME_MILLIS);
        Date expectedBefore = new Date(now.getTime() + SLOP_TIME_MILLIS);

        assertTrue("Time should be close to current time", actual.before(expectedBefore));
        assertTrue("Time should be close to current time", actual.after(expectedAfter));
    
public voidtestKeyStore_GetEntry_DSA_NullParams_Unencrypted_Success()

        mKeyStore.load(null, null);

        assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
                FAKE_DSA_KEY_1, KeyStore.UID_SELF, KeyStore.FLAG_NONE));
        assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1,
                FAKE_DSA_USER_1, KeyStore.UID_SELF, KeyStore.FLAG_NONE));
        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_DSA_CA_1,
                KeyStore.UID_SELF, KeyStore.FLAG_NONE));

        Entry entry = mKeyStore.getEntry(TEST_ALIAS_1, null);
        assertNotNull("Entry should exist", entry);

        assertTrue("Should be a PrivateKeyEntry", entry instanceof PrivateKeyEntry);

        PrivateKeyEntry keyEntry = (PrivateKeyEntry) entry;

        assertPrivateKeyEntryEquals(keyEntry, "DSA", FAKE_DSA_KEY_1, FAKE_DSA_USER_1, FAKE_DSA_CA_1);
    
public voidtestKeyStore_GetEntry_EC_NullParams_Unencrypted_Success()

        mKeyStore.load(null, null);

        assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
                FAKE_EC_KEY_1, KeyStore.UID_SELF, KeyStore.FLAG_NONE));
        assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1,
                FAKE_EC_USER_1, KeyStore.UID_SELF, KeyStore.FLAG_NONE));
        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_EC_CA_1,
                KeyStore.UID_SELF, KeyStore.FLAG_NONE));

        Entry entry = mKeyStore.getEntry(TEST_ALIAS_1, null);
        assertNotNull("Entry should exist", entry);

        assertTrue("Should be a PrivateKeyEntry", entry instanceof PrivateKeyEntry);

        PrivateKeyEntry keyEntry = (PrivateKeyEntry) entry;

        assertPrivateKeyEntryEquals(keyEntry, "EC", FAKE_EC_KEY_1, FAKE_EC_USER_1, FAKE_EC_CA_1);
    
public voidtestKeyStore_GetEntry_Nonexistent_NullParams_Encrypted_Failure()

        setupPassword();

        mKeyStore.load(null, null);

        assertNull("A non-existent entry should return null",
                mKeyStore.getEntry(TEST_ALIAS_1, null));
    
public voidtestKeyStore_GetEntry_Nonexistent_NullParams_Unencrypted_Failure()

        mKeyStore.load(null, null);

        assertNull("A non-existent entry should return null",
                mKeyStore.getEntry(TEST_ALIAS_1, null));
    
public voidtestKeyStore_GetEntry_NullParams_Encrypted_Success()

        setupPassword();

        mKeyStore.load(null, null);

        assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
                FAKE_RSA_KEY_1, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
        assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1, FAKE_RSA_USER_1,
                KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_RSA_CA_1,
                KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));

        Entry entry = mKeyStore.getEntry(TEST_ALIAS_1, null);
        assertNotNull("Entry should exist", entry);

        assertTrue("Should be a PrivateKeyEntry", entry instanceof PrivateKeyEntry);

        PrivateKeyEntry keyEntry = (PrivateKeyEntry) entry;

        assertPrivateKeyEntryEquals(keyEntry, "RSA", FAKE_RSA_KEY_1, FAKE_RSA_USER_1,
                FAKE_RSA_CA_1);
    
public voidtestKeyStore_GetEntry_RSA_NullParams_Unencrypted_Success()

        mKeyStore.load(null, null);

        assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
                FAKE_RSA_KEY_1, KeyStore.UID_SELF, KeyStore.FLAG_NONE));
        assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1,
                FAKE_RSA_USER_1, KeyStore.UID_SELF, KeyStore.FLAG_NONE));
        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_RSA_CA_1,
                KeyStore.UID_SELF, KeyStore.FLAG_NONE));

        Entry entry = mKeyStore.getEntry(TEST_ALIAS_1, null);
        assertNotNull("Entry should exist", entry);

        assertTrue("Should be a PrivateKeyEntry", entry instanceof PrivateKeyEntry);

        PrivateKeyEntry keyEntry = (PrivateKeyEntry) entry;

        assertPrivateKeyEntryEquals(keyEntry, "RSA", FAKE_RSA_KEY_1, FAKE_RSA_USER_1,
                FAKE_RSA_CA_1);
    
public voidtestKeyStore_GetKey_Certificate_Encrypted_Failure()

        setupPassword();

        mKeyStore.load(null, null);

        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_RSA_CA_1,
                KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));

        assertNull("Certificate entries should return null", mKeyStore.getKey(TEST_ALIAS_1, null));
    
public voidtestKeyStore_GetKey_NoPassword_Encrypted_Success()

        setupPassword();

        mKeyStore.load(null, null);

        assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
                FAKE_RSA_KEY_1, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
        assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1, FAKE_RSA_USER_1,
                KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_RSA_CA_1,
                KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));

        Key key = mKeyStore.getKey(TEST_ALIAS_1, null);
        assertNotNull("Key should exist", key);

        assertTrue("Should be a RSAPrivateKey", key instanceof RSAPrivateKey);

        RSAPrivateKey actualKey = (RSAPrivateKey) key;

        KeyFactory keyFact = KeyFactory.getInstance("RSA");
        PrivateKey expectedKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_RSA_KEY_1));

        assertEquals("Inserted key should be same as retrieved key",
                ((RSAPrivateKey) expectedKey).getModulus(), actualKey.getModulus());
    
public voidtestKeyStore_GetKey_NoPassword_Unencrypted_Success()

        mKeyStore.load(null, null);

        assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
                FAKE_RSA_KEY_1, KeyStore.UID_SELF, KeyStore.FLAG_NONE));
        assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1, FAKE_RSA_USER_1,
                KeyStore.UID_SELF, KeyStore.FLAG_NONE));
        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_RSA_CA_1,
                KeyStore.UID_SELF, KeyStore.FLAG_NONE));

        Key key = mKeyStore.getKey(TEST_ALIAS_1, null);
        assertNotNull("Key should exist", key);

        assertTrue("Should be a RSAPrivateKey", key instanceof RSAPrivateKey);

        RSAPrivateKey actualKey = (RSAPrivateKey) key;

        KeyFactory keyFact = KeyFactory.getInstance("RSA");
        PrivateKey expectedKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_RSA_KEY_1));

        assertEquals("Inserted key should be same as retrieved key",
                ((RSAPrivateKey) expectedKey).getModulus(), actualKey.getModulus());
    
public voidtestKeyStore_GetKey_NonExistent_Encrypted_Failure()

        setupPassword();

        mKeyStore.load(null, null);

        assertNull("A non-existent entry should return null", mKeyStore.getKey(TEST_ALIAS_1, null));
    
public voidtestKeyStore_GetProvider_Encrypted_Success()

        assertEquals(AndroidKeyStoreProvider.PROVIDER_NAME, mKeyStore.getProvider().getName());
        setupPassword();
        assertEquals(AndroidKeyStoreProvider.PROVIDER_NAME, mKeyStore.getProvider().getName());
    
public voidtestKeyStore_GetType_Encrypted_Success()

        assertEquals(AndroidKeyStore.NAME, mKeyStore.getType());
        setupPassword();
        assertEquals(AndroidKeyStore.NAME, mKeyStore.getType());
    
public voidtestKeyStore_IsCertificateEntry_CA_Encrypted_Success()

        setupPassword();
        mKeyStore.load(null, null);

        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_RSA_CA_1,
                KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));

        assertTrue("Should return true for CA certificate",
                mKeyStore.isCertificateEntry(TEST_ALIAS_1));
    
public voidtestKeyStore_IsCertificateEntry_NonExist_Encrypted_Failure()

        setupPassword();
        mKeyStore.load(null, null);

        assertFalse("Should return false for non-existent entry",
                mKeyStore.isCertificateEntry(TEST_ALIAS_1));
    
public voidtestKeyStore_IsCertificateEntry_NonExist_Unencrypted_Failure()

        mKeyStore.load(null, null);

        assertFalse("Should return false for non-existent entry",
                mKeyStore.isCertificateEntry(TEST_ALIAS_1));
    
public voidtestKeyStore_IsCertificateEntry_PrivateKey_Encrypted_Failure()

        setupPassword();
        mKeyStore.load(null, null);

        assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
                FAKE_RSA_KEY_1, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
        assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1, FAKE_RSA_USER_1,
                KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_RSA_CA_1,
                KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));

        assertFalse("Should return false for PrivateKeyEntry",
                mKeyStore.isCertificateEntry(TEST_ALIAS_1));
    
public voidtestKeyStore_IsKeyEntry_CA_Encrypted_Failure()

        setupPassword();
        mKeyStore.load(null, null);

        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_RSA_CA_1,
                KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));

        assertFalse("Should return false for CA certificate", mKeyStore.isKeyEntry(TEST_ALIAS_1));
    
public voidtestKeyStore_IsKeyEntry_NonExist_Encrypted_Failure()

        setupPassword();
        mKeyStore.load(null, null);

        assertFalse("Should return false for non-existent entry",
                mKeyStore.isKeyEntry(TEST_ALIAS_1));
    
public voidtestKeyStore_IsKeyEntry_PrivateKey_Encrypted_Success()

        setupPassword();
        mKeyStore.load(null, null);

        assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
                FAKE_RSA_KEY_1, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
        assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1, FAKE_RSA_USER_1,
                KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_RSA_CA_1,
                KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));

        assertTrue("Should return true for PrivateKeyEntry", mKeyStore.isKeyEntry(TEST_ALIAS_1));
    
public voidtestKeyStore_KeyOperations_Wrap_Encrypted_Success()

        setupPassword();
        mKeyStore.load(null, null);

        setupKey();

        // Test key usage
        Entry e = mKeyStore.getEntry(TEST_ALIAS_1, null);
        assertNotNull(e);
        assertTrue(e instanceof PrivateKeyEntry);

        PrivateKeyEntry privEntry = (PrivateKeyEntry) e;
        PrivateKey privKey = privEntry.getPrivateKey();
        assertNotNull(privKey);

        PublicKey pubKey = privEntry.getCertificate().getPublicKey();

        Cipher c = Cipher.getInstance("RSA/ECB/PKCS1Padding");
        c.init(Cipher.WRAP_MODE, pubKey);

        byte[] expectedKey = new byte[] {
                0x00, 0x05, (byte) 0xAA, (byte) 0x0A5, (byte) 0xFF, 0x55, 0x0A
        };

        SecretKey expectedSecret = new SecretKeySpec(expectedKey, "AES");

        byte[] wrappedExpected = c.wrap(expectedSecret);

        c.init(Cipher.UNWRAP_MODE, privKey);
        SecretKey actualSecret = (SecretKey) c.unwrap(wrappedExpected, "AES", Cipher.SECRET_KEY);

        assertEquals(Arrays.toString(expectedSecret.getEncoded()),
                Arrays.toString(actualSecret.getEncoded()));
    
public voidtestKeyStore_Load_InputStreamSupplied_Encrypted_Failure()

        byte[] buf = "FAKE KEYSTORE".getBytes();
        ByteArrayInputStream is = new ByteArrayInputStream(buf);

        try {
            mKeyStore.load(is, null);
            fail("Should throw IllegalArgumentException when InputStream is supplied");
        } catch (IllegalArgumentException success) {
        }
    
public voidtestKeyStore_Load_PasswordSupplied_Encrypted_Failure()

        try {
            mKeyStore.load(null, "password".toCharArray());
            fail("Should throw IllegalArgumentException when password is supplied");
        } catch (IllegalArgumentException success) {
        }
    
public voidtestKeyStore_SetCertificate_CAExists_Overwrite_Encrypted_Success()

        setupPassword();
        mKeyStore.load(null, null);

        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_RSA_CA_1,
                KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));

        assertAliases(new String[] { TEST_ALIAS_1 });

        final CertificateFactory f = CertificateFactory.getInstance("X.509");
        final Certificate cert = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_CA_1));

        // TODO have separate FAKE_CA for second test
        mKeyStore.setCertificateEntry(TEST_ALIAS_1, cert);

        assertAliases(new String[] { TEST_ALIAS_1 });
    
public voidtestKeyStore_SetCertificate_CA_Encrypted_Success()

        final CertificateFactory f = CertificateFactory.getInstance("X.509");
        final Certificate actual = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_CA_1));

        setupPassword();
        mKeyStore.load(null, null);

        mKeyStore.setCertificateEntry(TEST_ALIAS_1, actual);
        assertAliases(new String[] { TEST_ALIAS_1 });

        Certificate retrieved = mKeyStore.getCertificate(TEST_ALIAS_1);

        assertEquals("Retrieved certificate should be the same as the one inserted", actual,
                retrieved);
    
public voidtestKeyStore_SetCertificate_PrivateKeyExists_Encrypted_Failure()

        setupPassword();
        mKeyStore.load(null, null);

        assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
                FAKE_RSA_KEY_1, KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
        assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1, FAKE_RSA_USER_1,
                KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_RSA_CA_1,
                KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));

        assertAliases(new String[] { TEST_ALIAS_1 });

        final CertificateFactory f = CertificateFactory.getInstance("X.509");
        final Certificate cert = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_CA_1));

        try {
            mKeyStore.setCertificateEntry(TEST_ALIAS_1, cert);
            fail("Should throw when trying to overwrite a PrivateKey entry with a Certificate");
        } catch (KeyStoreException success) {
        }
    
public voidtestKeyStore_SetEntry_CAEntry_Overwrites_CAEntry_Encrypted_Success()

        setupPassword();
        mKeyStore.load(null, null);

        final CertificateFactory f = CertificateFactory.getInstance("X.509");

        // Insert TrustedCertificateEntry
        {
            final Certificate caCert = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_CA_1));

            TrustedCertificateEntry expectedCertEntry = new TrustedCertificateEntry(caCert);
            mKeyStore.setEntry(TEST_ALIAS_1, expectedCertEntry, null);

            Entry actualEntry = mKeyStore.getEntry(TEST_ALIAS_1, null);
            assertNotNull("Retrieved entry should exist", actualEntry);
            assertTrue("Retrieved entry should be of type TrustedCertificateEntry",
                    actualEntry instanceof TrustedCertificateEntry);
            TrustedCertificateEntry actualCertEntry = (TrustedCertificateEntry) actualEntry;
            assertEquals("Stored and retrieved certificates should be the same",
                    expectedCertEntry.getTrustedCertificate(),
                    actualCertEntry.getTrustedCertificate());
        }

        // Replace with TrustedCertificateEntry of USER
        {
            final Certificate userCert = f
                    .generateCertificate(new ByteArrayInputStream(FAKE_RSA_USER_1));

            TrustedCertificateEntry expectedUserEntry = new TrustedCertificateEntry(userCert);
            mKeyStore.setEntry(TEST_ALIAS_1, expectedUserEntry, null);

            Entry actualEntry = mKeyStore.getEntry(TEST_ALIAS_1, null);
            assertNotNull("Retrieved entry should exist", actualEntry);
            assertTrue("Retrieved entry should be of type TrustedCertificateEntry",
                    actualEntry instanceof TrustedCertificateEntry);
            TrustedCertificateEntry actualUserEntry = (TrustedCertificateEntry) actualEntry;
            assertEquals("Stored and retrieved certificates should be the same",
                    expectedUserEntry.getTrustedCertificate(),
                    actualUserEntry.getTrustedCertificate());
        }
    
public voidtestKeyStore_SetEntry_CAEntry_Overwrites_PrivateKeyEntry_Encrypted_Success()

        setupPassword();
        mKeyStore.load(null, null);

        final CertificateFactory f = CertificateFactory.getInstance("X.509");

        // Start with TrustedCertificateEntry
        {
            final Certificate caCert = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_CA_1));

            TrustedCertificateEntry expectedCertEntry = new TrustedCertificateEntry(caCert);
            mKeyStore.setEntry(TEST_ALIAS_1, expectedCertEntry, null);

            Entry actualEntry = mKeyStore.getEntry(TEST_ALIAS_1, null);
            assertNotNull("Retrieved entry should exist", actualEntry);
            assertTrue("Retrieved entry should be of type TrustedCertificateEntry",
                    actualEntry instanceof TrustedCertificateEntry);
            TrustedCertificateEntry actualCertEntry = (TrustedCertificateEntry) actualEntry;
            assertEquals("Stored and retrieved certificates should be the same",
                    expectedCertEntry.getTrustedCertificate(),
                    actualCertEntry.getTrustedCertificate());
        }

        // Replace with PrivateKeyEntry
        {
            KeyFactory keyFact = KeyFactory.getInstance("RSA");
            PrivateKey expectedKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_RSA_KEY_1));
            final Certificate[] expectedChain = new Certificate[2];
            expectedChain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_USER_1));
            expectedChain[1] = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_CA_1));

            PrivateKeyEntry expectedPrivEntry = new PrivateKeyEntry(expectedKey, expectedChain);

            mKeyStore.setEntry(TEST_ALIAS_1, expectedPrivEntry, null);

            Entry actualEntry = mKeyStore.getEntry(TEST_ALIAS_1, null);
            assertNotNull("Retrieved entry should exist", actualEntry);
            assertTrue("Retrieved entry should be of type PrivateKeyEntry",
                    actualEntry instanceof PrivateKeyEntry);

            PrivateKeyEntry actualPrivEntry = (PrivateKeyEntry) actualEntry;
            assertPrivateKeyEntryEquals(actualPrivEntry, "RSA", FAKE_RSA_KEY_1, FAKE_RSA_USER_1,
                    FAKE_RSA_CA_1);
        }
    
public voidtestKeyStore_SetEntry_PrivateKeyEntry_DSA_Unencrypted_Success()

        mKeyStore.load(null, null);

        KeyFactory keyFact = KeyFactory.getInstance("DSA");
        PrivateKey expectedKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_DSA_KEY_1));

        final CertificateFactory f = CertificateFactory.getInstance("X.509");

        final Certificate[] expectedChain = new Certificate[2];
        expectedChain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_DSA_USER_1));
        expectedChain[1] = f.generateCertificate(new ByteArrayInputStream(FAKE_DSA_CA_1));

        PrivateKeyEntry expected = new PrivateKeyEntry(expectedKey, expectedChain);

        mKeyStore.setEntry(TEST_ALIAS_1, expected, null);

        Entry actualEntry = mKeyStore.getEntry(TEST_ALIAS_1, null);
        assertNotNull("Retrieved entry should exist", actualEntry);

        assertTrue("Retrieved entry should be of type PrivateKeyEntry",
                actualEntry instanceof PrivateKeyEntry);

        PrivateKeyEntry actual = (PrivateKeyEntry) actualEntry;

        assertPrivateKeyEntryEquals(actual, "DSA", FAKE_DSA_KEY_1, FAKE_DSA_USER_1, FAKE_DSA_CA_1);
    
public voidtestKeyStore_SetEntry_PrivateKeyEntry_EC_Unencrypted_Success()

        mKeyStore.load(null, null);

        KeyFactory keyFact = KeyFactory.getInstance("EC");
        PrivateKey expectedKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_EC_KEY_1));

        final CertificateFactory f = CertificateFactory.getInstance("X.509");

        final Certificate[] expectedChain = new Certificate[2];
        expectedChain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_EC_USER_1));
        expectedChain[1] = f.generateCertificate(new ByteArrayInputStream(FAKE_EC_CA_1));

        PrivateKeyEntry expected = new PrivateKeyEntry(expectedKey, expectedChain);

        mKeyStore.setEntry(TEST_ALIAS_1, expected, null);

        Entry actualEntry = mKeyStore.getEntry(TEST_ALIAS_1, null);
        assertNotNull("Retrieved entry should exist", actualEntry);

        assertTrue("Retrieved entry should be of type PrivateKeyEntry",
                actualEntry instanceof PrivateKeyEntry);

        PrivateKeyEntry actual = (PrivateKeyEntry) actualEntry;

        assertPrivateKeyEntryEquals(actual, "EC", FAKE_EC_KEY_1, FAKE_EC_USER_1, FAKE_EC_CA_1);
    
public voidtestKeyStore_SetEntry_PrivateKeyEntry_Encrypted_Success()

        setupPassword();
        mKeyStore.load(null, null);

        KeyFactory keyFact = KeyFactory.getInstance("RSA");
        PrivateKey expectedKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_RSA_KEY_1));

        final CertificateFactory f = CertificateFactory.getInstance("X.509");

        final Certificate[] expectedChain = new Certificate[2];
        expectedChain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_USER_1));
        expectedChain[1] = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_CA_1));

        PrivateKeyEntry expected = new PrivateKeyEntry(expectedKey, expectedChain);

        mKeyStore.setEntry(TEST_ALIAS_1, expected, null);

        Entry actualEntry = mKeyStore.getEntry(TEST_ALIAS_1, null);
        assertNotNull("Retrieved entry should exist", actualEntry);

        assertTrue("Retrieved entry should be of type PrivateKeyEntry",
                actualEntry instanceof PrivateKeyEntry);

        PrivateKeyEntry actual = (PrivateKeyEntry) actualEntry;

        assertPrivateKeyEntryEquals(actual, "RSA", FAKE_RSA_KEY_1, FAKE_RSA_USER_1, FAKE_RSA_CA_1);
    
public voidtestKeyStore_SetEntry_PrivateKeyEntry_Overwrites_CAEntry_Encrypted_Success()

        setupPassword();
        mKeyStore.load(null, null);

        final CertificateFactory f = CertificateFactory.getInstance("X.509");

        final Certificate caCert = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_CA_1));

        // Start with PrivateKeyEntry
        {
            KeyFactory keyFact = KeyFactory.getInstance("RSA");
            PrivateKey expectedKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_RSA_KEY_1));
            final Certificate[] expectedChain = new Certificate[2];
            expectedChain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_USER_1));
            expectedChain[1] = caCert;

            PrivateKeyEntry expectedPrivEntry = new PrivateKeyEntry(expectedKey, expectedChain);

            mKeyStore.setEntry(TEST_ALIAS_1, expectedPrivEntry, null);

            Entry actualEntry = mKeyStore.getEntry(TEST_ALIAS_1, null);
            assertNotNull("Retrieved entry should exist", actualEntry);
            assertTrue("Retrieved entry should be of type PrivateKeyEntry",
                    actualEntry instanceof PrivateKeyEntry);

            PrivateKeyEntry actualPrivEntry = (PrivateKeyEntry) actualEntry;
            assertPrivateKeyEntryEquals(actualPrivEntry, "RSA", FAKE_RSA_KEY_1, FAKE_RSA_USER_1,
                    FAKE_RSA_CA_1);
        }

        // Replace with TrustedCertificateEntry
        {
            TrustedCertificateEntry expectedCertEntry = new TrustedCertificateEntry(caCert);
            mKeyStore.setEntry(TEST_ALIAS_1, expectedCertEntry, null);

            Entry actualEntry = mKeyStore.getEntry(TEST_ALIAS_1, null);
            assertNotNull("Retrieved entry should exist", actualEntry);
            assertTrue("Retrieved entry should be of type TrustedCertificateEntry",
                    actualEntry instanceof TrustedCertificateEntry);
            TrustedCertificateEntry actualCertEntry = (TrustedCertificateEntry) actualEntry;
            assertEquals("Stored and retrieved certificates should be the same",
                    expectedCertEntry.getTrustedCertificate(),
                    actualCertEntry.getTrustedCertificate());
        }
    
public voidtestKeyStore_SetEntry_PrivateKeyEntry_Overwrites_PrivateKeyEntry_Encrypted_Success()

        setupPassword();
        mKeyStore.load(null, null);

        final KeyFactory keyFact = KeyFactory.getInstance("RSA");
        final CertificateFactory f = CertificateFactory.getInstance("X.509");

        // Start with PrivateKeyEntry
        {
            PrivateKey expectedKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_RSA_KEY_1));

            final Certificate[] expectedChain = new Certificate[2];
            expectedChain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_USER_1));
            expectedChain[1] = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_CA_1));

            PrivateKeyEntry expected = new PrivateKeyEntry(expectedKey, expectedChain);

            mKeyStore.setEntry(TEST_ALIAS_1, expected, null);

            Entry actualEntry = mKeyStore.getEntry(TEST_ALIAS_1, null);
            assertNotNull("Retrieved entry should exist", actualEntry);

            assertTrue("Retrieved entry should be of type PrivateKeyEntry",
                    actualEntry instanceof PrivateKeyEntry);

            PrivateKeyEntry actual = (PrivateKeyEntry) actualEntry;

            assertPrivateKeyEntryEquals(actual, "RSA", FAKE_RSA_KEY_1, FAKE_RSA_USER_1,
                    FAKE_RSA_CA_1);
        }

        // TODO make entirely new test vector for the overwrite
        // Replace with PrivateKeyEntry
        {
            PrivateKey expectedKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_RSA_KEY_1));

            final Certificate[] expectedChain = new Certificate[2];
            expectedChain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_USER_1));
            expectedChain[1] = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_CA_1));

            PrivateKeyEntry expected = new PrivateKeyEntry(expectedKey, expectedChain);

            mKeyStore.setEntry(TEST_ALIAS_1, expected, null);

            Entry actualEntry = mKeyStore.getEntry(TEST_ALIAS_1, null);
            assertNotNull("Retrieved entry should exist", actualEntry);

            assertTrue("Retrieved entry should be of type PrivateKeyEntry",
                    actualEntry instanceof PrivateKeyEntry);

            PrivateKeyEntry actual = (PrivateKeyEntry) actualEntry;

            assertPrivateKeyEntryEquals(actual, "RSA", FAKE_RSA_KEY_1, FAKE_RSA_USER_1,
                    FAKE_RSA_CA_1);
        }
    
public voidtestKeyStore_SetEntry_PrivateKeyEntry_Overwrites_ShortPrivateKeyEntry_Encrypted_Success()

        setupPassword();
        mKeyStore.load(null, null);

        final CertificateFactory f = CertificateFactory.getInstance("X.509");

        final Certificate caCert = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_CA_1));

        // Start with PrivateKeyEntry
        {
            KeyFactory keyFact = KeyFactory.getInstance("RSA");
            PrivateKey expectedKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_RSA_KEY_1));
            final Certificate[] expectedChain = new Certificate[2];
            expectedChain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_USER_1));
            expectedChain[1] = caCert;

            PrivateKeyEntry expectedPrivEntry = new PrivateKeyEntry(expectedKey, expectedChain);

            mKeyStore.setEntry(TEST_ALIAS_1, expectedPrivEntry, null);

            Entry actualEntry = mKeyStore.getEntry(TEST_ALIAS_1, null);
            assertNotNull("Retrieved entry should exist", actualEntry);
            assertTrue("Retrieved entry should be of type PrivateKeyEntry",
                    actualEntry instanceof PrivateKeyEntry);

            PrivateKeyEntry actualPrivEntry = (PrivateKeyEntry) actualEntry;
            assertPrivateKeyEntryEquals(actualPrivEntry, "RSA", FAKE_RSA_KEY_1, FAKE_RSA_USER_1,
                    FAKE_RSA_CA_1);
        }

        // Replace with PrivateKeyEntry that has no chain
        {
            KeyFactory keyFact = KeyFactory.getInstance("RSA");
            PrivateKey expectedKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_RSA_KEY_1));
            final Certificate[] expectedChain = new Certificate[1];
            expectedChain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_USER_1));

            PrivateKeyEntry expectedPrivEntry = new PrivateKeyEntry(expectedKey, expectedChain);

            mKeyStore.setEntry(TEST_ALIAS_1, expectedPrivEntry, null);

            Entry actualEntry = mKeyStore.getEntry(TEST_ALIAS_1, null);
            assertNotNull("Retrieved entry should exist", actualEntry);
            assertTrue("Retrieved entry should be of type PrivateKeyEntry",
                    actualEntry instanceof PrivateKeyEntry);

            PrivateKeyEntry actualPrivEntry = (PrivateKeyEntry) actualEntry;
            assertPrivateKeyEntryEquals(actualPrivEntry, "RSA", FAKE_RSA_KEY_1, FAKE_RSA_USER_1,
                    null);
        }
    
public voidtestKeyStore_SetEntry_PrivateKeyEntry_Params_Unencrypted_Failure()

        mKeyStore.load(null, null);

        KeyFactory keyFact = KeyFactory.getInstance("RSA");
        PrivateKey expectedKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_RSA_KEY_1));

        final CertificateFactory f = CertificateFactory.getInstance("X.509");

        final Certificate[] expectedChain = new Certificate[2];
        expectedChain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_USER_1));
        expectedChain[1] = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_CA_1));

        PrivateKeyEntry entry = new PrivateKeyEntry(expectedKey, expectedChain);

        try {
            mKeyStore.setEntry(TEST_ALIAS_1, entry,
                    new KeyStoreParameter.Builder(getContext())
                    .setEncryptionRequired(true)
                    .build());
            fail("Shouldn't be able to insert encrypted entry when KeyStore uninitialized");
        } catch (KeyStoreException expected) {
        }

        assertNull(mKeyStore.getEntry(TEST_ALIAS_1, null));
    
public voidtestKeyStore_SetEntry_PrivateKeyEntry_RSA_Unencrypted_Success()

        mKeyStore.load(null, null);

        KeyFactory keyFact = KeyFactory.getInstance("RSA");
        PrivateKey expectedKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_RSA_KEY_1));

        final CertificateFactory f = CertificateFactory.getInstance("X.509");

        final Certificate[] expectedChain = new Certificate[2];
        expectedChain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_USER_1));
        expectedChain[1] = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_CA_1));

        PrivateKeyEntry expected = new PrivateKeyEntry(expectedKey, expectedChain);

        mKeyStore.setEntry(TEST_ALIAS_1, expected, null);

        Entry actualEntry = mKeyStore.getEntry(TEST_ALIAS_1, null);
        assertNotNull("Retrieved entry should exist", actualEntry);

        assertTrue("Retrieved entry should be of type PrivateKeyEntry",
                actualEntry instanceof PrivateKeyEntry);

        PrivateKeyEntry actual = (PrivateKeyEntry) actualEntry;

        assertPrivateKeyEntryEquals(actual, "RSA", FAKE_RSA_KEY_1, FAKE_RSA_USER_1, FAKE_RSA_CA_1);
    
public voidtestKeyStore_SetKeyEntry_Encrypted_Success()

        setupPassword();
        mKeyStore.load(null, null);

        final CertificateFactory f = CertificateFactory.getInstance("X.509");

        final Certificate caCert = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_CA_1));

        KeyFactory keyFact = KeyFactory.getInstance("RSA");
        PrivateKey privKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_RSA_KEY_1));
        final Certificate[] chain = new Certificate[2];
        chain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_USER_1));
        chain[1] = caCert;

        mKeyStore.setKeyEntry(TEST_ALIAS_1, privKey, null, chain);

        Entry actualEntry = mKeyStore.getEntry(TEST_ALIAS_1, null);
        assertNotNull("Retrieved entry should exist", actualEntry);

        assertTrue("Retrieved entry should be of type PrivateKeyEntry",
                actualEntry instanceof PrivateKeyEntry);

        PrivateKeyEntry actual = (PrivateKeyEntry) actualEntry;

        assertPrivateKeyEntryEquals(actual, "RSA", FAKE_RSA_KEY_1, FAKE_RSA_USER_1, FAKE_RSA_CA_1);
    
public voidtestKeyStore_SetKeyEntry_ProtectedKey_Encrypted_Failure()

        setupPassword();
        mKeyStore.load(null, null);

        final CertificateFactory f = CertificateFactory.getInstance("X.509");

        final Certificate caCert = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_CA_1));

        KeyFactory keyFact = KeyFactory.getInstance("RSA");
        PrivateKey privKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_RSA_KEY_1));
        final Certificate[] chain = new Certificate[2];
        chain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_USER_1));
        chain[1] = caCert;

        try {
            mKeyStore.setKeyEntry(TEST_ALIAS_1, privKey, "foo".toCharArray(), chain);
            fail("Should fail when a password is specified");
        } catch (KeyStoreException success) {
        }
    
public voidtestKeyStore_SetKeyEntry_ReplacedChain_DifferentPrivateKey_Encrypted_Failure()

        setupPassword();
        mKeyStore.load(null, null);

        // Create key #1
        {
            final String privateKeyAlias = Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1;
            assertTrue(mAndroidKeyStore.generate(privateKeyAlias, KeyStore.UID_SELF,
                    NativeCrypto.EVP_PKEY_RSA, 1024, KeyStore.FLAG_ENCRYPTED, null));

            X509Certificate cert = generateCertificate(mAndroidKeyStore, TEST_ALIAS_1,
                    TEST_SERIAL_1, TEST_DN_1, NOW, NOW_PLUS_10_YEARS);

            assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1,
                    cert.getEncoded(), KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
        }

        // Create key #2
        {
            final String privateKeyAlias = Credentials.USER_PRIVATE_KEY + TEST_ALIAS_2;
            assertTrue(mAndroidKeyStore.generate(privateKeyAlias, KeyStore.UID_SELF,
                    NativeCrypto.EVP_PKEY_RSA, 1024, KeyStore.FLAG_ENCRYPTED, null));

            X509Certificate cert = generateCertificate(mAndroidKeyStore, TEST_ALIAS_2,
                    TEST_SERIAL_2, TEST_DN_2, NOW, NOW_PLUS_10_YEARS);

            assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_2,
                    cert.getEncoded(), KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));
        }

        // Replace key #1 with key #2
        {
            Key key1 = mKeyStore.getKey(TEST_ALIAS_2, null);

            X509Certificate cert = generateCertificate(mAndroidKeyStore, TEST_ALIAS_2,
                    TEST_SERIAL_2, TEST_DN_2, NOW, NOW_PLUS_10_YEARS);

            try {
                mKeyStore.setKeyEntry(TEST_ALIAS_1, key1, null, new Certificate[] { cert });
                fail("Should not allow setting of KeyEntry with wrong PrivaetKey");
            } catch (KeyStoreException success) {
            }
        }
    
public voidtestKeyStore_SetKeyEntry_ReplacedChain_Encrypted_Success()

        setupPassword();
        mKeyStore.load(null, null);

        // Create key #1
        {
            final String privateKeyAlias = Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1;
            assertTrue(mAndroidKeyStore.generate(privateKeyAlias, KeyStore.UID_SELF,
                    NativeCrypto.EVP_PKEY_RSA, 1024, KeyStore.FLAG_ENCRYPTED, null));

            Key key = mKeyStore.getKey(TEST_ALIAS_1, null);

            assertTrue(key instanceof PrivateKey);

            PrivateKey expectedKey = (PrivateKey) key;

            X509Certificate expectedCert = generateCertificate(mAndroidKeyStore, TEST_ALIAS_1,
                    TEST_SERIAL_1, TEST_DN_1, NOW, NOW_PLUS_10_YEARS);

            assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1,
                    expectedCert.getEncoded(), KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));

            Entry entry = mKeyStore.getEntry(TEST_ALIAS_1, null);

            assertTrue(entry instanceof PrivateKeyEntry);

            PrivateKeyEntry keyEntry = (PrivateKeyEntry) entry;

            assertPrivateKeyEntryEquals(keyEntry, expectedKey, expectedCert, null);
        }

        // Replace key #1 with new chain
        {
            Key key = mKeyStore.getKey(TEST_ALIAS_1, null);

            assertTrue(key instanceof PrivateKey);

            PrivateKey expectedKey = (PrivateKey) key;

            X509Certificate expectedCert = generateCertificate(mAndroidKeyStore, TEST_ALIAS_1,
                    TEST_SERIAL_2, TEST_DN_2, NOW, NOW_PLUS_10_YEARS);

            mKeyStore.setKeyEntry(TEST_ALIAS_1, expectedKey, null,
                    new Certificate[] { expectedCert });

            Entry entry = mKeyStore.getEntry(TEST_ALIAS_1, null);

            assertTrue(entry instanceof PrivateKeyEntry);

            PrivateKeyEntry keyEntry = (PrivateKeyEntry) entry;

            assertPrivateKeyEntryEquals(keyEntry, expectedKey, expectedCert, null);
        }
    
public voidtestKeyStore_SetKeyEntry_ReplacedChain_UnencryptedToEncrypted_Failure()

        mKeyStore.load(null, null);

        // Create key #1
        {
            final String privateKeyAlias = Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1;
            assertTrue(mAndroidKeyStore.generate(privateKeyAlias,
                    android.security.KeyStore.UID_SELF, NativeCrypto.EVP_PKEY_RSA, 1024,
                    android.security.KeyStore.FLAG_NONE, null));

            X509Certificate cert =
                    generateCertificate(mAndroidKeyStore, TEST_ALIAS_1, TEST_SERIAL_1, TEST_DN_1,
                            NOW, NOW_PLUS_10_YEARS);

            assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1,
                    cert.getEncoded(), android.security.KeyStore.UID_SELF,
                    android.security.KeyStore.FLAG_NONE));
        }

        // Replace with one that requires encryption
        {
            Entry entry = mKeyStore.getEntry(TEST_ALIAS_1, null);

            try {
                mKeyStore.setEntry(TEST_ALIAS_1, entry,
                        new KeyStoreParameter.Builder(getContext())
                                .setEncryptionRequired(true)
                                .build());
                fail("Should not allow setting of Entry without unlocked keystore");
            } catch (KeyStoreException success) {
            }

            assertTrue(mAndroidKeyStore.password("1111"));
            assertTrue(mAndroidKeyStore.isUnlocked());

            mKeyStore.setEntry(TEST_ALIAS_1, entry,
                    new KeyStoreParameter.Builder(getContext())
                            .setEncryptionRequired(true)
                            .build());
        }
    
public voidtestKeyStore_SetKeyEntry_Replaced_Encrypted_Success()

        setupPassword();
        mKeyStore.load(null, null);

        final CertificateFactory f = CertificateFactory.getInstance("X.509");

        final Certificate caCert = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_CA_1));

        // Insert initial key
        {
            KeyFactory keyFact = KeyFactory.getInstance("RSA");
            PrivateKey privKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_RSA_KEY_1));
            final Certificate[] chain = new Certificate[2];
            chain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_USER_1));
            chain[1] = caCert;

            mKeyStore.setKeyEntry(TEST_ALIAS_1, privKey, null, chain);

            Entry actualEntry = mKeyStore.getEntry(TEST_ALIAS_1, null);
            assertNotNull("Retrieved entry should exist", actualEntry);

            assertTrue("Retrieved entry should be of type PrivateKeyEntry",
                    actualEntry instanceof PrivateKeyEntry);

            PrivateKeyEntry actual = (PrivateKeyEntry) actualEntry;

            assertPrivateKeyEntryEquals(actual, "RSA", FAKE_RSA_KEY_1, FAKE_RSA_USER_1,
                    FAKE_RSA_CA_1);
        }

        // TODO make a separate key
        // Replace key
        {
            KeyFactory keyFact = KeyFactory.getInstance("RSA");
            PrivateKey privKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_RSA_KEY_1));
            final Certificate[] chain = new Certificate[2];
            chain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_RSA_USER_1));
            chain[1] = caCert;

            mKeyStore.setKeyEntry(TEST_ALIAS_1, privKey, null, chain);

            Entry actualEntry = mKeyStore.getEntry(TEST_ALIAS_1, null);
            assertNotNull("Retrieved entry should exist", actualEntry);

            assertTrue("Retrieved entry should be of type PrivateKeyEntry",
                    actualEntry instanceof PrivateKeyEntry);

            PrivateKeyEntry actual = (PrivateKeyEntry) actualEntry;

            assertPrivateKeyEntryEquals(actual, "RSA", FAKE_RSA_KEY_1, FAKE_RSA_USER_1,
                    FAKE_RSA_CA_1);
        }
    
public voidtestKeyStore_Size_Encrypted_Success()

        setupPassword();
        mKeyStore.load(null, null);

        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_RSA_CA_1,
                KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));

        assertEquals("The keystore size should match expected", 1, mKeyStore.size());
        assertAliases(new String[] { TEST_ALIAS_1 });

        assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_2, FAKE_RSA_CA_1,
                KeyStore.UID_SELF, KeyStore.FLAG_ENCRYPTED));

        assertEquals("The keystore size should match expected", 2, mKeyStore.size());
        assertAliases(new String[] { TEST_ALIAS_1, TEST_ALIAS_2 });

        assertTrue(mAndroidKeyStore.generate(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_3,
                KeyStore.UID_SELF, NativeCrypto.EVP_PKEY_RSA, 1024, KeyStore.FLAG_ENCRYPTED,
                null));

        assertEquals("The keystore size should match expected", 3, mKeyStore.size());
        assertAliases(new String[] { TEST_ALIAS_1, TEST_ALIAS_2, TEST_ALIAS_3 });

        assertTrue(mAndroidKeyStore.delete(Credentials.CA_CERTIFICATE + TEST_ALIAS_1));

        assertEquals("The keystore size should match expected", 2, mKeyStore.size());
        assertAliases(new String[] { TEST_ALIAS_2, TEST_ALIAS_3 });

        assertTrue(mAndroidKeyStore.delKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_3));

        assertEquals("The keystore size should match expected", 1, mKeyStore.size());
        assertAliases(new String[] { TEST_ALIAS_2 });
    
public voidtestKeyStore_Store_LoadStoreParam_Encrypted_Failure()

        setupPassword();
        mKeyStore.load(null, null);

        try {
            mKeyStore.store(null);
            fail("Should throw UnsupportedOperationException when trying to store");
        } catch (UnsupportedOperationException success) {
        }
    
public voidtestKeyStore_Store_OutputStream_Encrypted_Failure()

        setupPassword();
        mKeyStore.load(null, null);

        OutputStream sink = new ByteArrayOutputStream();
        try {
            mKeyStore.store(sink, null);
            fail("Should throw UnsupportedOperationException when trying to store");
        } catch (UnsupportedOperationException success) {
        }

        try {
            mKeyStore.store(sink, "blah".toCharArray());
            fail("Should throw UnsupportedOperationException when trying to store");
        } catch (UnsupportedOperationException success) {
        }