Merge "Single PSSH entitlement handling" into qt-dev

am: 19c6e57269

Change-Id: Ie11018d844b1d43862815a72ca185a980ddd1f76
This commit is contained in:
Rahul Frias
2019-05-13 09:45:04 -07:00
committed by android-build-merger
3 changed files with 163 additions and 22 deletions

View File

@@ -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

View File

@@ -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.

View File

@@ -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,