credstore: Don't require credentials to use ACP ids starting at 0. This fixes a bug in credstore where it only worked if a credential used ACP ids starting at zero and upwards (e.g. no holes). This is not a reasonable requirement, it just happened to be a bug which wasn't triggered because all CTS tests uses identifiers starting at 0 with no holes. This bug-fix is merged along with a new CTS test to check this bug no longer exists. Bug: 160966911 Test: atest android.security.identity.cts Test: New CTS test testProvisionAcpIdNotStartingAtZero Merged-In: I58595e6bf5f3ca3f82ebe9291fde54b7cf11e0dd Change-Id: I7731f24510a3d380c473906d5e771422bcb7efe7
diff --git a/identity/Credential.cpp b/identity/Credential.cpp index 59a4d81..28ba752 100644 --- a/identity/Credential.cpp +++ b/identity/Credential.cpp
@@ -184,7 +184,21 @@ // in the startRetrieval() call. vector<int32_t> requestCounts; const vector<SecureAccessControlProfile>& allProfiles = data_->getSecureAccessControlProfiles(); - vector<bool> includeProfile(allProfiles.size()); + + // We don't support ACP identifiers which isn't in the range 0 to 31. This + // guarantee exists so it's feasible to implement the TA part of an Identity + // Credential HAL implementation where the TA uses a 32-bit word to indicate + // which profiles are authorized. + for (const SecureAccessControlProfile& profile : allProfiles) { + if (profile.id < 0 || profile.id >= 32) { + return Status::fromServiceSpecificError( + ICredentialStore::ERROR_GENERIC, + "Invalid accessProfileId in profile (must be between 0 and 31)"); + } + } + + vector<bool> includeProfile(32); + for (const RequestNamespaceParcel& rns : requestNamespaces) { size_t numEntriesInNsToRequest = 0; for (const RequestEntryParcel& rep : rns.entries) { @@ -195,11 +209,12 @@ optional<EntryData> data = data_->getEntryData(rns.namespaceName, rep.name); if (data) { for (int32_t id : data.value().accessControlProfileIds) { - if (id >= int32_t(includeProfile.size())) { + if (id < 0 || id >= 32) { LOG(ERROR) << "Invalid accessControlProfileId " << id << " for " << rns.namespaceName << ": " << rep.name; return Status::fromServiceSpecificError( - ICredentialStore::ERROR_GENERIC, "Invalid accessProfileId for entry"); + ICredentialStore::ERROR_GENERIC, + "Invalid accessProfileId in entry (must be between 0 and 31)"); } includeProfile[id] = true; } @@ -212,7 +227,7 @@ // HAL. vector<SecureAccessControlProfile> selectedProfiles; for (size_t n = 0; n < allProfiles.size(); n++) { - if (includeProfile[n]) { + if (includeProfile[allProfiles[n].id]) { selectedProfiles.push_back(allProfiles[n]); } }