CDM core: Removed support for v15 provisioning responses.
[ Merge of http://go/wvgerrit/160277 ] OEMCrypto v15 did not require core messages during DRM certificate provisioning. The CDM's certificate provisioning flow was allowing for either case (with or without core messages) when provisioning. Now, devices can safely assume that all provsisioning responses will be v16 or newer; all requests/response must contain a core message. Bug: 252670759 Test: run_x86_64_tests and request_license_test Change-Id: I9f51e07caf642eaf646ef40bdd640b3ccfe2533c
This commit is contained in:
@@ -50,8 +50,6 @@ class CertificateProvisioning {
|
||||
wvutil::FileSystem* file_system, const CdmProvisioningResponse& response,
|
||||
std::string* cert, std::string* wrapped_key);
|
||||
|
||||
bool supports_core_messages() const { return supports_core_messages_; }
|
||||
|
||||
// Helper methods
|
||||
|
||||
// Extract serial number and system ID from a DRM Device certificate.
|
||||
@@ -123,13 +121,6 @@ class CertificateProvisioning {
|
||||
// Key type of the generated key pair in provisioning 4.
|
||||
CryptoWrappedKey::Type provisioning_40_key_type_;
|
||||
|
||||
// Indicates whether OEMCrypto supports core messages, and whether the
|
||||
// CDM should expect a core message in the response. This is primarily
|
||||
// used to distinguish between v16+ OEMCrypto or an earlier version.
|
||||
// Assume core messages are supported, and check if OEMCrypto populates
|
||||
// the core message field when calling PrepAndSignProvisioningRequest().
|
||||
bool supports_core_messages_ = true;
|
||||
|
||||
CORE_DISALLOW_COPY_AND_ASSIGN(CertificateProvisioning);
|
||||
};
|
||||
|
||||
|
||||
@@ -87,8 +87,6 @@ bool RetrieveOemCertificateAndLoadPrivateKey(CryptoSession& crypto_session,
|
||||
|
||||
} // namespace
|
||||
// Protobuf generated classes.
|
||||
using video_widevine::ClientIdentification_ClientCapabilities;
|
||||
using video_widevine::ClientIdentification_NameValue;
|
||||
using video_widevine::DrmCertificate;
|
||||
using video_widevine::EncryptedClientIdentification;
|
||||
using video_widevine::ProvisioningOptions;
|
||||
@@ -97,8 +95,6 @@ using video_widevine::ProvisioningResponse;
|
||||
using video_widevine::PublicKeyToCertify;
|
||||
using video_widevine::SignedDrmCertificate;
|
||||
using video_widevine::SignedProvisioningMessage;
|
||||
using video_widevine::
|
||||
SignedProvisioningMessage_ProvisioningProtocolVersion_VERSION_1_1;
|
||||
|
||||
// static
|
||||
void CertificateProvisioning::GetProvisioningServerUrl(
|
||||
@@ -112,18 +108,16 @@ void CertificateProvisioning::GetProvisioningServerUrl(
|
||||
|
||||
CdmResponseType CertificateProvisioning::Init(
|
||||
const std::string& service_certificate) {
|
||||
std::string certificate = service_certificate.empty()
|
||||
? kCpProductionServiceCertificate
|
||||
: service_certificate;
|
||||
const std::string certificate = service_certificate.empty()
|
||||
? kCpProductionServiceCertificate
|
||||
: service_certificate;
|
||||
return service_certificate_->Init(certificate);
|
||||
}
|
||||
|
||||
/*
|
||||
* Fill in the appropriate SPOID (Stable Per-Origin IDentifier) option.
|
||||
* One of spoid, provider_id or stable_id will be passed to the provisioning
|
||||
* server for determining a unique per origin ID for the device.
|
||||
* It is also valid (though deprecated) to leave the settings unset.
|
||||
*/
|
||||
// Fill in the appropriate SPOID (Stable Per-Origin IDentifier) option.
|
||||
// One of spoid, provider_id or stable_id will be passed to the provisioning
|
||||
// server for determining a unique per origin ID for the device.
|
||||
// It is also valid (though deprecated) to leave the settings unset.
|
||||
CdmResponseType CertificateProvisioning::SetSpoidParameter(
|
||||
const std::string& origin, const std::string& spoid,
|
||||
ProvisioningRequest* request) {
|
||||
@@ -135,14 +129,13 @@ CdmResponseType CertificateProvisioning::SetSpoidParameter(
|
||||
// Use the SPOID that has been pre-provided
|
||||
request->set_spoid(spoid);
|
||||
} else if (Properties::UseProviderIdInProvisioningRequest()) {
|
||||
if (!service_certificate_->provider_id().empty()) {
|
||||
request->set_provider_id(service_certificate_->provider_id());
|
||||
} else {
|
||||
if (service_certificate_->provider_id().empty()) {
|
||||
LOGE(
|
||||
"Failed to set provider ID: "
|
||||
"Service certificate provider ID is empty");
|
||||
return SERVICE_CERTIFICATE_PROVIDER_ID_EMPTY;
|
||||
}
|
||||
request->set_provider_id(service_certificate_->provider_id());
|
||||
} else if (origin != EMPTY_ORIGIN) {
|
||||
// Legacy behavior - Concatenate Unique ID with Origin
|
||||
std::string device_unique_id;
|
||||
@@ -159,10 +152,8 @@ CdmResponseType CertificateProvisioning::SetSpoidParameter(
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the provisioning protocol version - dictated by OEMCrypto
|
||||
* support for OEM certificates.
|
||||
*/
|
||||
// Return the provisioning protocol version - dictated by OEMCrypto
|
||||
// support for OEM certificates.
|
||||
SignedProvisioningMessage::ProvisioningType
|
||||
CertificateProvisioning::GetProvisioningType() {
|
||||
switch (crypto_session_->GetPreProvisionTokenType()) {
|
||||
@@ -175,13 +166,11 @@ CertificateProvisioning::GetProvisioningType() {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Compose a device provisioning request and output *request in a
|
||||
* JSON-compatible format (web-safe base64).
|
||||
* Also return *default_url of the provisioning server.
|
||||
*
|
||||
* Returns NO_ERROR for success and CERT_PROVISIONING_REQUEST_ERROR_? if fails.
|
||||
*/
|
||||
// Compose a device provisioning request and output *request in a
|
||||
// JSON-compatible format (web-safe base64).
|
||||
// Also return *default_url of the provisioning server.
|
||||
//
|
||||
// Returns NO_ERROR for success and CERT_PROVISIONING_REQUEST_ERROR_? if fails.
|
||||
CdmResponseType CertificateProvisioning::GetProvisioningRequest(
|
||||
wvutil::FileSystem* file_system,
|
||||
RequestedSecurityLevel requested_security_level,
|
||||
@@ -240,18 +229,17 @@ CdmResponseType CertificateProvisioning::GetProvisioningRequestInternal(
|
||||
|
||||
// The provisioning server does not convert the nonce to uint32_t, it just
|
||||
// passes the binary data to the response message.
|
||||
std::string the_nonce(reinterpret_cast<char*>(&nonce), sizeof(nonce));
|
||||
provisioning_request.set_nonce(the_nonce);
|
||||
const std::string encoded_nonce(reinterpret_cast<char*>(&nonce),
|
||||
sizeof(nonce));
|
||||
provisioning_request.set_nonce(encoded_nonce);
|
||||
|
||||
ProvisioningOptions* options = provisioning_request.mutable_options();
|
||||
switch (cert_type) {
|
||||
case kCertificateWidevine:
|
||||
options->set_certificate_type(
|
||||
video_widevine::ProvisioningOptions_CertificateType_WIDEVINE_DRM);
|
||||
options->set_certificate_type(ProvisioningOptions::WIDEVINE_DRM);
|
||||
break;
|
||||
case kCertificateX509:
|
||||
options->set_certificate_type(
|
||||
video_widevine::ProvisioningOptions_CertificateType_X509);
|
||||
options->set_certificate_type(ProvisioningOptions::X509);
|
||||
break;
|
||||
default:
|
||||
LOGE("Unknown certificate type: %d", static_cast<int>(cert_type));
|
||||
@@ -288,14 +276,9 @@ CdmResponseType CertificateProvisioning::GetProvisioningRequestInternal(
|
||||
signed_provisioning_msg.set_message(serialized_message);
|
||||
signed_provisioning_msg.set_signature(request_signature);
|
||||
signed_provisioning_msg.set_provisioning_type(GetProvisioningType());
|
||||
if (core_message.empty()) {
|
||||
// OEMCrypto does not support core messages.
|
||||
supports_core_messages_ = false;
|
||||
} else {
|
||||
signed_provisioning_msg.set_oemcrypto_core_message(core_message);
|
||||
}
|
||||
signed_provisioning_msg.set_oemcrypto_core_message(core_message);
|
||||
signed_provisioning_msg.set_protocol_version(
|
||||
SignedProvisioningMessage_ProvisioningProtocolVersion_VERSION_1_1);
|
||||
SignedProvisioningMessage::VERSION_1_1);
|
||||
|
||||
std::string serialized_request;
|
||||
signed_provisioning_msg.SerializeToString(&serialized_request);
|
||||
@@ -421,7 +404,7 @@ CdmResponseType CertificateProvisioning::GetProvisioning40RequestInternal(
|
||||
signed_provisioning_msg.mutable_message());
|
||||
signed_provisioning_msg.set_provisioning_type(GetProvisioningType());
|
||||
signed_provisioning_msg.set_protocol_version(
|
||||
SignedProvisioningMessage_ProvisioningProtocolVersion_VERSION_1_1);
|
||||
SignedProvisioningMessage::VERSION_1_1);
|
||||
|
||||
std::string serialized_request;
|
||||
signed_provisioning_msg.SerializeToString(&serialized_request);
|
||||
@@ -541,13 +524,13 @@ CdmResponseType CertificateProvisioning::HandleProvisioning40Response(
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* The response message consists of a device certificate and the device RSA key.
|
||||
* The device RSA key is stored in the T.E.E. The device certificate is stored
|
||||
* in the device.
|
||||
*
|
||||
* Returns NO_ERROR for success and CERT_PROVISIONING_RESPONSE_ERROR_? if fails.
|
||||
*/
|
||||
// The response message consists of a device certificate and the
|
||||
// wrapped device private key (either RSA or ECC). The wrapped device
|
||||
// private key is loaded into the TEE, unwrapped, verified and
|
||||
// re-wrapped. The device certificate and re-wrapped device private
|
||||
// key are stored on the device.
|
||||
//
|
||||
// Returns NO_ERROR for success and CERT_PROVISIONING_RESPONSE_ERROR_? if fails.
|
||||
CdmResponseType CertificateProvisioning::HandleProvisioningResponse(
|
||||
wvutil::FileSystem* file_system,
|
||||
const CdmProvisioningResponse& response_message, std::string* cert,
|
||||
@@ -597,30 +580,16 @@ CdmResponseType CertificateProvisioning::HandleProvisioningResponse(
|
||||
error = true;
|
||||
}
|
||||
|
||||
if (supports_core_messages() &&
|
||||
(!signed_response.has_oemcrypto_core_message() ||
|
||||
signed_response.oemcrypto_core_message().empty())) {
|
||||
if (!signed_response.has_oemcrypto_core_message()) {
|
||||
LOGE("Signed response does not have core message");
|
||||
error = true;
|
||||
} else if (!supports_core_messages() &&
|
||||
(signed_response.has_oemcrypto_core_message() &&
|
||||
!signed_response.oemcrypto_core_message().empty())) {
|
||||
const std::string& core_message = signed_response.oemcrypto_core_message();
|
||||
// This case should not occur. However, the CDM will let OEMCrypto
|
||||
// fail.
|
||||
LOGW(
|
||||
"Received unexpected core message in provisioning request: "
|
||||
"core_message_size = %zu",
|
||||
core_message.size());
|
||||
}
|
||||
|
||||
if (error) return CERT_PROVISIONING_RESPONSE_ERROR_3;
|
||||
|
||||
const std::string& signed_message = signed_response.message();
|
||||
const std::string& signature = signed_response.signature();
|
||||
const std::string core_message =
|
||||
supports_core_messages() ? signed_response.oemcrypto_core_message()
|
||||
: std::string();
|
||||
const std::string& core_message = signed_response.oemcrypto_core_message();
|
||||
|
||||
ProvisioningResponse provisioning_response;
|
||||
if (!provisioning_response.ParseFromString(signed_message)) {
|
||||
@@ -630,7 +599,7 @@ CdmResponseType CertificateProvisioning::HandleProvisioningResponse(
|
||||
|
||||
if (provisioning_response.has_status()) {
|
||||
if (provisioning_response.status() != ProvisioningResponse::NO_ERROR) {
|
||||
LOGE("Provisioning Response status: %d", provisioning_response.status());
|
||||
LOGE("Provisioning response status: %d", provisioning_response.status());
|
||||
}
|
||||
|
||||
switch (provisioning_response.status()) {
|
||||
@@ -699,7 +668,6 @@ CdmResponseType CertificateProvisioning::HandleProvisioningResponse(
|
||||
|
||||
// The certificate will be stored to the device as the final step in
|
||||
// the device provisioning process.
|
||||
|
||||
DeviceFiles handle(file_system);
|
||||
if (!handle.Init(security_level)) {
|
||||
LOGE("Failed to initialize DeviceFiles");
|
||||
@@ -785,7 +753,7 @@ bool CertificateProvisioning::ExtractDeviceInfo(
|
||||
DrmCertificate drm_certificate;
|
||||
if (!drm_certificate.ParseFromString(
|
||||
signed_drm_certificate.drm_certificate()) ||
|
||||
(drm_certificate.type() != video_widevine::DrmCertificate::DEVICE)) {
|
||||
(drm_certificate.type() != DrmCertificate::DEVICE)) {
|
||||
LOGE("Failed to parse DRM device certificate message");
|
||||
return false;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user