Merge changes I0049d5ba,I28ebc5a2

* changes:
  identity: Replace RemotelyProvisionedKey with librkp_support
  Add helper library to get remotely provisioned key
diff --git a/identity/Android.bp b/identity/Android.bp
index ecf667d..f4fcc0a 100644
--- a/identity/Android.bp
+++ b/identity/Android.bp
@@ -36,7 +36,6 @@
         "CredentialData.cpp",
         "CredentialStore.cpp",
         "CredentialStoreFactory.cpp",
-        "RemotelyProvisionedKey.cpp",
         "Session.cpp",
         "Util.cpp",
         "WritableCredential.cpp",
@@ -55,6 +54,7 @@
         "libhidlbase",
         "libkeymaster4support",
         "libkeystore-attestation-application-id",
+        "librkp_support",
         "libutils",
         "libutilscallstack",
         "libvintf",
diff --git a/identity/CredentialStore.cpp b/identity/CredentialStore.cpp
index e200cb5..cb2e8c7 100644
--- a/identity/CredentialStore.cpp
+++ b/identity/CredentialStore.cpp
@@ -24,12 +24,12 @@
 #include <android/hardware/security/keymint/RpcHardwareInfo.h>
 #include <binder/IPCThreadState.h>
 #include <binder/IServiceManager.h>
+#include <rkp/support/rkpd_client.h>
 #include <vintf/VintfObject.h>
 
 #include "Credential.h"
 #include "CredentialData.h"
 #include "CredentialStore.h"
-#include "RemotelyProvisionedKey.h"
 #include "Session.h"
 #include "Util.h"
 #include "WritableCredential.h"
