Merge "Adding a test to list aliases of large number of Keystore entries with long aliases."
diff --git a/keystore2/tests/keystore2_client_list_entries_tests.rs b/keystore2/tests/keystore2_client_list_entries_tests.rs
index 62e3dd0..3b656c3 100644
--- a/keystore2/tests/keystore2_client_list_entries_tests.rs
+++ b/keystore2/tests/keystore2_client_list_entries_tests.rs
@@ -14,6 +14,8 @@
use nix::unistd::{getuid, Gid, Uid};
use rustutils::users::AID_USER_OFFSET;
+use std::collections::HashSet;
+use std::fmt::Write;
use android_hardware_security_keymint::aidl::android::hardware::security::keymint::SecurityLevel::SecurityLevel;
use android_system_keystore2::aidl::android::system::keystore2::{
@@ -21,6 +23,7 @@
KeyPermission::KeyPermission, ResponseCode::ResponseCode,
};
+use crate::keystore2_client_test_utils::delete_app_key;
use keystore2_test_utils::{get_keystore_service, key_generations, key_generations::Error, run_as};
/// Try to find a key with given key parameters using `listEntries` API.
@@ -183,3 +186,68 @@
assert!(result.is_err());
assert_eq!(Error::Rc(ResponseCode::INVALID_ARGUMENT), result.unwrap_err());
}
+
+/// Import large number of Keystore entries with long aliases and try to list aliases
+/// of all the entries in the keystore.
+#[test]
+fn keystore2_list_entries_with_long_aliases_success() {
+ static CLIENT_CTX: &str = "u:r:untrusted_app:s0:c91,c256,c10,c20";
+
+ const USER_ID: u32 = 92;
+ const APPLICATION_ID: u32 = 10002;
+ static CLIENT_UID: u32 = USER_ID * AID_USER_OFFSET + APPLICATION_ID;
+ static CLIENT_GID: u32 = CLIENT_UID;
+
+ unsafe {
+ run_as::run_as(CLIENT_CTX, Uid::from_raw(CLIENT_UID), Gid::from_raw(CLIENT_GID), || {
+ let keystore2 = get_keystore_service();
+ let sec_level = keystore2.getSecurityLevel(SecurityLevel::TRUSTED_ENVIRONMENT).unwrap();
+
+ // Make sure there are no keystore entries exist before adding new entries.
+ let key_descriptors = keystore2.listEntries(Domain::APP, -1).unwrap();
+ if !key_descriptors.is_empty() {
+ key_descriptors.into_iter().map(|key| key.alias.unwrap()).for_each(|alias| {
+ delete_app_key(&keystore2, &alias).unwrap();
+ });
+ }
+
+ let mut imported_key_aliases = HashSet::new();
+
+ // Import 100 keys with aliases of length 6000.
+ for count in 1..101 {
+ let mut alias = String::new();
+ write!(alias, "{}_{}", "X".repeat(6000), count).unwrap();
+ imported_key_aliases.insert(alias.clone());
+
+ let result =
+ key_generations::import_aes_key(&sec_level, Domain::APP, -1, Some(alias));
+ assert!(result.is_ok());
+ }
+
+ // b/222287335 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 entries from Keystore
+ // - check whether the retrieved key entries list is a subset of imported key aliases
+ // - delete this subset of keystore entries from Keystore as well as from imported
+ // list of key aliases
+ // - continue above steps till it cleanup all the imported keystore entries.
+ while !imported_key_aliases.is_empty() {
+ let key_descriptors = keystore2.listEntries(Domain::APP, -1).unwrap();
+
+ // Check retrieved key entries list is a subset of imported keys list.
+ assert!(key_descriptors
+ .iter()
+ .all(|key| imported_key_aliases.contains(key.alias.as_ref().unwrap())));
+
+ // Delete the listed key entries from Keystore as well as from imported keys list.
+ key_descriptors.into_iter().map(|key| key.alias.unwrap()).for_each(|alias| {
+ delete_app_key(&keystore2, &alias).unwrap();
+ assert!(imported_key_aliases.remove(&alias));
+ });
+ }
+
+ assert!(imported_key_aliases.is_empty());
+ })
+ };
+}