|
|
|
|
@@ -2129,11 +2129,13 @@ class WvCdmRequestLicenseTest : public WvCdmTestBase {
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Unprovision() {
|
|
|
|
|
void Unprovision() { Unprovision(kDefaultCdmIdentifier); }
|
|
|
|
|
|
|
|
|
|
void Unprovision(const CdmIdentifier& identifier) {
|
|
|
|
|
EXPECT_EQ(wvcdm::NO_ERROR,
|
|
|
|
|
decryptor_->Unprovision(kSecurityLevelL1, kDefaultCdmIdentifier));
|
|
|
|
|
decryptor_->Unprovision(kSecurityLevelL1, identifier));
|
|
|
|
|
EXPECT_EQ(wvcdm::NO_ERROR,
|
|
|
|
|
decryptor_->Unprovision(kSecurityLevelL3, kDefaultCdmIdentifier));
|
|
|
|
|
decryptor_->Unprovision(kSecurityLevelL3, identifier));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool IsProvisioned(const CdmIdentifier& identifier,
|
|
|
|
|
@@ -2231,16 +2233,22 @@ class WvCdmRequestLicenseTest : public WvCdmTestBase {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CdmSecurityLevel GetDefaultSecurityLevel() {
|
|
|
|
|
std::string level = GetSecurityLevel(nullptr).c_str();
|
|
|
|
|
CdmSecurityLevel security_level = kSecurityLevelUninitialized;
|
|
|
|
|
if (level.compare(wvcdm::QUERY_VALUE_SECURITY_LEVEL_L1) == 0) {
|
|
|
|
|
security_level = kSecurityLevelL1;
|
|
|
|
|
} else if (level.compare(wvcdm::QUERY_VALUE_SECURITY_LEVEL_L3) == 0) {
|
|
|
|
|
security_level = kSecurityLevelL3;
|
|
|
|
|
} else {
|
|
|
|
|
EXPECT_TRUE(false) << "Default Security level is undefined: " << level;
|
|
|
|
|
std::string security_level;
|
|
|
|
|
const CdmResponseType status = decryptor_->QueryStatus(
|
|
|
|
|
kLevelDefault, wvcdm::QUERY_KEY_SECURITY_LEVEL, &security_level);
|
|
|
|
|
if (status != NO_ERROR) {
|
|
|
|
|
ADD_FAILURE() << "Failed to obtain default security level: "
|
|
|
|
|
<< status.ToString();
|
|
|
|
|
return kSecurityLevelUninitialized;
|
|
|
|
|
}
|
|
|
|
|
return security_level;
|
|
|
|
|
if (security_level == wvcdm::QUERY_VALUE_SECURITY_LEVEL_L1) {
|
|
|
|
|
return kSecurityLevelL1;
|
|
|
|
|
}
|
|
|
|
|
if (security_level == wvcdm::QUERY_VALUE_SECURITY_LEVEL_L3) {
|
|
|
|
|
return kSecurityLevelL3;
|
|
|
|
|
}
|
|
|
|
|
ADD_FAILURE() << "Undefined security level: " << security_level;
|
|
|
|
|
return kSecurityLevelUninitialized;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uint32_t QueryStatus(RequestedSecurityLevel security_level,
|
|
|
|
|
@@ -6552,9 +6560,12 @@ TEST_F(WvCdmRequestLicenseTest, DISABLED_DecryptPathTest) {
|
|
|
|
|
// not match the license's key set ID (possible for entry to have
|
|
|
|
|
// been overwritten).
|
|
|
|
|
TEST_F(WvCdmRequestLicenseTest, RemoveOfflineLicenseWithMissingUsageEntry) {
|
|
|
|
|
Unprovision();
|
|
|
|
|
Provision();
|
|
|
|
|
const CdmSecurityLevel security_level = GetDefaultSecurityLevel();
|
|
|
|
|
const RequestedSecurityLevel requested_security_level =
|
|
|
|
|
(security_level == kSecurityLevelL3) ? kLevel3 : kLevelDefault;
|
|
|
|
|
|
|
|
|
|
Unprovision(kExampleIdentifier);
|
|
|
|
|
Provision(kExampleIdentifier, requested_security_level);
|
|
|
|
|
|
|
|
|
|
FileSystem file_system;
|
|
|
|
|
DeviceFiles handle(&file_system);
|
|
|
|
|
@@ -6568,9 +6579,9 @@ TEST_F(WvCdmRequestLicenseTest, RemoveOfflineLicenseWithMissingUsageEntry) {
|
|
|
|
|
// This license will be used to test how the CDM handles request to
|
|
|
|
|
// remove it when its entry has been deleted.
|
|
|
|
|
|
|
|
|
|
decryptor_->OpenSession(config_.key_system(), nullptr, kDefaultCdmIdentifier,
|
|
|
|
|
decryptor_->OpenSession(config_.key_system(), nullptr, kExampleIdentifier,
|
|
|
|
|
nullptr, &session_id_);
|
|
|
|
|
GenerateKeyRequest(key_id, kLicenseTypeOffline);
|
|
|
|
|
GenerateKeyRequest(key_id, kLicenseTypeOffline, kExampleIdentifier);
|
|
|
|
|
VerifyKeyRequestResponse(config_.license_server(), client_auth);
|
|
|
|
|
// Save the key set ID for check below.
|
|
|
|
|
const std::string original_key_set_id(key_set_id_);
|
|
|
|
|
@@ -6584,9 +6595,9 @@ TEST_F(WvCdmRequestLicenseTest, RemoveOfflineLicenseWithMissingUsageEntry) {
|
|
|
|
|
EXPECT_EQ(DeviceFiles::kNoError, sub_result);
|
|
|
|
|
|
|
|
|
|
// Re-provision.
|
|
|
|
|
Unprovision();
|
|
|
|
|
Unprovision(kExampleIdentifier);
|
|
|
|
|
handle.DeleteAllFiles();
|
|
|
|
|
Provision();
|
|
|
|
|
Provision(kExampleIdentifier, requested_security_level);
|
|
|
|
|
|
|
|
|
|
// Part 1: Test when usage entry is out of range of the table.
|
|
|
|
|
|
|
|
|
|
@@ -6597,26 +6608,26 @@ TEST_F(WvCdmRequestLicenseTest, RemoveOfflineLicenseWithMissingUsageEntry) {
|
|
|
|
|
|
|
|
|
|
std::vector<CdmKeySetId> key_set_ids;
|
|
|
|
|
EXPECT_EQ(wvcdm::NO_ERROR,
|
|
|
|
|
decryptor_->ListStoredLicenses(
|
|
|
|
|
security_level, kDefaultCdmIdentifier, &key_set_ids));
|
|
|
|
|
decryptor_->ListStoredLicenses(security_level, kExampleIdentifier,
|
|
|
|
|
&key_set_ids));
|
|
|
|
|
// Note: It is possible that future changes to the CDM will cause this
|
|
|
|
|
// check to fail (such by filtering results from ListStoreLicenses).
|
|
|
|
|
EXPECT_THAT(key_set_ids, Contains(original_key_set_id));
|
|
|
|
|
|
|
|
|
|
EXPECT_EQ(wvcdm::NO_ERROR,
|
|
|
|
|
decryptor_->RemoveOfflineLicense(
|
|
|
|
|
original_key_set_id, security_level, kDefaultCdmIdentifier));
|
|
|
|
|
original_key_set_id, security_level, kExampleIdentifier));
|
|
|
|
|
|
|
|
|
|
// Verify license has been removed.
|
|
|
|
|
EXPECT_EQ(wvcdm::NO_ERROR,
|
|
|
|
|
decryptor_->ListStoredLicenses(
|
|
|
|
|
security_level, kDefaultCdmIdentifier, &key_set_ids));
|
|
|
|
|
decryptor_->ListStoredLicenses(security_level, kExampleIdentifier,
|
|
|
|
|
&key_set_ids));
|
|
|
|
|
EXPECT_THAT(key_set_ids, Not(Contains(original_key_set_id)));
|
|
|
|
|
|
|
|
|
|
// Re-provision.
|
|
|
|
|
Unprovision();
|
|
|
|
|
Unprovision(kExampleIdentifier);
|
|
|
|
|
handle.DeleteAllFiles();
|
|
|
|
|
Provision();
|
|
|
|
|
Provision(kExampleIdentifier, requested_security_level);
|
|
|
|
|
|
|
|
|
|
// Part 2: Test when the entry does not match the license's key set ID.
|
|
|
|
|
|
|
|
|
|
@@ -6624,26 +6635,183 @@ TEST_F(WvCdmRequestLicenseTest, RemoveOfflineLicenseWithMissingUsageEntry) {
|
|
|
|
|
EXPECT_EQ(DeviceFiles::kNoError, sub_result);
|
|
|
|
|
|
|
|
|
|
// Request another license so that the usage table is not empty.
|
|
|
|
|
decryptor_->OpenSession(config_.key_system(), nullptr, kDefaultCdmIdentifier,
|
|
|
|
|
decryptor_->OpenSession(config_.key_system(), nullptr, kExampleIdentifier,
|
|
|
|
|
nullptr, &session_id_);
|
|
|
|
|
GenerateKeyRequest(key_id, kLicenseTypeOffline);
|
|
|
|
|
GenerateKeyRequest(key_id, kLicenseTypeOffline, kExampleIdentifier);
|
|
|
|
|
VerifyKeyRequestResponse(config_.license_server(), client_auth);
|
|
|
|
|
decryptor_->CloseSession(session_id_);
|
|
|
|
|
|
|
|
|
|
// Get list of existing offline licenses.
|
|
|
|
|
EXPECT_EQ(wvcdm::NO_ERROR,
|
|
|
|
|
decryptor_->ListStoredLicenses(
|
|
|
|
|
security_level, kDefaultCdmIdentifier, &key_set_ids));
|
|
|
|
|
decryptor_->ListStoredLicenses(security_level, kExampleIdentifier,
|
|
|
|
|
&key_set_ids));
|
|
|
|
|
EXPECT_THAT(key_set_ids, Contains(original_key_set_id));
|
|
|
|
|
|
|
|
|
|
EXPECT_EQ(wvcdm::NO_ERROR,
|
|
|
|
|
decryptor_->RemoveOfflineLicense(
|
|
|
|
|
original_key_set_id, security_level, kDefaultCdmIdentifier));
|
|
|
|
|
original_key_set_id, security_level, kExampleIdentifier));
|
|
|
|
|
|
|
|
|
|
// Verify license has been removed.
|
|
|
|
|
EXPECT_EQ(wvcdm::NO_ERROR,
|
|
|
|
|
decryptor_->ListStoredLicenses(
|
|
|
|
|
security_level, kDefaultCdmIdentifier, &key_set_ids));
|
|
|
|
|
decryptor_->ListStoredLicenses(security_level, kExampleIdentifier,
|
|
|
|
|
&key_set_ids));
|
|
|
|
|
EXPECT_THAT(key_set_ids, Not(Contains(original_key_set_id)));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_F(WvCdmRequestLicenseTest, RemoveOfflineLicenseAfterUnprovisioning) {
|
|
|
|
|
const CdmSecurityLevel security_level = GetDefaultSecurityLevel();
|
|
|
|
|
const RequestedSecurityLevel requested_security_level =
|
|
|
|
|
(security_level == kSecurityLevelL3) ? kLevel3 : kLevelDefault;
|
|
|
|
|
|
|
|
|
|
Unprovision(kExampleIdentifier);
|
|
|
|
|
Provision(kExampleIdentifier, requested_security_level);
|
|
|
|
|
|
|
|
|
|
std::string key_id;
|
|
|
|
|
std::string client_auth;
|
|
|
|
|
GetOfflineConfiguration(&key_id, &client_auth);
|
|
|
|
|
|
|
|
|
|
// Setup: Request an offline license to create a valid license file.
|
|
|
|
|
// This license will be used to test how the CDM handles request to
|
|
|
|
|
// remove when the device has been unprovisioned.
|
|
|
|
|
|
|
|
|
|
decryptor_->OpenSession(config_.key_system(), nullptr, kExampleIdentifier,
|
|
|
|
|
nullptr, &session_id_);
|
|
|
|
|
GenerateKeyRequest(key_id, kLicenseTypeOffline, kExampleIdentifier);
|
|
|
|
|
VerifyKeyRequestResponse(config_.license_server(), client_auth);
|
|
|
|
|
|
|
|
|
|
// Save the key set ID for check below.
|
|
|
|
|
const std::string original_key_set_id(key_set_id_);
|
|
|
|
|
decryptor_->CloseSession(session_id_);
|
|
|
|
|
|
|
|
|
|
// Unprovision, making the old DRM certificate unavailable.
|
|
|
|
|
Unprovision(kExampleIdentifier);
|
|
|
|
|
|
|
|
|
|
std::vector<CdmKeySetId> key_set_ids;
|
|
|
|
|
EXPECT_EQ(wvcdm::NO_ERROR,
|
|
|
|
|
decryptor_->ListStoredLicenses(security_level, kExampleIdentifier,
|
|
|
|
|
&key_set_ids));
|
|
|
|
|
// Note: It is possible that future changes to the CDM will cause this
|
|
|
|
|
// check to fail (such by filtering results from ListStoreLicenses).
|
|
|
|
|
EXPECT_THAT(key_set_ids, Contains(original_key_set_id));
|
|
|
|
|
|
|
|
|
|
// Remove offline license, without causing a provisioning error.
|
|
|
|
|
EXPECT_EQ(wvcdm::NO_ERROR,
|
|
|
|
|
decryptor_->RemoveOfflineLicense(
|
|
|
|
|
original_key_set_id, security_level, kExampleIdentifier));
|
|
|
|
|
|
|
|
|
|
// Verify license has been removed.
|
|
|
|
|
EXPECT_EQ(wvcdm::NO_ERROR,
|
|
|
|
|
decryptor_->ListStoredLicenses(security_level, kExampleIdentifier,
|
|
|
|
|
&key_set_ids));
|
|
|
|
|
EXPECT_THAT(key_set_ids, Not(Contains(original_key_set_id)));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_F(WvCdmRequestLicenseTest, RemoveOfflineLicenseAfterReprovisioning) {
|
|
|
|
|
const CdmSecurityLevel security_level = GetDefaultSecurityLevel();
|
|
|
|
|
const RequestedSecurityLevel requested_security_level =
|
|
|
|
|
(security_level == kSecurityLevelL3) ? kLevel3 : kLevelDefault;
|
|
|
|
|
|
|
|
|
|
Unprovision(kExampleIdentifier);
|
|
|
|
|
Provision(kExampleIdentifier, requested_security_level);
|
|
|
|
|
|
|
|
|
|
std::string key_id;
|
|
|
|
|
std::string client_auth;
|
|
|
|
|
GetOfflineConfiguration(&key_id, &client_auth);
|
|
|
|
|
|
|
|
|
|
// Setup: Request an offline license to create a valid license file.
|
|
|
|
|
// This license will be used to test how the CDM handles request to
|
|
|
|
|
// remove when the device has been unprovisioned.
|
|
|
|
|
|
|
|
|
|
decryptor_->OpenSession(config_.key_system(), nullptr, kExampleIdentifier,
|
|
|
|
|
nullptr, &session_id_);
|
|
|
|
|
GenerateKeyRequest(key_id, kLicenseTypeOffline, kExampleIdentifier);
|
|
|
|
|
VerifyKeyRequestResponse(config_.license_server(), client_auth);
|
|
|
|
|
|
|
|
|
|
// Save the key set ID for check below.
|
|
|
|
|
const std::string original_key_set_id(key_set_id_);
|
|
|
|
|
decryptor_->CloseSession(session_id_);
|
|
|
|
|
|
|
|
|
|
// Reprovision, making the old DRM certificate unavailable.
|
|
|
|
|
Unprovision(kExampleIdentifier);
|
|
|
|
|
Provision(kExampleIdentifier, requested_security_level);
|
|
|
|
|
|
|
|
|
|
std::vector<CdmKeySetId> key_set_ids;
|
|
|
|
|
EXPECT_EQ(wvcdm::NO_ERROR,
|
|
|
|
|
decryptor_->ListStoredLicenses(security_level, kExampleIdentifier,
|
|
|
|
|
&key_set_ids));
|
|
|
|
|
// Note: It is possible that future changes to the CDM will cause this
|
|
|
|
|
// check to fail (such by filtering results from ListStoreLicenses).
|
|
|
|
|
EXPECT_THAT(key_set_ids, Contains(original_key_set_id));
|
|
|
|
|
|
|
|
|
|
// Remove offline license, without causing a license load error.
|
|
|
|
|
EXPECT_EQ(wvcdm::NO_ERROR,
|
|
|
|
|
decryptor_->RemoveOfflineLicense(
|
|
|
|
|
original_key_set_id, security_level, kExampleIdentifier));
|
|
|
|
|
|
|
|
|
|
// Verify license has been removed.
|
|
|
|
|
EXPECT_EQ(wvcdm::NO_ERROR,
|
|
|
|
|
decryptor_->ListStoredLicenses(security_level, kExampleIdentifier,
|
|
|
|
|
&key_set_ids));
|
|
|
|
|
EXPECT_THAT(key_set_ids, Not(Contains(original_key_set_id)));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_F(WvCdmRequestLicenseTest, RemoveUnlimitedOfflineLicense) {
|
|
|
|
|
const CdmSecurityLevel security_level = GetDefaultSecurityLevel();
|
|
|
|
|
const RequestedSecurityLevel requested_security_level =
|
|
|
|
|
(security_level == kSecurityLevelL3) ? kLevel3 : kLevelDefault;
|
|
|
|
|
|
|
|
|
|
Unprovision(kExampleIdentifier);
|
|
|
|
|
Provision(kExampleIdentifier, requested_security_level);
|
|
|
|
|
|
|
|
|
|
std::string key_id;
|
|
|
|
|
std::string client_auth;
|
|
|
|
|
GetOfflineConfiguration(&key_id, &client_auth);
|
|
|
|
|
|
|
|
|
|
// Override content ID.
|
|
|
|
|
key_id = wvutil::a2bs_hex(
|
|
|
|
|
"0000004d" // size = 77
|
|
|
|
|
"70737368" // type = "pssh"
|
|
|
|
|
"00000000" // flags = None
|
|
|
|
|
"edef8ba979d64acea3c827dcd51d21ed" // system_id = Widevine
|
|
|
|
|
"0000002d" // pssh_data_size = 45
|
|
|
|
|
// WidevinePsshData(
|
|
|
|
|
// algorithm = AESCTR,
|
|
|
|
|
// provider = "widevine_test"
|
|
|
|
|
// content_id = b"GTS_CAN_PERSIST_LICENSE_0S")
|
|
|
|
|
"08011a0d7769646576696e655f7465"
|
|
|
|
|
"7374221a4754535f43414e5f504552"
|
|
|
|
|
"534953545f4c4943454e53455f3053");
|
|
|
|
|
|
|
|
|
|
// Setup: Request an offline license to create a valid license file.
|
|
|
|
|
// This license will be used to test how the CDM handles request to
|
|
|
|
|
// remove when the device has been unprovisioned.
|
|
|
|
|
|
|
|
|
|
decryptor_->OpenSession(config_.key_system(), nullptr, kExampleIdentifier,
|
|
|
|
|
nullptr, &session_id_);
|
|
|
|
|
GenerateKeyRequest(key_id, kLicenseTypeOffline, kExampleIdentifier);
|
|
|
|
|
VerifyKeyRequestResponse(config_.license_server(), client_auth);
|
|
|
|
|
|
|
|
|
|
// Save the key set ID for check below.
|
|
|
|
|
const std::string original_key_set_id(key_set_id_);
|
|
|
|
|
decryptor_->CloseSession(session_id_);
|
|
|
|
|
|
|
|
|
|
std::vector<CdmKeySetId> key_set_ids;
|
|
|
|
|
EXPECT_EQ(wvcdm::NO_ERROR,
|
|
|
|
|
decryptor_->ListStoredLicenses(security_level, kExampleIdentifier,
|
|
|
|
|
&key_set_ids));
|
|
|
|
|
// Note: It is possible that future changes to the CDM will cause this
|
|
|
|
|
// check to fail (such by filtering results from ListStoreLicenses).
|
|
|
|
|
EXPECT_THAT(key_set_ids, Contains(original_key_set_id));
|
|
|
|
|
|
|
|
|
|
// Remove offline license, without causing a generate signature error.
|
|
|
|
|
EXPECT_EQ(wvcdm::NO_ERROR,
|
|
|
|
|
decryptor_->RemoveOfflineLicense(
|
|
|
|
|
original_key_set_id, security_level, kExampleIdentifier));
|
|
|
|
|
|
|
|
|
|
// Verify license has been removed.
|
|
|
|
|
EXPECT_EQ(wvcdm::NO_ERROR,
|
|
|
|
|
decryptor_->ListStoredLicenses(security_level, kExampleIdentifier,
|
|
|
|
|
&key_set_ids));
|
|
|
|
|
EXPECT_THAT(key_set_ids, Not(Contains(original_key_set_id)));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|