Minimize unsafe blocks
Use named rather than inline lambdas to minimize the amount of code that
needs to be inside an `unsafe` block. Pure refactor, no code change.
Also update safety comments.
Test: keystore2_client_tests
Flag: none, pure refactor of test code
Change-Id: Id10efe4ebad37656222e1f3440e60d526a7ab59a
diff --git a/keystore2/tests/keystore2_client_attest_key_tests.rs b/keystore2/tests/keystore2_client_attest_key_tests.rs
index 033036b..d93573a 100644
--- a/keystore2/tests/keystore2_client_attest_key_tests.rs
+++ b/keystore2/tests/keystore2_client_attest_key_tests.rs
@@ -661,41 +661,44 @@
static APP_UID: u32 = USER_ID * AID_USER_OFFSET + APPLICATION_ID;
static APP_GID: u32 = APP_UID;
- // SAFETY: The test is run in a separate process with no other threads.
+ let gen_key_fn = || {
+ skip_test_if_no_app_attest_key_feature!();
+ let sl = SecLevel::tee();
+ if sl.keystore2.getInterfaceVersion().unwrap() < 4 {
+ // `GET_ATTESTATION_APPLICATION_ID_FAILED` is supported on devices with
+ // `IKeystoreService` version >= 4.
+ return;
+ }
+ let att_challenge: &[u8] = b"foo";
+ let alias = format!("ks_attest_rsa_encrypt_key_aaid_fail{}", getuid());
+
+ let result = key_generations::map_ks_error(key_generations::generate_rsa_key(
+ &sl,
+ Domain::APP,
+ -1,
+ Some(alias),
+ &key_generations::KeyParams {
+ key_size: 2048,
+ purpose: vec![KeyPurpose::ATTEST_KEY],
+ padding: Some(PaddingMode::RSA_PKCS1_1_5_SIGN),
+ digest: Some(Digest::SHA_2_256),
+ mgf_digest: None,
+ block_mode: None,
+ att_challenge: Some(att_challenge.to_vec()),
+ },
+ None,
+ ));
+
+ assert!(result.is_err());
+ assert_eq!(
+ result.unwrap_err(),
+ Error::Rc(ResponseCode::GET_ATTESTATION_APPLICATION_ID_FAILED)
+ );
+ };
+
+ // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
+ // `--test-threads=1`), and nothing yet done with binder.
unsafe {
- run_as::run_as(APP_USER_CTX, Uid::from_raw(APP_UID), Gid::from_raw(APP_GID), || {
- skip_test_if_no_app_attest_key_feature!();
- let sl = SecLevel::tee();
- if sl.keystore2.getInterfaceVersion().unwrap() < 4 {
- // `GET_ATTESTATION_APPLICATION_ID_FAILED` is supported on devices with
- // `IKeystoreService` version >= 4.
- return;
- }
- let att_challenge: &[u8] = b"foo";
- let alias = format!("ks_attest_rsa_encrypt_key_aaid_fail{}", getuid());
-
- let result = key_generations::map_ks_error(key_generations::generate_rsa_key(
- &sl,
- Domain::APP,
- -1,
- Some(alias),
- &key_generations::KeyParams {
- key_size: 2048,
- purpose: vec![KeyPurpose::ATTEST_KEY],
- padding: Some(PaddingMode::RSA_PKCS1_1_5_SIGN),
- digest: Some(Digest::SHA_2_256),
- mgf_digest: None,
- block_mode: None,
- att_challenge: Some(att_challenge.to_vec()),
- },
- None,
- ));
-
- assert!(result.is_err());
- assert_eq!(
- result.unwrap_err(),
- Error::Rc(ResponseCode::GET_ATTESTATION_APPLICATION_ID_FAILED)
- );
- })
+ run_as::run_as(APP_USER_CTX, Uid::from_raw(APP_UID), Gid::from_raw(APP_GID), gen_key_fn)
};
}
diff --git a/keystore2/tests/keystore2_client_ec_key_tests.rs b/keystore2/tests/keystore2_client_ec_key_tests.rs
index 8aa9bc4..2ae65b2 100644
--- a/keystore2/tests/keystore2_client_ec_key_tests.rs
+++ b/keystore2/tests/keystore2_client_ec_key_tests.rs
@@ -425,7 +425,9 @@
// Client#1: Generate a key and create an operation using generated key.
// Wait until the parent notifies to continue. Once the parent notifies, this operation
// is expected to be completed successfully.
- // SAFETY: The test is run in a separate process with no other threads.
+
+ // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
+ // `--test-threads=1`), and nothing yet done with binder.
let mut child_handle = unsafe {
execute_op_run_as_child(
TARGET_CTX,
@@ -446,20 +448,23 @@
const APPLICATION_ID_2: u32 = 10602;
let uid2 = USER_ID * AID_USER_OFFSET + APPLICATION_ID_2;
let gid2 = USER_ID * AID_USER_OFFSET + APPLICATION_ID_2;
- // SAFETY: The test is run in a separate process with no other threads.
+
+ let get_key_fn = move || {
+ let keystore2_inst = get_keystore_service();
+ let result = key_generations::map_ks_error(keystore2_inst.getKeyEntry(&KeyDescriptor {
+ domain: Domain::APP,
+ nspace: -1,
+ alias: Some(alias.to_string()),
+ blob: None,
+ }));
+ assert!(result.is_err());
+ assert_eq!(Error::Rc(ResponseCode::KEY_NOT_FOUND), result.unwrap_err());
+ };
+
+ // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
+ // `--test-threads=1`), and nothing yet done with binder.
unsafe {
- run_as::run_as(TARGET_CTX, Uid::from_raw(uid2), Gid::from_raw(gid2), move || {
- let keystore2_inst = get_keystore_service();
- let result =
- key_generations::map_ks_error(keystore2_inst.getKeyEntry(&KeyDescriptor {
- domain: Domain::APP,
- nspace: -1,
- alias: Some(alias.to_string()),
- blob: None,
- }));
- assert!(result.is_err());
- assert_eq!(Error::Rc(ResponseCode::KEY_NOT_FOUND), result.unwrap_err());
- });
+ run_as::run_as(TARGET_CTX, Uid::from_raw(uid2), Gid::from_raw(gid2), get_key_fn);
};
// Notify the child process (client#1) to resume and finish.
diff --git a/keystore2/tests/keystore2_client_grant_key_tests.rs b/keystore2/tests/keystore2_client_grant_key_tests.rs
index 89569f5..853790e 100644
--- a/keystore2/tests/keystore2_client_grant_key_tests.rs
+++ b/keystore2/tests/keystore2_client_grant_key_tests.rs
@@ -108,43 +108,48 @@
static GRANTEE_UID: u32 = USER_ID * AID_USER_OFFSET + APPLICATION_ID;
static GRANTEE_GID: u32 = GRANTEE_UID;
- // SAFETY: The test is run in a separate process with no other threads.
- let grant_key_nspace = unsafe {
- run_as::run_as(TARGET_SU_CTX, Uid::from_raw(0), Gid::from_raw(0), || {
- let empty_access_vector = KeyPermission::NONE.0;
+ let grantor_fn = || {
+ let empty_access_vector = KeyPermission::NONE.0;
- let grant_key = key_generations::map_ks_error(generate_ec_key_and_grant_to_user(
- GRANTEE_UID.try_into().unwrap(),
- empty_access_vector,
- ))
- .unwrap();
+ let grant_key = key_generations::map_ks_error(generate_ec_key_and_grant_to_user(
+ GRANTEE_UID.try_into().unwrap(),
+ empty_access_vector,
+ ))
+ .unwrap();
- assert_eq!(grant_key.domain, Domain::GRANT);
+ assert_eq!(grant_key.domain, Domain::GRANT);
- grant_key.nspace
- })
+ grant_key.nspace
};
+ // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
+ // `--test-threads=1`), and nothing yet done with binder.
+ let grant_key_nspace =
+ unsafe { run_as::run_as(TARGET_SU_CTX, Uid::from_raw(0), Gid::from_raw(0), grantor_fn) };
+
// In grantee context try to load the key, it should fail to load the granted key as it is
// granted with empty access vector.
- // SAFETY: The test is run in a separate process with no other threads.
+ let grantee_fn = move || {
+ let keystore2 = get_keystore_service();
+
+ let result = key_generations::map_ks_error(keystore2.getKeyEntry(&KeyDescriptor {
+ domain: Domain::GRANT,
+ nspace: grant_key_nspace,
+ alias: None,
+ blob: None,
+ }));
+ assert!(result.is_err());
+ assert_eq!(Error::Rc(ResponseCode::PERMISSION_DENIED), result.unwrap_err());
+ };
+
+ // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
+ // `--test-threads=1`), and nothing yet done with binder.
unsafe {
run_as::run_as(
GRANTEE_CTX,
Uid::from_raw(GRANTEE_UID),
Gid::from_raw(GRANTEE_GID),
- move || {
- let keystore2 = get_keystore_service();
-
- let result = key_generations::map_ks_error(keystore2.getKeyEntry(&KeyDescriptor {
- domain: Domain::GRANT,
- nspace: grant_key_nspace,
- alias: None,
- blob: None,
- }));
- assert!(result.is_err());
- assert_eq!(Error::Rc(ResponseCode::PERMISSION_DENIED), result.unwrap_err());
- },
+ grantee_fn,
)
};
}
@@ -165,73 +170,77 @@
static GRANTEE_GID: u32 = GRANTEE_UID;
// Generate a key and grant it to a user with GET_INFO|USE key permissions.
- // SAFETY: The test is run in a separate process with no other threads.
- let grant_key_nspace = unsafe {
- run_as::run_as(TARGET_SU_CTX, Uid::from_raw(0), Gid::from_raw(0), || {
- let access_vector = KeyPermission::GET_INFO.0 | KeyPermission::USE.0;
- let grant_key = key_generations::map_ks_error(generate_ec_key_and_grant_to_user(
- GRANTEE_UID.try_into().unwrap(),
- access_vector,
- ))
- .unwrap();
+ let grantor_fn = || {
+ let access_vector = KeyPermission::GET_INFO.0 | KeyPermission::USE.0;
+ let grant_key = key_generations::map_ks_error(generate_ec_key_and_grant_to_user(
+ GRANTEE_UID.try_into().unwrap(),
+ access_vector,
+ ))
+ .unwrap();
- assert_eq!(grant_key.domain, Domain::GRANT);
+ assert_eq!(grant_key.domain, Domain::GRANT);
- grant_key.nspace
- })
+ grant_key.nspace
};
+ // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
+ // `--test-threads=1`), and nothing yet done with binder.
+ let grant_key_nspace =
+ unsafe { run_as::run_as(TARGET_SU_CTX, Uid::from_raw(0), Gid::from_raw(0), grantor_fn) };
+
// In grantee context load the key and try to perform crypto operation.
- // SAFETY: The test is run in a separate process with no other threads.
+ let grantee_fn = move || {
+ let sl = SecLevel::tee();
+
+ // Load the granted key.
+ let key_entry_response = sl
+ .keystore2
+ .getKeyEntry(&KeyDescriptor {
+ domain: Domain::GRANT,
+ nspace: grant_key_nspace,
+ alias: None,
+ blob: None,
+ })
+ .unwrap();
+
+ // Perform sample crypto operation using granted key.
+ let op_response = sl
+ .binder
+ .createOperation(
+ &key_entry_response.metadata.key,
+ &authorizations::AuthSetBuilder::new()
+ .purpose(KeyPurpose::SIGN)
+ .digest(Digest::SHA_2_256),
+ false,
+ )
+ .unwrap();
+ assert!(op_response.iOperation.is_some());
+ assert_eq!(
+ Ok(()),
+ key_generations::map_ks_error(perform_sample_sign_operation(
+ &op_response.iOperation.unwrap()
+ ))
+ );
+
+ // Try to delete the key, it is expected to be fail with permission denied error.
+ let result = key_generations::map_ks_error(sl.keystore2.deleteKey(&KeyDescriptor {
+ domain: Domain::GRANT,
+ nspace: grant_key_nspace,
+ alias: None,
+ blob: None,
+ }));
+ assert!(result.is_err());
+ assert_eq!(Error::Rc(ResponseCode::PERMISSION_DENIED), result.unwrap_err());
+ };
+
+ // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
+ // `--test-threads=1`), and nothing yet done with binder.
unsafe {
run_as::run_as(
GRANTEE_CTX,
Uid::from_raw(GRANTEE_UID),
Gid::from_raw(GRANTEE_GID),
- move || {
- let sl = SecLevel::tee();
-
- // Load the granted key.
- let key_entry_response = sl
- .keystore2
- .getKeyEntry(&KeyDescriptor {
- domain: Domain::GRANT,
- nspace: grant_key_nspace,
- alias: None,
- blob: None,
- })
- .unwrap();
-
- // Perform sample crypto operation using granted key.
- let op_response = sl
- .binder
- .createOperation(
- &key_entry_response.metadata.key,
- &authorizations::AuthSetBuilder::new()
- .purpose(KeyPurpose::SIGN)
- .digest(Digest::SHA_2_256),
- false,
- )
- .unwrap();
- assert!(op_response.iOperation.is_some());
- assert_eq!(
- Ok(()),
- key_generations::map_ks_error(perform_sample_sign_operation(
- &op_response.iOperation.unwrap()
- ))
- );
-
- // Try to delete the key, it is expected to be fail with permission denied error.
- let result =
- key_generations::map_ks_error(sl.keystore2.deleteKey(&KeyDescriptor {
- domain: Domain::GRANT,
- nspace: grant_key_nspace,
- alias: None,
- blob: None,
- }));
- assert!(result.is_err());
- assert_eq!(Error::Rc(ResponseCode::PERMISSION_DENIED), result.unwrap_err());
- },
+ grantee_fn,
)
};
}
@@ -250,60 +259,65 @@
static ALIAS: &str = "ks_grant_key_delete_success";
// Generate a key and grant it to a user with DELETE permission.
- // SAFETY: The test is run in a separate process with no other threads.
- let grant_key_nspace = unsafe {
- run_as::run_as(GRANTOR_SU_CTX, Uid::from_raw(0), Gid::from_raw(0), || {
- let sl = SecLevel::tee();
- let access_vector = KeyPermission::DELETE.0;
- let mut grant_keys = generate_ec_key_and_grant_to_users(
- &sl,
- Some(ALIAS.to_string()),
- vec![GRANTEE_UID.try_into().unwrap()],
- access_vector,
- )
- .unwrap();
+ let grantor_fn = || {
+ let sl = SecLevel::tee();
+ let access_vector = KeyPermission::DELETE.0;
+ let mut grant_keys = generate_ec_key_and_grant_to_users(
+ &sl,
+ Some(ALIAS.to_string()),
+ vec![GRANTEE_UID.try_into().unwrap()],
+ access_vector,
+ )
+ .unwrap();
- grant_keys.remove(0)
- })
+ grant_keys.remove(0)
};
+ // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
+ // `--test-threads=1`), and nothing yet done with binder.
+ let grant_key_nspace =
+ unsafe { run_as::run_as(GRANTOR_SU_CTX, Uid::from_raw(0), Gid::from_raw(0), grantor_fn) };
+
// Grantee context, delete the key.
- // SAFETY: The test is run in a separate process with no other threads.
+ let grantee_fn = move || {
+ let keystore2 = get_keystore_service();
+ keystore2
+ .deleteKey(&KeyDescriptor {
+ domain: Domain::GRANT,
+ nspace: grant_key_nspace,
+ alias: None,
+ blob: None,
+ })
+ .unwrap();
+ };
+
+ // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
+ // `--test-threads=1`), and nothing yet done with binder.
unsafe {
run_as::run_as(
GRANTEE_CTX,
Uid::from_raw(GRANTEE_UID),
Gid::from_raw(GRANTEE_GID),
- move || {
- let keystore2 = get_keystore_service();
- keystore2
- .deleteKey(&KeyDescriptor {
- domain: Domain::GRANT,
- nspace: grant_key_nspace,
- alias: None,
- blob: None,
- })
- .unwrap();
- },
+ grantee_fn,
)
};
// Verify whether key got deleted in grantor's context.
- // SAFETY: The test is run in a separate process with no other threads.
- unsafe {
- run_as::run_as(GRANTOR_SU_CTX, Uid::from_raw(0), Gid::from_raw(0), move || {
- let keystore2_inst = get_keystore_service();
- let result =
- key_generations::map_ks_error(keystore2_inst.getKeyEntry(&KeyDescriptor {
- domain: Domain::APP,
- nspace: -1,
- alias: Some(ALIAS.to_string()),
- blob: None,
- }));
- assert!(result.is_err());
- assert_eq!(Error::Rc(ResponseCode::KEY_NOT_FOUND), result.unwrap_err());
- })
+ let grantor_fn = move || {
+ let keystore2_inst = get_keystore_service();
+ let result = key_generations::map_ks_error(keystore2_inst.getKeyEntry(&KeyDescriptor {
+ domain: Domain::APP,
+ nspace: -1,
+ alias: Some(ALIAS.to_string()),
+ blob: None,
+ }));
+ assert!(result.is_err());
+ assert_eq!(Error::Rc(ResponseCode::KEY_NOT_FOUND), result.unwrap_err());
};
+
+ // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
+ // `--test-threads=1`), and nothing yet done with binder.
+ unsafe { run_as::run_as(GRANTOR_SU_CTX, Uid::from_raw(0), Gid::from_raw(0), grantor_fn) };
}
/// Grant a key to the user. In grantee context load the granted key and try to grant it to second
@@ -326,75 +340,82 @@
static SEC_GRANTEE_GID: u32 = SEC_GRANTEE_UID;
// Generate a key and grant it to a user with GET_INFO permission.
- // SAFETY: The test is run in a separate process with no other threads.
- let grant_key_nspace = unsafe {
- run_as::run_as(GRANTOR_SU_CTX, Uid::from_raw(0), Gid::from_raw(0), || {
- let sl = SecLevel::tee();
- let access_vector = KeyPermission::GET_INFO.0;
- let alias = format!("ks_grant_perm_denied_key_{}", getuid());
- let mut grant_keys = generate_ec_key_and_grant_to_users(
- &sl,
- Some(alias),
- vec![GRANTEE_UID.try_into().unwrap()],
- access_vector,
- )
- .unwrap();
+ let grantor_fn = || {
+ let sl = SecLevel::tee();
+ let access_vector = KeyPermission::GET_INFO.0;
+ let alias = format!("ks_grant_perm_denied_key_{}", getuid());
+ let mut grant_keys = generate_ec_key_and_grant_to_users(
+ &sl,
+ Some(alias),
+ vec![GRANTEE_UID.try_into().unwrap()],
+ access_vector,
+ )
+ .unwrap();
- grant_keys.remove(0)
- })
+ grant_keys.remove(0)
};
+ // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
+ // `--test-threads=1`), and nothing yet done with binder.
+ let grant_key_nspace =
+ unsafe { run_as::run_as(GRANTOR_SU_CTX, Uid::from_raw(0), Gid::from_raw(0), grantor_fn) };
// Grantee context, load the granted key and try to grant it to `SEC_GRANTEE_UID` grantee.
- // SAFETY: The test is run in a separate process with no other threads.
+ let grantee_fn = move || {
+ let keystore2 = get_keystore_service();
+ let access_vector = KeyPermission::GET_INFO.0;
+
+ let key_entry_response = keystore2
+ .getKeyEntry(&KeyDescriptor {
+ domain: Domain::GRANT,
+ nspace: grant_key_nspace,
+ alias: None,
+ blob: None,
+ })
+ .unwrap();
+
+ let result = key_generations::map_ks_error(keystore2.grant(
+ &key_entry_response.metadata.key,
+ SEC_GRANTEE_UID.try_into().unwrap(),
+ access_vector,
+ ));
+ assert!(result.is_err());
+ assert_eq!(Error::Rc(ResponseCode::PERMISSION_DENIED), result.unwrap_err());
+ };
+
+ // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
+ // `--test-threads=1`), and nothing yet done with binder.
unsafe {
run_as::run_as(
GRANTEE_CTX,
Uid::from_raw(GRANTEE_UID),
Gid::from_raw(GRANTEE_GID),
- move || {
- let keystore2 = get_keystore_service();
- let access_vector = KeyPermission::GET_INFO.0;
-
- let key_entry_response = keystore2
- .getKeyEntry(&KeyDescriptor {
- domain: Domain::GRANT,
- nspace: grant_key_nspace,
- alias: None,
- blob: None,
- })
- .unwrap();
-
- let result = key_generations::map_ks_error(keystore2.grant(
- &key_entry_response.metadata.key,
- SEC_GRANTEE_UID.try_into().unwrap(),
- access_vector,
- ));
- assert!(result.is_err());
- assert_eq!(Error::Rc(ResponseCode::PERMISSION_DENIED), result.unwrap_err());
- },
+ grantee_fn,
)
};
// Make sure second grantee shouldn't have access to the above granted key.
- // SAFETY: The test is run in a separate process with no other threads.
+ let grantee2_fn = move || {
+ let keystore2 = get_keystore_service();
+
+ let result = key_generations::map_ks_error(keystore2.getKeyEntry(&KeyDescriptor {
+ domain: Domain::GRANT,
+ nspace: grant_key_nspace,
+ alias: None,
+ blob: None,
+ }));
+
+ assert!(result.is_err());
+ assert_eq!(Error::Rc(ResponseCode::KEY_NOT_FOUND), result.unwrap_err());
+ };
+
+ // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
+ // `--test-threads=1`), and nothing yet done with binder.
unsafe {
run_as::run_as(
GRANTEE_CTX,
Uid::from_raw(SEC_GRANTEE_UID),
Gid::from_raw(SEC_GRANTEE_GID),
- move || {
- let keystore2 = get_keystore_service();
-
- let result = key_generations::map_ks_error(keystore2.getKeyEntry(&KeyDescriptor {
- domain: Domain::GRANT,
- nspace: grant_key_nspace,
- alias: None,
- blob: None,
- }));
-
- assert!(result.is_err());
- assert_eq!(Error::Rc(ResponseCode::KEY_NOT_FOUND), result.unwrap_err());
- },
+ grantee2_fn,
)
};
}
@@ -457,57 +478,57 @@
static GRANTEE_GID: u32 = GRANTEE_UID;
// Generate a key and grant it to a user with GET_INFO permission.
- // SAFETY: The test is run in a separate process with no other threads.
- let grant_key_nspace = unsafe {
- run_as::run_as(GRANTOR_SU_CTX, Uid::from_raw(0), Gid::from_raw(0), || {
- let sl = SecLevel::tee();
- let alias = format!("ks_ungrant_test_key_1{}", getuid());
- let access_vector = KeyPermission::GET_INFO.0;
- let mut grant_keys = generate_ec_key_and_grant_to_users(
- &sl,
- Some(alias.to_string()),
- vec![GRANTEE_UID.try_into().unwrap()],
- access_vector,
+ let grantor_fn = || {
+ let sl = SecLevel::tee();
+ let alias = format!("ks_ungrant_test_key_1{}", getuid());
+ let access_vector = KeyPermission::GET_INFO.0;
+ let mut grant_keys = generate_ec_key_and_grant_to_users(
+ &sl,
+ Some(alias.to_string()),
+ vec![GRANTEE_UID.try_into().unwrap()],
+ access_vector,
+ )
+ .unwrap();
+
+ let grant_key_nspace = grant_keys.remove(0);
+
+ // Ungrant above granted key.
+ sl.keystore2
+ .ungrant(
+ &KeyDescriptor { domain: Domain::APP, nspace: -1, alias: Some(alias), blob: None },
+ GRANTEE_UID.try_into().unwrap(),
)
.unwrap();
- let grant_key_nspace = grant_keys.remove(0);
-
- // Ungrant above granted key.
- sl.keystore2
- .ungrant(
- &KeyDescriptor {
- domain: Domain::APP,
- nspace: -1,
- alias: Some(alias),
- blob: None,
- },
- GRANTEE_UID.try_into().unwrap(),
- )
- .unwrap();
-
- grant_key_nspace
- })
+ grant_key_nspace
};
+ // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
+ // `--test-threads=1`), and nothing yet done with binder.
+ let grant_key_nspace =
+ unsafe { run_as::run_as(GRANTOR_SU_CTX, Uid::from_raw(0), Gid::from_raw(0), grantor_fn) };
+
// Grantee context, try to load the ungranted key.
- // SAFETY: The test is run in a separate process with no other threads.
+ let grantee_fn = move || {
+ let keystore2 = get_keystore_service();
+ let result = key_generations::map_ks_error(keystore2.getKeyEntry(&KeyDescriptor {
+ domain: Domain::GRANT,
+ nspace: grant_key_nspace,
+ alias: None,
+ blob: None,
+ }));
+ assert!(result.is_err());
+ assert_eq!(Error::Rc(ResponseCode::KEY_NOT_FOUND), result.unwrap_err());
+ };
+
+ // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
+ // `--test-threads=1`), and nothing yet done with binder.
unsafe {
run_as::run_as(
GRANTEE_CTX,
Uid::from_raw(GRANTEE_UID),
Gid::from_raw(GRANTEE_GID),
- move || {
- let keystore2 = get_keystore_service();
- let result = key_generations::map_ks_error(keystore2.getKeyEntry(&KeyDescriptor {
- domain: Domain::GRANT,
- nspace: grant_key_nspace,
- alias: None,
- blob: None,
- }));
- assert!(result.is_err());
- assert_eq!(Error::Rc(ResponseCode::KEY_NOT_FOUND), result.unwrap_err());
- },
+ grantee_fn,
)
};
}
@@ -527,74 +548,79 @@
static GRANTEE_UID: u32 = USER_ID * AID_USER_OFFSET + APPLICATION_ID;
static GRANTEE_GID: u32 = GRANTEE_UID;
- // SAFETY: The test is run in a separate process with no other threads.
- let grant_key_nspace = unsafe {
- run_as::run_as(GRANTOR_SU_CTX, Uid::from_raw(0), Gid::from_raw(0), || {
- let sl = SecLevel::tee();
- let alias = format!("{}{}", "ks_grant_delete_ungrant_test_key_1", getuid());
+ let grantor_fn = || {
+ let sl = SecLevel::tee();
+ let alias = format!("{}{}", "ks_grant_delete_ungrant_test_key_1", getuid());
- let key_metadata = key_generations::generate_ec_p256_signing_key(
- &sl,
- Domain::SELINUX,
- key_generations::SELINUX_SHELL_NAMESPACE,
- Some(alias.to_string()),
- None,
- )
+ let key_metadata = key_generations::generate_ec_p256_signing_key(
+ &sl,
+ Domain::SELINUX,
+ key_generations::SELINUX_SHELL_NAMESPACE,
+ Some(alias.to_string()),
+ None,
+ )
+ .unwrap();
+
+ let access_vector = KeyPermission::GET_INFO.0;
+ let grant_key = sl
+ .keystore2
+ .grant(&key_metadata.key, GRANTEE_UID.try_into().unwrap(), access_vector)
.unwrap();
+ assert_eq!(grant_key.domain, Domain::GRANT);
- let access_vector = KeyPermission::GET_INFO.0;
- let grant_key = sl
- .keystore2
- .grant(&key_metadata.key, GRANTEE_UID.try_into().unwrap(), access_vector)
- .unwrap();
- assert_eq!(grant_key.domain, Domain::GRANT);
+ // Delete above granted key.
+ sl.keystore2.deleteKey(&key_metadata.key).unwrap();
- // Delete above granted key.
- sl.keystore2.deleteKey(&key_metadata.key).unwrap();
+ // Try to ungrant above granted key.
+ let result = key_generations::map_ks_error(
+ sl.keystore2.ungrant(&key_metadata.key, GRANTEE_UID.try_into().unwrap()),
+ );
+ assert!(result.is_err());
+ assert_eq!(Error::Rc(ResponseCode::KEY_NOT_FOUND), result.unwrap_err());
- // Try to ungrant above granted key.
- let result = key_generations::map_ks_error(
- sl.keystore2.ungrant(&key_metadata.key, GRANTEE_UID.try_into().unwrap()),
- );
- assert!(result.is_err());
- assert_eq!(Error::Rc(ResponseCode::KEY_NOT_FOUND), result.unwrap_err());
+ // Generate a new key with the same alias and try to access the earlier granted key
+ // in grantee context.
+ let result = key_generations::generate_ec_p256_signing_key(
+ &sl,
+ Domain::SELINUX,
+ key_generations::SELINUX_SHELL_NAMESPACE,
+ Some(alias),
+ None,
+ );
+ assert!(result.is_ok());
- // Generate a new key with the same alias and try to access the earlier granted key
- // in grantee context.
- let result = key_generations::generate_ec_p256_signing_key(
- &sl,
- Domain::SELINUX,
- key_generations::SELINUX_SHELL_NAMESPACE,
- Some(alias),
- None,
- );
- assert!(result.is_ok());
-
- grant_key.nspace
- })
+ grant_key.nspace
};
+ // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
+ // `--test-threads=1`), and nothing yet done with binder.
+ let grant_key_nspace =
+ unsafe { run_as::run_as(GRANTOR_SU_CTX, Uid::from_raw(0), Gid::from_raw(0), grantor_fn) };
+
// Make sure grant did not persist, try to access the earlier granted key in grantee context.
// Grantee context should fail to load the granted key as its associated key is deleted in
// grantor context.
- // SAFETY: The test is run in a separate process with no other threads.
+ let grantee_fn = move || {
+ let keystore2 = get_keystore_service();
+
+ let result = key_generations::map_ks_error(keystore2.getKeyEntry(&KeyDescriptor {
+ domain: Domain::GRANT,
+ nspace: grant_key_nspace,
+ alias: None,
+ blob: None,
+ }));
+ assert!(result.is_err());
+ assert_eq!(Error::Rc(ResponseCode::KEY_NOT_FOUND), result.unwrap_err());
+ };
+
+ // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
+ // `--test-threads=1`), and nothing yet done with binder.
unsafe {
run_as::run_as(
GRANTEE_CTX,
Uid::from_raw(GRANTEE_UID),
Gid::from_raw(GRANTEE_GID),
- move || {
- let keystore2 = get_keystore_service();
-
- let result = key_generations::map_ks_error(keystore2.getKeyEntry(&KeyDescriptor {
- domain: Domain::GRANT,
- nspace: grant_key_nspace,
- alias: None,
- blob: None,
- }));
- assert!(result.is_err());
- assert_eq!(Error::Rc(ResponseCode::KEY_NOT_FOUND), result.unwrap_err());
- },
+ grantee_fn,
)
};
}
@@ -616,44 +642,48 @@
static GRANTEE_2_GID: u32 = GRANTEE_2_UID;
// Generate a key and grant it to multiple users with GET_INFO|USE permissions.
- // SAFETY: The test is run in a separate process with no other threads.
- let mut grant_keys = unsafe {
- run_as::run_as(GRANTOR_SU_CTX, Uid::from_raw(0), Gid::from_raw(0), || {
- let sl = SecLevel::tee();
- let alias = format!("ks_grant_test_key_2{}", getuid());
- let access_vector = KeyPermission::GET_INFO.0 | KeyPermission::USE.0;
+ let grantor_fn = || {
+ let sl = SecLevel::tee();
+ let alias = format!("ks_grant_test_key_2{}", getuid());
+ let access_vector = KeyPermission::GET_INFO.0 | KeyPermission::USE.0;
- generate_ec_key_and_grant_to_users(
- &sl,
- Some(alias),
- vec![GRANTEE_1_UID.try_into().unwrap(), GRANTEE_2_UID.try_into().unwrap()],
- access_vector,
- )
- .unwrap()
- })
+ generate_ec_key_and_grant_to_users(
+ &sl,
+ Some(alias),
+ vec![GRANTEE_1_UID.try_into().unwrap(), GRANTEE_2_UID.try_into().unwrap()],
+ access_vector,
+ )
+ .unwrap()
};
+ // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
+ // `--test-threads=1`), and nothing yet done with binder.
+ let mut grant_keys =
+ unsafe { run_as::run_as(GRANTOR_SU_CTX, Uid::from_raw(0), Gid::from_raw(0), grantor_fn) };
+
for (grantee_uid, grantee_gid) in
&[(GRANTEE_1_UID, GRANTEE_1_GID), (GRANTEE_2_UID, GRANTEE_2_GID)]
{
let grant_key_nspace = grant_keys.remove(0);
- // SAFETY: The test is run in a separate process with no other threads.
+ let grantee_fn = move || {
+ let sl = SecLevel::tee();
+
+ assert_eq!(
+ Ok(()),
+ key_generations::map_ks_error(load_grant_key_and_perform_sign_operation(
+ &sl,
+ grant_key_nspace
+ ))
+ );
+ };
+ // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
+ // `--test-threads=1`), and nothing yet done with binder.
unsafe {
run_as::run_as(
GRANTEE_CTX,
Uid::from_raw(*grantee_uid),
Gid::from_raw(*grantee_gid),
- move || {
- let sl = SecLevel::tee();
-
- assert_eq!(
- Ok(()),
- key_generations::map_ks_error(load_grant_key_and_perform_sign_operation(
- &sl,
- grant_key_nspace
- ))
- );
- },
+ grantee_fn,
)
};
}
@@ -677,76 +707,84 @@
static GRANTEE_2_GID: u32 = GRANTEE_2_UID;
// Generate a key and grant it to multiple users with GET_INFO permission.
- // SAFETY: The test is run in a separate process with no other threads.
- let mut grant_keys = unsafe {
- run_as::run_as(GRANTOR_SU_CTX, Uid::from_raw(0), Gid::from_raw(0), || {
- let sl = SecLevel::tee();
- let alias = format!("ks_grant_test_key_2{}", getuid());
- let access_vector =
- KeyPermission::GET_INFO.0 | KeyPermission::USE.0 | KeyPermission::DELETE.0;
+ let grantor_fn = || {
+ let sl = SecLevel::tee();
+ let alias = format!("ks_grant_test_key_2{}", getuid());
+ let access_vector =
+ KeyPermission::GET_INFO.0 | KeyPermission::USE.0 | KeyPermission::DELETE.0;
- generate_ec_key_and_grant_to_users(
- &sl,
- Some(alias),
- vec![GRANTEE_1_UID.try_into().unwrap(), GRANTEE_2_UID.try_into().unwrap()],
- access_vector,
- )
- .unwrap()
- })
+ generate_ec_key_and_grant_to_users(
+ &sl,
+ Some(alias),
+ vec![GRANTEE_1_UID.try_into().unwrap(), GRANTEE_2_UID.try_into().unwrap()],
+ access_vector,
+ )
+ .unwrap()
};
+ // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
+ // `--test-threads=1`), and nothing yet done with binder.
+ let mut grant_keys =
+ unsafe { run_as::run_as(GRANTOR_SU_CTX, Uid::from_raw(0), Gid::from_raw(0), grantor_fn) };
+
// Grantee #1 context
let grant_key1_nspace = grant_keys.remove(0);
- // SAFETY: The test is run in a separate process with no other threads.
+ let grantee1_fn = move || {
+ let sl = SecLevel::tee();
+
+ assert_eq!(
+ Ok(()),
+ key_generations::map_ks_error(load_grant_key_and_perform_sign_operation(
+ &sl,
+ grant_key1_nspace
+ ))
+ );
+
+ // Delete the granted key.
+ sl.keystore2
+ .deleteKey(&KeyDescriptor {
+ domain: Domain::GRANT,
+ nspace: grant_key1_nspace,
+ alias: None,
+ blob: None,
+ })
+ .unwrap();
+ };
+
+ // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
+ // `--test-threads=1`), and nothing yet done with binder.
unsafe {
run_as::run_as(
GRANTEE_CTX,
Uid::from_raw(GRANTEE_1_UID),
Gid::from_raw(GRANTEE_1_GID),
- move || {
- let sl = SecLevel::tee();
-
- assert_eq!(
- Ok(()),
- key_generations::map_ks_error(load_grant_key_and_perform_sign_operation(
- &sl,
- grant_key1_nspace
- ))
- );
-
- // Delete the granted key.
- sl.keystore2
- .deleteKey(&KeyDescriptor {
- domain: Domain::GRANT,
- nspace: grant_key1_nspace,
- alias: None,
- blob: None,
- })
- .unwrap();
- },
+ grantee1_fn,
)
};
// Grantee #2 context
let grant_key2_nspace = grant_keys.remove(0);
- // SAFETY: The test is run in a separate process with no other threads.
+ let grantee2_fn = move || {
+ let keystore2 = get_keystore_service();
+
+ let result = key_generations::map_ks_error(keystore2.getKeyEntry(&KeyDescriptor {
+ domain: Domain::GRANT,
+ nspace: grant_key2_nspace,
+ alias: None,
+ blob: None,
+ }));
+ assert!(result.is_err());
+ assert_eq!(Error::Rc(ResponseCode::KEY_NOT_FOUND), result.unwrap_err());
+ };
+
+ // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
+ // `--test-threads=1`), and nothing yet done with binder.
unsafe {
run_as::run_as(
GRANTEE_CTX,
Uid::from_raw(GRANTEE_2_UID),
Gid::from_raw(GRANTEE_2_GID),
- move || {
- let keystore2 = get_keystore_service();
-
- let result = key_generations::map_ks_error(keystore2.getKeyEntry(&KeyDescriptor {
- domain: Domain::GRANT,
- nspace: grant_key2_nspace,
- alias: None,
- blob: None,
- }));
- assert!(result.is_err());
- assert_eq!(Error::Rc(ResponseCode::KEY_NOT_FOUND), result.unwrap_err());
- },
+ grantee2_fn,
)
};
}
diff --git a/keystore2/tests/keystore2_client_keystore_engine_tests.rs b/keystore2/tests/keystore2_client_keystore_engine_tests.rs
index 01f8917..a576993 100644
--- a/keystore2/tests/keystore2_client_keystore_engine_tests.rs
+++ b/keystore2/tests/keystore2_client_keystore_engine_tests.rs
@@ -162,26 +162,31 @@
static GRANTEE_GID: u32 = GRANTEE_UID;
// Generate a key and grant it to a user with GET_INFO|USE|DELETE key permissions.
- // SAFETY: The test is run in a separate process with no other threads.
- let grant_key_nspace = unsafe {
- run_as::run_as(TARGET_SU_CTX, Uid::from_raw(0), Gid::from_raw(0), || {
- let sl = SecLevel::tee();
- let alias = "keystore2_engine_rsa_key";
- generate_key_and_grant_to_user(&sl, alias, GRANTEE_UID, Algorithm::RSA).unwrap()
- })
+ let grantor_fn = || {
+ let sl = SecLevel::tee();
+ let alias = "keystore2_engine_rsa_key";
+ generate_key_and_grant_to_user(&sl, alias, GRANTEE_UID, Algorithm::RSA).unwrap()
};
+ // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
+ // `--test-threads=1`), and nothing yet done with binder.
+ let grant_key_nspace =
+ unsafe { run_as::run_as(TARGET_SU_CTX, Uid::from_raw(0), Gid::from_raw(0), grantor_fn) };
+
// In grantee context load the key and try to perform crypto operation.
- // SAFETY: The test is run in a separate process with no other threads.
+ let grantee_fn = move || {
+ let keystore2 = get_keystore_service();
+ perform_crypto_op_using_granted_key(&keystore2, grant_key_nspace);
+ };
+
+ // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
+ // `--test-threads=1`), and nothing yet done with binder.
unsafe {
run_as::run_as(
GRANTEE_CTX,
Uid::from_raw(GRANTEE_UID),
Gid::from_raw(GRANTEE_GID),
- move || {
- let keystore2 = get_keystore_service();
- perform_crypto_op_using_granted_key(&keystore2, grant_key_nspace);
- },
+ grantee_fn,
)
};
}
@@ -197,26 +202,31 @@
static GRANTEE_GID: u32 = GRANTEE_UID;
// Generate a key and grant it to a user with GET_INFO|USE|DELETE key permissions.
- // SAFETY: The test is run in a separate process with no other threads.
- let grant_key_nspace = unsafe {
- run_as::run_as(TARGET_SU_CTX, Uid::from_raw(0), Gid::from_raw(0), || {
- let sl = SecLevel::tee();
- let alias = "keystore2_engine_ec_test_key";
- generate_key_and_grant_to_user(&sl, alias, GRANTEE_UID, Algorithm::EC).unwrap()
- })
+ let grantor_fn = || {
+ let sl = SecLevel::tee();
+ let alias = "keystore2_engine_ec_test_key";
+ generate_key_and_grant_to_user(&sl, alias, GRANTEE_UID, Algorithm::EC).unwrap()
};
+ // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
+ // `--test-threads=1`), and nothing yet done with binder.
+ let grant_key_nspace =
+ unsafe { run_as::run_as(TARGET_SU_CTX, Uid::from_raw(0), Gid::from_raw(0), grantor_fn) };
+
// In grantee context load the key and try to perform crypto operation.
- // SAFETY: The test is run in a separate process with no other threads.
+ let grantee_fn = move || {
+ let keystore2 = get_keystore_service();
+ perform_crypto_op_using_granted_key(&keystore2, grant_key_nspace);
+ };
+
+ // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
+ // `--test-threads=1`), and nothing yet done with binder.
unsafe {
run_as::run_as(
GRANTEE_CTX,
Uid::from_raw(GRANTEE_UID),
Gid::from_raw(GRANTEE_GID),
- move || {
- let keystore2 = get_keystore_service();
- perform_crypto_op_using_granted_key(&keystore2, grant_key_nspace);
- },
+ grantee_fn,
)
};
}
@@ -233,46 +243,51 @@
// Generate a key and re-encode it's certificate as PEM and update it and
// grant it to a user with GET_INFO|USE|DELETE key permissions.
- // SAFETY: The test is run in a separate process with no other threads.
- let grant_key_nspace = unsafe {
- run_as::run_as(TARGET_SU_CTX, Uid::from_raw(0), Gid::from_raw(0), || {
- let sl = SecLevel::tee();
- let alias = "keystore2_engine_rsa_pem_pub_key";
- let grant_key_nspace =
- generate_key_and_grant_to_user(&sl, alias, GRANTEE_UID, Algorithm::RSA).unwrap();
+ let grantor_fn = || {
+ let sl = SecLevel::tee();
+ let alias = "keystore2_engine_rsa_pem_pub_key";
+ let grant_key_nspace =
+ generate_key_and_grant_to_user(&sl, alias, GRANTEE_UID, Algorithm::RSA).unwrap();
- // Update certificate with encodeed PEM data.
- let key_entry_response = sl
- .keystore2
- .getKeyEntry(&KeyDescriptor {
- domain: Domain::APP,
- nspace: -1,
- alias: Some(alias.to_string()),
- blob: None,
- })
- .unwrap();
- let cert_bytes = key_entry_response.metadata.certificate.as_ref().unwrap();
- let cert = X509::from_der(cert_bytes.as_ref()).unwrap();
- let cert_pem = cert.to_pem().unwrap();
- sl.keystore2
- .updateSubcomponent(&key_entry_response.metadata.key, Some(&cert_pem), None)
- .expect("updateSubcomponent failed.");
+ // Update certificate with encodeed PEM data.
+ let key_entry_response = sl
+ .keystore2
+ .getKeyEntry(&KeyDescriptor {
+ domain: Domain::APP,
+ nspace: -1,
+ alias: Some(alias.to_string()),
+ blob: None,
+ })
+ .unwrap();
+ let cert_bytes = key_entry_response.metadata.certificate.as_ref().unwrap();
+ let cert = X509::from_der(cert_bytes.as_ref()).unwrap();
+ let cert_pem = cert.to_pem().unwrap();
+ sl.keystore2
+ .updateSubcomponent(&key_entry_response.metadata.key, Some(&cert_pem), None)
+ .expect("updateSubcomponent failed.");
- grant_key_nspace
- })
+ grant_key_nspace
};
+ // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
+ // `--test-threads=1`), and nothing yet done with binder.
+ let grant_key_nspace =
+ unsafe { run_as::run_as(TARGET_SU_CTX, Uid::from_raw(0), Gid::from_raw(0), grantor_fn) };
+
// In grantee context load the key and try to perform crypto operation.
- // SAFETY: The test is run in a separate process with no other threads.
+ let grantee_fn = move || {
+ let keystore2 = get_keystore_service();
+ perform_crypto_op_using_granted_key(&keystore2, grant_key_nspace);
+ };
+
+ // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
+ // `--test-threads=1`), and nothing yet done with binder.
unsafe {
run_as::run_as(
GRANTEE_CTX,
Uid::from_raw(GRANTEE_UID),
Gid::from_raw(GRANTEE_GID),
- move || {
- let keystore2 = get_keystore_service();
- perform_crypto_op_using_granted_key(&keystore2, grant_key_nspace);
- },
+ grantee_fn,
)
};
}
diff --git a/keystore2/tests/keystore2_client_list_entries_tests.rs b/keystore2/tests/keystore2_client_list_entries_tests.rs
index 539dac2..af01a6e 100644
--- a/keystore2/tests/keystore2_client_list_entries_tests.rs
+++ b/keystore2/tests/keystore2_client_list_entries_tests.rs
@@ -59,93 +59,97 @@
static GRANTEE_UID: u32 = USER_ID * AID_USER_OFFSET + APPLICATION_ID;
static GRANTEE_GID: u32 = GRANTEE_UID;
- // SAFETY: The test is run in a separate process with no other threads.
- unsafe {
- run_as::run_as(GRANTOR_SU_CTX, Uid::from_raw(0), Gid::from_raw(0), || {
- let sl = SecLevel::tee();
+ let gen_key_fn = || {
+ let sl = SecLevel::tee();
- let alias = format!("list_entries_grant_key1_{}", getuid());
+ let alias = format!("list_entries_grant_key1_{}", getuid());
- // Make sure there is no key exist with this `alias` in `SELINUX` domain and
- // `SELINUX_SHELL_NAMESPACE` namespace.
- if key_alias_exists(
- &sl.keystore2,
- Domain::SELINUX,
- key_generations::SELINUX_SHELL_NAMESPACE,
- alias.to_string(),
- ) {
- sl.keystore2
- .deleteKey(&KeyDescriptor {
- domain: Domain::SELINUX,
- nspace: key_generations::SELINUX_SHELL_NAMESPACE,
- alias: Some(alias.to_string()),
- blob: None,
- })
- .unwrap();
- }
-
- // Generate a key with above defined `alias`.
- let key_metadata = key_generations::generate_ec_p256_signing_key(
- &sl,
- Domain::SELINUX,
- key_generations::SELINUX_SHELL_NAMESPACE,
- Some(alias.to_string()),
- None,
- )
- .unwrap();
-
- // Verify that above generated key entry is listed with domain SELINUX and
- // namespace SELINUX_SHELL_NAMESPACE
- assert!(key_alias_exists(
- &sl.keystore2,
- Domain::SELINUX,
- key_generations::SELINUX_SHELL_NAMESPACE,
- alias,
- ));
-
- // Grant a key with GET_INFO permission.
- let access_vector = KeyPermission::GET_INFO.0;
+ // Make sure there is no key exist with this `alias` in `SELINUX` domain and
+ // `SELINUX_SHELL_NAMESPACE` namespace.
+ if key_alias_exists(
+ &sl.keystore2,
+ Domain::SELINUX,
+ key_generations::SELINUX_SHELL_NAMESPACE,
+ alias.to_string(),
+ ) {
sl.keystore2
- .grant(&key_metadata.key, GRANTEE_UID.try_into().unwrap(), access_vector)
+ .deleteKey(&KeyDescriptor {
+ domain: Domain::SELINUX,
+ nspace: key_generations::SELINUX_SHELL_NAMESPACE,
+ alias: Some(alias.to_string()),
+ blob: None,
+ })
.unwrap();
- })
+ }
+
+ // Generate a key with above defined `alias`.
+ let key_metadata = key_generations::generate_ec_p256_signing_key(
+ &sl,
+ Domain::SELINUX,
+ key_generations::SELINUX_SHELL_NAMESPACE,
+ Some(alias.to_string()),
+ None,
+ )
+ .unwrap();
+
+ // Verify that above generated key entry is listed with domain SELINUX and
+ // namespace SELINUX_SHELL_NAMESPACE
+ assert!(key_alias_exists(
+ &sl.keystore2,
+ Domain::SELINUX,
+ key_generations::SELINUX_SHELL_NAMESPACE,
+ alias,
+ ));
+
+ // Grant a key with GET_INFO permission.
+ let access_vector = KeyPermission::GET_INFO.0;
+ sl.keystore2
+ .grant(&key_metadata.key, GRANTEE_UID.try_into().unwrap(), access_vector)
+ .unwrap();
};
+ // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
+ // `--test-threads=1`), and nothing yet done with binder.
+ unsafe { run_as::run_as(GRANTOR_SU_CTX, Uid::from_raw(0), Gid::from_raw(0), gen_key_fn) };
+
// In user context validate list of key entries associated with it.
- // SAFETY: The test is run in a separate process with no other threads.
+ let list_keys_fn = move || {
+ let sl = SecLevel::tee();
+ let alias = format!("list_entries_success_key{}", getuid());
+
+ let key_metadata = key_generations::generate_ec_p256_signing_key(
+ &sl,
+ Domain::APP,
+ -1,
+ Some(alias.to_string()),
+ None,
+ )
+ .unwrap();
+
+ // Make sure there is only one existing key entry and that should be the same key
+ // generated in this user context. Granted key shouldn't be included in this list.
+ let key_descriptors = sl.keystore2.listEntries(Domain::APP, -1).unwrap();
+ assert_eq!(1, key_descriptors.len());
+
+ let key = key_descriptors.first().unwrap();
+ assert_eq!(key.alias, Some(alias));
+ assert_eq!(key.nspace, GRANTEE_UID.try_into().unwrap());
+ assert_eq!(key.domain, Domain::APP);
+
+ sl.keystore2.deleteKey(&key_metadata.key).unwrap();
+
+ let key_descriptors = sl.keystore2.listEntries(Domain::APP, -1).unwrap();
+ assert_eq!(0, key_descriptors.len());
+ };
+
+ // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
+ // `--test-threads=1`), and nothing yet done with binder.
unsafe {
run_as::run_as(
GRANTEE_CTX,
Uid::from_raw(GRANTEE_UID),
Gid::from_raw(GRANTEE_GID),
- move || {
- let sl = SecLevel::tee();
- let alias = format!("list_entries_success_key{}", getuid());
-
- let key_metadata = key_generations::generate_ec_p256_signing_key(
- &sl,
- Domain::APP,
- -1,
- Some(alias.to_string()),
- None,
- )
- .unwrap();
-
- // Make sure there is only one key entry exist and that should be the same key
- // generated in this user context. Granted key shouldn't be included in this list.
- let key_descriptors = sl.keystore2.listEntries(Domain::APP, -1).unwrap();
- assert_eq!(1, key_descriptors.len());
-
- let key = key_descriptors.first().unwrap();
- assert_eq!(key.alias, Some(alias));
- assert_eq!(key.nspace, GRANTEE_UID.try_into().unwrap());
- assert_eq!(key.domain, Domain::APP);
-
- sl.keystore2.deleteKey(&key_metadata.key).unwrap();
-
- let key_descriptors = sl.keystore2.listEntries(Domain::APP, -1).unwrap();
- assert_eq!(0, key_descriptors.len());
- },
+ list_keys_fn,
)
};
}
@@ -159,18 +163,19 @@
let agid = 91 * AID_USER_OFFSET + 10001;
static TARGET_CTX: &str = "u:r:untrusted_app:s0:c91,c256,c10,c20";
- // SAFETY: The test is run in a separate process with no other threads.
- unsafe {
- run_as::run_as(TARGET_CTX, Uid::from_raw(auid), Gid::from_raw(agid), move || {
- let keystore2 = get_keystore_service();
+ let list_keys_fn = move || {
+ let keystore2 = get_keystore_service();
- let result = key_generations::map_ks_error(
- keystore2.listEntries(Domain::SELINUX, key_generations::SELINUX_SHELL_NAMESPACE),
- );
- assert!(result.is_err());
- assert_eq!(Error::Rc(ResponseCode::PERMISSION_DENIED), result.unwrap_err());
- })
+ let result = key_generations::map_ks_error(
+ keystore2.listEntries(Domain::SELINUX, key_generations::SELINUX_SHELL_NAMESPACE),
+ );
+ assert!(result.is_err());
+ assert_eq!(Error::Rc(ResponseCode::PERMISSION_DENIED), result.unwrap_err());
};
+
+ // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
+ // `--test-threads=1`), and nothing yet done with binder.
+ unsafe { run_as::run_as(TARGET_CTX, Uid::from_raw(auid), Gid::from_raw(agid), list_keys_fn) };
}
/// Try to list key entries with domain BLOB. Test should fail with error repose code
@@ -197,56 +202,64 @@
static CLIENT_UID: u32 = USER_ID * AID_USER_OFFSET + APPLICATION_ID;
static CLIENT_GID: u32 = CLIENT_UID;
- // SAFETY: The test is run in a separate process with no other threads.
- unsafe {
- run_as::run_as(CLIENT_CTX, Uid::from_raw(CLIENT_UID), Gid::from_raw(CLIENT_GID), || {
- let sl = SecLevel::tee();
+ let import_keys_fn = || {
+ let sl = SecLevel::tee();
- // Make sure there are no keystore entries exist before adding new entries.
+ // Make sure there are no keystore entries exist before adding new entries.
+ let key_descriptors = sl.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(&sl.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(&sl, 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 = sl.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(&sl.keystore2, &alias).unwrap();
- });
- }
- let mut imported_key_aliases = HashSet::new();
+ // 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())));
- // 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());
+ // 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(&sl.keystore2, &alias).unwrap();
+ assert!(imported_key_aliases.remove(&alias));
+ });
+ }
- let result = key_generations::import_aes_key(&sl, Domain::APP, -1, Some(alias));
- assert!(result.is_ok());
- }
+ assert!(imported_key_aliases.is_empty());
+ };
- // 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 = sl.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(&sl.keystore2, &alias).unwrap();
- assert!(imported_key_aliases.remove(&alias));
- });
- }
-
- assert!(imported_key_aliases.is_empty());
- })
+ // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
+ // `--test-threads=1`), and nothing yet done with binder.
+ unsafe {
+ run_as::run_as(
+ CLIENT_CTX,
+ Uid::from_raw(CLIENT_UID),
+ Gid::from_raw(CLIENT_GID),
+ import_keys_fn,
+ )
};
}
@@ -262,50 +275,58 @@
static CLIENT_UID: u32 = USER_ID * AID_USER_OFFSET + APPLICATION_ID;
static CLIENT_GID: u32 = CLIENT_UID;
- // SAFETY: The test is run in a separate process with no other threads.
+ let import_keys_fn = || {
+ let sl = SecLevel::tee();
+
+ // Make sure there are no keystore entries exist before adding new entries.
+ delete_all_entries(&sl.keystore2);
+
+ // Import 100 keys with aliases of length 6000.
+ let mut imported_key_aliases =
+ key_generations::import_aes_keys(&sl, "X".repeat(6000), 1..101).unwrap();
+ assert_eq!(
+ sl.keystore2.getNumberOfEntries(Domain::APP, -1).unwrap(),
+ 100,
+ "Error while importing keys"
+ );
+
+ let mut start_past_alias = None;
+ let mut alias;
+ while !imported_key_aliases.is_empty() {
+ let key_descriptors =
+ sl.keystore2.listEntriesBatched(Domain::APP, -1, start_past_alias).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())));
+
+ alias = key_descriptors.last().unwrap().alias.clone().unwrap();
+ start_past_alias = Some(alias.as_ref());
+ // Delete the listed key entries from imported keys list.
+ key_descriptors.into_iter().map(|key| key.alias.unwrap()).for_each(|alias| {
+ assert!(imported_key_aliases.remove(&alias));
+ });
+ }
+
+ assert!(imported_key_aliases.is_empty());
+ delete_all_entries(&sl.keystore2);
+ assert_eq!(
+ sl.keystore2.getNumberOfEntries(Domain::APP, -1).unwrap(),
+ 0,
+ "Error while doing cleanup"
+ );
+ };
+
+ // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
+ // `--test-threads=1`), and nothing yet done with binder.
unsafe {
- run_as::run_as(CLIENT_CTX, Uid::from_raw(CLIENT_UID), Gid::from_raw(CLIENT_GID), || {
- let sl = SecLevel::tee();
-
- // Make sure there are no keystore entries exist before adding new entries.
- delete_all_entries(&sl.keystore2);
-
- // Import 100 keys with aliases of length 6000.
- let mut imported_key_aliases =
- key_generations::import_aes_keys(&sl, "X".repeat(6000), 1..101).unwrap();
- assert_eq!(
- sl.keystore2.getNumberOfEntries(Domain::APP, -1).unwrap(),
- 100,
- "Error while importing keys"
- );
-
- let mut start_past_alias = None;
- let mut alias;
- while !imported_key_aliases.is_empty() {
- let key_descriptors =
- sl.keystore2.listEntriesBatched(Domain::APP, -1, start_past_alias).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())));
-
- alias = key_descriptors.last().unwrap().alias.clone().unwrap();
- start_past_alias = Some(alias.as_ref());
- // Delete the listed key entries from imported keys list.
- key_descriptors.into_iter().map(|key| key.alias.unwrap()).for_each(|alias| {
- assert!(imported_key_aliases.remove(&alias));
- });
- }
-
- assert!(imported_key_aliases.is_empty());
- delete_all_entries(&sl.keystore2);
- assert_eq!(
- sl.keystore2.getNumberOfEntries(Domain::APP, -1).unwrap(),
- 0,
- "Error while doing cleanup"
- );
- })
+ run_as::run_as(
+ CLIENT_CTX,
+ Uid::from_raw(CLIENT_UID),
+ Gid::from_raw(CLIENT_GID),
+ import_keys_fn,
+ )
};
}
@@ -329,90 +350,106 @@
static CLIENT_GID: u32 = CLIENT_UID;
static ALIAS_PREFIX: &str = "key_test_batch_list";
- // SAFETY: The test is run in a separate process with no other threads.
- unsafe {
- run_as::run_as(CLIENT_CTX, Uid::from_raw(CLIENT_UID), Gid::from_raw(CLIENT_GID), || {
- let sl = SecLevel::tee();
+ let import_keys_fn = || {
+ let sl = SecLevel::tee();
- // Make sure there are no keystore entries exist before adding new entries.
- delete_all_entries(&sl.keystore2);
+ // Make sure there are no keystore entries exist before adding new entries.
+ delete_all_entries(&sl.keystore2);
- // Import 3 keys with below aliases -
- // [key_test_batch_list_1, key_test_batch_list_2, key_test_batch_list_3]
- let imported_key_aliases =
- key_generations::import_aes_keys(&sl, ALIAS_PREFIX.to_string(), 1..4).unwrap();
- assert_eq!(
- sl.keystore2.getNumberOfEntries(Domain::APP, -1).unwrap(),
- 3,
- "Error while importing keys"
- );
+ // Import 3 keys with below aliases -
+ // [key_test_batch_list_1, key_test_batch_list_2, key_test_batch_list_3]
+ let imported_key_aliases =
+ key_generations::import_aes_keys(&sl, ALIAS_PREFIX.to_string(), 1..4).unwrap();
+ assert_eq!(
+ sl.keystore2.getNumberOfEntries(Domain::APP, -1).unwrap(),
+ 3,
+ "Error while importing keys"
+ );
- // List all entries in keystore for this user-id.
- let key_descriptors = sl.keystore2.listEntriesBatched(Domain::APP, -1, None).unwrap();
- assert_eq!(key_descriptors.len(), 3);
+ // List all entries in keystore for this user-id.
+ let key_descriptors = sl.keystore2.listEntriesBatched(Domain::APP, -1, None).unwrap();
+ assert_eq!(key_descriptors.len(), 3);
- // Makes sure all listed aliases are matching with imported keys aliases.
- assert!(key_descriptors
- .iter()
- .all(|key| imported_key_aliases.contains(key.alias.as_ref().unwrap())));
- })
+ // Makes sure all listed aliases are matching with imported keys aliases.
+ assert!(key_descriptors
+ .iter()
+ .all(|key| imported_key_aliases.contains(key.alias.as_ref().unwrap())));
};
- // SAFETY: The test is run in a separate process with no other threads.
+ // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
+ // `--test-threads=1`), and nothing yet done with binder.
unsafe {
- run_as::run_as(CLIENT_CTX, Uid::from_raw(CLIENT_UID), Gid::from_raw(CLIENT_GID), || {
- let sl = SecLevel::tee();
+ run_as::run_as(
+ CLIENT_CTX,
+ Uid::from_raw(CLIENT_UID),
+ Gid::from_raw(CLIENT_GID),
+ import_keys_fn,
+ )
+ };
- // Import another 5 keys with below aliases -
- // [ key_test_batch_list_4, key_test_batch_list_5, key_test_batch_list_6,
- // key_test_batch_list_7, key_test_batch_list_8 ]
- let mut imported_key_aliases =
- key_generations::import_aes_keys(&sl, ALIAS_PREFIX.to_string(), 4..9).unwrap();
+ let import_more_fn = || {
+ let sl = SecLevel::tee();
- // Above context already 3 keys are imported, in this context 5 keys are imported,
- // total 8 keystore entries are expected to be present in Keystore for this user-id.
- assert_eq!(
- sl.keystore2.getNumberOfEntries(Domain::APP, -1).unwrap(),
- 8,
- "Error while importing keys"
- );
+ // Import another 5 keys with below aliases -
+ // [ key_test_batch_list_4, key_test_batch_list_5, key_test_batch_list_6,
+ // key_test_batch_list_7, key_test_batch_list_8 ]
+ let mut imported_key_aliases =
+ key_generations::import_aes_keys(&sl, ALIAS_PREFIX.to_string(), 4..9).unwrap();
- // List keystore entries with `start_past_alias` as "key_test_batch_list_3".
- // `listEntriesBatched` should list all the keystore entries with
- // alias > "key_test_batch_list_3".
- let key_descriptors = sl
- .keystore2
- .listEntriesBatched(Domain::APP, -1, Some("key_test_batch_list_3"))
- .unwrap();
- assert_eq!(key_descriptors.len(), 5);
+ // Above context already 3 keys are imported, in this context 5 keys are imported,
+ // total 8 keystore entries are expected to be present in Keystore for this user-id.
+ assert_eq!(
+ sl.keystore2.getNumberOfEntries(Domain::APP, -1).unwrap(),
+ 8,
+ "Error while importing keys"
+ );
- // Make sure above listed aliases are matching with imported keys aliases.
- assert!(key_descriptors
- .iter()
- .all(|key| imported_key_aliases.contains(key.alias.as_ref().unwrap())));
+ // List keystore entries with `start_past_alias` as "key_test_batch_list_3".
+ // `listEntriesBatched` should list all the keystore entries with
+ // alias > "key_test_batch_list_3".
+ let key_descriptors = sl
+ .keystore2
+ .listEntriesBatched(Domain::APP, -1, Some("key_test_batch_list_3"))
+ .unwrap();
+ assert_eq!(key_descriptors.len(), 5);
- // List all keystore entries with `start_past_alias` as `None`.
- // `listEntriesBatched` should list all the keystore entries.
- let key_descriptors = sl.keystore2.listEntriesBatched(Domain::APP, -1, None).unwrap();
- assert_eq!(key_descriptors.len(), 8);
+ // Make sure above listed aliases are matching with imported keys aliases.
+ assert!(key_descriptors
+ .iter()
+ .all(|key| imported_key_aliases.contains(key.alias.as_ref().unwrap())));
- // Include previously imported keys aliases as well
- imported_key_aliases.insert(ALIAS_PREFIX.to_owned() + "_1");
- imported_key_aliases.insert(ALIAS_PREFIX.to_owned() + "_2");
- imported_key_aliases.insert(ALIAS_PREFIX.to_owned() + "_3");
+ // List all keystore entries with `start_past_alias` as `None`.
+ // `listEntriesBatched` should list all the keystore entries.
+ let key_descriptors = sl.keystore2.listEntriesBatched(Domain::APP, -1, None).unwrap();
+ assert_eq!(key_descriptors.len(), 8);
- // Make sure all the above listed aliases are matching with imported keys aliases.
- assert!(key_descriptors
- .iter()
- .all(|key| imported_key_aliases.contains(key.alias.as_ref().unwrap())));
+ // Include previously imported keys aliases as well
+ imported_key_aliases.insert(ALIAS_PREFIX.to_owned() + "_1");
+ imported_key_aliases.insert(ALIAS_PREFIX.to_owned() + "_2");
+ imported_key_aliases.insert(ALIAS_PREFIX.to_owned() + "_3");
- delete_all_entries(&sl.keystore2);
- assert_eq!(
- sl.keystore2.getNumberOfEntries(Domain::APP, -1).unwrap(),
- 0,
- "Error while doing cleanup"
- );
- })
+ // Make sure all the above listed aliases are matching with imported keys aliases.
+ assert!(key_descriptors
+ .iter()
+ .all(|key| imported_key_aliases.contains(key.alias.as_ref().unwrap())));
+
+ delete_all_entries(&sl.keystore2);
+ assert_eq!(
+ sl.keystore2.getNumberOfEntries(Domain::APP, -1).unwrap(),
+ 0,
+ "Error while doing cleanup"
+ );
+ };
+
+ // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
+ // `--test-threads=1`), and nothing yet done with binder.
+ unsafe {
+ run_as::run_as(
+ CLIENT_CTX,
+ Uid::from_raw(CLIENT_UID),
+ Gid::from_raw(CLIENT_GID),
+ import_more_fn,
+ )
};
}
@@ -425,23 +462,31 @@
static CLIENT_UID: u32 = USER_ID * AID_USER_OFFSET + APPLICATION_ID;
static CLIENT_GID: u32 = CLIENT_UID;
- // SAFETY: The test is run in a separate process with no other threads.
+ let list_keys_fn = || {
+ let keystore2 = get_keystore_service();
+
+ // Make sure there are no keystore entries exist before adding new entries.
+ delete_all_entries(&keystore2);
+
+ // List all entries in keystore for this user-id, pass startingPastAlias = None
+ let key_descriptors = keystore2.listEntriesBatched(Domain::APP, -1, None).unwrap();
+ assert_eq!(key_descriptors.len(), 0);
+
+ // List all entries in keystore for this user-id, pass startingPastAlias = <random value>
+ let key_descriptors =
+ keystore2.listEntriesBatched(Domain::APP, -1, Some("startingPastAlias")).unwrap();
+ assert_eq!(key_descriptors.len(), 0);
+ };
+
+ // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
+ // `--test-threads=1`), and nothing yet done with binder.
unsafe {
- run_as::run_as(CLIENT_CTX, Uid::from_raw(CLIENT_UID), Gid::from_raw(CLIENT_GID), || {
- let keystore2 = get_keystore_service();
-
- // Make sure there are no keystore entries exist before adding new entries.
- delete_all_entries(&keystore2);
-
- // List all entries in keystore for this user-id, pass startingPastAlias = None
- let key_descriptors = keystore2.listEntriesBatched(Domain::APP, -1, None).unwrap();
- assert_eq!(key_descriptors.len(), 0);
-
- // List all entries in keystore for this user-id, pass startingPastAlias = <random value>
- let key_descriptors =
- keystore2.listEntriesBatched(Domain::APP, -1, Some("startingPastAlias")).unwrap();
- assert_eq!(key_descriptors.len(), 0);
- })
+ run_as::run_as(
+ CLIENT_CTX,
+ Uid::from_raw(CLIENT_UID),
+ Gid::from_raw(CLIENT_GID),
+ list_keys_fn,
+ )
};
}
@@ -510,131 +555,135 @@
static CLIENT_GID: u32 = CLIENT_UID;
static ALIAS_PREFIX: &str = "key_test_batch_list";
- // SAFETY: The test is run in a separate process with no other threads.
+ let list_keys_fn = || {
+ let sl = SecLevel::tee();
+
+ // Make sure there are no keystore entries exist before adding new entries.
+ delete_all_entries(&sl.keystore2);
+
+ // Import keys with below mentioned aliases -
+ // [
+ // key_test_batch_list_1,
+ // key_test_batch_list_2,
+ // key_test_batch_list_3,
+ // key_test_batch_list_4,
+ // key_test_batch_list_5,
+ // key_test_batch_list_10,
+ // key_test_batch_list_11,
+ // key_test_batch_list_12,
+ // key_test_batch_list_21,
+ // key_test_batch_list_22,
+ // ]
+ let _imported_key_aliases =
+ key_generations::import_aes_keys(&sl, ALIAS_PREFIX.to_string(), 1..6).unwrap();
+ assert_eq!(
+ sl.keystore2.getNumberOfEntries(Domain::APP, -1).unwrap(),
+ 5,
+ "Error while importing keys"
+ );
+ let _imported_key_aliases =
+ key_generations::import_aes_keys(&sl, ALIAS_PREFIX.to_string(), 10..13).unwrap();
+ assert_eq!(
+ sl.keystore2.getNumberOfEntries(Domain::APP, -1).unwrap(),
+ 8,
+ "Error while importing keys"
+ );
+ let _imported_key_aliases =
+ key_generations::import_aes_keys(&sl, ALIAS_PREFIX.to_string(), 21..23).unwrap();
+ assert_eq!(
+ sl.keystore2.getNumberOfEntries(Domain::APP, -1).unwrap(),
+ 10,
+ "Error while importing keys"
+ );
+
+ // List the aliases using given `startingPastAlias` and verify the listed
+ // aliases with the expected list of aliases.
+ verify_aliases(&sl.keystore2, Some(format!("{}{}", ALIAS_PREFIX, "_5").as_str()), vec![]);
+
+ verify_aliases(
+ &sl.keystore2,
+ Some(format!("{}{}", ALIAS_PREFIX, "_4").as_str()),
+ vec![ALIAS_PREFIX.to_owned() + "_5"],
+ );
+
+ verify_aliases(
+ &sl.keystore2,
+ Some(format!("{}{}", ALIAS_PREFIX, "_3").as_str()),
+ vec![ALIAS_PREFIX.to_owned() + "_4", ALIAS_PREFIX.to_owned() + "_5"],
+ );
+
+ verify_aliases(
+ &sl.keystore2,
+ Some(format!("{}{}", ALIAS_PREFIX, "_2").as_str()),
+ vec![
+ ALIAS_PREFIX.to_owned() + "_21",
+ ALIAS_PREFIX.to_owned() + "_22",
+ ALIAS_PREFIX.to_owned() + "_3",
+ ALIAS_PREFIX.to_owned() + "_4",
+ ALIAS_PREFIX.to_owned() + "_5",
+ ],
+ );
+
+ verify_aliases(
+ &sl.keystore2,
+ Some(format!("{}{}", ALIAS_PREFIX, "_1").as_str()),
+ vec![
+ ALIAS_PREFIX.to_owned() + "_10",
+ ALIAS_PREFIX.to_owned() + "_11",
+ ALIAS_PREFIX.to_owned() + "_12",
+ ALIAS_PREFIX.to_owned() + "_2",
+ ALIAS_PREFIX.to_owned() + "_21",
+ ALIAS_PREFIX.to_owned() + "_22",
+ ALIAS_PREFIX.to_owned() + "_3",
+ ALIAS_PREFIX.to_owned() + "_4",
+ ALIAS_PREFIX.to_owned() + "_5",
+ ],
+ );
+
+ verify_aliases(
+ &sl.keystore2,
+ Some(ALIAS_PREFIX),
+ vec![
+ ALIAS_PREFIX.to_owned() + "_1",
+ ALIAS_PREFIX.to_owned() + "_10",
+ ALIAS_PREFIX.to_owned() + "_11",
+ ALIAS_PREFIX.to_owned() + "_12",
+ ALIAS_PREFIX.to_owned() + "_2",
+ ALIAS_PREFIX.to_owned() + "_21",
+ ALIAS_PREFIX.to_owned() + "_22",
+ ALIAS_PREFIX.to_owned() + "_3",
+ ALIAS_PREFIX.to_owned() + "_4",
+ ALIAS_PREFIX.to_owned() + "_5",
+ ],
+ );
+
+ verify_aliases(
+ &sl.keystore2,
+ None,
+ vec![
+ ALIAS_PREFIX.to_owned() + "_1",
+ ALIAS_PREFIX.to_owned() + "_10",
+ ALIAS_PREFIX.to_owned() + "_11",
+ ALIAS_PREFIX.to_owned() + "_12",
+ ALIAS_PREFIX.to_owned() + "_2",
+ ALIAS_PREFIX.to_owned() + "_21",
+ ALIAS_PREFIX.to_owned() + "_22",
+ ALIAS_PREFIX.to_owned() + "_3",
+ ALIAS_PREFIX.to_owned() + "_4",
+ ALIAS_PREFIX.to_owned() + "_5",
+ ],
+ );
+ };
+
+ // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
+ // `--test-threads=1`), and nothing yet done with binder.
unsafe {
- run_as::run_as(CLIENT_CTX, Uid::from_raw(CLIENT_UID), Gid::from_raw(CLIENT_GID), || {
- let sl = SecLevel::tee();
-
- // Make sure there are no keystore entries exist before adding new entries.
- delete_all_entries(&sl.keystore2);
-
- // Import keys with below mentioned aliases -
- // [
- // key_test_batch_list_1,
- // key_test_batch_list_2,
- // key_test_batch_list_3,
- // key_test_batch_list_4,
- // key_test_batch_list_5,
- // key_test_batch_list_10,
- // key_test_batch_list_11,
- // key_test_batch_list_12,
- // key_test_batch_list_21,
- // key_test_batch_list_22,
- // ]
- let _imported_key_aliases =
- key_generations::import_aes_keys(&sl, ALIAS_PREFIX.to_string(), 1..6).unwrap();
- assert_eq!(
- sl.keystore2.getNumberOfEntries(Domain::APP, -1).unwrap(),
- 5,
- "Error while importing keys"
- );
- let _imported_key_aliases =
- key_generations::import_aes_keys(&sl, ALIAS_PREFIX.to_string(), 10..13).unwrap();
- assert_eq!(
- sl.keystore2.getNumberOfEntries(Domain::APP, -1).unwrap(),
- 8,
- "Error while importing keys"
- );
- let _imported_key_aliases =
- key_generations::import_aes_keys(&sl, ALIAS_PREFIX.to_string(), 21..23).unwrap();
- assert_eq!(
- sl.keystore2.getNumberOfEntries(Domain::APP, -1).unwrap(),
- 10,
- "Error while importing keys"
- );
-
- // List the aliases using given `startingPastAlias` and verify the listed
- // aliases with the expected list of aliases.
- verify_aliases(
- &sl.keystore2,
- Some(format!("{}{}", ALIAS_PREFIX, "_5").as_str()),
- vec![],
- );
-
- verify_aliases(
- &sl.keystore2,
- Some(format!("{}{}", ALIAS_PREFIX, "_4").as_str()),
- vec![ALIAS_PREFIX.to_owned() + "_5"],
- );
-
- verify_aliases(
- &sl.keystore2,
- Some(format!("{}{}", ALIAS_PREFIX, "_3").as_str()),
- vec![ALIAS_PREFIX.to_owned() + "_4", ALIAS_PREFIX.to_owned() + "_5"],
- );
-
- verify_aliases(
- &sl.keystore2,
- Some(format!("{}{}", ALIAS_PREFIX, "_2").as_str()),
- vec![
- ALIAS_PREFIX.to_owned() + "_21",
- ALIAS_PREFIX.to_owned() + "_22",
- ALIAS_PREFIX.to_owned() + "_3",
- ALIAS_PREFIX.to_owned() + "_4",
- ALIAS_PREFIX.to_owned() + "_5",
- ],
- );
-
- verify_aliases(
- &sl.keystore2,
- Some(format!("{}{}", ALIAS_PREFIX, "_1").as_str()),
- vec![
- ALIAS_PREFIX.to_owned() + "_10",
- ALIAS_PREFIX.to_owned() + "_11",
- ALIAS_PREFIX.to_owned() + "_12",
- ALIAS_PREFIX.to_owned() + "_2",
- ALIAS_PREFIX.to_owned() + "_21",
- ALIAS_PREFIX.to_owned() + "_22",
- ALIAS_PREFIX.to_owned() + "_3",
- ALIAS_PREFIX.to_owned() + "_4",
- ALIAS_PREFIX.to_owned() + "_5",
- ],
- );
-
- verify_aliases(
- &sl.keystore2,
- Some(ALIAS_PREFIX),
- vec![
- ALIAS_PREFIX.to_owned() + "_1",
- ALIAS_PREFIX.to_owned() + "_10",
- ALIAS_PREFIX.to_owned() + "_11",
- ALIAS_PREFIX.to_owned() + "_12",
- ALIAS_PREFIX.to_owned() + "_2",
- ALIAS_PREFIX.to_owned() + "_21",
- ALIAS_PREFIX.to_owned() + "_22",
- ALIAS_PREFIX.to_owned() + "_3",
- ALIAS_PREFIX.to_owned() + "_4",
- ALIAS_PREFIX.to_owned() + "_5",
- ],
- );
-
- verify_aliases(
- &sl.keystore2,
- None,
- vec![
- ALIAS_PREFIX.to_owned() + "_1",
- ALIAS_PREFIX.to_owned() + "_10",
- ALIAS_PREFIX.to_owned() + "_11",
- ALIAS_PREFIX.to_owned() + "_12",
- ALIAS_PREFIX.to_owned() + "_2",
- ALIAS_PREFIX.to_owned() + "_21",
- ALIAS_PREFIX.to_owned() + "_22",
- ALIAS_PREFIX.to_owned() + "_3",
- ALIAS_PREFIX.to_owned() + "_4",
- ALIAS_PREFIX.to_owned() + "_5",
- ],
- );
- })
+ run_as::run_as(
+ CLIENT_CTX,
+ Uid::from_raw(CLIENT_UID),
+ Gid::from_raw(CLIENT_GID),
+ list_keys_fn,
+ )
};
}
@@ -647,20 +696,21 @@
let agid = 91 * AID_USER_OFFSET + 10001;
static TARGET_CTX: &str = "u:r:untrusted_app:s0:c91,c256,c10,c20";
- // SAFETY: The test is run in a separate process with no other threads.
- unsafe {
- run_as::run_as(TARGET_CTX, Uid::from_raw(auid), Gid::from_raw(agid), move || {
- let keystore2 = get_keystore_service();
+ let list_keys_fn = move || {
+ let keystore2 = get_keystore_service();
- let result = key_generations::map_ks_error(keystore2.listEntriesBatched(
- Domain::SELINUX,
- key_generations::SELINUX_SHELL_NAMESPACE,
- None,
- ));
- assert!(result.is_err());
- assert_eq!(Error::Rc(ResponseCode::PERMISSION_DENIED), result.unwrap_err());
- })
+ let result = key_generations::map_ks_error(keystore2.listEntriesBatched(
+ Domain::SELINUX,
+ key_generations::SELINUX_SHELL_NAMESPACE,
+ None,
+ ));
+ assert!(result.is_err());
+ assert_eq!(Error::Rc(ResponseCode::PERMISSION_DENIED), result.unwrap_err());
};
+
+ // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
+ // `--test-threads=1`), and nothing yet done with binder.
+ unsafe { run_as::run_as(TARGET_CTX, Uid::from_raw(auid), Gid::from_raw(agid), list_keys_fn) };
}
/// Try to list key entries with domain BLOB. Test should fail with error response code
@@ -687,19 +737,19 @@
let agid = 91 * AID_USER_OFFSET + 10001;
static TARGET_CTX: &str = "u:r:untrusted_app:s0:c91,c256,c10,c20";
- // SAFETY: The test is run in a separate process with no other threads.
- unsafe {
- run_as::run_as(TARGET_CTX, Uid::from_raw(auid), Gid::from_raw(agid), move || {
- let keystore2 = get_keystore_service();
+ let get_num_fn = move || {
+ let keystore2 = get_keystore_service();
- let result = key_generations::map_ks_error(
- keystore2
- .getNumberOfEntries(Domain::SELINUX, key_generations::SELINUX_SHELL_NAMESPACE),
- );
- assert!(result.is_err());
- assert_eq!(Error::Rc(ResponseCode::PERMISSION_DENIED), result.unwrap_err());
- })
+ let result = key_generations::map_ks_error(
+ keystore2.getNumberOfEntries(Domain::SELINUX, key_generations::SELINUX_SHELL_NAMESPACE),
+ );
+ assert!(result.is_err());
+ assert_eq!(Error::Rc(ResponseCode::PERMISSION_DENIED), result.unwrap_err());
};
+
+ // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
+ // `--test-threads=1`), and nothing yet done with binder.
+ unsafe { run_as::run_as(TARGET_CTX, Uid::from_raw(auid), Gid::from_raw(agid), get_num_fn) };
}
/// Try to get number of key entries with domain BLOB. Test should fail with error response code
diff --git a/keystore2/tests/keystore2_client_operation_tests.rs b/keystore2/tests/keystore2_client_operation_tests.rs
index 5f640ef..b4dd385 100644
--- a/keystore2/tests/keystore2_client_operation_tests.rs
+++ b/keystore2/tests/keystore2_client_operation_tests.rs
@@ -40,7 +40,8 @@
///
/// # Safety
///
-/// Must be called from a process with no other threads.
+/// Must only be called from a single-threaded process (e.g. as enforced by `AndroidTest.xml`
+/// setting `--test-threads=1`).
pub unsafe fn create_operations(
target_ctx: &'static str,
forced_op: ForcedOp,
@@ -50,7 +51,7 @@
let base_gid = 99 * AID_USER_OFFSET + 10001;
let base_uid = 99 * AID_USER_OFFSET + 10001;
(0..max_ops)
- // SAFETY: The caller guarantees that there are no other threads.
+ // Safety: The caller guarantees that there are no other threads.
.map(|i| unsafe {
execute_op_run_as_child(
target_ctx,
@@ -93,7 +94,8 @@
const MAX_OPS: i32 = 100;
static TARGET_CTX: &str = "u:r:untrusted_app:s0:c91,c256,c10,c20";
- // SAFETY: The test is run in a separate process with no other threads.
+ // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
+ // `--test-threads=1`), and nothing yet done with binder.
let mut child_handles = unsafe { create_operations(TARGET_CTX, ForcedOp(false), MAX_OPS) };
// Wait until all child procs notifies us to continue,
@@ -127,7 +129,8 @@
static TARGET_CTX: &str = "u:r:untrusted_app:s0:c91,c256,c10,c20";
// Create regular operations.
- // SAFETY: The test is run in a separate process with no other threads.
+ // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
+ // `--test-threads=1`), and nothing yet done with binder.
let mut child_handles = unsafe { create_operations(TARGET_CTX, ForcedOp(false), MAX_OPS) };
// Wait until all child procs notifies us to continue, so that there are enough
@@ -139,28 +142,31 @@
// Create a forced operation.
let auid = 99 * AID_USER_OFFSET + 10604;
let agid = 99 * AID_USER_OFFSET + 10604;
- // SAFETY: The test is run in a separate process with no other threads.
+ let force_op_fn = move || {
+ let alias = format!("ks_prune_forced_op_key_{}", getuid());
+
+ // To make room for this forced op, system should be able to prune one of the
+ // above created regular operations and create a slot for this forced operation
+ // successfully.
+ create_signing_operation(
+ ForcedOp(true),
+ KeyPurpose::SIGN,
+ Digest::SHA_2_256,
+ Domain::SELINUX,
+ 100,
+ Some(alias),
+ )
+ .expect("Client failed to create forced operation after BACKEND_BUSY state.");
+ };
+
+ // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
+ // `--test-threads=1`), and nothing yet done with binder.
unsafe {
run_as::run_as(
key_generations::TARGET_VOLD_CTX,
Uid::from_raw(auid),
Gid::from_raw(agid),
- move || {
- let alias = format!("ks_prune_forced_op_key_{}", getuid());
-
- // To make room for this forced op, system should be able to prune one of the
- // above created regular operations and create a slot for this forced operation
- // successfully.
- create_signing_operation(
- ForcedOp(true),
- KeyPurpose::SIGN,
- Digest::SHA_2_256,
- Domain::SELINUX,
- 100,
- Some(alias),
- )
- .expect("Client failed to create forced operation after BACKEND_BUSY state.");
- },
+ force_op_fn,
);
};
@@ -212,7 +218,9 @@
// Create initial forced operation in a child process
// and wait for the parent to notify to perform operation.
let alias = format!("ks_forced_op_key_{}", getuid());
- // SAFETY: The test is run in a separate process with no other threads.
+
+ // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
+ // `--test-threads=1`), and nothing yet done with binder.
let mut first_op_handle = unsafe {
execute_op_run_as_child(
key_generations::TARGET_SU_CTX,
@@ -231,7 +239,8 @@
// Create MAX_OPS number of forced operations.
let mut child_handles =
- // SAFETY: The test is run in a separate process with no other threads.
+ // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
+ // `--test-threads=1`), and nothing yet done with binder.
unsafe { create_operations(key_generations::TARGET_SU_CTX, ForcedOp(true), MAX_OPS) };
// Wait until all child procs notifies us to continue, so that there are enough operations
@@ -295,7 +304,9 @@
// Create an operation in an untrusted_app context. Wait until the parent notifies to continue.
// Once the parent notifies, this operation is expected to be completed successfully.
let alias = format!("ks_reg_op_key_{}", getuid());
- // SAFETY: The test is run in a separate process with no other threads.
+
+ // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
+ // `--test-threads=1`), and nothing yet done with binder.
let mut child_handle = unsafe {
execute_op_run_as_child(
TARGET_CTX,
@@ -393,21 +404,24 @@
let gid = USER_ID * AID_USER_OFFSET + APPLICATION_ID;
for context in TARGET_CTXS.iter() {
- // SAFETY: The test is run in a separate process with no other threads.
+ let forced_op_fn = move || {
+ let alias = format!("ks_app_forced_op_test_key_{}", getuid());
+ let result = key_generations::map_ks_error(create_signing_operation(
+ ForcedOp(true),
+ KeyPurpose::SIGN,
+ Digest::SHA_2_256,
+ Domain::APP,
+ -1,
+ Some(alias),
+ ));
+ assert!(result.is_err());
+ assert_eq!(Error::Rc(ResponseCode::PERMISSION_DENIED), result.unwrap_err());
+ };
+
+ // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
+ // `--test-threads=1`), and nothing yet done with binder.
unsafe {
- run_as::run_as(context, Uid::from_raw(uid), Gid::from_raw(gid), move || {
- let alias = format!("ks_app_forced_op_test_key_{}", getuid());
- let result = key_generations::map_ks_error(create_signing_operation(
- ForcedOp(true),
- KeyPurpose::SIGN,
- Digest::SHA_2_256,
- Domain::APP,
- -1,
- Some(alias),
- ));
- assert!(result.is_err());
- assert_eq!(Error::Rc(ResponseCode::PERMISSION_DENIED), result.unwrap_err());
- });
+ run_as::run_as(context, Uid::from_raw(uid), Gid::from_raw(gid), forced_op_fn);
}
}
}
@@ -422,21 +436,23 @@
let uid = USER_ID * AID_USER_OFFSET + APPLICATION_ID;
let gid = USER_ID * AID_USER_OFFSET + APPLICATION_ID;
+ let forced_op_fn = move || {
+ let alias = format!("ks_vold_forced_op_key_{}", getuid());
+ create_signing_operation(
+ ForcedOp(true),
+ KeyPurpose::SIGN,
+ Digest::SHA_2_256,
+ Domain::SELINUX,
+ key_generations::SELINUX_VOLD_NAMESPACE,
+ Some(alias),
+ )
+ .expect("Client with vold context failed to create forced operation.");
+ };
- // SAFETY: The test is run in a separate process with no other threads.
+ // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
+ // `--test-threads=1`), and nothing yet done with binder.
unsafe {
- run_as::run_as(TARGET_CTX, Uid::from_raw(uid), Gid::from_raw(gid), move || {
- let alias = format!("ks_vold_forced_op_key_{}", getuid());
- create_signing_operation(
- ForcedOp(true),
- KeyPurpose::SIGN,
- Digest::SHA_2_256,
- Domain::SELINUX,
- key_generations::SELINUX_VOLD_NAMESPACE,
- Some(alias),
- )
- .expect("Client with vold context failed to create forced operation.");
- });
+ run_as::run_as(TARGET_CTX, Uid::from_raw(uid), Gid::from_raw(gid), forced_op_fn);
}
}
diff --git a/keystore2/tests/keystore2_client_test_utils.rs b/keystore2/tests/keystore2_client_test_utils.rs
index 9029b97..831fc85 100644
--- a/keystore2/tests/keystore2_client_test_utils.rs
+++ b/keystore2/tests/keystore2_client_test_utils.rs
@@ -25,7 +25,11 @@
};
use binder::wait_for_interface;
use keystore2_test_utils::{
- authorizations, key_generations, key_generations::Error, run_as, SecLevel,
+ authorizations, key_generations,
+ key_generations::Error,
+ run_as,
+ run_as::{ChannelReader, ChannelWriter},
+ SecLevel,
};
use nix::unistd::{Gid, Uid};
use openssl::bn::BigNum;
@@ -305,7 +309,8 @@
///
/// # Safety
///
-/// Must only be called from a single-threaded process.
+/// Must only be called from a single-threaded process (e.g. as enforced by `AndroidTest.xml`
+/// setting `--test-threads=1`).
pub unsafe fn execute_op_run_as_child(
target_ctx: &'static str,
domain: Domain,
@@ -315,41 +320,44 @@
agid: Gid,
forced_op: ForcedOp,
) -> run_as::ChildHandle<TestOutcome, BarrierReached> {
- // SAFETY: The caller guarantees that there are no other threads.
- unsafe {
- run_as::run_as_child(target_ctx, auid, agid, move |reader, writer| {
- let result = key_generations::map_ks_error(create_signing_operation(
- forced_op,
- KeyPurpose::SIGN,
- Digest::SHA_2_256,
- domain,
- nspace,
- alias,
- ));
+ let child_fn = move |reader: &mut ChannelReader<BarrierReached>,
+ writer: &mut ChannelWriter<BarrierReached>| {
+ let result = key_generations::map_ks_error(create_signing_operation(
+ forced_op,
+ KeyPurpose::SIGN,
+ Digest::SHA_2_256,
+ domain,
+ nspace,
+ alias,
+ ));
- // Let the parent know that an operation has been started, then
- // wait until the parent notifies us to continue, so the operation
- // remains open.
- writer.send(&BarrierReached {});
- reader.recv();
+ // Let the parent know that an operation has been started, then
+ // wait until the parent notifies us to continue, so the operation
+ // remains open.
+ writer.send(&BarrierReached {});
+ reader.recv();
- // Continue performing the operation after parent notifies.
- match &result {
- Ok(CreateOperationResponse { iOperation: Some(op), .. }) => {
- match key_generations::map_ks_error(perform_sample_sign_operation(op)) {
- Ok(()) => TestOutcome::Ok,
- Err(Error::Km(ErrorCode::INVALID_OPERATION_HANDLE)) => {
- TestOutcome::InvalidHandle
- }
- Err(e) => panic!("Error in performing op: {:#?}", e),
+ // Continue performing the operation after parent notifies.
+ match &result {
+ Ok(CreateOperationResponse { iOperation: Some(op), .. }) => {
+ match key_generations::map_ks_error(perform_sample_sign_operation(op)) {
+ Ok(()) => TestOutcome::Ok,
+ Err(Error::Km(ErrorCode::INVALID_OPERATION_HANDLE)) => {
+ TestOutcome::InvalidHandle
}
+ Err(e) => panic!("Error in performing op: {:#?}", e),
}
- Ok(_) => TestOutcome::OtherErr,
- Err(Error::Rc(ResponseCode::BACKEND_BUSY)) => TestOutcome::BackendBusy,
- _ => TestOutcome::OtherErr,
}
- })
- .expect("Failed to create an operation.")
+ Ok(_) => TestOutcome::OtherErr,
+ Err(Error::Rc(ResponseCode::BACKEND_BUSY)) => TestOutcome::BackendBusy,
+ _ => TestOutcome::OtherErr,
+ }
+ };
+
+ // Safety: The caller guarantees that there are no other threads.
+ unsafe {
+ run_as::run_as_child(target_ctx, auid, agid, child_fn)
+ .expect("Failed to create an operation.")
}
}
diff --git a/keystore2/tests/keystore2_client_update_subcomponent_tests.rs b/keystore2/tests/keystore2_client_update_subcomponent_tests.rs
index e25e52a..c1ec6a1 100644
--- a/keystore2/tests/keystore2_client_update_subcomponent_tests.rs
+++ b/keystore2/tests/keystore2_client_update_subcomponent_tests.rs
@@ -166,115 +166,115 @@
static GRANTEE_2_GID: u32 = GRANTEE_2_UID;
// Generate a key and grant it to multiple users with different access permissions.
- // SAFETY: The test is run in a separate process with no other threads.
- let mut granted_keys = unsafe {
- run_as::run_as(GRANTOR_SU_CTX, Uid::from_raw(0), Gid::from_raw(0), || {
- let sl = SecLevel::tee();
- let alias = format!("ks_update_subcompo_test_1_{}", getuid());
- let mut granted_keys = Vec::new();
+ let grantor_fn = || {
+ let sl = SecLevel::tee();
+ let alias = format!("ks_update_subcompo_test_1_{}", getuid());
+ let mut granted_keys = Vec::new();
- let key_metadata = key_generations::generate_ec_p256_signing_key(
- &sl,
- Domain::APP,
- -1,
- Some(alias),
- None,
- )
+ let key_metadata =
+ key_generations::generate_ec_p256_signing_key(&sl, Domain::APP, -1, Some(alias), None)
+ .unwrap();
+
+ // Grant a key without update permission.
+ let access_vector = KeyPermission::GET_INFO.0;
+ let granted_key = sl
+ .keystore2
+ .grant(&key_metadata.key, GRANTEE_1_UID.try_into().unwrap(), access_vector)
.unwrap();
+ assert_eq!(granted_key.domain, Domain::GRANT);
+ granted_keys.push(granted_key.nspace);
- // Grant a key without update permission.
- let access_vector = KeyPermission::GET_INFO.0;
- let granted_key = sl
- .keystore2
- .grant(&key_metadata.key, GRANTEE_1_UID.try_into().unwrap(), access_vector)
- .unwrap();
- assert_eq!(granted_key.domain, Domain::GRANT);
- granted_keys.push(granted_key.nspace);
+ // Grant a key with update permission.
+ let access_vector = KeyPermission::GET_INFO.0 | KeyPermission::UPDATE.0;
+ let granted_key = sl
+ .keystore2
+ .grant(&key_metadata.key, GRANTEE_2_UID.try_into().unwrap(), access_vector)
+ .unwrap();
+ assert_eq!(granted_key.domain, Domain::GRANT);
+ granted_keys.push(granted_key.nspace);
- // Grant a key with update permission.
- let access_vector = KeyPermission::GET_INFO.0 | KeyPermission::UPDATE.0;
- let granted_key = sl
- .keystore2
- .grant(&key_metadata.key, GRANTEE_2_UID.try_into().unwrap(), access_vector)
- .unwrap();
- assert_eq!(granted_key.domain, Domain::GRANT);
- granted_keys.push(granted_key.nspace);
-
- granted_keys
- })
+ granted_keys
};
+ // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
+ // `--test-threads=1`), and nothing yet done with binder.
+ let mut granted_keys =
+ unsafe { run_as::run_as(GRANTOR_SU_CTX, Uid::from_raw(0), Gid::from_raw(0), grantor_fn) };
+
// Grantee context, try to update the key public certs, permission denied error is expected.
let granted_key1_nspace = granted_keys.remove(0);
- // SAFETY: The test is run in a separate process with no other threads.
+ let grantee1_fn = move || {
+ let keystore2 = get_keystore_service();
+
+ let other_cert: [u8; 32] = [123; 32];
+ let other_cert_chain: [u8; 32] = [12; 32];
+
+ let result = key_generations::map_ks_error(keystore2.updateSubcomponent(
+ &KeyDescriptor {
+ domain: Domain::GRANT,
+ nspace: granted_key1_nspace,
+ alias: None,
+ blob: None,
+ },
+ Some(&other_cert),
+ Some(&other_cert_chain),
+ ));
+ assert!(result.is_err());
+ assert_eq!(Error::Rc(ResponseCode::PERMISSION_DENIED), result.unwrap_err());
+ };
+
+ // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
+ // `--test-threads=1`), and nothing yet done with binder.
unsafe {
run_as::run_as(
GRANTEE_CTX,
Uid::from_raw(GRANTEE_1_UID),
Gid::from_raw(GRANTEE_1_GID),
- move || {
- let keystore2 = get_keystore_service();
-
- let other_cert: [u8; 32] = [123; 32];
- let other_cert_chain: [u8; 32] = [12; 32];
-
- let result = key_generations::map_ks_error(keystore2.updateSubcomponent(
- &KeyDescriptor {
- domain: Domain::GRANT,
- nspace: granted_key1_nspace,
- alias: None,
- blob: None,
- },
- Some(&other_cert),
- Some(&other_cert_chain),
- ));
- assert!(result.is_err());
- assert_eq!(Error::Rc(ResponseCode::PERMISSION_DENIED), result.unwrap_err());
- },
+ grantee1_fn,
)
};
// Grantee context, update granted key public certs. Update should happen successfully.
let granted_key2_nspace = granted_keys.remove(0);
- // SAFETY: The test is run in a separate process with no other threads.
+ let grantee2_fn = move || {
+ let keystore2 = get_keystore_service();
+
+ let other_cert: [u8; 32] = [124; 32];
+ let other_cert_chain: [u8; 32] = [13; 32];
+
+ keystore2
+ .updateSubcomponent(
+ &KeyDescriptor {
+ domain: Domain::GRANT,
+ nspace: granted_key2_nspace,
+ alias: None,
+ blob: None,
+ },
+ Some(&other_cert),
+ Some(&other_cert_chain),
+ )
+ .expect("updateSubcomponent should have succeeded.");
+
+ let key_entry_response = keystore2
+ .getKeyEntry(&KeyDescriptor {
+ domain: Domain::GRANT,
+ nspace: granted_key2_nspace,
+ alias: None,
+ blob: None,
+ })
+ .unwrap();
+ assert_eq!(Some(other_cert.to_vec()), key_entry_response.metadata.certificate);
+ assert_eq!(Some(other_cert_chain.to_vec()), key_entry_response.metadata.certificateChain);
+ };
+
+ // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
+ // `--test-threads=1`), and nothing yet done with binder.
unsafe {
run_as::run_as(
GRANTEE_CTX,
Uid::from_raw(GRANTEE_2_UID),
Gid::from_raw(GRANTEE_2_GID),
- move || {
- let keystore2 = get_keystore_service();
-
- let other_cert: [u8; 32] = [124; 32];
- let other_cert_chain: [u8; 32] = [13; 32];
-
- keystore2
- .updateSubcomponent(
- &KeyDescriptor {
- domain: Domain::GRANT,
- nspace: granted_key2_nspace,
- alias: None,
- blob: None,
- },
- Some(&other_cert),
- Some(&other_cert_chain),
- )
- .expect("updateSubcomponent should have succeeded.");
-
- let key_entry_response = keystore2
- .getKeyEntry(&KeyDescriptor {
- domain: Domain::GRANT,
- nspace: granted_key2_nspace,
- alias: None,
- blob: None,
- })
- .unwrap();
- assert_eq!(Some(other_cert.to_vec()), key_entry_response.metadata.certificate);
- assert_eq!(
- Some(other_cert_chain.to_vec()),
- key_entry_response.metadata.certificateChain
- );
- },
+ grantee2_fn,
)
};
}
diff --git a/keystore2/tests/legacy_blobs/keystore2_legacy_blob_tests.rs b/keystore2/tests/legacy_blobs/keystore2_legacy_blob_tests.rs
index 11a4c0b..cb99fe7 100644
--- a/keystore2/tests/legacy_blobs/keystore2_legacy_blob_tests.rs
+++ b/keystore2/tests/legacy_blobs/keystore2_legacy_blob_tests.rs
@@ -137,205 +137,203 @@
std::fs::remove_dir_all(path_buf.as_path()).unwrap();
}
- // Safety: run_as must be called from a single threaded process.
- // This device test is run as a separate single threaded process.
- let mut gen_key_result = unsafe {
- run_as::run_as(TARGET_SU_CTX, Uid::from_raw(0), Gid::from_raw(0), || {
- // Remove user if already exist.
- let maint_service = get_maintenance();
- match maint_service.onUserRemoved(99) {
- Ok(_) => {
- println!("User was existed, deleted successfully");
- }
- Err(e) => {
- println!("onUserRemoved error: {:#?}", e);
- }
+ let gen_key_fn = || {
+ // Remove user if already exist.
+ let maint_service = get_maintenance();
+ match maint_service.onUserRemoved(99) {
+ Ok(_) => {
+ println!("User did exist, deleted successfully");
}
- let sl = SecLevel::tee();
+ Err(e) => {
+ println!("onUserRemoved error: {:#?}", e);
+ }
+ }
+ let sl = SecLevel::tee();
- // Generate Key BLOB and prepare legacy keystore blob files.
- let att_challenge: Option<&[u8]> = if rkp_only() { None } else { Some(b"foo") };
- let key_metadata = key_generations::generate_ec_p256_signing_key(
- &sl,
- Domain::BLOB,
- SELINUX_SHELL_NAMESPACE,
- None,
- att_challenge,
+ // Generate Key BLOB and prepare legacy keystore blob files.
+ let att_challenge: Option<&[u8]> = if rkp_only() { None } else { Some(b"foo") };
+ let key_metadata = key_generations::generate_ec_p256_signing_key(
+ &sl,
+ Domain::BLOB,
+ SELINUX_SHELL_NAMESPACE,
+ None,
+ att_challenge,
+ )
+ .expect("Failed to generate key blob");
+
+ // Create keystore file layout for user_99.
+ let pw: Password = PASSWORD.into();
+ let pw_key = TestKey(pw.derive_key_pbkdf2(SUPERKEY_SALT, 32).unwrap());
+ let super_key =
+ TestKey(pw_key.decrypt(SUPERKEY_PAYLOAD, SUPERKEY_IV, SUPERKEY_TAG).unwrap());
+
+ let mut path_buf = PathBuf::from("/data/misc/keystore/user_99");
+ if !path_buf.as_path().is_dir() {
+ std::fs::create_dir(path_buf.as_path()).unwrap();
+ }
+ path_buf.push(".masterkey");
+ if !path_buf.as_path().is_file() {
+ std::fs::write(path_buf.as_path(), SUPERKEY).unwrap();
+ }
+
+ let mut path_buf = PathBuf::from("/data/misc/keystore/user_99");
+ path_buf.push("9910001_USRPKEY_authbound");
+ if !path_buf.as_path().is_file() {
+ make_encrypted_key_file(
+ path_buf.as_path(),
+ &super_key,
+ &key_metadata.key.blob.unwrap(),
)
- .expect("Failed to generate key blob");
+ .unwrap();
+ }
- // Create keystore file layout for user_99.
- let pw: Password = PASSWORD.into();
- let pw_key = TestKey(pw.derive_key_pbkdf2(SUPERKEY_SALT, 32).unwrap());
- let super_key =
- TestKey(pw_key.decrypt(SUPERKEY_PAYLOAD, SUPERKEY_IV, SUPERKEY_TAG).unwrap());
-
- let mut path_buf = PathBuf::from("/data/misc/keystore/user_99");
- if !path_buf.as_path().is_dir() {
- std::fs::create_dir(path_buf.as_path()).unwrap();
- }
- path_buf.push(".masterkey");
- if !path_buf.as_path().is_file() {
- std::fs::write(path_buf.as_path(), SUPERKEY).unwrap();
- }
-
- let mut path_buf = PathBuf::from("/data/misc/keystore/user_99");
- path_buf.push("9910001_USRPKEY_authbound");
- if !path_buf.as_path().is_file() {
- make_encrypted_key_file(
- path_buf.as_path(),
- &super_key,
- &key_metadata.key.blob.unwrap(),
- )
+ let mut path_buf = PathBuf::from("/data/misc/keystore/user_99");
+ path_buf.push(".9910001_chr_USRPKEY_authbound");
+ if !path_buf.as_path().is_file() {
+ make_encrypted_characteristics_file(path_buf.as_path(), &super_key, KEY_PARAMETERS)
.unwrap();
- }
+ }
+ let mut path_buf = PathBuf::from("/data/misc/keystore/user_99");
+ path_buf.push("9910001_USRCERT_authbound");
+ if !path_buf.as_path().is_file() {
+ make_cert_blob_file(path_buf.as_path(), key_metadata.certificate.as_ref().unwrap())
+ .unwrap();
+ }
+
+ if let Some(chain) = key_metadata.certificateChain.as_ref() {
let mut path_buf = PathBuf::from("/data/misc/keystore/user_99");
- path_buf.push(".9910001_chr_USRPKEY_authbound");
+ path_buf.push("9910001_CACERT_authbound");
if !path_buf.as_path().is_file() {
- make_encrypted_characteristics_file(path_buf.as_path(), &super_key, KEY_PARAMETERS)
- .unwrap();
+ make_cert_blob_file(path_buf.as_path(), chain).unwrap();
}
+ }
- let mut path_buf = PathBuf::from("/data/misc/keystore/user_99");
- path_buf.push("9910001_USRCERT_authbound");
- if !path_buf.as_path().is_file() {
- make_cert_blob_file(path_buf.as_path(), key_metadata.certificate.as_ref().unwrap())
- .unwrap();
+ // Keystore2 disables the legacy importer when it finds the legacy database empty.
+ // However, if the device boots with an empty legacy database, the optimization kicks in
+ // and keystore2 never checks the legacy file system layout.
+ // So, restart keystore2 service to detect populated legacy database.
+ keystore2_restart_service();
+
+ let auth_service = get_authorization();
+ match auth_service.onDeviceUnlocked(99, Some(PASSWORD)) {
+ Ok(result) => {
+ println!("Unlock Result: {:?}", result);
}
-
- if let Some(chain) = key_metadata.certificateChain.as_ref() {
- let mut path_buf = PathBuf::from("/data/misc/keystore/user_99");
- path_buf.push("9910001_CACERT_authbound");
- if !path_buf.as_path().is_file() {
- make_cert_blob_file(path_buf.as_path(), chain).unwrap();
- }
+ Err(e) => {
+ panic!("Unlock should have succeeded: {:?}", e);
}
+ }
- // Keystore2 disables the legacy importer when it finds the legacy database empty.
- // However, if the device boots with an empty legacy database, the optimization kicks in
- // and keystore2 never checks the legacy file system layout.
- // So, restart keystore2 service to detect populated legacy database.
- keystore2_restart_service();
+ let mut key_params: Vec<KsKeyparameter> = Vec::new();
+ for param in key_metadata.authorizations {
+ let key_param = KsKeyparameter::new(param.keyParameter.into(), param.securityLevel);
+ key_params.push(key_param);
+ }
- let auth_service = get_authorization();
- match auth_service.onDeviceUnlocked(99, Some(PASSWORD)) {
- Ok(result) => {
- println!("Unlock Result: {:?}", result);
- }
- Err(e) => {
- panic!("Unlock should have succeeded: {:?}", e);
- }
- }
-
- let mut key_params: Vec<KsKeyparameter> = Vec::new();
- for param in key_metadata.authorizations {
- let key_param = KsKeyparameter::new(param.keyParameter.into(), param.securityLevel);
- key_params.push(key_param);
- }
-
- KeygenResult {
- cert: key_metadata.certificate.unwrap(),
- cert_chain: key_metadata.certificateChain.unwrap_or_default(),
- key_parameters: key_params,
- }
- })
+ KeygenResult {
+ cert: key_metadata.certificate.unwrap(),
+ cert_chain: key_metadata.certificateChain.unwrap_or_default(),
+ key_parameters: key_params,
+ }
};
- // Safety: run_as must be called from a single threaded process.
- // This device test is run as a separate single threaded process.
- unsafe {
- run_as::run_as(TARGET_CTX, Uid::from_raw(auid), Gid::from_raw(agid), move || {
- println!("UID: {}", getuid());
- println!("Android User ID: {}", rustutils::users::multiuser_get_user_id(9910001));
- println!("Android app ID: {}", rustutils::users::multiuser_get_app_id(9910001));
+ // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
+ // `--test-threads=1`), and nothing yet done with binder.
+ let mut gen_key_result =
+ unsafe { run_as::run_as(TARGET_SU_CTX, Uid::from_raw(0), Gid::from_raw(0), gen_key_fn) };
- let test_alias = "authbound";
- let keystore2 = get_keystore_service();
+ let use_key_fn = move || {
+ println!("UID: {}", getuid());
+ println!("Android User ID: {}", rustutils::users::multiuser_get_user_id(9910001));
+ println!("Android app ID: {}", rustutils::users::multiuser_get_app_id(9910001));
- match keystore2.getKeyEntry(&KeyDescriptor {
- domain: Domain::APP,
- nspace: SELINUX_SHELL_NAMESPACE,
- alias: Some(test_alias.to_string()),
- blob: None,
- }) {
- Ok(key_entry_response) => {
- assert_eq!(
- key_entry_response.metadata.certificate.unwrap(),
- gen_key_result.cert
- );
- assert_eq!(
- key_entry_response.metadata.certificateChain.unwrap_or_default(),
- gen_key_result.cert_chain
- );
- assert_eq!(key_entry_response.metadata.key.domain, Domain::KEY_ID);
- assert_ne!(key_entry_response.metadata.key.nspace, 0);
- assert_eq!(
- key_entry_response.metadata.keySecurityLevel,
- SecurityLevel::SecurityLevel::TRUSTED_ENVIRONMENT
- );
+ let test_alias = "authbound";
+ let keystore2 = get_keystore_service();
- // Preapare KsKeyParameter list from getKeEntry response Authorizations.
- let mut key_params: Vec<KsKeyparameter> = Vec::new();
- for param in key_entry_response.metadata.authorizations {
- let key_param =
- KsKeyparameter::new(param.keyParameter.into(), param.securityLevel);
- key_params.push(key_param);
- }
+ match keystore2.getKeyEntry(&KeyDescriptor {
+ domain: Domain::APP,
+ nspace: SELINUX_SHELL_NAMESPACE,
+ alias: Some(test_alias.to_string()),
+ blob: None,
+ }) {
+ Ok(key_entry_response) => {
+ assert_eq!(key_entry_response.metadata.certificate.unwrap(), gen_key_result.cert);
+ assert_eq!(
+ key_entry_response.metadata.certificateChain.unwrap_or_default(),
+ gen_key_result.cert_chain
+ );
+ assert_eq!(key_entry_response.metadata.key.domain, Domain::KEY_ID);
+ assert_ne!(key_entry_response.metadata.key.nspace, 0);
+ assert_eq!(
+ key_entry_response.metadata.keySecurityLevel,
+ SecurityLevel::SecurityLevel::TRUSTED_ENVIRONMENT
+ );
- // Combine keyparameters from gen_key_result and keyparameters
- // from legacy key-char file.
- let mut legacy_file_key_params: Vec<KsKeyparameter> = Vec::new();
- match structured_test_params() {
- LegacyKeyCharacteristics::File(legacy_key_params) => {
- for param in &legacy_key_params {
- let mut present_in_gen_params = false;
- for gen_param in &gen_key_result.key_parameters {
- if param.get_tag() == gen_param.get_tag() {
- present_in_gen_params = true;
- }
- }
- if !present_in_gen_params {
- legacy_file_key_params.push(param.clone());
+ // Preapare KsKeyParameter list from getKeEntry response Authorizations.
+ let mut key_params: Vec<KsKeyparameter> = Vec::new();
+ for param in key_entry_response.metadata.authorizations {
+ let key_param =
+ KsKeyparameter::new(param.keyParameter.into(), param.securityLevel);
+ key_params.push(key_param);
+ }
+
+ // Combine keyparameters from gen_key_result and keyparameters
+ // from legacy key-char file.
+ let mut legacy_file_key_params: Vec<KsKeyparameter> = Vec::new();
+ match structured_test_params() {
+ LegacyKeyCharacteristics::File(legacy_key_params) => {
+ for param in &legacy_key_params {
+ let mut present_in_gen_params = false;
+ for gen_param in &gen_key_result.key_parameters {
+ if param.get_tag() == gen_param.get_tag() {
+ present_in_gen_params = true;
}
}
- }
- _ => {
- panic!("Expecting file characteristics");
+ if !present_in_gen_params {
+ legacy_file_key_params.push(param.clone());
+ }
}
}
-
- // Remove Key-Params which have security levels other than TRUSTED_ENVIRONMENT
- gen_key_result.key_parameters.retain(|in_element| {
- *in_element.security_level()
- == SecurityLevel::SecurityLevel::TRUSTED_ENVIRONMENT
- });
-
- println!("GetKeyEntry response key params: {:#?}", key_params);
- println!("Generated key params: {:#?}", gen_key_result.key_parameters);
-
- gen_key_result.key_parameters.append(&mut legacy_file_key_params);
-
- println!("Combined key params: {:#?}", gen_key_result.key_parameters);
-
- // Validate all keyparameters present in getKeyEntry response.
- for param in &key_params {
- gen_key_result.key_parameters.retain(|in_element| *in_element != *param);
+ _ => {
+ panic!("Expecting file characteristics");
}
+ }
- println!(
- "GetKeyEntry response unmatched key params: {:#?}",
- gen_key_result.key_parameters
- );
- assert_eq!(gen_key_result.key_parameters.len(), 0);
+ // Remove Key-Params which have security levels other than TRUSTED_ENVIRONMENT
+ gen_key_result.key_parameters.retain(|in_element| {
+ *in_element.security_level()
+ == SecurityLevel::SecurityLevel::TRUSTED_ENVIRONMENT
+ });
+
+ println!("GetKeyEntry response key params: {:#?}", key_params);
+ println!("Generated key params: {:#?}", gen_key_result.key_parameters);
+
+ gen_key_result.key_parameters.append(&mut legacy_file_key_params);
+
+ println!("Combined key params: {:#?}", gen_key_result.key_parameters);
+
+ // Validate all keyparameters present in getKeyEntry response.
+ for param in &key_params {
+ gen_key_result.key_parameters.retain(|in_element| *in_element != *param);
}
- Err(s) => {
- panic!("getKeyEntry should have succeeded. {:?}", s);
- }
- };
- })
+
+ println!(
+ "GetKeyEntry response unmatched key params: {:#?}",
+ gen_key_result.key_parameters
+ );
+ assert_eq!(gen_key_result.key_parameters.len(), 0);
+ }
+ Err(s) => {
+ panic!("getKeyEntry should have succeeded. {:?}", s);
+ }
+ };
};
+ // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
+ // `--test-threads=1`), and nothing yet done with binder.
+ unsafe { run_as::run_as(TARGET_CTX, Uid::from_raw(auid), Gid::from_raw(agid), use_key_fn) };
+
// Make sure keystore2 clean up imported legacy db.
let path_buf = PathBuf::from("/data/misc/keystore/user_99");
if path_buf.as_path().is_dir() {
@@ -367,7 +365,7 @@
/// 6. To load and import the legacy key using its alias.
/// 7. After successful key import validate the user cert and cert-chain with initially
/// generated blobs.
-/// 8. Validate imported key perameters. Imported key parameters list should be the combination
+/// 8. Validate imported key parameters. Imported key parameters list should be the combination
/// of the key-parameters in characteristics file and the characteristics according to
/// the augmentation rules. There might be duplicate entries with different values for the
/// parameters like OS_VERSION, OS_VERSION, BOOT_PATCHLEVEL, VENDOR_PATCHLEVEL etc.
@@ -385,177 +383,172 @@
std::fs::remove_dir_all(path_buf.as_path()).unwrap();
}
- // Safety: run_as must be called from a single threaded process.
- // This device test is run as a separate single threaded process.
- let gen_key_result = unsafe {
- run_as::run_as(TARGET_SU_CTX, Uid::from_raw(0), Gid::from_raw(0), || {
- // Remove user if already exist.
- let maint_service = get_maintenance();
- match maint_service.onUserRemoved(98) {
- Ok(_) => {
- println!("User was existed, deleted successfully");
- }
- Err(e) => {
- println!("onUserRemoved error: {:#?}", e);
- }
+ let gen_key_fn = || {
+ // Remove user if already exist.
+ let maint_service = get_maintenance();
+ match maint_service.onUserRemoved(98) {
+ Ok(_) => {
+ println!("User did exist, deleted successfully");
}
+ Err(e) => {
+ println!("onUserRemoved error: {:#?}", e);
+ }
+ }
- let sl = SecLevel::tee();
- // Generate Key BLOB and prepare legacy keystore blob files.
- let att_challenge: Option<&[u8]> = if rkp_only() { None } else { Some(b"foo") };
- let key_metadata = key_generations::generate_ec_p256_signing_key(
- &sl,
- Domain::BLOB,
- SELINUX_SHELL_NAMESPACE,
- None,
- att_challenge,
+ let sl = SecLevel::tee();
+ // Generate Key BLOB and prepare legacy keystore blob files.
+ let att_challenge: Option<&[u8]> = if rkp_only() { None } else { Some(b"foo") };
+ let key_metadata = key_generations::generate_ec_p256_signing_key(
+ &sl,
+ Domain::BLOB,
+ SELINUX_SHELL_NAMESPACE,
+ None,
+ att_challenge,
+ )
+ .expect("Failed to generate key blob");
+
+ // Create keystore file layout for user_98.
+ let pw: Password = PASSWORD.into();
+ let pw_key = TestKey(pw.derive_key_pbkdf2(SUPERKEY_SALT, 32).unwrap());
+ let super_key =
+ TestKey(pw_key.decrypt(SUPERKEY_PAYLOAD, SUPERKEY_IV, SUPERKEY_TAG).unwrap());
+
+ let mut path_buf = PathBuf::from("/data/misc/keystore/user_98");
+ if !path_buf.as_path().is_dir() {
+ std::fs::create_dir(path_buf.as_path()).unwrap();
+ }
+ path_buf.push(".masterkey");
+ if !path_buf.as_path().is_file() {
+ std::fs::write(path_buf.as_path(), SUPERKEY).unwrap();
+ }
+
+ let mut path_buf = PathBuf::from("/data/misc/keystore/user_98");
+ path_buf.push("9810001_USRPKEY_authboundcertenc");
+ if !path_buf.as_path().is_file() {
+ make_encrypted_key_file(
+ path_buf.as_path(),
+ &super_key,
+ &key_metadata.key.blob.unwrap(),
)
- .expect("Failed to generate key blob");
+ .unwrap();
+ }
- // Create keystore file layout for user_98.
- let pw: Password = PASSWORD.into();
- let pw_key = TestKey(pw.derive_key_pbkdf2(SUPERKEY_SALT, 32).unwrap());
- let super_key =
- TestKey(pw_key.decrypt(SUPERKEY_PAYLOAD, SUPERKEY_IV, SUPERKEY_TAG).unwrap());
+ let mut path_buf = PathBuf::from("/data/misc/keystore/user_98");
+ path_buf.push(".9810001_chr_USRPKEY_authboundcertenc");
+ if !path_buf.as_path().is_file() {
+ std::fs::write(path_buf.as_path(), USRPKEY_AUTHBOUND_CHR).unwrap();
+ }
+ let mut path_buf = PathBuf::from("/data/misc/keystore/user_98");
+ path_buf.push("9810001_USRCERT_authboundcertenc");
+ if !path_buf.as_path().is_file() {
+ make_encrypted_usr_cert_file(
+ path_buf.as_path(),
+ &super_key,
+ key_metadata.certificate.as_ref().unwrap(),
+ )
+ .unwrap();
+ }
+
+ if let Some(chain) = key_metadata.certificateChain.as_ref() {
let mut path_buf = PathBuf::from("/data/misc/keystore/user_98");
- if !path_buf.as_path().is_dir() {
- std::fs::create_dir(path_buf.as_path()).unwrap();
- }
- path_buf.push(".masterkey");
+ path_buf.push("9810001_CACERT_authboundcertenc");
if !path_buf.as_path().is_file() {
- std::fs::write(path_buf.as_path(), SUPERKEY).unwrap();
+ make_encrypted_ca_cert_file(path_buf.as_path(), &super_key, chain).unwrap();
}
+ }
- let mut path_buf = PathBuf::from("/data/misc/keystore/user_98");
- path_buf.push("9810001_USRPKEY_authboundcertenc");
- if !path_buf.as_path().is_file() {
- make_encrypted_key_file(
- path_buf.as_path(),
- &super_key,
- &key_metadata.key.blob.unwrap(),
- )
- .unwrap();
+ // Keystore2 disables the legacy importer when it finds the legacy database empty.
+ // However, if the device boots with an empty legacy database, the optimization kicks in
+ // and keystore2 never checks the legacy file system layout.
+ // So, restart keystore2 service to detect populated legacy database.
+ keystore2_restart_service();
+
+ let auth_service = get_authorization();
+ match auth_service.onDeviceUnlocked(98, Some(PASSWORD)) {
+ Ok(result) => {
+ println!("Unlock Result: {:?}", result);
}
-
- let mut path_buf = PathBuf::from("/data/misc/keystore/user_98");
- path_buf.push(".9810001_chr_USRPKEY_authboundcertenc");
- if !path_buf.as_path().is_file() {
- std::fs::write(path_buf.as_path(), USRPKEY_AUTHBOUND_CHR).unwrap();
+ Err(e) => {
+ panic!("Unlock should have succeeded: {:?}", e);
}
+ }
- let mut path_buf = PathBuf::from("/data/misc/keystore/user_98");
- path_buf.push("9810001_USRCERT_authboundcertenc");
- if !path_buf.as_path().is_file() {
- make_encrypted_usr_cert_file(
- path_buf.as_path(),
- &super_key,
- key_metadata.certificate.as_ref().unwrap(),
- )
- .unwrap();
- }
+ let mut key_params: Vec<KsKeyparameter> = Vec::new();
+ for param in key_metadata.authorizations {
+ let key_param = KsKeyparameter::new(param.keyParameter.into(), param.securityLevel);
+ key_params.push(key_param);
+ }
- if let Some(chain) = key_metadata.certificateChain.as_ref() {
- let mut path_buf = PathBuf::from("/data/misc/keystore/user_98");
- path_buf.push("9810001_CACERT_authboundcertenc");
- if !path_buf.as_path().is_file() {
- make_encrypted_ca_cert_file(path_buf.as_path(), &super_key, chain).unwrap();
- }
- }
-
- // Keystore2 disables the legacy importer when it finds the legacy database empty.
- // However, if the device boots with an empty legacy database, the optimization kicks in
- // and keystore2 never checks the legacy file system layout.
- // So, restart keystore2 service to detect populated legacy database.
- keystore2_restart_service();
-
- let auth_service = get_authorization();
- match auth_service.onDeviceUnlocked(98, Some(PASSWORD)) {
- Ok(result) => {
- println!("Unlock Result: {:?}", result);
- }
- Err(e) => {
- panic!("Unlock should have succeeded: {:?}", e);
- }
- }
-
- let mut key_params: Vec<KsKeyparameter> = Vec::new();
- for param in key_metadata.authorizations {
- let key_param = KsKeyparameter::new(param.keyParameter.into(), param.securityLevel);
- key_params.push(key_param);
- }
-
- KeygenResult {
- cert: key_metadata.certificate.unwrap(),
- cert_chain: key_metadata.certificateChain.unwrap_or_default(),
- key_parameters: key_params,
- }
- })
+ KeygenResult {
+ cert: key_metadata.certificate.unwrap(),
+ cert_chain: key_metadata.certificateChain.unwrap_or_default(),
+ key_parameters: key_params,
+ }
};
- // Safety: run_as must be called from a single threaded process.
- // This device test is run as a separate single threaded process.
- unsafe {
- run_as::run_as(TARGET_CTX, Uid::from_raw(auid), Gid::from_raw(agid), move || {
- println!("UID: {}", getuid());
- println!("Android User ID: {}", rustutils::users::multiuser_get_user_id(9810001));
- println!("Android app ID: {}", rustutils::users::multiuser_get_app_id(9810001));
+ // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
+ // `--test-threads=1`), and nothing yet done with binder.
+ let gen_key_result =
+ unsafe { run_as::run_as(TARGET_SU_CTX, Uid::from_raw(0), Gid::from_raw(0), gen_key_fn) };
- let test_alias = "authboundcertenc";
- let keystore2 = get_keystore_service();
+ let use_key_fn = move || {
+ println!("UID: {}", getuid());
+ println!("Android User ID: {}", rustutils::users::multiuser_get_user_id(9810001));
+ println!("Android app ID: {}", rustutils::users::multiuser_get_app_id(9810001));
- match keystore2.getKeyEntry(&KeyDescriptor {
- domain: Domain::APP,
- nspace: SELINUX_SHELL_NAMESPACE,
- alias: Some(test_alias.to_string()),
- blob: None,
- }) {
- Ok(key_entry_response) => {
- assert_eq!(
- key_entry_response.metadata.certificate.unwrap(),
- gen_key_result.cert
- );
- assert_eq!(
- key_entry_response.metadata.certificateChain.unwrap_or_default(),
- gen_key_result.cert_chain
- );
+ let test_alias = "authboundcertenc";
+ let keystore2 = get_keystore_service();
- // Preapare KsKeyParameter list from getKeEntry response Authorizations.
- let mut key_params: Vec<KsKeyparameter> = Vec::new();
- for param in key_entry_response.metadata.authorizations {
- let key_param =
- KsKeyparameter::new(param.keyParameter.into(), param.securityLevel);
- key_params.push(key_param);
+ match keystore2.getKeyEntry(&KeyDescriptor {
+ domain: Domain::APP,
+ nspace: SELINUX_SHELL_NAMESPACE,
+ alias: Some(test_alias.to_string()),
+ blob: None,
+ }) {
+ Ok(key_entry_response) => {
+ assert_eq!(key_entry_response.metadata.certificate.unwrap(), gen_key_result.cert);
+ assert_eq!(
+ key_entry_response.metadata.certificateChain.unwrap_or_default(),
+ gen_key_result.cert_chain
+ );
+
+ // Preapare KsKeyParameter list from getKeEntry response Authorizations.
+ let mut key_params: Vec<KsKeyparameter> = Vec::new();
+ for param in key_entry_response.metadata.authorizations {
+ let key_param =
+ KsKeyparameter::new(param.keyParameter.into(), param.securityLevel);
+ key_params.push(key_param);
+ }
+
+ println!("GetKeyEntry response key params: {:#?}", key_params);
+ println!("Generated key params: {:#?}", gen_key_result.key_parameters);
+ match structured_test_params_cache() {
+ LegacyKeyCharacteristics::Cache(legacy_key_params) => {
+ println!("Legacy key-char cache: {:#?}", legacy_key_params);
+ // Validate all keyparameters present in getKeyEntry response.
+ for param in &legacy_key_params {
+ key_params.retain(|in_element| *in_element != *param);
+ }
+
+ println!("GetKeyEntry response unmatched key params: {:#?}", key_params);
+ assert_eq!(key_params.len(), 0);
}
-
- println!("GetKeyEntry response key params: {:#?}", key_params);
- println!("Generated key params: {:#?}", gen_key_result.key_parameters);
- match structured_test_params_cache() {
- LegacyKeyCharacteristics::Cache(legacy_key_params) => {
- println!("Legacy key-char cache: {:#?}", legacy_key_params);
- // Validate all keyparameters present in getKeyEntry response.
- for param in &legacy_key_params {
- key_params.retain(|in_element| *in_element != *param);
- }
-
- println!(
- "GetKeyEntry response unmatched key params: {:#?}",
- key_params
- );
- assert_eq!(key_params.len(), 0);
- }
- _ => {
- panic!("Expecting file characteristics");
- }
+ _ => {
+ panic!("Expecting file characteristics");
}
}
- Err(s) => {
- panic!("getKeyEntry should have succeeded. {:?}", s);
- }
- };
- })
+ }
+ Err(s) => {
+ panic!("getKeyEntry should have succeeded. {:?}", s);
+ }
+ };
};
+ // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
+ // `--test-threads=1`), and nothing yet done with binder.
+ unsafe { run_as::run_as(TARGET_CTX, Uid::from_raw(auid), Gid::from_raw(agid), use_key_fn) };
+
// Make sure keystore2 clean up imported legacy db.
let path_buf = PathBuf::from("/data/misc/keystore/user_98");
if path_buf.as_path().is_dir() {