diff --git a/libwvdrmengine/cdm/core/include/crypto_session.h b/libwvdrmengine/cdm/core/include/crypto_session.h index b9a56391..0401cbfc 100644 --- a/libwvdrmengine/cdm/core/include/crypto_session.h +++ b/libwvdrmengine/cdm/core/include/crypto_session.h @@ -13,6 +13,7 @@ #include #include "OEMCryptoCENC.h" +#include "crypto_wrapped_key.h" #include "disallow_copy_and_assign.h" #include "key_session.h" #include "metrics_collections.h" @@ -54,6 +55,9 @@ class CryptoSession { bool rsa_2048_bit; bool rsa_3072_bit; bool rsa_cast; + bool ecc_secp256r1; + bool ecc_secp384r1; + bool ecc_secp521r1; }; // Creates an instance of CryptoSession with the given |crypto_metrics|. @@ -167,7 +171,7 @@ class CryptoSession { const std::string& signature, std::string* wrapped_private_key); virtual CdmResponseType LoadCertificatePrivateKey( - const std::string& wrapped_key); + const CryptoWrappedKey& private_key); // Media data path virtual CdmResponseType Decrypt(const CdmDecryptionParametersV16& params); diff --git a/libwvdrmengine/cdm/core/include/crypto_wrapped_key.h b/libwvdrmengine/cdm/core/include/crypto_wrapped_key.h new file mode 100644 index 00000000..bf947bb9 --- /dev/null +++ b/libwvdrmengine/cdm/core/include/crypto_wrapped_key.h @@ -0,0 +1,52 @@ +// Copyright 2020 Google LLC. All Rights Reserved. This file and proprietary +// source code may only be used and distributed under the Widevine License +// Agreement. +#ifndef WVCDM_CORE_CRYPTO_WRAPPED_KEY_H_ +#define WVCDM_CORE_CRYPTO_WRAPPED_KEY_H_ + +#include + +namespace wvcdm { + +// Represents OEMCrypto's wrapped private DRM key. As of v16, it is +// possible for OEMCrypto to support ECC-based DRM certificates. The +// format of the wrapped key is vendor specific; however, the API +// requires that the CDM track whether the wrapped key is RSA or ECC. +class CryptoWrappedKey { + public: + enum Type : int32_t { kUninitialized = 0, kRsa = 1, kEcc = 2 }; + CryptoWrappedKey() {} + CryptoWrappedKey(Type type, const std::string& key) + : type_(type), key_(key) {} + + Type type() const { return type_; } + void set_type(Type type) { type_ = type; } + + const std::string& key() const { return key_; } + // Mutable reference getter for passing to OMECrypto. + std::string& key() { return key_; } + void set_key(const std::string& key) { key_ = key; } + + void Clear() { + type_ = kUninitialized; + key_.clear(); + } + // A valid key must have a known key type and have key data. + bool IsValid() const { return type_ != kUninitialized && !key_.empty(); } + // Equality operator is for testing only. Real keys may have + // different meta data but the same logical key. + bool operator==(const CryptoWrappedKey& other) const { + return type_ == other.type_ && key_ == other.key_; + } + + private: + // DRM key type of the wrapped key. For wrapped keys which the type + // of key is unknown, assume it to be RSA. + Type type_ = kUninitialized; + // Vendor-specific wrapped DRM key. + std::string key_; +}; // class CryptoWrappedKey + +} // namespace wvcdm + +#endif // WVCDM_CORE_CRYPTO_WRAPPED_KEY_H_ diff --git a/libwvdrmengine/cdm/core/include/device_files.h b/libwvdrmengine/cdm/core/include/device_files.h index 6add2dd0..b760d453 100644 --- a/libwvdrmengine/cdm/core/include/device_files.h +++ b/libwvdrmengine/cdm/core/include/device_files.h @@ -9,6 +9,7 @@ #include #include +#include "crypto_wrapped_key.h" #include "device_files.pb.h" #include "disallow_copy_and_assign.h" #include "platform.h" @@ -98,10 +99,10 @@ class DeviceFiles { // ATSC certificates are installed by the ATSC service. They can be read // and used but not written or removed. virtual bool StoreCertificate(const std::string& certificate, - const std::string& wrapped_private_key); + const CryptoWrappedKey& private_key); virtual bool RetrieveCertificate(bool atsc_mode_enabled, std::string* certificate, - std::string* wrapped_private_key, + CryptoWrappedKey* private_key, std::string* serial_number, uint32_t* system_id); virtual bool HasCertificate(bool atsc_mode_enabled); @@ -269,6 +270,7 @@ class DeviceFiles { FRIEND_TEST(DeviceFilesSecurityLevelTest, SecurityLevel); FRIEND_TEST(DeviceCertificateTest, StoreCertificate); FRIEND_TEST(DeviceCertificateTest, ReadCertificate); + FRIEND_TEST(DeviceCertificateTest, ReadCertificateWithoutKeyType); FRIEND_TEST(DeviceCertificateTest, HasCertificate); FRIEND_TEST(DeviceFilesStoreTest, StoreLicense); FRIEND_TEST(DeviceFilesHlsAttributesTest, Delete); diff --git a/libwvdrmengine/cdm/core/include/wv_cdm_types.h b/libwvdrmengine/cdm/core/include/wv_cdm_types.h index 7154ee7e..acad7d0f 100644 --- a/libwvdrmengine/cdm/core/include/wv_cdm_types.h +++ b/libwvdrmengine/cdm/core/include/wv_cdm_types.h @@ -417,6 +417,7 @@ enum CdmResponseType : int32_t { RESTORE_OFFLINE_LICENSE_ERROR_3 = 362, NO_SRM_VERSION = 363, SESSION_NOT_FOUND_23 = 364, + CERT_PROVISIONING_RESPONSE_ERROR_9 = 365, // Don't forget to add new values to // * core/test/test_printers.cpp. // * android/include/mapErrors-inl.h diff --git a/libwvdrmengine/cdm/core/src/cdm_session.cpp b/libwvdrmengine/cdm/core/src/cdm_session.cpp index 6d6720e6..f993f5de 100644 --- a/libwvdrmengine/cdm/core/src/cdm_session.cpp +++ b/libwvdrmengine/cdm/core/src/cdm_session.cpp @@ -13,6 +13,7 @@ #include "cdm_engine.h" #include "clock.h" +#include "crypto_wrapped_key.h" #include "file_store.h" #include "log.h" #include "properties.h" @@ -170,18 +171,18 @@ CdmResponseType CdmSession::Init(CdmClientPropertySet* cdm_client_property_set, // License server client ID token is a stored certificate. Stage it or // indicate that provisioning is needed. Get token from stored certificate - std::string wrapped_key; + CryptoWrappedKey private_key; bool atsc_mode_enabled = false; if (cdm_client_property_set != nullptr) atsc_mode_enabled = cdm_client_property_set->use_atsc_mode(); if (!file_handle_->RetrieveCertificate(atsc_mode_enabled, &client_token, - &wrapped_key, &serial_number, + &private_key, &serial_number, nullptr)) { return NEED_PROVISIONING; } CdmResponseType load_cert_sts; M_TIME( - load_cert_sts = crypto_session_->LoadCertificatePrivateKey(wrapped_key), + load_cert_sts = crypto_session_->LoadCertificatePrivateKey(private_key), crypto_metrics_, crypto_session_load_certificate_private_key_, load_cert_sts); switch (load_cert_sts) { @@ -202,9 +203,12 @@ CdmResponseType CdmSession::Init(CdmClientPropertySet* cdm_client_property_set, if (forced_session_id) { key_set_id_ = *forced_session_id; } else { - bool ok = GenerateKeySetId(atsc_mode_enabled, &key_set_id_); - (void)ok; // ok is now used when assertions are turned off. + const bool ok = GenerateKeySetId(atsc_mode_enabled, &key_set_id_); assert(ok); + if (!ok) { + // Assertions may be disabled + LOGE("Could not generate keyset ID"); + } } session_id_ = diff --git a/libwvdrmengine/cdm/core/src/certificate_provisioning.cpp b/libwvdrmengine/cdm/core/src/certificate_provisioning.cpp index 68a6ba02..84741bca 100644 --- a/libwvdrmengine/cdm/core/src/certificate_provisioning.cpp +++ b/libwvdrmengine/cdm/core/src/certificate_provisioning.cpp @@ -5,6 +5,7 @@ #include "certificate_provisioning.h" #include "client_identification.h" +#include "crypto_wrapped_key.h" #include "device_files.h" #include "file_store.h" #include "license_protocol.pb.h" @@ -333,7 +334,8 @@ CdmResponseType CertificateProvisioning::HandleProvisioningResponse( } else { // The response is base64 encoded in a JSON wrapper. // Extract it and decode it. On error return an empty string. - bool result = ExtractAndDecodeSignedMessage(response_message, &response); + const bool result = + ExtractAndDecodeSignedMessage(response_message, &response); if (!result || response.empty()) { LOGE("Provisioning response message is an invalid JSON/base64 string"); return CERT_PROVISIONING_RESPONSE_ERROR_1; @@ -391,9 +393,9 @@ CdmResponseType CertificateProvisioning::HandleProvisioningResponse( return CERT_PROVISIONING_RESPONSE_ERROR_4; } - std::string wrapped_private_key; + CryptoWrappedKey private_key; const CdmResponseType status = crypto_session_->LoadProvisioning( - signed_message, core_message, signature, &wrapped_private_key); + signed_message, core_message, signature, &private_key.key()); if (status != NO_ERROR) { LOGE("LoadProvisioning failed: status = %d", static_cast(status)); @@ -404,15 +406,46 @@ CdmResponseType CertificateProvisioning::HandleProvisioningResponse( crypto_session_->Close(); // This is the entire certificate (SignedDrmDeviceCertificate). - const std::string& device_certificate = + const std::string& device_cert_data = provisioning_response.device_certificate(); if (cert_type_ == kCertificateX509) { - *cert = device_certificate; - *wrapped_key = wrapped_private_key; + *cert = device_cert_data; + *wrapped_key = private_key.key(); return NO_ERROR; } + // Need to parse cert for key type. + SignedDrmDeviceCertificate 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; + if (!device_cert.ParseFromString(signed_device_cert.drm_certificate())) { + LOGE("Failed to parse DRM certificate"); + return CERT_PROVISIONING_RESPONSE_ERROR_9; + } + if (!device_cert.has_algorithm()) { + LOGW("DRM certificate does not specify algorithm type, assuming RSA"); + private_key.set_type(CryptoWrappedKey::kRsa); + } else { + switch (device_cert.algorithm()) { + case DrmDeviceCertificate::RSA: + private_key.set_type(CryptoWrappedKey::kRsa); + break; + case DrmDeviceCertificate::ECC_SECP256R1: + case DrmDeviceCertificate::ECC_SECP384R1: + case DrmDeviceCertificate::ECC_SECP521R1: + private_key.set_type(CryptoWrappedKey::kEcc); + break; + default: + LOGE("Unknown DRM key type: algorithm = %d", + static_cast(device_cert.algorithm())); + return CERT_PROVISIONING_RESPONSE_ERROR_9; + } + } + // The certificate will be stored to the device as the final step in // the device provisioning process. @@ -421,7 +454,7 @@ CdmResponseType CertificateProvisioning::HandleProvisioningResponse( LOGE("Failed to initialize DeviceFiles"); return CERT_PROVISIONING_RESPONSE_ERROR_7; } - if (!handle.StoreCertificate(device_certificate, wrapped_private_key)) { + if (!handle.StoreCertificate(device_cert_data, private_key)) { LOGE("Failed to store provisioning certificate"); return CERT_PROVISIONING_RESPONSE_ERROR_8; } diff --git a/libwvdrmengine/cdm/core/src/client_identification.cpp b/libwvdrmengine/cdm/core/src/client_identification.cpp index a3404297..519fdf39 100644 --- a/libwvdrmengine/cdm/core/src/client_identification.cpp +++ b/libwvdrmengine/cdm/core/src/client_identification.cpp @@ -56,7 +56,9 @@ bool IsPropertyKeyReserved(const std::string& prop_name) { } // namespace // Protobuf generated classes. -using video_widevine::ClientIdentification_ClientCapabilities; +using ClientCapabilities = + video_widevine::ClientIdentification::ClientCapabilities; +using AnalogOutputCapabilities = ClientCapabilities::AnalogOutputCapabilities; using video_widevine::ClientIdentification_NameValue; using video_widevine::EncryptedClientIdentification; using video_widevine::ProvisioningOptions; @@ -187,7 +189,7 @@ CdmResponseType ClientIdentification::Prepare( client_id->set_provider_client_token(provider_client_token); } - ClientIdentification_ClientCapabilities* client_capabilities = + ClientCapabilities* client_capabilities = client_id->mutable_client_capabilities(); client_capabilities->set_client_token(true); @@ -214,38 +216,31 @@ CdmResponseType ClientIdentification::Prepare( switch (max_version) { case HDCP_NONE: client_capabilities->set_max_hdcp_version( - video_widevine:: - ClientIdentification_ClientCapabilities_HdcpVersion_HDCP_NONE); + ClientCapabilities::HDCP_NONE); break; case HDCP_V1: client_capabilities->set_max_hdcp_version( - video_widevine:: - ClientIdentification_ClientCapabilities_HdcpVersion_HDCP_V1); + ClientCapabilities::HDCP_V1); break; case HDCP_V2: client_capabilities->set_max_hdcp_version( - video_widevine:: - ClientIdentification_ClientCapabilities_HdcpVersion_HDCP_V2); + ClientCapabilities::HDCP_V2); break; case HDCP_V2_1: client_capabilities->set_max_hdcp_version( - video_widevine:: - ClientIdentification_ClientCapabilities_HdcpVersion_HDCP_V2_1); + ClientCapabilities::HDCP_V2_1); break; case HDCP_V2_2: client_capabilities->set_max_hdcp_version( - video_widevine:: - ClientIdentification_ClientCapabilities_HdcpVersion_HDCP_V2_2); + ClientCapabilities::HDCP_V2_2); break; case HDCP_V2_3: client_capabilities->set_max_hdcp_version( - video_widevine:: - ClientIdentification_ClientCapabilities_HdcpVersion_HDCP_V2_3); + ClientCapabilities::HDCP_V2_3); break; case HDCP_NO_DIGITAL_OUTPUT: client_capabilities->set_max_hdcp_version( - video_widevine:: - ClientIdentification_ClientCapabilities_HdcpVersion_HDCP_NO_DIGITAL_OUTPUT); + ClientCapabilities::HDCP_NO_DIGITAL_OUTPUT); break; default: LOGW("Unexpected HDCP max capability version: max_version = %d", @@ -258,13 +253,23 @@ CdmResponseType ClientIdentification::Prepare( if (crypto_session_->GetSupportedCertificateTypes(&supported_certs)) { if (supported_certs.rsa_2048_bit) { client_capabilities->add_supported_certificate_key_type( - video_widevine:: - ClientIdentification_ClientCapabilities_CertificateKeyType_RSA_2048); + ClientCapabilities::RSA_2048); } if (supported_certs.rsa_3072_bit) { client_capabilities->add_supported_certificate_key_type( - video_widevine:: - ClientIdentification_ClientCapabilities_CertificateKeyType_RSA_3072); + ClientCapabilities::RSA_3072); + } + if (supported_certs.ecc_secp256r1) { + client_capabilities->add_supported_certificate_key_type( + ClientCapabilities::ECC_SECP256R1); + } + if (supported_certs.ecc_secp384r1) { + client_capabilities->add_supported_certificate_key_type( + ClientCapabilities::ECC_SECP384R1); + } + if (supported_certs.ecc_secp521r1) { + client_capabilities->add_supported_certificate_key_type( + ClientCapabilities::ECC_SECP521R1); } } @@ -280,33 +285,27 @@ CdmResponseType ClientIdentification::Prepare( bool can_support_cgms_a; if (crypto_session_->GetAnalogOutputCapabilities( &can_support_output, &can_disable_output, &can_support_cgms_a)) { - video_widevine::ClientIdentification_ClientCapabilities_AnalogOutputCapabilities - capabilities = video_widevine:: - ClientIdentification_ClientCapabilities_AnalogOutputCapabilities_ANALOG_OUTPUT_NONE; + AnalogOutputCapabilities capabilities = + ClientCapabilities::ANALOG_OUTPUT_NONE; if (can_support_output) { if (can_support_cgms_a) { - capabilities = video_widevine:: - ClientIdentification_ClientCapabilities_AnalogOutputCapabilities_ANALOG_OUTPUT_SUPPORTS_CGMS_A; + capabilities = ClientCapabilities::ANALOG_OUTPUT_SUPPORTS_CGMS_A; } else { - capabilities = video_widevine:: - ClientIdentification_ClientCapabilities_AnalogOutputCapabilities_ANALOG_OUTPUT_SUPPORTED; + capabilities = ClientCapabilities::ANALOG_OUTPUT_SUPPORTED; } } client_capabilities->set_analog_output_capabilities(capabilities); client_capabilities->set_can_disable_analog_output(can_disable_output); } else { client_capabilities->set_analog_output_capabilities( - video_widevine:: - ClientIdentification_ClientCapabilities_AnalogOutputCapabilities_ANALOG_OUTPUT_UNKNOWN); + ClientCapabilities::ANALOG_OUTPUT_UNKNOWN); } - uint32_t version, tier; - if (crypto_session_->GetApiVersion(&version)) { - if (version >= OEM_CRYPTO_API_VERSION_SUPPORTS_RESOURCE_RATING_TIER) { - if (crypto_session_->GetResourceRatingTier(&tier)) { - client_capabilities->set_resource_rating_tier(tier); - } + if (api_version >= OEM_CRYPTO_API_VERSION_SUPPORTS_RESOURCE_RATING_TIER) { + uint32_t tier; + if (crypto_session_->GetResourceRatingTier(&tier)) { + client_capabilities->set_resource_rating_tier(tier); } } diff --git a/libwvdrmengine/cdm/core/src/crypto_session.cpp b/libwvdrmengine/cdm/core/src/crypto_session.cpp index 43509f23..45a9baed 100644 --- a/libwvdrmengine/cdm/core/src/crypto_session.cpp +++ b/libwvdrmengine/cdm/core/src/crypto_session.cpp @@ -1271,28 +1271,33 @@ CdmResponseType CryptoSession::LoadEntitledContentKeys( } CdmResponseType CryptoSession::LoadCertificatePrivateKey( - const std::string& wrapped_key) { + const CryptoWrappedKey& private_key) { // TODO(b/141655126): Getting the OEM Cert no longer loads the private key. // Call OEMCrypto_GetOEMPublicCertificate before OEMCrypto_LoadDRMPrivateKey // so it caches the OEMCrypto Public Key and then throw away result std::string temp_buffer(CERTIFICATE_DATA_SIZE, '\0'); size_t buf_size = temp_buffer.size(); uint8_t* buf = reinterpret_cast(&temp_buffer[0]); - OEMCryptoResult sts; - WithOecSessionLock( + OEMCryptoResult sts = WithOecSessionLock( "LoadCertificatePrivateKey() calling OEMCrypto_GetOEMPublicCertificate", [&] { - sts = OEMCrypto_GetOEMPublicCertificate(buf, &buf_size, - requested_security_level_); + return OEMCrypto_GetOEMPublicCertificate(buf, &buf_size, + requested_security_level_); }); metrics_->oemcrypto_get_oem_public_certificate_.Increment(sts); - LOGV("Loading device RSA key: id = %u", oec_session_id_); + const OEMCrypto_PrivateKeyType key_type = + (private_key.type() == CryptoWrappedKey::kEcc) + ? OEMCrypto_ECC_Private_Key + : OEMCrypto_RSA_Private_Key; + const std::string& wrapped_key = private_key.key(); + + LOGV("Loading device DRM key: id = %u", oec_session_id_); // TODO(b/140813486): determine if cert is RSA or ECC. WithOecSessionLock( "LoadCertificatePrivateKey() calling OEMCrypto_LoadDRMPrivateKey()", [&] { M_TIME(sts = OEMCrypto_LoadDRMPrivateKey( - oec_session_id_, OEMCrypto_RSA_Private_Key, + oec_session_id_, key_type, reinterpret_cast(wrapped_key.data()), wrapped_key.size()), metrics_, oemcrypto_load_device_rsa_key_, sts); @@ -1888,14 +1893,16 @@ bool CryptoSession::GetSupportedCertificateTypes( LOGV("Getting supported certificate types: id = %u", oec_session_id_); RETURN_IF_UNINITIALIZED(false); RETURN_IF_NULL(support, false); - - uint32_t oec_support; - WithOecReadLock("GetSupportedCertificateTypes", [&] { - oec_support = OEMCrypto_SupportedCertificates(requested_security_level_); - }); + const uint32_t oec_support = + WithOecReadLock("GetSupportedCertificateTypes", [&] { + return OEMCrypto_SupportedCertificates(requested_security_level_); + }); support->rsa_2048_bit = oec_support & OEMCrypto_Supports_RSA_2048bit; support->rsa_3072_bit = oec_support & OEMCrypto_Supports_RSA_3072bit; support->rsa_cast = oec_support & OEMCrypto_Supports_RSA_CAST; + support->ecc_secp256r1 = oec_support & OEMCrypto_Supports_ECC_secp256r1; + support->ecc_secp384r1 = oec_support & OEMCrypto_Supports_ECC_secp384r1; + support->ecc_secp521r1 = oec_support & OEMCrypto_Supports_ECC_secp521r1; return true; } diff --git a/libwvdrmengine/cdm/core/src/device_files.cpp b/libwvdrmengine/cdm/core/src/device_files.cpp index 0385cdbd..7c21b8e4 100644 --- a/libwvdrmengine/cdm/core/src/device_files.cpp +++ b/libwvdrmengine/cdm/core/src/device_files.cpp @@ -112,8 +112,16 @@ bool DeviceFiles::Init(CdmSecurityLevel security_level) { } bool DeviceFiles::StoreCertificate(const std::string& certificate, - const std::string& wrapped_private_key) { + const CryptoWrappedKey& private_key) { RETURN_FALSE_IF_UNINITIALIZED(); + if (certificate.empty()) { + LOGE("Missing certificate information"); + return false; + } + if (!private_key.IsValid()) { + LOGE("Private key is invalid"); + return false; + } // Fill in file information video_widevine_client::sdk::File file; @@ -123,7 +131,19 @@ bool DeviceFiles::StoreCertificate(const std::string& certificate, DeviceCertificate* device_certificate = file.mutable_device_certificate(); device_certificate->set_certificate(certificate); - device_certificate->set_wrapped_private_key(wrapped_private_key); + device_certificate->set_wrapped_private_key(private_key.key()); + switch (private_key.type()) { + case CryptoWrappedKey::kRsa: + device_certificate->set_key_type(DeviceCertificate::RSA); + break; + case CryptoWrappedKey::kEcc: + device_certificate->set_key_type(DeviceCertificate::ECC); + break; + case CryptoWrappedKey::kUninitialized: // Suppress compiler warnings. + default: + LOGE("Unexpected key type"); + return false; + } std::string serialized_file; file.SerializeToString(&serialized_file); @@ -134,10 +154,12 @@ bool DeviceFiles::StoreCertificate(const std::string& certificate, bool DeviceFiles::RetrieveCertificate(bool atsc_mode_enabled, std::string* certificate, - std::string* wrapped_private_key, + CryptoWrappedKey* private_key, std::string* serial_number, uint32_t* system_id) { RETURN_FALSE_IF_UNINITIALIZED(); + RETURN_FALSE_IF_NULL(certificate); + RETURN_FALSE_IF_NULL(private_key); if (!HasCertificate(atsc_mode_enabled)) { return false; @@ -169,7 +191,30 @@ bool DeviceFiles::RetrieveCertificate(bool atsc_mode_enabled, DeviceCertificate device_certificate = file.device_certificate(); *certificate = device_certificate.certificate(); - *wrapped_private_key = device_certificate.wrapped_private_key(); + private_key->Clear(); + private_key->set_key(device_certificate.wrapped_private_key()); + if (device_certificate.has_key_type()) { + const DeviceCertificate::PrivateKeyType key_type = + device_certificate.key_type(); + switch (key_type) { + case DeviceCertificate::RSA: + private_key->set_type(CryptoWrappedKey::kRsa); + break; + case DeviceCertificate::ECC: + private_key->set_type(CryptoWrappedKey::kEcc); + break; + default: + LOGW("Unknown DRM key type, defaulting to RSA: type = %d", key_type); + private_key->set_type(CryptoWrappedKey::kRsa); + break; + } + } else { + // Possible that device certificate is from V15, in this case, the + // only supported key of at that time was RSA. + LOGD("No key type info, assuming RSA"); + private_key->set_type(CryptoWrappedKey::kRsa); + } + return CertificateProvisioning::ExtractDeviceInfo( device_certificate.certificate(), serial_number, system_id); } diff --git a/libwvdrmengine/cdm/core/src/device_files.proto b/libwvdrmengine/cdm/core/src/device_files.proto index 21eafe42..3d743525 100644 --- a/libwvdrmengine/cdm/core/src/device_files.proto +++ b/libwvdrmengine/cdm/core/src/device_files.proto @@ -21,8 +21,13 @@ message NameValue { } message DeviceCertificate { + enum PrivateKeyType { + RSA = 0; + ECC = 1; + } optional bytes certificate = 1; optional bytes wrapped_private_key = 2; + optional PrivateKeyType key_type = 3 [default = RSA]; } message License { diff --git a/libwvdrmengine/cdm/core/test/cdm_session_unittest.cpp b/libwvdrmengine/cdm/core/test/cdm_session_unittest.cpp index d3c32dbc..1822faee 100644 --- a/libwvdrmengine/cdm/core/test/cdm_session_unittest.cpp +++ b/libwvdrmengine/cdm/core/test/cdm_session_unittest.cpp @@ -9,6 +9,7 @@ #include "cdm_session.h" #include "crypto_key.h" +#include "crypto_wrapped_key.h" #include "properties.h" #include "service_certificate.h" #include "string_conversions.h" @@ -71,7 +72,7 @@ const std::string kToken = a2bs_hex( "8CD5A9DF6E3D3A99B806F6D60991358C5BE77117D4F3168F3348E9A048539F892F4D783152" "C7A8095224AA56B78C5CF7BD1AB1B179C0C0D11E3C3BAC84C141A00191321E3ACC17242E68" "3C"); -const std::string kWrappedKey = a2bs_hex( +const std::string kWrappedKeyData = a2bs_hex( "3B84252DD84F1A710365014A114507FFFA3DD404625D61D1EEC7C3A39D72CB8D9318ADE9DA" "05D69F9776DAFDA49A97BC30E84CA275925DFD98CA04F7DB23465103A224852192DE232902" "99FF82024F5CCA7716ACA9BE0B56348BA16B9E3136D73789C842CB2ECA4820DDAAF59CCB9B" @@ -108,14 +109,15 @@ const std::string kWrappedKey = a2bs_hex( "33EF70621A98184DDAB5E14BC971CF98CF6C91A37FFA83B00AD3BCABBAAB2DEF1C52F43003" "E74C92B44F9205D22262FB47948654229DE1920F8EDF96A19A88A1CA1552F8856FB4CBF83B" "AA3348419159D207F65FCE9C1A500C6818"); +const CryptoWrappedKey kWrappedKey = {CryptoWrappedKey::kRsa, kWrappedKeyData}; class MockDeviceFiles : public DeviceFiles { public: MockDeviceFiles() : DeviceFiles(nullptr) {} MOCK_METHOD1(Init, bool(CdmSecurityLevel)); - MOCK_METHOD5(RetrieveCertificate, - bool(bool, std::string*, std::string*, std::string*, uint32_t*)); + MOCK_METHOD5(RetrieveCertificate, bool(bool, std::string*, CryptoWrappedKey*, + std::string*, uint32_t*)); }; class MockUsageTableHeader : public UsageTableHeader { @@ -142,7 +144,8 @@ class MockCryptoSession : public TestCryptoSession { MOCK_METHOD0(GetSecurityLevel, CdmSecurityLevel()); MOCK_METHOD0(Open, CdmResponseType()); MOCK_METHOD1(Open, CdmResponseType(SecurityLevel)); - MOCK_METHOD1(LoadCertificatePrivateKey, CdmResponseType(const std::string&)); + MOCK_METHOD1(LoadCertificatePrivateKey, + CdmResponseType(const CryptoWrappedKey&)); MOCK_METHOD0(DeleteAllUsageReports, CdmResponseType()); MOCK_METHOD1(GetUsageSupportType, CdmResponseType(CdmUsageSupportType* type)); MOCK_METHOD0(GetUsageTableHeader, UsageTableHeader*()); @@ -219,7 +222,7 @@ TEST_F(CdmSessionTest, InitWithBuiltInCertificate) { RetrieveCertificate(false, NotNull(), NotNull(), NotNull(), _)) .WillOnce(DoAll(SetArgPointee<1>(kToken), SetArgPointee<2>(kWrappedKey), Return(true))); - EXPECT_CALL(*crypto_session_, LoadCertificatePrivateKey(StrEq(kWrappedKey))) + EXPECT_CALL(*crypto_session_, LoadCertificatePrivateKey(kWrappedKey)) .InSequence(crypto_session_seq) .WillOnce(Return(NO_ERROR)); EXPECT_CALL(*file_handle_, Init(Eq(level))).WillOnce(Return(true)); @@ -247,7 +250,7 @@ TEST_F(CdmSessionTest, InitWithCertificate) { RetrieveCertificate(false, NotNull(), NotNull(), NotNull(), _)) .WillOnce(DoAll(SetArgPointee<1>(kToken), SetArgPointee<2>(kWrappedKey), Return(true))); - EXPECT_CALL(*crypto_session_, LoadCertificatePrivateKey(StrEq(kWrappedKey))) + EXPECT_CALL(*crypto_session_, LoadCertificatePrivateKey(kWrappedKey)) .InSequence(crypto_session_seq) .WillOnce(Return(NO_ERROR)); EXPECT_CALL(*license_parser_, @@ -274,7 +277,7 @@ TEST_F(CdmSessionTest, ReInitFail) { RetrieveCertificate(false, NotNull(), NotNull(), NotNull(), _)) .WillOnce(DoAll(SetArgPointee<1>(kToken), SetArgPointee<2>(kWrappedKey), Return(true))); - EXPECT_CALL(*crypto_session_, LoadCertificatePrivateKey(StrEq(kWrappedKey))) + EXPECT_CALL(*crypto_session_, LoadCertificatePrivateKey(kWrappedKey)) .InSequence(crypto_session_seq) .WillOnce(Return(NO_ERROR)); EXPECT_CALL(*license_parser_, @@ -329,7 +332,7 @@ TEST_F(CdmSessionTest, UpdateUsageEntry) { RetrieveCertificate(false, NotNull(), NotNull(), NotNull(), _)) .WillOnce(DoAll(SetArgPointee<1>(kToken), SetArgPointee<2>(kWrappedKey), Return(true))); - EXPECT_CALL(*crypto_session_, LoadCertificatePrivateKey(StrEq(kWrappedKey))) + EXPECT_CALL(*crypto_session_, LoadCertificatePrivateKey(kWrappedKey)) .InSequence(crypto_session_seq) .WillOnce(Return(NO_ERROR)); EXPECT_CALL(*crypto_session_, GetUsageTableHeader()) diff --git a/libwvdrmengine/cdm/core/test/device_files_unittest.cpp b/libwvdrmengine/cdm/core/test/device_files_unittest.cpp index 25cc5553..fc9b8016 100644 --- a/libwvdrmengine/cdm/core/test/device_files_unittest.cpp +++ b/libwvdrmengine/cdm/core/test/device_files_unittest.cpp @@ -13,6 +13,7 @@ #include "arraysize.h" #include "cdm_random.h" +#include "crypto_wrapped_key.h" #include "file_store.h" #include "properties.h" #include "string_conversions.h" @@ -28,100 +29,212 @@ const uint32_t kWrappedKeyLen = 500; const std::string kEmptyString; -// Structurally valid test certificate. -// The data elements in this module are used to test the storage and -// retrieval of certificates and licenses +// Structurally valid test certificate of provisioning 3.0. +// {'certificate': {'algorithm': 'RSA', +// 'creation_time': '2020-12-14T23:17:27', +// 'public_key': ... 270 bytes, +// 'serial_number': '7CB49F987A635E1E0A52184694582D6E', +// 'type': 'DRM_USER_DEVICE'}, +// 'signature': ... 256 byts, +// 'signer': { +// 'certificate': {'creation_time': '2017-11-17T13:21:39', +// 'public_key': ... 270 bytes, +// 'serial_number': '65802C9B625E5A319C33DC1CB7C3C6D4', +// 'type': 'DRM_INTERMEDIATE'}, +// 'signature': ... 384 bytes } +// } +// Value of |certificate| in DeviceCertFile proto messages +// kTestCertificateFileData and kTestCertificateFileWithoutKeyTypeData const std::string kTestCertificate = a2bs_hex( - "0A98030802120D73657269616C5F6E756D62657218B4B2CDE00422E8024D49494243674B43" - "415145412B78475A2F77637A39756746705030374E73706F365531376C3059684669467078" - "78553470546B334C69667A3952337A734973754552777461372B66574966784F6F32303865" - "74742F6A68736B69566F645345743351424768345842697079576F704B775A393348486144" - "565A41414C692F32412B785442745764456F37584755756A4B447643322F615A4B756B666A" - "704F6955493841684C41666A6D6C63442F555A31515068306D4873676C524E436D7043776D" - "7753584139564E6D687A2B5069422B446D6C3457576E4B572F56486F32756A54587871372B" - "65664D55344832666E79335365334B594F73465046475A31544E5153596C46755368577248" - "5074694C6D5564506F50364356326D4D4C31746B2B6C3744494971587251684C554B444143" - "654D35726F4D78306B4C6855574238502B30756A31434E6C4E4E344A525A6C433778466671" - "694D62465255395A344E3659774944415141422899203A11746573742E7769646576696E65" - "2E636F6D128202307836353063396632653637303165336665373364333035343930346139" - "61346262646239363733336631633463373433656635373361643661633134633561336266" - "38613437333166366536323736666165613532343733303336373766623864626466323466" - "66373865353363323530353263646361383765656366656538353437366263623861303563" - "62396131656665663763623837646436383232336531313763653830306163343631373731" - "37323534343735376134383762653332663561623866653038373966613861646437386265" - "34363565613866386435616366393737653966316165333664346434373831366561366564" - "343133373262"); + "0AEB03080212107CB49F987A635E1E0A52184694582D6E1887C6E1FE05228E023082010A" + "0282010100DB13F5089C061E8EB62562692B3A06A774A99129BD63445FEC24448D07C30D" + "7343553442A989AF000B7D962033C290D9A81DDCBCF3980512445EB7E6CF544FC1FB3FC7" + "58FB9E06B6C28562A841E4AE2D3368795C41A2D6043CA9830E0F36583C8FDB839C2752C1" + "3E184034EE412BA8A90271295B094255A16319706F4D6C9CF1EBB1B39BA2A7B9B2780344" + "DD5834BF71F4D5185508D2FDFB10419BD4F48E79DDFC78471C11B9E99DF98221D6FAB25A" + "EE24574FB02D614974942A36527C62B73A6FB7CA9EF828EB598DA59060D654851103F857" + "A041E66B2FFB99713D31A64605932833E8CCDA6CF0F888AE6E78EDC9DA0D88A185B97FEB" + "3EA74CF146BE7D9267020301000128E83D3A0C7769646576696E652E636F6D480152AA01" + "080110001A8101044F554B9400E10B17185036B6A1628EFC61B22166DE2235717A44F953" + "B7928F3415B9D113835B10106CB6C2187F34188723D82ECF95CF5ECAB58923F173186081" + "5999F08BF4BE4A44DB7B991B5F915F2ADCEE481E26096AAEC3AC761B624A92158AC91035" + "041173392B1E495428F0D17406B10889B6B701FAF08D2284F95DBBCA2220595267DCA89A" + "2E57E7D4CA3C62ED6D12742408A07C103DF860DC0520C3664EEB1280028CD44E12AA7C1A" + "8EBF88C81A2A54EFD29F8BC6C377B0C11C3404F84D8B9EAD52A0E18E929A4923A4172C2A" + "C1CDADD16E41A7833AA0DE9D09F685DAC9ACC702CB9061632C1C82333A6FB6BC9C4B2540" + "BE18CED4AB0AF1C3EFE521308F3D4CF513C20500064FE935FDDF7BBAC0BA99AA7FA66017" + "898DEE6F6F5EF90C875D5D8DA39E769E8D1485253EEE93A97B35A8EAE8D3213D392B552F" + "B4B4A37955EBE7362287502EB649D982F06D308178642C1F69B12383B050CF60CD292093" + "29C148FB4F422ED5ED139A25A89E13D4AB2E8DB940299D1414AF30DDF0D06AF55C1978F6" + "E71E4548F20FFAE953A99D492F3D2847783338D74F66D2DFEBB50896ACBC4795A81AB405" + "0AAE020801121065802C9B625E5A319C33DC1CB7C3C6D418E3A5BDD005228E023082010A" + "0282010100B80502043C2A8A0FD8D25C613E1E3E3B5E349F332F04516A7510D38021A562" + "9B9AA027AEAD3C759B7AFE70BED65F3DF6860FF5EB60B983A3FFA33FDE06F3B73014DFC8" + "45AB371C6600562E9D904F842B8BA4A5D9200FFA3ED45D705520A5C372A889F9E3143862" + "34C6897AE655851FCD9ADB4EF9126C78386EA93BCB25BA3EC475C55C608E771C763AB025" + "06F9B07252D6ABF7EA64B1EBDE7B95C6407690533BD6890B9274C16066F74FC401EA355F" + "0A02106814D49BF0C89E6E1F8DB2A47841CD0DAD793296A107C36223404F2BF1FCA16FD0" + "A4B982634DB62407F8F14ACAE3B05A038BD3E4BBBAE4391BBFA7A47FB9D01DE857EA88E5" + "E36EE36E245859FC0F020301000128E83D1280037E06581A019184AB572AFDCADDD03F16" + "1CE68200F8E6F8AD161947360BC8D49C0D68009B1C4644F9B3F3FB6DDFD92EF92DE62D41" + "D459D29D81BFAEF3970A3A39D25B2662ECB03B2DA7B68302FAA6DD98D95A143CC8C1CB6A" + "DDA76D2EE9C3723FAF95A29CDC3E968B6821A91C051CA280A86669710A1AD7A44BF92180" + "27460DF694E2E9270396DF221963F21EE6AA220A5EE4A4D0FEB3D53EB5732F8F91E9A96B" + "3B8BE284C51339EA284D4D0EDD55B6AD56F7416420E05E059F9734A96BE25AA44560DBA8" + "C38755A42A82BD7F88EDD19DF346A667B33B8114C76A8838C423D824A50B23251A088136" + "D6E8F475299D2AFD46CEA51B5CBDF789A572125CD24FBB813B387A10CD2A30E3447634AB" + "3408F96B9CF3D98896D405F3F540D9C57962760FCD177CDD101EB8A4148B9C29CED5EAD6" + "45A95B698F1CDC6E1DB6678B85074186080D68D13CD37E07B16DE370CD9AFB9B25564A73" + "A30E2AF8085EA37D310C474F0E67AC00CA992A5296FAEDAD7AA06ECD790F1E3D426558FA" + "98383E3CD2ED4830"); // A Wrapped Private Key -// The data elements in this module are used to test the storage and -// retrieval of certificates and licenses -const std::string kTestWrappedPrivateKey = - "4F724B065326371A2F5F6F51467C2E26555C453B5C7C1B4F2738454B782E3E7B5340435A" - "66374D0612052C521A233D7A67194871751C78575E5177070130264C4F037633320E667B" - "1A49192924491338693D106E6113014A733A241A1A033E28352178146B4F543D38104A59" - "19120325502C31365506096D59585E08774B5B567A7B5D03451E6B11633E52672C226103" - "104B3E4C031A6403050F3A574D2C501711773802741F7F3A0D364757101D02181C7D4D35" - "207167506A424C094E4A72316F791F162D76657D2B5D3C2D7B273A286927717561316518" - "7E55282430491467086425432347701C3116446D21645C756B2D3D0F797C3220322D622A" - "254D0B7D4F1D5D0C0A36755D1246741A34783C45157247091C78232B7D2E0E1F637A2A37" - "39085D76166747034350613969072F5B5C5B21657E470C7E513B3F091D74455A3A073705" - "7B7E3B5337191D4E7536087C334B6028530F3F5B23380B6A076031294501003D6D1F240F" - "63053D5D0B271B6A0F26185650731308660B0447566041684F584C22216E567D3B775569" - "5F7F3D6B64525E7227165948101540243C19495C4C702F37490F26613353797825624143" - "263043020E1E6760123D51056F2F1E482F2E3D021B27677D3E7E3C0C11757C3448275E08" - "382E111263644C6D224714706D760A054A586E17505C3429575A41043F184209"; +// Value of |wrapped_private_key| in DeviceCertFile proto messages +// kTestCertificateFileData and kTestCertificateFileWithoutKeyTypeData. +// Value is randomly generated value and is not compatible with a real +// OEMCrypto implementation. +const std::string kTestWrappedPrivateKeyData = a2bs_hex( + "B36550E6BEACCB34F6C3B2ABF86634EE5383829C844F9B0C14DCF9A22FE3543CCBA8FD61" + "E21CEE503E7A40B93B07A4186A362D9E6F88DD48D4516635C6D0C253C03F12EFA6095618" + "D647F5212C518C4A6AA7172BC691530703FEDDFDB25ECF885A53FF2B4B98773979D61AE6" + "59E340489811512A5C2FD445A4B0AE88A3A7F29ACE5B01ECF580D0993227BC408B602B0B" + "C099920C17044FE66242372C2B2E8CA5C1EEC0844BC19198ADADE47FB449DC9B30784952" + "B3A8131B912CE928070D665C0557EBE7484FDABFBCA0F2C2BFD4FBDDB6681C4689FD276C" + "231B72B15AC4E5C3C088449DE4785F1D4835AC44E39B119991EFF6E72C7D3B8C75CE588D" + "B0B3AD69EB79C19B22CB518EF964C9D985AFD3677F0D13015AD7BEA84CD01E335E68AF15" + "3B989FE8BEEC60A94753C638535FA3F215F750F6954AC395F8702941409E7276910CE118" + "19649641318B5BD1B78DECEADB2B562312CC286DB0BCC14A60C84CB21AB6E75E59DAFBE7" + "01D6405DD3F47D2F8A95422ED8EB5ECE330C9886406B3B69180B697521F3865B4A05DF2B" + "B51D16CAFEF05866E5D55C360C759F5B10E0D354D63D5A14E5BA19DBF9394E18E474E790" + "63B4E877C2FE6BCA732ED39B091B6D7A21DD9D6D6750C1CA2ABC5DEC2A81B5359771849E" + "7B4560EB6D329E59455A70F57F035DFB50EC4354D7E068ADFAFAD4081ACA67FD"); +const CryptoWrappedKey kTestWrappedKey = {CryptoWrappedKey::kRsa, + kTestWrappedPrivateKeyData}; -// The test certificate in file storage format. -// The data elements in this module are used to test the storage and -// retrieval of certificates and licenses +// Structurally valid test certificate device file, missing |key_type| field. +// {'certificate': kTestCertificate, +// 'wrapped_private_key': kTestWrappedPrivateKeyData +// } +const std::string kTestCertificateFileWithoutKeyTypeData = a2bs_hex( + "0AA90F080110011AA20F0AA80B0AEB03080212107CB49F987A635E1E0A52184694582D6E" + "1887C6E1FE05228E023082010A0282010100DB13F5089C061E8EB62562692B3A06A774A9" + "9129BD63445FEC24448D07C30D7343553442A989AF000B7D962033C290D9A81DDCBCF398" + "0512445EB7E6CF544FC1FB3FC758FB9E06B6C28562A841E4AE2D3368795C41A2D6043CA9" + "830E0F36583C8FDB839C2752C13E184034EE412BA8A90271295B094255A16319706F4D6C" + "9CF1EBB1B39BA2A7B9B2780344DD5834BF71F4D5185508D2FDFB10419BD4F48E79DDFC78" + "471C11B9E99DF98221D6FAB25AEE24574FB02D614974942A36527C62B73A6FB7CA9EF828" + "EB598DA59060D654851103F857A041E66B2FFB99713D31A64605932833E8CCDA6CF0F888" + "AE6E78EDC9DA0D88A185B97FEB3EA74CF146BE7D9267020301000128E83D3A0C77696465" + "76696E652E636F6D480152AA01080110001A8101044F554B9400E10B17185036B6A1628E" + "FC61B22166DE2235717A44F953B7928F3415B9D113835B10106CB6C2187F34188723D82E" + "CF95CF5ECAB58923F1731860815999F08BF4BE4A44DB7B991B5F915F2ADCEE481E26096A" + "AEC3AC761B624A92158AC91035041173392B1E495428F0D17406B10889B6B701FAF08D22" + "84F95DBBCA2220595267DCA89A2E57E7D4CA3C62ED6D12742408A07C103DF860DC0520C3" + "664EEB1280028CD44E12AA7C1A8EBF88C81A2A54EFD29F8BC6C377B0C11C3404F84D8B9E" + "AD52A0E18E929A4923A4172C2AC1CDADD16E41A7833AA0DE9D09F685DAC9ACC702CB9061" + "632C1C82333A6FB6BC9C4B2540BE18CED4AB0AF1C3EFE521308F3D4CF513C20500064FE9" + "35FDDF7BBAC0BA99AA7FA66017898DEE6F6F5EF90C875D5D8DA39E769E8D1485253EEE93" + "A97B35A8EAE8D3213D392B552FB4B4A37955EBE7362287502EB649D982F06D308178642C" + "1F69B12383B050CF60CD29209329C148FB4F422ED5ED139A25A89E13D4AB2E8DB940299D" + "1414AF30DDF0D06AF55C1978F6E71E4548F20FFAE953A99D492F3D2847783338D74F66D2" + "DFEBB50896ACBC4795A81AB4050AAE020801121065802C9B625E5A319C33DC1CB7C3C6D4" + "18E3A5BDD005228E023082010A0282010100B80502043C2A8A0FD8D25C613E1E3E3B5E34" + "9F332F04516A7510D38021A5629B9AA027AEAD3C759B7AFE70BED65F3DF6860FF5EB60B9" + "83A3FFA33FDE06F3B73014DFC845AB371C6600562E9D904F842B8BA4A5D9200FFA3ED45D" + "705520A5C372A889F9E314386234C6897AE655851FCD9ADB4EF9126C78386EA93BCB25BA" + "3EC475C55C608E771C763AB02506F9B07252D6ABF7EA64B1EBDE7B95C6407690533BD689" + "0B9274C16066F74FC401EA355F0A02106814D49BF0C89E6E1F8DB2A47841CD0DAD793296" + "A107C36223404F2BF1FCA16FD0A4B982634DB62407F8F14ACAE3B05A038BD3E4BBBAE439" + "1BBFA7A47FB9D01DE857EA88E5E36EE36E245859FC0F020301000128E83D1280037E0658" + "1A019184AB572AFDCADDD03F161CE68200F8E6F8AD161947360BC8D49C0D68009B1C4644" + "F9B3F3FB6DDFD92EF92DE62D41D459D29D81BFAEF3970A3A39D25B2662ECB03B2DA7B683" + "02FAA6DD98D95A143CC8C1CB6ADDA76D2EE9C3723FAF95A29CDC3E968B6821A91C051CA2" + "80A86669710A1AD7A44BF9218027460DF694E2E9270396DF221963F21EE6AA220A5EE4A4" + "D0FEB3D53EB5732F8F91E9A96B3B8BE284C51339EA284D4D0EDD55B6AD56F7416420E05E" + "059F9734A96BE25AA44560DBA8C38755A42A82BD7F88EDD19DF346A667B33B8114C76A88" + "38C423D824A50B23251A088136D6E8F475299D2AFD46CEA51B5CBDF789A572125CD24FBB" + "813B387A10CD2A30E3447634AB3408F96B9CF3D98896D405F3F540D9C57962760FCD177C" + "DD101EB8A4148B9C29CED5EAD645A95B698F1CDC6E1DB6678B85074186080D68D13CD37E" + "07B16DE370CD9AFB9B25564A73A30E2AF8085EA37D310C474F0E67AC00CA992A5296FAED" + "AD7AA06ECD790F1E3D426558FA98383E3CD2ED483012F403B36550E6BEACCB34F6C3B2AB" + "F86634EE5383829C844F9B0C14DCF9A22FE3543CCBA8FD61E21CEE503E7A40B93B07A418" + "6A362D9E6F88DD48D4516635C6D0C253C03F12EFA6095618D647F5212C518C4A6AA7172B" + "C691530703FEDDFDB25ECF885A53FF2B4B98773979D61AE659E340489811512A5C2FD445" + "A4B0AE88A3A7F29ACE5B01ECF580D0993227BC408B602B0BC099920C17044FE66242372C" + "2B2E8CA5C1EEC0844BC19198ADADE47FB449DC9B30784952B3A8131B912CE928070D665C" + "0557EBE7484FDABFBCA0F2C2BFD4FBDDB6681C4689FD276C231B72B15AC4E5C3C088449D" + "E4785F1D4835AC44E39B119991EFF6E72C7D3B8C75CE588DB0B3AD69EB79C19B22CB518E" + "F964C9D985AFD3677F0D13015AD7BEA84CD01E335E68AF153B989FE8BEEC60A94753C638" + "535FA3F215F750F6954AC395F8702941409E7276910CE11819649641318B5BD1B78DECEA" + "DB2B562312CC286DB0BCC14A60C84CB21AB6E75E59DAFBE701D6405DD3F47D2F8A95422E" + "D8EB5ECE330C9886406B3B69180B697521F3865B4A05DF2BB51D16CAFEF05866E5D55C36" + "0C759F5B10E0D354D63D5A14E5BA19DBF9394E18E474E79063B4E877C2FE6BCA732ED39B" + "091B6D7A21DD9D6D6750C1CA2ABC5DEC2A81B5359771849E7B4560EB6D329E59455A70F5" + "7F035DFB50EC4354D7E068ADFAFAD4081ACA67FD1220F07050C50264B496211432D47DAA" + "88EE59BAD141B8FD372BAE67A6FF05C74DAC"); + +// Structurally valid test certificate device file. +// {'certificate': kTestCertificate, +// 'key_type': 'RSA', +// 'wrapped_private_key': kTestWrappedPrivateKeyData +// } const std::string kTestCertificateFileData = a2bs_hex( - "0A950D080110011A8E0D0AA0050A98030802120D73657269616C5F6E756D62657218B4B2CD" - "E00422E8024D49494243674B43415145412B78475A2F77637A39756746705030374E73706F" - "365531376C305968466946707878553470546B334C69667A3952337A734973754552777461" - "372B66574966784F6F3230386574742F6A68736B69566F6453457433514247683458426970" - "79576F704B775A393348486144565A41414C692F32412B785442745764456F37584755756A" - "4B447643322F615A4B756B666A704F6955493841684C41666A6D6C63442F555A3151506830" - "6D4873676C524E436D7043776D7753584139564E6D687A2B5069422B446D6C3457576E4B57" - "2F56486F32756A54587871372B65664D55344832666E79335365334B594F73465046475A31" - "544E5153596C467553685772485074694C6D5564506F50364356326D4D4C31746B2B6C3744" - "494971587251684C554B444143654D35726F4D78306B4C6855574238502B30756A31434E6C" - "4E4E344A525A6C433778466671694D62465255395A344E3659774944415141422899203A11" - "746573742E7769646576696E652E636F6D1282023078363530633966326536373031653366" - "65373364333035343930346139613462626462393637333366316334633734336566353733" - "61643661633134633561336266386134373331663665363237366661656135323437333033" - "36373766623864626466323466663738653533633235303532636463613837656563666565" - "38353437366263623861303563623961316566656637636238376464363832323365313137" - "63653830306163343631373731373235343437353761343837626533326635616238666530" - "38373966613861646437386265343635656138663864356163663937376539663161653336" - "6434643437383136656136656434313337326212E807344637323442303635333236333731" - "41324635463646353134363743324532363535354334353342354337433142344632373338" - "34353442373832453345374235333430343335413636333734443036313230353243353231" - "41323333443741363731393438373137353143373835373545353137373037303133303236" - "34433446303337363333333230453636374231413439313932393234343931333338363933" - "44313036453631313330313441373333413234314131413033334532383335323137383134" - "36423446353433443338313034413539313931323033323535303243333133363535303630" - "39364435393538354530383737344235423536374137423544303334353145364231313633" - "33453532363732433232363130333130344233453443303331413634303330353046334135" - "37344432433530313731313737333830323734314637463341304433363437353731303144" - "30323138314337443444333532303731363735303641343234433039344534413732333136" - "46373931463136324437363635374432423544334332443742323733413238363932373731" - "37353631333136353138374535353238323433303439313436373038363432353433323334" - "37373031433331313634343644323136343543373536423244334430463739374333323230" - "33323244363232413235344430423744344631443544304330413336373535443132343637" - "34314133343738334334353135373234373039314337383233324237443245304531463633" - "37413241333733393038354437363136363734373033343335303631333936393037324635" - "42354335423231363537453437304337453531334233463039314437343435354133413037" - "33373035374237453342353333373139314434453735333630383743333334423630323835" - "33304633463542323333383042364130373630333132393435303130303344364431463234" - "30463633303533443544304232373142364130463236313835363530373331333038363630" - "42303434373536363034313638344635383443323232313645353637443342373735353639" - "35463746334436423634353235453732323731363539343831303135343032343343313934" - "39354334433730324633373439304632363631333335333739373832353632343134333236" - "33303433303230453145363736303132334435313035364632463145343832463245334430" - "32314232373637374433453745334330433131373537433334343832373545303833383245" - "31313132363336343443364432323437313437303644373630413035344135383645313735" - "303543333432393537354134313034334631383432303912205C6993E9656F73A41739773A" - "0FCBA8AE232CD8856ACE585FF6BFB2A09C20061E"); + "0AAB0F080110011AA40F0AA80B0AEB03080212107CB49F987A635E1E0A52184694582D6E" + "1887C6E1FE05228E023082010A0282010100DB13F5089C061E8EB62562692B3A06A774A9" + "9129BD63445FEC24448D07C30D7343553442A989AF000B7D962033C290D9A81DDCBCF398" + "0512445EB7E6CF544FC1FB3FC758FB9E06B6C28562A841E4AE2D3368795C41A2D6043CA9" + "830E0F36583C8FDB839C2752C13E184034EE412BA8A90271295B094255A16319706F4D6C" + "9CF1EBB1B39BA2A7B9B2780344DD5834BF71F4D5185508D2FDFB10419BD4F48E79DDFC78" + "471C11B9E99DF98221D6FAB25AEE24574FB02D614974942A36527C62B73A6FB7CA9EF828" + "EB598DA59060D654851103F857A041E66B2FFB99713D31A64605932833E8CCDA6CF0F888" + "AE6E78EDC9DA0D88A185B97FEB3EA74CF146BE7D9267020301000128E83D3A0C77696465" + "76696E652E636F6D480152AA01080110001A8101044F554B9400E10B17185036B6A1628E" + "FC61B22166DE2235717A44F953B7928F3415B9D113835B10106CB6C2187F34188723D82E" + "CF95CF5ECAB58923F1731860815999F08BF4BE4A44DB7B991B5F915F2ADCEE481E26096A" + "AEC3AC761B624A92158AC91035041173392B1E495428F0D17406B10889B6B701FAF08D22" + "84F95DBBCA2220595267DCA89A2E57E7D4CA3C62ED6D12742408A07C103DF860DC0520C3" + "664EEB1280028CD44E12AA7C1A8EBF88C81A2A54EFD29F8BC6C377B0C11C3404F84D8B9E" + "AD52A0E18E929A4923A4172C2AC1CDADD16E41A7833AA0DE9D09F685DAC9ACC702CB9061" + "632C1C82333A6FB6BC9C4B2540BE18CED4AB0AF1C3EFE521308F3D4CF513C20500064FE9" + "35FDDF7BBAC0BA99AA7FA66017898DEE6F6F5EF90C875D5D8DA39E769E8D1485253EEE93" + "A97B35A8EAE8D3213D392B552FB4B4A37955EBE7362287502EB649D982F06D308178642C" + "1F69B12383B050CF60CD29209329C148FB4F422ED5ED139A25A89E13D4AB2E8DB940299D" + "1414AF30DDF0D06AF55C1978F6E71E4548F20FFAE953A99D492F3D2847783338D74F66D2" + "DFEBB50896ACBC4795A81AB4050AAE020801121065802C9B625E5A319C33DC1CB7C3C6D4" + "18E3A5BDD005228E023082010A0282010100B80502043C2A8A0FD8D25C613E1E3E3B5E34" + "9F332F04516A7510D38021A5629B9AA027AEAD3C759B7AFE70BED65F3DF6860FF5EB60B9" + "83A3FFA33FDE06F3B73014DFC845AB371C6600562E9D904F842B8BA4A5D9200FFA3ED45D" + "705520A5C372A889F9E314386234C6897AE655851FCD9ADB4EF9126C78386EA93BCB25BA" + "3EC475C55C608E771C763AB02506F9B07252D6ABF7EA64B1EBDE7B95C6407690533BD689" + "0B9274C16066F74FC401EA355F0A02106814D49BF0C89E6E1F8DB2A47841CD0DAD793296" + "A107C36223404F2BF1FCA16FD0A4B982634DB62407F8F14ACAE3B05A038BD3E4BBBAE439" + "1BBFA7A47FB9D01DE857EA88E5E36EE36E245859FC0F020301000128E83D1280037E0658" + "1A019184AB572AFDCADDD03F161CE68200F8E6F8AD161947360BC8D49C0D68009B1C4644" + "F9B3F3FB6DDFD92EF92DE62D41D459D29D81BFAEF3970A3A39D25B2662ECB03B2DA7B683" + "02FAA6DD98D95A143CC8C1CB6ADDA76D2EE9C3723FAF95A29CDC3E968B6821A91C051CA2" + "80A86669710A1AD7A44BF9218027460DF694E2E9270396DF221963F21EE6AA220A5EE4A4" + "D0FEB3D53EB5732F8F91E9A96B3B8BE284C51339EA284D4D0EDD55B6AD56F7416420E05E" + "059F9734A96BE25AA44560DBA8C38755A42A82BD7F88EDD19DF346A667B33B8114C76A88" + "38C423D824A50B23251A088136D6E8F475299D2AFD46CEA51B5CBDF789A572125CD24FBB" + "813B387A10CD2A30E3447634AB3408F96B9CF3D98896D405F3F540D9C57962760FCD177C" + "DD101EB8A4148B9C29CED5EAD645A95B698F1CDC6E1DB6678B85074186080D68D13CD37E" + "07B16DE370CD9AFB9B25564A73A30E2AF8085EA37D310C474F0E67AC00CA992A5296FAED" + "AD7AA06ECD790F1E3D426558FA98383E3CD2ED483012F403B36550E6BEACCB34F6C3B2AB" + "F86634EE5383829C844F9B0C14DCF9A22FE3543CCBA8FD61E21CEE503E7A40B93B07A418" + "6A362D9E6F88DD48D4516635C6D0C253C03F12EFA6095618D647F5212C518C4A6AA7172B" + "C691530703FEDDFDB25ECF885A53FF2B4B98773979D61AE659E340489811512A5C2FD445" + "A4B0AE88A3A7F29ACE5B01ECF580D0993227BC408B602B0BC099920C17044FE66242372C" + "2B2E8CA5C1EEC0844BC19198ADADE47FB449DC9B30784952B3A8131B912CE928070D665C" + "0557EBE7484FDABFBCA0F2C2BFD4FBDDB6681C4689FD276C231B72B15AC4E5C3C088449D" + "E4785F1D4835AC44E39B119991EFF6E72C7D3B8C75CE588DB0B3AD69EB79C19B22CB518E" + "F964C9D985AFD3677F0D13015AD7BEA84CD01E335E68AF153B989FE8BEEC60A94753C638" + "535FA3F215F750F6954AC395F8702941409E7276910CE11819649641318B5BD1B78DECEA" + "DB2B562312CC286DB0BCC14A60C84CB21AB6E75E59DAFBE701D6405DD3F47D2F8A95422E" + "D8EB5ECE330C9886406B3B69180B697521F3865B4A05DF2BB51D16CAFEF05866E5D55C36" + "0C759F5B10E0D354D63D5A14E5BA19DBF9394E18E474E79063B4E877C2FE6BCA732ED39B" + "091B6D7A21DD9D6D6750C1CA2ABC5DEC2A81B5359771849E7B4560EB6D329E59455A70F5" + "7F035DFB50EC4354D7E068ADFAFAD4081ACA67FD18001220A28ED0C0D4697C870B56192C" + "F2AF86D7362398EB250F6A29BE3A0C4887F0D653"); struct LicenseInfo { std::string key_set_id; @@ -2129,9 +2242,10 @@ MATCHER_P(StrAndLenContains, str_vector, "") { TEST_F(DeviceCertificateTest, StoreCertificate) { MockFileSystem file_system; - std::string certificate(CdmRandom::RandomData(kCertificateLen)); - std::string wrapped_private_key(CdmRandom::RandomData(kWrappedKeyLen)); - std::string device_certificate_path = + const std::string certificate(CdmRandom::RandomData(kCertificateLen)); + const CryptoWrappedKey private_key(CryptoWrappedKey::kRsa, + CdmRandom::RandomData(kWrappedKeyLen)); + const std::string device_certificate_path = device_base_path_ + DeviceFiles::GetCertificateFileName(false); // Call to Open will return a unique_ptr, freeing this object. @@ -2141,21 +2255,21 @@ TEST_F(DeviceCertificateTest, StoreCertificate) { .WillOnce(Return(file)); EXPECT_CALL(*file, Write(_, _)) .With(AllArgs(StrAndLenContains( - std::vector{certificate, wrapped_private_key}))) + std::vector{certificate, private_key.key()}))) .WillOnce(ReturnArg<1>()); EXPECT_CALL(*file, Read(_, _)).Times(0); DeviceFiles device_files(&file_system); EXPECT_TRUE(device_files.Init(kSecurityLevelL1)); - EXPECT_TRUE(device_files.StoreCertificate(certificate, wrapped_private_key)); + EXPECT_TRUE(device_files.StoreCertificate(certificate, private_key)); } TEST_P(DeviceCertificateTest, ReadCertificate) { MockFileSystem file_system; const bool atsc_mode = GetParam(); - std::string device_certificate_path = + const std::string device_certificate_path = device_base_path_ + DeviceFiles::GetCertificateFileName(atsc_mode); - std::string data = kTestCertificateFileData; + const std::string data = kTestCertificateFileData; // Call to Open will return a unique_ptr, freeing this object. MockFile* file = new MockFile(); @@ -2174,14 +2288,51 @@ TEST_P(DeviceCertificateTest, ReadCertificate) { DeviceFiles device_files(&file_system); EXPECT_TRUE(device_files.Init(kSecurityLevelL1)); - std::string certificate, wrapped_private_key; + std::string certificate; + CryptoWrappedKey private_key; std::string serial_number; uint32_t system_id = 0; - ASSERT_TRUE(device_files.RetrieveCertificate(atsc_mode, &certificate, - &wrapped_private_key, - &serial_number, &system_id)); + ASSERT_TRUE(device_files.RetrieveCertificate( + atsc_mode, &certificate, &private_key, &serial_number, &system_id)); EXPECT_EQ(kTestCertificate, certificate); - EXPECT_EQ(kTestWrappedPrivateKey, wrapped_private_key); + EXPECT_EQ(kTestWrappedKey, private_key); + EXPECT_EQ("7CB49F987A635E1E0A52184694582D6E", b2a_hex(serial_number)); +} + +TEST_P(DeviceCertificateTest, ReadCertificateWithoutKeyType) { + // Stored files without an explicit key type should default to RSA. + MockFileSystem file_system; + const bool atsc_mode = GetParam(); + const std::string device_certificate_path = + device_base_path_ + DeviceFiles::GetCertificateFileName(atsc_mode); + const std::string data = kTestCertificateFileWithoutKeyTypeData; + + // Call to Open will return a unique_ptr, freeing this object. + MockFile* file = new MockFile(); + EXPECT_CALL(file_system, Exists(StrEq(device_certificate_path))) + .Times(2) + .WillRepeatedly(Return(true)); + EXPECT_CALL(file_system, FileSize(StrEq(device_certificate_path))) + .WillOnce(Return(data.size())); + EXPECT_CALL(file_system, DoOpen(StrEq(device_certificate_path), _)) + .WillOnce(Return(file)); + EXPECT_CALL(*file, Read(NotNull(), Eq(data.size()))) + .WillOnce(DoAll(SetArrayArgument<0>(data.begin(), data.end()), + Return(data.size()))); + EXPECT_CALL(*file, Write(_, _)).Times(0); + + DeviceFiles device_files(&file_system); + EXPECT_TRUE(device_files.Init(kSecurityLevelL1)); + + std::string certificate; + CryptoWrappedKey private_key; + std::string serial_number; + uint32_t system_id = 0; + ASSERT_TRUE(device_files.RetrieveCertificate( + atsc_mode, &certificate, &private_key, &serial_number, &system_id)); + EXPECT_EQ(kTestCertificate, certificate); + EXPECT_EQ(kTestWrappedKey, private_key); + EXPECT_EQ("7CB49F987A635E1E0A52184694582D6E", b2a_hex(serial_number)); } TEST_P(DeviceCertificateTest, HasCertificate) { @@ -2210,7 +2361,8 @@ INSTANTIATE_TEST_CASE_P(AtscMode, DeviceCertificateTest, TEST_P(DeviceFilesSecurityLevelTest, SecurityLevel) { MockFileSystem file_system; std::string certificate(CdmRandom::RandomData(kCertificateLen)); - std::string wrapped_private_key(CdmRandom::RandomData(kWrappedKeyLen)); + const CryptoWrappedKey private_key(CryptoWrappedKey::kRsa, + CdmRandom::RandomData(kWrappedKeyLen)); CdmSecurityLevel security_level = GetParam(); std::string device_base_path; @@ -2226,13 +2378,13 @@ TEST_P(DeviceFilesSecurityLevelTest, SecurityLevel) { .WillOnce(Return(file)); EXPECT_CALL(*file, Write(_, _)) .With(AllArgs(StrAndLenContains( - std::vector{certificate, wrapped_private_key}))) + std::vector{certificate, private_key.key()}))) .WillOnce(ReturnArg<1>()); EXPECT_CALL(*file, Read(_, _)).Times(0); DeviceFiles device_files(&file_system); EXPECT_TRUE(device_files.Init(security_level)); - EXPECT_TRUE(device_files.StoreCertificate(certificate, wrapped_private_key)); + EXPECT_TRUE(device_files.StoreCertificate(certificate, private_key)); } INSTANTIATE_TEST_CASE_P(SecurityLevel, DeviceFilesSecurityLevelTest, diff --git a/libwvdrmengine/cdm/core/test/license_unittest.cpp b/libwvdrmengine/cdm/core/test/license_unittest.cpp index 84e39dff..cf22f709 100644 --- a/libwvdrmengine/cdm/core/test/license_unittest.cpp +++ b/libwvdrmengine/cdm/core/test/license_unittest.cpp @@ -116,7 +116,10 @@ const std::string kLicenseRequestSignature = a2bs_hex( const std::string kFakeCoreMessage = a2bs_hex("DEADBEEF"); const CryptoSession::SupportedCertificateTypes kDefaultSupportedCertTypes = { - true, true, true}; + /* RSA 2048 */ true, /* RSA 3072 */ true, + /* RSA CAST */ false, + /* ECC 256 */ true, /* ECC 384 */ true, + /* ECC 521 */ true}; const std::string kFakeEntitlementKeyId = a2bs_hex("2a538231c616c67143032a645f9c545d"); @@ -171,6 +174,8 @@ class MockInitializationData : public InitializationData { } // namespace // Protobuf generated classes +using ClientCapabilities = + video_widevine::ClientIdentification::ClientCapabilities; using video_widevine::ClientIdentification; using video_widevine::License; using video_widevine::License_KeyContainer; @@ -304,7 +309,7 @@ TEST_F(CdmLicenseTest, PrepareKeyRequestValidation) { bool usage_information_support = true; CryptoSession::HdcpCapability current_hdcp_version = HDCP_NO_DIGITAL_OUTPUT; CryptoSession::HdcpCapability max_hdcp_version = HDCP_V2_1; - uint32_t crypto_session_api_version = 9; + const uint32_t crypto_session_api_version = 16; EXPECT_CALL(*crypto_session_, IsOpen()).WillOnce(Return(true)); EXPECT_CALL(*crypto_session_, request_id()) @@ -315,10 +320,10 @@ TEST_F(CdmLicenseTest, PrepareKeyRequestValidation) { EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull())) .WillOnce(DoAll(SetArgPointee<0>(current_hdcp_version), SetArgPointee<1>(max_hdcp_version), Return(NO_ERROR))); + // Supported certificates set by SetUp(). EXPECT_CALL(*crypto_session_, GetSupportedCertificateTypes(NotNull())); EXPECT_CALL(*crypto_session_, GetApiVersion(NotNull())) - .Times(2) - .WillRepeatedly( + .WillOnce( DoAll(SetArgPointee<0>(crypto_session_api_version), Return(true))); EXPECT_CALL(*clock_, GetCurrentTime()).WillOnce(Return(kLicenseStartTime)); EXPECT_CALL(*crypto_session_, GenerateNonce(NotNull())) @@ -379,24 +384,22 @@ TEST_F(CdmLicenseTest, PrepareKeyRequestValidation) { EXPECT_FALSE(client_id.has_provider_client_token()); EXPECT_FALSE(client_id.has_license_counter()); - const ::video_widevine::ClientIdentification_ClientCapabilities& - client_capabilities = client_id.client_capabilities(); + const ClientCapabilities& client_capabilities = + client_id.client_capabilities(); EXPECT_TRUE(client_capabilities.has_client_token()); EXPECT_TRUE(client_capabilities.has_session_token()); EXPECT_FALSE(client_capabilities.video_resolution_constraints()); - EXPECT_EQ(video_widevine:: - ClientIdentification_ClientCapabilities_HdcpVersion_HDCP_V2_1, + EXPECT_EQ(ClientCapabilities::HDCP_V2_1, client_capabilities.max_hdcp_version()); EXPECT_EQ(crypto_session_api_version, client_capabilities.oem_crypto_api_version()); - EXPECT_THAT( - client_capabilities.supported_certificate_key_type(), - UnorderedElementsAre( - video_widevine:: - ClientIdentification_ClientCapabilities_CertificateKeyType_RSA_2048, - video_widevine:: - ClientIdentification_ClientCapabilities_CertificateKeyType_RSA_3072)); + EXPECT_THAT(client_capabilities.supported_certificate_key_type(), + UnorderedElementsAre(ClientCapabilities::RSA_2048, + ClientCapabilities::RSA_3072, + ClientCapabilities::ECC_SECP256R1, + ClientCapabilities::ECC_SECP384R1, + ClientCapabilities::ECC_SECP521R1)); EXPECT_FALSE(client_capabilities.has_resource_rating_tier()); // Verify Content Identification @@ -425,11 +428,12 @@ TEST_F(CdmLicenseTest, PrepareKeyRequestValidation) { } TEST_F(CdmLicenseTest, PrepareKeyRequestValidationV15) { - bool usage_information_support = true; - CryptoSession::HdcpCapability current_hdcp_version = HDCP_NO_DIGITAL_OUTPUT; - CryptoSession::HdcpCapability max_hdcp_version = HDCP_V2_1; - uint32_t crypto_session_api_version = 15; - uint32_t resource_rating_tier = RESOURCE_RATING_TIER_LOW; + const bool usage_information_support = true; + const CryptoSession::HdcpCapability current_hdcp_version = + HDCP_NO_DIGITAL_OUTPUT; + const CryptoSession::HdcpCapability max_hdcp_version = HDCP_V2_1; + const uint32_t crypto_session_api_version = 15; + const uint32_t resource_rating_tier = RESOURCE_RATING_TIER_LOW; EXPECT_CALL(*crypto_session_, IsOpen()).WillOnce(Return(true)); EXPECT_CALL(*crypto_session_, request_id()) @@ -442,8 +446,7 @@ TEST_F(CdmLicenseTest, PrepareKeyRequestValidationV15) { SetArgPointee<1>(max_hdcp_version), Return(NO_ERROR))); EXPECT_CALL(*crypto_session_, GetSupportedCertificateTypes(NotNull())); EXPECT_CALL(*crypto_session_, GetApiVersion(NotNull())) - .Times(2) - .WillRepeatedly( + .WillOnce( DoAll(SetArgPointee<0>(crypto_session_api_version), Return(true))); EXPECT_CALL(*crypto_session_, GetResourceRatingTier(NotNull())) .WillOnce(DoAll(SetArgPointee<0>(resource_rating_tier), Return(true))); @@ -506,24 +509,22 @@ TEST_F(CdmLicenseTest, PrepareKeyRequestValidationV15) { EXPECT_FALSE(client_id.has_provider_client_token()); EXPECT_FALSE(client_id.has_license_counter()); - const ::video_widevine::ClientIdentification_ClientCapabilities& - client_capabilities = client_id.client_capabilities(); + const ClientCapabilities& client_capabilities = + client_id.client_capabilities(); EXPECT_TRUE(client_capabilities.has_client_token()); EXPECT_TRUE(client_capabilities.has_session_token()); EXPECT_FALSE(client_capabilities.video_resolution_constraints()); - EXPECT_EQ(video_widevine:: - ClientIdentification_ClientCapabilities_HdcpVersion_HDCP_V2_1, + EXPECT_EQ(ClientCapabilities::HDCP_V2_1, client_capabilities.max_hdcp_version()); EXPECT_EQ(crypto_session_api_version, client_capabilities.oem_crypto_api_version()); - EXPECT_THAT( - client_capabilities.supported_certificate_key_type(), - UnorderedElementsAre( - video_widevine:: - ClientIdentification_ClientCapabilities_CertificateKeyType_RSA_2048, - video_widevine:: - ClientIdentification_ClientCapabilities_CertificateKeyType_RSA_3072)); + EXPECT_THAT(client_capabilities.supported_certificate_key_type(), + UnorderedElementsAre(ClientCapabilities::RSA_2048, + ClientCapabilities::RSA_3072, + ClientCapabilities::ECC_SECP256R1, + ClientCapabilities::ECC_SECP384R1, + ClientCapabilities::ECC_SECP521R1)); EXPECT_EQ(resource_rating_tier, client_capabilities.resource_rating_tier()); // Verify Content Identification diff --git a/libwvdrmengine/cdm/core/test/test_printers.cpp b/libwvdrmengine/cdm/core/test/test_printers.cpp index 74a3d6c2..786b0134 100644 --- a/libwvdrmengine/cdm/core/test/test_printers.cpp +++ b/libwvdrmengine/cdm/core/test/test_printers.cpp @@ -68,6 +68,9 @@ void PrintTo(const enum CdmResponseType& value, ::std::ostream* os) { case CERT_PROVISIONING_RESPONSE_ERROR_8: *os << "CERT_PROVISIONING_RESPONSE_ERROR_8"; break; + case CERT_PROVISIONING_RESPONSE_ERROR_9: + *os << "CERT_PROVISIONING_RESPONSE_ERROR_9"; + break; case CLIENT_ID_AES_ENCRYPT_ERROR: *os << "CLIENT_ID_AES_ENCRYPT_ERROR"; break; diff --git a/libwvdrmengine/cdm/test/request_license_test.cpp b/libwvdrmengine/cdm/test/request_license_test.cpp index fc30d375..787ebf62 100644 --- a/libwvdrmengine/cdm/test/request_license_test.cpp +++ b/libwvdrmengine/cdm/test/request_license_test.cpp @@ -17,6 +17,7 @@ #include "arraysize.h" #include "cdm_identifier.h" #include "config_test_env.h" +#include "crypto_wrapped_key.h" #include "device_files.h" #include "device_files.pb.h" #include "file_store.h" @@ -2288,7 +2289,7 @@ TEST_F(WvCdmRequestLicenseTest, UnprovisionTest) { DeviceFiles handle(&file_system); EXPECT_TRUE(handle.Init(security_level)); std::string certificate; - std::string wrapped_private_key; + CryptoWrappedKey wrapped_private_key; std::string serial_number; uint32_t system_id; EXPECT_TRUE(handle.RetrieveCertificate( diff --git a/libwvdrmengine/include/WVErrors.h b/libwvdrmengine/include/WVErrors.h index 5d4820b3..eda2f4ce 100644 --- a/libwvdrmengine/include/WVErrors.h +++ b/libwvdrmengine/include/WVErrors.h @@ -298,10 +298,11 @@ enum { kLoadUsageEntryInvalidSession = ERROR_DRM_VENDOR_MIN + 313, kRestoreOfflineLicenseError3 = ERROR_DRM_VENDOR_MIN + 314, kNoSrmVersion = ERROR_DRM_VENDOR_MIN + 315, + kCertProvisioningResponseError9 = ERROR_DRM_VENDOR_MIN + 316, // This should always follow the last error code. // The offset value should be updated each time a new error code is added. - kErrorWVDrmMaxErrorUsed = ERROR_DRM_VENDOR_MIN + 315, + kErrorWVDrmMaxErrorUsed = ERROR_DRM_VENDOR_MIN + 316, // Used by crypto test mode kErrorTestMode = ERROR_DRM_VENDOR_MAX, diff --git a/libwvdrmengine/include/mapErrors-inl.h b/libwvdrmengine/include/mapErrors-inl.h index ba0a92b6..b0ee42ed 100644 --- a/libwvdrmengine/include/mapErrors-inl.h +++ b/libwvdrmengine/include/mapErrors-inl.h @@ -103,6 +103,8 @@ static android::status_t mapCdmResponseType(wvcdm::CdmResponseType res) { return kCertProvisioningResponseError7; case wvcdm::CERT_PROVISIONING_RESPONSE_ERROR_8: return kCertProvisioningResponseError8; + case wvcdm::CERT_PROVISIONING_RESPONSE_ERROR_9: + return kCertProvisioningResponseError9; case wvcdm::CLIENT_IDENTIFICATION_TOKEN_ERROR_1: return kClientIdentificationTokenError1; case wvcdm::CLIENT_ID_AES_ENCRYPT_ERROR: diff --git a/libwvdrmengine/include_hidl/mapErrors-inl.h b/libwvdrmengine/include_hidl/mapErrors-inl.h index fc7b2cf1..6952e126 100644 --- a/libwvdrmengine/include_hidl/mapErrors-inl.h +++ b/libwvdrmengine/include_hidl/mapErrors-inl.h @@ -358,6 +358,7 @@ static Status mapCdmResponseType_1_0(wvcdm::CdmResponseType res) { case wvcdm::LICENSE_USAGE_ENTRY_MISSING: case wvcdm::PROVISIONING_NOT_ALLOWED_FOR_ATSC: case wvcdm::NO_SRM_VERSION: + case wvcdm::CERT_PROVISIONING_RESPONSE_ERROR_9: ALOGW("Returns UNKNOWN error for legacy status: %d", res); return Status::ERROR_DRM_UNKNOWN;