Use Usage information from OEMCrypto on clock rollback

[ Merge of http://go/wvgerrit/123103 ]

This corrects setting of first and last playback times stored by the
CDM on rollback. Earlier usage information from the usage entry in
OEMCrypto would be ignored on rollback even when available.
Information stored along with the license in persistent storage would
be used instead.

A new test with longer duration expiry has been added as well as some
additional verification.

Bug: 186199213
Test: WV unit/integration test
Change-Id: I601f9584a8a0c5137ce68546f8ec833bf2e70cc5
This commit is contained in:
Rahul Frias
2021-04-23 03:57:10 -07:00
parent 2a316f65fe
commit 87e84d5498
2 changed files with 72 additions and 5 deletions

View File

@@ -864,13 +864,13 @@ CdmResponseType CdmLicense::RestoreOfflineLicense(
break;
case CryptoSession::kUsageDurationsValid: {
int64_t current_time = clock_->GetCurrentTime();
if (current_time - seconds_since_started > 0)
playback_start_time = current_time - seconds_since_started;
if (current_time - last_playback_time > 0)
last_playback_time = current_time - seconds_since_last_played;
playback_start_time = current_time - seconds_since_started;
last_playback_time = current_time - seconds_since_last_played;
break;
}
default:
// Use playback_start_time and last_playback_time from
// persistently stored license data
break;
}
}

View File

@@ -6593,6 +6593,69 @@ TEST_F(WvCdmRequestLicenseRollbackTest, Offline_RollbackBeforeRestoreKey) {
ASSERT_EQ(NO_ERROR, decryptor_->CloseSession(session_id_));
}
// The difference between this test and Offline_RollbackBeforeRestoreKey is
// that this test has a 15 second expiration window.
// Offline_RollbackBeforeRestoreKey has a 5 second window. The rollback
// before restore causes the expiration timer to run from the rollback time.
// The license in Offline_RollbackBeforeRestoreKey is expired by the time
// the rollback is undone, while this one has not yet expired.
TEST_F(WvCdmRequestLicenseRollbackTest,
Offline_LongerDurationRollbackBeforeRestoreKey) {
Unprovision();
Provision();
// The default offline asset is "offline_clip2". Substitute '2' for '8'.
// "offline_clip8" has a 15 second expiration.
std::string key_id;
std::string client_auth;
GetOfflineConfiguration(&key_id, &client_auth);
key_id[key_id.size() - 1] = '8';
ASSERT_EQ(NO_ERROR, decryptor_->OpenSession(config_.key_system(), nullptr,
kDefaultCdmIdentifier, nullptr,
&session_id_));
GenerateKeyRequest(key_id, kLicenseTypeOffline);
VerifyKeyRequestResponse(config_.license_server(), client_auth);
// Verify that we can decrypt a subsample to begin with.
EXPECT_EQ(NO_ERROR, Decrypt(session_id_));
CdmKeySetId key_set_id = key_set_id_;
EXPECT_FALSE(key_set_id_.empty());
decryptor_->CloseSession(session_id_);
// This number must be > the time between GenerateKeyRequest and this call.
RollbackSystemTime(10 * 1000);
session_id_.clear();
decryptor_->OpenSession(config_.key_system(), nullptr, kDefaultCdmIdentifier,
nullptr, &session_id_);
decryptor_->RestoreKey(session_id_, key_set_id);
// Verify we can't decrypt. The license start time is in the future.
EXPECT_EQ(DECRYPT_NOT_READY, Decrypt(session_id_));
RestoreSystemTime();
// Sleep for a little bit to account for the execution time of OpenSession and
// RestoreKey.
std::this_thread::sleep_for(std::chrono::milliseconds(kExpirationWindowMs_));
// Verify we can decrypt.
EXPECT_EQ(NO_ERROR, Decrypt(session_id_));
// Sleep for a while more.
std::this_thread::sleep_for(std::chrono::milliseconds(kExpirationTimeMs_));
// Rollback time + kExpirationWindowMs_ + kExpirationTimeMs_ (~17s) will have
// elapsed. This is greater than the expiration window for longer duration
// licenses (15s). The license should have expired.
EXPECT_EQ(NEED_KEY, Decrypt(session_id_));
ASSERT_EQ(NO_ERROR, decryptor_->CloseSession(session_id_));
}
TEST_F(WvCdmRequestLicenseRollbackTest,
Offline_RollbackAndExpireAfterRestoreKey) {
Unprovision();
@@ -6631,6 +6694,8 @@ TEST_F(WvCdmRequestLicenseRollbackTest,
RestoreSystemTime();
EXPECT_EQ(NEED_KEY, Decrypt(session_id_));
ASSERT_EQ(NO_ERROR, decryptor_->CloseSession(session_id_));
}
@@ -6665,9 +6730,11 @@ TEST_F(WvCdmRequestLicenseRollbackTest,
std::this_thread::sleep_for(
std::chrono::milliseconds(kExpirationWithWindowMs_));
// Verify that we can no longer decrypt a subsample due to key expiration.
EXPECT_EQ(NEED_KEY, Decrypt(session_id_));
RollbackSystemTime(kExpirationWithWindowMs_);
// Verify that we can no longer decrypt a subsample due to key expiration.
EXPECT_EQ(NEED_KEY, Decrypt(session_id_));
RestoreSystemTime();