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<()> {