identity: Migrate to RKPD for attestation keys

Bug: 261214100
Test: TBD
Change-Id: I760ba8c23be0889e7d01ac6c1513eba348ff96b2
diff --git a/identity/CredentialStore.cpp b/identity/CredentialStore.cpp
index c5c429b..eb9bdb6 100644
--- a/identity/CredentialStore.cpp
+++ b/identity/CredentialStore.cpp
@@ -26,6 +26,8 @@
 #include <android/security/remoteprovisioning/RemotelyProvisionedKey.h>
 #include <binder/IPCThreadState.h>
 #include <binder/IServiceManager.h>
+#include <server_configurable_flags/get_flags.h>
+#include <vintf/VintfObject.h>
 
 #include "Credential.h"
 #include "CredentialData.h"
@@ -39,41 +41,14 @@
 namespace identity {
 namespace {
 
-using ::android::hardware::security::keymint::IRemotelyProvisionedComponent;
-using ::android::hardware::security::keymint::RpcHardwareInfo;
 using ::android::security::remoteprovisioning::IRemotelyProvisionedKeyPool;
-using ::android::security::remoteprovisioning::RemotelyProvisionedKey;
+using ::android::security::rkp::IRemoteProvisioning;
 
-std::optional<std::string>
-getRemotelyProvisionedComponentId(const sp<IIdentityCredentialStore>& hal) {
-    auto init = [](const sp<IIdentityCredentialStore>& hal) -> std::optional<std::string> {
-        sp<IRemotelyProvisionedComponent> remotelyProvisionedComponent;
-        Status status = hal->getRemotelyProvisionedComponent(&remotelyProvisionedComponent);
-        if (!status.isOk()) {
-            LOG(ERROR) << "Error getting remotely provisioned component: " << status;
-            return std::nullopt;
-        }
-
-        RpcHardwareInfo rpcHwInfo;
-        status = remotelyProvisionedComponent->getHardwareInfo(&rpcHwInfo);
-        if (!status.isOk()) {
-            LOG(ERROR) << "Error getting remotely provisioned component hardware info: " << status;
-            return std::nullopt;
-        }
-
-        if (!rpcHwInfo.uniqueId) {
-            LOG(ERROR) << "Remotely provisioned component is missing a unique id, which is "
-                       << "required for credential key remotely provisioned attestation keys. "
-                       << "This is a bug in the vendor implementation.";
-            return std::nullopt;
-        }
-
-        // This id is required to later fetch remotely provisioned attestation keys.
-        return *rpcHwInfo.uniqueId;
-    };
-
-    static std::optional<std::string> id = init(hal);
-    return id;
+bool useRkpd() {
+    std::string useRkpdFlagValue = server_configurable_flags::GetServerConfigurableFlag(
+        "remote_key_provisioning_native", "enable_rkpd",
+        /*default_value=*/"false");
+    return useRkpdFlagValue == "true";
 }
 
 }  // namespace
@@ -90,13 +65,30 @@
     halApiVersion_ = hal_->getInterfaceVersion();
 
     if (hwInfo_.isRemoteKeyProvisioningSupported) {
-        keyPool_ = android::waitForService<IRemotelyProvisionedKeyPool>(
-            IRemotelyProvisionedKeyPool::descriptor);
-        if (keyPool_.get() == nullptr) {
-            LOG(ERROR) << "Error getting IRemotelyProvisionedKeyPool HAL with service name '"
-                       << IRemotelyProvisionedKeyPool::descriptor << "'";
+        status = hal_->getRemotelyProvisionedComponent(&rpc_);
+        if (!status.isOk()) {
+            LOG(ERROR) << "Error getting remotely provisioned component: " << status;
             return false;
         }
+        useRkpd_ = useRkpd();
+
+        if (useRkpd_) {
+            uid_t callingUid = android::IPCThreadState::self()->getCallingUid();
+            auto rpcKeyFuture = getRpcKeyFuture(rpc_, callingUid);
+            if (!rpcKeyFuture) {
+                LOG(ERROR) << "Error in getRpcKeyFuture()";
+                return false;
+            }
+            rpcKeyFuture_ = std::move(*rpcKeyFuture);
+        } else {
+            keyPool_ = android::waitForService<IRemotelyProvisionedKeyPool>(
+                IRemotelyProvisionedKeyPool::descriptor);
+            if (!keyPool_) {
+                LOG(ERROR) << "Error getting IRemotelyProvisionedKeyPool HAL with service name '"
+                           << IRemotelyProvisionedKeyPool::descriptor << "'";
+                return false;
+            }
+        }
     }
 
     LOG(INFO) << "Connected to Identity Credential HAL with API version " << halApiVersion_
@@ -209,28 +201,54 @@
 
 Status CredentialStore::setRemotelyProvisionedAttestationKey(
     IWritableIdentityCredential* halWritableCredential) {
-    std::optional<std::string> rpcId = getRemotelyProvisionedComponentId(hal_);
-    if (!rpcId) {
-        return Status::fromServiceSpecificError(ERROR_GENERIC,
-                                                "Error getting remotely provisioned component id");
+    std::vector<uint8_t> keyBlob;
+    std::vector<uint8_t> encodedCertChain;
+    Status status;
+
+    if (useRkpd_) {
+        if (rpcKeyFuture_.wait_for(std::chrono::seconds(10)) != std::future_status::ready) {
+            return Status::fromServiceSpecificError(
+                ERROR_GENERIC, "Waiting for remotely provisioned attestation key timed out");
+        }
+
+        std::optional<::android::security::rkp::RemotelyProvisionedKey> key = rpcKeyFuture_.get();
+        if (!key) {
+            return Status::fromServiceSpecificError(
+                ERROR_GENERIC, "Failed to get remotely provisioned attestation key");
+        }
+
+        if (key->keyBlob.empty()) {
+            return Status::fromServiceSpecificError(
+                ERROR_GENERIC, "Remotely provisioned attestation key blob is empty");
+        }
+
+        keyBlob = std::move(key->keyBlob);
+        encodedCertChain = std::move(key->encodedCertChain);
+    } else {
+        std::optional<std::string> rpcId = getRpcId(rpc_);
+        if (!rpcId) {
+            return Status::fromServiceSpecificError(
+                ERROR_GENERIC, "Error getting remotely provisioned component id");
+        }
+
+        uid_t callingUid = android::IPCThreadState::self()->getCallingUid();
+        ::android::security::remoteprovisioning::RemotelyProvisionedKey key;
+        Status status = keyPool_->getAttestationKey(callingUid, *rpcId, &key);
+        if (!status.isOk()) {
+            LOG(WARNING) << "Unable to fetch remotely provisioned attestation key, falling back "
+                         << "to the factory-provisioned attestation key.";
+            return Status::ok();
+        }
+
+        keyBlob = std::move(key.keyBlob);
+        encodedCertChain = std::move(key.encodedCertChain);
     }
 
-    uid_t callingUid = android::IPCThreadState::self()->getCallingUid();
-    RemotelyProvisionedKey key;
-    Status status = keyPool_->getAttestationKey(callingUid, *rpcId, &key);
-    if (!status.isOk()) {
-        LOG(WARNING) << "Unable to fetch remotely provisioned attestation key, falling back "
-                     << "to the factory-provisioned attestation key.";
-        return Status::ok();
-    }
-
-    status = halWritableCredential->setRemotelyProvisionedAttestationKey(key.keyBlob,
-                                                                         key.encodedCertChain);
+    status = halWritableCredential->setRemotelyProvisionedAttestationKey(keyBlob, encodedCertChain);
     if (!status.isOk()) {
         LOG(ERROR) << "Error setting remotely provisioned attestation key on credential";
         return status;
     }
-
     return Status::ok();
 }