Added listUidsOfCredentialBoundKeys method to AIDL
Bug: b/112321280
Test: add auth bound keys from an app
Test: adb shell "su 1000 keystore_cli_v2 list-apps-with-keys"
Test: see uid of app listed
Test: $ ./keystore/tests/list_auth_bound_keys_test.sh
Change-Id: Id6739ea17e566f9aa51f1bd2d5a0715f1020b644
diff --git a/keystore/key_store_service.cpp b/keystore/key_store_service.cpp
index 2f07fbf..24bf331 100644
--- a/keystore/key_store_service.cpp
+++ b/keystore/key_store_service.cpp
@@ -276,6 +276,79 @@
return Status::ok();
}
+/*
+ * This method will return the uids of all auth bound keys for the calling user.
+ * This is intended to be used for alerting the user about which apps will be affected
+ * if the password/pin is removed. Only allowed to be called by system.
+ * The output is bound by the initial size of uidsOut to be compatible with Java.
+ */
+Status KeyStoreService::listUidsOfAuthBoundKeys(::std::vector<int32_t>* uidsOut,
+ int32_t* aidl_return) {
+ const int32_t callingUid = IPCThreadState::self()->getCallingUid();
+ const int32_t userId = get_user_id(callingUid);
+ const int32_t appId = get_app_id(callingUid);
+ if (appId != AID_SYSTEM) {
+ ALOGE("Permission listUidsOfAuthBoundKeys denied for aid %d", appId);
+ *aidl_return = static_cast<int32_t>(ResponseCode::PERMISSION_DENIED);
+ return Status::ok();
+ }
+
+ const String8 prefix8("");
+ auto userState = mKeyStore->getUserStateDB().getUserState(userId);
+ const std::string userDirName = userState->getUserDirName();
+ auto encryptionKey = userState->getEncryptionKey();
+ auto state = userState->getState();
+ // unlock the user state
+ userState = {};
+
+ ResponseCode rc;
+ std::list<LockedKeyBlobEntry> internal_matches;
+ std::tie(rc, internal_matches) =
+ LockedKeyBlobEntry::list(userDirName, [&](uid_t, const std::string&) {
+ // Need to filter on auth bound state, so just return true.
+ return true;
+ });
+ if (rc != ResponseCode::NO_ERROR) {
+ ALOGE("Error listing blob entries for user %d", userId);
+ return Status::fromServiceSpecificError(static_cast<int32_t>(rc));
+ }
+
+ auto it = uidsOut->begin();
+ for (LockedKeyBlobEntry& entry : internal_matches) {
+ if (it == uidsOut->end()) {
+ ALOGW("Maximum number (%d) of auth bound uids found, truncating remainder",
+ static_cast<int32_t>(uidsOut->capacity()));
+ break;
+ }
+ if (std::find(uidsOut->begin(), it, entry->uid()) != it) {
+ // uid already in list, skip
+ continue;
+ }
+
+ auto [rc, blob, charBlob] = entry.readBlobs(encryptionKey, state);
+ if (rc != ResponseCode::NO_ERROR && rc != ResponseCode::LOCKED) {
+ ALOGE("Error reading blob for key %s", entry->alias().c_str());
+ continue;
+ }
+
+ if (blob && blob.isEncrypted()) {
+ *it++ = entry->uid();
+ } else if (charBlob) {
+ auto [success, hwEnforced, swEnforced] = charBlob.getKeyCharacteristics();
+ if (!success) {
+ ALOGE("Error reading blob characteristics for key %s", entry->alias().c_str());
+ continue;
+ }
+ if (hwEnforced.Contains(TAG_USER_SECURE_ID) ||
+ swEnforced.Contains(TAG_USER_SECURE_ID)) {
+ *it++ = entry->uid();
+ }
+ }
+ }
+ *aidl_return = static_cast<int32_t>(ResponseCode::NO_ERROR);
+ return Status::ok();
+}
+
Status KeyStoreService::reset(int32_t* aidl_return) {
if (!checkBinderPermission(P_RESET)) {
*aidl_return = static_cast<int32_t>(ResponseCode::PERMISSION_DENIED);