Merge "[cbor] Use libcoset/libciborium to convert ed25519 pub key to cbor"
diff --git a/diced/Android.bp b/diced/Android.bp
index 22e069a..24a736d 100644
--- a/diced/Android.bp
+++ b/diced/Android.bp
@@ -25,8 +25,6 @@
     name: "libdiced_utils",
     crate_name: "diced_utils",
     srcs: ["src/utils.rs"],
-    vendor_available: true,
-
     rustlibs: [
         "libanyhow",
     ],
@@ -47,8 +45,6 @@
     name: "libdiced_sample_inputs",
     crate_name: "diced_sample_inputs",
     srcs: ["src/sample_inputs.rs"],
-    vendor_available: true,
-
     rustlibs: [
         "libanyhow",
         "libciborium",
diff --git a/keystore2/src/vintf/lib.rs b/keystore2/src/vintf/lib.rs
index 89e18eb..08384bd 100644
--- a/keystore2/src/vintf/lib.rs
+++ b/keystore2/src/vintf/lib.rs
@@ -19,14 +19,6 @@
     unsafe extern "C++" {
         include!("vintf.hpp");
 
-        /// Gets all HAL names.
-        /// Note that this is not a zero-cost shim: it will make copies of the strings.
-        fn get_hal_names() -> Vec<String>;
-
-        /// Gets all HAL names and versions.
-        /// Note that this is not a zero-cost shim: it will make copies of the strings.
-        fn get_hal_names_and_versions() -> Vec<String>;
-
         /// Gets the instances of the given package, version, and interface tuple.
         /// Note that this is not a zero-cost shim: it will make copies of the strings.
         fn get_hidl_instances(
@@ -43,20 +35,3 @@
 }
 
 pub use ffi::*;
-
-#[cfg(test)]
-mod tests {
-
-    use super::*;
-
-    #[test]
-    fn test() {
-        let names = get_hal_names();
-        assert_ne!(names.len(), 0);
-
-        let names_and_versions = get_hal_names_and_versions();
-        assert_ne!(names_and_versions.len(), 0);
-
-        assert!(names_and_versions.len() >= names.len());
-    }
-}
diff --git a/keystore2/src/vintf/vintf.cpp b/keystore2/src/vintf/vintf.cpp
index 00625bf..a550b10 100644
--- a/keystore2/src/vintf/vintf.cpp
+++ b/keystore2/src/vintf/vintf.cpp
@@ -26,18 +26,6 @@
     return result;
 }
 
-rust::Vec<rust::String> get_hal_names() {
-    const auto manifest = android::vintf::VintfObject::GetDeviceHalManifest();
-    const auto names = manifest->getHalNames();
-    return convert(names);
-}
-
-rust::Vec<rust::String> get_hal_names_and_versions() {
-    const auto manifest = android::vintf::VintfObject::GetDeviceHalManifest();
-    const auto names = manifest->getHalNamesAndVersions();
-    return convert(names);
-}
-
 rust::Vec<rust::String> get_hidl_instances(rust::Str package, size_t major_version,
                                            size_t minor_version, rust::Str interfaceName) {
     android::vintf::Version version(major_version, minor_version);
diff --git a/keystore2/src/vintf/vintf.hpp b/keystore2/src/vintf/vintf.hpp
index dbc88f0..c4a7ef6 100644
--- a/keystore2/src/vintf/vintf.hpp
+++ b/keystore2/src/vintf/vintf.hpp
@@ -18,8 +18,6 @@
 
 #include "rust/cxx.h"
 
-rust::Vec<rust::String> get_hal_names();
-rust::Vec<rust::String> get_hal_names_and_versions();
 rust::Vec<rust::String> get_hidl_instances(rust::Str package, size_t major_version,
                                            size_t minor_version, rust::Str interfaceName);
 rust::Vec<rust::String> get_aidl_instances(rust::Str package, size_t version,
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());
+        })
+    };
+}
diff --git a/keystore2/tests/keystore2_client_update_subcomponent_tests.rs b/keystore2/tests/keystore2_client_update_subcomponent_tests.rs
index c987f22..0be092f 100644
--- a/keystore2/tests/keystore2_client_update_subcomponent_tests.rs
+++ b/keystore2/tests/keystore2_client_update_subcomponent_tests.rs
@@ -80,6 +80,71 @@
     assert_eq!(Error::Rc(ResponseCode::KEY_NOT_FOUND), result.unwrap_err());
 }
 
+/// Try to update non-existing asymmetric key public cert only. Test should fail
+/// to update with error response code `KEY_NOT_FOUND`.
+#[test]
+fn keystore2_update_subcomponent_no_key_entry_cert_fail() {
+    let alias = "update_no_key_entry_cert_only_component_fail_key";
+    let keystore2 = get_keystore_service();
+    let other_cert: [u8; 32] = [123; 32];
+
+    let result = key_generations::map_ks_error(keystore2.updateSubcomponent(
+        &KeyDescriptor {
+            domain: Domain::APP,
+            nspace: -1,
+            alias: Some(alias.to_string()),
+            blob: None,
+        },
+        Some(&other_cert),
+        None,
+    ));
+    assert!(result.is_err());
+    assert_eq!(Error::Rc(ResponseCode::KEY_NOT_FOUND), result.unwrap_err());
+}
+
+/// Try to update non existing key with the only given certificate-chain, test should succeed
+/// in creating a new keystore entry with the given certificate-chain.
+#[test]
+fn keystore2_update_subcomponent_no_key_entry_cert_chain_success() {
+    let alias = "update_no_key_entry_cert_chain_only_component_success";
+    let keystore2 = get_keystore_service();
+    let cert_entries =
+        vec![(Domain::SELINUX, key_generations::SELINUX_SHELL_NAMESPACE), (Domain::APP, -1)];
+    let other_cert_chain: [u8; 32] = [12; 32];
+
+    for (domain, nspace) in cert_entries {
+        keystore2
+            .updateSubcomponent(
+                &KeyDescriptor { domain, nspace, alias: Some(alias.to_string()), blob: None },
+                None,
+                Some(&other_cert_chain),
+            )
+            .expect("updateSubcomponent should have succeeded.");
+
+        let key_entry_response = keystore2
+            .getKeyEntry(&KeyDescriptor {
+                domain,
+                nspace,
+                alias: Some(alias.to_string()),
+                blob: None,
+            })
+            .unwrap();
+        assert_eq!(Some(other_cert_chain.to_vec()), key_entry_response.metadata.certificateChain);
+        assert!(key_entry_response.metadata.certificate.is_none(), "Unexpected certificate entry");
+        assert!(key_entry_response.metadata.authorizations.is_empty(), "Unexpected authorizations");
+        assert_eq!(key_entry_response.metadata.keySecurityLevel, SecurityLevel::SOFTWARE);
+
+        keystore2
+            .deleteKey(&KeyDescriptor {
+                domain,
+                nspace,
+                alias: Some(alias.to_string()),
+                blob: None,
+            })
+            .unwrap();
+    }
+}
+
 /// Generate a key and grant it to two users. For one user grant it with only `GET_INFO` access
 /// permission and for another user grant it with GET_INFO and UPDATE access permissions. In a
 /// grantee context where key is granted with only GET_INFO access permission, try to update