Handle key rotation

[ Merge of http://go/wvgerrit/77049 ]

Entitlement PSSHs can now be provided in follow on key generation
requests to cause keys to be rotated without needing a license
exchange.

Bug: 128462397
Test: WV unit/integration tests, Netflix and GPlay tests,
      GtsMediaDrmTests

Change-Id: I6ed0901a35c498240f42e405a522d82ea8dce2f7
This commit is contained in:
Rahul Frias
2019-04-18 11:32:58 -07:00
parent 79a271fcce
commit 2e2e92280e
5 changed files with 183 additions and 2 deletions

View File

@@ -34,6 +34,7 @@ class InitializationData {
CdmHlsMethod hls_method() const { return hls_method_; }
std::vector<video_widevine::WidevinePsshData_EntitledKey> ExtractWrappedKeys()
const;
bool contains_entitled_keys() const { return contains_entitled_keys_; }
private:
bool SelectWidevinePssh(const CdmInitData& init_data,
@@ -86,6 +87,7 @@ class InitializationData {
bool is_hls_;
bool is_webm_;
bool is_audio_;
bool contains_entitled_keys_;
std::vector<uint8_t> hls_iv_;
CdmHlsMethod hls_method_;

View File

@@ -439,8 +439,13 @@ CdmResponseType CdmSession::GenerateKeyRequestInternal(
if (is_release_) {
return GenerateReleaseRequest(key_request);
} else if (license_received_) { // renewal
return GenerateRenewalRequest(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
if (init_data.contains_entitled_keys())
return license_parser_->HandleEmbeddedKeyData(init_data);
else
return GenerateRenewalRequest(key_request);
} else {
key_request->type = kKeyRequestTypeInitial;

View File

@@ -56,6 +56,7 @@ InitializationData::InitializationData(const std::string& type,
is_hls_(false),
is_webm_(false),
is_audio_(false),
contains_entitled_keys_(false),
hls_method_(kHlsMethodNone) {
if (type == ISO_BMFF_VIDEO_MIME_TYPE || type == ISO_BMFF_AUDIO_MIME_TYPE ||
type == CENC_INIT_DATA_FORMAT) {
@@ -138,12 +139,19 @@ bool InitializationData::SelectWidevinePssh(const CdmInitData& init_data,
continue;
}
if (pssh.type() == WidevinePsshData_Type_ENTITLED_KEY) {
contains_entitled_keys_ = true;
*output = pssh_payloads[i];
return true;
}
}
}
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

@@ -524,12 +524,14 @@ TEST_F(InitializationDataTest, HandlesMultipleWidevinePsshs) {
kOemCryptoWithoutEntitlements);
EXPECT_FALSE(single_init_data.IsEmpty());
EXPECT_EQ(kSingleKeyWidevinePsshBoxData, single_init_data.data());
EXPECT_FALSE(single_init_data.contains_entitled_keys());
InitializationData entitled_init_data(ISO_BMFF_VIDEO_MIME_TYPE,
kMultipleWidevinePsshBox,
kOemCryptoWithEntitlements);
EXPECT_FALSE(entitled_init_data.IsEmpty());
EXPECT_EQ(kEntitledKeysWidevinePsshBoxData, entitled_init_data.data());
EXPECT_TRUE(entitled_init_data.contains_entitled_keys());
}
TEST_P(HlsKeyFormatVersionsExtractionTest, ExtractKeyFormatVersions) {