From 0cf99f685f2011fcd456a778c34c109f75badf7b Mon Sep 17 00:00:00 2001 From: Rahul Frias Date: Tue, 2 Mar 2021 15:39:23 -0800 Subject: [PATCH] Update drm_certificate.proto [ Merge of http://go/wvgerrit/118563 ] Sync with the latest version of drm_certificate.proto to add in certificate expiry time. Add in signed_drm_certificate.proto and remove messages from device_certificate.proto. SignedDrmDeviceCertificate and DrmDeviceCertificate are now named SignedDrmCertificate and DrmCertificate. This necessitated non-proto changes. Bug: 169740403 Test: WV unit/integration tests Change-Id: Ie5969ac7217a25eb075a41df59b77da2becd4545 --- .../cdm/core/src/certificate_provisioning.cpp | 37 ++++----- .../cdm/core/src/license_protocol.proto | 82 +++++++------------ .../cdm/core/src/service_certificate.cpp | 18 ++-- .../core/test/fake_provisioning_server.cpp | 6 +- libwvdrmengine/cdm/core/test/test_base.cpp | 4 +- 5 files changed, 62 insertions(+), 85 deletions(-) diff --git a/libwvdrmengine/cdm/core/src/certificate_provisioning.cpp b/libwvdrmengine/cdm/core/src/certificate_provisioning.cpp index a957ab95..fbff6d49 100644 --- a/libwvdrmengine/cdm/core/src/certificate_provisioning.cpp +++ b/libwvdrmengine/cdm/core/src/certificate_provisioning.cpp @@ -111,12 +111,12 @@ namespace wvcdm { // Protobuf generated classes. using video_widevine::ClientIdentification_ClientCapabilities; using video_widevine::ClientIdentification_NameValue; -using video_widevine::DrmDeviceCertificate; +using video_widevine::DrmCertificate; using video_widevine::EncryptedClientIdentification; using video_widevine::ProvisioningOptions; using video_widevine::ProvisioningRequest; using video_widevine::ProvisioningResponse; -using video_widevine::SignedDrmDeviceCertificate; +using video_widevine::SignedDrmCertificate; using video_widevine::SignedProvisioningMessage; using video_widevine:: SignedProvisioningMessage_ProvisioningProtocolVersion_VERSION_1_1; @@ -425,7 +425,7 @@ CdmResponseType CertificateProvisioning::HandleProvisioningResponse( const CdmSecurityLevel security_level = crypto_session_->GetSecurityLevel(); crypto_session_->Close(); - // This is the entire certificate (SignedDrmDeviceCertificate). + // This is the entire certificate (SignedDrmCertificate). const std::string& device_cert_data = provisioning_response.device_certificate(); @@ -436,12 +436,12 @@ CdmResponseType CertificateProvisioning::HandleProvisioningResponse( } // Need to parse cert for key type. - SignedDrmDeviceCertificate signed_device_cert; + SignedDrmCertificate signed_device_cert; if (!signed_device_cert.ParseFromString(device_cert_data)) { LOGE("Failed to parse signed DRM certificate"); return CERT_PROVISIONING_RESPONSE_ERROR_9; } - DrmDeviceCertificate device_cert; + DrmCertificate device_cert; if (!device_cert.ParseFromString(signed_device_cert.drm_certificate())) { LOGE("Failed to parse DRM certificate"); return CERT_PROVISIONING_RESPONSE_ERROR_9; @@ -451,12 +451,12 @@ CdmResponseType CertificateProvisioning::HandleProvisioningResponse( private_key.set_type(CryptoWrappedKey::kRsa); } else { switch (device_cert.algorithm()) { - case DrmDeviceCertificate::RSA: + case DrmCertificate::RSA: private_key.set_type(CryptoWrappedKey::kRsa); break; - case DrmDeviceCertificate::ECC_SECP256R1: - case DrmDeviceCertificate::ECC_SECP384R1: - case DrmDeviceCertificate::ECC_SECP521R1: + case DrmCertificate::ECC_SECP256R1: + case DrmCertificate::ECC_SECP384R1: + case DrmCertificate::ECC_SECP521R1: private_key.set_type(CryptoWrappedKey::kEcc); break; default: @@ -498,25 +498,24 @@ bool CertificateProvisioning::ExtractDeviceInfo( } // Get serial number and system ID from certificate - SignedDrmDeviceCertificate signed_drm_device_certificate; - if (!signed_drm_device_certificate.ParseFromString(device_certificate) || - !signed_drm_device_certificate.has_drm_certificate()) { + SignedDrmCertificate signed_drm_certificate; + if (!signed_drm_certificate.ParseFromString(device_certificate) || + !signed_drm_certificate.has_drm_certificate()) { LOGE("Failed to parse signed DRM device certificate"); return false; } - DrmDeviceCertificate drm_device_certificate; - if (!drm_device_certificate.ParseFromString( - signed_drm_device_certificate.drm_certificate()) || - (drm_device_certificate.type() != - video_widevine::DrmDeviceCertificate::DRM_USER_DEVICE)) { + DrmCertificate drm_certificate; + if (!drm_certificate.ParseFromString( + signed_drm_certificate.drm_certificate()) || + (drm_certificate.type() != video_widevine::DrmCertificate::DEVICE)) { LOGE("Failed to parse DRM device certificate message"); return false; } if (serial_number != nullptr) { - *serial_number = drm_device_certificate.serial_number(); + *serial_number = drm_certificate.serial_number(); } if (system_id != nullptr) { - *system_id = drm_device_certificate.system_id(); + *system_id = drm_certificate.system_id(); } return true; } diff --git a/libwvdrmengine/cdm/core/src/license_protocol.proto b/libwvdrmengine/cdm/core/src/license_protocol.proto index cf789287..eaf2a45e 100644 --- a/libwvdrmengine/cdm/core/src/license_protocol.proto +++ b/libwvdrmengine/cdm/core/src/license_protocol.proto @@ -804,12 +804,18 @@ message EncryptedClientIdentification { } // ---------------------------------------------------------------------------- -// Source of truth: drm_certificate.proto -// Formally: device_certificate.proto (of wv_drm_sdk) +// drm_certificate.proto // ---------------------------------------------------------------------------- // Description of section: -// Device certificate and certificate status list format definitions. - +// Definition of the root of trust identifier proto. The proto message contains +// the EC-IES encrypted identifier (e.g. keybox unique id) for a device and +// an associated hash. These can be used by Widevine to identify the root of +// trust that was used to acquire a DRM certificate. +// +// In addition to the encrypted part and the hash, the proto contains the +// version of the root of trust id which implies the EC key algorithm that was +// used. +// Next id: 5 message RootOfTrustId { // The version specifies the EC algorithm that was used to generate the // root of trust id. @@ -840,13 +846,12 @@ message RootOfTrustId { // DRM certificate definition for user devices, intermediate, service, and root // certificates. -// DrmDeviceCertificate tracks the provisioning service's DrmCertificate, -// only including fields that are required by CDM devices. -message DrmDeviceCertificate { - enum CertificateType { - ROOT = 0; - DRM_INTERMEDIATE = 1; - DRM_USER_DEVICE = 2; +// Next id: 13 +message DrmCertificate { + enum Type { + ROOT = 0; // ProtoBestPractices: ignore. + DEVICE_MODEL = 1; + DEVICE = 2; SERVICE = 3; PROVISIONER = 4; } @@ -877,12 +882,16 @@ message DrmDeviceCertificate { } // Type of certificate. Required. - optional CertificateType type = 1; + optional Type type = 1; // 128-bit globally unique serial number of certificate. // Value is 0 for root certificate. Required. optional bytes serial_number = 2; // POSIX time, in seconds, when the certificate was created. Required. optional uint32 creation_time_seconds = 3; + // POSIX time, in seconds, when the certificate should expire. Value of zero + // denotes indefinite expiry time. For more information on limited lifespan + // DRM certificates see (go/limited-lifespan-drm-certificates). + optional uint32 expiration_time_seconds = 12; // Device public key. PKCS#1 ASN.1 DER-encoded. Required. optional bytes public_key = 4; // Widevine system ID for the device. Required for intermediate and @@ -917,50 +926,21 @@ message DrmDeviceCertificate { optional EncryptionKey encryption_key = 11; } -// DeviceCertificate signed with intermediate or root certificate private key. -message SignedDrmDeviceCertificate { +// ---------------------------------------------------------------------------- +// signed_drm_certificate.proto +// ---------------------------------------------------------------------------- +// Description of section: +// DrmCertificate signed by a higher (CA) DRM certificate. +message SignedDrmCertificate { // Serialized certificate. Required. optional bytes drm_certificate = 1; // Signature of certificate. Signed with root or intermediate // certificate specified below. Required. optional bytes signature = 2; - // SignedDrmDeviceCertificate used to sign this certificate. - optional SignedDrmDeviceCertificate signer = 3; -} - -// Contains the status of the root or an intermediate DeviceCertificate. -message DeviceCertificateStatus { - enum Status { - VALID = 0; - REVOKED = 1; - }; - - // Serial number of the intermediate DrmDeviceCertificate to which this - // message refers. Required. - optional bytes drm_serial_number = 1; - // Status of the certificate. Optional. - optional Status status = 2 [default = VALID]; - // Device model information about the device to which the intermediate - // certificate(s) correspond. - optional ProvisionedDeviceInfo device_info = 4; -} - -// List of DeviceCertificateStatus. Used to propagate certificate revocation -// status and device information. -message DeviceCertificateStatusList { - // POSIX time, in seconds, when the list was created. Required. - optional uint32 creation_time_seconds = 1; - // DeviceCertificateStatus for each system ID. - repeated DeviceCertificateStatus certificate_status = 2; -} - -// Signed CertificateStatusList -message SignedCertificateStatusList { - // Serialized DeviceCertificateStatusList. Required. - optional bytes certificate_status_list = 1; - // Signature of certificate_status_list. Signed with root certificate private - // key using RSASSA-PSS. Required. - optional bytes signature = 2; + // SignedDrmCertificate used to sign this certificate. + optional SignedDrmCertificate signer = 3; + // Optional field that indicates the hash algorithm used in signature scheme. + optional HashAlgorithmProto hash_algorithm = 4; } // ---------------------------------------------------------------------------- diff --git a/libwvdrmengine/cdm/core/src/service_certificate.cpp b/libwvdrmengine/cdm/core/src/service_certificate.cpp index 28bba818..47625a7a 100644 --- a/libwvdrmengine/cdm/core/src/service_certificate.cpp +++ b/libwvdrmengine/cdm/core/src/service_certificate.cpp @@ -129,10 +129,10 @@ namespace wvcdm { // Protobuf generated classes. using video_widevine::ClientIdentification; -using video_widevine::DrmDeviceCertificate; +using video_widevine::DrmCertificate; using video_widevine::EncryptedClientIdentification; using video_widevine::LicenseError; -using video_widevine::SignedDrmDeviceCertificate; +using video_widevine::SignedDrmCertificate; using video_widevine::SignedMessage; CdmResponseType ServiceCertificate::Init(const std::string& certificate) { @@ -140,12 +140,12 @@ CdmResponseType ServiceCertificate::Init(const std::string& certificate) { sizeof(kRootCertForProd)); // Load root cert public key. Don't bother verifying it. - SignedDrmDeviceCertificate signed_root_cert; + SignedDrmCertificate signed_root_cert; if (!signed_root_cert.ParseFromString(root_cert_str)) { LOGE("Failed to deserialize signed root certificate"); return DEVICE_CERTIFICATE_ERROR_1; } - DrmDeviceCertificate root_cert; + DrmCertificate root_cert; if (!root_cert.ParseFromString(signed_root_cert.drm_certificate())) { LOGE("Failed to deserialize root certificate"); return DEVICE_CERTIFICATE_ERROR_1; @@ -158,7 +158,7 @@ CdmResponseType ServiceCertificate::Init(const std::string& certificate) { // Load the provided service certificate. // First, parse it and verify its signature. - SignedDrmDeviceCertificate signed_service_cert; + SignedDrmCertificate signed_service_cert; if (!signed_service_cert.ParseFromString(certificate)) { LOGE("Failed to parse signed service certificate"); return DEVICE_CERTIFICATE_ERROR_2; @@ -174,19 +174,17 @@ CdmResponseType ServiceCertificate::Init(const std::string& certificate) { } #endif - DrmDeviceCertificate service_cert; + DrmCertificate service_cert; if (!service_cert.ParseFromString(signed_service_cert.drm_certificate())) { LOGE("Failed to parse service certificate"); return DEVICE_CERTIFICATE_ERROR_2; } - if (service_cert.type() != - video_widevine::DrmDeviceCertificate_CertificateType_SERVICE) { + if (service_cert.type() != video_widevine::DrmCertificate_Type_SERVICE) { LOGE( "DRM device certificate type is not a service certificate: " "type = %d, expected_type = %d", static_cast(service_cert.type()), - static_cast( - video_widevine::DrmDeviceCertificate_CertificateType_SERVICE)); + static_cast(video_widevine::DrmCertificate_Type_SERVICE)); return DEVICE_CERTIFICATE_ERROR_3; } diff --git a/libwvdrmengine/cdm/core/test/fake_provisioning_server.cpp b/libwvdrmengine/cdm/core/test/fake_provisioning_server.cpp index ab0008b3..1877f4bb 100644 --- a/libwvdrmengine/cdm/core/test/fake_provisioning_server.cpp +++ b/libwvdrmengine/cdm/core/test/fake_provisioning_server.cpp @@ -221,8 +221,8 @@ FakeProvisioningServer::FakeProvisioningServer() { // Generate a service certificate that can convince the CDM we are a real // provisioning server. it only works if the CDM is compiled with the symbol // ACCEPT_TEST_CERT defined. - video_widevine::DrmDeviceCertificate cert; - cert.set_type(video_widevine::DrmDeviceCertificate_CertificateType_SERVICE); + video_widevine::DrmCertificate cert; + cert.set_type(video_widevine::DrmCertificate_Type_SERVICE); cert.set_public_key(kPublicFakeServiceCert); cert.set_serial_number("Serial Number 007"); @@ -231,7 +231,7 @@ FakeProvisioningServer::FakeProvisioningServer() { std::string serialized_cert; cert.SerializeToString(&serialized_cert); - video_widevine::SignedDrmDeviceCertificate signed_cert; + video_widevine::SignedDrmCertificate signed_cert; signed_cert.set_drm_certificate(serialized_cert); signed_cert.SerializeToString(&service_certificate_); } diff --git a/libwvdrmengine/cdm/core/test/test_base.cpp b/libwvdrmengine/cdm/core/test/test_base.cpp index 8f5dc172..3f4117f6 100644 --- a/libwvdrmengine/cdm/core/test/test_base.cpp +++ b/libwvdrmengine/cdm/core/test/test_base.cpp @@ -572,9 +572,9 @@ void TestLicenseHolder::CreateDefaultLicense() { // Extract the RSA key from the DRM certificate. std::string token = client_id.token(); - video_widevine::SignedDrmDeviceCertificate signed_drm_cert; + video_widevine::SignedDrmCertificate signed_drm_cert; EXPECT_TRUE(signed_drm_cert.ParseFromString(token)); - video_widevine::DrmDeviceCertificate drm_cert; + video_widevine::DrmCertificate drm_cert; EXPECT_TRUE(drm_cert.ParseFromString(signed_drm_cert.drm_certificate())); EXPECT_TRUE(rsa_key_.Init(drm_cert.public_key())); EXPECT_TRUE(rsa_key_.VerifySignature(signed_message.msg(),