Refactor missed provisioning and renewal tests

Merge from Widevine repo of http://go/wvgerrit/169079

Bug: 253779846
Merged from https://widevine-internal-review.googlesource.com/167738

Change-Id: If8fc484f02fc1544977f1fb3a5fe1fa42d7367d7
This commit is contained in:
Vicky Min
2023-03-27 19:42:06 -07:00
committed by Fred Gylys-Colwell
parent 225a3e50ed
commit f83698a164
6 changed files with 404 additions and 410 deletions

View File

@@ -6,6 +6,9 @@
#include "oemcrypto_license_test.h"
#include "platform.h"
#include "test_sleep.h"
using ::testing::Range;
namespace wvoec {
@@ -800,5 +803,169 @@ TEST_F(OEMCryptoSessionTests, CheckMinimumPatchLevel) {
}
}
//
// Load, Refresh Keys Test
//
// Refresh keys should work if the license uses a nonce.
TEST_P(OEMCryptoRefreshTest, RefreshWithNonce) {
LoadLicense();
RenewalRoundTrip renewal_messages(&license_messages_);
MakeRenewalRequest(&renewal_messages);
LoadRenewal(&renewal_messages, OEMCrypto_SUCCESS);
}
// Refresh keys should work if the license does not use a nonce.
TEST_P(OEMCryptoRefreshTest, RefreshNoNonce) {
license_messages_.set_control(0);
LoadLicense();
RenewalRoundTrip renewal_messages(&license_messages_);
MakeRenewalRequest(&renewal_messages);
LoadRenewal(&renewal_messages, OEMCrypto_SUCCESS);
}
// Refresh keys should NOT work if a license has not been loaded.
TEST_P(OEMCryptoRefreshTestAPI16, RefreshNoLicense) {
Session s;
s.open();
constexpr size_t message_size = kMaxCoreMessage + 42;
std::vector<uint8_t> data(message_size);
for (size_t i = 0; i < data.size(); i++) data[i] = i & 0xFF;
size_t gen_signature_length = 0;
size_t core_message_length = 0;
OEMCryptoResult sts = OEMCrypto_PrepAndSignRenewalRequest(
s.session_id(), data.data(), data.size(), &core_message_length, nullptr,
&gen_signature_length);
ASSERT_LT(core_message_length, message_size);
if (sts == OEMCrypto_ERROR_SHORT_BUFFER) {
vector<uint8_t> gen_signature(gen_signature_length);
sts = OEMCrypto_PrepAndSignRenewalRequest(
s.session_id(), data.data(), data.size(), &core_message_length,
gen_signature.data(), &gen_signature_length);
}
ASSERT_NE(OEMCrypto_SUCCESS, sts);
}
// Refresh keys should fail if the nonce is not in the session.
TEST_P(OEMCryptoRefreshTestAPI16, RefreshBadNonce) {
LoadLicense();
RenewalRoundTrip renewal_messages(&license_messages_);
MakeRenewalRequest(&renewal_messages);
renewal_messages.core_request().nonce ^= 42;
LoadRenewal(&renewal_messages, OEMCrypto_ERROR_INVALID_NONCE);
}
// Refresh keys should fail if the session_id does not match the license.
TEST_P(OEMCryptoRefreshTestAPI16, RefreshBadSessionID) {
LoadLicense();
RenewalRoundTrip renewal_messages(&license_messages_);
MakeRenewalRequest(&renewal_messages);
renewal_messages.core_request().session_id += 1;
LoadRenewal(&renewal_messages, OEMCrypto_ERROR_INVALID_NONCE);
}
// Refresh keys should handle the maximum message size.
TEST_P(OEMCryptoRefreshTest, RefreshLargeBuffer) {
LoadLicense();
RenewalRoundTrip renewal_messages(&license_messages_);
const size_t max_size = GetResourceValue(kLargeMessageSize);
renewal_messages.set_message_size(max_size);
MakeRenewalRequest(&renewal_messages);
LoadRenewal(&renewal_messages, OEMCrypto_SUCCESS);
}
// This situation would occur if an app only uses one key in the license. When
// that happens, SelectKey would be called before the first decrypt, and then
// would not need to be called again, even if the license is refreshed.
TEST_P(OEMCryptoRefreshTest, RefreshWithNoSelectKey) {
LoadLicense();
// Call select key before the refresh. No calls below to TestDecryptCTR with
// select key set to true.
ASSERT_NO_FATAL_FAILURE(session_.TestDecryptCTR(true));
// This should still be valid key, even if the refresh failed, because this
// is before the original license duration.
wvutil::TestSleep::Sleep(kShortSleep);
ASSERT_NO_FATAL_FAILURE(session_.TestDecryptCTR(false));
// This should be after duration of the original license, but before the
// expiration of the refresh message. This should fail until we have loaded
// the renewal.
wvutil::TestSleep::Sleep(kShortSleep + kLongSleep);
ASSERT_NO_FATAL_FAILURE(
session_.TestDecryptCTR(false, OEMCrypto_ERROR_KEY_EXPIRED));
RenewalRoundTrip renewal_messages(&license_messages_);
MakeRenewalRequest(&renewal_messages);
LoadRenewal(&renewal_messages, OEMCrypto_SUCCESS);
// After we've loaded the renewal, decrypt should succeed again.
ASSERT_NO_FATAL_FAILURE(session_.TestDecryptCTR(false));
}
// Test that playback clock is correctly started and that the license can be
// renewed.
TEST_P(OEMCryptoRefreshTest, RenewLicenseLoadSuccess) {
license_messages_.core_response().renewal_delay_base = OEMCrypto_License_Load;
timer_limits_.rental_duration_seconds = kDuration; // 2 seconds.
timer_limits_.initial_renewal_duration_seconds = kLongDuration; // 5 seconds.
// First version to support Renew on Load.
constexpr uint32_t kFeatureVersion = 18;
// Loading the license should start the playback clock.
LoadLicense();
// Sleep until just after rental window is over.
wvutil::TestSleep::Sleep(kDuration + kShortSleep);
if (license_api_version_ < kFeatureVersion ||
global_features.api_version < kFeatureVersion) {
// If the feature is not supported, then we expect failure because the
// playback clock was not started and we are outside the rental window.
ASSERT_NO_FATAL_FAILURE(
session_.TestDecryptCTR(true, OEMCrypto_ERROR_KEY_EXPIRED));
return;
} else {
// If the feature is supported, we expect decrypt to work because we are
// still within the initial renewal window, and the playback clock should
// have started.
ASSERT_NO_FATAL_FAILURE(session_.TestDecryptCTR(true, OEMCrypto_SUCCESS));
}
// This is after the initial renewal duration, so we expect failure before
// loading the renewal.
wvutil::TestSleep::Sleep(kShortSleep + kLongSleep);
ASSERT_NO_FATAL_FAILURE(
session_.TestDecryptCTR(false, OEMCrypto_ERROR_KEY_EXPIRED));
RenewalRoundTrip renewal_messages(&license_messages_);
MakeRenewalRequest(&renewal_messages);
LoadRenewal(&renewal_messages, OEMCrypto_SUCCESS);
// After we've loaded the renewal, decrypt should succeed again.
ASSERT_NO_FATAL_FAILURE(session_.TestDecryptCTR(false));
}
TEST_P(OEMCryptoRefreshTest, RenewLicenseLoadOutsideRentalDuration) {
license_messages_.core_response().renewal_delay_base = OEMCrypto_License_Load;
timer_limits_.rental_duration_seconds = kDuration; // 2 seconds.
timer_limits_.initial_renewal_duration_seconds = kLongDuration; // 5 seconds.
// Sleep until just after rental window is over.
wvutil::TestSleep::Sleep(kDuration + kShortSleep);
// Loading the license should start the playback clock.
LoadLicense();
// If the license is loaded after the rental duration window, we expect
// failure.
ASSERT_NO_FATAL_FAILURE(
session_.TestDecryptCTR(false, OEMCrypto_ERROR_UNKNOWN_FAILURE));
return;
}
INSTANTIATE_TEST_SUITE_P(TestAll, OEMCryptoRefreshTest,
Range<uint32_t>(kCurrentAPI - 1, kCurrentAPI + 1));
// These tests only work when the license has a core message.
INSTANTIATE_TEST_SUITE_P(TestAPI16, OEMCryptoRefreshTestAPI16,
Range<uint32_t>(kCoreMessagesAPI, kCurrentAPI + 1));
/// @}
} // namespace wvoec