Allow offline licenses to be loaded and restored in the same session
[ Merge of http://go/wvgerrit/103243 ] In v16, OEMCrypto specifications required that an error be returned if multiple attempts are made to load an offline license into a session. This caused the GTS test testConcurrentDrmCertificates to fail. It was introduced to verify that a license could retrieved and loaded into a session and then restored. This was based on an app use case. Ideally we would like to disallow a this behavior but need to make sure it is not being used by apps. For now this will be allowed. If detected, the CDM will reintialize the OEMCrypto session and allow the license to be restored. Bug: 161551490 Test: WV unit integration tests, GtsMediaTestCases and WidevineConcurrentDrmCertificatesTest#testConcurrentDrmCertificates, MediaDrmTest#testMultipleLoadKeys on a redfin Change-Id: I0834e4419c3a6dccfd77aaea3afa3d65c2c0c742
This commit is contained in:
@@ -111,6 +111,18 @@ CdmResponseType CdmSession::Init(CdmClientPropertySet* cdm_client_property_set,
|
||||
return REINIT_ERROR;
|
||||
}
|
||||
|
||||
// Save parameters in case Init needs to be called again (load and restore
|
||||
// offline license)
|
||||
if (cdm_client_property_set)
|
||||
cdm_client_property_set_ = cdm_client_property_set;
|
||||
|
||||
if (forced_session_id) {
|
||||
forced_session_id_value_ = *forced_session_id;
|
||||
forced_session_id_ = &forced_session_id_value_;
|
||||
}
|
||||
|
||||
if (event_listener) event_listener_ = event_listener;
|
||||
|
||||
if (cdm_client_property_set && cdm_client_property_set->security_level() ==
|
||||
QUERY_VALUE_SECURITY_LEVEL_L3) {
|
||||
requested_security_level_ = kLevel3;
|
||||
@@ -229,6 +241,24 @@ CdmResponseType CdmSession::Init(CdmClientPropertySet* cdm_client_property_set,
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
CdmResponseType CdmSession::ReleaseOfflineResources() {
|
||||
// |license_parser_| and |policy_engine_| are reset in Init. No need to
|
||||
// deallocate here.
|
||||
if (usage_support_type_ == kUsageEntrySupport &&
|
||||
has_provider_session_token() && usage_table_header_ != nullptr &&
|
||||
!is_release_) {
|
||||
UpdateUsageEntryInformation();
|
||||
}
|
||||
|
||||
if (!key_set_id_.empty()) {
|
||||
// Unreserve the license ID.
|
||||
file_handle_->UnreserveLicenseId(key_set_id_);
|
||||
}
|
||||
crypto_session_.reset(CryptoSession::MakeCryptoSession(crypto_metrics_));
|
||||
initialized_ = false;
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
CdmResponseType CdmSession::RestoreOfflineSession(const CdmKeySetId& key_set_id,
|
||||
CdmLicenseType license_type,
|
||||
int* error_detail) {
|
||||
@@ -239,6 +269,31 @@ CdmResponseType CdmSession::RestoreOfflineSession(const CdmKeySetId& key_set_id,
|
||||
if (!key_set_id_.empty()) {
|
||||
file_handle_->UnreserveLicenseId(key_set_id_);
|
||||
}
|
||||
|
||||
// On android, we previously permitted an offline license to be loaded and
|
||||
// restored in the same session. OEMCrypto v16+ disallows it so we need to
|
||||
// release and initialize an OEMCrypto session. We will still prohibit
|
||||
// multiple restore attempts on the same session.
|
||||
// TODO(b/161865160): reevalute this scenario. Should we also
|
||||
// (a) only allow a restore for the same key set ID that was loaded
|
||||
// (b) if (a) is true, indicate success and do nothing else rather than
|
||||
// release resources and reinitialize.
|
||||
// We need to investigate the conditions that caused an app failure and
|
||||
// led us to add a test to support this use case as there were multiple
|
||||
// related issues.
|
||||
if (!has_license_been_loaded_ && has_license_been_restored_) {
|
||||
LOGE("Disallow multiple offline license restores");
|
||||
return RESTORE_OFFLINE_LICENSE_ERROR_3;
|
||||
}
|
||||
|
||||
if (has_license_been_loaded_) {
|
||||
CdmResponseType status = ReleaseOfflineResources();
|
||||
if (status != NO_ERROR) return status;
|
||||
status =
|
||||
Init(cdm_client_property_set_, forced_session_id_, event_listener_);
|
||||
if (status != NO_ERROR) return status;
|
||||
}
|
||||
has_license_been_restored_ = true;
|
||||
key_set_id_ = key_set_id;
|
||||
|
||||
DeviceFiles::CdmLicenseData license_data;
|
||||
@@ -585,6 +640,7 @@ CdmResponseType CdmSession::AddKeyInternal(const CdmKeyResponse& key_response) {
|
||||
sts = StoreLicense();
|
||||
if (sts != NO_ERROR) return sts;
|
||||
}
|
||||
has_license_been_loaded_ = true;
|
||||
|
||||
return KEY_ADDED;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user