diff options
Diffstat (limited to 'keystore/tests/src/android/security/AndroidKeyStoreTest.java')
-rw-r--r-- | keystore/tests/src/android/security/AndroidKeyStoreTest.java | 373 |
1 files changed, 316 insertions, 57 deletions
diff --git a/keystore/tests/src/android/security/AndroidKeyStoreTest.java b/keystore/tests/src/android/security/AndroidKeyStoreTest.java index 8928e06..05ffe109 100644 --- a/keystore/tests/src/android/security/AndroidKeyStoreTest.java +++ b/keystore/tests/src/android/security/AndroidKeyStoreTest.java @@ -469,12 +469,14 @@ public class AndroidKeyStoreTest extends AndroidTestCase { assertTrue(mAndroidKeyStore.reset()); assertFalse(mAndroidKeyStore.isUnlocked()); + mKeyStore = java.security.KeyStore.getInstance("AndroidKeyStore"); + } + + private void setupPassword() { assertTrue(mAndroidKeyStore.password("1111")); assertTrue(mAndroidKeyStore.isUnlocked()); assertEquals(0, mAndroidKeyStore.saw("").length); - - mKeyStore = java.security.KeyStore.getInstance(AndroidKeyStore.NAME); } private void assertAliases(final String[] expectedAliases) throws KeyStoreException { @@ -495,7 +497,9 @@ public class AndroidKeyStoreTest extends AndroidTestCase { expectedAliases.length, count); } - public void testKeyStore_Aliases_Success() throws Exception { + public void testKeyStore_Aliases_Encrypted_Success() throws Exception { + setupPassword(); + mKeyStore.load(null, null); assertAliases(new String[] {}); @@ -509,7 +513,9 @@ public class AndroidKeyStoreTest extends AndroidTestCase { assertAliases(new String[] { TEST_ALIAS_1, TEST_ALIAS_2 }); } - public void testKeyStore_Aliases_NotInitialized_Failure() throws Exception { + public void testKeyStore_Aliases_NotInitialized_Encrypted_Failure() throws Exception { + setupPassword(); + try { mKeyStore.aliases(); fail("KeyStore should throw exception when not initialized"); @@ -517,7 +523,9 @@ public class AndroidKeyStoreTest extends AndroidTestCase { } } - public void testKeyStore_ContainsAliases_PrivateAndCA_Success() throws Exception { + public void testKeyStore_ContainsAliases_PrivateAndCA_Encrypted_Success() throws Exception { + setupPassword(); + mKeyStore.load(null, null); assertAliases(new String[] {}); @@ -534,7 +542,9 @@ public class AndroidKeyStoreTest extends AndroidTestCase { mKeyStore.containsAlias(TEST_ALIAS_3)); } - public void testKeyStore_ContainsAliases_CAOnly_Success() throws Exception { + public void testKeyStore_ContainsAliases_CAOnly_Encrypted_Success() throws Exception { + setupPassword(); + mKeyStore.load(null, null); assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_2, FAKE_CA_1)); @@ -542,13 +552,17 @@ public class AndroidKeyStoreTest extends AndroidTestCase { assertTrue("Should contain added CA certificate", mKeyStore.containsAlias(TEST_ALIAS_2)); } - public void testKeyStore_ContainsAliases_NonExistent_Failure() throws Exception { + public void testKeyStore_ContainsAliases_NonExistent_Encrypted_Failure() throws Exception { + setupPassword(); + mKeyStore.load(null, null); assertFalse("Should contain added CA certificate", mKeyStore.containsAlias(TEST_ALIAS_1)); } - public void testKeyStore_DeleteEntry_Success() throws Exception { + public void testKeyStore_DeleteEntry_Encrypted_Success() throws Exception { + setupPassword(); + mKeyStore.load(null, null); // TEST_ALIAS_1 @@ -578,14 +592,18 @@ public class AndroidKeyStoreTest extends AndroidTestCase { assertAliases(new String[] { }); } - public void testKeyStore_DeleteEntry_EmptyStore_Success() throws Exception { + public void testKeyStore_DeleteEntry_EmptyStore_Encrypted_Success() throws Exception { + setupPassword(); + mKeyStore.load(null, null); // Should not throw when a non-existent entry is requested for delete. mKeyStore.deleteEntry(TEST_ALIAS_1); } - public void testKeyStore_DeleteEntry_NonExistent_Success() throws Exception { + public void testKeyStore_DeleteEntry_NonExistent_Encrypted_Success() throws Exception { + setupPassword(); + mKeyStore.load(null, null); // TEST_ALIAS_1 @@ -598,7 +616,9 @@ public class AndroidKeyStoreTest extends AndroidTestCase { mKeyStore.deleteEntry(TEST_ALIAS_2); } - public void testKeyStore_GetCertificate_Single_Success() throws Exception { + public void testKeyStore_GetCertificate_Single_Encrypted_Success() throws Exception { + setupPassword(); + mKeyStore.load(null, null); assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1)); @@ -618,14 +638,18 @@ public class AndroidKeyStoreTest extends AndroidTestCase { assertEquals("Actual and retrieved certificates should be the same", actual, retrieved); } - public void testKeyStore_GetCertificate_NonExist_Failure() throws Exception { + public void testKeyStore_GetCertificate_NonExist_Encrypted_Failure() throws Exception { + setupPassword(); + mKeyStore.load(null, null); assertNull("Certificate should not exist in keystore", mKeyStore.getCertificate(TEST_ALIAS_1)); } - public void testKeyStore_GetCertificateAlias_CAEntry_Success() throws Exception { + public void testKeyStore_GetCertificateAlias_CAEntry_Encrypted_Success() throws Exception { + setupPassword(); + mKeyStore.load(null, null); assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1)); @@ -637,7 +661,10 @@ public class AndroidKeyStoreTest extends AndroidTestCase { mKeyStore.getCertificateAlias(actual)); } - public void testKeyStore_GetCertificateAlias_PrivateKeyEntry_Success() throws Exception { + public void testKeyStore_GetCertificateAlias_PrivateKeyEntry_Encrypted_Success() + throws Exception { + setupPassword(); + mKeyStore.load(null, null); assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1, @@ -652,8 +679,10 @@ public class AndroidKeyStoreTest extends AndroidTestCase { mKeyStore.getCertificateAlias(actual)); } - public void testKeyStore_GetCertificateAlias_CAEntry_WithPrivateKeyUsingCA_Success() + public void testKeyStore_GetCertificateAlias_CAEntry_WithPrivateKeyUsingCA_Encrypted_Success() throws Exception { + setupPassword(); + mKeyStore.load(null, null); // Insert TrustedCertificateEntry with CA name @@ -672,7 +701,10 @@ public class AndroidKeyStoreTest extends AndroidTestCase { mKeyStore.getCertificateAlias(actual)); } - public void testKeyStore_GetCertificateAlias_NonExist_Empty_Failure() throws Exception { + public void testKeyStore_GetCertificateAlias_NonExist_Empty_Encrypted_Failure() + throws Exception { + setupPassword(); + mKeyStore.load(null, null); CertificateFactory f = CertificateFactory.getInstance("X.509"); @@ -682,7 +714,9 @@ public class AndroidKeyStoreTest extends AndroidTestCase { mKeyStore.getCertificateAlias(actual)); } - public void testKeyStore_GetCertificateAlias_NonExist_Failure() throws Exception { + public void testKeyStore_GetCertificateAlias_NonExist_Encrypted_Failure() throws Exception { + setupPassword(); + mKeyStore.load(null, null); assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1)); @@ -694,7 +728,9 @@ public class AndroidKeyStoreTest extends AndroidTestCase { mKeyStore.getCertificateAlias(userCert)); } - public void testKeyStore_GetCertificateChain_SingleLength_Success() throws Exception { + public void testKeyStore_GetCertificateChain_SingleLength_Encrypted_Success() throws Exception { + setupPassword(); + mKeyStore.load(null, null); assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1, @@ -720,14 +756,18 @@ public class AndroidKeyStoreTest extends AndroidTestCase { mKeyStore.getCertificateChain(TEST_ALIAS_2)); } - public void testKeyStore_GetCertificateChain_NonExist_Failure() throws Exception { + public void testKeyStore_GetCertificateChain_NonExist_Encrypted_Failure() throws Exception { + setupPassword(); + mKeyStore.load(null, null); assertNull("Stored certificate alias should not be found", mKeyStore.getCertificateChain(TEST_ALIAS_1)); } - public void testKeyStore_GetCreationDate_PrivateKeyEntry_Success() throws Exception { + public void testKeyStore_GetCreationDate_PrivateKeyEntry_Encrypted_Success() throws Exception { + setupPassword(); + mKeyStore.load(null, null); assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1, @@ -745,7 +785,29 @@ public class AndroidKeyStoreTest extends AndroidTestCase { assertTrue("Time should be close to current time", actual.after(expectedAfter)); } - public void testKeyStore_GetCreationDate_CAEntry_Success() throws Exception { + public void testKeyStore_GetCreationDate_PrivateKeyEntry_Unencrypted_Success() throws Exception { + mKeyStore.load(null, null); + + assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1, + FAKE_KEY_1, KeyStore.UID_SELF, KeyStore.FLAG_NONE)); + assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1, FAKE_USER_1, + KeyStore.UID_SELF, KeyStore.FLAG_NONE)); + assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_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 void testKeyStore_GetCreationDate_CAEntry_Encrypted_Success() throws Exception { + setupPassword(); + mKeyStore.load(null, null); assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1)); @@ -761,7 +823,9 @@ public class AndroidKeyStoreTest extends AndroidTestCase { assertTrue("Time should be close to current time", actual.after(expectedAfter)); } - public void testKeyStore_GetEntry_NullParams_Success() throws Exception { + public void testKeyStore_GetEntry_NullParams_Encrypted_Success() throws Exception { + setupPassword(); + mKeyStore.load(null, null); assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1, @@ -779,6 +843,26 @@ public class AndroidKeyStoreTest extends AndroidTestCase { assertPrivateKeyEntryEquals(keyEntry, FAKE_KEY_1, FAKE_USER_1, FAKE_CA_1); } + public void testKeyStore_GetEntry_NullParams_Unencrypted_Success() throws Exception { + mKeyStore.load(null, null); + + assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1, + FAKE_KEY_1, KeyStore.UID_SELF, KeyStore.FLAG_NONE)); + assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1, FAKE_USER_1, + KeyStore.UID_SELF, KeyStore.FLAG_NONE)); + assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_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, FAKE_KEY_1, FAKE_USER_1, FAKE_CA_1); + } + @SuppressWarnings("unchecked") private void assertPrivateKeyEntryEquals(PrivateKeyEntry keyEntry, byte[] key, byte[] cert, byte[] ca) throws Exception { @@ -801,8 +885,9 @@ public class AndroidKeyStoreTest extends AndroidTestCase { private void assertPrivateKeyEntryEquals(PrivateKeyEntry keyEntry, PrivateKey expectedKey, Certificate expectedCert, Collection<Certificate> expectedChain) throws Exception { - assertEquals("Returned PrivateKey should be what we inserted", expectedKey, - keyEntry.getPrivateKey()); + 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()); @@ -823,14 +908,25 @@ public class AndroidKeyStoreTest extends AndroidTestCase { } } - public void testKeyStore_GetEntry_Nonexistent_NullParams_Failure() throws Exception { + public void testKeyStore_GetEntry_Nonexistent_NullParams_Encrypted_Failure() throws Exception { + setupPassword(); + mKeyStore.load(null, null); assertNull("A non-existent entry should return null", mKeyStore.getEntry(TEST_ALIAS_1, null)); } - public void testKeyStore_GetKey_NoPassword_Success() throws Exception { + public void testKeyStore_GetEntry_Nonexistent_NullParams_Unencrypted_Failure() throws Exception { + mKeyStore.load(null, null); + + assertNull("A non-existent entry should return null", + mKeyStore.getEntry(TEST_ALIAS_1, null)); + } + + public void testKeyStore_GetKey_NoPassword_Encrypted_Success() throws Exception { + setupPassword(); + mKeyStore.load(null, null); assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1, @@ -848,10 +944,37 @@ public class AndroidKeyStoreTest extends AndroidTestCase { KeyFactory keyFact = KeyFactory.getInstance("RSA"); PrivateKey expectedKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_KEY_1)); - assertEquals("Inserted key should be same as retrieved key", actualKey, expectedKey); + assertEquals("Inserted key should be same as retrieved key", + ((RSAPrivateKey) expectedKey).getModulus(), actualKey.getModulus()); } - public void testKeyStore_GetKey_Certificate_Failure() throws Exception { + public void testKeyStore_GetKey_NoPassword_Unencrypted_Success() throws Exception { + mKeyStore.load(null, null); + + assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1, + FAKE_KEY_1, KeyStore.UID_SELF, KeyStore.FLAG_NONE)); + assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1, FAKE_USER_1, + KeyStore.UID_SELF, KeyStore.FLAG_NONE)); + assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_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_KEY_1)); + + assertEquals("Inserted key should be same as retrieved key", + ((RSAPrivateKey) expectedKey).getModulus(), actualKey.getModulus()); + } + + public void testKeyStore_GetKey_Certificate_Encrypted_Failure() throws Exception { + setupPassword(); + mKeyStore.load(null, null); assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1)); @@ -859,21 +982,28 @@ public class AndroidKeyStoreTest extends AndroidTestCase { assertNull("Certificate entries should return null", mKeyStore.getKey(TEST_ALIAS_1, null)); } - public void testKeyStore_GetKey_NonExistent_Failure() throws Exception { + public void testKeyStore_GetKey_NonExistent_Encrypted_Failure() throws Exception { + setupPassword(); + mKeyStore.load(null, null); assertNull("A non-existent entry should return null", mKeyStore.getKey(TEST_ALIAS_1, null)); } - public void testKeyStore_GetProvider_Success() throws Exception { + public void testKeyStore_GetProvider_Encrypted_Success() throws Exception { + assertEquals(AndroidKeyStoreProvider.PROVIDER_NAME, mKeyStore.getProvider().getName()); + setupPassword(); assertEquals(AndroidKeyStoreProvider.PROVIDER_NAME, mKeyStore.getProvider().getName()); } - public void testKeyStore_GetType_Success() throws Exception { + public void testKeyStore_GetType_Encrypted_Success() throws Exception { + assertEquals(AndroidKeyStore.NAME, mKeyStore.getType()); + setupPassword(); assertEquals(AndroidKeyStore.NAME, mKeyStore.getType()); } - public void testKeyStore_IsCertificateEntry_CA_Success() throws Exception { + public void testKeyStore_IsCertificateEntry_CA_Encrypted_Success() throws Exception { + setupPassword(); mKeyStore.load(null, null); assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1)); @@ -882,7 +1012,8 @@ public class AndroidKeyStoreTest extends AndroidTestCase { mKeyStore.isCertificateEntry(TEST_ALIAS_1)); } - public void testKeyStore_IsCertificateEntry_PrivateKey_Failure() throws Exception { + public void testKeyStore_IsCertificateEntry_PrivateKey_Encrypted_Failure() throws Exception { + setupPassword(); mKeyStore.load(null, null); assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1, @@ -894,14 +1025,23 @@ public class AndroidKeyStoreTest extends AndroidTestCase { mKeyStore.isCertificateEntry(TEST_ALIAS_1)); } - public void testKeyStore_IsCertificateEntry_NonExist_Failure() throws Exception { + public void testKeyStore_IsCertificateEntry_NonExist_Encrypted_Failure() throws Exception { + setupPassword(); + mKeyStore.load(null, null); + + assertFalse("Should return false for non-existent entry", + mKeyStore.isCertificateEntry(TEST_ALIAS_1)); + } + + public void testKeyStore_IsCertificateEntry_NonExist_Unencrypted_Failure() throws Exception { mKeyStore.load(null, null); assertFalse("Should return false for non-existent entry", mKeyStore.isCertificateEntry(TEST_ALIAS_1)); } - public void testKeyStore_IsKeyEntry_PrivateKey_Success() throws Exception { + public void testKeyStore_IsKeyEntry_PrivateKey_Encrypted_Success() throws Exception { + setupPassword(); mKeyStore.load(null, null); assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1, @@ -912,7 +1052,8 @@ public class AndroidKeyStoreTest extends AndroidTestCase { assertTrue("Should return true for PrivateKeyEntry", mKeyStore.isKeyEntry(TEST_ALIAS_1)); } - public void testKeyStore_IsKeyEntry_CA_Failure() throws Exception { + public void testKeyStore_IsKeyEntry_CA_Encrypted_Failure() throws Exception { + setupPassword(); mKeyStore.load(null, null); assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1)); @@ -920,17 +1061,19 @@ public class AndroidKeyStoreTest extends AndroidTestCase { assertFalse("Should return false for CA certificate", mKeyStore.isKeyEntry(TEST_ALIAS_1)); } - public void testKeyStore_IsKeyEntry_NonExist_Failure() throws Exception { + public void testKeyStore_IsKeyEntry_NonExist_Encrypted_Failure() throws Exception { + setupPassword(); mKeyStore.load(null, null); assertFalse("Should return false for non-existent entry", mKeyStore.isKeyEntry(TEST_ALIAS_1)); } - public void testKeyStore_SetCertificate_CA_Success() throws Exception { + public void testKeyStore_SetCertificate_CA_Encrypted_Success() throws Exception { final CertificateFactory f = CertificateFactory.getInstance("X.509"); final Certificate actual = f.generateCertificate(new ByteArrayInputStream(FAKE_CA_1)); + setupPassword(); mKeyStore.load(null, null); mKeyStore.setCertificateEntry(TEST_ALIAS_1, actual); @@ -942,7 +1085,8 @@ public class AndroidKeyStoreTest extends AndroidTestCase { retrieved); } - public void testKeyStore_SetCertificate_CAExists_Overwrite_Success() throws Exception { + public void testKeyStore_SetCertificate_CAExists_Overwrite_Encrypted_Success() throws Exception { + setupPassword(); mKeyStore.load(null, null); assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1)); @@ -958,7 +1102,8 @@ public class AndroidKeyStoreTest extends AndroidTestCase { assertAliases(new String[] { TEST_ALIAS_1 }); } - public void testKeyStore_SetCertificate_PrivateKeyExists_Failure() throws Exception { + public void testKeyStore_SetCertificate_PrivateKeyExists_Encrypted_Failure() throws Exception { + setupPassword(); mKeyStore.load(null, null); assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1, @@ -978,7 +1123,8 @@ public class AndroidKeyStoreTest extends AndroidTestCase { } } - public void testKeyStore_SetEntry_PrivateKeyEntry_Success() throws Exception { + public void testKeyStore_SetEntry_PrivateKeyEntry_Encrypted_Success() throws Exception { + setupPassword(); mKeyStore.load(null, null); KeyFactory keyFact = KeyFactory.getInstance("RSA"); @@ -1005,8 +1151,63 @@ public class AndroidKeyStoreTest extends AndroidTestCase { assertPrivateKeyEntryEquals(actual, FAKE_KEY_1, FAKE_USER_1, FAKE_CA_1); } - public void testKeyStore_SetEntry_PrivateKeyEntry_Overwrites_PrivateKeyEntry_Success() + public void testKeyStore_SetEntry_PrivateKeyEntry_Unencrypted_Success() throws Exception { + mKeyStore.load(null, null); + + KeyFactory keyFact = KeyFactory.getInstance("RSA"); + PrivateKey expectedKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_KEY_1)); + + final CertificateFactory f = CertificateFactory.getInstance("X.509"); + + final Certificate[] expectedChain = new Certificate[2]; + expectedChain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_USER_1)); + expectedChain[1] = f.generateCertificate(new ByteArrayInputStream(FAKE_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, FAKE_KEY_1, FAKE_USER_1, FAKE_CA_1); + } + + public void testKeyStore_SetEntry_PrivateKeyEntry_Params_Unencrypted_Failure() throws Exception { + mKeyStore.load(null, null); + + KeyFactory keyFact = KeyFactory.getInstance("RSA"); + PrivateKey expectedKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_KEY_1)); + + final CertificateFactory f = CertificateFactory.getInstance("X.509"); + + final Certificate[] expectedChain = new Certificate[2]; + expectedChain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_USER_1)); + expectedChain[1] = f.generateCertificate(new ByteArrayInputStream(FAKE_CA_1)); + + PrivateKeyEntry entry = new PrivateKeyEntry(expectedKey, expectedChain); + + try { + mKeyStore.setEntry(TEST_ALIAS_1, entry, + new AndroidKeyStoreParameter.Builder(getContext()) + .setEncryptionRequired() + .build()); + fail("Shouldn't be able to insert encrypted entry when KeyStore uninitialized"); + } catch (KeyStoreException expected) { + } + + assertNull(mKeyStore.getEntry(TEST_ALIAS_1, null)); + } + + public void + testKeyStore_SetEntry_PrivateKeyEntry_Overwrites_PrivateKeyEntry_Encrypted_Success() throws Exception { + setupPassword(); mKeyStore.load(null, null); final KeyFactory keyFact = KeyFactory.getInstance("RSA"); @@ -1060,7 +1261,9 @@ public class AndroidKeyStoreTest extends AndroidTestCase { } } - public void testKeyStore_SetEntry_CAEntry_Overwrites_PrivateKeyEntry_Success() throws Exception { + public void testKeyStore_SetEntry_CAEntry_Overwrites_PrivateKeyEntry_Encrypted_Success() + throws Exception { + setupPassword(); mKeyStore.load(null, null); final CertificateFactory f = CertificateFactory.getInstance("X.509"); @@ -1104,7 +1307,9 @@ public class AndroidKeyStoreTest extends AndroidTestCase { } } - public void testKeyStore_SetEntry_PrivateKeyEntry_Overwrites_CAEntry_Success() throws Exception { + public void testKeyStore_SetEntry_PrivateKeyEntry_Overwrites_CAEntry_Encrypted_Success() + throws Exception { + setupPassword(); mKeyStore.load(null, null); final CertificateFactory f = CertificateFactory.getInstance("X.509"); @@ -1148,8 +1353,11 @@ public class AndroidKeyStoreTest extends AndroidTestCase { } } - public void testKeyStore_SetEntry_PrivateKeyEntry_Overwrites_ShortPrivateKeyEntry_Success() + public + void + testKeyStore_SetEntry_PrivateKeyEntry_Overwrites_ShortPrivateKeyEntry_Encrypted_Success() throws Exception { + setupPassword(); mKeyStore.load(null, null); final CertificateFactory f = CertificateFactory.getInstance("X.509"); @@ -1198,7 +1406,9 @@ public class AndroidKeyStoreTest extends AndroidTestCase { } } - public void testKeyStore_SetEntry_CAEntry_Overwrites_CAEntry_Success() throws Exception { + public void testKeyStore_SetEntry_CAEntry_Overwrites_CAEntry_Encrypted_Success() + throws Exception { + setupPassword(); mKeyStore.load(null, null); final CertificateFactory f = CertificateFactory.getInstance("X.509"); @@ -1239,7 +1449,8 @@ public class AndroidKeyStoreTest extends AndroidTestCase { } } - public void testKeyStore_SetKeyEntry_ProtectedKey_Failure() throws Exception { + public void testKeyStore_SetKeyEntry_ProtectedKey_Encrypted_Failure() throws Exception { + setupPassword(); mKeyStore.load(null, null); final CertificateFactory f = CertificateFactory.getInstance("X.509"); @@ -1259,7 +1470,8 @@ public class AndroidKeyStoreTest extends AndroidTestCase { } } - public void testKeyStore_SetKeyEntry_Success() throws Exception { + public void testKeyStore_SetKeyEntry_Encrypted_Success() throws Exception { + setupPassword(); mKeyStore.load(null, null); final CertificateFactory f = CertificateFactory.getInstance("X.509"); @@ -1285,7 +1497,8 @@ public class AndroidKeyStoreTest extends AndroidTestCase { assertPrivateKeyEntryEquals(actual, FAKE_KEY_1, FAKE_USER_1, FAKE_CA_1); } - public void testKeyStore_SetKeyEntry_Replaced_Success() throws Exception { + public void testKeyStore_SetKeyEntry_Replaced_Encrypted_Success() throws Exception { + setupPassword(); mKeyStore.load(null, null); final CertificateFactory f = CertificateFactory.getInstance("X.509"); @@ -1376,7 +1589,8 @@ public class AndroidKeyStoreTest extends AndroidTestCase { return cert; } - public void testKeyStore_SetKeyEntry_ReplacedChain_Success() throws Exception { + public void testKeyStore_SetKeyEntry_ReplacedChain_Encrypted_Success() throws Exception { + setupPassword(); mKeyStore.load(null, null); // Create key #1 @@ -1429,8 +1643,9 @@ public class AndroidKeyStoreTest extends AndroidTestCase { } } - public void testKeyStore_SetKeyEntry_ReplacedChain_DifferentPrivateKey_Failure() + public void testKeyStore_SetKeyEntry_ReplacedChain_DifferentPrivateKey_Encrypted_Failure() throws Exception { + setupPassword(); mKeyStore.load(null, null); // Create key #1 @@ -1472,7 +1687,48 @@ public class AndroidKeyStoreTest extends AndroidTestCase { } } - public void testKeyStore_Size_Success() throws Exception { + public void testKeyStore_SetKeyEntry_ReplacedChain_UnencryptedToEncrypted_Failure() + throws Exception { + 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, android.security.KeyStore.FLAG_NONE)); + + 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 AndroidKeyStoreParameter.Builder( + getContext()).setEncryptionRequired().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 AndroidKeyStoreParameter.Builder(getContext()) + .setEncryptionRequired() + .build()); + } + } + + public void testKeyStore_Size_Encrypted_Success() throws Exception { + setupPassword(); mKeyStore.load(null, null); assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1)); @@ -1501,7 +1757,8 @@ public class AndroidKeyStoreTest extends AndroidTestCase { assertAliases(new String[] { TEST_ALIAS_2 }); } - public void testKeyStore_Store_LoadStoreParam_Failure() throws Exception { + public void testKeyStore_Store_LoadStoreParam_Encrypted_Failure() throws Exception { + setupPassword(); mKeyStore.load(null, null); try { @@ -1511,7 +1768,7 @@ public class AndroidKeyStoreTest extends AndroidTestCase { } } - public void testKeyStore_Load_InputStreamSupplied_Failure() throws Exception { + public void testKeyStore_Load_InputStreamSupplied_Encrypted_Failure() throws Exception { byte[] buf = "FAKE KEYSTORE".getBytes(); ByteArrayInputStream is = new ByteArrayInputStream(buf); @@ -1522,7 +1779,7 @@ public class AndroidKeyStoreTest extends AndroidTestCase { } } - public void testKeyStore_Load_PasswordSupplied_Failure() throws Exception { + public void testKeyStore_Load_PasswordSupplied_Encrypted_Failure() throws Exception { try { mKeyStore.load(null, "password".toCharArray()); fail("Should throw IllegalArgumentException when password is supplied"); @@ -1530,7 +1787,8 @@ public class AndroidKeyStoreTest extends AndroidTestCase { } } - public void testKeyStore_Store_OutputStream_Failure() throws Exception { + public void testKeyStore_Store_OutputStream_Encrypted_Failure() throws Exception { + setupPassword(); mKeyStore.load(null, null); OutputStream sink = new ByteArrayOutputStream(); @@ -1558,7 +1816,8 @@ public class AndroidKeyStoreTest extends AndroidTestCase { cert.getEncoded())); } - public void testKeyStore_KeyOperations_Wrap_Success() throws Exception { + public void testKeyStore_KeyOperations_Wrap_Encrypted_Success() throws Exception { + setupPassword(); mKeyStore.load(null, null); setupKey(); |