WVDrmPlugin changes to query device CSR payload for prov 4
[ Merge of https://widevine-internal-review.googlesource.com/c/cdm/+/178891/ ] Plugin to provide getPropertyByteArray("deviceSignedCsrPayload") which returns the signed CSR payload for device registration. It queries both BCC and device info to be set in plugin before calling this getPropertyByteArray("deviceSignedCsrPayload") method. The returned csr payload will be used by assemble the device CSR by the caller for device registration. Bug: 286556950 Test: build WV DRM plugin Change-Id: Ie592f53497f6d391ff232fd02bd4e66ca857e0e4
This commit is contained in:
@@ -4,7 +4,7 @@
|
||||
// Agreement.
|
||||
//
|
||||
|
||||
//#define LOG_NDEBUG 0
|
||||
// #define LOG_NDEBUG 0
|
||||
#define LOG_TAG "WVCdm"
|
||||
|
||||
#include "WVDrmPlugin.h"
|
||||
@@ -154,6 +154,12 @@ HdcpLevel mapHdcpLevel(const std::string& level) {
|
||||
}
|
||||
}
|
||||
|
||||
bool isRootOrShell() {
|
||||
const uid_t AID_ROOT = 0, AID_SHELL = 2000;
|
||||
const uid_t uid = AIBinder_getCallingUid();
|
||||
return (uid == AID_ROOT || uid == AID_SHELL);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
WVDrmPlugin::WVDrmPlugin(const android::sp<WvContentDecryptionModule>& cdm,
|
||||
@@ -759,7 +765,8 @@ Status WVDrmPlugin::unprovisionDevice() {
|
||||
}
|
||||
|
||||
drm_metrics::WvCdmMetrics proto_metrics;
|
||||
const CdmResponseType result = mCDM->GetCurrentMetrics(identifier, &proto_metrics);
|
||||
const CdmResponseType result =
|
||||
mCDM->GetCurrentMetrics(identifier, &proto_metrics);
|
||||
if (result != wvcdm::NO_ERROR) {
|
||||
return toNdkScopedAStatus(mapCdmResponseType(result));
|
||||
}
|
||||
@@ -1066,7 +1073,8 @@ Status WVDrmPlugin::unprovisionDevice() {
|
||||
value = info->name;
|
||||
} else {
|
||||
auto err = info.error();
|
||||
ALOGW("apex info error %d: %s", err.code().value(), err.message().c_str());
|
||||
ALOGW("apex info error %d: %s", err.code().value(),
|
||||
err.message().c_str());
|
||||
value = "Google";
|
||||
}
|
||||
#else
|
||||
@@ -1165,6 +1173,26 @@ Status WVDrmPlugin::unprovisionDevice() {
|
||||
return toNdkScopedAStatus(status);
|
||||
}
|
||||
|
||||
static WvStatus getDeviceSignedCsrPayload(
|
||||
android::sp<wvcdm::WvContentDecryptionModule> const cdm,
|
||||
std::string& certificate_signing_request_challenge,
|
||||
std::string& device_info, std::string* csr) {
|
||||
if (certificate_signing_request_challenge.empty() || device_info.empty()) {
|
||||
ALOGW("CSR challenge or device info is empty.");
|
||||
return WvStatus(Status::BAD_VALUE);
|
||||
}
|
||||
std::string signed_csr_payload;
|
||||
CdmResponseType res = cdm->QueryDeviceSignedCsrPayload(
|
||||
certificate_signing_request_challenge, device_info, &signed_csr_payload);
|
||||
if (res != wvcdm::NO_ERROR) {
|
||||
ALOGE("Error querying CDM device_signed_csr_payload: %d",
|
||||
static_cast<int>(res));
|
||||
return mapCdmResponseType(res);
|
||||
}
|
||||
*csr = signed_csr_payload;
|
||||
return WvStatus(Status::OK);
|
||||
}
|
||||
|
||||
::ndk::ScopedAStatus WVDrmPlugin::getPropertyByteArray(
|
||||
const std::string& in_propertyName, vector<uint8_t>* _aidl_return) {
|
||||
WvStatus status(Status::OK);
|
||||
@@ -1210,6 +1238,42 @@ Status WVDrmPlugin::unprovisionDevice() {
|
||||
value = StrToVector(serialized_metrics);
|
||||
}
|
||||
}
|
||||
} else if (name == "bootCertificateChain" && isRootOrShell()) {
|
||||
std::string boot_certificate_chain;
|
||||
CdmResponseType res = mCDM->QueryStatus(
|
||||
wvcdm::kLevelDefault, wvcdm::QUERY_KEY_DEBUG_BOOT_CERTIFICATE_CHAIN,
|
||||
&boot_certificate_chain);
|
||||
if (res != wvcdm::NO_ERROR) {
|
||||
ALOGE("Error querying CDM boot certificate chain: %d",
|
||||
static_cast<int>(res));
|
||||
status = mapCdmResponseType(res);
|
||||
} else {
|
||||
value = StrToVector(boot_certificate_chain);
|
||||
}
|
||||
} else if (name == "verifiedDeviceInfo" && isRootOrShell()) {
|
||||
std::string verified_device_info;
|
||||
CdmResponseType res = mCDM->QueryStatus(wvcdm::kLevelDefault,
|
||||
wvcdm::QUERY_KEY_DEVICE_INFORMATION,
|
||||
&verified_device_info);
|
||||
if (res != wvcdm::NO_ERROR) {
|
||||
ALOGE("Error querying CDM verified device info: %d",
|
||||
static_cast<int>(res));
|
||||
status = mapCdmResponseType(res);
|
||||
} else {
|
||||
value = StrToVector(verified_device_info);
|
||||
}
|
||||
} else if (name == "deviceSignedCsrPayload" && isRootOrShell()) {
|
||||
std::string signed_csr_payload;
|
||||
status =
|
||||
getDeviceSignedCsrPayload(mCDM, mCertificateSigningRequestChallenge,
|
||||
mDeviceInfo, &signed_csr_payload);
|
||||
if (status != Status::OK) {
|
||||
ALOGE("Error querying CDM signed CSR payload: %d", status.get());
|
||||
} else {
|
||||
value = StrToVector(signed_csr_payload);
|
||||
}
|
||||
mCertificateSigningRequestChallenge.clear();
|
||||
mDeviceInfo.clear();
|
||||
} else {
|
||||
ALOGE("App requested unknown byte array property %s", name.c_str());
|
||||
status = WvStatus(Status::ERROR_DRM_CANNOT_HANDLE);
|
||||
@@ -1349,8 +1413,9 @@ Status WVDrmPlugin::unprovisionDevice() {
|
||||
}
|
||||
} else if (name == "storeAtscLicense") {
|
||||
if (!mCdmIdentifierBuilder.is_sealed()) {
|
||||
ALOGE("Cdm identifier builder is not sealed. Storing ATSC license "
|
||||
"prohibited");
|
||||
ALOGE(
|
||||
"Cdm identifier builder is not sealed. Storing ATSC license "
|
||||
"prohibited");
|
||||
return toNdkScopedAStatus(Status::ERROR_DRM_CANNOT_HANDLE);
|
||||
}
|
||||
if (!mPropertySet.use_atsc_mode()) {
|
||||
@@ -1366,8 +1431,7 @@ Status WVDrmPlugin::unprovisionDevice() {
|
||||
}
|
||||
std::string key_set_id, license_data;
|
||||
status = parseAtscLicenseData(_value, &key_set_id, &license_data);
|
||||
if (status != Status::OK)
|
||||
return toNdkScopedAStatus(status);
|
||||
if (status != Status::OK) return toNdkScopedAStatus(status);
|
||||
|
||||
const CdmResponseType res = mCDM->StoreAtscLicense(
|
||||
identifier, getRequestedSecurityLevel(), key_set_id, license_data);
|
||||
@@ -1400,6 +1464,11 @@ Status WVDrmPlugin::unprovisionDevice() {
|
||||
} else {
|
||||
return toNdkScopedAStatus(Status::BAD_VALUE);
|
||||
}
|
||||
} else if (name == "certificateSigningRequestChallenge" && isRootOrShell()) {
|
||||
mCertificateSigningRequestChallenge =
|
||||
std::string(_value.begin(), _value.end());
|
||||
} else if (name == "deviceInfo" && isRootOrShell()) {
|
||||
mDeviceInfo = std::string(_value.begin(), _value.end());
|
||||
} else {
|
||||
ALOGE("App set unknown byte array property %s", name.c_str());
|
||||
return toNdkScopedAStatus(Status::ERROR_DRM_CANNOT_HANDLE);
|
||||
@@ -1830,8 +1899,7 @@ bool WVDrmPlugin::isProvisioned(wvcdm::CdmSecurityLevel securityLevel,
|
||||
}
|
||||
|
||||
WvStatus WVDrmPlugin::parseAtscLicenseData(
|
||||
const std::string& in_value,
|
||||
std::string* key_set_id,
|
||||
const std::string& in_value, std::string* key_set_id,
|
||||
std::string* serialized_license_data) {
|
||||
if (key_set_id == nullptr) {
|
||||
ALOGE("key_set_id null");
|
||||
@@ -1843,34 +1911,39 @@ WvStatus WVDrmPlugin::parseAtscLicenseData(
|
||||
return WvStatus(Status::ERROR_DRM_CANNOT_HANDLE);
|
||||
}
|
||||
|
||||
if (in_value.compare(0,
|
||||
strlen(wvcdm::ATSC_KEY_SET_ID_PREFIX),
|
||||
if (in_value.compare(0, strlen(wvcdm::ATSC_KEY_SET_ID_PREFIX),
|
||||
&wvcdm::ATSC_KEY_SET_ID_PREFIX[0]) != 0) {
|
||||
ALOGE("ATSC license input does not conform to expectations. Key set does "
|
||||
"not have a valid ATSC Key set prefix %s", in_value.c_str());
|
||||
ALOGE(
|
||||
"ATSC license input does not conform to expectations. Key set does "
|
||||
"not have a valid ATSC Key set prefix %s",
|
||||
in_value.c_str());
|
||||
return WvStatus(Status::BAD_VALUE);
|
||||
}
|
||||
const char kColon = ':';
|
||||
const size_t pos = in_value.find(kColon);
|
||||
if (pos == std::string::npos) {
|
||||
ALOGE("ATSC license input does not conform to expectations. Missing colon "
|
||||
"= %s", in_value.c_str());
|
||||
ALOGE(
|
||||
"ATSC license input does not conform to expectations. Missing colon "
|
||||
"= %s",
|
||||
in_value.c_str());
|
||||
return WvStatus(Status::BAD_VALUE);
|
||||
}
|
||||
|
||||
if (pos == in_value.length()) {
|
||||
ALOGE("ATSC license input does not conform to expectations. No data after "
|
||||
"colon");
|
||||
ALOGE(
|
||||
"ATSC license input does not conform to expectations. No data after "
|
||||
"colon");
|
||||
return WvStatus(Status::BAD_VALUE);
|
||||
}
|
||||
|
||||
*key_set_id = in_value.substr(0, pos);
|
||||
const std::vector<uint8_t> license_data_binary =
|
||||
wvutil::Base64Decode(in_value.substr(pos+1));
|
||||
wvutil::Base64Decode(in_value.substr(pos + 1));
|
||||
|
||||
if (license_data_binary.empty()) {
|
||||
ALOGE("ATSC license input does not conform to expectations. License data "
|
||||
"failed to decode from Base64");
|
||||
ALOGE(
|
||||
"ATSC license input does not conform to expectations. License data "
|
||||
"failed to decode from Base64");
|
||||
return WvStatus(Status::BAD_VALUE);
|
||||
}
|
||||
serialized_license_data->assign(license_data_binary.begin(),
|
||||
@@ -1879,7 +1952,6 @@ WvStatus WVDrmPlugin::parseAtscLicenseData(
|
||||
return WvStatus(Status::OK);
|
||||
}
|
||||
|
||||
|
||||
WvStatus WVDrmPlugin::mapAndNotifyOfCdmResponseType(
|
||||
const vector<uint8_t>& sessionId, CdmResponseType res) {
|
||||
notifyOfCdmResponseType(sessionId, res);
|
||||
|
||||
Reference in New Issue
Block a user