Keystore 2.0: Implement list keys.
Test: keystore2_test
Change-Id: Id5b875adce95723cd837b22beca7af44621bb2cd
diff --git a/keystore2/src/service.rs b/keystore2/src/service.rs
index eb0d01b..cb04031 100644
--- a/keystore2/src/service.rs
+++ b/keystore2/src/service.rs
@@ -22,10 +22,11 @@
use crate::error::{self, map_or_log_err, ErrorCode};
use crate::globals::DB;
use crate::permission;
-use crate::permission::KeyPerm;
+use crate::permission::{KeyPerm, KeystorePerm};
use crate::security_level::KeystoreSecurityLevel;
use crate::utils::{
- check_grant_permission, check_key_permission, key_parameters_to_authorizations, Asp,
+ check_grant_permission, check_key_permission, check_keystore_permission,
+ key_parameters_to_authorizations, Asp,
};
use android_hardware_security_keymint::aidl::android::hardware::security::keymint::SecurityLevel::SecurityLevel;
use android_system_keystore2::aidl::android::system::keystore2::{
@@ -35,6 +36,8 @@
};
use anyhow::{anyhow, Context, Result};
use binder::{IBinder, Interface, ThreadState};
+use error::Error;
+use keystore2_selinux as selinux;
/// Implementation of the IKeystoreService.
pub struct KeystoreService {
@@ -146,8 +149,44 @@
}
fn list_entries(&self, domain: Domain, namespace: i64) -> Result<Vec<KeyDescriptor>> {
- // TODO implement.
- Err(anyhow!(error::Error::sys()))
+ let mut k = match domain {
+ Domain::APP => KeyDescriptor {
+ domain,
+ nspace: ThreadState::get_calling_uid() as u64 as i64,
+ ..Default::default()
+ },
+ Domain::SELINUX => KeyDescriptor{domain, nspace: namespace, ..Default::default()},
+ _ => return Err(Error::perm()).context(
+ "In list_entries: List entries is only supported for Domain::APP and Domain::SELINUX."
+ ),
+ };
+
+ // First we check if the caller has the info permission for the selected domain/namespace.
+ // By default we use the calling uid as namespace if domain is Domain::APP.
+ // If the first check fails we check if the caller has the list permission allowing to list
+ // any namespace. In that case we also adjust the queried namespace if a specific uid was
+ // selected.
+ match check_key_permission(KeyPerm::get_info(), &k, &None) {
+ Err(e) => {
+ if let Some(selinux::Error::PermissionDenied) =
+ e.root_cause().downcast_ref::<selinux::Error>()
+ {
+ check_keystore_permission(KeystorePerm::list())
+ .context("In list_entries: While checking keystore permission.")?;
+ if namespace != -1 {
+ k.nspace = namespace;
+ }
+ } else {
+ return Err(e).context("In list_entries: While checking key permission.")?;
+ }
+ }
+ Ok(()) => {}
+ };
+
+ DB.with(|db| {
+ let mut db = db.borrow_mut();
+ db.list(k.domain, k.nspace)
+ })
}
fn delete_key(&self, key: &KeyDescriptor) -> Result<()> {