diff --git a/libwvdrmengine/cdm/core/include/device_files.h b/libwvdrmengine/cdm/core/include/device_files.h index c5a9e522..6ae81306 100644 --- a/libwvdrmengine/cdm/core/include/device_files.h +++ b/libwvdrmengine/cdm/core/include/device_files.h @@ -106,6 +106,8 @@ class DeviceFiles { std::string key_set_id; CdmUsageEntry usage_entry; uint32_t usage_entry_number; + std::string drm_certificate; + CryptoWrappedKey wrapped_private_key; }; DeviceFiles(FileSystem*); @@ -162,13 +164,12 @@ class DeviceFiles { // required creation of reverse lookup tables (CdmUsageEntryInfo). // |app_id| however was hashed and unextractable, and necessitated the // switch to |usage_info_file_name| - virtual bool StoreUsageInfo(const std::string& provider_session_token, - const CdmKeyMessage& key_request, - const CdmKeyResponse& key_response, - const std::string& usage_info_file_name, - const std::string& key_set_id, - const CdmUsageEntry& usage_entry, - uint32_t usage_entry_number); + virtual bool StoreUsageInfo( + const std::string& provider_session_token, + const CdmKeyMessage& key_request, const CdmKeyResponse& key_response, + const std::string& usage_info_file_name, const std::string& key_set_id, + const CdmUsageEntry& usage_entry, uint32_t usage_entry_number, + const std::string& drm_certificate, const CryptoWrappedKey& wrapped_key); // Retrieve usage identifying information stored on the file system. // The caller needs to specify at least one of |ksids| or @@ -214,12 +215,6 @@ class DeviceFiles { virtual bool DeleteAllUsageInfo(); - // Retrieve one usage info from the file. Subsequent calls will retrieve - // subsequent entries in the table for this app_id. - virtual bool RetrieveUsageInfo( - const std::string& usage_info_file_name, - std::vector >* usage_info); - // Retrieve the usage info entry specified by |provider_session_token|. // Returns false if the entry could not be found. virtual bool RetrieveUsageInfo(const std::string& usage_info_file_name, @@ -227,14 +222,17 @@ class DeviceFiles { CdmKeyMessage* license_request, CdmKeyResponse* license_response, CdmUsageEntry* usage_entry, - uint32_t* usage_entry_number); + uint32_t* usage_entry_number, + std::string* drm_certificate, + CryptoWrappedKey* wrapped_key); // Retrieve the usage info entry specified by |key_set_id|. // Returns false if the entry could not be found. virtual bool RetrieveUsageInfoByKeySetId( const std::string& usage_info_file_name, const std::string& key_set_id, std::string* provider_session_token, CdmKeyMessage* license_request, CdmKeyResponse* license_response, CdmUsageEntry* usage_entry, - uint32_t* usage_entry_number); + uint32_t* usage_entry_number, std::string* drm_certificate, + CryptoWrappedKey* wrapped_key); // These APIs support upgrading from usage tables to usage tabler header + // entries introduced in OEMCrypto V13. diff --git a/libwvdrmengine/cdm/core/src/cdm_engine.cpp b/libwvdrmengine/cdm/core/src/cdm_engine.cpp index aab679e9..ce171159 100644 --- a/libwvdrmengine/cdm/core/src/cdm_engine.cpp +++ b/libwvdrmengine/cdm/core/src/cdm_engine.cpp @@ -1490,16 +1490,17 @@ CdmResponseType CdmEngine::RemoveUsageInfo( new CdmSession(file_system_, metrics_->AddSession())); usage_session_->Init(usage_property_set_.get()); - std::vector usage_data; CdmKeyMessage license_request; CdmKeyResponse license_response; CdmUsageEntry usage_entry; uint32_t usage_entry_number; + std::string drm_certificate; + CryptoWrappedKey wrapped_private_key; - if (!handle.RetrieveUsageInfo(DeviceFiles::GetUsageInfoFileName(app_id), - provider_session_token, &license_request, - &license_response, &usage_entry, - &usage_entry_number)) { + if (!handle.RetrieveUsageInfo( + DeviceFiles::GetUsageInfoFileName(app_id), provider_session_token, + &license_request, &license_response, &usage_entry, + &usage_entry_number, &drm_certificate, &wrapped_private_key)) { // Try other security level continue; } @@ -1575,7 +1576,8 @@ CdmResponseType CdmEngine::LoadUsageSession(const CdmKeySetId& key_set_id, DeviceFiles::GetUsageInfoFileName(app_id), key_set_id, &(usage_data.provider_session_token), &(usage_data.license_request), &(usage_data.license), &(usage_data.usage_entry), - &(usage_data.usage_entry_number))) { + &(usage_data.usage_entry_number), &(usage_data.drm_certificate), + &(usage_data.wrapped_private_key))) { LOGE("Unable to find usage information"); return LOAD_USAGE_INFO_MISSING; } diff --git a/libwvdrmengine/cdm/core/src/cdm_session.cpp b/libwvdrmengine/cdm/core/src/cdm_session.cpp index 0277cda1..aeb11a63 100644 --- a/libwvdrmengine/cdm/core/src/cdm_session.cpp +++ b/libwvdrmengine/cdm/core/src/cdm_session.cpp @@ -1018,10 +1018,12 @@ CdmResponseType CdmSession::StoreLicense() { std::string app_id; GetApplicationId(&app_id); + std::string drm_certificate; + CryptoWrappedKey wrapped_private_key; if (!file_handle_->StoreUsageInfo( provider_session_token, key_request_, key_response_, DeviceFiles::GetUsageInfoFileName(app_id), key_set_id_, usage_entry_, - usage_entry_number_)) { + usage_entry_number_, drm_certificate, wrapped_private_key)) { LOGE("Unable to store usage info"); // Usage info file is corrupt. Delete current usage entry and file. if (usage_support_type_ == kUsageEntrySupport) { diff --git a/libwvdrmengine/cdm/core/src/device_files.cpp b/libwvdrmengine/cdm/core/src/device_files.cpp index e4636400..2fa06fed 100644 --- a/libwvdrmengine/cdm/core/src/device_files.cpp +++ b/libwvdrmengine/cdm/core/src/device_files.cpp @@ -32,6 +32,7 @@ using video_widevine_client::sdk::License_LicenseState_ACTIVE; using video_widevine_client::sdk::License_LicenseState_RELEASING; using video_widevine_client::sdk::NameValue; using video_widevine_client::sdk::UsageInfo; +using video_widevine_client::sdk::UsageInfo_DrmUsageCertificate; using video_widevine_client::sdk::UsageInfo_ProviderSession; using video_widevine_client::sdk::UsageTableInfo; using video_widevine_client::sdk::UsageTableInfo_UsageEntryInfo; @@ -134,7 +135,7 @@ bool ExtractFromDeviceCertificate(const DeviceCertificate& device_certificate, if (!has_certificate && !has_key) return true; // Flag if not a default certificate - if (!(has_certificate && has_key)) { + if (!has_certificate || !has_key) { LOGE( "Device certificate proto belongs to neither a default or legacy cert. " "has_certificate: %s, has_key: %s", @@ -142,6 +143,16 @@ bool ExtractFromDeviceCertificate(const DeviceCertificate& device_certificate, return false; } + if (device_certificate.certificate().empty() || + device_certificate.wrapped_private_key().empty()) { + LOGE( + "Device certificate proto belongs does not have a valid certificate or " + "wrapped key. certificate size: %zu, wrapped key size: %zu", + device_certificate.certificate().size(), + device_certificate.wrapped_private_key().size()); + return false; + } + *certificate = device_certificate.certificate(); private_key->Clear(); private_key->set_key(device_certificate.wrapped_private_key()); @@ -169,6 +180,112 @@ bool ExtractFromDeviceCertificate(const DeviceCertificate& device_certificate, return true; } +bool FindOrInsertUsageCertificate( + const std::string& drm_certificate, + const wvcdm::CryptoWrappedKey& wrapped_private_key, UsageInfo* usage_info, + uint32_t* drm_certificate_id) { + RETURN_FALSE_IF_NULL(usage_info); + RETURN_FALSE_IF_NULL(drm_certificate_id); + + // Scan |drm_certificate_cache| for |drm_certificate|. If present, + // return the id + std::set ids; + for (const UsageInfo_DrmUsageCertificate& drm_device_cert : + usage_info->drm_certificate_cache()) { + if (drm_device_cert.drm_certificate().certificate() == drm_certificate) { + *drm_certificate_id = drm_device_cert.drm_certificate_id(); + return true; + } + ids.insert(drm_device_cert.drm_certificate_id()); + } + + uint32_t last_id = 0; + + // |drm_certificate| is not in the cache. Find the first non-contiguous + // id number to insert + for (uint32_t id : ids) { + if (id > last_id + 1) { + break; + } + last_id = id; + } + + if (ids.empty()) + *drm_certificate_id = 0; + else + *drm_certificate_id = last_id + 1; + + // Now insert into |drm_certificate_cache| + UsageInfo_DrmUsageCertificate* drm_usage_certificate = + usage_info->add_drm_certificate_cache(); + drm_usage_certificate->set_drm_certificate_id(*drm_certificate_id); + + return SetDeviceCertificate(drm_certificate, wrapped_private_key, + drm_usage_certificate->mutable_drm_certificate()); +} + +bool FindUsageCertificate( + uint32_t drm_certificate_id, + const google::protobuf::RepeatedPtrField& + drm_certificate_cache, + std::string* drm_certificate, + wvcdm::CryptoWrappedKey* wrapped_private_key) { + for (const UsageInfo_DrmUsageCertificate& drm_usage_cert : + drm_certificate_cache) { + if (drm_usage_cert.drm_certificate_id() == drm_certificate_id) { + return ExtractFromDeviceCertificate(drm_usage_cert.drm_certificate(), + drm_certificate, wrapped_private_key); + } + } + + LOGE("Unable to find any certificate in usage cache for entry: %d", + drm_certificate_id); + return false; +} + +bool UsageCertificateCacheCleanUp(UsageInfo* usage_info) { + const google::protobuf::RepeatedPtrField& + provider_sessions = usage_info->sessions(); + google::protobuf::RepeatedPtrField* + drm_certificate_cache = usage_info->mutable_drm_certificate_cache(); + + // Find all the DRM certificate ids in |drm_certificate_cache| + std::set ids; + for (const UsageInfo_DrmUsageCertificate& drm_usage_cert : + *drm_certificate_cache) { + ids.insert(drm_usage_cert.drm_certificate_id()); + } + + // Next find all the DRM certificate ids in |provider_sessions| + std::set session_ids; + for (const UsageInfo_ProviderSession& session : provider_sessions) { + session_ids.insert(session.drm_certificate_id()); + } + + // Now find all the entry numbers for DRM certificates in + // |drm_device_certificates| but not in |provider_sessions|. These need to + // be removed. + std::set ids_to_erase; + std::set_difference(ids.begin(), ids.end(), session_ids.begin(), + session_ids.end(), + std::inserter(ids_to_erase, ids_to_erase.begin())); + + const auto is_deletable = + [&ids_to_erase]( + const UsageInfo_DrmUsageCertificate& usage_certificate) -> bool { + return std::find(ids_to_erase.cbegin(), ids_to_erase.cend(), + usage_certificate.drm_certificate_id()) != + ids_to_erase.cend(); + }; + + drm_certificate_cache->erase( + std::remove_if(drm_certificate_cache->begin(), + drm_certificate_cache->end(), is_deletable), + drm_certificate_cache->end()); + + return true; +} + } // namespace namespace wvcdm { @@ -522,7 +639,7 @@ bool DeviceFiles::StoreLicense(const CdmLicenseData& license_data, } license->set_usage_entry(license_data.usage_entry); license->set_usage_entry_number(license_data.usage_entry_number); - if (license_data.drm_certificate.size() > 0) { + if (!license_data.drm_certificate.empty()) { DeviceCertificate* device_certificate = license->mutable_drm_certificate(); if (!SetDeviceCertificate(license_data.drm_certificate, license_data.wrapped_private_key, @@ -685,13 +802,12 @@ bool DeviceFiles::UnreserveLicenseId(const std::string& key_set_id) { return true; } -bool DeviceFiles::StoreUsageInfo(const std::string& provider_session_token, - const CdmKeyMessage& key_request, - const CdmKeyResponse& key_response, - const std::string& usage_info_file_name, - const std::string& key_set_id, - const std::string& usage_entry, - uint32_t usage_entry_number) { +bool DeviceFiles::StoreUsageInfo( + const std::string& provider_session_token, const CdmKeyMessage& key_request, + const CdmKeyResponse& key_response, const std::string& usage_info_file_name, + const std::string& key_set_id, const std::string& usage_entry, + uint32_t usage_entry_number, const std::string& drm_certificate, + const CryptoWrappedKey& wrapped_private_key) { RETURN_FALSE_IF_UNINITIALIZED(); video_widevine_client::sdk::File file; if (!FileExists(usage_info_file_name)) { @@ -715,6 +831,16 @@ bool DeviceFiles::StoreUsageInfo(const std::string& provider_session_token, provider_session->set_usage_entry(usage_entry); provider_session->set_usage_entry_number(usage_entry_number); + if (drm_certificate.size() > 0) { + uint32_t drm_certificate_id; + if (!FindOrInsertUsageCertificate(drm_certificate, wrapped_private_key, + usage_info, &drm_certificate_id)) { + LOGE("Unable to insert a certificate in the usage certificate cache"); + return false; + } + provider_session->set_drm_certificate_id(drm_certificate_id); + } + std::string serialized_file; file.SerializeToString(&serialized_file); return StoreFileWithHash(usage_info_file_name, serialized_file) == kNoError; @@ -822,6 +948,7 @@ bool DeviceFiles::DeleteUsageInfo(const std::string& usage_info_file_name, sessions->SwapElements(index, usage_info->sessions_size() - 1); } sessions->RemoveLast(); + UsageCertificateCacheCleanUp(usage_info); std::string serialized_file; file.SerializeToString(&serialized_file); @@ -884,6 +1011,7 @@ bool DeviceFiles::DeleteMultipleUsageInfoByKeySetIds( } if (sessions->size() > 0) { + UsageCertificateCacheCleanUp(file.mutable_usage_info()); std::string serialized_file; file.SerializeToString(&serialized_file); return StoreFileWithHash(usage_info_file_name, serialized_file) == kNoError; @@ -898,41 +1026,21 @@ bool DeviceFiles::DeleteAllUsageInfo() { kUsageInfoFileNameExt); } -bool DeviceFiles::RetrieveUsageInfo( - const std::string& usage_info_file_name, - std::vector >* usage_info) { - RETURN_FALSE_IF_UNINITIALIZED(); - RETURN_FALSE_IF_NULL(usage_info); - - if (!FileExists(usage_info_file_name) || - GetFileSize(usage_info_file_name) == 0) { - usage_info->resize(0); - return true; - } - - video_widevine_client::sdk::File file; - if (RetrieveHashedFile(usage_info_file_name, &file) != kNoError) { - LOGE("Unable to retrieve usage info file"); - return false; - } - - usage_info->resize(file.usage_info().sessions_size()); - for (int i = 0; i < file.usage_info().sessions_size(); ++i) { - (*usage_info)[i] = - std::make_pair(file.usage_info().sessions(i).license_request(), - file.usage_info().sessions(i).license()); - } - - return true; -} - bool DeviceFiles::RetrieveUsageInfo(const std::string& usage_info_file_name, const std::string& provider_session_token, CdmKeyMessage* license_request, CdmKeyResponse* license, std::string* usage_entry, - uint32_t* usage_entry_number) { + uint32_t* usage_entry_number, + std::string* drm_certificate, + CryptoWrappedKey* wrapped_private_key) { RETURN_FALSE_IF_UNINITIALIZED(); + RETURN_FALSE_IF_NULL(license_request); + RETURN_FALSE_IF_NULL(license); + RETURN_FALSE_IF_NULL(usage_entry); + RETURN_FALSE_IF_NULL(usage_entry_number); + RETURN_FALSE_IF_NULL(drm_certificate); + RETURN_FALSE_IF_NULL(wrapped_private_key); video_widevine_client::sdk::File file; if (RetrieveHashedFile(usage_info_file_name, &file) != kNoError) { @@ -948,6 +1056,20 @@ bool DeviceFiles::RetrieveUsageInfo(const std::string& usage_info_file_name, *usage_entry = file.usage_info().sessions(index).usage_entry(); *usage_entry_number = file.usage_info().sessions(index).usage_entry_number(); + + if (!file.usage_info().sessions(index).has_drm_certificate_id()) { + drm_certificate->clear(); + wrapped_private_key->Clear(); + return true; + } + + if (!FindUsageCertificate( + file.usage_info().sessions(index).drm_certificate_id(), + file.usage_info().drm_certificate_cache(), drm_certificate, + wrapped_private_key)) { + LOGE("Unable to find DRM certificate information from usage cache"); + return false; + } return true; } } @@ -959,8 +1081,15 @@ bool DeviceFiles::RetrieveUsageInfoByKeySetId( const std::string& usage_info_file_name, const std::string& key_set_id, std::string* provider_session_token, CdmKeyMessage* license_request, CdmKeyResponse* license, std::string* usage_entry, - uint32_t* usage_entry_number) { + uint32_t* usage_entry_number, std::string* drm_certificate, + CryptoWrappedKey* wrapped_private_key) { RETURN_FALSE_IF_UNINITIALIZED(); + RETURN_FALSE_IF_NULL(license_request); + RETURN_FALSE_IF_NULL(license); + RETURN_FALSE_IF_NULL(usage_entry); + RETURN_FALSE_IF_NULL(usage_entry_number); + RETURN_FALSE_IF_NULL(drm_certificate); + RETURN_FALSE_IF_NULL(wrapped_private_key); video_widevine_client::sdk::File file; if (RetrieveHashedFile(usage_info_file_name, &file) != kNoError) { @@ -977,6 +1106,20 @@ bool DeviceFiles::RetrieveUsageInfoByKeySetId( *usage_entry = file.usage_info().sessions(index).usage_entry(); *usage_entry_number = file.usage_info().sessions(index).usage_entry_number(); + + if (!file.usage_info().sessions(index).has_drm_certificate_id()) { + drm_certificate->clear(); + wrapped_private_key->Clear(); + return true; + } + + if (!FindUsageCertificate( + file.usage_info().sessions(index).drm_certificate_id(), + file.usage_info().drm_certificate_cache(), drm_certificate, + wrapped_private_key)) { + LOGE("Unable to find DRM certificate information from usage cache"); + return false; + } return true; } } @@ -993,6 +1136,7 @@ bool DeviceFiles::StoreUsageInfo(const std::string& usage_info_file_name, file.set_version(video_widevine_client::sdk::File::VERSION_1); UsageInfo* usage_info = file.mutable_usage_info(); + for (size_t i = 0; i < usage_data.size(); ++i) { UsageInfo_ProviderSession* provider_session = usage_info->add_sessions(); @@ -1006,6 +1150,17 @@ bool DeviceFiles::StoreUsageInfo(const std::string& usage_info_file_name, usage_data[i].key_set_id.size()); provider_session->set_usage_entry(usage_data[i].usage_entry); provider_session->set_usage_entry_number(usage_data[i].usage_entry_number); + + if (usage_data[i].drm_certificate.size() > 0) { + uint32_t drm_certificate_id; + if (!FindOrInsertUsageCertificate(usage_data[i].drm_certificate, + usage_data[i].wrapped_private_key, + usage_info, &drm_certificate_id)) { + LOGE("Unable to insert a certificate in the usage certificate cache"); + return false; + } + provider_session->set_drm_certificate_id(drm_certificate_id); + } } std::string serialized_file; @@ -1041,6 +1196,17 @@ bool DeviceFiles::UpdateUsageInfo(const std::string& usage_info_file_name, provider_session->set_usage_entry(usage_data.usage_entry); provider_session->set_usage_entry_number(usage_data.usage_entry_number); + if (usage_data.drm_certificate.size() > 0) { + uint32_t drm_certificate_id; + if (!FindOrInsertUsageCertificate(usage_data.drm_certificate, + usage_data.wrapped_private_key, + usage_info, &drm_certificate_id)) { + LOGE("Unable to find a certificate in to update the usage info"); + return false; + } + provider_session->set_drm_certificate_id(drm_certificate_id); + } + std::string serialized_file; file.SerializeToString(&serialized_file); return StoreFileWithHash(usage_info_file_name, serialized_file) == @@ -1079,6 +1245,19 @@ bool DeviceFiles::RetrieveUsageInfo(const std::string& usage_info_file_name, (*usage_data)[i].usage_entry = file.usage_info().sessions(i).usage_entry(); (*usage_data)[i].usage_entry_number = file.usage_info().sessions(i).usage_entry_number(); + + if (!file.usage_info().sessions(i).has_drm_certificate_id()) { + (*usage_data)[i].drm_certificate.clear(); + (*usage_data)[i].wrapped_private_key.Clear(); + } else { + if (!FindUsageCertificate( + file.usage_info().sessions(i).drm_certificate_id(), + file.usage_info().drm_certificate_cache(), + &(*usage_data)[i].drm_certificate, + &(*usage_data)[i].wrapped_private_key)) { + LOGW("Unable to find DRM certificate information from usage cache"); + } + } } return true; @@ -1108,6 +1287,20 @@ bool DeviceFiles::RetrieveUsageInfo(const std::string& usage_info_file_name, usage_data->usage_entry = file.usage_info().sessions(index).usage_entry(); usage_data->usage_entry_number = file.usage_info().sessions(index).usage_entry_number(); + + if (!file.usage_info().sessions(index).has_drm_certificate_id()) { + usage_data->drm_certificate.clear(); + usage_data->wrapped_private_key.Clear(); + return true; + } + + if (!FindUsageCertificate( + file.usage_info().sessions(index).drm_certificate_id(), + file.usage_info().drm_certificate_cache(), + &usage_data->drm_certificate, &usage_data->wrapped_private_key)) { + LOGE("Unable to find DRM certificate information from usage cache"); + return false; + } return true; } } diff --git a/libwvdrmengine/cdm/core/src/device_files.proto b/libwvdrmengine/cdm/core/src/device_files.proto index 25956ee0..c52cee1f 100644 --- a/libwvdrmengine/cdm/core/src/device_files.proto +++ b/libwvdrmengine/cdm/core/src/device_files.proto @@ -80,17 +80,17 @@ message UsageInfo { optional int64 usage_entry_number = 6; // If not present, use the legacy DRM certificate rather than // one in DrmDeviceCertificate - optional int32 drm_certificate_entry_number = 7; + optional uint32 drm_certificate_id = 7; } // A cache of DeviceCertificates associated with usage entries - message DrmDeviceCertificate { - optional int32 drm_certificate_entry_number = 1; + message DrmUsageCertificate { + optional uint32 drm_certificate_id = 1; optional DeviceCertificate drm_certificate = 2; } repeated ProviderSession sessions = 1; - repeated DrmDeviceCertificate drm_device_certificates = 2; + repeated DrmUsageCertificate drm_certificate_cache = 2; } message HlsAttributes { diff --git a/libwvdrmengine/cdm/core/src/usage_table_header.cpp b/libwvdrmengine/cdm/core/src/usage_table_header.cpp index 440f9b00..98e5c9bc 100644 --- a/libwvdrmengine/cdm/core/src/usage_table_header.cpp +++ b/libwvdrmengine/cdm/core/src/usage_table_header.cpp @@ -118,10 +118,12 @@ bool RetrieveUsageInfoLicense(DeviceFiles* device_files, CdmUsageEntry usage_entry; std::string provider_session_token; CdmKeyMessage license_request; + std::string drm_certificate; + CryptoWrappedKey wrapped_private_key; if (!device_files->RetrieveUsageInfoByKeySetId( usage_info_file_name, key_set_id, &provider_session_token, - &license_request, license_message, &usage_entry, - usage_entry_number)) { + &license_request, license_message, &usage_entry, usage_entry_number, + &drm_certificate, &wrapped_private_key)) { LOGW( "Failed to retrieve usage information: " "key_set_id = %s, usage_info_file_name = %s", @@ -598,12 +600,14 @@ CdmResponseType UsageTableHeader::GetEntry(uint32_t usage_entry_number, std::string provider_session_token; CdmKeyMessage license_request; CdmKeyResponse license; + std::string drm_certificate; + CryptoWrappedKey wrapped_private_key; if (!device_files->RetrieveUsageInfoByKeySetId( usage_entry_info_[usage_entry_number].usage_info_file_name, usage_entry_info_[usage_entry_number].key_set_id, &provider_session_token, &license_request, &license, usage_entry, - &entry_number)) { + &entry_number, &drm_certificate, &wrapped_private_key)) { LOGE("Failed to retrieve usage information"); return USAGE_GET_ENTRY_RETRIEVE_USAGE_INFO_FAILED; } @@ -667,11 +671,13 @@ CdmResponseType UsageTableHeader::StoreEntry(uint32_t usage_entry_number, uint32_t entry_number; std::string provider_session_token, init_data, key_request, key_response, key_renewal_request; + std::string drm_certificate; + CryptoWrappedKey wrapped_private_key; if (!device_files->RetrieveUsageInfoByKeySetId( usage_entry_info_[usage_entry_number].usage_info_file_name, usage_entry_info_[usage_entry_number].key_set_id, &provider_session_token, &key_request, &key_response, &entry, - &entry_number)) { + &entry_number, &drm_certificate, &wrapped_private_key)) { LOGE("Failed to retrieve usage information"); return USAGE_STORE_ENTRY_RETRIEVE_USAGE_INFO_FAILED; } @@ -682,7 +688,7 @@ CdmResponseType UsageTableHeader::StoreEntry(uint32_t usage_entry_number, provider_session_token, key_request, key_response, usage_entry_info_[usage_entry_number].usage_info_file_name, usage_entry_info_[usage_entry_number].key_set_id, usage_entry, - usage_entry_number)) { + usage_entry_number, drm_certificate, wrapped_private_key)) { LOGE("Failed to store usage information"); return USAGE_STORE_USAGE_INFO_FAILED; } diff --git a/libwvdrmengine/cdm/core/test/device_files_unittest.cpp b/libwvdrmengine/cdm/core/test/device_files_unittest.cpp index b06f7019..3b6b7125 100644 --- a/libwvdrmengine/cdm/core/test/device_files_unittest.cpp +++ b/libwvdrmengine/cdm/core/test/device_files_unittest.cpp @@ -27,6 +27,14 @@ namespace { const uint32_t kCertificateLen = 700; const uint32_t kWrappedKeyLen = 500; constexpr size_t kZero = 0; +const std::string kDrmCertificate = "a drm certificate"; +const std::string kAnotherDrmCertificate = "another drm certificate"; +const std::string kWrappedPrivateKey = "a wrapped private key"; +const std::string kAnotherWrappedPrivateKey = "another wrapped private key"; +const CryptoWrappedKey kCryptoWrappedKey(CryptoWrappedKey::kRsa, + kWrappedPrivateKey); +const CryptoWrappedKey kAnotherCryptoWrappedKey(CryptoWrappedKey::kEcc, + kAnotherWrappedPrivateKey); const std::string kEmptyString; @@ -2929,6 +2937,8 @@ const UsageInfo kUsageInfoTestData[] = { "003b12a38554336305525fa6ab70f024a18c73631bb1531eca3f0782c72d" "ba017311b3f1e98c739632e305e4bc0b2561ae2b"), 5, + kEmptyString, + CryptoWrappedKey(), }, a2bs_hex( "0AA407080310012A9D070A9A070A20B8E7F26B6B8B59BABF05B5A1F8927B412A85BC8" @@ -2989,6 +2999,8 @@ const UsageInfo kUsageInfoTestData[] = { "335611bf3bf1a1c89e2dea27c17a9d9a58a74121e840b002e8a6fb590072" "45be786c1f64"), 9, + kEmptyString, + CryptoWrappedKey(), }, a2bs_hex( "0AE80C080310012AE10C0A9A070A20B8E7F26B6B8B59BABF05B5A1F8927B412A85BC8" @@ -3067,6 +3079,8 @@ const UsageInfo kUsageInfoTestData[] = { "41e610d1efb56ed7ce2228a70e2e150afb66edc2da066d463aa90ba0caff" "078fbfec05c8"), 0, + kEmptyString, + CryptoWrappedKey(), }, a2bs_hex("0AF404080310012AED040AEA040A20BB3370CCD3C3C49573D6B74386D1886D98" "88BD81FE3241BCD2BAC9407D1A834E12C001DC0E51CFA5863F6C0B32A4AD7FA4" @@ -3115,6 +3129,8 @@ const UsageInfo kUsageInfoTestData[] = { "9b17eaf020cede0a9e0e7b5d91e4db7abdce445936cb2deecdefefdb14b7" "8f67b7ca5c733c9e88446fd814584584b86becbf6eb2b0e3d5603e8b"), 25, + kEmptyString, + CryptoWrappedKey(), }, a2bs_hex( "0AE604080310012ADF040ADC040A1E9212A6926F21C6727C1EE89D5607047A1636F20" @@ -3163,6 +3179,8 @@ const UsageInfo kUsageInfoTestData[] = { "fd5ed05887b8fa3bfd6ecc7bc91e621342732062d2f4411b763e20328af6" "f8ef5030e2f8027aef9e"), 6, + kEmptyString, + CryptoWrappedKey(), }, a2bs_hex( "0AE809080310012AE1090ADC040A1E9212A6926F21C6727C1EE89D5607047A1636F20" @@ -3231,9 +3249,11 @@ const UsageInfo kUsageInfoTestData[] = { "4ac5bb1da69acb44da06e4522c9a93d310cdda5dac1e1e0b91abff41e4e2" "edda4001"), 7, + kDrmCertificate, + kCryptoWrappedKey, }, a2bs_hex( - "0AEC09080310012AE5090AEA040A20BB3370CCD3C3C49573D6B74386D1886D9888BD8" + "0AA00A080310012A990A0AEA040A20BB3370CCD3C3C49573D6B74386D1886D9888BD8" "1FE3241BCD2BAC9407D1A834E12C001DC0E51CFA5863F6C0B32A4AD7FA40625DADCC2" "DCDE9E7FA3983B8804D9966803181682FC8AE831472E0B2FC26276242FBCE624D286E" "EDECCE5555804913B4F8F86C5AE86160B8434B109169A63DA04C5265102D772C11805" @@ -3251,7 +3271,7 @@ const UsageInfo kUsageInfoTestData[] = { "3646535343430383365663465652A60EA106C124476B753D39368A5966972A2729BB8" "BBEA734A2B3E812B705EACE016C8A03C9A406094D80059EF4CA26F1928FA2DAA5DE9A" "6F22372E5C7A941E610D1EFB56ED7CE2228A70E2E150AFB66EDC2DA066D463AA90BA0" - "CAFF078FBFEC05C830000AF5040A21EACE80E30BFDA213F1CE4DBCFD9D4D24B8E2AE0" + "CAFF078FBFEC05C830000AF7040A21EACE80E30BFDA213F1CE4DBCFD9D4D24B8E2AE0" "0054D167D9D7AE99547062B911312B40168A7665A21348FC0590328608DC520BE40F5" "B749328568FE383EF69C1A587AB2446CF9C41D821373D0856A883B316519A42218F80" "E7BD5764D16BAC9A9B427A7278F5940E563FCF6DEE0FF3AADBB702EBF2C54EC354AE7" @@ -3261,16 +3281,18 @@ const UsageInfo kUsageInfoTestData[] = { "12A2D6DCB15383A6D9AF4519EF804C6053A10C436002DE3A4EFCC017755F4AD1101BD" "C813E2D211732418DEE529CBB413C48AA5884C76A5C6F556A715055560D4247F5BF31" "0956949A3A171A4AA608A48446884E7676D558FF64D392B84E617805693D90F1E9B7B" - "540C383D384D7F7CE06C23618681BD838CEB1A514047F1C562C43159CC5E21588FBFC" - "E8A354111160F1A1E2BD3D798A000579BDFDB977252809EE1502DF8045972FE8AAC84" - "0211C2F8D9E4D5BE18509C327C647D654C4B6CC430B98F1FF37C96FAB087FB561B8CC" - "18480F877C873594D3148FF74B0E3C6327C27CA876DAE7422398FC5E85269CBA49AD0" - "99221C6B7369643865383033353063626566363436336130303235653663632A7C7CC" - "C7CE96055E16A52FA192EA2CF3C9DF3E89B9133A52286F71E6C6D82D0435F6B2155DF" - "DE590B347D8C86F62D7DFBAAE640C237256F609E5DA9CC6C103465FE3441612BBDFDF" - "4D1C24B2147FEB8565CEF4993E439C9D564A39A4AC5BB1DA69ACB44DA06E4522C9A93" - "D310CDDA5DAC1E1E0B91ABFF41E4E2EDDA40013007122062B0F22E176F77881114844" - "DABC6F0EB0F80381D8A06ECDF09913A5CF8E85B3F")}, + "540C383D384D7F7CE06C23618681BD838CEB1A514047F1C562C43159CC5E21588FBF" + "CE8A354111160F1A1E2BD3D798A000579BDFDB977252809EE1502DF8045972FE8AAC8" + "40211C2F8D9E4D5BE18509C327C647D654C4B6CC430B98F1FF37C96FAB087FB561B8C" + "C18480F877C873594D3148FF74B0E3C6327C27CA876DAE7422398FC5E85269CBA49AD" + "099221C6B7369643865383033353063626566363436336130303235653663632A7C7C" + "CC7CE96055E16A52FA192EA2CF3C9DF3E89B9133A52286F71E6C6D82D0435F6B2155D" + "FDE590B347D8C86F62D7DFBAAE640C237256F609E5DA9CC6C103465FE3441612BBDFD" + "F4D1C24B2147FEB8565CEF4993E439C9D564A39A4AC5BB1DA69ACB44DA06E4522C9A9" + "3D310CDDA5DAC1E1E0B91ABFF41E4E2EDDA40013007380012300800122C0A11612064" + "726D20636572746966696361746512156120777261707065642070726976617465206" + "B657918001220BD67878F6AA958EC6996061F69BF65E9806221BCA1CF26FFA4BF1D0B" + "4ECE8806")}, // test vector 6, app id: "", usage entry 2 {"", { @@ -3297,6 +3319,8 @@ const UsageInfo kUsageInfoTestData[] = { "a96388bf6be3c4f4f0b7e2f59efc6b8e965d8fadd5ab86b2bb816d2573ec" "36eb42b571297681be152d40639d"), 0, + kEmptyString, + CryptoWrappedKey(), }, a2bs_hex( "0ADA11080310012AD3110A9A070A20B8E7F26B6B8B59BABF05B5A1F8927B412A85BC8" @@ -3391,9 +3415,11 @@ const UsageInfo kUsageInfoTestData[] = { "a6b634d840925f711ae330599f0e0863800902b05d201a8a87b88a4bc170" "65a1a8a556c34bf86b53afcc9951be15bea9ab55"), 27, + kAnotherDrmCertificate, + kAnotherCryptoWrappedKey, }, a2bs_hex( - "0AB60E080310012AAF0E0ADC040A1E9212A6926F21C6727C1EE89D5607047A1636F20" + "0AF60E080310012AEF0E0ADC040A1E9212A6926F21C6727C1EE89D5607047A1636F20" "6F70E21FDA86E01B6A4B512A401EF947ABED64078EDF5B21FE6D3FB65384595D63A6D" "03E4D1D397C5019DEEB6890D3EF8773002B91E255AF0820FB594069DF55D8ABF96498" "E493F5C70F6B85F50E12A1ED3C039AD0CD838FE44D3FA9E2BBDDEB2919041203111ED" @@ -3421,33 +3447,35 @@ const UsageInfo kUsageInfoTestData[] = { "6A462DEF7A18A7D0ACEBF9F6E8A604356ADE2C81450C5466A472890B03EEFCF65388F" "060E24551C67B7D46AE5D4D841D5CC63D137FD543FAE2C771756590B90E480CA0126F" "1FC0090ACE62499E47569FC52196C788F80139755BDF12A7ACB29FD6E23A46A4C036F" - "04FF1ED6CD714094253BF1C58762C93F0DDF8A73C4BE927FFEC2723A16D8FFE512885" - "1F58537461275F6AA1976E3B399B7243919207E040EC16C5328E8AB082278FCE0E5D3" - "DF5C5F92DBA51FA6613587D4ECE31F2C001B49BFAED434F9512E895C2E09C88DDBF18" - "4BFAFE4D82E5D05A26AC06CDE29FAF6AB05B96685649C923779CE5EF7F316531ADA8E" - "74E45AB1DC1D75648AA2DE052674728867E87639FF9B782A3322186B7369646531643" - "3306233336235356632646562343731362A64D44A9D70A7C582559F089B1C0FDFCBDA" - "F5E26B672FCA5D58E889B407A0BA8599079CDE11FADFAB23AA1B97622839F3B7E1A96" - "F8332BEC5FBCBC9EB64FD5ED05887B8FA3BFD6ECC7BC91E621342732062D2F4411B76" - "3E20328AF6F8EF5030E2F8027AEF9E30060ACB040A1B8F922E955B269458ED1345BDE" - "9A24516520A536817E8E8612154A112A401D4ACC596A52055CEE710E1FEC44796DBF3" - "AE6B017AB156D9BFF7BFDB8F1E6352BFBE453034968F940C36AC18800E22BB2FF7126" - "8053702EF3FCE3FB2D607A078E0D1449FCC9D0675D41B1A65F78E3C02370D18112AAE" - "1E2577FF9087825A45125DB5DEE8E27BD14EA8666B4E8E6ABA6811C40B585AABB9C91" - "85209A48D11130FF690316916961F28286C71C3E985D7DC3352166E414B89DA2C17CC" - "5B69FC9C00990697F51A9002169D3C432F9C2F8B99E11632BD7D6A63F3D57679C567B" - "EDCB2E596ACE1050453732040CB468E9C43F6009B430CA4A4046D017E67A4BADD5B71" - "C0C9FCE2274817F0BCDA311A4F8703E6DC32AEDF30E6F9ABD40E249FC8B0A5045CC1E" - "47E60A60B4893EF92602F5584E1162F4FF3EE6D906228F97B442ACE1FB175D113B671" - "BDBE4CEFFDD98F2BB094C0DFAC03B79541A44D8AFFDC987F4268706B5A554E998907E" - "B7126E8C6BC07C837D8AEEBEA3249E37B4B7DD7327300FE7E62C15981CF73A13E806D" - "065BCADC2C747256907A5493592B07A0C07F9CD805FCDC0D30F70E4C4B2959A0F5238" - "5C6BD3E6EEB4E3D81FDC1A9DC3C76FAF1BFED913D58567FA9B296D27DFF5217C583E7" - "C134A642601F8237221E6B73696465363834393138643663333962666136353261343" - "061643933362A50703F69807C8F4D140168874B924A625132EB3B896A381D617B8FB8" - "3C7314A6B634D840925F711AE330599F0E0863800902B05D201A8A87B88A4BC17065A" - "1A8A556C34BF86B53AFCC9951BE15BEA9AB55301B122002206F46D9D05740AD34B99F" - "10C21A2FA23B8E45DCB00713E32D5CECF239D0A8")}, + "04FF1ED6CD714094253BF1C58762C93F0DDF8A73C4BE927FFEC2723A16D8FFE51288" + "51F58537461275F6AA1976E3B399B7243919207E040EC16C5328E8AB082278FCE0E5D" + "3DF5C5F92DBA51FA6613587D4ECE31F2C001B49BFAED434F9512E895C2E09C88DDBF1" + "84BFAFE4D82E5D05A26AC06CDE29FAF6AB05B96685649C923779CE5EF7F316531ADA8" + "E74E45AB1DC1D75648AA2DE052674728867E87639FF9B782A3322186B736964653164" + "33306233336235356632646562343731362A64D44A9D70A7C582559F089B1C0FDFCBD" + "AF5E26B672FCA5D58E889B407A0BA8599079CDE11FADFAB23AA1B97622839F3B7E1A9" + "6F8332BEC5FBCBC9EB64FD5ED05887B8FA3BFD6ECC7BC91E621342732062D2F4411B7" + "63E20328AF6F8EF5030E2F8027AEF9E30060ACD040A1B8F922E955B269458ED1345BD" + "E9A24516520A536817E8E8612154A112A401D4ACC596A52055CEE710E1FEC44796DBF" + "3AE6B017AB156D9BFF7BFDB8F1E6352BFBE453034968F940C36AC18800E22BB2FF712" + "68053702EF3FCE3FB2D607A078E0D1449FCC9D0675D41B1A65F78E3C02370D18112AA" + "E1E2577FF9087825A45125DB5DEE8E27BD14EA8666B4E8E6ABA6811C40B585AABB9C9" + "185209A48D11130FF690316916961F28286C71C3E985D7DC3352166E414B89DA2C17C" + "C5B69FC9C00990697F51A9002169D3C432F9C2F8B99E11632BD7D6A63F3D57679C567" + "BEDCB2E596ACE1050453732040CB468E9C43F6009B430CA4A4046D017E67A4BADD5B7" + "1C0C9FCE2274817F0BCDA311A4F8703E6DC32AEDF30E6F9ABD40E249FC8B0A5045CC1" + "E47E60A60B4893EF92602F5584E1162F4FF3EE6D906228F97B442ACE1FB175D113B67" + "1BDBE4CEFFDD98F2BB094C0DFAC03B79541A44D8AFFDC987F4268706B5A554E998907" + "EB7126E8C6BC07C837D8AEEBEA3249E37B4B7DD7327300FE7E62C15981CF73A13E806" + "D065BCADC2C747256907A5493592B07A0C07F9CD805FCDC0D30F70E4C4B2959A0F523" + "85C6BD3E6EEB4E3D81FDC1A9DC3C76FAF1BFED913D58567FA9B296D27DFF5217C583E" + "7C134A642601F8237221E6B7369646536383439313864366333396266613635326134" + "3061643933362A50703F69807C8F4D140168874B924A625132EB3B896A381D617B8FB" + "83C7314A6B634D840925F711AE330599F0E0863800902B05D201A8A87B88A4BC17065" + "A1A8A556C34BF86B53AFCC9951BE15BEA9AB55301B3800123C080012380A17616E6F7" + "46865722064726D206365727469666963617465121B616E6F74686572207772617070" + "65642070726976617465206B65791801122082BB366A1D04CD51FA6BE0E5E1F7B9393" + "0C2E887586E2E5FBC6838ADDD3A209B")}, // test vector 8, app id: "app_1", usage entry 2 {"app_1", { @@ -3474,9 +3502,11 @@ const UsageInfo kUsageInfoTestData[] = { "09914a3d7e898d93170317bfcff34861c0d687048cc93542a75a2c99b232" "3fafea1ee0c3e3d24edf2633"), 7, + kDrmCertificate, + kCryptoWrappedKey, }, a2bs_hex( - "0ABD0E080310012AB60E0AEA040A20BB3370CCD3C3C49573D6B74386D1886D9888BD8" + "0AF30E080310012AEC0E0AEA040A20BB3370CCD3C3C49573D6B74386D1886D9888BD8" "1FE3241BCD2BAC9407D1A834E12C001DC0E51CFA5863F6C0B32A4AD7FA40625DADCC2" "DCDE9E7FA3983B8804D9966803181682FC8AE831472E0B2FC26276242FBCE624D286E" "EDECCE5555804913B4F8F86C5AE86160B8434B109169A63DA04C5265102D772C11805" @@ -3494,7 +3524,7 @@ const UsageInfo kUsageInfoTestData[] = { "3646535343430383365663465652A60EA106C124476B753D39368A5966972A2729BB8" "BBEA734A2B3E812B705EACE016C8A03C9A406094D80059EF4CA26F1928FA2DAA5DE9A" "6F22372E5C7A941E610D1EFB56ED7CE2228A70E2E150AFB66EDC2DA066D463AA90BA0" - "CAFF078FBFEC05C830000AF5040A21EACE80E30BFDA213F1CE4DBCFD9D4D24B8E2AE0" + "CAFF078FBFEC05C830000AF7040A21EACE80E30BFDA213F1CE4DBCFD9D4D24B8E2AE0" "0054D167D9D7AE99547062B911312B40168A7665A21348FC0590328608DC520BE40F5" "B749328568FE383EF69C1A587AB2446CF9C41D821373D0856A883B316519A42218F80" "E7BD5764D16BAC9A9B427A7278F5940E563FCF6DEE0FF3AADBB702EBF2C54EC354AE7" @@ -3512,25 +3542,27 @@ const UsageInfo kUsageInfoTestData[] = { "C7CE96055E16A52FA192EA2CF3C9DF3E89B9133A52286F71E6C6D82D0435F6B2155DF" "DE590B347D8C86F62D7DFBAAE640C237256F609E5DA9CC6C103465FE3441612BBDFDF" "4D1C24B2147FEB8565CEF4993E439C9D564A39A4AC5BB1DA69ACB44DA06E4522C9A93" - "D310CDDA5DAC1E1E0B91ABFF41E4E2EDDA400130070ACE040A20D0B9A07AD7FFEEC13" - "784BD60DA011BE3589F3E450227FD36B1A3F6786CDBFE8F129801A419C5687A592099" - "DC67DA8BC4F5EF238C80FE4CE3E2FCB025392EFB14384B581B595A0E8FA95DE637FB2" - "184719EB36AD6539EE9DF0F67697F91D0186E04552E811196029CF4E256518DDF3215" - "AF8EC61442C17D6753B93F9D3A9240BAE39BACF5563659CF47D3A611CE20ED3EBBF86" - "CDDAD60CC2847C4595DCFD934D012CE205960052158461D7C5D480DE2E597876E64E8" - "F8DE692829A31AA402F7C19357E50FC474437C1A635C5BAE8F6F51AFA20750766DB19" - "457DFF7AEF2CAE78848A225CC6A088BBCFFEAD5BE6AAB6FC8AF091BF459C3BD9BCFA1" - "8DE53EF76DB1B4826CF0B8FF7B2D7C44BBADB3CD7AEDD8F639D1F38C52A58611A9782" - "AEACE72BE69A73D2E091A1120DC63F7BA6F1CB6CDDD69E9A236232ED8C14CEE665756" - "BA51F1D2E2530AB3662CE1B6EFBA91C5F10C53ABC886D6F25B5DC40417E54270843F3" - "B454C8C047FC366249E30379B0FBE0174FCAB8B8405AE7F20F6F2B81F11082FF0E270" - "B75F1E1AA7ED5806F4E65B46B872DBCB703D7BF20B9ECAA481425A5218D85A49595F3" - "ED268D61F1BE8E38E6126EB075FA6B7AE80431C8521C4BC2CE701E45D33BFCA9A5B0B" - "66B550AAB21EAE41F84CADFD2517DEE9A2C139AD475C387D25221C6B7369643332316" - "262363336663861336635636435643534613233362A48C3CB027611397B5D70CC0B08" - "E0F5249CD19996DA674E33722902173D45D709914A3D7E898D93170317BFCFF34861C" - "0D687048CC93542A75A2C99B2323FAFEA1EE0C3E3D24EDF263330071220B174821B32" - "5B0A6A900AD8C660C755D3B0273CA6E81D70E2C548CDEC07BE53FA")}, + "D310CDDA5DAC1E1E0B91ABFF41E4E2EDDA4001300738000AD0040A20D0B9A07AD7FFE" + "EC13784BD60DA011BE3589F3E450227FD36B1A3F6786CDBFE8F129801A419C5687A59" + "2099DC67DA8BC4F5EF238C80FE4CE3E2FCB025392EFB14384B581B595A0E8FA95DE63" + "7FB2184719EB36AD6539EE9DF0F67697F91D0186E04552E811196029CF4E256518DDF" + "3215AF8EC61442C17D6753B93F9D3A9240BAE39BACF5563659CF47D3A611CE20ED3EB" + "BF86CDDAD60CC2847C4595DCFD934D012CE205960052158461D7C5D480DE2E597876E" + "64E8F8DE692829A31AA402F7C19357E50FC474437C1A635C5BAE8F6F51AFA20750766" + "DB19457DFF7AEF2CAE78848A225CC6A088BBCFFEAD5BE6AAB6FC8AF091BF459C3BD9B" + "CFA18DE53EF76DB1B4826CF0B8FF7B2D7C44BBADB3CD7AEDD8F639D1F38C52A58611A" + "9782AEACE72BE69A73D2E091A1120DC63F7BA6F1CB6CDDD69E9A236232ED8C14CEE66" + "5756BA51F1D2E2530AB3662CE1B6EFBA91C5F10C53ABC886D6F25B5DC40417E542708" + "43F3B454C8C047FC366249E30379B0FBE0174FCAB8B8405AE7F20F6F2B81F11082FF0" + "E270B75F1E1AA7ED5806F4E65B46B872DBCB703D7BF20B9ECAA481425A5218D85A495" + "95F3ED268D61F1BE8E38E6126EB075FA6B7AE80431C8521C4BC2CE701E45D33BFCA9A" + "5B0B66B550AAB21EAE41F84CADFD2517DEE9A2C139AD475C387D25221C6B736964333" + "2316262363336663861336635636435643534613233362A48C3CB027611397B5D70CC" + "0B08E0F5249CD19996DA674E33722902173D45D709914A3D7E898D93170317BFCFF34" + "861C0D687048CC93542A75A2C99B2323FAFEA1EE0C3E3D24EDF263330073800123008" + "00122C0A11612064726D2063657274696669636174651215612077726170706564207" + "0726976617465206B657918001220C662693A9E231B85CEB7A3A50DEAA8279777B363" + "2C6D9ABC12FBB295018482E4")}, }; // kUsageInfoTestData const DeviceFiles::CdmUsageData kUsageInfoUpdateTestData = { @@ -3565,6 +3597,8 @@ const DeviceFiles::CdmUsageData kUsageInfoUpdateTestData = { "003b12a3855016c8a03c9a406094d80059ef4ca26f1928fa2a3f0782c72d" "ba0e2228a70e2e150afb66e305e4bc0b2561ae2b"), 6, + kEmptyString, + CryptoWrappedKey(), }; // kUsageInfoUpdateTestData struct HlsAttributesInfo { @@ -5177,6 +5211,10 @@ TEST_P(DeviceFilesUsageInfoTest, Store) { usage_data_fields.push_back(kUsageInfoTestData[i].usage_data.license); usage_data_fields.push_back(kUsageInfoTestData[i].usage_data.key_set_id); usage_data_fields.push_back(kUsageInfoTestData[i].usage_data.usage_entry); + usage_data_fields.push_back( + kUsageInfoTestData[i].usage_data.drm_certificate); + usage_data_fields.push_back( + kUsageInfoTestData[i].usage_data.wrapped_private_key.key()); } } @@ -5244,6 +5282,12 @@ TEST_P(DeviceFilesUsageInfoTest, Retrieve) { usage_data_list[i].usage_entry); EXPECT_EQ(kUsageInfoTestData[j].usage_data.usage_entry_number, usage_data_list[i].usage_entry_number); + EXPECT_EQ(kUsageInfoTestData[j].usage_data.drm_certificate, + usage_data_list[i].drm_certificate); + EXPECT_EQ(kUsageInfoTestData[j].usage_data.wrapped_private_key.type(), + usage_data_list[i].wrapped_private_key.type()); + EXPECT_EQ(kUsageInfoTestData[j].usage_data.wrapped_private_key.key(), + usage_data_list[i].wrapped_private_key.key()); found = true; } ++j; diff --git a/libwvdrmengine/cdm/core/test/usage_table_header_unittest.cpp b/libwvdrmengine/cdm/core/test/usage_table_header_unittest.cpp index 7d026ee7..20258519 100644 --- a/libwvdrmengine/cdm/core/test/usage_table_header_unittest.cpp +++ b/libwvdrmengine/cdm/core/test/usage_table_header_unittest.cpp @@ -178,6 +178,8 @@ const DeviceFiles::CdmUsageData kCdmUsageData1 = { /* key_set_id = */ "key_set_id_1", /* usage_entry = */ "usage_entry_1", /* usage_entry_number = */ 0, + /* drm_certificate = */ kDrmCertificate, + /* wrapped_private_key = */ kCryptoWrappedKey, }; const DeviceFiles::CdmUsageData kCdmUsageData2 = { /* provider_session_token = */ "provider_session_token_2", @@ -186,6 +188,8 @@ const DeviceFiles::CdmUsageData kCdmUsageData2 = { /* key_set_id = */ "key_set_id_2", /* usage_entry = */ "usage_entry_2", /* usage_entry_number = */ 0, + /* drm_certificate = */ kDrmCertificate, + /* wrapped_private_key = */ kCryptoWrappedKey, }; const DeviceFiles::CdmUsageData kCdmUsageData3 = { /* provider_session_token = */ "provider_session_token_3", @@ -194,6 +198,8 @@ const DeviceFiles::CdmUsageData kCdmUsageData3 = { /* key_set_id = */ "key_set_id_3", /* usage_entry = */ "usage_entry_3", /* usage_entry_number = */ 0, + /* drm_certificate = */ kDrmCertificate, + /* wrapped_private_key = */ kCryptoWrappedKey, }; const std::vector kEmptyUsageInfoUsageDataList; @@ -404,19 +410,20 @@ class MockDeviceFiles : public DeviceFiles { MOCK_METHOD2(DeleteUsageInfo, bool(const std::string&, const std::string&)); MOCK_METHOD2(DeleteMultipleUsageInfoByKeySetIds, bool(const std::string&, const std::vector&)); - MOCK_METHOD7(RetrieveUsageInfoByKeySetId, + MOCK_METHOD9(RetrieveUsageInfoByKeySetId, bool(const std::string&, const std::string&, std::string*, - CdmKeyMessage*, CdmKeyResponse*, CdmUsageEntry*, - uint32_t*)); + CdmKeyMessage*, CdmKeyResponse*, CdmUsageEntry*, uint32_t*, + std::string*, CryptoWrappedKey*)); MOCK_METHOD2(StoreLicense, bool(const CdmLicenseData&, ResponseType*)); MOCK_METHOD1(DeleteLicense, bool(const std::string&)); MOCK_METHOD0(DeleteAllLicenses, bool()); MOCK_METHOD0(DeleteAllUsageInfo, bool()); MOCK_METHOD0(DeleteUsageTableInfo, bool()); - MOCK_METHOD7(StoreUsageInfo, + MOCK_METHOD9(StoreUsageInfo, bool(const std::string&, const CdmKeyMessage&, const CdmKeyResponse&, const std::string&, - const std::string&, const CdmUsageEntry&, uint32_t)); + const std::string&, const CdmUsageEntry&, uint32_t, + const std::string&, const CryptoWrappedKey&)); MOCK_METHOD2(RetrieveUsageInfo, bool(const std::string&, std::vector*)); MOCK_METHOD1(ListLicenses, bool(std::vector* key_set_ids)); @@ -1446,13 +1453,13 @@ TEST_F(UsageTableHeaderTest, InvalidateEntry_LastSecureStopEntriesAreMissing) { RetrieveUsageInfoByKeySetId( kUsageEntryInfoSecureStop2.usage_info_file_name, kUsageEntryInfoSecureStop2.key_set_id, NotNull(), NotNull(), - NotNull(), NotNull(), NotNull())) + NotNull(), NotNull(), NotNull(), NotNull(), NotNull())) .WillOnce(Return(false)); EXPECT_CALL(*device_files_, RetrieveUsageInfoByKeySetId( kUsageEntryInfoSecureStop3.usage_info_file_name, kUsageEntryInfoSecureStop3.key_set_id, NotNull(), NotNull(), - NotNull(), NotNull(), NotNull())) + NotNull(), NotNull(), NotNull(), NotNull(), NotNull())) .WillOnce(Return(false)); // Shrink to contain only the one valid entry. @@ -1619,23 +1626,25 @@ TEST_F(UsageTableHeaderTest, RetrieveUsageInfoByKeySetId( kUsageEntryInfoSecureStop2.usage_info_file_name, kUsageEntryInfoSecureStop2.key_set_id, NotNull(), NotNull(), - NotNull(), NotNull(), NotNull())) - .WillOnce(DoAll(SetArgPointee<2>(kProviderSessionToken), - SetArgPointee<3>(kKeyRequest), - SetArgPointee<4>(kKeyResponse), - SetArgPointee<5>(kUsageEntry), - SetArgPointee<6>(2) /* Mismatch */, Return(true))); + NotNull(), NotNull(), NotNull(), NotNull(), NotNull())) + .WillOnce(DoAll( + SetArgPointee<2>(kProviderSessionToken), + SetArgPointee<3>(kKeyRequest), SetArgPointee<4>(kKeyResponse), + SetArgPointee<5>(kUsageEntry), SetArgPointee<6>(2) /* Mismatch */, + SetArgPointee<7>(kDrmCertificate), + SetArgPointee<8>(kCryptoWrappedKey), Return(true))); EXPECT_CALL(*device_files_, RetrieveUsageInfoByKeySetId( kUsageEntryInfoSecureStop3.usage_info_file_name, kUsageEntryInfoSecureStop3.key_set_id, NotNull(), NotNull(), - NotNull(), NotNull(), NotNull())) - .WillOnce(DoAll(SetArgPointee<2>(kProviderSessionToken), - SetArgPointee<3>(kKeyRequest), - SetArgPointee<4>(kKeyResponse), - SetArgPointee<5>(kUsageEntry), - SetArgPointee<6>(3) /* Mismatch */, Return(true))); + NotNull(), NotNull(), NotNull(), NotNull(), NotNull())) + .WillOnce(DoAll( + SetArgPointee<2>(kProviderSessionToken), + SetArgPointee<3>(kKeyRequest), SetArgPointee<4>(kKeyResponse), + SetArgPointee<5>(kUsageEntry), SetArgPointee<6>(3) /* Mismatch */, + SetArgPointee<7>(kDrmCertificate), + SetArgPointee<8>(kCryptoWrappedKey), Return(true))); // Shrink to contain only the one valid entry. EXPECT_CALL(*crypto_session_, @@ -1888,11 +1897,13 @@ TEST_F(UsageTableHeaderTest, RetrieveUsageInfoByKeySetId( kUsageEntryInfoSecureStop3.usage_info_file_name, kUsageEntryInfoSecureStop3.key_set_id, NotNull(), NotNull(), - NotNull(), NotNull(), NotNull())) - .WillOnce(DoAll( - SetArgPointee<2>(kProviderSessionToken), - SetArgPointee<3>(kKeyRequest), SetArgPointee<4>(kKeyResponse), - SetArgPointee<5>(kUsageEntry), SetArgPointee<6>(4), Return(true))); + NotNull(), NotNull(), NotNull(), NotNull(), NotNull())) + .WillOnce(DoAll(SetArgPointee<2>(kProviderSessionToken), + SetArgPointee<3>(kKeyRequest), + SetArgPointee<4>(kKeyResponse), + SetArgPointee<5>(kUsageEntry), SetArgPointee<6>(4), + SetArgPointee<7>(kDrmCertificate), + SetArgPointee<8>(kCryptoWrappedKey), Return(true))); // Calls during Move(). EXPECT_CALL(*crypto_session_, Open(kLevelDefault)).WillOnce(Return(NO_ERROR)); @@ -2098,11 +2109,13 @@ TEST_F( RetrieveUsageInfoByKeySetId( kUsageEntryInfoSecureStop3.usage_info_file_name, kUsageEntryInfoSecureStop3.key_set_id, NotNull(), NotNull(), - NotNull(), NotNull(), NotNull())) - .WillOnce(DoAll( - SetArgPointee<2>(kProviderSessionToken), - SetArgPointee<3>(kKeyRequest), SetArgPointee<4>(kKeyResponse), - SetArgPointee<5>(kUsageEntry), SetArgPointee<6>(4), Return(true))); + NotNull(), NotNull(), NotNull(), NotNull(), NotNull())) + .WillOnce(DoAll(SetArgPointee<2>(kProviderSessionToken), + SetArgPointee<3>(kKeyRequest), + SetArgPointee<4>(kKeyResponse), + SetArgPointee<5>(kUsageEntry), SetArgPointee<6>(4), + SetArgPointee<7>(kDrmCertificate), + SetArgPointee<8>(kCryptoWrappedKey), Return(true))); EXPECT_CALL(*crypto_session_, LoadUsageEntry(4, kUsageEntry)) .WillOnce(Return(LOAD_USAGE_ENTRY_INVALID_SESSION)); @@ -2112,11 +2125,13 @@ TEST_F( RetrieveUsageInfoByKeySetId( kUsageEntryInfoSecureStop2.usage_info_file_name, kUsageEntryInfoSecureStop2.key_set_id, NotNull(), NotNull(), - NotNull(), NotNull(), NotNull())) - .WillOnce(DoAll( - SetArgPointee<2>(kProviderSessionToken), - SetArgPointee<3>(kKeyRequest), SetArgPointee<4>(kKeyResponse), - SetArgPointee<5>(kUsageEntry), SetArgPointee<6>(3), Return(true))); + NotNull(), NotNull(), NotNull(), NotNull(), NotNull())) + .WillOnce(DoAll(SetArgPointee<2>(kProviderSessionToken), + SetArgPointee<3>(kKeyRequest), + SetArgPointee<4>(kKeyResponse), + SetArgPointee<5>(kUsageEntry), SetArgPointee<6>(3), + SetArgPointee<7>(kDrmCertificate), + SetArgPointee<8>(kCryptoWrappedKey), Return(true))); EXPECT_CALL(*crypto_session_, LoadUsageEntry(3, kUsageEntry)) .WillOnce(Return(LOAD_USAGE_ENTRY_INVALID_SESSION)); @@ -2311,12 +2326,14 @@ TEST_F(UsageTableHeaderTest, InvalidateEntry_LastEntryIsSecureStop) { RetrieveUsageInfoByKeySetId( kUsageEntryInfoSecureStop3.usage_info_file_name, kUsageEntryInfoSecureStop3.key_set_id, NotNull(), NotNull(), - NotNull(), NotNull(), NotNull())) + NotNull(), NotNull(), NotNull(), NotNull(), NotNull())) .Times(2) // First to get entry, second to update. - .WillRepeatedly(DoAll( - SetArgPointee<2>(kProviderSessionToken), - SetArgPointee<3>(kKeyRequest), SetArgPointee<4>(kKeyResponse), - SetArgPointee<5>(kUsageEntry), SetArgPointee<6>(4), Return(true))); + .WillRepeatedly(DoAll(SetArgPointee<2>(kProviderSessionToken), + SetArgPointee<3>(kKeyRequest), + SetArgPointee<4>(kKeyResponse), + SetArgPointee<5>(kUsageEntry), SetArgPointee<6>(4), + SetArgPointee<7>(kDrmCertificate), + SetArgPointee<8>(kCryptoWrappedKey), Return(true))); EXPECT_CALL( *device_files_, DeleteUsageInfo(kUsageEntryInfoSecureStop3.usage_info_file_name, _)) @@ -2324,7 +2341,7 @@ TEST_F(UsageTableHeaderTest, InvalidateEntry_LastEntryIsSecureStop) { EXPECT_CALL( *device_files_, StoreUsageInfo(_, _, _, kUsageEntryInfoSecureStop3.usage_info_file_name, - kUsageEntryInfoSecureStop3.key_set_id, _, 1)) + kUsageEntryInfoSecureStop3.key_set_id, _, 1, _, _)) .WillOnce(Return(true)); EXPECT_CALL(*crypto_session_, LoadUsageEntry(4, kUsageEntry)) .WillOnce(Return(NO_ERROR)); @@ -2335,12 +2352,14 @@ TEST_F(UsageTableHeaderTest, InvalidateEntry_LastEntryIsSecureStop) { RetrieveUsageInfoByKeySetId( kUsageEntryInfoSecureStop2.usage_info_file_name, kUsageEntryInfoSecureStop2.key_set_id, NotNull(), NotNull(), - NotNull(), NotNull(), NotNull())) + NotNull(), NotNull(), NotNull(), NotNull(), NotNull())) .Times(2) // First to get entry, second to update. - .WillRepeatedly(DoAll( - SetArgPointee<2>(kProviderSessionToken), - SetArgPointee<3>(kKeyRequest), SetArgPointee<4>(kKeyResponse), - SetArgPointee<5>(kUsageEntry), SetArgPointee<6>(3), Return(true))); + .WillRepeatedly(DoAll(SetArgPointee<2>(kProviderSessionToken), + SetArgPointee<3>(kKeyRequest), + SetArgPointee<4>(kKeyResponse), + SetArgPointee<5>(kUsageEntry), SetArgPointee<6>(3), + SetArgPointee<7>(kDrmCertificate), + SetArgPointee<8>(kCryptoWrappedKey), Return(true))); EXPECT_CALL( *device_files_, DeleteUsageInfo(kUsageEntryInfoSecureStop2.usage_info_file_name, _)) @@ -2348,7 +2367,7 @@ TEST_F(UsageTableHeaderTest, InvalidateEntry_LastEntryIsSecureStop) { EXPECT_CALL( *device_files_, StoreUsageInfo(_, _, _, kUsageEntryInfoSecureStop2.usage_info_file_name, - kUsageEntryInfoSecureStop2.key_set_id, _, 2)) + kUsageEntryInfoSecureStop2.key_set_id, _, 2, _, _)) .WillOnce(Return(true)); EXPECT_CALL(*crypto_session_, LoadUsageEntry(3, kUsageEntry)) .WillOnce(Return(NO_ERROR)); @@ -2561,12 +2580,14 @@ TEST_F(UsageTableHeaderTest, RetrieveUsageInfoByKeySetId( kUsageEntryInfoSecureStop3.usage_info_file_name, kUsageEntryInfoSecureStop3.key_set_id, NotNull(), NotNull(), - NotNull(), NotNull(), NotNull())) + NotNull(), NotNull(), NotNull(), NotNull(), NotNull())) .Times(2) // First to get entry, second to update. - .WillRepeatedly(DoAll( - SetArgPointee<2>(kProviderSessionToken), - SetArgPointee<3>(kKeyRequest), SetArgPointee<4>(kKeyResponse), - SetArgPointee<5>(kUsageEntry), SetArgPointee<6>(4), Return(true))); + .WillRepeatedly(DoAll(SetArgPointee<2>(kProviderSessionToken), + SetArgPointee<3>(kKeyRequest), + SetArgPointee<4>(kKeyResponse), + SetArgPointee<5>(kUsageEntry), SetArgPointee<6>(4), + SetArgPointee<7>(kDrmCertificate), + SetArgPointee<8>(kCryptoWrappedKey), Return(true))); EXPECT_CALL( *device_files_, DeleteUsageInfo(kUsageEntryInfoSecureStop3.usage_info_file_name, _)) @@ -2574,7 +2595,7 @@ TEST_F(UsageTableHeaderTest, EXPECT_CALL( *device_files_, StoreUsageInfo(_, _, _, kUsageEntryInfoSecureStop3.usage_info_file_name, - kUsageEntryInfoSecureStop3.key_set_id, _, 1)) + kUsageEntryInfoSecureStop3.key_set_id, _, 1, _, _)) .WillOnce(Return(true)); EXPECT_CALL(*crypto_session_, LoadUsageEntry(4, kUsageEntry)) .WillOnce(Return(NO_ERROR)); @@ -2585,12 +2606,14 @@ TEST_F(UsageTableHeaderTest, RetrieveUsageInfoByKeySetId( kUsageEntryInfoSecureStop2.usage_info_file_name, kUsageEntryInfoSecureStop2.key_set_id, NotNull(), NotNull(), - NotNull(), NotNull(), NotNull())) + NotNull(), NotNull(), NotNull(), NotNull(), NotNull())) .Times(2) // First to get entry, second to update. - .WillRepeatedly(DoAll( - SetArgPointee<2>(kProviderSessionToken), - SetArgPointee<3>(kKeyRequest), SetArgPointee<4>(kKeyResponse), - SetArgPointee<5>(kUsageEntry), SetArgPointee<6>(3), Return(true))); + .WillRepeatedly(DoAll(SetArgPointee<2>(kProviderSessionToken), + SetArgPointee<3>(kKeyRequest), + SetArgPointee<4>(kKeyResponse), + SetArgPointee<5>(kUsageEntry), SetArgPointee<6>(3), + SetArgPointee<7>(kDrmCertificate), + SetArgPointee<8>(kCryptoWrappedKey), Return(true))); EXPECT_CALL( *device_files_, DeleteUsageInfo(kUsageEntryInfoSecureStop2.usage_info_file_name, _)) @@ -2598,7 +2621,7 @@ TEST_F(UsageTableHeaderTest, EXPECT_CALL( *device_files_, StoreUsageInfo(_, _, _, kUsageEntryInfoSecureStop2.usage_info_file_name, - kUsageEntryInfoSecureStop2.key_set_id, _, 2)) + kUsageEntryInfoSecureStop2.key_set_id, _, 2, _, _)) .WillOnce(Return(true)); EXPECT_CALL(*crypto_session_, LoadUsageEntry(3, kUsageEntry)) .WillOnce(Return(NO_ERROR)); @@ -3292,7 +3315,8 @@ TEST_F(UsageTableHeaderTest, LruUsageTableUpgrade_NoAction) { // These function are called specifically by the LRU upgrading system. EXPECT_CALL(*device_files_, RetrieveLicense(_, _, _)).Times(0); - EXPECT_CALL(*device_files_, RetrieveUsageInfoByKeySetId(_, _, _, _, _, _, _)) + EXPECT_CALL(*device_files_, + RetrieveUsageInfoByKeySetId(_, _, _, _, _, _, _, _, _)) .Times(0); EXPECT_TRUE(usage_table_header_->Init(kSecurityLevelL1, crypto_session_)); @@ -3326,12 +3350,14 @@ TEST_F(UsageTableHeaderTest, LruUsageTableUpgrade_Succeed) { Return(true))); } else { EXPECT_CALL(*device_files_, - RetrieveUsageInfoByKeySetId( - info.usage_info_file_name, info.key_set_id, NotNull(), - NotNull(), NotNull(), NotNull(), NotNull())) + RetrieveUsageInfoByKeySetId(info.usage_info_file_name, + info.key_set_id, NotNull(), + NotNull(), NotNull(), NotNull(), + NotNull(), NotNull(), NotNull())) .WillOnce(DoAll(SetArgPointee<4>(kUpgradableLicenseInfoList[i]), SetArgPointee<6>(static_cast(i)), - Return(true))); + SetArgPointee<7>(kDrmCertificate), + SetArgPointee<8>(kCryptoWrappedKey), Return(true))); } } @@ -3449,12 +3475,14 @@ TEST_F(UsageTableHeaderTest, DoAll(SetArgPointee<1>(license_data_list[i]), Return(true))); } else { EXPECT_CALL(*device_files_, - RetrieveUsageInfoByKeySetId( - info.usage_info_file_name, info.key_set_id, NotNull(), - NotNull(), NotNull(), NotNull(), NotNull())) + RetrieveUsageInfoByKeySetId(info.usage_info_file_name, + info.key_set_id, NotNull(), + NotNull(), NotNull(), NotNull(), + NotNull(), NotNull(), NotNull())) .WillOnce(DoAll(SetArgPointee<4>(upgradable_license_info_list[i]), SetArgPointee<6>(static_cast(i)), - Return(true))); + SetArgPointee<7>(kDrmCertificate), + SetArgPointee<8>(kCryptoWrappedKey), Return(true))); } } @@ -3502,9 +3530,10 @@ TEST_F(UsageTableHeaderTest, LruUsageTableUpgrade_AllFailure) { .WillOnce(Return(false)); } else { EXPECT_CALL(*device_files_, - RetrieveUsageInfoByKeySetId( - info.usage_info_file_name, info.key_set_id, NotNull(), - NotNull(), NotNull(), NotNull(), NotNull())) + RetrieveUsageInfoByKeySetId(info.usage_info_file_name, + info.key_set_id, NotNull(), + NotNull(), NotNull(), NotNull(), + NotNull(), NotNull(), NotNull())) .WillOnce(Return(false)); } }