Source release v3.4.1

This commit is contained in:
Gene Morgan
2017-09-01 14:17:56 -07:00
parent 8082775924
commit 183aacf0a3
50 changed files with 1508 additions and 2342 deletions

View File

@@ -48,17 +48,41 @@ using video_widevine::ClientIdentification_NameValue;
using video_widevine::DrmDeviceCertificate;
using video_widevine::EncryptedClientIdentification;
using video_widevine::License;
using video_widevine::License_KeyContainer;
using video_widevine::LicenseError;
using video_widevine::LicenseIdentification;
using video_widevine::LicenseRequest;
using video_widevine::LicenseRequest_ContentIdentification;
using video_widevine::LicenseRequest_ContentIdentification_CencDeprecated;
using video_widevine::LicenseRequest_ContentIdentification_WebmDeprecated;
using video_widevine::LicenseRequest_ContentIdentification_ExistingLicense;
using video_widevine::LicenseRequest_ContentIdentification_WebmDeprecated;
using video_widevine::License_KeyContainer;
using video_widevine::SignedDrmDeviceCertificate;
using video_widevine::SignedMessage;
static std::vector<CryptoKey> ExtractSubSessionKeys(const License& license) {
std::vector<CryptoKey> key_array;
// Extract sub session key(s)
for (int i = 0; i < license.key_size(); ++i) {
CryptoKey key;
switch (license.key(i).type()) {
case License_KeyContainer::SUB_SESSION:
key.set_key_data(license.key(i).key());
key.set_key_data_iv(license.key(i).iv());
key.set_key_id(license.key(i).id());
key.set_track_label(license.key(i).track_label());
key_array.push_back(key);
break;
default:
// Ignore all but SUB_SESSION key types.
break;
}
}
return key_array;
}
static std::vector<CryptoKey> ExtractContentKeys(const License& license) {
std::vector<CryptoKey> key_array;
@@ -87,6 +111,7 @@ static std::vector<CryptoKey> ExtractContentKeys(const License& license) {
if (license.has_protection_scheme()) {
four_cc = license.protection_scheme();
}
key.set_track_label(license.key(i).track_label());
switch (four_cc) {
// b/30713238: Android N assumed that the "protection scheme" Four
// CC code, after being extracted from the protobuf, was host byte
@@ -115,11 +140,28 @@ static std::vector<CryptoKey> ExtractContentKeys(const License& license) {
}
break;
default:
// Ignore SIGNING key types as they are not content related
// Ignore SIGNING and SUB_SESSION key types as they are not content
// related.
break;
}
}
std::vector<CryptoKey> sub_session_keys = ExtractSubSessionKeys(license);
// Match the track label from the key arrays and add sub_license_key_id to
// the content key array.
LOGI("Received %d subsession keys", sub_session_keys.size());
if (!sub_session_keys.empty()) {
for (int i = 0; i < key_array.size(); ++i) {
if (key_array[i].track_label().empty()) continue;
for (int x = 0; x < sub_session_keys.size(); ++x) {
if (sub_session_keys[x].track_label() == key_array[i].track_label()) {
key_array[i].set_sub_session_key_id(sub_session_keys[x].key_id());
key_array[i].set_sub_session_key(sub_session_keys[x].key_data());
}
}
}
}
return key_array;
}
@@ -221,8 +263,8 @@ CdmResponseType CdmLicense::PrepareKeyRequest(
status = PrepareClientId(app_parameters, &license_request);
if (NO_ERROR != status) return status;
status = PrepareContentId(init_data, license_type, request_id,
&license_request);
status =
PrepareContentId(init_data, license_type, request_id, &license_request);
if (NO_ERROR != status) return status;
license_request.set_type(LicenseRequest::NEW);
@@ -237,6 +279,37 @@ CdmResponseType CdmLicense::PrepareKeyRequest(
}
license_request.set_key_control_nonce(nonce);
LOGD("PrepareKeyRequest: nonce=%u", nonce);
// Prepare the request for any embedded keys that may exist in the
// initialization data.
std::vector<video_widevine::SubLicense> embedded_key_data =
init_data.ExtractEmbeddedKeys();
for (int i = 0; i < embedded_key_data.size(); ++i) {
bool exists = false;
if (!crypto_session_->GenerateSubSessionNonce(
embedded_key_data[i].sub_session_key_id(), &exists, &nonce)) {
return LICENSE_REQUEST_NONCE_GENERATION_ERROR;
}
if (exists) {
SignedMessage signed_sub_license;
License_KeyContainer keyc;
// Parse the sub license for this track to extract the label.
if (!signed_sub_license.ParseFromString(embedded_key_data[i].key_msg()) ||
!keyc.ParseFromString(signed_sub_license.msg()) ||
keyc.track_label().empty()) {
return LICENSE_REQUEST_INVALID_SUBLICENSE;
}
LicenseRequest::SubSessionData* sub_session_data =
license_request.add_sub_session_data();
sub_session_data->set_sub_session_key_id(
embedded_key_data[i].sub_session_key_id());
sub_session_data->set_nonce(nonce);
sub_session_data->set_track_label(keyc.track_label());
}
}
license_request.set_protocol_version(video_widevine::VERSION_2_1);
// License request is complete. Serialize it.
@@ -438,7 +511,6 @@ CdmResponseType CdmLicense::HandleKeyResponse(
LOGE("CdmLicense::HandleKeyResponse: no session keys present");
return SESSION_KEYS_NOT_FOUND;
}
if (!crypto_session_->GenerateDerivedKeys(key_request_,
signed_response.session_key()))
return GENERATE_DERIVED_KEYS_ERROR;
@@ -492,7 +564,8 @@ CdmResponseType CdmLicense::HandleKeyResponse(
renew_with_client_id_ = license.policy().always_include_client_id();
}
CdmResponseType resp = crypto_session_->LoadKeys(
CdmResponseType resp = NO_ERROR;
resp = crypto_session_->LoadKeys(
signed_response.msg(), signed_response.signature(), mac_key_iv, mac_key,
key_array, provider_session_token_);
@@ -587,6 +660,45 @@ CdmResponseType CdmLicense::HandleKeyUpdateResponse(
}
}
CdmResponseType CdmLicense::HandleSubLicense(
const InitializationData& init_data) {
std::vector<video_widevine::SubLicense> subkeys =
init_data.ExtractEmbeddedKeys();
std::set<KeyId> loaded_keys;
// Build a license with the rotated keys.
License license;
for (int i = 0; i < subkeys.size(); ++i) {
SignedMessage sm;
if (!sm.ParseFromString(subkeys[i].key_msg())) {
return LICENSE_REQUEST_INVALID_SUBLICENSE;
}
License_KeyContainer keyc;
if (!keyc.ParseFromString(sm.msg())) {
return LICENSE_REQUEST_INVALID_SUBLICENSE;
}
std::vector<CryptoKey> keys;
keys.resize(1);
keys[0].set_key_id(keyc.id());
keys[0].set_key_data(keyc.key());
keys[0].set_key_data_iv(keyc.iv());
keys[0].set_key_control(keyc.key_control().key_control_block());
keys[0].set_key_control_iv(keyc.key_control().iv());
keys[0].set_track_label(keyc.track_label());
CdmResponseType result = crypto_session_->LoadKeys(
sm.msg(), sm.signature(), std::string(), std::string(), keys,
std::string());
if (result != KEY_ADDED) {
return result;
}
loaded_keys.insert(keyc.id());
*license.add_key() = keyc;
}
loaded_keys_.swap(loaded_keys);
policy_engine_->UpdateLicenseKeys(license);
return KEY_MESSAGE;
}
bool CdmLicense::RestoreOfflineLicense(
const CdmKeyMessage& license_request,
const CdmKeyResponse& license_response,
@@ -994,8 +1106,7 @@ CdmResponseType CdmLicense::PrepareContentId(
template <typename T>
bool CdmLicense::SetTypeAndId(CdmLicenseType license_type,
const std::string& request_id,
T* content_id) {
const std::string& request_id, T* content_id) {
switch (license_type) {
case kLicenseTypeOffline:
content_id->set_license_type(video_widevine::OFFLINE);