Merge "Integration tests to verify clear lead content plays successfully" into main

This commit is contained in:
Kyle Zhang
2024-03-29 04:39:46 +00:00
committed by Android (Google) Code Review
4 changed files with 83 additions and 13 deletions

View File

@@ -3,6 +3,7 @@
// Agreement. // Agreement.
#include "certificate_provisioning.h" #include "certificate_provisioning.h"
#include "license_holder.h"
#include "log.h" #include "log.h"
#include "provisioning_holder.h" #include "provisioning_holder.h"
#include "test_base.h" #include "test_base.h"
@@ -128,9 +129,11 @@ class CoreIntegrationTest : public WvCdmTestBaseWithEngine {
} }
}; };
// Verify that SPOIDs and DRM certificate serial number are stable between /**
// factory resets/provisioning attempts for the same app and different between * Verify that SPOIDs and DRM certificate serial number are stable between
// different apps. Test using two different apps and origins. * factory resets/provisioning attempts for the same app and different between
* different apps. Test using two different apps and origins.
*/
TEST_F(CoreIntegrationTest, ProvisioningStableSpoidTest) { TEST_F(CoreIntegrationTest, ProvisioningStableSpoidTest) {
std::string level; std::string level;
ASSERT_EQ( ASSERT_EQ(
@@ -233,4 +236,44 @@ TEST_F(CoreIntegrationTest, ProvisioningStableSpoidTest) {
ASSERT_NE(drm_cert_serial_number_app_1_origin_1[0], ASSERT_NE(drm_cert_serial_number_app_1_origin_1[0],
drm_cert_serial_number_app_1_origin_2[0]); drm_cert_serial_number_app_1_origin_2[0]);
} }
/**
* A clear lead without a license loaded.
*/
TEST_F(CoreIntegrationTest, ClearLead) {
LicenseHolder holder("CDM_Streaming", &cdm_engine_, config_);
const KeyId key_id = "";
ASSERT_NO_FATAL_FAILURE(holder.OpenSession());
ASSERT_NO_FATAL_FAILURE(holder.FetchLicense());
EXPECT_EQ(NO_ERROR, holder.DecryptClearLead(key_id));
ASSERT_NO_FATAL_FAILURE(holder.CloseSession());
}
/**
* Playback clear lead with a license loaded. Playback should succeed.
*/
TEST_F(CoreIntegrationTest, ClearLeadAfterLicenseLoad) {
LicenseHolder holder("CDM_Streaming", &cdm_engine_, config_);
const KeyId key_id = "";
ASSERT_NO_FATAL_FAILURE(holder.OpenSession());
ASSERT_NO_FATAL_FAILURE(holder.FetchLicense());
ASSERT_NO_FATAL_FAILURE(holder.LoadLicense());
EXPECT_EQ(NO_ERROR, holder.DecryptClearLead(key_id));
ASSERT_NO_FATAL_FAILURE(holder.CloseSession());
}
/**
* Decrypt without a license loaded. Decrypt should fail with a NEED_KEY error.
*/
TEST_F(CoreIntegrationTest, NeedKeyBeforeLicenseLoad) {
LicenseHolder holder("CDM_Streaming", &cdm_engine_, config_);
const KeyId key_id = "0000000000000000";
ASSERT_NO_FATAL_FAILURE(holder.OpenSession());
ASSERT_NO_FATAL_FAILURE(holder.FetchLicense());
EXPECT_EQ(NEED_KEY, holder.Decrypt(key_id));
ASSERT_NO_FATAL_FAILURE(holder.CloseSession());
}
} // namespace wvcdm } // namespace wvcdm

View File

@@ -176,6 +176,20 @@ CdmResponseType LicenseHolder::Decrypt(const std::string& key_id) {
return cdm_engine_->DecryptV16(session_id_, params); return cdm_engine_->DecryptV16(session_id_, params);
} }
CdmResponseType LicenseHolder::DecryptClearLead(const std::string& key_id) {
constexpr size_t buffer_size = 500;
const std::vector<uint8_t> input(buffer_size, 0);
std::vector<uint8_t> output(buffer_size, 0);
const std::vector<uint8_t> iv(KEY_IV_SIZE, 0);
CdmDecryptionParametersV16 params(key_id);
params.is_secure = false;
CdmDecryptionSample sample(input.data(), output.data(), 0, input.size(), iv);
CdmDecryptionSubsample subsample(input.size(), 0);
sample.subsamples.push_back(subsample);
params.samples.push_back(sample);
return cdm_engine_->DecryptV16(session_id_, params);
}
void LicenseHolder::DecryptSecure(const KeyId& key_id) { void LicenseHolder::DecryptSecure(const KeyId& key_id) {
ASSERT_TRUE(wvoec::global_features.test_secure_buffers); ASSERT_TRUE(wvoec::global_features.test_secure_buffers);
constexpr size_t buffer_size = 500; constexpr size_t buffer_size = 500;

View File

@@ -86,6 +86,9 @@ class LicenseHolder {
// Try to decrypt some random data. This does not verify that the data is // Try to decrypt some random data. This does not verify that the data is
// decrypted correctly. Returns the result of the decrypt operation. // decrypted correctly. Returns the result of the decrypt operation.
CdmResponseType Decrypt(const std::string& key_id); CdmResponseType Decrypt(const std::string& key_id);
// Try to copy the clear lead to a secure buffer. Returns the result of the
// copy buffer operation.
CdmResponseType DecryptClearLead(const std::string& key_id);
// Try to decrypt some random data to a secure buffer. If the test harness // Try to decrypt some random data to a secure buffer. If the test harness
// does not allow creating a secure buffer, then this function fails // does not allow creating a secure buffer, then this function fails
// immediately. Otherwise, a secure buffer is created and used for a // immediately. Otherwise, a secure buffer is created and used for a

View File

@@ -35,7 +35,9 @@ class CorePIGTest : public WvCdmTestBaseWithEngine {
} }
}; };
// An offline license with nonce not required. /**
* An offline license with nonce not required.
*/
TEST_F(CorePIGTest, OfflineNoNonce) { TEST_F(CorePIGTest, OfflineNoNonce) {
LicenseHolder holder("CDM_OfflineNoNonce", &cdm_engine_, config_); LicenseHolder holder("CDM_OfflineNoNonce", &cdm_engine_, config_);
holder.set_can_persist(true); holder.set_can_persist(true);
@@ -54,7 +56,9 @@ TEST_F(CorePIGTest, OfflineNoNonce) {
ASSERT_NO_FATAL_FAILURE(holder.CloseSession()); ASSERT_NO_FATAL_FAILURE(holder.CloseSession());
} }
// An offline license with nonce and provider session token. /**
* An offline license with nonce and provider session token.
*/
TEST_F(CorePIGTest, OfflineWithPST) { TEST_F(CorePIGTest, OfflineWithPST) {
LicenseHolder holder("CDM_OfflineWithPST", &cdm_engine_, config_); LicenseHolder holder("CDM_OfflineWithPST", &cdm_engine_, config_);
holder.set_can_persist(true); holder.set_can_persist(true);
@@ -128,10 +132,12 @@ TEST_F(CorePIGTest, OfflineMultipleLicensesWithDefrag) {
ASSERT_NO_FATAL_FAILURE(holder3.CloseSession()); ASSERT_NO_FATAL_FAILURE(holder3.CloseSession());
} }
// This test verifies that the system can download and install license with a /**
// key that requires secure buffers. It also verifies that we cannot decrypt to * This test verifies that the system can download and install license with a
// a non-secure buffer using this key, but that we can decrypt to a secure * key that requires secure buffers. It also verifies that we cannot decrypt to
// buffer, if the test harness supports secure buffers. * a non-secure buffer using this key, but that we can decrypt to a secure
* buffer, if the test harness supports secure buffers.
*/
TEST_F(CorePIGTest, OfflineHWSecureRequired) { TEST_F(CorePIGTest, OfflineHWSecureRequired) {
LicenseHolder holder("CDM_OfflineHWSecureRequired", &cdm_engine_, config_); LicenseHolder holder("CDM_OfflineHWSecureRequired", &cdm_engine_, config_);
holder.set_can_persist(true); holder.set_can_persist(true);
@@ -170,8 +176,10 @@ TEST_F(CorePIGTest, OfflineHWSecureRequired) {
ASSERT_NO_FATAL_FAILURE(holder.CloseSession()); ASSERT_NO_FATAL_FAILURE(holder.CloseSession());
} }
// Should be able to request license, perform playback, generate a license /**
// release, and receive the release response. * Should be able to request license, perform playback, generate a license
* release, and receive the release response.
*/
TEST_F(CorePIGTest, LicenseRelease1) { TEST_F(CorePIGTest, LicenseRelease1) {
if (!wvoec::global_features.usage_table) { if (!wvoec::global_features.usage_table) {
GTEST_SKIP() << "Test for usage table devices only."; GTEST_SKIP() << "Test for usage table devices only.";
@@ -194,8 +202,10 @@ TEST_F(CorePIGTest, LicenseRelease1) {
ASSERT_NO_FATAL_FAILURE(holder.CloseSession()); ASSERT_NO_FATAL_FAILURE(holder.CloseSession());
} }
// Should be able to request license, wait some time, generate a license /**
// release, and receive the release response. * Should be able to request license, wait some time, generate a license
* release, and receive the release response.
*/
TEST_F(CorePIGTest, LicenseRelease2) { TEST_F(CorePIGTest, LicenseRelease2) {
if (!wvoec::global_features.usage_table) { if (!wvoec::global_features.usage_table) {
GTEST_SKIP() << "Test for usage table devices only."; GTEST_SKIP() << "Test for usage table devices only.";