Adding tests using Domain::KEY_ID.
- Test to verify that Domain::KEY_ID is not allowed for generating
a key. Try to generate a key with domain as KEY_ID and expect an
error.
- Test to find key entry with domain as KEY_ID.
Generate a key and load it with domain as KEY_ID. Test should be
able to create an operation using the key loaded with domain as
KEY_ID.
- Generate a key with an alias. Generate another key and bind it with
same alias. Verify that originally generated key no longer exists
and report an error if we try to use it.
- Generate a key with an alias. Load the generated key with domain
KEY_ID. Generate another key and bind it with same alias. Verify
that originally loaded key no longer exists and report an error
if we try to use it.
Bug: 194359114
Test: atest keystore2_client_test
Change-Id: Ibfe237181311decf5f6f00dc222d5cd124e4ac11
diff --git a/keystore2/tests/keystore2_client_tests.rs b/keystore2/tests/keystore2_client_tests.rs
index 0853b5f..671b4ae 100644
--- a/keystore2/tests/keystore2_client_tests.rs
+++ b/keystore2/tests/keystore2_client_tests.rs
@@ -1053,3 +1053,232 @@
// Delete the generated key blob.
sec_level.deleteKey(&key_metadata.key).unwrap();
}
+
+/// Try to generate a key with `Domain::KEY_ID`, test should fail with an error code
+/// `SYSTEM_ERROR`. `Domain::KEY_ID` is not allowed to use for generating a key. Key id is returned
+/// by Keystore2 after a key has been mapped from an alias.
+#[test]
+fn keystore2_generate_key_with_key_id_domain_expect_sys_error() {
+ let alias = "ks_gen_key_id_test_key";
+ let keystore2 = get_keystore_service();
+ let sec_level = keystore2.getSecurityLevel(SecurityLevel::TRUSTED_ENVIRONMENT).unwrap();
+
+ let result = key_generations::map_ks_error(key_generations::generate_ec_key(
+ &*sec_level,
+ Domain::KEY_ID,
+ key_generations::SELINUX_SHELL_NAMESPACE,
+ Some(alias.to_string()),
+ EcCurve::P_256,
+ Digest::SHA_2_256,
+ ));
+ assert!(result.is_err());
+ assert_eq!(Error::Rc(ResponseCode::SYSTEM_ERROR), result.unwrap_err());
+}
+
+/// Generate a key and try to load the generated key using KEY_ID as domain. Create an
+/// operation using key which is loaded with domain as KEY_ID. Test should create an operation
+/// successfully.
+#[test]
+fn keystore2_find_key_with_key_id_as_domain() {
+ let keystore2 = get_keystore_service();
+ let sec_level = keystore2.getSecurityLevel(SecurityLevel::TRUSTED_ENVIRONMENT).unwrap();
+ let alias = "ks_key_id_test_key";
+
+ let key_metadata = key_generations::generate_ec_key(
+ &*sec_level,
+ Domain::APP,
+ -1,
+ Some(alias.to_string()),
+ EcCurve::P_256,
+ Digest::SHA_2_256,
+ )
+ .expect("Failed to generate a EC key.");
+
+ // Try to load the above generated key with KEY_ID as domain.
+ let key_entry_response = keystore2
+ .getKeyEntry(&KeyDescriptor {
+ domain: Domain::KEY_ID,
+ nspace: key_metadata.key.nspace,
+ alias: Some(alias.to_string()),
+ blob: None,
+ })
+ .expect("Error in getKeyEntry to load a key with domain KEY_ID.");
+
+ // Verify above found key is same the one generated.
+ assert_eq!(key_metadata.key, key_entry_response.metadata.key);
+ assert_eq!(key_metadata.certificate, key_entry_response.metadata.certificate);
+ assert_eq!(key_metadata.certificateChain, key_entry_response.metadata.certificateChain);
+ assert_eq!(key_metadata.key.nspace, key_entry_response.metadata.key.nspace);
+
+ // Try to create an operation using above loaded key, operation should be created
+ // successfully.
+ let op_response = sec_level
+ .createOperation(
+ &key_entry_response.metadata.key,
+ &authorizations::AuthSetBuilder::new()
+ .purpose(KeyPurpose::SIGN)
+ .digest(Digest::SHA_2_256),
+ false,
+ )
+ .expect("Error in creation of operation.");
+
+ assert!(op_response.iOperation.is_some());
+ assert_eq!(
+ Ok(()),
+ key_generations::map_ks_error(perform_sample_sign_operation(
+ &op_response.iOperation.unwrap()
+ ))
+ );
+}
+
+/// Generate a key with an alias. Generate another key and bind it to the same alias.
+/// Try to create an operation using previously generated key. Creation of an operation should
+/// fail because previously generated key material is no longer accessible. Test should successfully
+/// create an operation using the rebound key.
+#[test]
+fn keystore2_key_id_alias_rebind_verify_by_alias() {
+ let keystore2 = get_keystore_service();
+ let sec_level = keystore2.getSecurityLevel(SecurityLevel::TRUSTED_ENVIRONMENT).unwrap();
+ let alias = format!("ks_key_id_test_alias_rebind_1_{}", getuid());
+
+ let key_metadata = key_generations::generate_ec_key(
+ &*sec_level,
+ Domain::APP,
+ -1,
+ Some(alias.to_string()),
+ EcCurve::P_256,
+ Digest::SHA_2_256,
+ )
+ .expect("Failed to generate a EC key.");
+
+ // Generate a key with same alias as above generated key, so that alias will be rebound
+ // to this key.
+ let new_key_metadata = key_generations::generate_ec_key(
+ &*sec_level,
+ Domain::APP,
+ -1,
+ Some(alias),
+ EcCurve::P_256,
+ Digest::SHA_2_256,
+ )
+ .expect("Failed to generate a rebound EC key.");
+
+ assert_ne!(key_metadata.key, new_key_metadata.key);
+ assert_ne!(key_metadata.certificate, new_key_metadata.certificate);
+ assert_ne!(key_metadata.key.nspace, new_key_metadata.key.nspace);
+
+ // Try to create an operation using previously generated key_metadata.
+ // It should fail as previously generated key material is no longer remains valid.
+ let result = key_generations::map_ks_error(sec_level.createOperation(
+ &key_metadata.key,
+ &authorizations::AuthSetBuilder::new().purpose(KeyPurpose::SIGN).digest(Digest::SHA_2_256),
+ false,
+ ));
+ assert!(result.is_err());
+ assert_eq!(Error::Rc(ResponseCode::KEY_NOT_FOUND), result.unwrap_err());
+
+ // Try to create an operation using rebound key, operation should be created
+ // successfully.
+ let op_response = sec_level
+ .createOperation(
+ &new_key_metadata.key,
+ &authorizations::AuthSetBuilder::new()
+ .purpose(KeyPurpose::SIGN)
+ .digest(Digest::SHA_2_256),
+ false,
+ )
+ .expect("Error in creation of operation using rebound key.");
+
+ assert!(op_response.iOperation.is_some());
+ assert_eq!(
+ Ok(()),
+ key_generations::map_ks_error(perform_sample_sign_operation(
+ &op_response.iOperation.unwrap()
+ ))
+ );
+}
+
+/// Generate a key with an alias. Load the generated key with `Domain::KEY_ID`. Generate another
+/// key and bind it to the same alias. Try to create an operation using the key loaded with domain
+/// `KEY_ID`. Creation of an operation should fail because originally loaded key no longer exists.
+/// Test should successfully create an operation using the rebound key.
+#[test]
+fn keystore2_key_id_alias_rebind_verify_by_key_id() {
+ let keystore2 = get_keystore_service();
+ let sec_level = keystore2.getSecurityLevel(SecurityLevel::TRUSTED_ENVIRONMENT).unwrap();
+ let alias = format!("ks_key_id_test_alias_rebind_2_{}", getuid());
+
+ let key_metadata = key_generations::generate_ec_key(
+ &*sec_level,
+ Domain::APP,
+ -1,
+ Some(alias.to_string()),
+ EcCurve::P_256,
+ Digest::SHA_2_256,
+ )
+ .expect("Failed to generate a EC key.");
+
+ // Load the above generated key with KEY_ID as domain.
+ let key_entry_response = keystore2
+ .getKeyEntry(&KeyDescriptor {
+ domain: Domain::KEY_ID,
+ nspace: key_metadata.key.nspace,
+ alias: Some(alias.to_string()),
+ blob: None,
+ })
+ .expect("Error in getKeyEntry to load a key with domain KEY_ID.");
+
+ // Verify above found key is same the one generated.
+ assert_eq!(key_metadata.key, key_entry_response.metadata.key);
+ assert_eq!(key_metadata.certificate, key_entry_response.metadata.certificate);
+ assert_eq!(key_metadata.certificateChain, key_entry_response.metadata.certificateChain);
+ assert_eq!(key_metadata.key.nspace, key_entry_response.metadata.key.nspace);
+
+ // Generate another key with same alias as above generated key, so that alias will be rebound
+ // to this key.
+ let new_key_metadata = key_generations::generate_ec_key(
+ &*sec_level,
+ Domain::APP,
+ -1,
+ Some(alias),
+ EcCurve::P_256,
+ Digest::SHA_2_256,
+ )
+ .expect("Failed to generate a rebound EC key.");
+
+ // Verify that an alias is rebound to a new key.
+ assert_eq!(key_metadata.key.alias, new_key_metadata.key.alias);
+ assert_ne!(key_metadata.key, new_key_metadata.key);
+ assert_ne!(key_metadata.certificate, new_key_metadata.certificate);
+ assert_ne!(key_metadata.key.nspace, new_key_metadata.key.nspace);
+
+ // Try to create an operation using previously loaded key_entry_response.
+ // It should fail as previously generated key material is no longer valid.
+ let result = key_generations::map_ks_error(sec_level.createOperation(
+ &key_entry_response.metadata.key,
+ &authorizations::AuthSetBuilder::new().purpose(KeyPurpose::SIGN).digest(Digest::SHA_2_256),
+ false,
+ ));
+ assert!(result.is_err());
+ assert_eq!(Error::Rc(ResponseCode::KEY_NOT_FOUND), result.unwrap_err());
+
+ // Try to create an operation using rebound key, operation should be created
+ // successfully.
+ let op_response = sec_level
+ .createOperation(
+ &new_key_metadata.key,
+ &authorizations::AuthSetBuilder::new()
+ .purpose(KeyPurpose::SIGN)
+ .digest(Digest::SHA_2_256),
+ false,
+ )
+ .expect("Error in creation of operation using rebound key.");
+
+ assert!(op_response.iOperation.is_some());
+ assert_eq!(
+ Ok(()),
+ key_generations::map_ks_error(perform_sample_sign_operation(
+ &op_response.iOperation.unwrap()
+ ))
+ );
+}