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:
committed by
Fred Gylys-Colwell
parent
225a3e50ed
commit
f83698a164
@@ -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
|
||||
@@ -359,6 +359,52 @@ class LicenseWithUsageEntry {
|
||||
bool active_;
|
||||
};
|
||||
|
||||
class OEMCryptoRefreshTest : public OEMCryptoLicenseTest {
|
||||
protected:
|
||||
void SetUp() override {
|
||||
OEMCryptoLicenseTest::SetUp();
|
||||
// These values allow us to run a few simple duration tests or just start
|
||||
// playback right away. All times are in seconds since the license was
|
||||
// signed.
|
||||
// Soft expiry false means timers are strictly enforce.
|
||||
timer_limits_.soft_enforce_rental_duration = true;
|
||||
timer_limits_.soft_enforce_playback_duration = false;
|
||||
// Playback may begin immediately.
|
||||
timer_limits_.earliest_playback_start_seconds = 0;
|
||||
// First playback may be within the first two seconds.
|
||||
timer_limits_.rental_duration_seconds = kDuration;
|
||||
// Once started, playback may last two seconds without a renewal.
|
||||
timer_limits_.initial_renewal_duration_seconds = kDuration;
|
||||
// Total playback is not limited.
|
||||
timer_limits_.total_playback_duration_seconds = 0;
|
||||
}
|
||||
|
||||
void LoadLicense() {
|
||||
license_messages_.core_response().timer_limits = timer_limits_;
|
||||
ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest());
|
||||
ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse());
|
||||
ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse());
|
||||
ASSERT_EQ(OEMCrypto_SUCCESS, license_messages_.LoadResponse());
|
||||
}
|
||||
|
||||
void MakeRenewalRequest(RenewalRoundTrip* renewal_messages) {
|
||||
ASSERT_NO_FATAL_FAILURE(renewal_messages->SignAndVerifyRequest());
|
||||
ASSERT_NO_FATAL_FAILURE(renewal_messages->CreateDefaultResponse());
|
||||
}
|
||||
|
||||
void LoadRenewal(RenewalRoundTrip* renewal_messages,
|
||||
OEMCryptoResult expected_result) {
|
||||
ASSERT_NO_FATAL_FAILURE(renewal_messages->EncryptAndSignResponse());
|
||||
ASSERT_EQ(expected_result, renewal_messages->LoadResponse());
|
||||
}
|
||||
|
||||
ODK_TimerLimits timer_limits_;
|
||||
};
|
||||
|
||||
// This class is for the refresh tests that should only be run on licenses with
|
||||
// a core message.
|
||||
class OEMCryptoRefreshTestAPI16 : public OEMCryptoRefreshTest {};
|
||||
|
||||
} // namespace wvoec
|
||||
|
||||
#endif // CDM_OEMCRYPTO_LICENSE_TEST_
|
||||
@@ -868,5 +868,195 @@ TEST_F(OEMCryptoLoadsCertificate, CertificateProvisionLargeBuffer) {
|
||||
provisioning_messages.encoded_rsa_key()));
|
||||
}
|
||||
|
||||
// Test that a wrapped RSA key can be loaded.
|
||||
TEST_F(OEMCryptoLoadsCertificate, LoadWrappedRSAKey) {
|
||||
ASSERT_NO_FATAL_FAILURE(CreateWrappedDRMKey());
|
||||
Session s;
|
||||
ASSERT_NO_FATAL_FAILURE(s.open());
|
||||
ASSERT_NO_FATAL_FAILURE(s.LoadWrappedRsaDrmKey(wrapped_drm_key_));
|
||||
}
|
||||
|
||||
class OEMCryptoLoadsCertVariousKeys : public OEMCryptoLoadsCertificate {
|
||||
public:
|
||||
void TestKey(const uint8_t* key, size_t key_length) {
|
||||
encoded_rsa_key_.assign(key, key + key_length);
|
||||
ASSERT_NO_FATAL_FAILURE(CreateWrappedDRMKey());
|
||||
Session s;
|
||||
ASSERT_NO_FATAL_FAILURE(s.open());
|
||||
ASSERT_NO_FATAL_FAILURE(s.SetRsaPublicKeyFromPrivateKeyInfo(
|
||||
encoded_rsa_key_.data(), encoded_rsa_key_.size()));
|
||||
ASSERT_NO_FATAL_FAILURE(s.LoadWrappedRsaDrmKey(wrapped_drm_key_));
|
||||
|
||||
LicenseRoundTrip license_messages(&s);
|
||||
ASSERT_NO_FATAL_FAILURE(license_messages.SignAndVerifyRequest());
|
||||
ASSERT_NO_FATAL_FAILURE(license_messages.CreateDefaultResponse());
|
||||
ASSERT_NO_FATAL_FAILURE(license_messages.EncryptAndSignResponse());
|
||||
ASSERT_EQ(OEMCrypto_SUCCESS, license_messages.LoadResponse());
|
||||
ASSERT_NO_FATAL_FAILURE(s.TestDecryptCTR());
|
||||
}
|
||||
};
|
||||
|
||||
// Test a 3072 bit RSA key certificate.
|
||||
TEST_F(OEMCryptoLoadsCertVariousKeys, TestLargeRSAKey3072) {
|
||||
TestKey(kTestRSAPKCS8PrivateKeyInfo3_3072,
|
||||
sizeof(kTestRSAPKCS8PrivateKeyInfo3_3072));
|
||||
}
|
||||
|
||||
// Test an RSA key certificate which has a private key generated using the
|
||||
// Carmichael totient.
|
||||
TEST_F(OEMCryptoLoadsCertVariousKeys, TestCarmichaelRSAKey) {
|
||||
TestKey(kTestKeyRSACarmichael_2048, sizeof(kTestKeyRSACarmichael_2048));
|
||||
}
|
||||
|
||||
TEST_F(OEMCryptoLoadsCertVariousKeys, TestCarmichaelNonZeroNormalDer) {
|
||||
TestKey(kCarmichaelNonZeroNormalDer, kCarmichaelNonZeroNormalDerLen);
|
||||
}
|
||||
|
||||
TEST_F(OEMCryptoLoadsCertVariousKeys, TestCarmichaelNonZeroShortDer) {
|
||||
TestKey(kCarmichaelNonZeroShortDer, kCarmichaelNonZeroShortDerLen);
|
||||
}
|
||||
|
||||
TEST_F(OEMCryptoLoadsCertVariousKeys, TestCarmichaelZeroNormalDer) {
|
||||
TestKey(kCarmichaelZeroNormalDer, kCarmichaelZeroNormalDerLen);
|
||||
}
|
||||
|
||||
TEST_F(OEMCryptoLoadsCertVariousKeys, TestCarmichaelZeroShortDer) {
|
||||
TestKey(kCarmichaelZeroShortDer, kCarmichaelZeroShortDerLen);
|
||||
}
|
||||
|
||||
TEST_F(OEMCryptoLoadsCertVariousKeys, TestDualNonZeroNormalDer) {
|
||||
TestKey(kDualNonZeroNormalDer, kDualNonZeroNormalDerLen);
|
||||
}
|
||||
|
||||
TEST_F(OEMCryptoLoadsCertVariousKeys, TestDualNonZeroShortDer) {
|
||||
TestKey(kDualNonZeroShortDer, kDualNonZeroShortDerLen);
|
||||
}
|
||||
|
||||
TEST_F(OEMCryptoLoadsCertVariousKeys, TestDualZeroNormalDer) {
|
||||
TestKey(kDualZeroNormalDer, kDualZeroNormalDerLen);
|
||||
}
|
||||
|
||||
TEST_F(OEMCryptoLoadsCertVariousKeys, TestDualZeroShortDer) {
|
||||
TestKey(kDualZeroShortDer, kDualZeroShortDerLen);
|
||||
}
|
||||
|
||||
TEST_F(OEMCryptoLoadsCertVariousKeys, TestEulerNonZeroNormalDer) {
|
||||
TestKey(kEulerNonZeroNormalDer, kEulerNonZeroNormalDerLen);
|
||||
}
|
||||
|
||||
TEST_F(OEMCryptoLoadsCertVariousKeys, TestEulerZeroNormalDer) {
|
||||
TestKey(kEulerZeroNormalDer, kEulerZeroNormalDerLen);
|
||||
}
|
||||
|
||||
// This tests that two sessions can use different RSA keys simultaneously.
|
||||
TEST_F(OEMCryptoLoadsCertificate, TestMultipleRSAKeys) {
|
||||
ASSERT_NO_FATAL_FAILURE(CreateWrappedDRMKey());
|
||||
Session s1; // Session s1 loads the default rsa key, but doesn't use it
|
||||
// until after s2 uses its key.
|
||||
ASSERT_NO_FATAL_FAILURE(s1.open());
|
||||
ASSERT_NO_FATAL_FAILURE(s1.SetRsaPublicKeyFromPrivateKeyInfo(
|
||||
encoded_rsa_key_.data(), encoded_rsa_key_.size()));
|
||||
ASSERT_NO_FATAL_FAILURE(s1.LoadWrappedRsaDrmKey(wrapped_drm_key_));
|
||||
|
||||
Session s2; // Session s2 uses a different rsa key.
|
||||
encoded_rsa_key_.assign(kTestRSAPKCS8PrivateKeyInfo4_2048,
|
||||
kTestRSAPKCS8PrivateKeyInfo4_2048 +
|
||||
sizeof(kTestRSAPKCS8PrivateKeyInfo4_2048));
|
||||
ASSERT_NO_FATAL_FAILURE(CreateWrappedDRMKey());
|
||||
ASSERT_NO_FATAL_FAILURE(s2.open());
|
||||
ASSERT_NO_FATAL_FAILURE(s2.SetRsaPublicKeyFromPrivateKeyInfo(
|
||||
encoded_rsa_key_.data(), encoded_rsa_key_.size()));
|
||||
ASSERT_NO_FATAL_FAILURE(s2.LoadWrappedRsaDrmKey(wrapped_drm_key_));
|
||||
LicenseRoundTrip license_messages2(&s2);
|
||||
ASSERT_NO_FATAL_FAILURE(license_messages2.SignAndVerifyRequest());
|
||||
ASSERT_NO_FATAL_FAILURE(license_messages2.CreateDefaultResponse());
|
||||
ASSERT_NO_FATAL_FAILURE(license_messages2.EncryptAndSignResponse());
|
||||
ASSERT_EQ(OEMCrypto_SUCCESS, license_messages2.LoadResponse());
|
||||
ASSERT_NO_FATAL_FAILURE(s2.TestDecryptCTR());
|
||||
s2.close();
|
||||
|
||||
// After s2 has loaded its rsa key, we continue using s1's key.
|
||||
LicenseRoundTrip license_messages1(&s1);
|
||||
ASSERT_NO_FATAL_FAILURE(license_messages1.SignAndVerifyRequest());
|
||||
ASSERT_NO_FATAL_FAILURE(license_messages1.CreateDefaultResponse());
|
||||
ASSERT_NO_FATAL_FAILURE(license_messages1.EncryptAndSignResponse());
|
||||
ASSERT_EQ(OEMCrypto_SUCCESS, license_messages1.LoadResponse());
|
||||
ASSERT_NO_FATAL_FAILURE(s1.TestDecryptCTR());
|
||||
}
|
||||
|
||||
// This tests the maximum number of DRM private keys that OEMCrypto can load
|
||||
TEST_F(OEMCryptoLoadsCertificate, TestMaxDRMKeys) {
|
||||
const size_t max_total_keys = GetResourceValue(kMaxTotalDRMPrivateKeys);
|
||||
std::vector<std::unique_ptr<Session>> sessions;
|
||||
std::vector<std::unique_ptr<LicenseRoundTrip>> licenses;
|
||||
|
||||
// It should be able to load up to kMaxTotalDRMPrivateKeys keys
|
||||
for (size_t i = 0; i < max_total_keys; i++) {
|
||||
sessions.push_back(std::unique_ptr<Session>(new Session()));
|
||||
licenses.push_back(std::unique_ptr<LicenseRoundTrip>(
|
||||
new LicenseRoundTrip(sessions[i].get())));
|
||||
const size_t key_index = i % kTestRSAPKCS8PrivateKeys_2048.size();
|
||||
encoded_rsa_key_.assign(kTestRSAPKCS8PrivateKeys_2048[key_index].begin(),
|
||||
kTestRSAPKCS8PrivateKeys_2048[key_index].end());
|
||||
ASSERT_NO_FATAL_FAILURE(CreateWrappedDRMKey());
|
||||
ASSERT_NO_FATAL_FAILURE(sessions[i]->open());
|
||||
ASSERT_NO_FATAL_FAILURE(InstallTestDrmKey(sessions[i].get()));
|
||||
}
|
||||
|
||||
// Attempts to load one more key than the kMaxTotalDRMPrivateKeys
|
||||
if (global_features.provisioning_method == OEMCrypto_BootCertificateChain) {
|
||||
Session s;
|
||||
const size_t buffer_size = 5000; // Make sure it is large enough.
|
||||
std::vector<uint8_t> public_key(buffer_size);
|
||||
size_t public_key_size = buffer_size;
|
||||
std::vector<uint8_t> public_key_signature(buffer_size);
|
||||
size_t public_key_signature_size = buffer_size;
|
||||
std::vector<uint8_t> wrapped_private_key(buffer_size);
|
||||
size_t wrapped_private_key_size = buffer_size;
|
||||
OEMCrypto_PrivateKeyType key_type;
|
||||
OEMCryptoResult result = OEMCrypto_GenerateCertificateKeyPair(
|
||||
s.session_id(), public_key.data(), &public_key_size,
|
||||
public_key_signature.data(), &public_key_signature_size,
|
||||
wrapped_private_key.data(), &wrapped_private_key_size, &key_type);
|
||||
// Key creation is allowed to fail due to resource restriction
|
||||
if (result != OEMCrypto_SUCCESS) {
|
||||
ASSERT_TRUE(result == OEMCrypto_ERROR_INSUFFICIENT_RESOURCES ||
|
||||
result == OEMCrypto_ERROR_TOO_MANY_KEYS);
|
||||
}
|
||||
} else {
|
||||
Session s;
|
||||
encoded_rsa_key_.assign(kTestRSAPKCS8PrivateKeyInfo2_2048,
|
||||
kTestRSAPKCS8PrivateKeyInfo2_2048 +
|
||||
sizeof(kTestRSAPKCS8PrivateKeyInfo2_2048));
|
||||
Session ps;
|
||||
ProvisioningRoundTrip provisioning_messages(&ps, encoded_rsa_key_);
|
||||
provisioning_messages.PrepareSession(keybox_);
|
||||
ASSERT_NO_FATAL_FAILURE(provisioning_messages.SignAndVerifyRequest());
|
||||
ASSERT_NO_FATAL_FAILURE(provisioning_messages.CreateDefaultResponse());
|
||||
ASSERT_NO_FATAL_FAILURE(provisioning_messages.EncryptAndSignResponse());
|
||||
OEMCryptoResult result = provisioning_messages.LoadResponse();
|
||||
// Key loading is allowed to fail due to resource restriction
|
||||
if (result != OEMCrypto_SUCCESS) {
|
||||
ASSERT_TRUE(result == OEMCrypto_ERROR_INSUFFICIENT_RESOURCES ||
|
||||
result == OEMCrypto_ERROR_TOO_MANY_KEYS);
|
||||
}
|
||||
}
|
||||
// Verifies that the DRM keys which are already loaded should still function
|
||||
for (size_t i = 0; i < licenses.size(); i++) {
|
||||
ASSERT_NO_FATAL_FAILURE(licenses[i]->SignAndVerifyRequest());
|
||||
ASSERT_NO_FATAL_FAILURE(licenses[i]->CreateDefaultResponse());
|
||||
ASSERT_NO_FATAL_FAILURE(licenses[i]->EncryptAndSignResponse());
|
||||
ASSERT_EQ(OEMCrypto_SUCCESS, licenses[i]->LoadResponse());
|
||||
ASSERT_NO_FATAL_FAILURE(sessions[i]->TestDecryptCTR());
|
||||
}
|
||||
}
|
||||
|
||||
// Devices that load certificates, should at least support RSA 2048 keys.
|
||||
TEST_F(OEMCryptoLoadsCertificate, SupportsCertificatesAPI13) {
|
||||
ASSERT_NE(0u,
|
||||
OEMCrypto_Supports_RSA_2048bit & OEMCrypto_SupportedCertificates())
|
||||
<< "Supported certificates is only " << OEMCrypto_SupportedCertificates();
|
||||
}
|
||||
|
||||
/// @}
|
||||
} // namespace wvoec
|
||||
@@ -10,6 +10,7 @@
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "OEMCryptoCENC.h"
|
||||
#include "oec_extra_test_keys.h"
|
||||
#include "oemcrypto_basic_test.h"
|
||||
#include "oemcrypto_license_test.h"
|
||||
#include "oemcrypto_resource_test.h"
|
||||
|
||||
@@ -1432,179 +1432,6 @@ INSTANTIATE_TEST_SUITE_P(TestHDCP, OEMCryptoSessionTestLoadCasKeysWithHDCP,
|
||||
Range(1, 6));
|
||||
/// @}
|
||||
|
||||
/// @addtogroup renewal
|
||||
/// @{
|
||||
|
||||
//
|
||||
// Load, Refresh Keys Test
|
||||
//
|
||||
|
||||
// This class is for the refresh tests that should only be run on licenses with
|
||||
// a core message.
|
||||
class OEMCryptoRefreshTestAPI16 : public OEMCryptoRefreshTest {};
|
||||
|
||||
// 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));
|
||||
|
||||
/// @}
|
||||
|
||||
/// @addtogroup security
|
||||
/// @{
|
||||
|
||||
@@ -1770,201 +1597,6 @@ TEST_F(
|
||||
|
||||
/// @}
|
||||
|
||||
/// @addtogroup provision
|
||||
/// @{
|
||||
|
||||
// Test that a wrapped RSA key can be loaded.
|
||||
TEST_F(OEMCryptoLoadsCertificate, LoadWrappedRSAKey) {
|
||||
ASSERT_NO_FATAL_FAILURE(CreateWrappedDRMKey());
|
||||
Session s;
|
||||
ASSERT_NO_FATAL_FAILURE(s.open());
|
||||
ASSERT_NO_FATAL_FAILURE(s.LoadWrappedRsaDrmKey(wrapped_drm_key_));
|
||||
}
|
||||
|
||||
class OEMCryptoLoadsCertVariousKeys : public OEMCryptoLoadsCertificate {
|
||||
public:
|
||||
void TestKey(const uint8_t* key, size_t key_length) {
|
||||
encoded_rsa_key_.assign(key, key + key_length);
|
||||
ASSERT_NO_FATAL_FAILURE(CreateWrappedDRMKey());
|
||||
Session s;
|
||||
ASSERT_NO_FATAL_FAILURE(s.open());
|
||||
ASSERT_NO_FATAL_FAILURE(s.SetRsaPublicKeyFromPrivateKeyInfo(
|
||||
encoded_rsa_key_.data(), encoded_rsa_key_.size()));
|
||||
ASSERT_NO_FATAL_FAILURE(s.LoadWrappedRsaDrmKey(wrapped_drm_key_));
|
||||
|
||||
LicenseRoundTrip license_messages(&s);
|
||||
ASSERT_NO_FATAL_FAILURE(license_messages.SignAndVerifyRequest());
|
||||
ASSERT_NO_FATAL_FAILURE(license_messages.CreateDefaultResponse());
|
||||
ASSERT_NO_FATAL_FAILURE(license_messages.EncryptAndSignResponse());
|
||||
ASSERT_EQ(OEMCrypto_SUCCESS, license_messages.LoadResponse());
|
||||
ASSERT_NO_FATAL_FAILURE(s.TestDecryptCTR());
|
||||
}
|
||||
};
|
||||
|
||||
// Test a 3072 bit RSA key certificate.
|
||||
TEST_F(OEMCryptoLoadsCertVariousKeys, TestLargeRSAKey3072) {
|
||||
TestKey(kTestRSAPKCS8PrivateKeyInfo3_3072,
|
||||
sizeof(kTestRSAPKCS8PrivateKeyInfo3_3072));
|
||||
}
|
||||
|
||||
// Test an RSA key certificate which has a private key generated using the
|
||||
// Carmichael totient.
|
||||
TEST_F(OEMCryptoLoadsCertVariousKeys, TestCarmichaelRSAKey) {
|
||||
TestKey(kTestKeyRSACarmichael_2048, sizeof(kTestKeyRSACarmichael_2048));
|
||||
}
|
||||
|
||||
TEST_F(OEMCryptoLoadsCertVariousKeys, TestCarmichaelNonZeroNormalDer) {
|
||||
TestKey(kCarmichaelNonZeroNormalDer, kCarmichaelNonZeroNormalDerLen);
|
||||
}
|
||||
|
||||
TEST_F(OEMCryptoLoadsCertVariousKeys, TestCarmichaelNonZeroShortDer) {
|
||||
TestKey(kCarmichaelNonZeroShortDer, kCarmichaelNonZeroShortDerLen);
|
||||
}
|
||||
|
||||
TEST_F(OEMCryptoLoadsCertVariousKeys, TestCarmichaelZeroNormalDer) {
|
||||
TestKey(kCarmichaelZeroNormalDer, kCarmichaelZeroNormalDerLen);
|
||||
}
|
||||
|
||||
TEST_F(OEMCryptoLoadsCertVariousKeys, TestCarmichaelZeroShortDer) {
|
||||
TestKey(kCarmichaelZeroShortDer, kCarmichaelZeroShortDerLen);
|
||||
}
|
||||
|
||||
TEST_F(OEMCryptoLoadsCertVariousKeys, TestDualNonZeroNormalDer) {
|
||||
TestKey(kDualNonZeroNormalDer, kDualNonZeroNormalDerLen);
|
||||
}
|
||||
|
||||
TEST_F(OEMCryptoLoadsCertVariousKeys, TestDualNonZeroShortDer) {
|
||||
TestKey(kDualNonZeroShortDer, kDualNonZeroShortDerLen);
|
||||
}
|
||||
|
||||
TEST_F(OEMCryptoLoadsCertVariousKeys, TestDualZeroNormalDer) {
|
||||
TestKey(kDualZeroNormalDer, kDualZeroNormalDerLen);
|
||||
}
|
||||
|
||||
TEST_F(OEMCryptoLoadsCertVariousKeys, TestDualZeroShortDer) {
|
||||
TestKey(kDualZeroShortDer, kDualZeroShortDerLen);
|
||||
}
|
||||
|
||||
TEST_F(OEMCryptoLoadsCertVariousKeys, TestEulerNonZeroNormalDer) {
|
||||
TestKey(kEulerNonZeroNormalDer, kEulerNonZeroNormalDerLen);
|
||||
}
|
||||
|
||||
TEST_F(OEMCryptoLoadsCertVariousKeys, TestEulerZeroNormalDer) {
|
||||
TestKey(kEulerZeroNormalDer, kEulerZeroNormalDerLen);
|
||||
}
|
||||
|
||||
// This tests that two sessions can use different RSA keys simultaneously.
|
||||
TEST_F(OEMCryptoLoadsCertificate, TestMultipleRSAKeys) {
|
||||
ASSERT_NO_FATAL_FAILURE(CreateWrappedDRMKey());
|
||||
Session s1; // Session s1 loads the default rsa key, but doesn't use it
|
||||
// until after s2 uses its key.
|
||||
ASSERT_NO_FATAL_FAILURE(s1.open());
|
||||
ASSERT_NO_FATAL_FAILURE(s1.SetRsaPublicKeyFromPrivateKeyInfo(
|
||||
encoded_rsa_key_.data(), encoded_rsa_key_.size()));
|
||||
ASSERT_NO_FATAL_FAILURE(s1.LoadWrappedRsaDrmKey(wrapped_drm_key_));
|
||||
|
||||
Session s2; // Session s2 uses a different rsa key.
|
||||
encoded_rsa_key_.assign(kTestRSAPKCS8PrivateKeyInfo4_2048,
|
||||
kTestRSAPKCS8PrivateKeyInfo4_2048 +
|
||||
sizeof(kTestRSAPKCS8PrivateKeyInfo4_2048));
|
||||
ASSERT_NO_FATAL_FAILURE(CreateWrappedDRMKey());
|
||||
ASSERT_NO_FATAL_FAILURE(s2.open());
|
||||
ASSERT_NO_FATAL_FAILURE(s2.SetRsaPublicKeyFromPrivateKeyInfo(
|
||||
encoded_rsa_key_.data(), encoded_rsa_key_.size()));
|
||||
ASSERT_NO_FATAL_FAILURE(s2.LoadWrappedRsaDrmKey(wrapped_drm_key_));
|
||||
LicenseRoundTrip license_messages2(&s2);
|
||||
ASSERT_NO_FATAL_FAILURE(license_messages2.SignAndVerifyRequest());
|
||||
ASSERT_NO_FATAL_FAILURE(license_messages2.CreateDefaultResponse());
|
||||
ASSERT_NO_FATAL_FAILURE(license_messages2.EncryptAndSignResponse());
|
||||
ASSERT_EQ(OEMCrypto_SUCCESS, license_messages2.LoadResponse());
|
||||
ASSERT_NO_FATAL_FAILURE(s2.TestDecryptCTR());
|
||||
s2.close();
|
||||
|
||||
// After s2 has loaded its rsa key, we continue using s1's key.
|
||||
LicenseRoundTrip license_messages1(&s1);
|
||||
ASSERT_NO_FATAL_FAILURE(license_messages1.SignAndVerifyRequest());
|
||||
ASSERT_NO_FATAL_FAILURE(license_messages1.CreateDefaultResponse());
|
||||
ASSERT_NO_FATAL_FAILURE(license_messages1.EncryptAndSignResponse());
|
||||
ASSERT_EQ(OEMCrypto_SUCCESS, license_messages1.LoadResponse());
|
||||
ASSERT_NO_FATAL_FAILURE(s1.TestDecryptCTR());
|
||||
}
|
||||
|
||||
// This tests the maximum number of DRM private keys that OEMCrypto can load
|
||||
TEST_F(OEMCryptoLoadsCertificate, TestMaxDRMKeys) {
|
||||
const size_t max_total_keys = GetResourceValue(kMaxTotalDRMPrivateKeys);
|
||||
std::vector<std::unique_ptr<Session>> sessions;
|
||||
std::vector<std::unique_ptr<LicenseRoundTrip>> licenses;
|
||||
|
||||
// It should be able to load up to kMaxTotalDRMPrivateKeys keys
|
||||
for (size_t i = 0; i < max_total_keys; i++) {
|
||||
sessions.push_back(std::unique_ptr<Session>(new Session()));
|
||||
licenses.push_back(std::unique_ptr<LicenseRoundTrip>(
|
||||
new LicenseRoundTrip(sessions[i].get())));
|
||||
const size_t key_index = i % kTestRSAPKCS8PrivateKeys_2048.size();
|
||||
encoded_rsa_key_.assign(kTestRSAPKCS8PrivateKeys_2048[key_index].begin(),
|
||||
kTestRSAPKCS8PrivateKeys_2048[key_index].end());
|
||||
ASSERT_NO_FATAL_FAILURE(CreateWrappedDRMKey());
|
||||
ASSERT_NO_FATAL_FAILURE(sessions[i]->open());
|
||||
ASSERT_NO_FATAL_FAILURE(InstallTestDrmKey(sessions[i].get()));
|
||||
}
|
||||
|
||||
// Attempts to load one more key than the kMaxTotalDRMPrivateKeys
|
||||
if (global_features.provisioning_method == OEMCrypto_BootCertificateChain) {
|
||||
Session s;
|
||||
const size_t buffer_size = 5000; // Make sure it is large enough.
|
||||
std::vector<uint8_t> public_key(buffer_size);
|
||||
size_t public_key_size = buffer_size;
|
||||
std::vector<uint8_t> public_key_signature(buffer_size);
|
||||
size_t public_key_signature_size = buffer_size;
|
||||
std::vector<uint8_t> wrapped_private_key(buffer_size);
|
||||
size_t wrapped_private_key_size = buffer_size;
|
||||
OEMCrypto_PrivateKeyType key_type;
|
||||
OEMCryptoResult result = OEMCrypto_GenerateCertificateKeyPair(
|
||||
s.session_id(), public_key.data(), &public_key_size,
|
||||
public_key_signature.data(), &public_key_signature_size,
|
||||
wrapped_private_key.data(), &wrapped_private_key_size, &key_type);
|
||||
// Key creation is allowed to fail due to resource restriction
|
||||
if (result != OEMCrypto_SUCCESS) {
|
||||
ASSERT_TRUE(result == OEMCrypto_ERROR_INSUFFICIENT_RESOURCES ||
|
||||
result == OEMCrypto_ERROR_TOO_MANY_KEYS);
|
||||
}
|
||||
} else {
|
||||
Session s;
|
||||
encoded_rsa_key_.assign(kTestRSAPKCS8PrivateKeyInfo2_2048,
|
||||
kTestRSAPKCS8PrivateKeyInfo2_2048 +
|
||||
sizeof(kTestRSAPKCS8PrivateKeyInfo2_2048));
|
||||
Session ps;
|
||||
ProvisioningRoundTrip provisioning_messages(&ps, encoded_rsa_key_);
|
||||
provisioning_messages.PrepareSession(keybox_);
|
||||
ASSERT_NO_FATAL_FAILURE(provisioning_messages.SignAndVerifyRequest());
|
||||
ASSERT_NO_FATAL_FAILURE(provisioning_messages.CreateDefaultResponse());
|
||||
ASSERT_NO_FATAL_FAILURE(provisioning_messages.EncryptAndSignResponse());
|
||||
OEMCryptoResult result = provisioning_messages.LoadResponse();
|
||||
// Key loading is allowed to fail due to resource restriction
|
||||
if (result != OEMCrypto_SUCCESS) {
|
||||
ASSERT_TRUE(result == OEMCrypto_ERROR_INSUFFICIENT_RESOURCES ||
|
||||
result == OEMCrypto_ERROR_TOO_MANY_KEYS);
|
||||
}
|
||||
}
|
||||
// Verifies that the DRM keys which are already loaded should still function
|
||||
for (size_t i = 0; i < licenses.size(); i++) {
|
||||
ASSERT_NO_FATAL_FAILURE(licenses[i]->SignAndVerifyRequest());
|
||||
ASSERT_NO_FATAL_FAILURE(licenses[i]->CreateDefaultResponse());
|
||||
ASSERT_NO_FATAL_FAILURE(licenses[i]->EncryptAndSignResponse());
|
||||
ASSERT_EQ(OEMCrypto_SUCCESS, licenses[i]->LoadResponse());
|
||||
ASSERT_NO_FATAL_FAILURE(sessions[i]->TestDecryptCTR());
|
||||
}
|
||||
}
|
||||
|
||||
// Devices that load certificates, should at least support RSA 2048 keys.
|
||||
TEST_F(OEMCryptoLoadsCertificate, SupportsCertificatesAPI13) {
|
||||
ASSERT_NE(0u,
|
||||
OEMCrypto_Supports_RSA_2048bit & OEMCrypto_SupportedCertificates())
|
||||
<< "Supported certificates is only " << OEMCrypto_SupportedCertificates();
|
||||
}
|
||||
|
||||
/// @}
|
||||
|
||||
/// @addtogroup security
|
||||
/// @{
|
||||
|
||||
|
||||
@@ -19,48 +19,6 @@
|
||||
|
||||
namespace wvoec {
|
||||
|
||||
class OEMCryptoRefreshTest : public OEMCryptoLicenseTest {
|
||||
protected:
|
||||
void SetUp() override {
|
||||
OEMCryptoLicenseTest::SetUp();
|
||||
// These values allow us to run a few simple duration tests or just start
|
||||
// playback right away. All times are in seconds since the license was
|
||||
// signed.
|
||||
// Soft expiry false means timers are strictly enforce.
|
||||
timer_limits_.soft_enforce_rental_duration = true;
|
||||
timer_limits_.soft_enforce_playback_duration = false;
|
||||
// Playback may begin immediately.
|
||||
timer_limits_.earliest_playback_start_seconds = 0;
|
||||
// First playback may be within the first two seconds.
|
||||
timer_limits_.rental_duration_seconds = kDuration;
|
||||
// Once started, playback may last two seconds without a renewal.
|
||||
timer_limits_.initial_renewal_duration_seconds = kDuration;
|
||||
// Total playback is not limited.
|
||||
timer_limits_.total_playback_duration_seconds = 0;
|
||||
}
|
||||
|
||||
void LoadLicense() {
|
||||
license_messages_.core_response().timer_limits = timer_limits_;
|
||||
ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest());
|
||||
ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse());
|
||||
ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse());
|
||||
ASSERT_EQ(OEMCrypto_SUCCESS, license_messages_.LoadResponse());
|
||||
}
|
||||
|
||||
void MakeRenewalRequest(RenewalRoundTrip* renewal_messages) {
|
||||
ASSERT_NO_FATAL_FAILURE(renewal_messages->SignAndVerifyRequest());
|
||||
ASSERT_NO_FATAL_FAILURE(renewal_messages->CreateDefaultResponse());
|
||||
}
|
||||
|
||||
void LoadRenewal(RenewalRoundTrip* renewal_messages,
|
||||
OEMCryptoResult expected_result) {
|
||||
ASSERT_NO_FATAL_FAILURE(renewal_messages->EncryptAndSignResponse());
|
||||
ASSERT_EQ(expected_result, renewal_messages->LoadResponse());
|
||||
}
|
||||
|
||||
ODK_TimerLimits timer_limits_;
|
||||
};
|
||||
|
||||
// This class is for testing the generic crypto functionality.
|
||||
class OEMCryptoGenericCryptoTest : public OEMCryptoRefreshTest {
|
||||
protected:
|
||||
|
||||
Reference in New Issue
Block a user