diff --git a/libwvdrmengine/cdm/core/include/cdm_session.h b/libwvdrmengine/cdm/core/include/cdm_session.h index 31657814..4f83aaf4 100644 --- a/libwvdrmengine/cdm/core/include/cdm_session.h +++ b/libwvdrmengine/cdm/core/include/cdm_session.h @@ -85,8 +85,10 @@ class CdmSession { virtual void OnKeyReleaseEvent(const CdmKeySetId& key_set_id); virtual void GetApplicationId(std::string* app_id); - virtual SecurityLevel GetRequestedSecurityLevel(); - virtual CdmSecurityLevel GetSecurityLevel(); + virtual SecurityLevel GetRequestedSecurityLevel() { + return requested_security_level_; + } + virtual CdmSecurityLevel GetSecurityLevel() { return security_level_; } virtual CdmResponseType DeleteUsageInformation(const std::string& app_id); virtual CdmResponseType UpdateUsageInformation(); @@ -130,6 +132,7 @@ class CdmSession { bool is_offline_; bool is_release_; CdmSecurityLevel security_level_; + SecurityLevel requested_security_level_; std::string app_id_; // decryption and usage flags diff --git a/libwvdrmengine/cdm/core/include/license.h b/libwvdrmengine/cdm/core/include/license.h index 9fa55d63..b27415bf 100644 --- a/libwvdrmengine/cdm/core/include/license.h +++ b/libwvdrmengine/cdm/core/include/license.h @@ -86,7 +86,7 @@ class CdmLicense { scoped_ptr clock_; // For testing - CdmLicense(Clock* clock); + CdmLicense(Clock* clock); // CdmLicense takes ownership of the clock. #if defined(UNIT_TEST) friend class CdmLicenseTest; #endif diff --git a/libwvdrmengine/cdm/core/src/cdm_engine.cpp b/libwvdrmengine/cdm/core/src/cdm_engine.cpp index 12316c18..d4d052f6 100644 --- a/libwvdrmengine/cdm/core/src/cdm_engine.cpp +++ b/libwvdrmengine/cdm/core/src/cdm_engine.cpp @@ -207,9 +207,8 @@ CdmResponseType CdmEngine::GenerateKeyRequest( if (license_type == kLicenseTypeRelease) { sts = iter->second->RestoreOfflineSession(key_set_id, kLicenseTypeRelease); if (sts != KEY_ADDED) { - LOGE( - "CdmEngine::GenerateKeyRequest: key release restoration failed," - "sts = %d", sts); + LOGE("CdmEngine::GenerateKeyRequest: key release restoration failed," + "sts = %d", static_cast(sts)); return sts; } } @@ -223,9 +222,8 @@ CdmResponseType CdmEngine::GenerateKeyRequest( cert_provisioning_requested_security_level_ = iter->second->GetRequestedSecurityLevel(); } - LOGE( - "CdmEngine::GenerateKeyRequest: key request generation failed, " - "sts = %d", sts); + LOGE("CdmEngine::GenerateKeyRequest: key request generation failed, " + "sts = %d", static_cast(sts)); return sts; } @@ -291,7 +289,7 @@ CdmResponseType CdmEngine::RestoreKey(const CdmSessionId& session_id, LOGI("CdmEngine::RestoreKey"); if (key_set_id.empty()) { - LOGE("CdmEngine::RestoreKey: invalid key set id"); + LOGI("CdmEngine::RestoreKey: invalid key set id"); return KEY_ERROR; } @@ -308,7 +306,7 @@ CdmResponseType CdmEngine::RestoreKey(const CdmSessionId& session_id, cert_provisioning_requested_security_level_ = iter->second->GetRequestedSecurityLevel(); } - if (KEY_ADDED != sts) { + if (sts != KEY_ADDED) { LOGE("CdmEngine::RestoreKey: restore offline session failed = %d", sts); } return sts; @@ -376,7 +374,7 @@ CdmResponseType CdmEngine::RenewKey(const CdmSessionId& session_id, CdmResponseType sts = iter->second->RenewKey(key_data); if (KEY_ADDED != sts) { - LOGE("CdmEngine::RenewKey: keys not added, sts=%d", sts); + LOGE("CdmEngine::RenewKey: keys not added, sts=%d", static_cast(sts)); return sts; } diff --git a/libwvdrmengine/cdm/core/src/cdm_session.cpp b/libwvdrmengine/cdm/core/src/cdm_session.cpp index a3afe9d4..5917fed1 100644 --- a/libwvdrmengine/cdm/core/src/cdm_session.cpp +++ b/libwvdrmengine/cdm/core/src/cdm_session.cpp @@ -73,11 +73,17 @@ void CdmSession::Create(CdmLicense* license_parser, is_usage_update_needed_ = false; is_initial_decryption_ = true; has_decrypted_since_last_report_ = false; - if (cdm_client_property_set) { + requested_security_level_ = kLevelDefault; + if (NULL != cdm_client_property_set) { + if (QUERY_VALUE_SECURITY_LEVEL_L3.compare( + cdm_client_property_set->security_level()) == 0) { + requested_security_level_ = kLevel3; + } Properties::AddSessionPropertySet(session_id_, cdm_client_property_set); } - security_level_ = GetRequestedSecurityLevel() == kLevel3 ? kSecurityLevelL3 - : GetSecurityLevel(); + security_level_ = + GetRequestedSecurityLevel() == kLevel3 ? kSecurityLevelL3 + : kSecurityLevelUninitialized; app_id_.clear(); } @@ -92,8 +98,9 @@ CdmResponseType CdmSession::Init() { LOGE("CdmSession::Init: Failed due to previous initialization"); return UNKNOWN_ERROR; } - CdmResponseType sts = crypto_session_->Open(GetRequestedSecurityLevel()); + CdmResponseType sts = crypto_session_->Open(requested_security_level_); if (NO_ERROR != sts) return sts; + security_level_ = crypto_session_->GetSecurityLevel(); std::string token; if (Properties::use_certificates_as_identification()) { @@ -293,7 +300,7 @@ CdmResponseType CdmSession::QueryStatus(CdmQueryMap* key_info) { return UNKNOWN_ERROR; } - switch (crypto_session_->GetSecurityLevel()) { + switch (security_level_) { case kSecurityLevelL1: (*key_info)[QUERY_KEY_SECURITY_LEVEL] = QUERY_VALUE_SECURITY_LEVEL_L1; break; @@ -588,23 +595,6 @@ void CdmSession::GetApplicationId(std::string* app_id) { } } -SecurityLevel CdmSession::GetRequestedSecurityLevel() { - std::string security_level; - if (Properties::GetSecurityLevel(session_id_, &security_level) && - security_level == QUERY_VALUE_SECURITY_LEVEL_L3) { - return kLevel3; - } - - return kLevelDefault; -} - -CdmSecurityLevel CdmSession::GetSecurityLevel() { - if (NULL == crypto_session_.get()) - return kSecurityLevelUninitialized; - - return crypto_session_.get()->GetSecurityLevel(); -} - CdmResponseType CdmSession::DeleteUsageInformation(const std::string& app_id) { if (!file_handle_->Reset(security_level_)) { LOGE("CdmSession::StoreLicense: Unable to initialize device files"); diff --git a/libwvdrmengine/cdm/core/src/crypto_session.cpp b/libwvdrmengine/cdm/core/src/crypto_session.cpp index 0585510e..083ad49e 100644 --- a/libwvdrmengine/cdm/core/src/crypto_session.cpp +++ b/libwvdrmengine/cdm/core/src/crypto_session.cpp @@ -175,8 +175,7 @@ bool CryptoSession::GetApiVersion(uint32_t* version) { if (!initialized_) { return false; } - *version = OEMCrypto_APIVersion( - kSecurityLevelL3 == GetSecurityLevel() ? kLevel3 : kLevelDefault); + *version = OEMCrypto_APIVersion(requested_security_level_); return true; } diff --git a/libwvdrmengine/cdm/core/test/cdm_session_unittest.cpp b/libwvdrmengine/cdm/core/test/cdm_session_unittest.cpp index c940c52a..3dbffe1c 100644 --- a/libwvdrmengine/cdm/core/test/cdm_session_unittest.cpp +++ b/libwvdrmengine/cdm/core/test/cdm_session_unittest.cpp @@ -92,6 +92,7 @@ using ::testing::Eq; using ::testing::NotNull; using ::testing::Return; using ::testing::SetArgPointee; +using ::testing::Sequence; using ::testing::StrEq; class MockDeviceFiles : public DeviceFiles { @@ -151,15 +152,20 @@ class CdmSessionTest : public ::testing::Test { }; TEST_F(CdmSessionTest, InitWithCertificate) { + Sequence crypto_session_seq; CdmSecurityLevel level = kSecurityLevelL1; - EXPECT_CALL(*crypto_session_, GetSecurityLevel()).WillOnce(Return(level)); EXPECT_CALL(*crypto_session_, Open(Eq(kLevelDefault))) + .InSequence(crypto_session_seq) .WillOnce(Return(NO_ERROR)); + EXPECT_CALL(*crypto_session_, GetSecurityLevel()) + .InSequence(crypto_session_seq) + .WillOnce(Return(level)); EXPECT_CALL(*file_handle_, Init(Eq(level))).WillOnce(Return(true)); EXPECT_CALL(*file_handle_, RetrieveCertificate(NotNull(), NotNull())) .WillOnce(DoAll(SetArgPointee<0>(kToken), SetArgPointee<1>(kWrappedKey), Return(true))); EXPECT_CALL(*crypto_session_, LoadCertificatePrivateKey(StrEq(kWrappedKey))) + .InSequence(crypto_session_seq) .WillOnce(Return(true)); EXPECT_CALL(*license_parser_, Init(Eq(kToken), Eq(crypto_session_), Eq(policy_engine_))) @@ -172,11 +178,16 @@ TEST_F(CdmSessionTest, InitWithCertificate) { } TEST_F(CdmSessionTest, InitWithKeybox) { + Sequence crypto_session_seq; CdmSecurityLevel level = kSecurityLevelL1; - EXPECT_CALL(*crypto_session_, GetSecurityLevel()).WillOnce(Return(level)); EXPECT_CALL(*crypto_session_, Open(Eq(kLevelDefault))) + .InSequence(crypto_session_seq) .WillOnce(Return(NO_ERROR)); + EXPECT_CALL(*crypto_session_, GetSecurityLevel()) + .InSequence(crypto_session_seq) + .WillOnce(Return(level)); EXPECT_CALL(*crypto_session_, GetToken(NotNull())) + .InSequence(crypto_session_seq) .WillOnce(DoAll(SetArgPointee<0>(kToken), Return(true))); EXPECT_CALL(*license_parser_, Init(Eq(kToken), Eq(crypto_session_), Eq(policy_engine_))) @@ -189,15 +200,20 @@ TEST_F(CdmSessionTest, InitWithKeybox) { } TEST_F(CdmSessionTest, ReInitFail) { + Sequence crypto_session_seq; CdmSecurityLevel level = kSecurityLevelL1; - EXPECT_CALL(*crypto_session_, GetSecurityLevel()).WillOnce(Return(level)); EXPECT_CALL(*crypto_session_, Open(Eq(kLevelDefault))) + .InSequence(crypto_session_seq) .WillOnce(Return(NO_ERROR)); + EXPECT_CALL(*crypto_session_, GetSecurityLevel()) + .InSequence(crypto_session_seq) + .WillOnce(Return(level)); EXPECT_CALL(*file_handle_, Init(Eq(level))).WillOnce(Return(true)); EXPECT_CALL(*file_handle_, RetrieveCertificate(NotNull(), NotNull())) .WillOnce(DoAll(SetArgPointee<0>(kToken), SetArgPointee<1>(kWrappedKey), Return(true))); EXPECT_CALL(*crypto_session_, LoadCertificatePrivateKey(StrEq(kWrappedKey))) + .InSequence(crypto_session_seq) .WillOnce(Return(true)); EXPECT_CALL(*license_parser_, Init(Eq(kToken), Eq(crypto_session_), Eq(policy_engine_))) @@ -212,7 +228,6 @@ TEST_F(CdmSessionTest, ReInitFail) { TEST_F(CdmSessionTest, InitFailCryptoError) { CdmSecurityLevel level = kSecurityLevelL1; - EXPECT_CALL(*crypto_session_, GetSecurityLevel()).WillOnce(Return(level)); EXPECT_CALL(*crypto_session_, Open(Eq(kLevelDefault))) .WillOnce(Return(UNKNOWN_ERROR)); @@ -223,10 +238,14 @@ TEST_F(CdmSessionTest, InitFailCryptoError) { } TEST_F(CdmSessionTest, InitNeedsProvisioning) { + Sequence crypto_session_seq; CdmSecurityLevel level = kSecurityLevelL1; - EXPECT_CALL(*crypto_session_, GetSecurityLevel()).WillOnce(Return(level)); EXPECT_CALL(*crypto_session_, Open(Eq(kLevelDefault))) + .InSequence(crypto_session_seq) .WillOnce(Return(NO_ERROR)); + EXPECT_CALL(*crypto_session_, GetSecurityLevel()) + .InSequence(crypto_session_seq) + .WillOnce(Return(level)); EXPECT_CALL(*file_handle_, Init(Eq(level))).WillOnce(Return(true)); EXPECT_CALL(*file_handle_, RetrieveCertificate(NotNull(), NotNull())) .WillOnce(Return(false)); diff --git a/libwvdrmengine/cdm/test/request_license_test.cpp b/libwvdrmengine/cdm/test/request_license_test.cpp index 6b9206d1..c453faab 100644 --- a/libwvdrmengine/cdm/test/request_license_test.cpp +++ b/libwvdrmengine/cdm/test/request_license_test.cpp @@ -1330,12 +1330,7 @@ TEST_P(WvCdmUsageInfoTest, UsageInfo) { EXPECT_EQ(NO_ERROR, decryptor_.ReleaseUsageInfo(release_msg)); } status = decryptor_.GetUsageInfo(usage_info_data->app_id, &usage_info); - switch (status) { - case KEY_MESSAGE: EXPECT_FALSE(usage_info.empty()); break; - case NO_ERROR: EXPECT_TRUE(usage_info.empty()); break; - default: FAIL() << "GetUsageInfo failed with error " - << static_cast(status) ; break; - } + EXPECT_EQ(usage_info.empty() ? NO_ERROR : KEY_MESSAGE, status); } } @@ -1362,6 +1357,7 @@ TEST_F(WvCdmRequestLicenseTest, QueryUnmodifiedSessionStatus) { TEST_F(WvCdmRequestLicenseTest, QueryModifiedSessionStatus) { // Test that L3 is returned when properties downgrade security. + Unprovision(); Provision(kLevel3); TestWvCdmClientPropertySet property_set_L3; property_set_L3.set_security_level(QUERY_VALUE_SECURITY_LEVEL_L3); @@ -1530,6 +1526,8 @@ TEST_F(WvCdmRequestLicenseTest, SecurityLevelPathBackwardCompatibility) { EXPECT_TRUE(file.List(base_path, &files)); int number_of_new_files = files.size() - number_of_files; + // There should be a new license file, and maybe a new usage table + // file. EXPECT_LE(1, number_of_new_files); EXPECT_GE(2, number_of_new_files);