diff options
Diffstat (limited to 'tests/tests/keystore/src/android/keystore/cts/AndroidKeyStoreTest.java')
-rw-r--r-- | tests/tests/keystore/src/android/keystore/cts/AndroidKeyStoreTest.java | 206 |
1 files changed, 30 insertions, 176 deletions
diff --git a/tests/tests/keystore/src/android/keystore/cts/AndroidKeyStoreTest.java b/tests/tests/keystore/src/android/keystore/cts/AndroidKeyStoreTest.java index bf2e941bfa5..56dd1b0f561 100644 --- a/tests/tests/keystore/src/android/keystore/cts/AndroidKeyStoreTest.java +++ b/tests/tests/keystore/src/android/keystore/cts/AndroidKeyStoreTest.java @@ -16,13 +16,11 @@ package android.keystore.cts; -import static com.google.common.truth.Truth.assertThat; - import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; @@ -39,13 +37,6 @@ import android.util.Log; import androidx.test.InstrumentationRegistry; import androidx.test.runner.AndroidJUnit4; -import com.android.bedstead.nene.annotations.Nullable; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; - import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.OutputStream; @@ -72,7 +63,6 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; import java.util.Collection; -import java.util.Collections; import java.util.Date; import java.util.Enumeration; import java.util.HashSet; @@ -88,6 +78,11 @@ import javax.crypto.Mac; import javax.crypto.SecretKey; import javax.security.auth.x500.X500Principal; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + @RunWith(AndroidJUnit4.class) public class AndroidKeyStoreTest { private static final String TAG = AndroidKeyStoreTest.class.getSimpleName(); @@ -828,12 +823,6 @@ public class AndroidKeyStoreTest { expectedAliases.length, count); } - private void deleteEntryIfNotNull(@Nullable String alias) throws Exception { - if (alias != null) { - mKeyStore.deleteEntry(alias); - } - } - @Test public void testKeyStore_Aliases_Unencrypted_Success() throws Exception { mKeyStore.load(null, null); @@ -2172,9 +2161,8 @@ public class AndroidKeyStoreTest { PrivateKey privateKey3 = generatePrivateKey("RSA", FAKE_RSA_KEY_1); final int MAX_NUMBER_OF_KEYS = 2500; - final StringBuilder aliasPrefix = new StringBuilder("test_large_number_of_rsa_keys_"); + final String ALIAS_PREFIX = "test_large_number_of_rsa_keys_"; int keyCount = 0; - String entryName2 = null; mKeyStore.load(null); try { @@ -2187,12 +2175,11 @@ public class AndroidKeyStoreTest { new KeyStore.PrivateKeyEntry(privateKey1, new Certificate[] {cert1}), protectionParams); - keyCount = importKeyManyTimes(MAX_NUMBER_OF_KEYS, aliasPrefix, - new PrivateKeyEntry(privateKey3, new Certificate[] {cert3}), - protectionParams); + keyCount = importKeyManyTimes(MAX_NUMBER_OF_KEYS, ALIAS_PREFIX, + new PrivateKeyEntry(privateKey3, new Certificate[] {cert3}), protectionParams); keyCount++; - entryName2 = "test" + keyCount; + String entryName2 = "test" + keyCount; mKeyStore.setEntry(entryName2, new KeyStore.PrivateKeyEntry(privateKey2, new Certificate[] {cert2}), protectionParams); @@ -2219,9 +2206,7 @@ public class AndroidKeyStoreTest { sig.update(message); assertTrue(sig.verify(signature)); } finally { - mKeyStore.deleteEntry(entryName1); - deleteEntryIfNotNull(entryName2); - deleteManyTestKeys(keyCount, aliasPrefix); + deleteManyTestKeys(keyCount, ALIAS_PREFIX); } } @@ -2250,9 +2235,8 @@ public class AndroidKeyStoreTest { PrivateKey privateKey3 = generatePrivateKey("EC", FAKE_EC_KEY_1); final int MAX_NUMBER_OF_KEYS = 2500; - final StringBuilder aliasPrefix = new StringBuilder("test_large_number_of_ec_keys_"); + final String ALIAS_PREFIX = "test_large_number_of_ec_keys_"; int keyCount = 0; - String entryName2 = null; mKeyStore.load(null); try { @@ -2264,12 +2248,12 @@ public class AndroidKeyStoreTest { new KeyStore.PrivateKeyEntry(privateKey1, new Certificate[] {cert1}), protectionParams); - keyCount = importKeyManyTimes(MAX_NUMBER_OF_KEYS, aliasPrefix, + keyCount = importKeyManyTimes(MAX_NUMBER_OF_KEYS, ALIAS_PREFIX, new KeyStore.PrivateKeyEntry(privateKey3, new Certificate[] {cert3}), protectionParams); keyCount++; - entryName2 = "test" + keyCount; + String entryName2 = "test" + keyCount; mKeyStore.setEntry(entryName2, new KeyStore.PrivateKeyEntry(privateKey2, new Certificate[] {cert2}), protectionParams); @@ -2296,9 +2280,7 @@ public class AndroidKeyStoreTest { sig.update(message); assertTrue(sig.verify(signature)); } finally { - mKeyStore.deleteEntry(entryName1); - deleteEntryIfNotNull(entryName2); - deleteManyTestKeys(keyCount, aliasPrefix); + deleteManyTestKeys(keyCount, ALIAS_PREFIX); } } @@ -2325,9 +2307,8 @@ public class AndroidKeyStoreTest { HexEncoding.decode("33333333333333333333777777777777"), "AES"); final int MAX_NUMBER_OF_KEYS = 10000; - final StringBuilder aliasPrefix = new StringBuilder("test_large_number_of_aes_keys_"); + final String ALIAS_PREFIX = "test_large_number_of_aes_keys_"; int keyCount = 0; - String entryName2 = null; mKeyStore.load(null); try { @@ -2338,11 +2319,11 @@ public class AndroidKeyStoreTest { .build(); mKeyStore.setEntry(entryName1, new KeyStore.SecretKeyEntry(key1), protectionParams); - keyCount = importKeyManyTimes(MAX_NUMBER_OF_KEYS, aliasPrefix, + keyCount = importKeyManyTimes(MAX_NUMBER_OF_KEYS, ALIAS_PREFIX, new KeyStore.SecretKeyEntry(key3), protectionParams); ++keyCount; - entryName2 = "test" + keyCount; + String entryName2 = "test" + keyCount; mKeyStore.setEntry(entryName2, new KeyStore.SecretKeyEntry(key2), protectionParams); SecretKey keystoreKey2 = (SecretKey) mKeyStore.getKey(entryName2, null); SecretKey keystoreKey1 = (SecretKey) mKeyStore.getKey(entryName1, null); @@ -2364,9 +2345,7 @@ public class AndroidKeyStoreTest { cipher.init(Cipher.DECRYPT_MODE, key2, cipherParams); assertArrayEquals(plaintext, cipher.doFinal(ciphertext)); } finally { - mKeyStore.deleteEntry(entryName1); - deleteEntryIfNotNull(entryName2); - deleteManyTestKeys(keyCount, aliasPrefix); + deleteManyTestKeys(keyCount, ALIAS_PREFIX); } } @@ -2395,9 +2374,8 @@ public class AndroidKeyStoreTest { HexEncoding.decode("33333333333333333333777777777777"), "HmacSHA256"); final int MAX_NUMBER_OF_KEYS = 10000; - final StringBuilder aliasPrefix = new StringBuilder("test_large_number_of_hmac_keys_"); + final String ALIAS_PREFIX = "test_large_number_of_hmac_keys_"; int keyCount = 0; - String entryName2 = null; mKeyStore.load(null); try { @@ -2406,11 +2384,11 @@ public class AndroidKeyStoreTest { .build(); mKeyStore.setEntry(entryName1, new KeyStore.SecretKeyEntry(key1), protectionParams); - keyCount = importKeyManyTimes(MAX_NUMBER_OF_KEYS, aliasPrefix, + keyCount = importKeyManyTimes(MAX_NUMBER_OF_KEYS, ALIAS_PREFIX, new KeyStore.SecretKeyEntry(key3), protectionParams); keyCount++; - entryName2 = "test" + keyCount; + String entryName2 = "test" + keyCount; mKeyStore.setEntry(entryName2, new KeyStore.SecretKeyEntry(key2), protectionParams); SecretKey keystoreKey2 = (SecretKey) mKeyStore.getKey(entryName2, null); SecretKey keystoreKey1 = (SecretKey) mKeyStore.getKey(entryName1, null); @@ -2430,9 +2408,7 @@ public class AndroidKeyStoreTest { "59b57e77e4e2cb36b5c7b84af198ac004327bc549de6931a1b5505372dd8c957"), mac.doFinal(message)); } finally { - mKeyStore.deleteEntry(entryName1); - deleteEntryIfNotNull(entryName2); - deleteManyTestKeys(keyCount, aliasPrefix); + deleteManyTestKeys(keyCount, ALIAS_PREFIX); } } @@ -2630,8 +2606,8 @@ public class AndroidKeyStoreTest { * * This method is time-bounded */ - private int importKeyManyTimes(int numberOfKeys, StringBuilder aliasPrefix, Entry keyEntry, - KeyProtection protectionParams, boolean isTimeBound) + private int importKeyManyTimes(int numberOfKeys, String aliasPrefix, Entry keyEntry, + KeyProtection protectionParams) throws InterruptedException { TimeBox timeBox = new TimeBox(mMaxImportDuration); AtomicInteger keyCounter = new AtomicInteger(0); @@ -2640,7 +2616,7 @@ public class AndroidKeyStoreTest { threads.add(new Thread(() -> { // Import key lots of times, under different aliases. Do this until we either run // out of time or we import the key numberOfKeys times. - while (!isTimeBound || !timeBox.isOutOfTime()) { + while (!timeBox.isOutOfTime()) { int count = keyCounter.incrementAndGet(); if (count > numberOfKeys) { // The loop is inherently racy, as multiple threads are simultaneously @@ -2653,7 +2629,7 @@ public class AndroidKeyStoreTest { if ((count % 1000) == 0) { Log.i(TAG, "Imported " + count + " keys"); } - String entryAlias = aliasPrefix.toString() + count; + String entryAlias = aliasPrefix + count; try { mKeyStore.setEntry(entryAlias, keyEntry, protectionParams); } catch (Throwable e) { @@ -2670,7 +2646,7 @@ public class AndroidKeyStoreTest { threads.get(i).join(); } Log.i(TAG, "Imported " + keyCounter.get() + " keys in " + timeBox.elapsed()); - if (keyCounter.get() != numberOfKeys && keyCounter.get() < MIN_SUPPORTED_KEY_COUNT) { + if (keyCounter.get() < MIN_SUPPORTED_KEY_COUNT) { fail("Failed to import " + MIN_SUPPORTED_KEY_COUNT + " keys in " + timeBox.elapsed() + ". Imported: " + keyCounter.get() + " keys"); } @@ -2678,22 +2654,11 @@ public class AndroidKeyStoreTest { return keyCounter.get(); } - private int importKeyManyTimes(int numberOfKeys, StringBuilder aliasPrefix, Entry keyEntry, - KeyProtection protectionParams) throws InterruptedException { - return importKeyManyTimes(numberOfKeys, aliasPrefix, keyEntry, protectionParams, true); - } - - private int importKeyManyTimesWithoutTimeLimit(int numberOfKeys, StringBuilder aliasPrefix, - Entry keyEntry, - KeyProtection protectionParams) throws InterruptedException { - return importKeyManyTimes(numberOfKeys, aliasPrefix, keyEntry, protectionParams, false); - } - /** * Delete <code>numberOfKeys</code> keys that follow the pattern "[aliasPrefix][keyCounter]". * This is done across multiple threads to both increase throughput as well as stress keystore. */ - private void deleteManyTestKeys(int numberOfKeys, StringBuilder aliasPrefix) + private void deleteManyTestKeys(int numberOfKeys, String aliasPrefix) throws InterruptedException { // Clean up Keystore without using KeyStore.aliases() which can't handle this many // entries. @@ -2708,9 +2673,8 @@ public class AndroidKeyStoreTest { if ((key > 0) && ((key % 1000) == 0)) { Log.i(TAG, "Deleted " + key + " keys"); } - String entryAlias = aliasPrefix.toString() + key; try { - mKeyStore.deleteEntry(entryAlias); + mKeyStore.deleteEntry("test" + key); } catch (Exception e) { fail("Unexpected exception in key cleanup: " + e); } @@ -2726,114 +2690,4 @@ public class AndroidKeyStoreTest { } Log.i(TAG, "Deleted " + numberOfKeys + " keys"); } - - private Set<String> createLargeNumberOfKeyStoreEntryAliases(int numberOfKeys, - StringBuilder aliasPrefix) - throws Exception { - Certificate cert = generateCertificate(FAKE_RSA_USER_1); - PrivateKey privateKey = generatePrivateKey("RSA", FAKE_RSA_KEY_1); - - mKeyStore.load(null); - KeyProtection protectionParams = new KeyProtection.Builder( - KeyProperties.PURPOSE_SIGN) - .setDigests(KeyProperties.DIGEST_SHA256) - .setSignaturePaddings(KeyProperties.SIGNATURE_PADDING_RSA_PKCS1) - .build(); - - int keyCount = importKeyManyTimesWithoutTimeLimit(numberOfKeys, aliasPrefix, - new PrivateKeyEntry(privateKey, new Certificate[]{cert}), protectionParams); - - // Construct expected aliases list. - final Set<String> expectedAliases = new HashSet<>(keyCount); - for (int count = 1; count <= keyCount; count++) { - String entryAlias = aliasPrefix.toString() + count; - expectedAliases.add(entryAlias); - } - - return expectedAliases; - } - - private void importLargeNumberOfKeysValidateAliases(int numberOfKeys, StringBuilder aliasPrefix) - throws Exception { - Set<String> importedKeyAliases = createLargeNumberOfKeyStoreEntryAliases(numberOfKeys, - aliasPrefix); - assertThat(importedKeyAliases.size()).isEqualTo(numberOfKeys); - - try { - // b/222287335 Currently, limiting Keystore `listEntries` API to return subset of the - // Keystore entries to avoid running out of binder buffer space. - // To verify that all the imported key aliases are present in Keystore, get the list of - // aliases from Keystore, delete the matched aliases from Keystore and imported list of - // key aliases, continue this till all the imported key aliases are matched. - while (!importedKeyAliases.isEmpty()) { - // List the keystore entries aliases until all the imported key aliases are matched. - Set<String> aliases = new HashSet<String>(Collections.list(mKeyStore.aliases())); - - // Try to match the aliases with imported key aliases. - // Cleanup matching aliases from Keystore and imported key aliases list. - for (String alias: aliases) { - if (importedKeyAliases.contains(alias)) { - mKeyStore.deleteEntry(alias); - importedKeyAliases.remove(alias); - } - } - } - assertTrue("Failed to match imported keystore entries.", - importedKeyAliases.isEmpty()); - } finally { - if (!importedKeyAliases.isEmpty()) { - Log.i(TAG, "Final cleanup of imported keys"); - for (String alias: importedKeyAliases) { - mKeyStore.deleteEntry(alias); - } - } - } - assertTrue(importedKeyAliases.isEmpty()); - } - - /** - * Create long alias prefix of length 6000 characters. - */ - private StringBuilder createLongAliasPrefix() { - char[] prefixChar = new char[6000]; - Arrays.fill(prefixChar, 'T'); - StringBuilder prefixAlias = new StringBuilder(); - prefixAlias.append(prefixChar); - - return prefixAlias; - } - - /** - * Create large number of Keystore entries with long aliases and try to list aliases of all the - * entries in the keystore. - */ - @Test - public void testKeyStore_LargeNumberOfLongAliases() throws Exception { - final int maxNumberOfKeys = 100; - - importLargeNumberOfKeysValidateAliases(maxNumberOfKeys, createLongAliasPrefix()); - } - - /** - * Create limited number of Keystore entries with long aliases and try to list aliases of all - * the entries in the keystore. Test should successfully list all the Keystore entries aliases. - */ - @Test - public void testKeyStore_LimitedNumberOfLongAliasesSuccess() throws Exception { - final int maxNumberOfKeys = 10; - importLargeNumberOfKeysValidateAliases(maxNumberOfKeys, createLongAliasPrefix()); - } - - /** - * Create large number of Keystore entries with short length aliases and try to list aliases of - * all the entries in the keystore. Test should successfully list all the Keystore entries - * aliases. - */ - @Test - public void testKeyStore_LargeNumberShortAliasesSuccess() throws Exception { - final int maxNumberOfKeys = 2500; - final StringBuilder aliasPrefix = new StringBuilder("test_short_key_alias_"); - - importLargeNumberOfKeysValidateAliases(maxNumberOfKeys, aliasPrefix); - } } |