diff --git a/libwvdrmengine/oemcrypto/test/oemcrypto_test.cpp b/libwvdrmengine/oemcrypto/test/oemcrypto_test.cpp index 374e54d2..659df94a 100644 --- a/libwvdrmengine/oemcrypto/test/oemcrypto_test.cpp +++ b/libwvdrmengine/oemcrypto/test/oemcrypto_test.cpp @@ -4365,6 +4365,43 @@ TEST_P(UsageTableTestWithMAC, OnlineLicense) { s.TestDecryptCTR(false, OEMCrypto_ERROR_UNKNOWN_FAILURE)); } +TEST_P(UsageTableTestWithMAC, OnlineLicenseWithRefresh) { + std::string pst = "my_pst"; + ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_UpdateUsageTable()); + Session s; + ASSERT_NO_FATAL_FAILURE(s.open()); + ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s)); + ASSERT_NO_FATAL_FAILURE(s.FillSimpleMessage( + 0, wvoec_mock::kControlNonceEnabled | wvoec_mock::kControlNonceRequired, + s.get_nonce(), pst)); + ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign()); + ASSERT_NO_FATAL_FAILURE(s.LoadTestKeys(pst, new_mac_keys_)); + time_t loaded = time(NULL); + ASSERT_NO_FATAL_FAILURE(s.TestDecryptCTR()); + s.GenerateNonce(); + // License renewal message is signed by client and verified by the server. + ASSERT_NO_FATAL_FAILURE(s.VerifyClientSignature()); + size_t kAllKeys = 1; + ASSERT_NO_FATAL_FAILURE(s.RefreshTestKeys( + kAllKeys, + wvoec_mock::kControlNonceEnabled | wvoec_mock::kControlNonceRequired, + s.get_nonce(), OEMCrypto_SUCCESS)); + s.GenerateReport(pst); + time_t report_generated = time(NULL); + EXPECT_EQ(kActive, s.pst_report()->status); + // license received at LoadKeys, not at RefreshKeys. + EXPECT_NEAR(report_generated - loaded, + wvcdm::htonll64(s.pst_report()->seconds_since_license_received), + kTimeTolerance); + // First decrypt was just after LoadKeys. + EXPECT_NEAR(report_generated - loaded, + wvcdm::htonll64(s.pst_report()->seconds_since_first_decrypt), + kTimeTolerance); + // Last decrypt just before report generated. + EXPECT_NEAR(0, wvcdm::htonll64(s.pst_report()->seconds_since_last_decrypt), + kTimeTolerance); +} + TEST_F(UsageTableTest, RepeatOnlineLicense) { std::string pst = "my_pst"; ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_UpdateUsageTable()); @@ -4955,6 +4992,40 @@ TEST_P(UsageTableTestWithMAC, OfflineLicense) { ASSERT_NO_FATAL_FAILURE(LoadOfflineLicense(s, pst)); } +TEST_P(UsageTableTestWithMAC, OfflineLicenseRefresh) { + std::string pst = "my_pst"; + ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_UpdateUsageTable()); + Session s; + ASSERT_NO_FATAL_FAILURE(s.open()); + ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s)); + ASSERT_NO_FATAL_FAILURE(s.FillSimpleMessage( + 0, wvoec_mock::kControlNonceOrEntry, s.get_nonce(), pst)); + ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign()); + ASSERT_NO_FATAL_FAILURE(s.LoadTestKeys(pst, new_mac_keys_)); + time_t loaded = time(NULL); + ASSERT_NO_FATAL_FAILURE(s.TestDecryptCTR()); + s.GenerateNonce(); + // License renewal message is signed by client and verified by the server. + ASSERT_NO_FATAL_FAILURE(s.VerifyClientSignature()); + size_t kAllKeys = 1; + ASSERT_NO_FATAL_FAILURE(s.RefreshTestKeys( + kAllKeys, wvoec_mock::kControlNonceOrEntry, 0, OEMCrypto_SUCCESS)); + s.GenerateReport(pst); + time_t report_generated = time(NULL); + EXPECT_EQ(kActive, s.pst_report()->status); + // license received at LoadKeys, not at RefreshKeys. + EXPECT_NEAR(report_generated - loaded, + wvcdm::htonll64(s.pst_report()->seconds_since_license_received), + kTimeTolerance); + // First decrypt was just after LoadKeys. + EXPECT_NEAR(report_generated - loaded, + wvcdm::htonll64(s.pst_report()->seconds_since_first_decrypt), + kTimeTolerance); + // Last decrypt just before report generated. + EXPECT_NEAR(0, wvcdm::htonll64(s.pst_report()->seconds_since_last_decrypt), + kTimeTolerance); +} + TEST_P(UsageTableTestWithMAC, ReloadOfflineLicense) { std::string pst = "my_pst"; ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_UpdateUsageTable()); @@ -4985,6 +5056,60 @@ TEST_P(UsageTableTestWithMAC, ReloadOfflineLicense) { ASSERT_NO_FATAL_FAILURE(s.close()); } +TEST_P(UsageTableTestWithMAC, ReloadOfflineLicenseWithRefresh) { + std::string pst = "my_pst"; + ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_UpdateUsageTable()); + Session s; + ASSERT_NO_FATAL_FAILURE(LoadOfflineLicense(s, pst)); + time_t loaded = time(NULL); + + ASSERT_NO_FATAL_FAILURE(s.open()); + ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s)); + // We will reuse the encrypted and signed message, so we don't call + // FillSimpleMessage again. + ASSERT_NO_FATAL_FAILURE(s.LoadTestKeys(pst, new_mac_keys_)); + s.GenerateReport(pst); + s.GenerateReport(pst); + EXPECT_EQ(kUnused, s.pst_report()->status); + EXPECT_NEAR(0, + wvcdm::htonll64(s.pst_report()->seconds_since_license_received), + kTimeTolerance); + ASSERT_NO_FATAL_FAILURE(s.TestDecryptCTR()); + time_t decrypt_time = time(NULL); + s.GenerateReport(pst); + time_t report_generated = time(NULL); + EXPECT_EQ(kActive, s.pst_report()->status); + // license received at first LoadKeys. + EXPECT_NEAR(report_generated - loaded, + wvcdm::htonll64(s.pst_report()->seconds_since_license_received), + kTimeTolerance); + // First decrypt was just after second LoadKeys. + EXPECT_NEAR(report_generated - decrypt_time, + wvcdm::htonll64(s.pst_report()->seconds_since_first_decrypt), + kTimeTolerance); + EXPECT_NEAR(report_generated - decrypt_time, + wvcdm::htonll64(s.pst_report()->seconds_since_last_decrypt), + kTimeTolerance); + size_t kAllKeys = 1; + ASSERT_NO_FATAL_FAILURE(s.RefreshTestKeys( + kAllKeys, wvoec_mock::kControlNonceOrEntry, 0, OEMCrypto_SUCCESS)); + s.GenerateReport(pst); + report_generated = time(NULL); + EXPECT_EQ(kActive, s.pst_report()->status); + // license received at LoadKeys, not at RefreshKeys. + EXPECT_NEAR(report_generated - loaded, + wvcdm::htonll64(s.pst_report()->seconds_since_license_received), + kTimeTolerance); + // First decrypt was just after LoadKeys. + EXPECT_NEAR(report_generated - decrypt_time, + wvcdm::htonll64(s.pst_report()->seconds_since_first_decrypt), + kTimeTolerance); + // Last decrypt just before report generated. + EXPECT_NEAR(0, wvcdm::htonll64(s.pst_report()->seconds_since_last_decrypt), + kTimeTolerance); + ASSERT_NO_FATAL_FAILURE(s.close()); +} + TEST_P(UsageTableTestWithMAC, BadReloadOfflineLicense) { std::string pst = "my_pst"; ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_UpdateUsageTable());