@@ -39,7 +39,8 @@
 namespace identity {
 namespace {
 
-using ::android::security::rkp::IRemoteProvisioning;
+using ::android::security::rkp::RemotelyProvisionedKey;
+using ::android::security::rkp::support::getRpcKey;
 
 }  // namespace
 
@@ -183,17 +184,7 @@
     LOG(INFO) << "Fetching attestation key from RKPD";
 
     uid_t callingUid = android::IPCThreadState::self()->getCallingUid();
-    auto rpcKeyFuture = getRpcKeyFuture(rpc_, callingUid);
-    if (!rpcKeyFuture) {
-        return Status::fromServiceSpecificError(ERROR_GENERIC, "Error in getRpcKeyFuture()");
-    }
-
-    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();
+    std::optional<RemotelyProvisionedKey> key = getRpcKey(rpc_, callingUid);
     if (!key) {
         return Status::fromServiceSpecificError(
             ERROR_GENERIC, "Failed to get remotely provisioned attestation key");
diff --git a/identity/CredentialStore.h b/identity/CredentialStore.h
index 32c9975..8bc02e8 100644
--- a/identity/CredentialStore.h
+++ b/identity/CredentialStore.h
@@ -22,7 +22,6 @@
 
 #include <android/hardware/identity/IIdentityCredentialStore.h>
 #include <android/security/identity/BnCredentialStore.h>
-#include <android/security/rkp/IRemoteProvisioning.h>
 
 namespace android {
 namespace security {
diff --git a/provisioner/support/Android.bp b/provisioner/support/Android.bp
new file mode 100644
index 0000000..778b1e0
--- /dev/null
+++ b/provisioner/support/Android.bp
@@ -0,0 +1,64 @@
+// Copyright (C) 2023 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "hardware_interfaces_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["system_security_license"],
+}
+
+cc_defaults {
+    name: "librkp_support_defaults",
+    static_libs: [
+        "android.hardware.security.rkp-V3-cpp",
+        "android.security.rkp_aidl-cpp",
+    ],
+    shared_libs: [
+        "libbase",
+        "libbinder",
+        "libutils",
+        "libvintf",
+    ],
+    cflags: [
+        "-Wall",
+        "-Wextra",
+        "-Werror",
+    ],
+}
+
+cc_library {
+    name: "librkp_support",
+    defaults: ["librkp_support_defaults"],
+    srcs: [
+        "rkpd_client.cpp",
+    ],
+    export_include_dirs: ["include"],
+}
+
+cc_test {
+    name: "librkp_support_test",
+    defaults: [
+        "librkp_support_defaults",
+        "use_libaidlvintf_gtest_helper_static",
+    ],
+    srcs: ["test.cpp"],
+    static_libs: [
+        "librkp_support",
+    ],
+    test_suites: ["general-tests"],
+    require_root: true,
+}
diff --git a/provisioner/support/TEST_MAPPING b/provisioner/support/TEST_MAPPING
new file mode 100644
index 0000000..fc30104
--- /dev/null
+++ b/provisioner/support/TEST_MAPPING
@@ -0,0 +1,7 @@
+{
+  "presubmit": [
+    {
+      "name": "librkp_support_test"
+    }
+  ]
+}
diff --git a/identity/RemotelyProvisionedKey.h b/provisioner/support/include/rkp/support/rkpd_client.h
similarity index 66%
rename from identity/RemotelyProvisionedKey.h
rename to provisioner/support/include/rkp/support/rkpd_client.h
index e7ddfca..5a7fe6e 100644
--- a/identity/RemotelyProvisionedKey.h
+++ b/provisioner/support/include/rkp/support/rkpd_client.h
@@ -20,19 +20,20 @@
 #include <optional>
 
 #include <android/hardware/security/keymint/IRemotelyProvisionedComponent.h>
+#include <android/security/rkp/RemotelyProvisionedKey.h>
 
-namespace android {
-namespace security {
-namespace identity {
+namespace android::security::rkp::support {
 
 using ::android::hardware::security::keymint::IRemotelyProvisionedComponent;
 using ::android::security::rkp::RemotelyProvisionedKey;
 
-std::optional<std::string> getRpcId(const sp<IRemotelyProvisionedComponent>& rpc);
-
+// Callers of getRpcKeyFuture() and getRpcKey() need at least two threads to
+// retrieve the key, one to asynchronously handle binder callbacks and one to
+// wait on the future.
 std::optional<std::future<std::optional<RemotelyProvisionedKey>>>
 getRpcKeyFuture(const sp<IRemotelyProvisionedComponent>& rpc, int32_t keyId);
 
-}  // namespace identity
-}  // namespace security
-}  // namespace android
+std::optional<RemotelyProvisionedKey> getRpcKey(const sp<IRemotelyProvisionedComponent>& rpc,
+                                                int32_t keyId, int32_t timeout_sec = 10);
+
+}  // namespace android::security::rkp::support
diff --git a/identity/RemotelyProvisionedKey.cpp b/provisioner/support/rkpd_client.cpp
similarity index 88%
rename from identity/RemotelyProvisionedKey.cpp
rename to provisioner/support/rkpd_client.cpp
index 784a680..0643457 100644
--- a/identity/RemotelyProvisionedKey.cpp
+++ b/provisioner/support/rkpd_client.cpp
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#define LOG_TAG "credstore"
+#define LOG_TAG "rkpd_client"
 
 #include <atomic>
 
@@ -25,13 +25,10 @@
 #include <android/security/rkp/IRemoteProvisioning.h>
 #include <binder/IServiceManager.h>
 #include <binder/Status.h>
+#include <rkp/support/rkpd_client.h>
 #include <vintf/VintfObject.h>
 
-#include "RemotelyProvisionedKey.h"
-
-namespace android {
-namespace security {
-namespace identity {
+namespace android::security::rkp::support {
 namespace {
 
 using ::android::binder::Status;
@@ -46,6 +43,23 @@
 
 constexpr const char* kRemoteProvisioningServiceName = "remote_provisioning";
 
+std::optional<std::string> getRpcId(const sp<IRemotelyProvisionedComponent>& rpc) {
+    RpcHardwareInfo rpcHwInfo;
+    Status status = rpc->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. "
+                   << "This is a bug in the vendor implementation.";
+        return std::nullopt;
+    }
+
+    return *rpcHwInfo.uniqueId;
+}
+
 std::optional<String16> findRpcNameById(std::string_view targetRpcId) {
     auto deviceManifest = vintf::VintfObject::GetDeviceHalManifest();
     auto instances = deviceManifest->getAidlInstances("android.hardware.security.keymint",
@@ -157,24 +171,6 @@
 
 }  // namespace
 
-std::optional<std::string> getRpcId(const sp<IRemotelyProvisionedComponent>& rpc) {
-    RpcHardwareInfo rpcHwInfo;
-    Status status = rpc->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;
-    }
-
-    return *rpcHwInfo.uniqueId;
-}
-
 std::optional<std::future<std::optional<RemotelyProvisionedKey>>>
 getRpcKeyFuture(const sp<IRemotelyProvisionedComponent>& rpc, int32_t keyId) {
     std::promise<std::optional<RemotelyProvisionedKey>> keyPromise;
@@ -203,6 +199,21 @@
     return keyFuture;
 }
 
-}  // namespace identity
-}  // namespace security
-}  // namespace android
+std::optional<RemotelyProvisionedKey> getRpcKey(const sp<IRemotelyProvisionedComponent>& rpc,
+                                                int32_t keyId, int32_t timeout_sec) {
+    auto rpcKeyFuture = getRpcKeyFuture(rpc, keyId);
+    if (!rpcKeyFuture) {
+        LOG(ERROR) << "Failed getRpcKeyFuture()";
+        return std::nullopt;
+    }
+
+    auto timeout = std::chrono::seconds(timeout_sec);
+    if (rpcKeyFuture->wait_for(timeout) != std::future_status::ready) {
+        LOG(ERROR) << "Waiting for remotely provisioned attestation key timed out";
+        return std::nullopt;
+    }
+
+    return rpcKeyFuture->get();
+}
+
+}  // namespace android::security::rkp::support
diff --git a/provisioner/support/test.cpp b/provisioner/support/test.cpp
new file mode 100644
index 0000000..418eab9
--- /dev/null
+++ b/provisioner/support/test.cpp
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <aidl/Gtest.h>
+#include <aidl/Vintf.h>
+#include <android/hardware/security/keymint/IRemotelyProvisionedComponent.h>
+#include <binder/IServiceManager.h>
+#include <binder/ProcessState.h>
+#include <gtest/gtest.h>
+#include <rkp/support/rkpd_client.h>
+
+using ::android::getAidlHalInstanceNames;
+using ::android::sp;
+using ::android::String16;
+using ::android::hardware::security::keymint::IRemotelyProvisionedComponent;
+using ::android::security::rkp::RemotelyProvisionedKey;
+using ::android::security::rkp::support::getRpcKey;
+
+// TODO(b/272600606): Add tests for error cases
+class RkpdClientTest : public testing::TestWithParam<std::string> {
+  public:
+    virtual void SetUp() override {
+        auto rpcName = String16(GetParam().c_str());
+        rpc_ = android::waitForService<IRemotelyProvisionedComponent>(rpcName);
+        ASSERT_NE(rpc_, nullptr);
+    }
+
+    sp<IRemotelyProvisionedComponent> rpc_;
+};
+
+TEST_P(RkpdClientTest, getRpcKey) {
+    std::optional<RemotelyProvisionedKey> key = getRpcKey(rpc_, /*keyId=*/0);
+
+    ASSERT_TRUE(key.has_value()) << "Failed to get remotely provisioned attestation key";
+    ASSERT_FALSE(key->keyBlob.empty()) << "Key blob is empty";
+    ASSERT_FALSE(key->encodedCertChain.empty()) << "Certificate is empty";
+}
+
+INSTANTIATE_TEST_SUITE_P(
+    PerInstance, RkpdClientTest,
+    testing::ValuesIn(getAidlHalInstanceNames(IRemotelyProvisionedComponent::descriptor)),
+    ::android::PrintInstanceNameToString);
+
+int main(int argc, char** argv) {
+    testing::InitGoogleTest(&argc, argv);
+
+    // We need one thread to issue requests to RKPD and one to handle
+    // asynchronous responses from RKPD.
+    android::ProcessState::self()->setThreadPoolMaxThreadCount(2);
+    android::ProcessState::self()->startThreadPool();
+    return RUN_ALL_TESTS();
+}