From 5eed0446da3583d87aa2ef41d580ea2a968c8ba1 Mon Sep 17 00:00:00 2001 From: Alex Dale Date: Fri, 9 Apr 2021 01:44:02 -0700 Subject: [PATCH] Clean up CdmEngine logs. [ Merge of http://go/wvgerrit/121568 ] The CdmEngine logs had both too much and too little information. Since our logging has been enabled to print function names natively, many of the log information has become superfluous. Needless information has been removed, and many of the important INFO logs have been reduced to only the information not present in the function name. Some of the INFO and ERROR logs were missing identifiers to match failures with the same session request should the failures take more than a few milliseconds to occur. CDM session IDs and key set IDs have been included in all the logs that _appeared_ to have a slow operation between the top of the method and log. To help make enum values more readable, several enums-to-string functions have been implemented. These converters are intended for INFO logging and as such, do not log any addition information should the enum be out of range. To help make empty and null identifiers more readable in the logs, empty strings will be logged as and null strings will be logged as . While working through the "cdm_engine.cpp" file, a few minor changes have been made: - Adjust if statements to match with Google C++ style guidelines - Skipped anything that was not obvious - Added a const qualifier to variables where appropriate - Moved some null checks to the top of the method - Only where sequence is non-critical to normal operation - Removed unnecessary string to vector to string conversions - Reject empty |force_session_id| - Already enforced on CE CDM code and not uesd on Android Bug: 183576879 Test: CE CDM unittests Change-Id: Id165373055f7ce6097c93c48f84af74bd353c8cb --- libwvdrmengine/cdm/Android.bp | 1 + .../cdm/core/include/crypto_session.h | 3 +- libwvdrmengine/cdm/core/include/license.h | 2 - .../cdm/core/include/wv_cdm_types.h | 16 + libwvdrmengine/cdm/core/src/cdm_engine.cpp | 633 ++++++++---------- .../cdm/core/src/certificate_provisioning.cpp | 5 +- .../cdm/core/src/crypto_session.cpp | 5 - libwvdrmengine/cdm/core/src/wv_cdm_types.cpp | 76 +++ 8 files changed, 391 insertions(+), 350 deletions(-) create mode 100644 libwvdrmengine/cdm/core/src/wv_cdm_types.cpp diff --git a/libwvdrmengine/cdm/Android.bp b/libwvdrmengine/cdm/Android.bp index 8a2ba34a..4e66959b 100644 --- a/libwvdrmengine/cdm/Android.bp +++ b/libwvdrmengine/cdm/Android.bp @@ -61,6 +61,7 @@ cc_library_static { CORE_SRC_DIR + "/privacy_crypto_boringssl.cpp", CORE_SRC_DIR + "/service_certificate.cpp", CORE_SRC_DIR + "/usage_table_header.cpp", + CORE_SRC_DIR + "/wv_cdm_types.cpp", SRC_DIR + "/wv_content_decryption_module.cpp", METRICS_SRC_DIR + "/attribute_handler.cpp", METRICS_SRC_DIR + "/counter_metric.cpp", diff --git a/libwvdrmengine/cdm/core/include/crypto_session.h b/libwvdrmengine/cdm/core/include/crypto_session.h index 871c21b4..6ed570be 100644 --- a/libwvdrmengine/cdm/core/include/crypto_session.h +++ b/libwvdrmengine/cdm/core/include/crypto_session.h @@ -25,6 +25,7 @@ namespace wvcdm { class CryptoKey; +class CryptoSessionFactory; class UsageTableHeader; using CryptoKeyMap = std::map; @@ -40,8 +41,6 @@ OEMCrypto_Substring GetSubstring(const std::string& message = "", bool set_zero = false); OEMCryptoCipherMode ToOEMCryptoCipherMode(CdmCipherMode cipher_mode); -class CryptoSessionFactory; - class CryptoSession { public: using HdcpCapability = OEMCrypto_HDCP_Capability; diff --git a/libwvdrmengine/cdm/core/include/license.h b/libwvdrmengine/cdm/core/include/license.h index 59b51ab1..c0f83b69 100644 --- a/libwvdrmengine/cdm/core/include/license.h +++ b/libwvdrmengine/cdm/core/include/license.h @@ -21,7 +21,6 @@ class VersionInfo; } // namespace video_widevine namespace wvcdm { - class Clock; class CryptoSession; class PolicyEngine; @@ -186,7 +185,6 @@ class CdmLicense { CORE_DISALLOW_COPY_AND_ASSIGN(CdmLicense); }; - } // namespace wvcdm #endif // WVCDM_CORE_LICENSE_H_ diff --git a/libwvdrmengine/cdm/core/include/wv_cdm_types.h b/libwvdrmengine/cdm/core/include/wv_cdm_types.h index 7e112ccf..d4643ad1 100644 --- a/libwvdrmengine/cdm/core/include/wv_cdm_types.h +++ b/libwvdrmengine/cdm/core/include/wv_cdm_types.h @@ -793,6 +793,22 @@ class KeyMessage; class Request; class Key; +// Logging utilities for types defined above. +// Converts the different enum types to a human readable C-string for +// logging. Query strings values are used if available for the enum. +// These functions will fail silently to avoid double logging. +const char* CdmCertificateTypeToString(CdmCertificateType type); +const char* CdmLicenseTypeToString(CdmLicenseType license_type); +const char* CdmSecurityLevelToString(CdmSecurityLevel security_level); +const char* SecurityLevelToString(SecurityLevel security_level); +// Both IdToString() and IdPtrToString() functions are used to convert +// session IDs, key set IDs or other CDM specific identifiers to a +// loggable format. +const char* IdToString(const std::string& id); +// Some CDM API function allow for optional string parameters to be +// provided as string pointers. +const char* IdPtrToString(const std::string* id); + } // namespace wvcdm #endif // WVCDM_CORE_WV_CDM_TYPES_H_ diff --git a/libwvdrmengine/cdm/core/src/cdm_engine.cpp b/libwvdrmengine/cdm/core/src/cdm_engine.cpp index ac7091a9..c92556a2 100644 --- a/libwvdrmengine/cdm/core/src/cdm_engine.cpp +++ b/libwvdrmengine/cdm/core/src/cdm_engine.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #include "cdm_random.h" #include "cdm_session.h" @@ -25,6 +26,7 @@ #include "wv_cdm_constants.h" #include "wv_cdm_event_listener.h" +namespace wvcdm { namespace { const uint64_t kReleaseSessionTimeToLive = 60; // seconds const uint32_t kUpdateUsageInformationPeriod = 60; // seconds @@ -42,8 +44,6 @@ wvcdm::CdmOfflineLicenseState MapDeviceFilesLicenseState( } } // namespace -namespace wvcdm { - class UsagePropertySet : public CdmClientPropertySet { public: UsagePropertySet() {} @@ -111,41 +111,45 @@ CdmResponseType CdmEngine::OpenSession(const CdmKeySystem& key_system, WvCdmEventListener* event_listener, const CdmSessionId* forced_session_id, CdmSessionId* session_id) { - LOGI("Opening session"); - if (!ValidateKeySystem(key_system)) { - LOGI("Invalid key system: %s", key_system.c_str()); + LOGI("Invalid key system: %s", IdToString(key_system)); return INVALID_KEY_SYSTEM; } - if (!session_id && !forced_session_id) { - LOGE("No (forced/)session ID destination provided"); + if (session_id == nullptr && forced_session_id == nullptr) { + LOGE("Input |forced_session_id| and output |session_id| are both null"); return PARAMETER_NULL; } - if (forced_session_id) { + if (forced_session_id != nullptr) { + if (forced_session_id->empty()) { + // This should be enforce by the CE CDM code. + return EMPTY_SESSION_ID; + } if (session_map_.Exists(*forced_session_id)) { return DUPLICATE_SESSION_ID_SPECIFIED; } + LOGD("forced_session_id = %s", IdPtrToString(forced_session_id)); } CloseExpiredReleaseSessions(); std::unique_ptr new_session( new CdmSession(file_system_, metrics_->AddSession())); - CdmResponseType sts = + const CdmResponseType sts = new_session->Init(property_set, forced_session_id, event_listener); - if (sts != NO_ERROR) { - if (sts == NEED_PROVISIONING) { - // Reserve a session ID so the CDM can return success. - if (session_id) *session_id = new_session->GenerateSessionId(); - } else { - LOGE("Bad session init: status = %d", static_cast(sts)); - } + if (sts == NEED_PROVISIONING) { + // Reserve a session ID so the CDM can return success. + if (session_id) *session_id = new_session->GenerateSessionId(); return sts; } - CdmSessionId id = new_session->session_id(); - LOGI("New session ID: %s", id.c_str()); + if (sts != NO_ERROR) { + LOGE("Bad session init: status = %d", static_cast(sts)); + return sts; + } + + const CdmSessionId id = new_session->session_id(); + LOGI("New session: session_id = %s", IdToString(id)); std::unique_lock lock(session_map_lock_); session_map_.Add(id, new_session.release()); @@ -156,8 +160,7 @@ CdmResponseType CdmEngine::OpenSession(const CdmKeySystem& key_system, CdmResponseType CdmEngine::OpenKeySetSession( const CdmKeySetId& key_set_id, CdmClientPropertySet* property_set, WvCdmEventListener* event_listener) { - LOGI("Opening key set session: key_set_id = %s", key_set_id.c_str()); - + LOGI("key_set_id = %s", IdToString(key_set_id)); if (key_set_id.empty()) { LOGE("Invalid key set ID"); return EMPTY_KEYSET_ID_ENG_1; @@ -191,10 +194,10 @@ CdmResponseType CdmEngine::OpenKeySetSession( } CdmResponseType CdmEngine::CloseSession(const CdmSessionId& session_id) { - LOGI("Closing session: session_id = %s", session_id.c_str()); + LOGI("session_id = %s", IdToString(session_id)); std::unique_lock lock(session_map_lock_); if (!session_map_.CloseSession(session_id)) { - LOGE("Session not found: %s", session_id.c_str()); + LOGE("Session not found: session_id = %s", IdToString(session_id)); return SESSION_NOT_FOUND_1; } metrics_->ConsolidateSessions(); @@ -202,21 +205,18 @@ CdmResponseType CdmEngine::CloseSession(const CdmSessionId& session_id) { } CdmResponseType CdmEngine::CloseKeySetSession(const CdmKeySetId& key_set_id) { - LOGI("Closing key set session: key_set_id = %s", key_set_id.c_str()); - + LOGI("key_set_id = %s", IdToString(key_set_id)); CdmSessionId session_id; { std::unique_lock lock(release_key_sets_lock_); CdmReleaseKeySetMap::iterator iter = release_key_sets_.find(key_set_id); if (iter == release_key_sets_.end()) { - LOGE("Key set ID not found: %s", key_set_id.c_str()); + LOGE("Key set not found: key_set_id = %s", IdToString(key_set_id)); return KEYSET_ID_NOT_FOUND_1; } session_id = iter->second.first; } - - CdmResponseType sts = CloseSession(session_id); - + const CdmResponseType sts = CloseSession(session_id); std::unique_lock lock(release_key_sets_lock_); CdmReleaseKeySetMap::iterator iter = release_key_sets_.find(key_set_id); if (iter != release_key_sets_.end()) { @@ -234,30 +234,33 @@ CdmResponseType CdmEngine::GenerateKeyRequest( const CdmSessionId& session_id, const CdmKeySetId& key_set_id, const InitializationData& init_data, const CdmLicenseType license_type, CdmAppParameterMap& app_parameters, CdmKeyRequest* key_request) { - LOGI("Generating key request: session_id = %s", session_id.c_str()); + LOGI("session_id = %s, key_set_id = %s, license_type = %s", + IdToString(session_id), IdToString(key_set_id), + CdmLicenseTypeToString(license_type)); + if (key_request == nullptr) { + LOGE("Output |key_request| is null"); + return PARAMETER_NULL; + } CdmSessionId id = session_id; - CdmResponseType sts; - // NOTE: If AlwaysUseKeySetIds() is true, there is no need to consult the - // release_key_sets_ map for release licenses. + // |release_key_sets_| map for release licenses. if (license_type == kLicenseTypeRelease && !Properties::AlwaysUseKeySetIds()) { if (key_set_id.empty()) { LOGE("Invalid key set ID"); return EMPTY_KEYSET_ID_ENG_2; } - LOGI("Key set ID: %s", key_set_id.c_str()); - if (!session_id.empty()) { - LOGE("Invalid session ID: %s", session_id.c_str()); + LOGE("Session ID should be empty: session_id = %s", + IdToString(session_id)); return INVALID_SESSION_ID; } std::unique_lock lock(release_key_sets_lock_); CdmReleaseKeySetMap::iterator iter = release_key_sets_.find(key_set_id); if (iter == release_key_sets_.end()) { - LOGE("Key set ID not found: %s", key_set_id.c_str()); + LOGE("Key set not found: key_set_id = %s", IdToString(key_set_id)); return KEYSET_ID_NOT_FOUND_2; } @@ -266,37 +269,34 @@ CdmResponseType CdmEngine::GenerateKeyRequest( std::shared_ptr session; if (!session_map_.FindSession(id, &session)) { - LOGE("Session ID not found: %s", id.c_str()); + LOGE("Session not found: session_id = %s", IdToString(id)); return SESSION_NOT_FOUND_2; } - if (!key_request) { - LOGE("Output destination provided"); - return PARAMETER_NULL; - } - key_request->message.clear(); if (license_type == kLicenseTypeRelease && !session->license_received()) { int error_detail = NO_ERROR; - sts = session->RestoreOfflineSession(key_set_id, kLicenseTypeRelease, - &error_detail); + const CdmResponseType restore_status = session->RestoreOfflineSession( + key_set_id, kLicenseTypeRelease, &error_detail); session->GetMetrics()->cdm_session_restore_offline_session_.Increment( - sts, error_detail); - if (sts != KEY_ADDED) { - LOGE("Key release restoration failed, status = %d", - static_cast(sts)); - return sts; + restore_status, error_detail); + if (restore_status != KEY_ADDED) { + LOGE("Key release restoration failed: session_id = %s, status = %d", + IdToString(id), static_cast(restore_status)); + return restore_status; } } - sts = session->GenerateKeyRequest(init_data, license_type, app_parameters, - key_request); + const CdmResponseType sts = session->GenerateKeyRequest( + init_data, license_type, app_parameters, key_request); if (KEY_ADDED == sts) { return sts; - } else if (KEY_MESSAGE != sts) { - LOGE("Key request generation failed, status = %d", static_cast(sts)); + } + if (KEY_MESSAGE != sts) { + LOGE("CdmSession::GenerateKeyRequest failed: session_id = %s, status = %d", + IdToString(id), static_cast(sts)); return sts; } @@ -304,11 +304,8 @@ CdmResponseType CdmEngine::GenerateKeyRequest( OnKeyReleaseEvent(key_set_id); } - LOGD( - "key request: (%zu) %s", key_request->message.size(), - wvcdm::Base64SafeEncode(std::vector(key_request->message.begin(), - key_request->message.end())) - .c_str()); + LOGD("key_request = (%zu) %s", key_request->message.size(), + wvcdm::Base64SafeEncode(key_request->message).c_str()); return KEY_MESSAGE; } @@ -317,18 +314,18 @@ CdmResponseType CdmEngine::AddKey(const CdmSessionId& session_id, const CdmKeyResponse& key_data, CdmLicenseType* license_type, CdmKeySetId* key_set_id) { - LOGI("Adding key: session_id = %s", session_id.c_str()); + LOGI("session_id = %s, key_set_id = %s", IdToString(session_id), + IdPtrToString(key_set_id)); if (license_type == nullptr) { - LOGE("No license type provided"); + LOGE("Output |license_type| is null"); return PARAMETER_NULL; } CdmSessionId id = session_id; - bool license_type_release = session_id.empty(); - + const bool license_type_release = session_id.empty(); if (license_type_release) { - if (!key_set_id) { - LOGE("No key set ID provided"); + if (key_set_id == nullptr) { + LOGE("Input/output |key_set_id| is null"); return PARAMETER_NULL; } @@ -340,21 +337,18 @@ CdmResponseType CdmEngine::AddKey(const CdmSessionId& session_id, std::unique_lock lock(release_key_sets_lock_); CdmReleaseKeySetMap::iterator iter = release_key_sets_.find(*key_set_id); if (iter == release_key_sets_.end()) { - LOGE("Key set ID not found: %s", key_set_id->c_str()); + LOGE("Key set not found: key_set_id = %s", IdPtrToString(key_set_id)); return KEYSET_ID_NOT_FOUND_3; } - id = iter->second.first; } else { - LOGD("key data: (%zu) %s", key_data.size(), - wvcdm::Base64SafeEncode( - std::vector(key_data.begin(), key_data.end())) - .c_str()); + LOGD("key_data = (%zu) %s", key_data.size(), + wvcdm::Base64SafeEncode(key_data).c_str()); } std::shared_ptr session; if (!session_map_.FindSession(id, &session)) { - LOGE("Session ID not found: %s", id.c_str()); + LOGE("Session not found: session_id = %s", IdToString(id)); return SESSION_NOT_FOUND_3; } @@ -363,8 +357,7 @@ CdmResponseType CdmEngine::AddKey(const CdmSessionId& session_id, return EMPTY_KEY_DATA_1; } - CdmResponseType sts = (session->AddKey(key_data)); - + const CdmResponseType sts = session->AddKey(key_data); if (sts == KEY_ADDED) { if (session->is_release()) { *license_type = kLicenseTypeRelease; @@ -377,11 +370,11 @@ CdmResponseType CdmEngine::AddKey(const CdmSessionId& session_id, } } - if (key_set_id) { + if (key_set_id != nullptr) { if ((session->is_offline() || session->has_provider_session_token()) && !license_type_release) { *key_set_id = session->key_set_id(); - LOGI("Key set ID: %s", key_set_id->c_str()); + LOGI("key_set_id = %s", IdPtrToString(key_set_id)); } else { key_set_id->clear(); } @@ -391,21 +384,21 @@ CdmResponseType CdmEngine::AddKey(const CdmSessionId& session_id, case KEY_ADDED: break; case NEED_KEY: - LOGI("Service certificate loaded: No key added"); + LOGI("Service certificate loaded, no key added: session_id = %s", + IdToString(id)); break; default: - LOGE("Keys not added: status = %d", static_cast(sts)); + LOGE("CdmSession::AddKey failed: session_id = %s, status = %d", + IdToString(id), static_cast(sts)); break; } - return sts; } CdmResponseType CdmEngine::RestoreKey(const CdmSessionId& session_id, const CdmKeySetId& key_set_id) { - LOGI("Restoring key: session_id = %s, key_set_id = %s", session_id.c_str(), - key_set_id.c_str()); - + LOGI("session_id = %s, key_set_id = %s", IdToString(session_id), + IdToString(key_set_id)); if (key_set_id.empty()) { LOGI("Invalid key set ID"); return EMPTY_KEYSET_ID_ENG_4; @@ -413,131 +406,114 @@ CdmResponseType CdmEngine::RestoreKey(const CdmSessionId& session_id, std::shared_ptr session; if (!session_map_.FindSession(session_id, &session)) { - LOGE("Session ID not found: %s", session_id.c_str()); + LOGE("Session not found: session_id = %s", IdToString(session_id)); return SESSION_NOT_FOUND_4; } - CdmResponseType sts; int error_detail = NO_ERROR; - sts = session->RestoreOfflineSession(key_set_id, kLicenseTypeOffline, - &error_detail); + const CdmResponseType sts = session->RestoreOfflineSession( + key_set_id, kLicenseTypeOffline, &error_detail); session->GetMetrics()->cdm_session_restore_offline_session_.Increment( sts, error_detail); if (sts != KEY_ADDED && sts != GET_RELEASED_LICENSE_ERROR) { - LOGE("Restore offline session failed: status = %d", static_cast(sts)); + LOGE("Restore offline session failed: session_id = %s, status = %d", + IdToString(session_id), static_cast(sts)); } return sts; } CdmResponseType CdmEngine::RemoveKeys(const CdmSessionId& session_id) { - LOGI("Removing keys: session_id = %s", session_id.c_str()); - + LOGI("session_id = %s", IdToString(session_id)); std::shared_ptr session; if (!session_map_.FindSession(session_id, &session)) { - LOGE("Session ID not found: %s", session_id.c_str()); + LOGE("Session not found: session_id = %s", IdToString(session_id)); return SESSION_NOT_FOUND_5; } - session->RemoveKeys(); - return NO_ERROR; } CdmResponseType CdmEngine::RemoveLicense(const CdmSessionId& session_id) { - LOGI("Removing license: session_id = %s", session_id.c_str()); - + LOGI("session_id = %s", IdToString(session_id)); std::shared_ptr session; if (!session_map_.FindSession(session_id, &session)) { - LOGE("Session ID not found: %s", session_id.c_str()); + LOGE("Session not found: session_id = %s", IdToString(session_id)); return SESSION_NOT_FOUND_19; } - return session->RemoveLicense(); } CdmResponseType CdmEngine::GenerateRenewalRequest( const CdmSessionId& session_id, CdmKeyRequest* key_request) { - LOGI("Generating renewal request: session_id = %s", session_id.c_str()); - - std::shared_ptr session; - if (!session_map_.FindSession(session_id, &session)) { - LOGE("Session ID not found: %s", session_id.c_str()); - return SESSION_NOT_FOUND_6; - } - - if (!key_request) { - LOGE("No request destination"); + LOGI("session_id = %s", IdToString(session_id)); + if (key_request == nullptr) { + LOGE("Output |key_request| is null"); return PARAMETER_NULL; } - + std::shared_ptr session; + if (!session_map_.FindSession(session_id, &session)) { + LOGE("Session not found: session_id = %s", IdToString(session_id)); + return SESSION_NOT_FOUND_6; + } key_request->message.clear(); - - CdmResponseType sts = session->GenerateRenewalRequest(key_request); - + const CdmResponseType sts = session->GenerateRenewalRequest(key_request); if (KEY_MESSAGE != sts) { - LOGE("Key request gen. failed: status = %d", static_cast(sts)); + LOGE("Failed: session_id = %s, status = %d", IdToString(session_id), + static_cast(sts)); return sts; } - return KEY_MESSAGE; } CdmResponseType CdmEngine::RenewKey(const CdmSessionId& session_id, const CdmKeyResponse& key_data) { - LOGI("Renewing key: session_id = %s", session_id.c_str()); - - std::shared_ptr session; - if (!session_map_.FindSession(session_id, &session)) { - LOGE("Session ID not found: %s", session_id.c_str()); - return SESSION_NOT_FOUND_7; - } - + LOGI("session_id = %s", IdToString(session_id)); if (key_data.empty()) { LOGE("No key data"); return EMPTY_KEY_DATA_2; } - + std::shared_ptr session; + if (!session_map_.FindSession(session_id, &session)) { + LOGE("Session not found: session_id = %s", IdToString(session_id)); + return SESSION_NOT_FOUND_7; + } CdmResponseType sts; M_TIME(sts = session->RenewKey(key_data), session->GetMetrics(), cdm_session_renew_key_, sts); - if (KEY_ADDED != sts) { - LOGE("Keys not added: status = %d", static_cast(sts)); + LOGE("Failed: session_id = %s, status = %d", IdToString(session_id), + static_cast(sts)); return sts; } - return KEY_ADDED; } CdmResponseType CdmEngine::SetSessionServiceCertificate( const CdmSessionId& session_id, const std::string& service_certificate) { - LOGI("Setting service certificate: session_id = %s", session_id.c_str()); - + LOGI("session_id = %s", IdToString(session_id)); std::shared_ptr session; if (!session_map_.FindSession(session_id, &session)) { - LOGE("Session ID not found: %s", session_id.c_str()); + LOGE("Session not found: session_id = %s", IdToString(session_id)); return SESSION_NOT_FOUND_22; } - return session->SetServiceCertificate(service_certificate); } CdmResponseType CdmEngine::QueryStatus(SecurityLevel security_level, const std::string& query_token, std::string* query_response) { - LOGI("Querying status"); - std::unique_ptr crypto_session( - CryptoSession::MakeCryptoSession(metrics_->GetCryptoMetrics())); - CdmResponseType status; - - if (!query_response) { - LOGE("No query response destination"); + LOGD("security_level = %s, query_token = %s", + SecurityLevelToString(security_level), IdToString(query_token)); + if (query_response == nullptr) { + LOGE("Output |query_response| is null"); return PARAMETER_NULL; } + std::unique_ptr crypto_session( + CryptoSession::MakeCryptoSession(metrics_->GetCryptoMetrics())); // Add queries here, that can be answered before a session is opened if (query_token == QUERY_KEY_SECURITY_LEVEL) { - CdmSecurityLevel found_security_level = + const CdmSecurityLevel found_security_level = crypto_session->GetSecurityLevel(security_level); switch (found_security_level) { case kSecurityLevelL1: @@ -559,12 +535,13 @@ CdmResponseType CdmEngine::QueryStatus(SecurityLevel security_level, return UNKNOWN_ERROR; } return NO_ERROR; - } else if (query_token == QUERY_KEY_CURRENT_HDCP_LEVEL || - query_token == QUERY_KEY_MAX_HDCP_LEVEL) { + } + if (query_token == QUERY_KEY_CURRENT_HDCP_LEVEL || + query_token == QUERY_KEY_MAX_HDCP_LEVEL) { CryptoSession::HdcpCapability current_hdcp; CryptoSession::HdcpCapability max_hdcp; - status = crypto_session->GetHdcpCapabilities(security_level, ¤t_hdcp, - &max_hdcp); + const CdmResponseType status = crypto_session->GetHdcpCapabilities( + security_level, ¤t_hdcp, &max_hdcp); if (status != NO_ERROR) { LOGW("GetHdcpCapabilities failed: status = %d", static_cast(status)); @@ -573,7 +550,8 @@ CdmResponseType CdmEngine::QueryStatus(SecurityLevel security_level, *query_response = MapHdcpVersion( query_token == QUERY_KEY_CURRENT_HDCP_LEVEL ? current_hdcp : max_hdcp); return NO_ERROR; - } else if (query_token == QUERY_KEY_USAGE_SUPPORT) { + } + if (query_token == QUERY_KEY_USAGE_SUPPORT) { bool supports_usage_reporting; const bool got_info = crypto_session->HasUsageInfoSupport( security_level, &supports_usage_reporting); @@ -591,89 +569,89 @@ CdmResponseType CdmEngine::QueryStatus(SecurityLevel security_level, *query_response = supports_usage_reporting ? QUERY_VALUE_TRUE : QUERY_VALUE_FALSE; return NO_ERROR; - } else if (query_token == QUERY_KEY_NUMBER_OF_OPEN_SESSIONS) { + } + if (query_token == QUERY_KEY_NUMBER_OF_OPEN_SESSIONS) { size_t number_of_open_sessions; - status = crypto_session->GetNumberOfOpenSessions(security_level, - &number_of_open_sessions); + const CdmResponseType status = crypto_session->GetNumberOfOpenSessions( + security_level, &number_of_open_sessions); if (status != NO_ERROR) { LOGW("GetNumberOfOpenSessions failed: status = %d", static_cast(status)); return status; } - *query_response = std::to_string(number_of_open_sessions); return NO_ERROR; - } else if (query_token == QUERY_KEY_MAX_NUMBER_OF_SESSIONS) { + } + if (query_token == QUERY_KEY_MAX_NUMBER_OF_SESSIONS) { size_t maximum_number_of_sessions = 0; - status = crypto_session->GetMaxNumberOfSessions( + const CdmResponseType status = crypto_session->GetMaxNumberOfSessions( security_level, &maximum_number_of_sessions); - if (status != NO_ERROR) { LOGW("GetMaxNumberOfOpenSessions failed: status = %d", static_cast(status)); return status; } - *query_response = std::to_string(maximum_number_of_sessions); return NO_ERROR; - } else if (query_token == QUERY_KEY_OEMCRYPTO_API_VERSION) { + } + if (query_token == QUERY_KEY_OEMCRYPTO_API_VERSION) { uint32_t api_version; if (!crypto_session->GetApiVersion(security_level, &api_version)) { LOGW("GetApiVersion failed"); return UNKNOWN_ERROR; } - *query_response = std::to_string(api_version); return NO_ERROR; - } else if (query_token == QUERY_KEY_CURRENT_SRM_VERSION) { + } + if (query_token == QUERY_KEY_CURRENT_SRM_VERSION) { uint16_t current_srm_version; - status = crypto_session->GetSrmVersion(¤t_srm_version); - switch (status) { - case NO_ERROR: { - *query_response = std::to_string(current_srm_version); - return NO_ERROR; - } - case NO_SRM_VERSION: { - // SRM is not supported or not applicable (ex. local display only). - *query_response = QUERY_VALUE_NONE; - return NO_ERROR; - } - default: { - LOGW("GetCurrentSRMVersion failed: status = %d", - static_cast(status)); - return status; - } + const CdmResponseType status = + crypto_session->GetSrmVersion(¤t_srm_version); + if (status == NO_ERROR) { + *query_response = std::to_string(current_srm_version); + return NO_ERROR; } - } else if (query_token == QUERY_KEY_SRM_UPDATE_SUPPORT) { - bool is_srm_update_supported = crypto_session->IsSrmUpdateSupported(); + if (status == NO_SRM_VERSION) { + // SRM is not supported or not applicable (ex. local display only). + *query_response = QUERY_VALUE_NONE; + return NO_ERROR; + } + LOGW("GetCurrentSRMVersion failed: status = %d", static_cast(status)); + return status; + } + if (query_token == QUERY_KEY_SRM_UPDATE_SUPPORT) { + const bool is_srm_update_supported = crypto_session->IsSrmUpdateSupported(); *query_response = is_srm_update_supported ? QUERY_VALUE_TRUE : QUERY_VALUE_FALSE; return NO_ERROR; - } else if (query_token == QUERY_KEY_WVCDM_VERSION) { + } + if (query_token == QUERY_KEY_WVCDM_VERSION) { std::string cdm_version; if (!Properties::GetWVCdmVersion(&cdm_version)) { LOGW("GetWVCdmVersion failed"); return UNKNOWN_ERROR; } - *query_response = cdm_version; return NO_ERROR; - } else if (query_token == QUERY_KEY_RESOURCE_RATING_TIER) { + } + if (query_token == QUERY_KEY_RESOURCE_RATING_TIER) { uint32_t tier; if (!crypto_session->GetResourceRatingTier(security_level, &tier)) { LOGW("GetResourceRatingTier failed"); return UNKNOWN_ERROR; } - *query_response = std::to_string(tier); return NO_ERROR; - } else if (query_token == QUERY_KEY_OEMCRYPTO_BUILD_INFORMATION) { + } + if (query_token == QUERY_KEY_OEMCRYPTO_BUILD_INFORMATION) { if (!crypto_session->GetBuildInformation(security_level, query_response)) { LOGW("GetBuildInformation failed"); + query_response->clear(); return UNKNOWN_ERROR; } return NO_ERROR; - } else if (query_token == QUERY_KEY_DECRYPT_HASH_SUPPORT) { + } + if (query_token == QUERY_KEY_DECRYPT_HASH_SUPPORT) { uint32_t hash_support = 0; if (!crypto_session->GetDecryptHashSupport(security_level, &hash_support)) { LOGW("GetDecryptHashSupport failed"); @@ -681,9 +659,11 @@ CdmResponseType CdmEngine::QueryStatus(SecurityLevel security_level, } *query_response = std::to_string(hash_support); return NO_ERROR; - } else if (query_token == QUERY_KEY_PROVISIONING_MODEL) { + } + if (query_token == QUERY_KEY_PROVISIONING_MODEL) { CdmClientTokenType token_type = kClientTokenUninitialized; - status = crypto_session->GetProvisioningMethod(security_level, &token_type); + const CdmResponseType status = + crypto_session->GetProvisioningMethod(security_level, &token_type); if (status != NO_ERROR) { LOGW("GetProvisioningMethod failed: status = %d", static_cast(status)); @@ -701,12 +681,13 @@ CdmResponseType CdmEngine::QueryStatus(SecurityLevel security_level, break; case kClientTokenUninitialized: default: - LOGW("GetProvisioningMethod returns invalid token type: %d", + LOGW("GetProvisioningMethod returned invalid method: token_type = %d", static_cast(token_type)); return GET_PROVISIONING_METHOD_ERROR; } return NO_ERROR; - } else if (query_token == QUERY_KEY_MAX_USAGE_TABLE_ENTRIES) { + } + if (query_token == QUERY_KEY_MAX_USAGE_TABLE_ENTRIES) { size_t max_number_of_usage_entries; if (!crypto_session->GetMaximumUsageTableEntries( security_level, &max_number_of_usage_entries)) { @@ -721,17 +702,18 @@ CdmResponseType CdmEngine::QueryStatus(SecurityLevel security_level, } *query_response = std::to_string(max_number_of_usage_entries); return NO_ERROR; - } else if (query_token == QUERY_KEY_OEMCRYPTO_API_MINOR_VERSION) { + } + if (query_token == QUERY_KEY_OEMCRYPTO_API_MINOR_VERSION) { uint32_t api_minor_version; if (!crypto_session->GetApiMinorVersion(security_level, &api_minor_version)) { LOGW("GetApiMinorVersion failed"); return UNKNOWN_ERROR; } - *query_response = std::to_string(api_minor_version); return NO_ERROR; - } else if (query_token == QUERY_KEY_ANALOG_OUTPUT_CAPABILITIES) { + } + if (query_token == QUERY_KEY_ANALOG_OUTPUT_CAPABILITIES) { bool supported = false, can_disable = false, cgms_a = false; if (crypto_session->GetAnalogOutputCapabilities(&supported, &can_disable, &cgms_a)) { @@ -748,7 +730,8 @@ CdmResponseType CdmEngine::QueryStatus(SecurityLevel security_level, *query_response = QUERY_VALUE_UNKNOWN; } return NO_ERROR; - } else if (query_token == QUERY_KEY_CAN_DISABLE_ANALOG_OUTPUT) { + } + if (query_token == QUERY_KEY_CAN_DISABLE_ANALOG_OUTPUT) { bool supported = false, can_disable = false, cgms_a = false; if (crypto_session->GetAnalogOutputCapabilities(&supported, &can_disable, &cgms_a)) { @@ -759,6 +742,7 @@ CdmResponseType CdmEngine::QueryStatus(SecurityLevel security_level, return NO_ERROR; } + CdmResponseType status; M_TIME(status = crypto_session->Open(security_level), metrics_->GetCryptoMetrics(), crypto_session_open_, status, security_level); @@ -767,65 +751,64 @@ CdmResponseType CdmEngine::QueryStatus(SecurityLevel security_level, // Add queries here, that need an open session before they can be answered if (query_token == QUERY_KEY_DEVICE_ID) { - std::string deviceId; - status = crypto_session->GetExternalDeviceUniqueId(&deviceId); + std::string device_id; + status = crypto_session->GetExternalDeviceUniqueId(&device_id); metrics_->GetCryptoMetrics() ->crypto_session_get_device_unique_id_.Increment(status); if (status != NO_ERROR) return status; - - *query_response = deviceId; - } else if (query_token == QUERY_KEY_SYSTEM_ID) { + *query_response = device_id; + return NO_ERROR; + } + if (query_token == QUERY_KEY_SYSTEM_ID) { uint32_t system_id; - bool got_id = crypto_session->GetSystemId(&system_id); + const bool got_id = crypto_session->GetSystemId(&system_id); if (!got_id) { LOGW("QUERY_KEY_SYSTEM_ID unknown failure"); return UNKNOWN_ERROR; } - *query_response = std::to_string(system_id); - } else if (query_token == QUERY_KEY_PROVISIONING_ID) { + return NO_ERROR; + } + if (query_token == QUERY_KEY_PROVISIONING_ID) { std::string provisioning_id; status = crypto_session->GetProvisioningId(&provisioning_id); if (status != NO_ERROR) { LOGW("GetProvisioningId failed: status = %d", static_cast(status)); return status; } - *query_response = provisioning_id; - } else { - LOGW("Unknown status requested: query_token = %s", query_token.c_str()); - return INVALID_QUERY_KEY; + return NO_ERROR; } - - return NO_ERROR; + LOGW("Unknown status requested: query_token = %s", IdToString(query_token)); + return INVALID_QUERY_KEY; } CdmResponseType CdmEngine::QuerySessionStatus(const CdmSessionId& session_id, CdmQueryMap* query_response) { - LOGI("Querying session status: session_id = %s", session_id.c_str()); + LOGI("session_id = %s", IdToString(session_id)); std::shared_ptr session; if (!session_map_.FindSession(session_id, &session)) { - LOGE("Session ID not found: %s", session_id.c_str()); + LOGE("Session not found: session_id = %s", IdToString(session_id)); return SESSION_NOT_FOUND_8; } return session->QueryStatus(query_response); } bool CdmEngine::IsReleaseSession(const CdmSessionId& session_id) { - LOGI("Check if release session: session_id = %s", session_id.c_str()); + LOGI("session_id = %s", IdToString(session_id)); std::shared_ptr session; if (!session_map_.FindSession(session_id, &session)) { - LOGE("Session ID not found: %s", session_id.c_str()); + LOGE("Session not found: session_id = %s", IdToString(session_id)); return false; } return session->is_release(); } bool CdmEngine::IsOfflineSession(const CdmSessionId& session_id) { - LOGI("Check if offline session: session_id = %s", session_id.c_str()); + LOGI("session_id = %s", IdToString(session_id)); std::shared_ptr session; if (!session_map_.FindSession(session_id, &session)) { - LOGE("Session ID not found: %s", session_id.c_str()); + LOGE("Session not found: session_id = %s", IdToString(session_id)); return false; } return session->is_offline(); @@ -833,10 +816,10 @@ bool CdmEngine::IsOfflineSession(const CdmSessionId& session_id) { CdmResponseType CdmEngine::QueryKeyStatus(const CdmSessionId& session_id, CdmQueryMap* query_response) { - LOGI("Querying key status: session_id = %s", session_id.c_str()); + LOGI("session_id = %s", IdToString(session_id)); std::shared_ptr session; if (!session_map_.FindSession(session_id, &session)) { - LOGE("Session ID not found: %s", session_id.c_str()); + LOGE("Session not found: session_id = %s", IdToString(session_id)); return SESSION_NOT_FOUND_9; } return session->QueryKeyStatus(query_response); @@ -845,15 +828,15 @@ CdmResponseType CdmEngine::QueryKeyStatus(const CdmSessionId& session_id, CdmResponseType CdmEngine::QueryKeyAllowedUsage(const CdmSessionId& session_id, const std::string& key_id, CdmKeyAllowedUsage* key_usage) { - LOGI("Querying allowed key usage: session_id = %s, key_id = %s", - session_id.c_str(), key_id.c_str()); - if (!key_usage) { - LOGE("No response destination"); + LOGI("session_id = %s, key_id = %s", IdToString(session_id), + IdToString(key_id)); + if (key_usage == nullptr) { + LOGE("Output |key_usage| is null"); return PARAMETER_NULL; } std::shared_ptr session; if (!session_map_.FindSession(session_id, &session)) { - LOGE("Session ID not found: %s", session_id.c_str()); + LOGE("Session not found: session_id = %s", IdToString(session_id)); return SESSION_NOT_FOUND_12; } return session->QueryKeyAllowedUsage(key_id, key_usage); @@ -861,22 +844,19 @@ CdmResponseType CdmEngine::QueryKeyAllowedUsage(const CdmSessionId& session_id, CdmResponseType CdmEngine::QueryKeyAllowedUsage(const std::string& key_id, CdmKeyAllowedUsage* key_usage) { - LOGI("Querying allowed key useage (all sessions): key_id = %s", - key_id.c_str()); + LOGI("key_id = %s", IdToString(key_id)); if (!key_usage) { - LOGE("No response destination"); + LOGE("Output |key_usage| is null"); return PARAMETER_NULL; } key_usage->Clear(); - CdmSessionList sessions; session_map_.GetSessionList(sessions); - bool found = false; for (CdmSessionList::iterator iter = sessions.begin(); iter != sessions.end(); ++iter) { CdmKeyAllowedUsage found_in_this_session; - CdmResponseType sts = + const CdmResponseType sts = (*iter)->QueryKeyAllowedUsage(key_id, &found_in_this_session); if (sts == NO_ERROR) { if (found) { @@ -900,32 +880,28 @@ CdmResponseType CdmEngine::QueryKeyAllowedUsage(const std::string& key_id, CdmResponseType CdmEngine::QueryOemCryptoSessionId( const CdmSessionId& session_id, CdmQueryMap* query_response) { - LOGI("Querying OEMCrypto Session ID: session_id = %s", session_id.c_str()); + LOGI("session_id = %s", IdToString(session_id)); std::shared_ptr session; if (!session_map_.FindSession(session_id, &session)) { - LOGE("Session ID not found: %s", session_id.c_str()); + LOGE("Session not found: session_id = %s", IdToString(session_id)); return SESSION_NOT_FOUND_10; } return session->QueryOemCryptoSessionId(query_response); } bool CdmEngine::IsSecurityLevelSupported(CdmSecurityLevel level) { - LOGI("Checking if security level is supported: level = %d", - static_cast(level)); + LOGI("level = %s", CdmSecurityLevelToString(level)); metrics::CryptoMetrics alternate_crypto_metrics; std::unique_ptr crypto_session( CryptoSession::MakeCryptoSession(&alternate_crypto_metrics)); - - switch (level) { - case kSecurityLevelL1: - return crypto_session->GetSecurityLevel(kLevelDefault) == - kSecurityLevelL1; - case kSecurityLevelL3: - return crypto_session->GetSecurityLevel(kLevel3) == kSecurityLevelL3; - default: - LOGE("Invalid security level: %d", static_cast(level)); - return false; + if (level == kSecurityLevelL1) { + return crypto_session->GetSecurityLevel(kLevelDefault) == kSecurityLevelL1; } + if (level == kSecurityLevelL3) { + return crypto_session->GetSecurityLevel(kLevel3) == kSecurityLevelL3; + } + LOGE("Unsupported value: level = %d", static_cast(level)); + return false; } /* @@ -940,13 +916,13 @@ CdmResponseType CdmEngine::GetProvisioningRequest( const std::string& service_certificate, SecurityLevel requested_security_level, CdmProvisioningRequest* request, std::string* default_url) { - LOGI("Getting provisioning request"); + LOGI("cert_type = %s", CdmCertificateTypeToString(cert_type)); if (!request) { - LOGE("Invalid output parameters: request is null"); + LOGE("Output |request| is null"); return INVALID_PROVISIONING_REQUEST_PARAM_1; } if (!default_url) { - LOGE("Invalid output parameters: default_url is null"); + LOGE("Output |default_url| is null"); return INVALID_PROVISIONING_REQUEST_PARAM_2; } @@ -954,16 +930,17 @@ CdmResponseType CdmEngine::GetProvisioningRequest( if (!cert_provisioning_) { cert_provisioning_.reset( new CertificateProvisioning(metrics_->GetCryptoMetrics())); - CdmResponseType status = cert_provisioning_->Init(service_certificate); + const CdmResponseType status = + cert_provisioning_->Init(service_certificate); if (status != NO_ERROR) return status; } - CdmResponseType ret = cert_provisioning_->GetProvisioningRequest( + const CdmResponseType status = cert_provisioning_->GetProvisioningRequest( requested_security_level, cert_type, cert_authority, file_system_->origin(), spoid_, request, default_url); - if (ret != NO_ERROR) { + if (status != NO_ERROR) { cert_provisioning_.reset(); // Release resources. } - return ret; + return status; } /* @@ -977,19 +954,20 @@ CdmResponseType CdmEngine::HandleProvisioningResponse( const CdmProvisioningResponse& response, SecurityLevel requested_security_level, std::string* cert, std::string* wrapped_key) { - LOGI("Handling provision response"); + LOGI("response_size = %zu, security_level = %s", response.size(), + SecurityLevelToString(requested_security_level)); if (response.empty()) { LOGE("Empty provisioning response"); cert_provisioning_.reset(); return EMPTY_PROVISIONING_RESPONSE; } if (cert == nullptr) { - LOGE("Invalid certificate destination"); + LOGE("Output |cert| is null"); cert_provisioning_.reset(); return INVALID_PROVISIONING_PARAMETERS_1; } if (wrapped_key == nullptr) { - LOGE("Invalid wrapped key destination"); + LOGE("Output |wrapped_key| is null"); cert_provisioning_.reset(); return INVALID_PROVISIONING_PARAMETERS_2; } @@ -1014,7 +992,7 @@ CdmResponseType CdmEngine::HandleProvisioningResponse( return NO_ERROR; } - CdmResponseType ret = cert_provisioning_->HandleProvisioningResponse( + const CdmResponseType ret = cert_provisioning_->HandleProvisioningResponse( file_system_, response, cert, wrapped_key); // Release resources only on success. It is possible that a provisioning // attempt was made after this one was requested but before the response was @@ -1033,8 +1011,7 @@ bool CdmEngine::IsProvisioned(CdmSecurityLevel security_level) { security_level == kSecurityLevelL3 ? kLevel3 : kLevelDefault); CdmSession session(file_system_, metrics_->AddSession()); - - CdmResponseType status = session.Init(&property_set); + const CdmResponseType status = session.Init(&property_set); if (NO_ERROR != status) { LOGE("Init failed: status = %d", static_cast(status)); } @@ -1042,18 +1019,19 @@ bool CdmEngine::IsProvisioned(CdmSecurityLevel security_level) { } CdmResponseType CdmEngine::Unprovision(CdmSecurityLevel security_level) { - LOGI("Unprovisioning: security_level = %d", static_cast(security_level)); + LOGI("security_level = %s", CdmSecurityLevelToString(security_level)); // Devices with baked-in DRM certs cannot be reprovisioned and therefore must // not be unprovisioned. std::unique_ptr crypto_session( CryptoSession::MakeCryptoSession(metrics_->GetCryptoMetrics())); CdmClientTokenType token_type = kClientTokenUninitialized; - CdmResponseType res = crypto_session->GetProvisioningMethod( + const CdmResponseType res = crypto_session->GetProvisioningMethod( security_level == kSecurityLevelL3 ? kLevel3 : kLevelDefault, &token_type); if (res != NO_ERROR) { return res; - } else if (token_type == kClientTokenDrmCert) { + } + if (token_type == kClientTokenDrmCert) { return DEVICE_CANNOT_REPROVISION; } @@ -1064,27 +1042,25 @@ CdmResponseType CdmEngine::Unprovision(CdmSecurityLevel security_level) { } // TODO(b/141705730): Remove usage entries during unprovisioning. - if (!file_system_->IsGlobal()) { if (!handle.RemoveCertificate()) { LOGE("Unable to delete certificate"); return UNPROVISION_ERROR_2; } return NO_ERROR; - } else { - if (!handle.DeleteAllFiles()) { - LOGE("Unable to delete files"); - return UNPROVISION_ERROR_3; - } - return NO_ERROR; } + if (!handle.DeleteAllFiles()) { + LOGE("Unable to delete files"); + return UNPROVISION_ERROR_3; + } + return NO_ERROR; } CdmResponseType CdmEngine::ListStoredLicenses( CdmSecurityLevel security_level, std::vector* key_set_ids) { DeviceFiles handle(file_system_); if (!key_set_ids) { - LOGE("No response destination"); + LOGE("Output |key_set_ids| is null"); return INVALID_PARAMETERS_ENG_22; } if (!handle.Init(security_level)) { @@ -1104,7 +1080,7 @@ CdmResponseType CdmEngine::ListUsageIds( std::vector* provider_session_tokens) { DeviceFiles handle(file_system_); if (!ksids && !provider_session_tokens) { - LOGE("No response destination"); + LOGE("Outputs |ksids| and |provider_session_tokens| are null"); return INVALID_PARAMETERS_ENG_23; } if (!handle.Init(security_level)) { @@ -1112,7 +1088,8 @@ CdmResponseType CdmEngine::ListUsageIds( return LIST_USAGE_ERROR_1; } if (!handle.ListUsageIds(app_id, ksids, provider_session_tokens)) { - LOGE("ListUsageIds call failed"); + LOGE("Failed: app_id = %s, security_level = %s", IdToString(app_id), + CdmSecurityLevelToString(security_level)); return LIST_USAGE_ERROR_2; } return NO_ERROR; @@ -1121,21 +1098,19 @@ CdmResponseType CdmEngine::ListUsageIds( CdmResponseType CdmEngine::DeleteUsageRecord(const std::string& app_id, CdmSecurityLevel security_level, const std::string& key_set_id) { - LOGI("Deleting usage record: key_set_id = %s, app_id = %s", - key_set_id.c_str(), app_id.c_str()); - std::string provider_session_token; - + LOGI("app_id = %s, key_set_id = %s", IdToString(app_id), + IdToString(key_set_id)); DeviceFiles handle(file_system_); if (!handle.Init(security_level)) { LOGE("Unable to initialize device files"); return DELETE_USAGE_ERROR_1; } + std::string provider_session_token; if (!handle.GetProviderSessionToken(app_id, key_set_id, &provider_session_token)) { LOGE("GetProviderSessionToken failed"); return DELETE_USAGE_ERROR_2; } - return RemoveUsageInfo(app_id, provider_session_token); } @@ -1150,14 +1125,12 @@ CdmResponseType CdmEngine::GetOfflineLicenseState( DeviceFiles::CdmLicenseData license_data; DeviceFiles::ResponseType sub_error_code = DeviceFiles::kNoError; - - if (handle.RetrieveLicense(key_set_id, &license_data, &sub_error_code)) { - *license_state = MapDeviceFilesLicenseState(license_data.state); - } else { + if (!handle.RetrieveLicense(key_set_id, &license_data, &sub_error_code)) { LOGE("Failed to retrieve license state: key_set_id = %s", - key_set_id.c_str()); + IdToString(key_set_id)); return GET_OFFLINE_LICENSE_STATE_ERROR_2; } + *license_state = MapDeviceFilesLicenseState(license_data.state); return NO_ERROR; } @@ -1177,14 +1150,14 @@ CdmResponseType CdmEngine::RemoveOfflineLicense( CdmResponseType sts = OpenKeySetSession(key_set_id, &property_set, nullptr /* event listener */); if (sts != NO_ERROR) { - LOGE("Failed to open key set session: status = %d", static_cast(sts)); + LOGE("OpenKeySetSession failed: status = %d", static_cast(sts)); handle.DeleteLicense(key_set_id); return sts; } CdmSessionId session_id; CdmAppParameterMap dummy_app_params; - InitializationData dummy_init_data("", "", ""); + const InitializationData dummy_init_data("", "", ""); CdmKeyRequest key_request; // Calling with no session_id is okay sts = GenerateKeyRequest(session_id, key_set_id, dummy_init_data, @@ -1193,7 +1166,7 @@ CdmResponseType CdmEngine::RemoveOfflineLicense( std::unique_lock lock(release_key_sets_lock_); CdmReleaseKeySetMap::iterator iter = release_key_sets_.find(key_set_id); if (iter == release_key_sets_.end()) { - LOGE("Key set ID not found: %s", key_set_id.c_str()); + LOGE("Key set not found: key_set_id = %s", IdToString(key_set_id)); sts = REMOVE_OFFLINE_LICENSE_ERROR_2; } else { session_id = iter->second.first; @@ -1214,7 +1187,6 @@ CdmResponseType CdmEngine::RemoveOfflineLicense( handle.DeleteLicense(key_set_id); } CloseKeySetSession(key_set_id); - return sts; } @@ -1222,13 +1194,12 @@ CdmResponseType CdmEngine::GetUsageInfo(const std::string& app_id, const CdmSecureStopId& ssid, int* error_detail, CdmUsageInfo* usage_info) { - LOGI("Getting usage info: app_id = %s, ssid = %s", app_id.c_str(), - ssid.c_str()); + LOGI("app_id = %s, ssid = %s", IdToString(app_id), IdToString(ssid)); if (!usage_property_set_) { usage_property_set_.reset(new UsagePropertySet()); } - if (!usage_info) { - LOGE("No usage info destination"); + if (usage_info == nullptr) { + LOGE("Output |usage_info| is null"); return PARAMETER_NULL; } usage_property_set_->set_security_level(kLevelDefault); @@ -1294,18 +1265,17 @@ CdmResponseType CdmEngine::GetUsageInfo(const std::string& app_id, CdmResponseType CdmEngine::GetUsageInfo(const std::string& app_id, int* error_detail, CdmUsageInfo* usage_info) { - LOGI("Getting usage info: app_id = %s", app_id.c_str()); + LOGI("app_id = %s", IdToString(app_id)); + if (usage_info == nullptr) { + LOGE("Output |usage_info| is null"); + return PARAMETER_NULL; + } // Return a random usage report from a random security level SecurityLevel security_level = CdmRandom::RandomBool() ? kLevelDefault : kLevel3; CdmResponseType status = UNKNOWN_ERROR; - if (!usage_info) { - LOGE("No usage info destination"); - return PARAMETER_NULL; - } do { status = GetUsageInfo(app_id, security_level, error_detail, usage_info); - if (KEY_MESSAGE == status && !usage_info->empty()) { return status; } @@ -1325,10 +1295,10 @@ CdmResponseType CdmEngine::GetUsageInfo(const std::string& app_id, SecurityLevel requested_security_level, int* error_detail, CdmUsageInfo* usage_info) { - LOGI("Getting usage info: app_id = %s, security_level = %d", app_id.c_str(), - static_cast(requested_security_level)); - if (!usage_info) { - LOGE("No usage info destination"); + LOGI("app_id = %s, security_level = %s", IdToString(app_id), + SecurityLevelToString(requested_security_level)); + if (usage_info == nullptr) { + LOGE("Output |usage_info| is null"); return PARAMETER_NULL; } @@ -1398,8 +1368,8 @@ CdmResponseType CdmEngine::GetUsageInfo(const std::string& app_id, CdmResponseType CdmEngine::RemoveAllUsageInfo( const std::string& app_id, CdmSecurityLevel cdm_security_level) { - LOGI("Removing all usage info: app_id = %s, security_level = %d", - app_id.c_str(), static_cast(cdm_security_level)); + LOGI("app_id = %s, security_level = %s", IdToString(app_id), + CdmSecurityLevelToString(cdm_security_level)); if (!usage_property_set_) { usage_property_set_.reset(new UsagePropertySet()); } @@ -1408,7 +1378,7 @@ CdmResponseType CdmEngine::RemoveAllUsageInfo( CdmResponseType status = NO_ERROR; DeviceFiles handle(file_system_); if (handle.Init(cdm_security_level)) { - SecurityLevel security_level = + const SecurityLevel security_level = cdm_security_level == kSecurityLevelL3 ? kLevel3 : kLevelDefault; usage_property_set_->set_security_level(security_level); usage_session_.reset(new CdmSession(file_system_, metrics_->AddSession())); @@ -1457,7 +1427,7 @@ CdmResponseType CdmEngine::RemoveAllUsageInfo( } CdmResponseType CdmEngine::RemoveAllUsageInfo(const std::string& app_id) { - LOGI("Removing all usage info: app_id = %s", app_id.c_str()); + LOGI("app_id = %s", IdToString(app_id)); const CdmResponseType status_l1 = RemoveAllUsageInfo(app_id, kSecurityLevelL1); const CdmResponseType status_l3 = @@ -1471,8 +1441,8 @@ CdmResponseType CdmEngine::RemoveAllUsageInfo(const std::string& app_id) { CdmResponseType CdmEngine::RemoveUsageInfo( const std::string& app_id, const CdmSecureStopId& provider_session_token) { - LOGI("Removing usage info: app_id = %s, pst = %s", app_id.c_str(), - provider_session_token.c_str()); + LOGI("app_id = %s, pst = %s", IdToString(app_id), + IdToString(provider_session_token)); if (!usage_property_set_) { usage_property_set_.reset(new UsagePropertySet()); } @@ -1525,13 +1495,12 @@ CdmResponseType CdmEngine::RemoveUsageInfo( CdmResponseType CdmEngine::ReleaseUsageInfo( const CdmUsageInfoReleaseMessage& message) { - LOGI("Releasing usage info"); + LOGI("message_size = %zu", message.size()); if (!usage_session_) { - LOGE("CDM session not initialized"); + LOGE("Usage session not initialized"); return RELEASE_USAGE_INFO_ERROR; } - - CdmResponseType status = usage_session_->ReleaseKey(message); + const CdmResponseType status = usage_session_->ReleaseKey(message); usage_session_.reset(); if (NO_ERROR != status) { LOGE("ReleaseKey failed: status = %d", status); @@ -1541,27 +1510,25 @@ CdmResponseType CdmEngine::ReleaseUsageInfo( CdmResponseType CdmEngine::LoadUsageSession(const CdmKeySetId& key_set_id, CdmKeyMessage* release_message) { - LOGI("Loading usage session: key_set_id = %s", key_set_id.c_str()); + LOGI("key_set_id = %s", IdToString(key_set_id)); // This method is currently only used by the CE CDM, in which all session IDs // are key set IDs. assert(Properties::AlwaysUseKeySetIds()); - if (key_set_id.empty()) { LOGE("Invalid key set ID"); return EMPTY_KEYSET_ID_ENG_5; } + if (release_message == nullptr) { + LOGE("Output |release_message| is null"); + return PARAMETER_NULL; + } std::shared_ptr session; if (!session_map_.FindSession(key_set_id, &session)) { - LOGE("Session ID not found: %s ", key_set_id.c_str()); + LOGE("Session not found: key_set_id = %s", IdToString(key_set_id)); return SESSION_NOT_FOUND_11; } - if (!release_message) { - LOGE("No release message destination"); - return PARAMETER_NULL; - } - DeviceFiles handle(file_system_); if (!handle.Init(session->GetSecurityLevel())) { LOGE("Unable to initialize device files"); @@ -1589,15 +1556,14 @@ CdmResponseType CdmEngine::LoadUsageSession(const CdmKeySetId& key_set_id, session->GetMetrics()->cdm_session_restore_usage_session_.Increment( status, error_detail); if (KEY_ADDED != status) { - LOGE("Usage session error: status = %d", static_cast(status)); + LOGE("Restore failed: key_set_id = %s, status = %d", IdToString(key_set_id), + static_cast(status)); return status; } CdmKeyRequest request; status = session->GenerateReleaseRequest(&request); - - *release_message = request.message; - + *release_message = std::move(request.message); switch (status) { case KEY_MESSAGE: break; @@ -1652,12 +1618,12 @@ CdmResponseType CdmEngine::DecryptV16( } } if (!session) { - LOGE("Session not found: Empty session ID"); + LOGE("Session not found: session_id = "); return SESSION_NOT_FOUND_FOR_DECRYPT; } } else { if (!session_map_.FindSession(session_id, &session)) { - LOGE("Session not found: session_id = %s", session_id.c_str()); + LOGE("Session not found: session_id = %s", IdToString(session_id)); return SESSION_NOT_FOUND_FOR_DECRYPT; } } @@ -1672,12 +1638,12 @@ CdmResponseType CdmEngine::GenericEncrypt(const std::string& session_id, CdmEncryptionAlgorithm algorithm, std::string* out_buffer) { if (out_buffer == nullptr) { - LOGE("No out buffer provided"); + LOGE("Output |out_buffer| is null"); return PARAMETER_NULL; } std::shared_ptr session; if (!session_map_.FindSession(session_id, &session)) { - LOGE("Session ID not found: %s", session_id.c_str()); + LOGE("Session not found: session_id = %s", IdToString(session_id)); return SESSION_NOT_FOUND_13; } return session->GenericEncrypt(in_buffer, key_id, iv, algorithm, out_buffer); @@ -1690,12 +1656,12 @@ CdmResponseType CdmEngine::GenericDecrypt(const std::string& session_id, CdmEncryptionAlgorithm algorithm, std::string* out_buffer) { if (out_buffer == nullptr) { - LOGE("No out buffer provided"); + LOGE("Output |out_buffer| is null"); return PARAMETER_NULL; } std::shared_ptr session; if (!session_map_.FindSession(session_id, &session)) { - LOGE("Session ID not found: %s", session_id.c_str()); + LOGE("Session not found: session_id = %s", IdToString(session_id)); return SESSION_NOT_FOUND_14; } return session->GenericDecrypt(in_buffer, key_id, iv, algorithm, out_buffer); @@ -1707,12 +1673,12 @@ CdmResponseType CdmEngine::GenericSign(const std::string& session_id, CdmSigningAlgorithm algorithm, std::string* signature) { if (signature == nullptr) { - LOGE("No signature buffer provided"); + LOGE("Output |signature| is null"); return PARAMETER_NULL; } std::shared_ptr session; if (!session_map_.FindSession(session_id, &session)) { - LOGE("Session ID not found: %s", session_id.c_str()); + LOGE("Session not found: session_id = %s", IdToString(session_id)); return SESSION_NOT_FOUND_15; } return session->GenericSign(message, key_id, algorithm, signature); @@ -1725,7 +1691,7 @@ CdmResponseType CdmEngine::GenericVerify(const std::string& session_id, const std::string& signature) { std::shared_ptr session; if (!session_map_.FindSession(session_id, &session)) { - LOGE("Session ID not found: %s", session_id.c_str()); + LOGE("Session not found: session_id = %s", IdToString(session_id)); return SESSION_NOT_FOUND_16; } return session->GenericVerify(message, key_id, algorithm, signature); @@ -1735,15 +1701,15 @@ CdmResponseType CdmEngine::ParseDecryptHashString( const std::string& hash_string, CdmSessionId* session_id, uint32_t* frame_number, std::string* hash) { if (session_id == nullptr) { - LOGE("Session ID was not provided"); + LOGE("Output |session_id| is null"); return PARAMETER_NULL; } if (frame_number == nullptr) { - LOGE("Frame number was not provided"); + LOGE("Output |frame_number| is null"); return PARAMETER_NULL; } if (hash == nullptr) { - LOGE("Hash was not provided"); + LOGE("Output |hash| is null"); return PARAMETER_NULL; } std::stringstream ss; @@ -1779,19 +1745,18 @@ CdmResponseType CdmEngine::ParseDecryptHashString( return INVALID_DECRYPT_HASH_FORMAT; } - std::vector hash_vec = wvcdm::a2b_hex(tokens[2]); - if (hash_vec.empty()) { + *hash = wvcdm::a2bs_hex(tokens[2]); + if (hash->empty()) { LOGE("Malformed hash: %s", hash_string.c_str()); return INVALID_DECRYPT_HASH_FORMAT; } - hash->assign(hash_vec.begin(), hash_vec.end()); return NO_ERROR; } CdmResponseType CdmEngine::SetDecryptHash(const CdmSessionId& session_id, uint32_t frame_number, const std::string& hash) { - LOGI("Setting decrypt hash: session_id = %s", session_id.c_str()); + LOGI("session_id = %s", IdToString(session_id)); std::shared_ptr session; if (!session_map_.FindSession(session_id, &session)) { return SESSION_NOT_FOUND_20; @@ -1801,7 +1766,7 @@ CdmResponseType CdmEngine::SetDecryptHash(const CdmSessionId& session_id, CdmResponseType CdmEngine::GetDecryptHashError(const CdmSessionId& session_id, std::string* error_string) { - LOGI("Getting decrypt hash error: session_id = %s", session_id.c_str()); + LOGI("session_id = %s", IdToString(session_id)); std::shared_ptr session; if (!session_map_.FindSession(session_id, &session)) { return SESSION_NOT_FOUND_20; @@ -1825,18 +1790,17 @@ bool CdmEngine::IsKeyLoaded(const KeyId& key_id) { bool CdmEngine::FindSessionForKey(const KeyId& key_id, CdmSessionId* session_id) { if (session_id == nullptr) { - LOGE("No session ID destination provided"); + LOGE("Output |session_id| is null"); return false; } - - uint32_t session_sharing_id = Properties::GetSessionSharingId(*session_id); + const uint32_t session_sharing_id = + Properties::GetSessionSharingId(*session_id); std::unique_lock lock(session_map_lock_); CdmSessionList sessions; session_map_.GetSessionList(sessions); CdmSessionList::iterator session_iter = sessions.end(); - int64_t seconds_remaining = 0; for (CdmSessionList::iterator iter = sessions.begin(); iter != sessions.end(); ++iter) { @@ -1875,8 +1839,7 @@ bool CdmEngine::ValidateKeySystem(const CdmKeySystem& key_system) { void CdmEngine::OnTimerEvent() { Clock clock; - uint64_t current_time = clock.GetCurrentTime(); - + const uint64_t current_time = clock.GetCurrentTime(); bool usage_update_period_expired = false; if (current_time - last_usage_information_update_time_ > kUpdateUsageInformationPeriod) { @@ -1886,7 +1849,6 @@ void CdmEngine::OnTimerEvent() { bool is_initial_usage_update = false; bool is_usage_update_needed = false; - { std::unique_lock lock(session_map_lock_); CdmSessionList sessions; @@ -1923,7 +1885,6 @@ void CdmEngine::OnTimerEvent() { void CdmEngine::OnKeyReleaseEvent(const CdmKeySetId& key_set_id) { CdmSessionList sessions; session_map_.GetSessionList(sessions); - while (!sessions.empty()) { sessions.front()->OnKeyReleaseEvent(key_set_id); sessions.pop_front(); @@ -1937,11 +1898,11 @@ CdmResponseType CdmEngine::ValidateServiceCertificate(const std::string& cert) { CdmResponseType CdmEngine::SetPlaybackId(const CdmSessionId& session_id, const std::string& playback_id) { - LOGI("Setting session_id = %s playback_id = %s", session_id.c_str(), - playback_id.c_str()); + LOGI("session_id = %s, playback_id = %s", IdToString(session_id), + IdToString(playback_id)); std::shared_ptr session; if (!session_map_.FindSession(session_id, &session)) { - LOGE("Session ID not found: %s", session_id.c_str()); + LOGE("Session not found: session_id = %s", IdToString(session_id)); return SESSION_NOT_FOUND_23; } session->GetMetrics()->playback_id_.Record(playback_id); @@ -1970,8 +1931,7 @@ std::string CdmEngine::MapHdcpVersion(CryptoSession::HdcpCapability version) { } void CdmEngine::CloseExpiredReleaseSessions() { - int64_t current_time = clock_.GetCurrentTime(); - + const int64_t current_time = clock_.GetCurrentTime(); std::set close_session_set; { std::unique_lock lock(release_key_sets_lock_); @@ -1991,5 +1951,4 @@ void CdmEngine::CloseExpiredReleaseSessions() { CloseSession(*iter); } } - } // namespace wvcdm diff --git a/libwvdrmengine/cdm/core/src/certificate_provisioning.cpp b/libwvdrmengine/cdm/core/src/certificate_provisioning.cpp index 048da402..78242bf6 100644 --- a/libwvdrmengine/cdm/core/src/certificate_provisioning.cpp +++ b/libwvdrmengine/cdm/core/src/certificate_provisioning.cpp @@ -15,8 +15,8 @@ #include "string_conversions.h" #include "wv_cdm_constants.h" +namespace wvcdm { namespace { - const std::string kEmptyString; // URL for Google Provisioning Server. @@ -104,10 +104,7 @@ bool ExtractAndDecodeSignedMessage(const std::string& provisioning_response, result->assign(decoded_message.begin(), decoded_message.end()); return true; } - } // namespace - -namespace wvcdm { // Protobuf generated classes. using video_widevine::ClientIdentification_ClientCapabilities; using video_widevine::ClientIdentification_NameValue; diff --git a/libwvdrmengine/cdm/core/src/crypto_session.cpp b/libwvdrmengine/cdm/core/src/crypto_session.cpp index ca526a64..4f0f36b4 100644 --- a/libwvdrmengine/cdm/core/src/crypto_session.cpp +++ b/libwvdrmengine/cdm/core/src/crypto_session.cpp @@ -164,11 +164,6 @@ size_t GenericEncryptionBlockSize(CdmEncryptionAlgorithm algorithm) { } return kAes128BlockSize; } - -const char* SecurityLevelToString(SecurityLevel security_level) { - return security_level == kLevel3 ? QUERY_VALUE_SECURITY_LEVEL_L3.c_str() - : QUERY_VALUE_SECURITY_LEVEL_DEFAULT.c_str(); -} } // namespace shared_mutex CryptoSession::static_field_mutex_; diff --git a/libwvdrmengine/cdm/core/src/wv_cdm_types.cpp b/libwvdrmengine/cdm/core/src/wv_cdm_types.cpp new file mode 100644 index 00000000..ae390cfb --- /dev/null +++ b/libwvdrmengine/cdm/core/src/wv_cdm_types.cpp @@ -0,0 +1,76 @@ +// Copyright 2021 Google LLC. All Rights Reserved. This file and proprietary +// source code may only be used and distributed under the Widevine License +// Agreement. +#include "wv_cdm_types.h" + +#include "wv_cdm_constants.h" + +namespace wvcdm { +namespace { +const char kEmptyIdRep[] = ""; +const char kNullIdRep[] = ""; +const char kUnknownValueRep[] = ""; +} // namespace + +const char* CdmCertificateTypeToString(CdmCertificateType type) { + switch (type) { + case kCertificateWidevine: + return "Widevine"; + case kCertificateX509: + return "x509"; + } + return kUnknownValueRep; +} + +const char* CdmLicenseTypeToString(CdmLicenseType license_type) { + switch (license_type) { + case kLicenseTypeOffline: + return "Offline"; + case kLicenseTypeStreaming: + return "Streaming"; + case kLicenseTypeRelease: + return "Release"; + case kLicenseTypeTemporary: + return "Temporary"; + case kLicenseTypeEmbeddedKeyData: + return "EmbeddedKeyData"; + } + return kUnknownValueRep; +} + +const char* CdmSecurityLevelToString(CdmSecurityLevel security_level) { + switch (security_level) { + case kSecurityLevelUninitialized: + return "Uninitialized"; + case kSecurityLevelL1: + return QUERY_VALUE_SECURITY_LEVEL_L1.c_str(); + case kSecurityLevelL2: + return QUERY_VALUE_SECURITY_LEVEL_L2.c_str(); + case kSecurityLevelL3: + return QUERY_VALUE_SECURITY_LEVEL_L3.c_str(); + case kSecurityLevelUnknown: + break; + } + return QUERY_VALUE_SECURITY_LEVEL_UNKNOWN.c_str(); +} + +const char* SecurityLevelToString(SecurityLevel security_level) { + switch (security_level) { + case kLevelDefault: + return QUERY_VALUE_SECURITY_LEVEL_DEFAULT.c_str(); + case kLevel3: + return QUERY_VALUE_SECURITY_LEVEL_L3.c_str(); + } + return kUnknownValueRep; +} + +const char* IdToString(const std::string& id) { + return id.empty() ? kEmptyIdRep : id.c_str(); +} + +const char* IdPtrToString(const std::string* id) { + if (id == nullptr) return kNullIdRep; + return id->empty() ? kEmptyIdRep : id->c_str(); +} + +} // namespace wvcdm