Merge "Mark unused policy as such."
diff --git a/keystore2/src/attestation_key_utils.rs b/keystore2/src/attestation_key_utils.rs
index 8354ba5..3408942 100644
--- a/keystore2/src/attestation_key_utils.rs
+++ b/keystore2/src/attestation_key_utils.rs
@@ -59,8 +59,11 @@
     db: &mut KeystoreDB,
 ) -> Result<Option<AttestationKeyInfo>> {
     let challenge_present = params.iter().any(|kp| kp.tag == Tag::ATTESTATION_CHALLENGE);
+    let is_device_unique_attestation =
+        params.iter().any(|kp| kp.tag == Tag::DEVICE_UNIQUE_ATTESTATION);
     match attest_key_descriptor {
-        None if challenge_present => rem_prov_state
+        // Do not select an RKP key if DEVICE_UNIQUE_ATTESTATION is present.
+        None if challenge_present && !is_device_unique_attestation => rem_prov_state
             .get_remotely_provisioned_attestation_key_and_certs(key, caller_uid, params, db)
             .context(concat!(
                 "In get_attest_key_and_cert_chain: ",
diff --git a/keystore2/src/database.rs b/keystore2/src/database.rs
index a3979bd..baa3b12 100644
--- a/keystore2/src/database.rs
+++ b/keystore2/src/database.rs
@@ -2581,7 +2581,7 @@
 
                 Ok((key_id, access_key, access_vector))
             }
-            _ => Err(anyhow!(KsError::sys())),
+            _ => Err(anyhow!(KsError::Rc(ResponseCode::INVALID_ARGUMENT))),
         }
     }
 
diff --git a/keystore2/test_utils/key_generations.rs b/keystore2/test_utils/key_generations.rs
index f8628ee..6398f31 100644
--- a/keystore2/test_utils/key_generations.rs
+++ b/keystore2/test_utils/key_generations.rs
@@ -30,6 +30,8 @@
 
 /// Shell namespace.
 pub const SELINUX_SHELL_NAMESPACE: i64 = 1;
+/// Vold namespace.
+pub const SELINUX_VOLD_NAMESPACE: i64 = 100;
 
 /// SU context.
 pub const TARGET_SU_CTX: &str = "u:r:su:s0";
diff --git a/keystore2/tests/keystore2_client_tests.rs b/keystore2/tests/keystore2_client_tests.rs
index 03dcfec..06268c5 100644
--- a/keystore2/tests/keystore2_client_tests.rs
+++ b/keystore2/tests/keystore2_client_tests.rs
@@ -434,3 +434,91 @@
         _ => panic!("Operation should have created successfully."),
     }
 }
+
+/// This test will try to load the key with Domain::BLOB.
+/// INVALID_ARGUMENT error is expected.
+#[test]
+fn keystore2_get_key_entry_blob_fail() {
+    let keystore2 = get_keystore_service();
+    let sec_level = keystore2.getSecurityLevel(SecurityLevel::TRUSTED_ENVIRONMENT).unwrap();
+
+    // Generate a key with domain as BLOB.
+    let key_metadata = key_generations::generate_ec_p256_signing_key(
+        &sec_level,
+        Domain::BLOB,
+        key_generations::SELINUX_SHELL_NAMESPACE,
+        None,
+        None,
+        None,
+    )
+    .unwrap();
+
+    // Try to load the key using above generated KeyDescriptor.
+    let result = key_generations::map_ks_error(keystore2.getKeyEntry(&key_metadata.key));
+    assert!(result.is_err());
+    assert_eq!(Error::Rc(ResponseCode::INVALID_ARGUMENT), result.unwrap_err());
+
+    // Delete the generated key blob.
+    sec_level.deleteKey(&key_metadata.key).unwrap();
+}
+
+/// Try to create forced operations with various contexts -
+///   - untrusted_app
+///   - system_server
+///   - priv_app
+/// `PERMISSION_DENIED` error response is expected.
+#[test]
+fn keystore2_forced_op_perm_denied_test() {
+    static TARGET_CTXS: &[&str] =
+        &["u:r:untrusted_app:s0", "u:r:system_server:s0", "u:r:priv_app:s0"];
+    const USER_ID: u32 = 99;
+    const APPLICATION_ID: u32 = 10601;
+
+    let uid = USER_ID * AID_USER_OFFSET + APPLICATION_ID;
+    let gid = USER_ID * AID_USER_OFFSET + APPLICATION_ID;
+
+    for context in TARGET_CTXS.iter() {
+        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());
+            });
+        }
+    }
+}
+
+/// Try to create a forced operation with `vold` context.
+/// Should be able to create forced operation with `vold` context successfully.
+#[test]
+fn keystore2_forced_op_success_test() {
+    static TARGET_CTX: &str = "u:r:vold:s0";
+    const USER_ID: u32 = 99;
+    const APPLICATION_ID: u32 = 10601;
+
+    let uid = USER_ID * AID_USER_OFFSET + APPLICATION_ID;
+    let gid = USER_ID * AID_USER_OFFSET + APPLICATION_ID;
+
+    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.");
+        });
+    }
+}