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
@@ -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
|
||||
Reference in New Issue
Block a user