Provide BCC in WVDrmFactory dumpsys.
[ Merge of go/wvgerrit/c/cdm/+/165138 ] Enabled the Widevine DRM service on Android to return the raw boot certificate chain via the CDM status query capabilities. This property key is not available for app-level queries. The BCC is dumped by the WVDrmFactory when requested to print all CDM properties via dumpsys. Bug: 234095402 Test: request_license_test Test: adb shell dumpsys android.hardware.drm.IDrmFactory/widevine -p Change-Id: I34695b0655b4c609979577e9986974bc0fbda898
This commit is contained in:
@@ -119,6 +119,9 @@ static const std::string QUERY_KEY_CAN_DISABLE_ANALOG_OUTPUT =
|
||||
"CanDisableAnalogOutput";
|
||||
static const std::string QUERY_KEY_WATERMARKING_SUPPORT = "WatermarkingSupport";
|
||||
static const std::string QUERY_KEY_PRODUCTION_READY = "ProductionReady";
|
||||
// Internal query key. Should not be exposed to Android apps.
|
||||
static const std::string QUERY_KEY_DEBUG_BOOT_CERTIFICATE_CHAIN =
|
||||
"DebugBootCertificateChain";
|
||||
|
||||
static const std::string QUERY_VALUE_TRUE = "True";
|
||||
static const std::string QUERY_VALUE_FALSE = "False";
|
||||
|
||||
@@ -852,6 +852,25 @@ CdmResponseType CdmEngine::QueryStatus(RequestedSecurityLevel security_level,
|
||||
*query_response = std::to_string(system_id);
|
||||
return CdmResponseType(NO_ERROR);
|
||||
}
|
||||
if (query_token == QUERY_KEY_DEBUG_BOOT_CERTIFICATE_CHAIN) {
|
||||
std::string bcc;
|
||||
std::string signature_unused;
|
||||
const CdmResponseType status = crypto_session->GetBootCertificateChain(
|
||||
security_level, &bcc, &signature_unused);
|
||||
if (status == NO_ERROR) {
|
||||
LOGD("BCC length: %zu", bcc.size());
|
||||
*query_response = std::move(bcc);
|
||||
return CdmResponseType(NO_ERROR);
|
||||
}
|
||||
if (status == NOT_IMPLEMENTED_ERROR ||
|
||||
status == PROVISIONING_TYPE_IS_NOT_BOOT_CERTIFICATE_CHAIN_ERROR) {
|
||||
LOGD("BCC not available: %d", static_cast<int>(status.Enum()));
|
||||
*query_response = QUERY_VALUE_NONE;
|
||||
return CdmResponseType(NO_ERROR);
|
||||
}
|
||||
LOGE("Failed to extract BCC: status = %d", static_cast<int>(status.Enum()));
|
||||
return status;
|
||||
}
|
||||
|
||||
CdmResponseType status;
|
||||
M_TIME(status = crypto_session->Open(security_level),
|
||||
|
||||
@@ -837,19 +837,17 @@ CdmResponseType CryptoSession::GetProvisioningId(std::string* provisioning_id) {
|
||||
RETURN_IF_NULL(provisioning_id, PARAMETER_NULL);
|
||||
RETURN_IF_NOT_OPEN(CRYPTO_SESSION_NOT_OPEN);
|
||||
|
||||
if (pre_provision_token_type_ == kClientTokenOemCert) {
|
||||
// OEM Cert devices have no provisioning-unique ID embedded in them, so we
|
||||
// synthesize one by using the External Device-Unique ID and inverting all
|
||||
// the bits.
|
||||
CdmResponseType status = GetExternalDeviceUniqueId(provisioning_id);
|
||||
|
||||
if (pre_provision_token_type_ == kClientTokenOemCert ||
|
||||
pre_provision_token_type_ == kClientTokenBootCertChain) {
|
||||
// OEM Cert and BCC devices have no provisioning-unique ID embedded in
|
||||
// them, so we synthesize one by using the External Device-Unique ID
|
||||
// and inverting all the bits.
|
||||
const CdmResponseType status = GetExternalDeviceUniqueId(provisioning_id);
|
||||
if (status != NO_ERROR) return status;
|
||||
|
||||
for (size_t i = 0; i < provisioning_id->size(); ++i) {
|
||||
char value = (*provisioning_id)[i];
|
||||
(*provisioning_id)[i] = ~value;
|
||||
for (char& c : *provisioning_id) {
|
||||
c ^= 0xff;
|
||||
}
|
||||
|
||||
return CdmResponseType(NO_ERROR);
|
||||
}
|
||||
if (pre_provision_token_type_ == kClientTokenKeybox) {
|
||||
@@ -1383,7 +1381,14 @@ CdmResponseType CryptoSession::GetBootCertificateChain(
|
||||
RETURN_IF_UNINITIALIZED(CRYPTO_SESSION_NOT_INITIALIZED);
|
||||
LOGV("requested_security_level = %s",
|
||||
RequestedSecurityLevelToString(requested_security_level));
|
||||
if (pre_provision_token_type_ != kClientTokenBootCertChain) {
|
||||
CdmClientTokenType token_type = kClientTokenUninitialized;
|
||||
const CdmResponseType status =
|
||||
GetProvisioningMethod(requested_security_level, &token_type);
|
||||
if (status != NO_ERROR) {
|
||||
LOGE("Failed to get token type");
|
||||
return status;
|
||||
}
|
||||
if (token_type != kClientTokenBootCertChain) {
|
||||
return CdmResponseType(
|
||||
PROVISIONING_TYPE_IS_NOT_BOOT_CERTIFICATE_CHAIN_ERROR);
|
||||
}
|
||||
|
||||
@@ -4208,7 +4208,21 @@ TEST_F(WvCdmRequestLicenseTest, QueryStatus) {
|
||||
kLevelDefault, wvcdm::QUERY_KEY_PROVISIONING_MODEL, &value));
|
||||
// These are the only valid values for Android devices.
|
||||
EXPECT_TRUE(value == wvcdm::QUERY_VALUE_KEYBOX ||
|
||||
value == wvcdm::QUERY_VALUE_OEM_CERTIFICATE);
|
||||
value == wvcdm::QUERY_VALUE_OEM_CERTIFICATE ||
|
||||
value == wvcdm::QUERY_VALUE_BOOT_CERTIFICATE_CHAIN);
|
||||
|
||||
const bool expect_bcc = (value == wvcdm::QUERY_VALUE_BOOT_CERTIFICATE_CHAIN);
|
||||
EXPECT_EQ(wvcdm::NO_ERROR,
|
||||
decryptor_->QueryStatus(
|
||||
kLevelDefault, wvcdm::QUERY_KEY_DEBUG_BOOT_CERTIFICATE_CHAIN,
|
||||
&value));
|
||||
if (expect_bcc) {
|
||||
// Expect that the BCC is returned; but do not validate the actual value.
|
||||
EXPECT_FALSE(value.empty()) << "BCC is empty";
|
||||
EXPECT_NE(value, wvcdm::QUERY_VALUE_NONE) << "BCC is none";
|
||||
} else {
|
||||
EXPECT_EQ(value, wvcdm::QUERY_VALUE_NONE);
|
||||
}
|
||||
|
||||
EXPECT_EQ(
|
||||
wvcdm::NO_ERROR,
|
||||
|
||||
Reference in New Issue
Block a user