Add DRM reprovisioning request generation
[ Merge of http://go/wvgerrit/192010 ] Updates the CDM to add support for DRM reprovisioning request creation. - Load the baked-in certificate for use as the client token. - Add functions to build and sign a drm reprovisioning request. - Update the Rikers L3 OEMCrypto implementation to support signing provisioning requests and getting embedded certificate. - Update client id token to handle DRM reprovisioning. - Add OEMCrypto function to load the baked-in device certificate in Rikers CDMs and stubs for non-Rikers CDMs. - Add dynamic adapter support for getting embedded device certificate only on L3. Bug: 305093063 Test: WVTS Change-Id: I9a0ecf95e27213b046f03baa0781fb164179323b
This commit is contained in:
@@ -81,6 +81,7 @@ extern "C" OEMCryptoResult OEMCrypto_UseSecondaryKey(OEMCrypto_SESSION session,
|
||||
#endif
|
||||
|
||||
namespace wvcdm {
|
||||
|
||||
namespace {
|
||||
using UsageTableLock = std::unique_lock<std::recursive_mutex>;
|
||||
|
||||
@@ -346,6 +347,9 @@ CdmResponseType CryptoSession::GetProvisioningMethod(
|
||||
case OEMCrypto_BootCertificateChain:
|
||||
type = kClientTokenBootCertChain;
|
||||
break;
|
||||
case OEMCrypto_DrmReprovisioning:
|
||||
type = kClientTokenDrmReprovisioning;
|
||||
break;
|
||||
case OEMCrypto_ProvisioningError:
|
||||
default:
|
||||
if (static_cast<int>(method) == 0 && needs_keybox_provisioning_) {
|
||||
@@ -662,6 +666,8 @@ CdmResponseType CryptoSession::GetProvisioningToken(
|
||||
} else if (pre_provision_token_type_ == kClientTokenBootCertChain) {
|
||||
status = GetBootCertificateChain(requested_security_level, token,
|
||||
additional_token);
|
||||
} else if (pre_provision_token_type_ == kClientTokenDrmReprovisioning) {
|
||||
status = GetTokenFromEmbeddedCertificate(token);
|
||||
}
|
||||
metrics_->crypto_session_get_token_.Increment(status);
|
||||
return status;
|
||||
@@ -1253,6 +1259,7 @@ CdmResponseType CryptoSession::PrepareAndSignProvisioningRequest(
|
||||
}
|
||||
|
||||
OEMCryptoResult sts;
|
||||
// TODO: b/305093063 - Refactor to a switch statement to improve readability
|
||||
if (pre_provision_token_type_ == kClientTokenKeybox) {
|
||||
should_specify_algorithm = false;
|
||||
} else if (pre_provision_token_type_ == kClientTokenOemCert) {
|
||||
@@ -1268,6 +1275,10 @@ CdmResponseType CryptoSession::PrepareAndSignProvisioningRequest(
|
||||
should_specify_algorithm = true;
|
||||
// Do nothing here. The key to signing the provisioning 4.0 request for each
|
||||
// stage has been loaded already when it was generated by OEMCrypto.
|
||||
} else if (pre_provision_token_type_ == kClientTokenDrmReprovisioning) {
|
||||
should_specify_algorithm = false;
|
||||
// Do nothing here. The baked-in certificate used as the token has already
|
||||
// been loaded when the EncryptedClientId was filled in.
|
||||
} else {
|
||||
LOGE("Unknown method %d", pre_provision_token_type_);
|
||||
return CdmResponseType(UNKNOWN_CLIENT_TOKEN_TYPE);
|
||||
@@ -1439,6 +1450,59 @@ CdmResponseType CryptoSession::GetBootCertificateChain(
|
||||
return CdmResponseType(NO_ERROR);
|
||||
}
|
||||
|
||||
CdmResponseType CryptoSession::GetTokenFromEmbeddedCertificate(
|
||||
std::string* token) {
|
||||
RETURN_IF_UNINITIALIZED(CRYPTO_SESSION_NOT_INITIALIZED);
|
||||
RETURN_IF_NULL(token, PARAMETER_NULL);
|
||||
|
||||
CdmClientTokenType token_type = kClientTokenUninitialized;
|
||||
const CdmResponseType sts =
|
||||
GetProvisioningMethod(requested_security_level_, &token_type);
|
||||
if (sts != NO_ERROR) {
|
||||
LOGE("Failed to get token type");
|
||||
return sts;
|
||||
}
|
||||
if (token_type != kClientTokenDrmReprovisioning) {
|
||||
token->clear();
|
||||
return CdmResponseType(NO_ERROR);
|
||||
}
|
||||
|
||||
size_t certificate_length = CERTIFICATE_DATA_SIZE;
|
||||
std::string embedded_certificate(certificate_length, '\0');
|
||||
OEMCryptoResult status =
|
||||
WithOecReadLock("GetTokenFromEmbeddedCertificate - attempt 1", [&] {
|
||||
return OEMCrypto_GetEmbeddedDrmCertificate(
|
||||
reinterpret_cast<uint8_t*>(&embedded_certificate.front()),
|
||||
&certificate_length);
|
||||
});
|
||||
|
||||
if (status == OEMCrypto_ERROR_SHORT_BUFFER) {
|
||||
embedded_certificate.assign(certificate_length, '\0');
|
||||
status =
|
||||
WithOecReadLock("GetTokenFromEmbeddedCertificate - attempt 2", [&] {
|
||||
return OEMCrypto_GetEmbeddedDrmCertificate(
|
||||
reinterpret_cast<uint8_t*>(&embedded_certificate.front()),
|
||||
&certificate_length);
|
||||
});
|
||||
}
|
||||
|
||||
if (status == OEMCrypto_SUCCESS) {
|
||||
// TODO: b/312782308 - Store embedded certificate as SignedDrmCertificate
|
||||
video_widevine_client::sdk::HashedFile hashed_file;
|
||||
video_widevine_client::sdk::File file;
|
||||
embedded_certificate.resize(certificate_length);
|
||||
if (hashed_file.ParseFromString(embedded_certificate) &&
|
||||
file.ParseFromString(hashed_file.file())) {
|
||||
*token = file.device_certificate().certificate();
|
||||
return CdmResponseType(NO_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
token->clear();
|
||||
return MapOEMCryptoResult(status, GET_TOKEN_FROM_EMBEDDED_CERT_ERROR,
|
||||
"GetTokenFromEmbeddedCertificate");
|
||||
}
|
||||
|
||||
CdmResponseType CryptoSession::GetDeviceInformation(
|
||||
RequestedSecurityLevel requested_security_level, std::string* device_info) {
|
||||
RETURN_IF_NULL(device_info, PARAMETER_NULL);
|
||||
|
||||
Reference in New Issue
Block a user