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