Retry getKeyAttestationApplicationId when fails
We want to retry the command getKeyAttestationApplicationId
some number of times before we return a failure to the user.
Getting the attest app id can fail at times, but if we retry
it may succeed.
Test: atest keystore2_test
Test: atest CtsKeystoreTestCases
Bug: 238619180
Change-Id: I77e76c2f33f08c9214ea290284e75078e3b1eea1
diff --git a/keystore/keystore_attestation_id.cpp b/keystore/keystore_attestation_id.cpp
index 1534be1..d607fbf 100644
--- a/keystore/keystore_attestation_id.cpp
+++ b/keystore/keystore_attestation_id.cpp
@@ -29,6 +29,7 @@
#include <binder/Parcelable.h>
#include <binder/PersistableBundle.h>
+#include <aidl/android/system/keystore2/ResponseCode.h>
#include <android/security/keystore/BpKeyAttestationApplicationIdProvider.h>
#include <android/security/keystore/IKeyAttestationApplicationIdProvider.h>
#include <android/security/keystore/KeyAttestationApplicationId.h>
@@ -49,6 +50,8 @@
constexpr const char* kAttestationSystemPackageName = "AndroidSystem";
constexpr const char* kUnknownPackageName = "UnknownPackage";
+constexpr const size_t kMaxAttempts = 3;
+constexpr const unsigned long kRetryIntervalUsecs = 500000; // sleep for 500 ms
std::vector<uint8_t> signature2SHA256(const security::keystore::Signature& sig) {
std::vector<uint8_t> digest_buffer(SHA256_DIGEST_LENGTH);
@@ -56,6 +59,7 @@
return digest_buffer;
}
+using ::aidl::android::system::keystore2::ResponseCode;
using ::android::security::keystore::BpKeyAttestationApplicationIdProvider;
class KeyAttestationApplicationIdProvider : public BpKeyAttestationApplicationIdProvider {
@@ -279,17 +283,31 @@
} else {
/* Get the attestation application ID from package manager */
auto& pm = KeyAttestationApplicationIdProvider::get();
- auto status = pm.getKeyAttestationApplicationId(uid, &key_attestation_id);
+ ::android::binder::Status status;
+
+ // Retry on failure if a service specific error code.
+ for (size_t attempt{0}; attempt < kMaxAttempts; ++attempt) {
+ status = pm.getKeyAttestationApplicationId(uid, &key_attestation_id);
+ if (status.isOk()) {
+ break;
+ } else if (status.exceptionCode() != binder::Status::EX_SERVICE_SPECIFIC) {
+ ALOGW("Retry: key attestation ID failed with service specific error: %s %d",
+ status.exceptionMessage().c_str(), status.serviceSpecificErrorCode());
+ usleep(kRetryIntervalUsecs);
+ } else {
+ ALOGW("Retry: key attestation ID failed with error: %s %d",
+ status.exceptionMessage().c_str(), status.exceptionCode());
+ usleep(kRetryIntervalUsecs);
+ }
+ }
+
// Package Manager call has failed, perform attestation but indicate that the
// caller is unknown.
if (!status.isOk()) {
ALOGW("package manager request for key attestation ID failed with: %s %d",
status.exceptionMessage().c_str(), status.exceptionCode());
- auto pinfo = KeyAttestationPackageInfo();
- pinfo.packageName = String16(kUnknownPackageName);
- pinfo.versionCode = 1;
- key_attestation_id.packageInfos.push_back(std::move(pinfo));
+ return int32_t(ResponseCode::GET_ATTESTATION_APPLICATION_ID_FAILED);
}
}