mirror of
https://github.com/Evolution-X/hardware_interfaces
synced 2026-02-02 10:05:19 +00:00
Add a utility to JSON-format a CSR with build info
We need both the build fingerprint as well as the CSR when uploading data to the APFE provisioning server. Add a utility function to format the output as a JSON blob so that it may be easily collected in the factory in a serialized data format, then later uploaded. Test: libkeymint_remote_prov_support_test Test: VtsAidlKeyMintTargetTest Test: VtsHalRemotelyProvisionedComponentTargetTest Bug: 191301285 Change-Id: I751c5461876d83251869539f1a395ba13cb5cf84
This commit is contained in:
@@ -23,16 +23,11 @@ package {
|
|||||||
default_applicable_licenses: ["hardware_interfaces_license"],
|
default_applicable_licenses: ["hardware_interfaces_license"],
|
||||||
}
|
}
|
||||||
|
|
||||||
cc_test {
|
cc_defaults {
|
||||||
name: "VtsAidlKeyMintTargetTest",
|
name: "keymint_vts_defaults",
|
||||||
defaults: [
|
defaults: [
|
||||||
"VtsHalTargetTestDefaults",
|
|
||||||
"use_libaidlvintf_gtest_helper_static",
|
"use_libaidlvintf_gtest_helper_static",
|
||||||
],
|
"VtsHalTargetTestDefaults",
|
||||||
srcs: [
|
|
||||||
"AttestKeyTest.cpp",
|
|
||||||
"DeviceUniqueAttestationTest.cpp",
|
|
||||||
"KeyMintTest.cpp",
|
|
||||||
],
|
],
|
||||||
shared_libs: [
|
shared_libs: [
|
||||||
"libbinder_ndk",
|
"libbinder_ndk",
|
||||||
@@ -43,9 +38,24 @@ cc_test {
|
|||||||
"android.hardware.security.secureclock-V1-ndk_platform",
|
"android.hardware.security.secureclock-V1-ndk_platform",
|
||||||
"libcppbor_external",
|
"libcppbor_external",
|
||||||
"libcppcose_rkp",
|
"libcppcose_rkp",
|
||||||
|
"libjsoncpp",
|
||||||
"libkeymint",
|
"libkeymint",
|
||||||
"libkeymint_remote_prov_support",
|
"libkeymint_remote_prov_support",
|
||||||
"libkeymint_support",
|
"libkeymint_support",
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
cc_test {
|
||||||
|
name: "VtsAidlKeyMintTargetTest",
|
||||||
|
defaults: [
|
||||||
|
"keymint_vts_defaults",
|
||||||
|
],
|
||||||
|
srcs: [
|
||||||
|
"AttestKeyTest.cpp",
|
||||||
|
"DeviceUniqueAttestationTest.cpp",
|
||||||
|
"KeyMintTest.cpp",
|
||||||
|
],
|
||||||
|
static_libs: [
|
||||||
"libkeymint_vts_test_utils",
|
"libkeymint_vts_test_utils",
|
||||||
],
|
],
|
||||||
test_suites: [
|
test_suites: [
|
||||||
@@ -57,8 +67,7 @@ cc_test {
|
|||||||
cc_test_library {
|
cc_test_library {
|
||||||
name: "libkeymint_vts_test_utils",
|
name: "libkeymint_vts_test_utils",
|
||||||
defaults: [
|
defaults: [
|
||||||
"VtsHalTargetTestDefaults",
|
"keymint_vts_defaults",
|
||||||
"use_libaidlvintf_gtest_helper_static",
|
|
||||||
],
|
],
|
||||||
srcs: [
|
srcs: [
|
||||||
"KeyMintAidlTestBase.cpp",
|
"KeyMintAidlTestBase.cpp",
|
||||||
@@ -66,45 +75,22 @@ cc_test_library {
|
|||||||
export_include_dirs: [
|
export_include_dirs: [
|
||||||
".",
|
".",
|
||||||
],
|
],
|
||||||
shared_libs: [
|
|
||||||
"libbinder_ndk",
|
|
||||||
"libcrypto",
|
|
||||||
],
|
|
||||||
static_libs: [
|
static_libs: [
|
||||||
"android.hardware.security.keymint-V1-ndk_platform",
|
|
||||||
"android.hardware.security.secureclock-V1-ndk_platform",
|
|
||||||
"libcppbor_external",
|
|
||||||
"libcppcose_rkp",
|
|
||||||
"libgmock_ndk",
|
"libgmock_ndk",
|
||||||
"libkeymint",
|
|
||||||
"libkeymint_remote_prov_support",
|
|
||||||
"libkeymint_support",
|
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|
||||||
cc_test {
|
cc_test {
|
||||||
name: "VtsHalRemotelyProvisionedComponentTargetTest",
|
name: "VtsHalRemotelyProvisionedComponentTargetTest",
|
||||||
defaults: [
|
defaults: [
|
||||||
"VtsHalTargetTestDefaults",
|
"keymint_vts_defaults",
|
||||||
"use_libaidlvintf_gtest_helper_static",
|
|
||||||
],
|
],
|
||||||
srcs: [
|
srcs: [
|
||||||
"VtsRemotelyProvisionedComponentTests.cpp",
|
"VtsRemotelyProvisionedComponentTests.cpp",
|
||||||
],
|
],
|
||||||
shared_libs: [
|
|
||||||
"libbinder_ndk",
|
|
||||||
"libcrypto",
|
|
||||||
],
|
|
||||||
static_libs: [
|
static_libs: [
|
||||||
"android.hardware.security.keymint-V1-ndk_platform",
|
|
||||||
"android.hardware.security.secureclock-V1-ndk_platform",
|
|
||||||
"libcppbor_external",
|
|
||||||
"libcppcose_rkp",
|
|
||||||
"libgmock_ndk",
|
"libgmock_ndk",
|
||||||
"libkeymaster_portable",
|
"libkeymaster_portable",
|
||||||
"libkeymint",
|
|
||||||
"libkeymint_support",
|
|
||||||
"libkeymint_remote_prov_support",
|
|
||||||
"libkeymint_vts_test_utils",
|
"libkeymint_vts_test_utils",
|
||||||
"libpuresoftkeymasterdevice",
|
"libpuresoftkeymasterdevice",
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -57,9 +57,11 @@ cc_library {
|
|||||||
"include",
|
"include",
|
||||||
],
|
],
|
||||||
shared_libs: [
|
shared_libs: [
|
||||||
|
"libbase",
|
||||||
"libcppbor_external",
|
"libcppbor_external",
|
||||||
"libcppcose_rkp",
|
"libcppcose_rkp",
|
||||||
"libcrypto",
|
"libcrypto",
|
||||||
|
"libjsoncpp",
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -71,9 +73,11 @@ cc_test {
|
|||||||
"libgtest_main",
|
"libgtest_main",
|
||||||
],
|
],
|
||||||
shared_libs: [
|
shared_libs: [
|
||||||
|
"libbase",
|
||||||
"libcppbor_external",
|
"libcppbor_external",
|
||||||
"libcppcose_rkp",
|
"libcppcose_rkp",
|
||||||
"libcrypto",
|
"libcrypto",
|
||||||
|
"libjsoncpp",
|
||||||
"libkeymaster_portable",
|
"libkeymaster_portable",
|
||||||
"libkeymint_remote_prov_support",
|
"libkeymint_remote_prov_support",
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -87,4 +87,26 @@ struct BccEntryData {
|
|||||||
*/
|
*/
|
||||||
ErrMsgOr<std::vector<BccEntryData>> validateBcc(const cppbor::Array* bcc);
|
ErrMsgOr<std::vector<BccEntryData>> validateBcc(const cppbor::Array* bcc);
|
||||||
|
|
||||||
|
struct JsonOutput {
|
||||||
|
static JsonOutput Ok(std::string json) { return {std::move(json), ""}; }
|
||||||
|
static JsonOutput Error(std::string error) { return {"", std::move(error)}; }
|
||||||
|
|
||||||
|
std::string output;
|
||||||
|
std::string error; // if non-empty, this describes what went wrong
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Take a given certificate request and output a JSON blob containing both the
|
||||||
|
* build fingerprint and certificate request. This data may be serialized, then
|
||||||
|
* later uploaded to the remote provisioning service. The input csr is not
|
||||||
|
* validated, only encoded.
|
||||||
|
*
|
||||||
|
* Output format:
|
||||||
|
* {
|
||||||
|
* "build_fingerprint": <string>
|
||||||
|
* "csr": <base64 CBOR CSR>
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
JsonOutput jsonEncodeCsrWithBuild(const cppbor::Array& csr);
|
||||||
|
|
||||||
} // namespace aidl::android::hardware::security::keymint::remote_prov
|
} // namespace aidl::android::hardware::security::keymint::remote_prov
|
||||||
|
|||||||
@@ -14,13 +14,15 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <iterator>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
|
|
||||||
#include <remote_prov/remote_prov_utils.h>
|
#include <android-base/properties.h>
|
||||||
|
|
||||||
#include <openssl/rand.h>
|
|
||||||
|
|
||||||
#include <cppbor.h>
|
#include <cppbor.h>
|
||||||
|
#include <json/json.h>
|
||||||
|
#include <openssl/base64.h>
|
||||||
|
#include <openssl/rand.h>
|
||||||
|
#include <remote_prov/remote_prov_utils.h>
|
||||||
|
|
||||||
namespace aidl::android::hardware::security::keymint::remote_prov {
|
namespace aidl::android::hardware::security::keymint::remote_prov {
|
||||||
|
|
||||||
@@ -180,4 +182,36 @@ ErrMsgOr<std::vector<BccEntryData>> validateBcc(const cppbor::Array* bcc) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
JsonOutput jsonEncodeCsrWithBuild(const cppbor::Array& csr) {
|
||||||
|
const std::string kFingerprintProp = "ro.build.fingerprint";
|
||||||
|
|
||||||
|
if (!::android::base::WaitForPropertyCreation(kFingerprintProp)) {
|
||||||
|
return JsonOutput::Error("Unable to read build fingerprint");
|
||||||
|
}
|
||||||
|
|
||||||
|
bytevec csrCbor = csr.encode();
|
||||||
|
size_t base64Length;
|
||||||
|
int rc = EVP_EncodedLength(&base64Length, csrCbor.size());
|
||||||
|
if (!rc) {
|
||||||
|
return JsonOutput::Error("Error getting base64 length. Size overflow?");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<char> base64(base64Length);
|
||||||
|
rc = EVP_EncodeBlock(reinterpret_cast<uint8_t*>(base64.data()), csrCbor.data(), csrCbor.size());
|
||||||
|
++rc; // Account for NUL, which BoringSSL does not for some reason.
|
||||||
|
if (rc != base64Length) {
|
||||||
|
return JsonOutput::Error("Error writing base64. Expected " + std::to_string(base64Length) +
|
||||||
|
" bytes to be written, but " + std::to_string(rc) +
|
||||||
|
" bytes were actually written.");
|
||||||
|
}
|
||||||
|
|
||||||
|
Json::Value json(Json::objectValue);
|
||||||
|
json["build_fingerprint"] = ::android::base::GetProperty(kFingerprintProp, /*default=*/"");
|
||||||
|
json["csr"] = base64.data(); // Boring writes a NUL-terminated c-string
|
||||||
|
|
||||||
|
Json::StreamWriterBuilder factory;
|
||||||
|
factory["indentation"] = ""; // disable pretty formatting
|
||||||
|
return JsonOutput::Ok(Json::writeString(factory, json));
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace aidl::android::hardware::security::keymint::remote_prov
|
} // namespace aidl::android::hardware::security::keymint::remote_prov
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <android-base/properties.h>
|
||||||
#include <cppbor_parse.h>
|
#include <cppbor_parse.h>
|
||||||
#include <gmock/gmock.h>
|
#include <gmock/gmock.h>
|
||||||
#include <gtest/gtest.h>
|
#include <gtest/gtest.h>
|
||||||
@@ -23,6 +24,7 @@
|
|||||||
#include <openssl/curve25519.h>
|
#include <openssl/curve25519.h>
|
||||||
#include <remote_prov/remote_prov_utils.h>
|
#include <remote_prov/remote_prov_utils.h>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
#include "cppbor.h"
|
||||||
#include "keymaster/cppcose/cppcose.h"
|
#include "keymaster/cppcose/cppcose.h"
|
||||||
|
|
||||||
namespace aidl::android::hardware::security::keymint::remote_prov {
|
namespace aidl::android::hardware::security::keymint::remote_prov {
|
||||||
@@ -80,5 +82,20 @@ TEST(RemoteProvUtilsTest, GetProdEekChain) {
|
|||||||
EXPECT_THAT(eekPub, ElementsAreArray(geek->getBstrValue(CoseKey::PUBKEY_X).value_or(empty)));
|
EXPECT_THAT(eekPub, ElementsAreArray(geek->getBstrValue(CoseKey::PUBKEY_X).value_or(empty)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(RemoteProvUtilsTest, JsonEncodeCsr) {
|
||||||
|
cppbor::Array array;
|
||||||
|
array.add(1);
|
||||||
|
|
||||||
|
auto [json, error] = jsonEncodeCsrWithBuild(array);
|
||||||
|
|
||||||
|
ASSERT_TRUE(error.empty()) << error;
|
||||||
|
|
||||||
|
std::string expected = R"({"build_fingerprint":")" +
|
||||||
|
::android::base::GetProperty("ro.build.fingerprint", /*default=*/"") +
|
||||||
|
R"(","csr":"gQE="})";
|
||||||
|
|
||||||
|
ASSERT_EQ(json, expected);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
} // namespace aidl::android::hardware::security::keymint::remote_prov
|
} // namespace aidl::android::hardware::security::keymint::remote_prov
|
||||||
|
|||||||
Reference in New Issue
Block a user