Internal factory tool implements CSR v3 am: 5e24549b1a
Original change: https://googleplex-android-review.googlesource.com/c/platform/vendor/widevine/+/21725452 Change-Id: Ifafbbd0708a6c37bb73275cf0a19ed3c9b30e65e Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
@@ -6,45 +6,50 @@
|
||||
|
||||
#define LOG_TAG "wv_factory_extraction_tool"
|
||||
|
||||
#include <sys/random.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstdio>
|
||||
#include <cstdint>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
#include <iterator>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include <sys/random.h>
|
||||
|
||||
#include "WidevineProvisioner.h"
|
||||
|
||||
constexpr size_t kChallengeSize = 16;
|
||||
constexpr size_t kChallengeSize = 32;
|
||||
|
||||
// The Google root key for the Endpoint Encryption Key chain, encoded as COSE_Sign1
|
||||
// The Google root key for the Endpoint Encryption Key chain, encoded as
|
||||
// COSE_Sign1
|
||||
inline constexpr uint8_t kCoseEncodedRootCert[] = {
|
||||
0x84, 0x43, 0xa1, 0x01, 0x27, 0xa0, 0x58, 0x2a, 0xa4, 0x01, 0x01, 0x03, 0x27, 0x20, 0x06,
|
||||
0x21, 0x58, 0x20, 0x99, 0xb9, 0xee, 0xdd, 0x5e, 0xe4, 0x52, 0xf6, 0x85, 0xc6, 0x4c, 0x62,
|
||||
0xdc, 0x3e, 0x61, 0xab, 0x57, 0x48, 0x7d, 0x75, 0x37, 0x29, 0xad, 0x76, 0x80, 0x32, 0xd2,
|
||||
0xb3, 0xcb, 0x63, 0x58, 0xd9, 0x58, 0x40, 0x1e, 0x22, 0x08, 0x4b, 0xa4, 0xb7, 0xa4, 0xc8,
|
||||
0xd7, 0x4e, 0x03, 0x0e, 0xfe, 0xb8, 0xaf, 0x14, 0x4c, 0xa7, 0x3b, 0x6f, 0xa5, 0xcd, 0xdc,
|
||||
0xda, 0x79, 0xc6, 0x2b, 0x64, 0xfe, 0x99, 0x39, 0xaf, 0x76, 0xe7, 0x80, 0xfa, 0x66, 0x00,
|
||||
0x85, 0x0d, 0x07, 0x98, 0x2a, 0xac, 0x91, 0x5c, 0xa7, 0x25, 0x14, 0x49, 0x06, 0x34, 0x75,
|
||||
0xca, 0x8a, 0x27, 0x7a, 0xd9, 0xe3, 0x5a, 0x49, 0xeb, 0x02, 0x03};
|
||||
0x84, 0x43, 0xa1, 0x01, 0x27, 0xa0, 0x58, 0x2a, 0xa4, 0x01, 0x01, 0x03,
|
||||
0x27, 0x20, 0x06, 0x21, 0x58, 0x20, 0x99, 0xb9, 0xee, 0xdd, 0x5e, 0xe4,
|
||||
0x52, 0xf6, 0x85, 0xc6, 0x4c, 0x62, 0xdc, 0x3e, 0x61, 0xab, 0x57, 0x48,
|
||||
0x7d, 0x75, 0x37, 0x29, 0xad, 0x76, 0x80, 0x32, 0xd2, 0xb3, 0xcb, 0x63,
|
||||
0x58, 0xd9, 0x58, 0x40, 0x1e, 0x22, 0x08, 0x4b, 0xa4, 0xb7, 0xa4, 0xc8,
|
||||
0xd7, 0x4e, 0x03, 0x0e, 0xfe, 0xb8, 0xaf, 0x14, 0x4c, 0xa7, 0x3b, 0x6f,
|
||||
0xa5, 0xcd, 0xdc, 0xda, 0x79, 0xc6, 0x2b, 0x64, 0xfe, 0x99, 0x39, 0xaf,
|
||||
0x76, 0xe7, 0x80, 0xfa, 0x66, 0x00, 0x85, 0x0d, 0x07, 0x98, 0x2a, 0xac,
|
||||
0x91, 0x5c, 0xa7, 0x25, 0x14, 0x49, 0x06, 0x34, 0x75, 0xca, 0x8a, 0x27,
|
||||
0x7a, 0xd9, 0xe3, 0x5a, 0x49, 0xeb, 0x02, 0x03};
|
||||
|
||||
// The Google Endpoint Encryption Key certificate, encoded as COSE_Sign1
|
||||
inline constexpr uint8_t kCoseEncodedGeekCert[] = {
|
||||
0x84, 0x43, 0xa1, 0x01, 0x27, 0xa0, 0x58, 0x4e, 0xa5, 0x01, 0x01, 0x02, 0x58, 0x20,
|
||||
0xd0, 0xae, 0xc1, 0x15, 0xca, 0x2a, 0xcf, 0x73, 0xae, 0x6b, 0xcc, 0xcb, 0xd1, 0x96,
|
||||
0x1d, 0x65, 0xe8, 0xb1, 0xdd, 0xd7, 0x4a, 0x1a, 0x37, 0xb9, 0x43, 0x3a, 0x97, 0xd5,
|
||||
0x99, 0xdf, 0x98, 0x08, 0x03, 0x38, 0x18, 0x20, 0x04, 0x21, 0x58, 0x20, 0xbe, 0x85,
|
||||
0xe7, 0x46, 0xc4, 0xa3, 0x42, 0x5a, 0x40, 0xd9, 0x36, 0x3a, 0xa6, 0x15, 0xd0, 0x2c,
|
||||
0x58, 0x7e, 0x3d, 0xdc, 0x33, 0x02, 0x32, 0xd2, 0xfc, 0x5e, 0x1e, 0x87, 0x25, 0x5f,
|
||||
0x72, 0x60, 0x58, 0x40, 0x9b, 0xcf, 0x90, 0xe2, 0x2e, 0x4b, 0xab, 0xd1, 0x18, 0xb1,
|
||||
0x0e, 0x8e, 0x5d, 0x20, 0x27, 0x4b, 0x84, 0x58, 0xfe, 0xfc, 0x32, 0x90, 0x7e, 0x72,
|
||||
0x05, 0x83, 0xbc, 0xd7, 0x82, 0xbe, 0xfa, 0x64, 0x78, 0x2d, 0x54, 0x10, 0x4b, 0xc0,
|
||||
0x31, 0xbf, 0x6b, 0xe8, 0x1e, 0x35, 0xe2, 0xf0, 0x2d, 0xce, 0x6c, 0x2f, 0x4f, 0xf2,
|
||||
0xf5, 0x4f, 0xa5, 0xd4, 0x83, 0xad, 0x96, 0xa2, 0xf1, 0x87, 0x58, 0x04};
|
||||
0x84, 0x43, 0xa1, 0x01, 0x27, 0xa0, 0x58, 0x4e, 0xa5, 0x01, 0x01, 0x02,
|
||||
0x58, 0x20, 0xd0, 0xae, 0xc1, 0x15, 0xca, 0x2a, 0xcf, 0x73, 0xae, 0x6b,
|
||||
0xcc, 0xcb, 0xd1, 0x96, 0x1d, 0x65, 0xe8, 0xb1, 0xdd, 0xd7, 0x4a, 0x1a,
|
||||
0x37, 0xb9, 0x43, 0x3a, 0x97, 0xd5, 0x99, 0xdf, 0x98, 0x08, 0x03, 0x38,
|
||||
0x18, 0x20, 0x04, 0x21, 0x58, 0x20, 0xbe, 0x85, 0xe7, 0x46, 0xc4, 0xa3,
|
||||
0x42, 0x5a, 0x40, 0xd9, 0x36, 0x3a, 0xa6, 0x15, 0xd0, 0x2c, 0x58, 0x7e,
|
||||
0x3d, 0xdc, 0x33, 0x02, 0x32, 0xd2, 0xfc, 0x5e, 0x1e, 0x87, 0x25, 0x5f,
|
||||
0x72, 0x60, 0x58, 0x40, 0x9b, 0xcf, 0x90, 0xe2, 0x2e, 0x4b, 0xab, 0xd1,
|
||||
0x18, 0xb1, 0x0e, 0x8e, 0x5d, 0x20, 0x27, 0x4b, 0x84, 0x58, 0xfe, 0xfc,
|
||||
0x32, 0x90, 0x7e, 0x72, 0x05, 0x83, 0xbc, 0xd7, 0x82, 0xbe, 0xfa, 0x64,
|
||||
0x78, 0x2d, 0x54, 0x10, 0x4b, 0xc0, 0x31, 0xbf, 0x6b, 0xe8, 0x1e, 0x35,
|
||||
0xe2, 0xf0, 0x2d, 0xce, 0x6c, 0x2f, 0x4f, 0xf2, 0xf5, 0x4f, 0xa5, 0xd4,
|
||||
0x83, 0xad, 0x96, 0xa2, 0xf1, 0x87, 0x58, 0x04};
|
||||
|
||||
std::vector<uint8_t> generateChallenge() {
|
||||
std::vector<uint8_t> challenge(kChallengeSize);
|
||||
@@ -70,10 +75,10 @@ std::vector<uint8_t> generateChallenge() {
|
||||
|
||||
std::vector<uint8_t> getEekChain() {
|
||||
cppbor::Array chain;
|
||||
chain.add(cppbor::EncodedItem(
|
||||
std::vector<uint8_t>(std::begin(kCoseEncodedRootCert), std::end(kCoseEncodedRootCert))));
|
||||
chain.add(cppbor::EncodedItem(
|
||||
std::vector<uint8_t>(std::begin(kCoseEncodedGeekCert), std::end(kCoseEncodedGeekCert))));
|
||||
chain.add(cppbor::EncodedItem(std::vector<uint8_t>(
|
||||
std::begin(kCoseEncodedRootCert), std::end(kCoseEncodedRootCert))));
|
||||
chain.add(cppbor::EncodedItem(std::vector<uint8_t>(
|
||||
std::begin(kCoseEncodedGeekCert), std::end(kCoseEncodedGeekCert))));
|
||||
return chain.encode();
|
||||
}
|
||||
|
||||
@@ -81,20 +86,23 @@ cppbor::Array composeCertificateRequest(
|
||||
const std::vector<uint8_t>& protectedData,
|
||||
const std::vector<uint8_t>& verifiedDeviceInfo,
|
||||
const std::vector<uint8_t>& challenge) {
|
||||
cppbor::Array macedKeysToSign = cppbor::Array()
|
||||
.add(std::vector<uint8_t>(0)) // empty protected headers as bstr
|
||||
.add(cppbor::Map()) // empty unprotected headers
|
||||
.add(cppbor::Null()) // nil for the payload
|
||||
.add(std::vector<uint8_t>(0)); // MAC as returned from the HAL
|
||||
cppbor::Array macedKeysToSign =
|
||||
cppbor::Array()
|
||||
.add(std::vector<uint8_t>(0)) // empty protected headers as bstr
|
||||
.add(cppbor::Map()) // empty unprotected headers
|
||||
.add(cppbor::Null()) // nil for the payload
|
||||
.add(std::vector<uint8_t>(0)); // MAC as returned from the HAL
|
||||
|
||||
cppbor::Array deviceInfo =
|
||||
cppbor::Array().add(cppbor::EncodedItem(verifiedDeviceInfo)).add(cppbor::Map()); // Empty device info
|
||||
cppbor::Array deviceInfo = cppbor::Array()
|
||||
.add(cppbor::EncodedItem(verifiedDeviceInfo))
|
||||
.add(cppbor::Map()); // Empty device info
|
||||
|
||||
cppbor::Array certificateRequest = cppbor::Array()
|
||||
.add(std::move(deviceInfo))
|
||||
.add(challenge)
|
||||
.add(cppbor::EncodedItem(protectedData))
|
||||
.add(std::move(macedKeysToSign));
|
||||
cppbor::Array certificateRequest =
|
||||
cppbor::Array()
|
||||
.add(std::move(deviceInfo))
|
||||
.add(challenge)
|
||||
.add(cppbor::EncodedItem(protectedData))
|
||||
.add(std::move(macedKeysToSign));
|
||||
return certificateRequest;
|
||||
}
|
||||
|
||||
@@ -103,37 +111,51 @@ cppbor::Array getCsr(widevine::WidevineProvisioner& provisioner) {
|
||||
std::vector<uint8_t> verifiedDeviceInfo;
|
||||
std::vector<uint8_t> protectedData;
|
||||
|
||||
if (!provisioner.GenerateCertificateRequest(false, getEekChain(),
|
||||
verifiedDeviceInfo,
|
||||
protectedData)) {
|
||||
std::cerr << "Failed to generate certificate request." << std::endl;
|
||||
if (!provisioner.GenerateCertificateRequest(
|
||||
false, getEekChain(), verifiedDeviceInfo, protectedData)) {
|
||||
std::cerr << "Failed to generate certificate request." << std::endl;
|
||||
exit(-1);
|
||||
}
|
||||
auto csr =
|
||||
composeCertificateRequest(protectedData, verifiedDeviceInfo, challenge);
|
||||
composeCertificateRequest(protectedData, verifiedDeviceInfo, challenge);
|
||||
return csr;
|
||||
}
|
||||
|
||||
std::vector<uint8_t> getCsrV3(widevine::WidevineProvisioner& provisioner) {
|
||||
const std::vector<uint8_t> challenge = generateChallenge();
|
||||
std::vector<uint8_t> csr;
|
||||
|
||||
if (!provisioner.GenerateCertificateRequestV2(challenge, &csr)) {
|
||||
std::cerr << "Failed to generate certificate request v2." << std::endl;
|
||||
exit(-1);
|
||||
}
|
||||
return csr;
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
if (argc<2) {
|
||||
fprintf(stderr,"%s <bcc|device_info>\n",argv[0]);
|
||||
if (argc < 2) {
|
||||
fprintf(stderr, "%s <bcc|device_info>\n", argv[0]);
|
||||
return 0;
|
||||
}
|
||||
widevine::WidevineProvisioner provisioner;
|
||||
if (!std::strcmp(argv[1],"bcc")) {
|
||||
if (!std::strcmp(argv[1], "bcc")) {
|
||||
auto bcc = provisioner.GetBcc();
|
||||
fwrite(bcc.data(), 1 , bcc.size(), stdout);
|
||||
fwrite(bcc.data(), 1, bcc.size(), stdout);
|
||||
fflush(stdout);
|
||||
} else if (!std::strcmp(argv[1],"device_info")) {
|
||||
} else if (!std::strcmp(argv[1], "device_info")) {
|
||||
std::vector<uint8_t> deviceInfo;
|
||||
if (provisioner.GetDeviceInfo(deviceInfo)) {
|
||||
fwrite(deviceInfo.data(), 1 , deviceInfo.size(), stdout);
|
||||
fwrite(deviceInfo.data(), 1, deviceInfo.size(), stdout);
|
||||
fflush(stdout);
|
||||
}
|
||||
} else if (!std::strcmp(argv[1],"csr")) {
|
||||
} else if (!std::strcmp(argv[1], "csr")) {
|
||||
auto csr = getCsr(provisioner);
|
||||
auto bytes = csr.encode();
|
||||
std::copy(bytes.begin(), bytes.end(), std::ostream_iterator<char>(std::cout));
|
||||
std::copy(bytes.begin(), bytes.end(),
|
||||
std::ostream_iterator<char>(std::cout));
|
||||
} else if (!std::strcmp(argv[1], "csr_v3")) {
|
||||
auto csr = getCsrV3(provisioner);
|
||||
std::copy(csr.begin(), csr.end(), std::ostream_iterator<char>(std::cout));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -13,13 +13,6 @@
|
||||
|
||||
namespace widevine {
|
||||
|
||||
struct VerifiedDeviceInfo {
|
||||
std::vector<uint8_t> device_info;
|
||||
// Used by Interface of Remote Provisioning Component (IRPC) v3 for CSR
|
||||
// uploading
|
||||
std::vector<uint8_t> signed_csr_payload;
|
||||
};
|
||||
|
||||
class OEMCryptoInterface {
|
||||
public:
|
||||
OEMCryptoInterface() = default;
|
||||
@@ -40,7 +33,13 @@ class OEMCryptoInterface {
|
||||
// Retrieves the verified device information of the OEMCrypto library from
|
||||
// OEMCrypto implementation.
|
||||
OEMCryptoResult GetVerifiedDeviceInformation(
|
||||
VerifiedDeviceInfo& verified_device_info);
|
||||
std::vector<uint8_t>& verified_device_info);
|
||||
|
||||
// Generates device registration CSR payload and signs it with the leaf cert
|
||||
// of BCC.
|
||||
OEMCryptoResult GetSignedCsrPayload(const std::vector<uint8_t>& challenge,
|
||||
const std::vector<uint8_t>& device_info,
|
||||
std::vector<uint8_t>& signed_csr_payload);
|
||||
|
||||
private:
|
||||
typedef OEMCryptoResult (*Initialize_t)();
|
||||
@@ -50,8 +49,11 @@ class OEMCryptoInterface {
|
||||
size_t* additional_signature_size);
|
||||
typedef OEMCryptoResult (*BuildInformation_t)(char* buffer,
|
||||
size_t* buffer_length);
|
||||
typedef OEMCryptoResult (*GetDeviceInformation_t)(
|
||||
uint8_t* device_info, size_t* device_info_length,
|
||||
typedef OEMCryptoResult (*GetDeviceInformation_t)(uint8_t* device_info,
|
||||
size_t* device_info_length);
|
||||
typedef OEMCryptoResult (*GetDeviceSignedCsrPayload_t)(
|
||||
const uint8_t* challenge, size_t challenge_length,
|
||||
const uint8_t* device_info, size_t device_info_length,
|
||||
uint8_t* signed_csr_payload, size_t* signed_csr_payload_length);
|
||||
|
||||
Initialize_t Initialize = nullptr;
|
||||
@@ -59,6 +61,7 @@ class OEMCryptoInterface {
|
||||
GetBootCertificateChain_t GetBootCertificateChain = nullptr;
|
||||
BuildInformation_t BuildInformation = nullptr;
|
||||
GetDeviceInformation_t GetDeviceInformation = nullptr;
|
||||
GetDeviceSignedCsrPayload_t GetDeviceSignedCsrPayload = nullptr;
|
||||
|
||||
void* handle_ = nullptr;
|
||||
};
|
||||
|
||||
@@ -29,7 +29,8 @@ class WidevineProvisioner {
|
||||
bool GenerateCertificateRequest(
|
||||
bool testMode, const std::vector<uint8_t>& endpointEncCertChain,
|
||||
std::vector<uint8_t>& deviceInfo, std::vector<uint8_t>& protectedData);
|
||||
|
||||
bool GenerateCertificateRequestV2(const std::vector<uint8_t>& challenge,
|
||||
std::vector<uint8_t>* csr);
|
||||
bool GetDeviceInfo(std::vector<uint8_t>& device_info);
|
||||
|
||||
private:
|
||||
@@ -46,6 +47,7 @@ class WidevineProvisioner {
|
||||
void InitializeCryptoInterface();
|
||||
bool GetDeviceInfoCommon(cppbor::Map& device_info_map);
|
||||
bool TryAddVerifiedDeviceInfo(cppbor::Map& device_info_map);
|
||||
bool GetDeviceInfoV2(cppbor::Map& device_info_map);
|
||||
|
||||
std::unique_ptr<OEMCryptoInterface> crypto_interface_;
|
||||
};
|
||||
|
||||
@@ -81,6 +81,7 @@ bool OEMCryptoInterface::Init(const std::string& oemcrypto_path) {
|
||||
LOAD_SYM(GetBootCertificateChain);
|
||||
LOAD_SYM(BuildInformation);
|
||||
LOAD_SYM_IF_EXIST(GetDeviceInformation);
|
||||
LOAD_SYM_IF_EXIST(GetDeviceSignedCsrPayload);
|
||||
|
||||
OEMCryptoResult status = Initialize();
|
||||
if (status != OEMCrypto_SUCCESS) {
|
||||
@@ -145,7 +146,7 @@ OEMCryptoResult OEMCryptoInterface::GetOEMCryptoBuildInfo(
|
||||
}
|
||||
|
||||
OEMCryptoResult OEMCryptoInterface::GetVerifiedDeviceInformation(
|
||||
VerifiedDeviceInfo& verified_device_info) {
|
||||
std::vector<uint8_t>& verified_device_info) {
|
||||
if (handle_ == nullptr) {
|
||||
return OEMCrypto_ERROR_INIT_FAILED;
|
||||
}
|
||||
@@ -153,27 +154,46 @@ OEMCryptoResult OEMCryptoInterface::GetVerifiedDeviceInformation(
|
||||
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
verified_device_info.device_info.resize(0);
|
||||
size_t device_info_size = 0;
|
||||
verified_device_info.signed_csr_payload.resize(0);
|
||||
size_t signed_csr_payload_size = 0;
|
||||
|
||||
OEMCryptoResult result = GetDeviceInformation(
|
||||
verified_device_info.device_info.data(), &device_info_size,
|
||||
verified_device_info.signed_csr_payload.data(), &signed_csr_payload_size);
|
||||
verified_device_info.resize(0);
|
||||
size_t verified_device_info_size = 0;
|
||||
OEMCryptoResult result = GetDeviceInformation(verified_device_info.data(),
|
||||
&verified_device_info_size);
|
||||
LOGI("GetVerifiedDeviceInformation first attempt result %d", result);
|
||||
if (result == OEMCrypto_ERROR_SHORT_BUFFER) {
|
||||
verified_device_info.device_info.resize(device_info_size);
|
||||
verified_device_info.signed_csr_payload.resize(signed_csr_payload_size);
|
||||
result = GetDeviceInformation(
|
||||
verified_device_info.device_info.data(), &device_info_size,
|
||||
verified_device_info.signed_csr_payload.data(),
|
||||
&signed_csr_payload_size);
|
||||
verified_device_info.device_info.resize(device_info_size);
|
||||
verified_device_info.signed_csr_payload.resize(signed_csr_payload_size);
|
||||
verified_device_info.resize(verified_device_info_size);
|
||||
result = GetDeviceInformation(verified_device_info.data(),
|
||||
&verified_device_info_size);
|
||||
verified_device_info.resize(verified_device_info_size);
|
||||
LOGI("GetVerifiedDeviceInformation second attempt result %d", result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
OEMCryptoResult OEMCryptoInterface::GetSignedCsrPayload(
|
||||
const std::vector<uint8_t>& challenge,
|
||||
const std::vector<uint8_t>& device_info,
|
||||
std::vector<uint8_t>& signed_csr_payload) {
|
||||
if (handle_ == nullptr) {
|
||||
return OEMCrypto_ERROR_INIT_FAILED;
|
||||
}
|
||||
if (GetDeviceSignedCsrPayload == nullptr) {
|
||||
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
size_t signed_csr_payload_size = signed_csr_payload.size();
|
||||
OEMCryptoResult result = GetDeviceSignedCsrPayload(
|
||||
challenge.data(), challenge.size(), device_info.data(),
|
||||
device_info.size(), signed_csr_payload.data(), &signed_csr_payload_size);
|
||||
LOGI("GetDeviceSignedCsrPayload first attempt result %d", result);
|
||||
if (result == OEMCrypto_ERROR_SHORT_BUFFER) {
|
||||
signed_csr_payload.resize(signed_csr_payload_size);
|
||||
result = GetDeviceSignedCsrPayload(challenge.data(), challenge.size(),
|
||||
device_info.data(), device_info.size(),
|
||||
signed_csr_payload.data(),
|
||||
&signed_csr_payload_size);
|
||||
signed_csr_payload.resize(signed_csr_payload_size);
|
||||
LOGI("GetDeviceSignedCsrPayload second attempt result %d", result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ std::vector<uint8_t> WidevineProvisioner::GetBcc() {
|
||||
std::vector<uint8_t> bcc;
|
||||
OEMCryptoResult result = crypto_interface_->GetBcc(bcc);
|
||||
if (result != OEMCrypto_SUCCESS) {
|
||||
LOGE("Failed to get BCC.");
|
||||
LOGE("Failed to get BCC, result = %d", result);
|
||||
}
|
||||
return bcc;
|
||||
}
|
||||
@@ -58,7 +58,7 @@ bool WidevineProvisioner::GenerateCertificateRequest(
|
||||
std::vector<uint8_t> bcc;
|
||||
OEMCryptoResult result = crypto_interface_->GetBcc(bcc);
|
||||
if (result != OEMCrypto_SUCCESS) {
|
||||
LOGE("Failed to get BCC.");
|
||||
LOGE("Failed to get BCC, result = %d", result);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -73,7 +73,7 @@ bool WidevineProvisioner::GenerateCertificateRequest(
|
||||
|
||||
bool WidevineProvisioner::TryAddVerifiedDeviceInfo(
|
||||
cppbor::Map& device_info_map) {
|
||||
VerifiedDeviceInfo verified_device_info;
|
||||
std::vector<uint8_t> verified_device_info;
|
||||
OEMCryptoResult result =
|
||||
crypto_interface_->GetVerifiedDeviceInformation(verified_device_info);
|
||||
if (result == OEMCrypto_ERROR_NOT_IMPLEMENTED) {
|
||||
@@ -82,30 +82,22 @@ bool WidevineProvisioner::TryAddVerifiedDeviceInfo(
|
||||
return true;
|
||||
}
|
||||
if (result != OEMCrypto_SUCCESS) {
|
||||
LOGE("Failed to get verified device information.");
|
||||
LOGE("Failed to get verified device information, result = %d", result);
|
||||
return false;
|
||||
}
|
||||
auto [parsed, _, err] = cppbor::parse(
|
||||
reinterpret_cast<const uint8_t*>(verified_device_info.device_info.data()),
|
||||
verified_device_info.device_info.size());
|
||||
reinterpret_cast<const uint8_t*>(verified_device_info.data()),
|
||||
verified_device_info.size());
|
||||
if (!parsed || !parsed->asMap()) {
|
||||
LOGE("Failed to parse the verified device info cbor: %s", err.c_str());
|
||||
return false;
|
||||
}
|
||||
const cppbor::Map* verified_device_info_map = parsed->asMap();
|
||||
auto& make = verified_device_info_map->get("manufacturer");
|
||||
if (make && make->asTstr() && make->asTstr()->value() != "") {
|
||||
device_info_map.add("manufacturer", make->asTstr()->value());
|
||||
for (size_t i = 0; i < verified_device_info_map->size(); i++) {
|
||||
auto& [key_item, value_item] = (*verified_device_info_map)[i];
|
||||
LOGI("Found device info %s", key_item->asTstr()->value().data());
|
||||
device_info_map.add(key_item->clone(), value_item->clone());
|
||||
}
|
||||
auto& model = verified_device_info_map->get("model");
|
||||
if (model && model->asTstr() && model->asTstr()->value() != "") {
|
||||
device_info_map.add("model", model->asTstr()->value());
|
||||
}
|
||||
auto& fused = verified_device_info_map->get("fused");
|
||||
if (fused && fused->asUint()) {
|
||||
device_info_map.add("fused", fused->asUint()->value());
|
||||
}
|
||||
device_info_map.canonicalize();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -172,13 +164,11 @@ bool WidevineProvisioner::GetDeviceInfoCommon(cppbor::Map& device_info_map) {
|
||||
OEMCryptoResult result =
|
||||
crypto_interface_->GetOEMCryptoBuildInfo(oemcrypto_build_info);
|
||||
if (result != OEMCrypto_SUCCESS) {
|
||||
LOGE("Failed to get oemcrypto build info.");
|
||||
LOGE("Failed to get oemcrypto build info, result = %d", result);
|
||||
return false;
|
||||
}
|
||||
device_info_map.add(cppbor::Tstr("oemcrypto_build_info"),
|
||||
cppbor::Tstr(oemcrypto_build_info));
|
||||
|
||||
device_info_map.canonicalize();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -186,7 +176,6 @@ bool WidevineProvisioner::GetDeviceInfo(std::vector<uint8_t>& device_info) {
|
||||
auto device_info_map = cppbor::Map();
|
||||
device_info_map.add(cppbor::Tstr("type"), cppbor::Tstr("widevine"));
|
||||
device_info_map.add(cppbor::Tstr("version"), cppbor::Uint(2));
|
||||
device_info_map.canonicalize();
|
||||
if (!GetDeviceInfoCommon(device_info_map)) return false;
|
||||
device_info = device_info_map.canonicalize().encode();
|
||||
return true;
|
||||
@@ -318,6 +307,50 @@ cppbor::Array WidevineProvisioner::BuildCertReqRecipients(
|
||||
.add(cppbor::Null())); // No ciphertext
|
||||
}
|
||||
|
||||
bool WidevineProvisioner::GetDeviceInfoV2(cppbor::Map& device_info_map) {
|
||||
if (!GetDeviceInfoCommon(device_info_map)) return false;
|
||||
device_info_map.canonicalize();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WidevineProvisioner::GenerateCertificateRequestV2(
|
||||
const std::vector<uint8_t>& challenge, std::vector<uint8_t>* csr) {
|
||||
if (csr == nullptr) {
|
||||
LOGE("CSR is null.");
|
||||
return false;
|
||||
}
|
||||
// Prepare BCC
|
||||
std::vector<uint8_t> bcc;
|
||||
OEMCryptoResult result = crypto_interface_->GetBcc(bcc);
|
||||
if (result != OEMCrypto_SUCCESS) {
|
||||
LOGE("Failed to get BCC, result = %d", result);
|
||||
return false;
|
||||
}
|
||||
// Prepare device info
|
||||
auto device_info_map = cppbor::Map();
|
||||
if (!GetDeviceInfoV2(device_info_map)) {
|
||||
LOGE("Failed to get device_info.");
|
||||
return false;
|
||||
}
|
||||
// Prepare signed CSR payload
|
||||
auto device_info = device_info_map.encode();
|
||||
std::vector<uint8_t> signed_csr_payload;
|
||||
result = crypto_interface_->GetSignedCsrPayload(challenge, device_info,
|
||||
signed_csr_payload);
|
||||
if (result != OEMCrypto_SUCCESS) {
|
||||
LOGE("Failed to get the signed CSR payload, result = %d", result);
|
||||
return false;
|
||||
}
|
||||
// https://source.corp.google.com/android-internal/hardware/interfaces/security/rkp/aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl
|
||||
*csr = cppbor::Array()
|
||||
.add(1 /* version */)
|
||||
.add(cppbor::Map() /* UdsCerts */)
|
||||
.add(cppbor::EncodedItem(std::move(bcc)))
|
||||
.add(cppbor::EncodedItem(std::move(signed_csr_payload)))
|
||||
.encode();
|
||||
return true;
|
||||
}
|
||||
|
||||
void WidevineProvisioner::InitializeCryptoInterface() {
|
||||
std::string oemcrypto_path;
|
||||
if (!wvcdm::Properties::GetOEMCryptoPath(&oemcrypto_path)) {
|
||||
|
||||
Reference in New Issue
Block a user