Suppress error for removing lingering offline licenses.
[ Merge of http://go/wvgerrit/97963 ] There are situations where an offline license file will remain on the system after it's usage entry has been deleted. This would result in its key set ID being reported as present by the CDM, but any operations acting upon it will result in an error. The app should be able to remove the license without error, so long as the license file exists and no other OEMCrypto operations fail. This change introduces a new error code LICENSE_USAGE_ENTRY_MISSING, which indicates that a license's usage entry cannot be found. A new integration test checks that the CDM can handle the calls to removeOfflineLicense(). Bug: 137034719 Test: Android unit and integration tests Change-Id: Ibdbe963b7f7e3ac97b446300d8e3896cdee7abc5
This commit is contained in:
@@ -169,10 +169,13 @@ CdmResponseType CdmEngine::OpenKeySetSession(
|
||||
key_set_in_use =
|
||||
release_key_sets_.find(key_set_id) != release_key_sets_.end();
|
||||
}
|
||||
if (key_set_in_use) CloseKeySetSession(key_set_id);
|
||||
if (key_set_in_use) {
|
||||
LOGD("Reopening existing key session");
|
||||
CloseKeySetSession(key_set_id);
|
||||
}
|
||||
|
||||
CdmSessionId session_id;
|
||||
CdmResponseType sts =
|
||||
const CdmResponseType sts =
|
||||
OpenSession(KEY_SYSTEM, property_set, event_listener,
|
||||
nullptr /* forced_session_id */, &session_id);
|
||||
|
||||
@@ -1114,14 +1117,19 @@ CdmResponseType CdmEngine::RemoveOfflineLicense(
|
||||
property_set.set_security_level(
|
||||
security_level == kSecurityLevelL3 ? kLevel3 : kLevelDefault);
|
||||
DeviceFiles handle(file_system_);
|
||||
|
||||
if (!handle.Init(security_level)) {
|
||||
LOGE("Cannot initialize device files: security_level = %s",
|
||||
security_level == kSecurityLevelL3 ? "L3" : "Default");
|
||||
return REMOVE_OFFLINE_LICENSE_ERROR_1;
|
||||
}
|
||||
|
||||
CdmResponseType sts = OpenKeySetSession(key_set_id, &property_set,
|
||||
nullptr /* event listener */);
|
||||
if (sts != NO_ERROR) {
|
||||
if (!handle.Init(security_level)) {
|
||||
LOGE("Cannot initialize device files");
|
||||
}
|
||||
LOGE("Failed to open key set session: status = %d", static_cast<int>(sts));
|
||||
handle.DeleteLicense(key_set_id);
|
||||
return REMOVE_OFFLINE_LICENSE_ERROR_1;
|
||||
return sts;
|
||||
}
|
||||
|
||||
CdmSessionId session_id;
|
||||
@@ -1141,6 +1149,14 @@ CdmResponseType CdmEngine::RemoveOfflineLicense(
|
||||
session_id = iter->second.first;
|
||||
sts = RemoveLicense(session_id);
|
||||
}
|
||||
} else if (sts == LICENSE_USAGE_ENTRY_MISSING) {
|
||||
// It is possible that the CDM is tracking a key set ID, but has
|
||||
// removed the usage information associated with it. In this case,
|
||||
// it will no longer be possible to load the license for release;
|
||||
// and the file should simply be deleted.
|
||||
LOGW("License usage entry is missing, deleting license file");
|
||||
handle.DeleteLicense(key_set_id);
|
||||
sts = NO_ERROR;
|
||||
}
|
||||
|
||||
if (sts != NO_ERROR) {
|
||||
|
||||
@@ -282,6 +282,9 @@ CdmResponseType CdmSession::RestoreOfflineSession(const CdmKeySetId& key_set_id,
|
||||
key_response_, &provider_session_token) ||
|
||||
usage_table_header_ == nullptr) {
|
||||
provider_session_token.clear();
|
||||
} else if (!VerifyOfflineUsageEntry()) {
|
||||
LOGE("License usage entry is invalid, cannot restore");
|
||||
return LICENSE_USAGE_ENTRY_MISSING;
|
||||
} else {
|
||||
CdmResponseType sts = usage_table_header_->LoadEntry(
|
||||
crypto_session_.get(), usage_entry_, usage_entry_number_);
|
||||
@@ -1131,6 +1134,25 @@ void CdmSession::UpdateRequestLatencyTiming(CdmResponseType sts) {
|
||||
license_request_latency_.Clear();
|
||||
}
|
||||
|
||||
bool CdmSession::VerifyOfflineUsageEntry() {
|
||||
// Check that the current license is the same as the expected
|
||||
// entry in the usage table. It is possible that the license has
|
||||
// been removed from the usage table but the license file remains.
|
||||
if (usage_entry_number_ >= usage_table_header_->size()) {
|
||||
LOGD("License usage entry does not exist: entry_number = %u, size = %zu",
|
||||
usage_entry_number_, usage_table_header_->size());
|
||||
return false;
|
||||
}
|
||||
const CdmUsageEntryInfo& usage_entry_info =
|
||||
usage_table_header_->usage_entry_info().at(usage_entry_number_);
|
||||
if (usage_entry_info.storage_type != kStorageLicense ||
|
||||
usage_entry_info.key_set_id != key_set_id_) {
|
||||
LOGD("License usage entry does not match");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// For testing only - takes ownership of pointers
|
||||
|
||||
void CdmSession::set_license_parser(CdmLicense* license_parser) {
|
||||
|
||||
Reference in New Issue
Block a user