Implement dump for IKeystoreMaintenance
Sample output on Cuttlefish:
```
keystore2 running
Device info for r#TRUSTED_ENVIRONMENT with Uuid([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1])
HAL version: 300
Implementation name: Rust reference implementation
Implementation author: Google
Timestamp token required: false
Database size information (in bytes):
r#DATABASE : 77824
r#KEY_ENTRY : 4096 (unused 3603)
r#KEY_ENTRY_ID_INDEX : 4096 (unused 3969)
r#KEY_ENTRY_DOMAIN_NAMESPACE_INDEX : 4096 (unused 3820)
r#BLOB_ENTRY : 4096 (unused 863)
r#BLOB_ENTRY_KEY_ENTRY_ID_INDEX : 4096 (unused 3954)
r#KEY_PARAMETER : 4096 (unused 2459)
r#KEY_PARAMETER_KEY_ENTRY_ID_INDEX : 4096 (unused 3024)
r#KEY_METADATA : 4096 (unused 3826)
r#KEY_METADATA_KEY_ENTRY_ID_INDEX : 4096 (unused 3999)
r#GRANT : 4096 (unused 4088)
r#AUTH_TOKEN : 0
r#BLOB_METADATA : 4096 (unused 3572)
r#BLOB_METADATA_BLOB_ENTRY_ID_INDEX : 4096 (unused 3906)
```
Test: adb shell dumpsys android.security.maintenance
Bug: 344987718
Flag: android.security.keystore2.enable_dump
Change-Id: I231079f32648e2fab7fed4857f6d3e29755b0d19
diff --git a/keystore2/src/utils.rs b/keystore2/src/utils.rs
index 81ebdab..2b69d1e 100644
--- a/keystore2/src/utils.rs
+++ b/keystore2/src/utils.rs
@@ -38,6 +38,7 @@
};
use android_system_keystore2::aidl::android::system::keystore2::{
Authorization::Authorization, Domain::Domain, KeyDescriptor::KeyDescriptor,
+ ResponseCode::ResponseCode,
};
use anyhow::{Context, Result};
use binder::{FromIBinder, StatusCode, Strong, ThreadState};
@@ -125,14 +126,20 @@
/// identifiers. It throws an error if the permissions cannot be verified or if the caller doesn't
/// have the right permissions. Otherwise it returns silently.
pub fn check_device_attestation_permissions() -> anyhow::Result<()> {
- check_android_permission("android.permission.READ_PRIVILEGED_PHONE_STATE")
+ check_android_permission(
+ "android.permission.READ_PRIVILEGED_PHONE_STATE",
+ Error::Km(ErrorCode::CANNOT_ATTEST_IDS),
+ )
}
/// This function checks whether the calling app has the Android permissions needed to attest the
/// device-unique identifier. It throws an error if the permissions cannot be verified or if the
/// caller doesn't have the right permissions. Otherwise it returns silently.
pub fn check_unique_id_attestation_permissions() -> anyhow::Result<()> {
- check_android_permission("android.permission.REQUEST_UNIQUE_ID_ATTESTATION")
+ check_android_permission(
+ "android.permission.REQUEST_UNIQUE_ID_ATTESTATION",
+ Error::Km(ErrorCode::CANNOT_ATTEST_IDS),
+ )
}
/// This function checks whether the calling app has the Android permissions needed to manage
@@ -141,10 +148,19 @@
/// It throws an error if the permissions cannot be verified or if the caller doesn't
/// have the right permissions. Otherwise it returns silently.
pub fn check_get_app_uids_affected_by_sid_permissions() -> anyhow::Result<()> {
- check_android_permission("android.permission.MANAGE_USERS")
+ check_android_permission(
+ "android.permission.MANAGE_USERS",
+ Error::Km(ErrorCode::CANNOT_ATTEST_IDS),
+ )
}
-fn check_android_permission(permission: &str) -> anyhow::Result<()> {
+/// This function checks whether the calling app has the Android permission needed to dump
+/// Keystore state to logcat.
+pub fn check_dump_permission() -> anyhow::Result<()> {
+ check_android_permission("android.permission.DUMP", Error::Rc(ResponseCode::PERMISSION_DENIED))
+}
+
+fn check_android_permission(permission: &str, err: Error) -> anyhow::Result<()> {
let permission_controller: Strong<dyn IPermissionController::IPermissionController> =
binder::get_interface("permission")?;
@@ -160,8 +176,7 @@
map_binder_status(binder_result).context(ks_err!("checkPermission failed"))?;
match has_permissions {
true => Ok(()),
- false => Err(Error::Km(ErrorCode::CANNOT_ATTEST_IDS))
- .context(ks_err!("caller does not have the permission to attest device IDs")),
+ false => Err(err).context(ks_err!("caller does not have the '{permission}' permission")),
}
}