Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0611028b authored by Seth Moore's avatar Seth Moore Committed by Automerger Merge Worker
Browse files

Add a utility to JSON-format a CSR with build info am: 23f62459

Original change: https://googleplex-android-review.googlesource.com/c/platform/hardware/interfaces/+/15115450

Change-Id: I591dc34a4850ca8f40aa13026af1c62e421619ba
parents dfcbb902 23f62459
Loading
Loading
Loading
Loading
+20 −34
Original line number Diff line number Diff line
@@ -23,16 +23,11 @@ package {
    default_applicable_licenses: ["hardware_interfaces_license"],
}

cc_test {
    name: "VtsAidlKeyMintTargetTest",
cc_defaults {
    name: "keymint_vts_defaults",
    defaults: [
        "VtsHalTargetTestDefaults",
        "use_libaidlvintf_gtest_helper_static",
    ],
    srcs: [
        "AttestKeyTest.cpp",
        "DeviceUniqueAttestationTest.cpp",
        "KeyMintTest.cpp",
        "VtsHalTargetTestDefaults",
    ],
    shared_libs: [
        "libbinder_ndk",
@@ -43,9 +38,24 @@ cc_test {
        "android.hardware.security.secureclock-V1-ndk_platform",
        "libcppbor_external",
        "libcppcose_rkp",
        "libjsoncpp",
        "libkeymint",
        "libkeymint_remote_prov_support",
        "libkeymint_support",
    ],
}

cc_test {
    name: "VtsAidlKeyMintTargetTest",
    defaults: [
        "keymint_vts_defaults",
    ],
    srcs: [
        "AttestKeyTest.cpp",
        "DeviceUniqueAttestationTest.cpp",
        "KeyMintTest.cpp",
    ],
    static_libs: [
        "libkeymint_vts_test_utils",
    ],
    test_suites: [
@@ -57,8 +67,7 @@ cc_test {
cc_test_library {
    name: "libkeymint_vts_test_utils",
    defaults: [
        "VtsHalTargetTestDefaults",
        "use_libaidlvintf_gtest_helper_static",
        "keymint_vts_defaults",
    ],
    srcs: [
        "KeyMintAidlTestBase.cpp",
@@ -66,45 +75,22 @@ cc_test_library {
    export_include_dirs: [
        ".",
    ],
    shared_libs: [
        "libbinder_ndk",
        "libcrypto",
    ],
    static_libs: [
        "android.hardware.security.keymint-V1-ndk_platform",
        "android.hardware.security.secureclock-V1-ndk_platform",
        "libcppbor_external",
        "libcppcose_rkp",
        "libgmock_ndk",
        "libkeymint",
        "libkeymint_remote_prov_support",
        "libkeymint_support",
    ],
}

cc_test {
    name: "VtsHalRemotelyProvisionedComponentTargetTest",
    defaults: [
        "VtsHalTargetTestDefaults",
        "use_libaidlvintf_gtest_helper_static",
        "keymint_vts_defaults",
    ],
    srcs: [
        "VtsRemotelyProvisionedComponentTests.cpp",
    ],
    shared_libs: [
        "libbinder_ndk",
        "libcrypto",
    ],
    static_libs: [
        "android.hardware.security.keymint-V1-ndk_platform",
        "android.hardware.security.secureclock-V1-ndk_platform",
        "libcppbor_external",
        "libcppcose_rkp",
        "libgmock_ndk",
        "libkeymaster_portable",
        "libkeymint",
        "libkeymint_support",
        "libkeymint_remote_prov_support",
        "libkeymint_vts_test_utils",
        "libpuresoftkeymasterdevice",
    ],
+4 −0
Original line number Diff line number Diff line
@@ -57,9 +57,11 @@ cc_library {
        "include",
    ],
    shared_libs: [
        "libbase",
        "libcppbor_external",
        "libcppcose_rkp",
        "libcrypto",
        "libjsoncpp",
    ],
}

@@ -71,9 +73,11 @@ cc_test {
        "libgtest_main",
    ],
    shared_libs: [
        "libbase",
        "libcppbor_external",
        "libcppcose_rkp",
        "libcrypto",
        "libjsoncpp",
        "libkeymaster_portable",
        "libkeymint_remote_prov_support",
    ],
+22 −0
Original line number Diff line number Diff line
@@ -87,4 +87,26 @@ struct BccEntryData {
 */
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
+38 −4
Original line number Diff line number Diff line
@@ -14,13 +14,15 @@
 * limitations under the License.
 */

#include <iterator>
#include <tuple>

#include <remote_prov/remote_prov_utils.h>

#include <openssl/rand.h>

#include <android-base/properties.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 {

@@ -180,4 +182,36 @@ ErrMsgOr<std::vector<BccEntryData>> validateBcc(const cppbor::Array* bcc) {
    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
+17 −0
Original line number Diff line number Diff line
@@ -14,6 +14,7 @@
 * limitations under the License.
 */

#include <android-base/properties.h>
#include <cppbor_parse.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
@@ -23,6 +24,7 @@
#include <openssl/curve25519.h>
#include <remote_prov/remote_prov_utils.h>
#include <cstdint>
#include "cppbor.h"
#include "keymaster/cppcose/cppcose.h"

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)));
}

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 aidl::android::hardware::security::keymint::remote_prov