From 9f52cd37245c41b6d40caff0a47060a301bb85a7 Mon Sep 17 00:00:00 2001 From: Rahul Frias Date: Sun, 27 Jul 2014 19:41:09 -0700 Subject: [PATCH] Allow offline release retries A bug prevented regenerating license release requests. This has been corrected. A crash due to a formatting error has been addressed. Clean up of logging and additional logging for open session failures have been included. b/16197822 Merge of https://widevine-internal-review.googlesource.com/#/c/10806 from the widevine cdm repo. Change-Id: I854ead388f311d00b1cd700dfa1b2f58322c2dd4 --- libwvdrmengine/cdm/core/src/cdm_engine.cpp | 20 +++++------ libwvdrmengine/cdm/core/src/cdm_session.cpp | 8 +++-- .../cdm/core/src/crypto_session.cpp | 16 +++++++-- libwvdrmengine/cdm/test/Android.mk | 4 +++ .../cdm/test/request_license_test.cpp | 36 +++++++++++++++++++ libwvdrmengine/run_all_unit_tests.sh | 1 + 6 files changed, 70 insertions(+), 15 deletions(-) diff --git a/libwvdrmengine/cdm/core/src/cdm_engine.cpp b/libwvdrmengine/cdm/core/src/cdm_engine.cpp index 2f548a42..9a2bdbd7 100644 --- a/libwvdrmengine/cdm/core/src/cdm_engine.cpp +++ b/libwvdrmengine/cdm/core/src/cdm_engine.cpp @@ -76,7 +76,7 @@ CdmResponseType CdmEngine::OpenSession( cert_provisioning_requested_security_level_ = new_session->GetRequestedSecurityLevel(); } else { - LOGE("CdmEngine::OpenSession: bad session init: %u", sts); + LOGE("CdmEngine::OpenSession: bad session init: %d", sts); } return sts; } @@ -186,7 +186,7 @@ CdmResponseType CdmEngine::GenerateKeyRequest( sts = iter->second->RestoreOfflineSession(key_set_id, kLicenseTypeRelease); if (sts != KEY_ADDED) { LOGE("CdmEngine::GenerateKeyRequest: key release restoration failed," - "sts = %d", (int)sts); + "sts = %d", sts); return sts; } } @@ -201,7 +201,7 @@ CdmResponseType CdmEngine::GenerateKeyRequest( iter->second->GetRequestedSecurityLevel(); } LOGE("CdmEngine::GenerateKeyRequest: key request generation failed, " - "sts = %d", (int)sts); + "sts = %d", sts); return sts; } @@ -256,7 +256,7 @@ CdmResponseType CdmEngine::AddKey( CdmResponseType sts = iter->second->AddKey(key_data, key_set_id); if (KEY_ADDED != sts) { - LOGE("CdmEngine::AddKey: keys not added, result = %d", (int)sts); + LOGE("CdmEngine::AddKey: keys not added, result = %d", sts); return sts; } @@ -328,7 +328,7 @@ CdmResponseType CdmEngine::GenerateRenewalRequest( if (KEY_MESSAGE != sts) { LOGE("CdmEngine::GenerateRenewalRequest: key request gen. failed, sts=%d", - (int)sts); + sts); return sts; } @@ -353,7 +353,7 @@ CdmResponseType CdmEngine::RenewKey( CdmResponseType sts = iter->second->RenewKey(key_data); if (KEY_ADDED != sts) { - LOGE("CdmEngine::RenewKey: keys not added, sts=%d", (int)sts); + LOGE("CdmEngine::RenewKey: keys not added, sts=%d", sts); return sts; } @@ -560,7 +560,7 @@ CdmResponseType CdmEngine::GetUsageInfo(CdmUsageInfo* usage_info) { status = usage_session_->RestoreUsageSession(license_info[index].first, license_info[index].second); if (KEY_ADDED != status) { - LOGE("CdmEngine::GetUsageInfo: restore usage session (%d) error %ld", + LOGE("CdmEngine::GetUsageInfo: restore usage session (%u) error %d", index, status); usage_info->clear(); return status; @@ -569,7 +569,7 @@ CdmResponseType CdmEngine::GetUsageInfo(CdmUsageInfo* usage_info) { status = usage_session_->GenerateReleaseRequest(&(*usage_info)[0], &server_url); if (KEY_MESSAGE != status) { - LOGE("CdmEngine::GetUsageInfo: generate release request error: %ld", + LOGE("CdmEngine::GetUsageInfo: generate release request error: %d", status); usage_info->clear(); return status; @@ -586,7 +586,7 @@ CdmResponseType CdmEngine::ReleaseUsageInfo( CdmResponseType status = usage_session_->ReleaseKey(message); if (NO_ERROR != status) { - LOGE("CdmEngine::ReleaseUsageInfo: release key error: %ld", status); + LOGE("CdmEngine::ReleaseUsageInfo: release key error: %d", status); } return status; } @@ -726,7 +726,7 @@ void CdmEngine::OnTimerEvent() { // called only once per update usage information period CdmResponseType status = iter->second->UpdateUsageInformation(); if (NO_ERROR != status) { - LOGW("Update usage information failed: %u", status); + LOGW("Update usage information failed: %d", status); } else { update_usage_information = false; } diff --git a/libwvdrmengine/cdm/core/src/cdm_session.cpp b/libwvdrmengine/cdm/core/src/cdm_session.cpp index 0ce4d2f8..c10adedf 100644 --- a/libwvdrmengine/cdm/core/src/cdm_session.cpp +++ b/libwvdrmengine/cdm/core/src/cdm_session.cpp @@ -143,8 +143,12 @@ CdmResponseType CdmSession::RestoreOfflineSession( return UNKNOWN_ERROR; } - if (license_state != DeviceFiles::kLicenseStateActive) { - LOGE("CdmSession::Init invalid offline license state = %s", license_state); + // Do not restore a released offline license, unless a release retry + if (!(license_type == kLicenseTypeRelease || + license_state == DeviceFiles::kLicenseStateActive)) { + LOGE("CdmSession::Init invalid offline license state = %d, type = %d", + license_state, + license_type); return UNKNOWN_ERROR; } diff --git a/libwvdrmengine/cdm/core/src/crypto_session.cpp b/libwvdrmengine/cdm/core/src/crypto_session.cpp index 82a6abcd..b6012414 100644 --- a/libwvdrmengine/cdm/core/src/crypto_session.cpp +++ b/libwvdrmengine/cdm/core/src/crypto_session.cpp @@ -66,7 +66,11 @@ void CryptoSession::Init() { void CryptoSession::Terminate() { LOGV("CryptoSession::Terminate"); AutoLock auto_lock(crypto_lock_); - session_count_ -= 1; + if (session_count_ > 0) { + session_count_ -= 1; + } else { + LOGE("CryptoSession::Terminate error, session count: %d", session_count_); + } if (session_count_ > 0 || !initialized_) return; OEMCryptoResult sts = OEMCrypto_Terminate(); if (OEMCrypto_SUCCESS != sts) { @@ -240,12 +244,18 @@ CdmResponseType CryptoSession::Open(SecurityLevel requested_security_level) { OEMCryptoResult sts = OEMCrypto_OpenSession(&sid, requested_security_level); if (OEMCrypto_SUCCESS == sts) { oec_session_id_ = static_cast(sid); - LOGV("OpenSession: id= %ld", (uint32_t)oec_session_id_); + LOGV("OpenSession: id= %d", (uint32_t)oec_session_id_); open_ = true; } else if (OEMCrypto_ERROR_TOO_MANY_SESSIONS == sts) { + LOGE("OEMCrypto_Open failed: %d, open sessions: %ld, initialized: %d", + sts, session_count_, (int)initialized_); return INSUFFICIENT_CRYPTO_RESOURCES; } - if (!open_) return UNKNOWN_ERROR; + if (!open_) { + LOGE("OEMCrypto_Open failed: %d, open sessions: %ld, initialized: %d", + sts, session_count_, (int)initialized_); + return UNKNOWN_ERROR; + } OEMCrypto_GetRandom(reinterpret_cast(&request_id_base_), sizeof(request_id_base_)); diff --git a/libwvdrmengine/cdm/test/Android.mk b/libwvdrmengine/cdm/test/Android.mk index 03f2e1ae..66700ced 100644 --- a/libwvdrmengine/cdm/test/Android.mk +++ b/libwvdrmengine/cdm/test/Android.mk @@ -11,6 +11,10 @@ test_name := cdm_engine_test test_src_dir := ../core/test include $(LOCAL_PATH)/unit-test.mk +test_name := cdm_session_unittest +test_src_dir := ../core/test +include $(LOCAL_PATH)/unit-test.mk + test_name := device_files_unittest test_src_dir := ../core/test include $(LOCAL_PATH)/unit-test.mk diff --git a/libwvdrmengine/cdm/test/request_license_test.cpp b/libwvdrmengine/cdm/test/request_license_test.cpp index 28c657da..9eb33715 100644 --- a/libwvdrmengine/cdm/test/request_license_test.cpp +++ b/libwvdrmengine/cdm/test/request_license_test.cpp @@ -922,6 +922,42 @@ TEST_F(WvCdmRequestLicenseTest, ReleaseOfflineKeyTest) { VerifyKeyRequestResponse(g_license_server, client_auth, false); } +TEST_F(WvCdmRequestLicenseTest, ReleaseRetryOfflineKeyTest) { + // override default settings unless configured through the command line + std::string key_id; + std::string client_auth; + GetOfflineConfiguration(&key_id, &client_auth); + + decryptor_.OpenSession(g_key_system, NULL, &session_id_); + GenerateKeyRequest(key_id, kLicenseTypeOffline); + VerifyKeyRequestResponse(g_license_server, client_auth, false); + + CdmKeySetId key_set_id = key_set_id_; + EXPECT_FALSE(key_set_id_.empty()); + decryptor_.CloseSession(session_id_); + + session_id_.clear(); + key_set_id_.clear(); + decryptor_.OpenSession(g_key_system, NULL, &session_id_); + EXPECT_EQ(wvcdm::KEY_ADDED, decryptor_.RestoreKey(session_id_, key_set_id)); + decryptor_.CloseSession(session_id_); + + session_id_.clear(); + key_set_id_.clear(); + GenerateKeyRelease(key_set_id); + + session_id_.clear(); + decryptor_.OpenSession(g_key_system, NULL, &session_id_); + EXPECT_EQ(wvcdm::UNKNOWN_ERROR, decryptor_.RestoreKey(session_id_, key_set_id)); + decryptor_.CloseSession(session_id_); + + session_id_.clear(); + key_set_id_.clear(); + GenerateKeyRelease(key_set_id); + key_set_id_ = key_set_id; + VerifyKeyRequestResponse(g_license_server, client_auth, false); +} + TEST_F(WvCdmRequestLicenseTest, ExpiryOnReleaseOfflineKeyTest) { // override default settings unless configured through the command line std::string key_id; diff --git a/libwvdrmengine/run_all_unit_tests.sh b/libwvdrmengine/run_all_unit_tests.sh index 5523b489..4644070e 100755 --- a/libwvdrmengine/run_all_unit_tests.sh +++ b/libwvdrmengine/run_all_unit_tests.sh @@ -14,6 +14,7 @@ adb shell /system/bin/policy_engine_unittest adb shell /system/bin/libwvdrmmediacrypto_test adb shell /system/bin/libwvdrmdrmplugin_test adb shell /system/bin/cdm_engine_test +adb shell /system/bin/cdm_session_unittest adb shell /system/bin/file_store_unittest adb shell /system/bin/device_files_unittest adb shell /system/bin/timer_unittest