Merge "Single PSSH entitlement handling" into qt-dev
am: 19c6e57269
Change-Id: Ie11018d844b1d43862815a72ca185a980ddd1f76
This commit is contained in:
@@ -425,10 +425,12 @@ CdmResponseType CdmSession::GenerateKeyRequestInternal(
|
||||
case kLicenseTypeRelease:
|
||||
is_release_ = true;
|
||||
break;
|
||||
// TODO(jfore): CdmSession assumes a call to this method once a license has
|
||||
// been received is a call to generate a license renewal message. Use of
|
||||
// this enum differentiates the two calls. See "else if (license_received_)"
|
||||
// below.
|
||||
// TODO(b/132071885): Once a license has been received, CdmSession assumes
|
||||
// that a call to this method is to generate a license renewal/release
|
||||
// or key rotation. Key rotation can be indicated by specifing a license
|
||||
// type kLicenseTypeEmbeddedKeyData or interrogating the PSSH
|
||||
// (See "else if (license_received_)" below). b/132071885 is to evaluate
|
||||
// whether both mechanisms are needed.
|
||||
case kLicenseTypeEmbeddedKeyData:
|
||||
return license_parser_->HandleEmbeddedKeyData(init_data);
|
||||
default:
|
||||
@@ -441,7 +443,7 @@ CdmResponseType CdmSession::GenerateKeyRequestInternal(
|
||||
return GenerateReleaseRequest(key_request);
|
||||
} else if (license_received_) {
|
||||
// A call to GenerateKeyRequest after the initial license has been received
|
||||
// is either a renewal request or a key rotation event
|
||||
// is either a renewal/release request or a key rotation event
|
||||
if (init_data.contains_entitled_keys())
|
||||
return license_parser_->HandleEmbeddedKeyData(init_data);
|
||||
else
|
||||
|
||||
@@ -126,10 +126,9 @@ bool InitializationData::SelectWidevinePssh(const CdmInitData& init_data,
|
||||
return false;
|
||||
}
|
||||
|
||||
// If there are multiple PSSHs to choose from and this device prefers
|
||||
// entitlements, find the first |ENTITLED_KEY| PSSH, if present, and
|
||||
// select it.
|
||||
if (prefer_entitlements && pssh_payloads.size() > 1) {
|
||||
// If this device prefers entitlements, search through available PSSHs.
|
||||
// If present, select the first |ENTITLED_KEY| PSSH.
|
||||
if (prefer_entitlements && !pssh_payloads.empty()) {
|
||||
for (size_t i = 0; i < pssh_payloads.size(); ++i) {
|
||||
WidevinePsshData pssh;
|
||||
if (!pssh.ParseFromString(pssh_payloads[i])) {
|
||||
@@ -146,12 +145,6 @@ bool InitializationData::SelectWidevinePssh(const CdmInitData& init_data,
|
||||
}
|
||||
}
|
||||
|
||||
WidevinePsshData pssh;
|
||||
if (prefer_entitlements && pssh.ParseFromString(pssh_payloads[0])) {
|
||||
if (pssh.type() == WidevinePsshData_Type_ENTITLED_KEY)
|
||||
contains_entitled_keys_ = true;
|
||||
}
|
||||
|
||||
// Either there is only one PSSH, this device does not prefer entitlements,
|
||||
// or no entitlement PSSH was found. Regardless of how we got here, select the
|
||||
// first PSSH, which should be a |SINGLE| PSSH.
|
||||
|
||||
@@ -446,7 +446,55 @@ SubSampleInfo usage_info_sub_samples_icp[] = {
|
||||
wvcdm::a2b_hex("964c2dfda920357c668308d52d33c652"), 0,
|
||||
OEMCrypto_FirstSubsample | OEMCrypto_LastSubsample}};
|
||||
|
||||
SubSampleInfo entitlement_with_key_rotation_sub_sample[] = {
|
||||
SubSampleInfo kEntitlementWithKeyRotationSubSampleSinglePssh[] = {
|
||||
{
|
||||
true, 1, true, true, false,
|
||||
wvcdm::a2bs_hex("c8326486bb5d5c4a958f00b1111afc81"),
|
||||
wvcdm::a2b_hex(
|
||||
"64ab17b3e3dfab47245c7cce4543d4fc7a26dcf248f19f9b59f3c92601440b36"
|
||||
"17c8ed0c96c656549e461f38708cd47a434066f8df28ccc28b79252eee3f9c2d"
|
||||
"7f6c68ebe40141fe818fe082ca523c03d69ddaf183a93c022327fedc5582c5ab"
|
||||
"ca9d342b71263a67f9cb2336f12108aaaef464f17177e44e9b0c4e56e61da53c"
|
||||
"2150b4405cc82d994dfd9bf4087c761956d6688a9705db4cf350381085f383c4"
|
||||
"9666d4aed135c519c1f0b5cba06e287feea96ea367bf54e7368dcf998276c6e4"
|
||||
"6497e0c50e20fef74e42cb518fe7f22ef27202428688f86404e8278587017012"
|
||||
"c1d65537c6cbd7dde04aae338d68115a9f430afc100ab83cdadf45dca39db685"),
|
||||
wvcdm::a2b_hex(
|
||||
"cb468f067baa5634f83947b921fdb37e66bc5925edc4bdc2424db4c33cfd55a1"
|
||||
"cd0a96b6634796ddcf5ba8820b83f80d318ff49b7e614779f5e87dd6dfadd8d6"
|
||||
"cf95c7b0f21e4174e2e91371ebdb69866340a37a581a7c0713eda5168bcfc003"
|
||||
"12a341a83defa754c4601772ed9171526720b6a2b2b084030f21ef13f2a35dec"
|
||||
"e93f5c394c56d9ce108c2f5b0e5edb857d322fae24ec22f3ad726496b382306b"
|
||||
"4fdf5a0a99efc2db2a9458f0bfd6b21869c9acf6ea222fe942af6cd9b38d9a50"
|
||||
"a96db14ad27d368c5753aa5da8d8507603ed08086e2492bdff267ee64862f159"
|
||||
"b19d2c72b2f5a39520d5ae2aacae1a192d375d45f3f9ba86d5026cbcacdfecbe"),
|
||||
wvcdm::a2b_hex("f6f4b1e600a5b67813ed2bded913ba9f"), 0,
|
||||
OEMCrypto_FirstSubsample | OEMCrypto_LastSubsample},
|
||||
{
|
||||
true, 1, true, true, false,
|
||||
wvcdm::a2bs_hex("f8488775a99855ff94b93ec5bd499356"),
|
||||
wvcdm::a2b_hex(
|
||||
"64ab17b3e3dfab47245c7cce4543d4fc7a26dcf248f19f9b59f3c92601440b36"
|
||||
"17c8ed0c96c656549e461f38708cd47a434066f8df28ccc28b79252eee3f9c2d"
|
||||
"7f6c68ebe40141fe818fe082ca523c03d69ddaf183a93c022327fedc5582c5ab"
|
||||
"ca9d342b71263a67f9cb2336f12108aaaef464f17177e44e9b0c4e56e61da53c"
|
||||
"2150b4405cc82d994dfd9bf4087c761956d6688a9705db4cf350381085f383c4"
|
||||
"9666d4aed135c519c1f0b5cba06e287feea96ea367bf54e7368dcf998276c6e4"
|
||||
"6497e0c50e20fef74e42cb518fe7f22ef27202428688f86404e8278587017012"
|
||||
"c1d65537c6cbd7dde04aae338d68115a9f430afc100ab83cdadf45dca39db685"),
|
||||
wvcdm::a2b_hex(
|
||||
"51b0133e2e5f40c22d10ec0562799e5e4118aacaa6a820be976acee4b7689280"
|
||||
"541b56836c454414fbaebf9a3142baa2c8009a4f19ac033665bd3495f2ad19f3"
|
||||
"3b850d1e8e6957172571e82d3c812d03588c95a1ef49f08b33f21ea4f2d382c9"
|
||||
"28704e329847e5fe98966949f39e272ec30126f5d7a4ae21d3a0d25aa8ccf637"
|
||||
"d5f880a6733b07bdd33cfdc3c36dece2bffb6049f218162b024df4f800557568"
|
||||
"a792e0add16fc388ee13595313c3fbeef28f69737523e449dc2cf893f0566a79"
|
||||
"8a83110c8d3aaf5c1f7e8e8fe355a294a9a77b5494704b18e27f1315cb19c104"
|
||||
"3ad2061a2a414d40cc768fc4c8f49a3905e3a82095aa4eef6a1ad8af1029fced"),
|
||||
wvcdm::a2b_hex("f6f4b1e600a5b67813ed2bded913ba9f"), 0,
|
||||
OEMCrypto_FirstSubsample | OEMCrypto_LastSubsample}};
|
||||
|
||||
SubSampleInfo kEntitlementWithKeyRotationSubSampleDualPssh[] = {
|
||||
{
|
||||
true, 1, true, true, false,
|
||||
wvcdm::a2bs_hex("1D9B8E13B59951169348FF8D5B9394C0"),
|
||||
@@ -578,7 +626,75 @@ std::string kPsshStreamingClip21 = wvcdm::a2bs_hex(
|
||||
"EDEF8BA979D64ACEA3C827DCD51D21ED00000023" // Widevine system id
|
||||
"08011a0d7769646576696e655f746573" // pssh data
|
||||
"74221073747265616d696e675f636c69703231");
|
||||
const std::string kPsshEntitlementWithKeyRotation[] = {
|
||||
const std::string kSinglePsshEntitlementWithKeyRotation[] = {
|
||||
wvcdm::a2bs_hex(
|
||||
"000001fb7073736800000000" // blob size and pssh
|
||||
"edef8ba979d64acea3c827dcd51d21ed000001db" // Widevine system id
|
||||
"220b47726f7570563254657374381448" // pssh data
|
||||
"e3dc959b065002580272580a10668093"
|
||||
"381a8c5be48a0168ce372726ac1210c8"
|
||||
"326486bb5d5c4a958f00b1111afc811a"
|
||||
"20082cd9d3aed3ebe6239d30fbcf0b22"
|
||||
"1d28cbb0360ea1295c2363973346ec00"
|
||||
"512210914781334e864c8eb7f768cf26"
|
||||
"49073872580a10f872d11d5b1052f2bd"
|
||||
"a94e60a0e383021210450897c987a85c"
|
||||
"2e9579f968554a12991a2097e603ceea"
|
||||
"f35ed8cef1029eae7a0a54701e3d6db6"
|
||||
"80e7da1de3b22a8db347fb2210b41c34"
|
||||
"29b7bb96972bbaf6587bc0ddf172580a"
|
||||
"10bac58b9fce9e5929a42a180e529f19"
|
||||
"4712103f11f22988d25659b145ce4854"
|
||||
"3e6b141a20416e22768e5a57b08d155e"
|
||||
"5210d00658056947ff06d626668bceb3"
|
||||
"5eb01c6b57221081fb2ff3fef79d332f"
|
||||
"f98be46233596972580a101261c8036d"
|
||||
"ae5c8caa968858aa0ca9cc12106d583c"
|
||||
"b37c1456519843a81cf49912221a20c2"
|
||||
"1116bb54a226e8d879a4cd41d8879920"
|
||||
"2ae85b80d83b1b4447e5d7fcad6f6a22"
|
||||
"100b27a4c3f44771d2b0c7c34c66af35"
|
||||
"b572580a10ab1c8c259c6b5967991389"
|
||||
"65bff5ac0c1210b5b4473658565d3786"
|
||||
"efaf4b85d8e6e21a203ce6a9085285c2"
|
||||
"ece0b650dc83dd7aa8ac849611a8e3f8"
|
||||
"3c8f389223c0f3621522101946f0c2a3"
|
||||
"d543101cc842bbec2d0b30"),
|
||||
wvcdm::a2bs_hex(
|
||||
"000001fb7073736800000000" // blob size and pssh
|
||||
"edef8ba979d64acea3c827dcd51d21ed000001db" // Widevine system id
|
||||
"220b47726f7570563254657374381548" // pssh data
|
||||
"e3dc959b065002580272580a10668093"
|
||||
"381a8c5be48a0168ce372726ac1210f8"
|
||||
"488775a99855ff94b93ec5bd4993561a"
|
||||
"20d15ba631c20e95da0d4857f6a1d25a"
|
||||
"a3bccbd3fde18b3fdc1dd8c4f0ede76f"
|
||||
"402210d6dd3675f0d1150052e81b9107"
|
||||
"6d7fc172580a10f872d11d5b1052f2bd"
|
||||
"a94e60a0e383021210ad1f93ad921e53"
|
||||
"b097c415b2bf1ef1c61a20b2087b60a2"
|
||||
"d253ac2158a1bfa789b150b79701b29e"
|
||||
"c852a2662560f8b8977a4c2210051ed3"
|
||||
"2628671fbda58f506ba5ea713972580a"
|
||||
"10bac58b9fce9e5929a42a180e529f19"
|
||||
"47121027cdda7bfe5e5fd4bff2ebc9c7"
|
||||
"c020701a20f2cb1184d648a2404517e6"
|
||||
"7a39d698332aae6bb890a69bf7ddb536"
|
||||
"75b8ac41c62210a80ed7f9b728fdd566"
|
||||
"0b01b173ace26372580a101261c8036d"
|
||||
"ae5c8caa968858aa0ca9cc1210769a70"
|
||||
"0442a25bf5ae17174c70f4cb8e1a206c"
|
||||
"7b2012723fc47c83b003ea214204915f"
|
||||
"9a63dc373bf219f36ccf5697589aa422"
|
||||
"10bcc3c16e836cca264d5493a0c334d3"
|
||||
"4872580a10ab1c8c259c6b5967991389"
|
||||
"65bff5ac0c1210894b04aef78557c6a7"
|
||||
"e6e8855febbcc91a2025cc545ee3cd0c"
|
||||
"c323586610ff6a8f8f22a78f5fade2f2"
|
||||
"1083f152c52208f16d2210257aacacec"
|
||||
"512a2e769396b10e6d9dfa")
|
||||
};
|
||||
const std::string kDualPsshEntitlementWithKeyRotation[] = {
|
||||
wvcdm::a2bs_hex(
|
||||
"0000003e7073736800000000" // blob size and pssh
|
||||
"edef8ba979d64acea3c827dcd51d21ed0000001e" // Widevine system id
|
||||
@@ -735,6 +851,26 @@ RenewWithClientIdTestConfiguration
|
||||
{true, false, false, false,
|
||||
"Test: Usage reporting with client Id"}};
|
||||
|
||||
struct EntitlementTestConfiguration {
|
||||
std::string entitlement_pssh;
|
||||
std::string key_rotation_pssh;
|
||||
SubSampleInfo* sub_sample_with_initial_keys;
|
||||
SubSampleInfo* sub_sample_with_rotated_keys;
|
||||
};
|
||||
|
||||
EntitlementTestConfiguration kEntitlementTestConfiguration[] = {
|
||||
{// Single Widevine PSSH containing PSSH data of type ENTITLED_KEY
|
||||
kSinglePsshEntitlementWithKeyRotation[0],
|
||||
kSinglePsshEntitlementWithKeyRotation[1],
|
||||
&kEntitlementWithKeyRotationSubSampleSinglePssh[0],
|
||||
&kEntitlementWithKeyRotationSubSampleSinglePssh[1]},
|
||||
{// Two Widevine PSSHs containing PSSH data of type SINGLE, ENTITLED_KEY
|
||||
kDualPsshEntitlementWithKeyRotation[0],
|
||||
kDualPsshEntitlementWithKeyRotation[1],
|
||||
&kEntitlementWithKeyRotationSubSampleDualPssh[0],
|
||||
&kEntitlementWithKeyRotationSubSampleDualPssh[1]},
|
||||
};
|
||||
|
||||
// provider:"widevine_test",
|
||||
// content_id":"aGxzX3NhbXBsZV9hZXNfc3RyZWFtaW5n" (hls_sample_aes_streaming)
|
||||
// key_id:613db35603320eb8e7ea24bdeea3fdb8
|
||||
@@ -2880,29 +3016,39 @@ TEST_F(WvCdmRequestLicenseTest, OfflineLicenseRenewalAndRelease) {
|
||||
VerifyKeyRequestResponse(config_.license_server(), client_auth);
|
||||
}
|
||||
|
||||
TEST_F(WvCdmRequestLicenseTest, EntitlementWithKeyRotation) {
|
||||
class WvCdmEntitlementTest
|
||||
: public WvCdmRequestLicenseTest,
|
||||
public ::testing::WithParamInterface<EntitlementTestConfiguration*> {};
|
||||
|
||||
TEST_P(WvCdmEntitlementTest, EntitlementWithKeyRotation) {
|
||||
EntitlementTestConfiguration* config = GetParam();
|
||||
decryptor_.OpenSession(config_.key_system(), NULL, kDefaultCdmIdentifier,
|
||||
NULL, &session_id_);
|
||||
|
||||
// Fetch entitlement license
|
||||
GenerateKeyRequest(kPsshEntitlementWithKeyRotation[0], kLicenseTypeStreaming);
|
||||
GenerateKeyRequest(config->entitlement_pssh, kLicenseTypeStreaming);
|
||||
VerifyKeyRequestResponse(config_.license_server(), config_.client_auth());
|
||||
|
||||
// Verify that we can decrypt a subsample
|
||||
ASSERT_TRUE(VerifyDecryption(session_id_,
|
||||
entitlement_with_key_rotation_sub_sample[0]));
|
||||
*(config->sub_sample_with_initial_keys)));
|
||||
|
||||
// Key rotation
|
||||
ASSERT_TRUE(KeyRotationRequest(kLicenseTypeStreaming,
|
||||
kPsshEntitlementWithKeyRotation[1]));
|
||||
config->key_rotation_pssh));
|
||||
|
||||
// Verify that we can decrypt a subsample
|
||||
ASSERT_TRUE(VerifyDecryption(session_id_,
|
||||
entitlement_with_key_rotation_sub_sample[1]));
|
||||
*(config->sub_sample_with_rotated_keys)));
|
||||
|
||||
decryptor_.CloseSession(session_id_);
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
Cdm, WvCdmEntitlementTest,
|
||||
::testing::Range(&kEntitlementTestConfiguration[0],
|
||||
&kEntitlementTestConfiguration[2]));
|
||||
|
||||
TEST_F(WvCdmRequestLicenseTest, RemoveKeys) {
|
||||
ASSERT_EQ(NO_ERROR, decryptor_.OpenSession(config_.key_system(), NULL,
|
||||
kDefaultCdmIdentifier, NULL,
|
||||
|
||||
Reference in New Issue
Block a user