Merge "Internal BCC extraction tool to consume verified device info"
This commit is contained in:
@@ -13,6 +13,13 @@
|
||||
|
||||
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;
|
||||
@@ -30,6 +37,11 @@ class OEMCryptoInterface {
|
||||
// implementation.
|
||||
OEMCryptoResult GetOEMCryptoBuildInfo(std::string& build_info);
|
||||
|
||||
// Retrieves the verified device information of the OEMCrypto library from
|
||||
// OEMCrypto implementation.
|
||||
OEMCryptoResult GetVerifiedDeviceInformation(
|
||||
VerifiedDeviceInfo& verified_device_info);
|
||||
|
||||
private:
|
||||
typedef OEMCryptoResult (*Initialize_t)();
|
||||
typedef OEMCryptoResult (*Terminate_t)();
|
||||
@@ -38,11 +50,15 @@ 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,
|
||||
uint8_t* signed_csr_payload, size_t* signed_csr_payload_length);
|
||||
|
||||
Initialize_t Initialize = nullptr;
|
||||
Terminate_t Terminate = nullptr;
|
||||
GetBootCertificateChain_t GetBootCertificateChain = nullptr;
|
||||
BuildInformation_t BuildInformation = nullptr;
|
||||
GetDeviceInformation_t GetDeviceInformation = nullptr;
|
||||
|
||||
void* handle_ = nullptr;
|
||||
};
|
||||
|
||||
@@ -44,6 +44,8 @@ class WidevineProvisioner {
|
||||
cppbor::Array BuildCertReqRecipients(const std::vector<uint8_t>& pubkey,
|
||||
const std::vector<uint8_t>& kid) const;
|
||||
void InitializeCryptoInterface();
|
||||
bool GetDeviceInfoCommon(cppbor::Map& device_info_map);
|
||||
bool TryAddVerifiedDeviceInfo(cppbor::Map& device_info_map);
|
||||
|
||||
std::unique_ptr<OEMCryptoInterface> crypto_interface_;
|
||||
};
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
LOGE("%s", dlerror()); \
|
||||
return false; \
|
||||
}
|
||||
#define LOAD_SYM_IF_EXIST(name) \
|
||||
name = reinterpret_cast<name##_t>(LOOKUP(handle_, OEMCrypto_##name));
|
||||
|
||||
// These are implementations required by OEMCrypto Reference Implementation
|
||||
// and/or the Testbed, but not needed in this package.
|
||||
@@ -78,6 +80,7 @@ bool OEMCryptoInterface::Init(const std::string& oemcrypto_path) {
|
||||
LOAD_SYM(Terminate);
|
||||
LOAD_SYM(GetBootCertificateChain);
|
||||
LOAD_SYM(BuildInformation);
|
||||
LOAD_SYM_IF_EXIST(GetDeviceInformation);
|
||||
|
||||
OEMCryptoResult status = Initialize();
|
||||
if (status != OEMCrypto_SUCCESS) {
|
||||
@@ -141,4 +144,37 @@ OEMCryptoResult OEMCryptoInterface::GetOEMCryptoBuildInfo(
|
||||
return result;
|
||||
}
|
||||
|
||||
OEMCryptoResult OEMCryptoInterface::GetVerifiedDeviceInformation(
|
||||
VerifiedDeviceInfo& verified_device_info) {
|
||||
if (handle_ == nullptr) {
|
||||
return OEMCrypto_ERROR_INIT_FAILED;
|
||||
}
|
||||
if (GetDeviceInformation == nullptr) {
|
||||
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);
|
||||
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);
|
||||
LOGI("GetVerifiedDeviceInformation second attempt result %d", result);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace widevine
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "WidevineOemcryptoInterface.h"
|
||||
#include "log.h"
|
||||
#include "properties.h"
|
||||
|
||||
@@ -70,25 +71,87 @@ bool WidevineProvisioner::GenerateCertificateRequest(
|
||||
return true;
|
||||
}
|
||||
|
||||
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));
|
||||
|
||||
std::string company_name;
|
||||
if (!wvcdm::Properties::GetCompanyName(&company_name) ||
|
||||
company_name.empty()) {
|
||||
LOGE("Failed to get company name.");
|
||||
bool WidevineProvisioner::TryAddVerifiedDeviceInfo(
|
||||
cppbor::Map& device_info_map) {
|
||||
VerifiedDeviceInfo verified_device_info;
|
||||
OEMCryptoResult result =
|
||||
crypto_interface_->GetVerifiedDeviceInformation(verified_device_info);
|
||||
if (result == OEMCrypto_ERROR_NOT_IMPLEMENTED) {
|
||||
// OEMCrypto v17 and earlier doesn't support GetDeviceInformation()
|
||||
LOGI("OEMCrypto_GetDeviceInformation is not implemented.");
|
||||
return true;
|
||||
}
|
||||
if (result != OEMCrypto_SUCCESS) {
|
||||
LOGE("Failed to get verified device information.");
|
||||
return false;
|
||||
}
|
||||
device_info_map.add(cppbor::Tstr("manufacturer"), cppbor::Tstr(company_name));
|
||||
|
||||
std::string model_name;
|
||||
if (!wvcdm::Properties::GetModelName(&model_name) || model_name.empty()) {
|
||||
LOGE("Failed to get model name.");
|
||||
auto [parsed, _, err] = cppbor::parse(
|
||||
reinterpret_cast<const uint8_t*>(verified_device_info.device_info.data()),
|
||||
verified_device_info.device_info.size());
|
||||
if (!parsed || !parsed->asMap()) {
|
||||
LOGE("Failed to parse the verified device info cbor: %s", err.c_str());
|
||||
return false;
|
||||
}
|
||||
device_info_map.add(cppbor::Tstr("model"), cppbor::Tstr(model_name));
|
||||
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());
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
bool WidevineProvisioner::GetDeviceInfoCommon(cppbor::Map& device_info_map) {
|
||||
if (!TryAddVerifiedDeviceInfo(device_info_map)) return false;
|
||||
// Add device information from OS properties if the verified device info is
|
||||
// not present
|
||||
if (device_info_map.get("manufacturer") == nullptr) {
|
||||
std::string company_name;
|
||||
if (!wvcdm::Properties::GetCompanyName(&company_name) ||
|
||||
company_name.empty()) {
|
||||
LOGE("Failed to get company name.");
|
||||
return false;
|
||||
}
|
||||
device_info_map.add(cppbor::Tstr("manufacturer"),
|
||||
cppbor::Tstr(company_name));
|
||||
}
|
||||
|
||||
if (device_info_map.get("model") == nullptr) {
|
||||
std::string model_name;
|
||||
if (!wvcdm::Properties::GetModelName(&model_name) || model_name.empty()) {
|
||||
LOGE("Failed to get model name.");
|
||||
return false;
|
||||
}
|
||||
device_info_map.add(cppbor::Tstr("model"), cppbor::Tstr(model_name));
|
||||
}
|
||||
|
||||
if (device_info_map.get("device") == nullptr) {
|
||||
std::string device_name;
|
||||
if (!wvcdm::Properties::GetDeviceName(&device_name) ||
|
||||
device_name.empty()) {
|
||||
LOGE("Failed to get device name.");
|
||||
return false;
|
||||
}
|
||||
device_info_map.add(cppbor::Tstr("device"), cppbor::Tstr(device_name));
|
||||
}
|
||||
|
||||
if (device_info_map.get("product") == nullptr) {
|
||||
std::string product_name;
|
||||
if (!wvcdm::Properties::GetProductName(&product_name) ||
|
||||
product_name.empty()) {
|
||||
LOGE("Failed to get product name.");
|
||||
return false;
|
||||
}
|
||||
device_info_map.add(cppbor::Tstr("product"), cppbor::Tstr(product_name));
|
||||
}
|
||||
|
||||
std::string arch_name;
|
||||
if (!wvcdm::Properties::GetArchitectureName(&arch_name) ||
|
||||
@@ -98,21 +161,6 @@ bool WidevineProvisioner::GetDeviceInfo(std::vector<uint8_t>& device_info) {
|
||||
}
|
||||
device_info_map.add(cppbor::Tstr("architecture"), cppbor::Tstr(arch_name));
|
||||
|
||||
std::string device_name;
|
||||
if (!wvcdm::Properties::GetDeviceName(&device_name) || device_name.empty()) {
|
||||
LOGE("Failed to get device name.");
|
||||
return false;
|
||||
}
|
||||
device_info_map.add(cppbor::Tstr("device"), cppbor::Tstr(device_name));
|
||||
|
||||
std::string product_name;
|
||||
if (!wvcdm::Properties::GetProductName(&product_name) ||
|
||||
product_name.empty()) {
|
||||
LOGE("Failed to get product name.");
|
||||
return false;
|
||||
}
|
||||
device_info_map.add(cppbor::Tstr("product"), cppbor::Tstr(product_name));
|
||||
|
||||
std::string build_info;
|
||||
if (!wvcdm::Properties::GetBuildInfo(&build_info) || build_info.empty()) {
|
||||
LOGE("Failed to get build info.");
|
||||
@@ -130,6 +178,16 @@ bool WidevineProvisioner::GetDeviceInfo(std::vector<uint8_t>& device_info) {
|
||||
device_info_map.add(cppbor::Tstr("oemcrypto_build_info"),
|
||||
cppbor::Tstr(oemcrypto_build_info));
|
||||
|
||||
device_info_map.canonicalize();
|
||||
return true;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user