Core CDM: Removed secure stop support.
[ Merge of http://go/wvgerrit/158721 ] This CL removes support for secure stop / usage info sessions from the CDM engine and CDM session. APIs for related to secure stop operations will return NOT_IMPLEMENTED_ERROR. New secure stop licenses will be rejected by the CDM when added. Bug: 242289743 Test: run_x86_64_tests request_license_test Change-Id: I30cd47e580d63014e001c903382a28238746f6d4
This commit is contained in:
@@ -78,10 +78,6 @@ CdmSession::CdmSession(wvutil::FileSystem* file_system,
|
||||
is_temporary_(false),
|
||||
security_level_(kSecurityLevelUninitialized),
|
||||
requested_security_level_(kLevelDefault),
|
||||
is_initial_usage_update_(true),
|
||||
is_usage_update_needed_(false),
|
||||
usage_table_header_(nullptr),
|
||||
usage_entry_number_(0),
|
||||
mock_license_parser_in_use_(false),
|
||||
mock_policy_engine_in_use_(false) {
|
||||
assert(metrics_); // metrics_ must not be null.
|
||||
@@ -91,7 +87,7 @@ CdmSession::CdmSession(wvutil::FileSystem* file_system,
|
||||
}
|
||||
|
||||
CdmSession::~CdmSession() {
|
||||
if (has_provider_session_token() && supports_usage_info() && !is_release_) {
|
||||
if (HasUsageEntry() && !is_release_) {
|
||||
UpdateUsageEntryInformation();
|
||||
}
|
||||
|
||||
@@ -269,9 +265,9 @@ CdmResponseType CdmSession::RestoreOfflineSession(const CdmKeySetId& key_set_id,
|
||||
return GET_RELEASED_LICENSE_ERROR;
|
||||
}
|
||||
|
||||
std::string provider_session_token;
|
||||
bool sign_fake_request = false; // TODO(b/169483174): remove this variable.
|
||||
if (supports_usage_info()) {
|
||||
if (SupportsUsageEntries()) {
|
||||
std::string provider_session_token;
|
||||
if (!license_parser_->ExtractProviderSessionToken(
|
||||
key_response_, &provider_session_token)) {
|
||||
provider_session_token.clear();
|
||||
@@ -288,6 +284,7 @@ CdmResponseType CdmSession::RestoreOfflineSession(const CdmKeySetId& key_set_id,
|
||||
IdToString(key_set_id));
|
||||
return USAGE_ENTRY_ALREADY_LOADED;
|
||||
}
|
||||
provider_session_token_ = std::move(provider_session_token);
|
||||
if (sts != NO_ERROR) {
|
||||
LOGE("Failed to load usage entry: status = %d", static_cast<int>(sts));
|
||||
return sts;
|
||||
@@ -296,6 +293,10 @@ CdmResponseType CdmSession::RestoreOfflineSession(const CdmKeySetId& key_set_id,
|
||||
} else {
|
||||
sign_fake_request = true; // TODO(b/169483174): remove this block.
|
||||
}
|
||||
// Must be set before updating the usage entry. CdmLicense will attempt
|
||||
// to update the usage info when restoring.
|
||||
is_offline_ = true;
|
||||
|
||||
// TODO(b/169483174): remove this code in v17. For OEMCrypto v16, an offline
|
||||
// license would not work because the rental clock in OEMCrypto is only
|
||||
// started when the license request is signed. We will sign a fake license
|
||||
@@ -332,7 +333,7 @@ CdmResponseType CdmSession::RestoreOfflineSession(const CdmKeySetId& key_set_id,
|
||||
}
|
||||
}
|
||||
|
||||
if (!provider_session_token.empty() && supports_usage_info()) {
|
||||
if (HasUsageEntry()) {
|
||||
CdmResponseType sts = usage_table_header_->UpdateEntry(
|
||||
usage_entry_number_, crypto_session_.get(), &usage_entry_);
|
||||
if (sts != NO_ERROR) {
|
||||
@@ -340,74 +341,16 @@ CdmResponseType CdmSession::RestoreOfflineSession(const CdmKeySetId& key_set_id,
|
||||
return sts;
|
||||
}
|
||||
if (!StoreLicense(license_data.state, error_detail)) {
|
||||
LOGW("Unable to save updated usage info");
|
||||
LOGW("Unable to save updated license");
|
||||
}
|
||||
}
|
||||
|
||||
license_received_ = true;
|
||||
is_offline_ = true;
|
||||
is_release_ = license_type == kLicenseTypeRelease;
|
||||
has_license_been_restored_ = true;
|
||||
return KEY_ADDED;
|
||||
}
|
||||
|
||||
CdmResponseType CdmSession::RestoreUsageSession(
|
||||
const DeviceFiles::CdmUsageData& usage_data, int* error_detail) {
|
||||
if (!initialized_) {
|
||||
LOGE("CDM session not initialized");
|
||||
return NOT_INITIALIZED_ERROR;
|
||||
}
|
||||
if (!key_set_id_.empty()) {
|
||||
file_handle_->UnreserveLicenseId(key_set_id_);
|
||||
}
|
||||
key_set_id_ = usage_data.key_set_id;
|
||||
key_request_ = usage_data.license_request;
|
||||
key_response_ = usage_data.license;
|
||||
usage_entry_ = usage_data.usage_entry;
|
||||
usage_entry_number_ = usage_data.usage_entry_number;
|
||||
usage_provider_session_token_ = usage_data.provider_session_token;
|
||||
|
||||
CdmResponseType status = LoadPrivateOrLegacyKey(
|
||||
usage_data.drm_certificate, usage_data.wrapped_private_key);
|
||||
if (status != NO_ERROR) return status;
|
||||
|
||||
CdmResponseType sts = NO_ERROR;
|
||||
if (supports_usage_info()) {
|
||||
sts = usage_table_header_->LoadEntry(crypto_session_.get(), usage_entry_,
|
||||
usage_entry_number_);
|
||||
crypto_metrics_->usage_table_header_load_entry_.Increment(sts);
|
||||
if (sts != NO_ERROR) {
|
||||
LOGE("Failed to load usage entry: status = %d", static_cast<int>(sts));
|
||||
return sts;
|
||||
}
|
||||
}
|
||||
|
||||
sts = license_parser_->RestoreLicenseForRelease(usage_data.drm_certificate,
|
||||
key_request_, key_response_);
|
||||
|
||||
if (sts != NO_ERROR) {
|
||||
SetErrorDetail(error_detail, sts);
|
||||
return RELEASE_LICENSE_ERROR_2;
|
||||
}
|
||||
|
||||
if (supports_usage_info()) {
|
||||
sts = usage_table_header_->UpdateEntry(
|
||||
usage_entry_number_, crypto_session_.get(), &usage_entry_);
|
||||
if (sts != NO_ERROR) {
|
||||
LOGE("Failed to update usage entry: status = %d", static_cast<int>(sts));
|
||||
return sts;
|
||||
}
|
||||
if (!UpdateUsageInfo()) {
|
||||
LOGW("Unable to save updated usage info");
|
||||
}
|
||||
}
|
||||
|
||||
license_received_ = true;
|
||||
is_offline_ = false;
|
||||
is_release_ = true;
|
||||
return KEY_ADDED;
|
||||
}
|
||||
|
||||
// This is a thin wrapper that initiates the latency metric.
|
||||
CdmResponseType CdmSession::GenerateKeyRequest(
|
||||
const InitializationData& init_data, CdmLicenseType license_type,
|
||||
@@ -532,19 +475,21 @@ CdmResponseType CdmSession::AddKeyInternal(const CdmKeyResponse& key_response) {
|
||||
// to see if it has a provider session token. If so a new entry needs
|
||||
// to be created.
|
||||
CdmResponseType sts;
|
||||
std::string provider_session_token;
|
||||
if (supports_usage_info()) {
|
||||
if (SupportsUsageEntries()) {
|
||||
std::string provider_session_token;
|
||||
if (license_parser_->ExtractProviderSessionToken(key_response,
|
||||
&provider_session_token) &&
|
||||
!provider_session_token.empty()) {
|
||||
std::string app_id;
|
||||
GetApplicationId(&app_id);
|
||||
if (!is_offline_) {
|
||||
LOGE("CDM does not support secure stop licenses");
|
||||
return ADD_KEY_ERROR;
|
||||
}
|
||||
sts = usage_table_header_->AddEntry(
|
||||
crypto_session_.get(), is_offline_, key_set_id_,
|
||||
DeviceFiles::GetUsageInfoFileName(app_id), key_response,
|
||||
&usage_entry_number_);
|
||||
crypto_session_.get(), /* is_persistent */ true, key_set_id_,
|
||||
/* usage_info_filename */ "", key_response, &usage_entry_number_);
|
||||
crypto_metrics_->usage_table_header_add_entry_.Increment(sts);
|
||||
if (sts != NO_ERROR) return sts;
|
||||
provider_session_token_ = std::move(provider_session_token);
|
||||
}
|
||||
}
|
||||
sts =
|
||||
@@ -557,13 +502,14 @@ CdmResponseType CdmSession::AddKeyInternal(const CdmKeyResponse& key_response) {
|
||||
version_info.license_service_version());
|
||||
|
||||
// Update or invalidate entry if usage table header+entries are supported
|
||||
if (!provider_session_token.empty() && supports_usage_info()) {
|
||||
if (HasUsageEntry()) {
|
||||
if (sts != KEY_ADDED) {
|
||||
const CdmResponseType invalidate_sts =
|
||||
usage_table_header_->InvalidateEntry(
|
||||
usage_entry_number_, true, file_handle_.get(), crypto_metrics_);
|
||||
crypto_metrics_->usage_table_header_delete_entry_.Increment(
|
||||
invalidate_sts);
|
||||
provider_session_token_.clear();
|
||||
if (invalidate_sts != NO_ERROR) {
|
||||
LOGW("Invalidate usage entry failed: status = %d",
|
||||
static_cast<int>(invalidate_sts));
|
||||
@@ -580,15 +526,11 @@ CdmResponseType CdmSession::AddKeyInternal(const CdmKeyResponse& key_response) {
|
||||
IdToString(license_parser_->provider_session_token()),
|
||||
license_parser_->provider_session_token().size());
|
||||
|
||||
if ((is_offline_ || has_provider_session_token()) && !is_temporary_) {
|
||||
if (has_provider_session_token() && supports_usage_info()) {
|
||||
if (is_offline_ && !is_temporary_) {
|
||||
if (HasUsageEntry()) {
|
||||
usage_table_header_->UpdateEntry(usage_entry_number_,
|
||||
crypto_session_.get(), &usage_entry_);
|
||||
}
|
||||
|
||||
if (!is_offline_)
|
||||
usage_provider_session_token_ = license_parser_->provider_session_token();
|
||||
|
||||
sts = StoreLicense();
|
||||
if (sts != NO_ERROR) return sts;
|
||||
}
|
||||
@@ -700,7 +642,7 @@ CdmResponseType CdmSession::Decrypt(const CdmDecryptionParametersV16& params) {
|
||||
}
|
||||
has_decrypted_since_last_report_ = true;
|
||||
if (!is_usage_update_needed_) {
|
||||
is_usage_update_needed_ = has_provider_session_token();
|
||||
is_usage_update_needed_ = HasUsageEntry();
|
||||
}
|
||||
last_decrypt_failed_ = false;
|
||||
} else {
|
||||
@@ -786,7 +728,7 @@ CdmResponseType CdmSession::GenerateReleaseRequest(CdmKeyRequest* key_request) {
|
||||
|
||||
if (KEY_MESSAGE != status) return status;
|
||||
|
||||
if (has_provider_session_token() && supports_usage_info()) {
|
||||
if (HasUsageEntry()) {
|
||||
status = usage_table_header_->UpdateEntry(
|
||||
usage_entry_number_, crypto_session_.get(), &usage_entry_);
|
||||
|
||||
@@ -799,10 +741,6 @@ CdmResponseType CdmSession::GenerateReleaseRequest(CdmKeyRequest* key_request) {
|
||||
if (is_offline_) { // Mark license as being released
|
||||
if (!StoreLicense(kLicenseStateReleasing, nullptr))
|
||||
return RELEASE_KEY_REQUEST_ERROR;
|
||||
} else if (!usage_provider_session_token_.empty()) {
|
||||
if (supports_usage_info()) {
|
||||
if (!UpdateUsageInfo()) return RELEASE_USAGE_INFO_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
key_request_type_ = key_request->type;
|
||||
@@ -833,7 +771,7 @@ CdmResponseType CdmSession::DeleteUsageEntry(uint32_t usage_entry_number) {
|
||||
LOGE("CDM session not initialized");
|
||||
return NOT_INITIALIZED_ERROR;
|
||||
}
|
||||
if (!supports_usage_info()) {
|
||||
if (!SupportsUsageEntries()) {
|
||||
LOGE("Cannot delete entry, usage table not supported");
|
||||
return INCORRECT_USAGE_SUPPORT_TYPE_1;
|
||||
}
|
||||
@@ -862,6 +800,7 @@ CdmResponseType CdmSession::DeleteUsageEntry(uint32_t usage_entry_number) {
|
||||
sts = usage_table_header_->InvalidateEntry(
|
||||
usage_entry_number, true, file_handle_.get(), crypto_metrics_);
|
||||
crypto_metrics_->usage_table_header_delete_entry_.Increment(sts);
|
||||
provider_session_token_.clear();
|
||||
return sts;
|
||||
}
|
||||
|
||||
@@ -908,54 +847,23 @@ bool CdmSession::GenerateKeySetId(bool atsc_mode_enabled,
|
||||
}
|
||||
|
||||
CdmResponseType CdmSession::StoreLicense() {
|
||||
if (is_temporary_) {
|
||||
if (is_temporary_ || !is_offline_) {
|
||||
LOGE("Session type prohibits storage");
|
||||
return STORAGE_PROHIBITED;
|
||||
}
|
||||
|
||||
if (is_offline_) {
|
||||
if (key_set_id_.empty()) {
|
||||
LOGE("No key set ID");
|
||||
return EMPTY_KEYSET_ID;
|
||||
}
|
||||
|
||||
if (!license_parser_->is_offline()) {
|
||||
LOGE("License policy prohibits storage");
|
||||
return OFFLINE_LICENSE_PROHIBITED;
|
||||
}
|
||||
|
||||
if (!StoreLicense(kLicenseStateActive, nullptr)) {
|
||||
LOGE("Unable to store license");
|
||||
return STORE_LICENSE_ERROR_1;
|
||||
}
|
||||
return NO_ERROR;
|
||||
} // if (is_offline_)
|
||||
|
||||
std::string provider_session_token =
|
||||
license_parser_->provider_session_token();
|
||||
if (provider_session_token.empty()) {
|
||||
LOGE("No provider session token and not offline");
|
||||
return STORE_LICENSE_ERROR_2;
|
||||
if (key_set_id_.empty()) {
|
||||
LOGE("No key set ID");
|
||||
return EMPTY_KEYSET_ID;
|
||||
}
|
||||
|
||||
std::string app_id;
|
||||
GetApplicationId(&app_id);
|
||||
if (!file_handle_->StoreUsageInfo(
|
||||
provider_session_token, key_request_, key_response_,
|
||||
DeviceFiles::GetUsageInfoFileName(app_id), key_set_id_, usage_entry_,
|
||||
usage_entry_number_, drm_certificate_, wrapped_private_key_)) {
|
||||
LOGE("Unable to store usage info");
|
||||
// Usage info file is corrupt. Delete current usage entry and file.
|
||||
if (supports_usage_info()) {
|
||||
DeleteUsageEntry(usage_entry_number_);
|
||||
} else {
|
||||
LOGW("Cannot store, usage table not supported");
|
||||
}
|
||||
std::vector<std::string> provider_session_tokens;
|
||||
file_handle_->DeleteAllUsageInfoForApp(
|
||||
DeviceFiles::GetUsageInfoFileName(app_id), &provider_session_tokens);
|
||||
if (!license_parser_->is_offline()) {
|
||||
LOGE("License policy prohibits storage");
|
||||
return OFFLINE_LICENSE_PROHIBITED;
|
||||
}
|
||||
|
||||
return STORE_USAGE_INFO_ERROR;
|
||||
if (!StoreLicense(kLicenseStateActive, nullptr)) {
|
||||
LOGE("Unable to store license");
|
||||
return STORE_LICENSE_ERROR_1;
|
||||
}
|
||||
return NO_ERROR;
|
||||
}
|
||||
@@ -999,8 +907,8 @@ CdmResponseType CdmSession::RemoveKeys() {
|
||||
}
|
||||
|
||||
CdmResponseType CdmSession::RemoveLicense() {
|
||||
if (is_offline_ || has_provider_session_token()) {
|
||||
if (has_provider_session_token() && supports_usage_info()) {
|
||||
if (is_offline_) {
|
||||
if (HasUsageEntry()) {
|
||||
DeleteUsageEntry(usage_entry_number_);
|
||||
}
|
||||
DeleteLicenseFile();
|
||||
@@ -1009,17 +917,8 @@ CdmResponseType CdmSession::RemoveLicense() {
|
||||
}
|
||||
|
||||
bool CdmSession::DeleteLicenseFile() {
|
||||
if (!is_offline_ && !has_provider_session_token()) return false;
|
||||
|
||||
if (is_offline_) {
|
||||
return file_handle_->DeleteLicense(key_set_id_);
|
||||
} else {
|
||||
std::string app_id;
|
||||
GetApplicationId(&app_id);
|
||||
return file_handle_->DeleteUsageInfo(
|
||||
DeviceFiles::GetUsageInfoFileName(app_id),
|
||||
license_parser_->provider_session_token());
|
||||
}
|
||||
if (!is_offline_) return false;
|
||||
return file_handle_->DeleteLicense(key_set_id_);
|
||||
}
|
||||
|
||||
void CdmSession::NotifyResolution(uint32_t width, uint32_t height) {
|
||||
@@ -1050,16 +949,14 @@ void CdmSession::GetApplicationId(std::string* app_id) {
|
||||
}
|
||||
|
||||
CdmResponseType CdmSession::UpdateUsageEntryInformation() {
|
||||
if (!has_provider_session_token() || !supports_usage_info()) {
|
||||
LOGE("Unexpected state: usage_support = %s, PST present = %s, ",
|
||||
supports_usage_info() ? "true" : "false",
|
||||
has_provider_session_token() ? "yes" : "no");
|
||||
if (!HasUsageEntry()) {
|
||||
LOGE("Session does not have a usage entry");
|
||||
return INCORRECT_USAGE_SUPPORT_TYPE_2;
|
||||
}
|
||||
|
||||
CdmResponseType sts = NO_ERROR;
|
||||
// TODO(blueeyes): Add measurements to all UpdateEntry calls in a way that
|
||||
// allos us to isolate this particular use case within
|
||||
// allows us to isolate this particular use case within
|
||||
// UpdateUsageEntryInformation.
|
||||
M_TIME(sts = usage_table_header_->UpdateEntry(
|
||||
usage_entry_number_, crypto_session_.get(), &usage_entry_),
|
||||
@@ -1067,11 +964,8 @@ CdmResponseType CdmSession::UpdateUsageEntryInformation() {
|
||||
|
||||
if (sts != NO_ERROR) return sts;
|
||||
|
||||
if (is_offline_)
|
||||
StoreLicense(is_release_ ? kLicenseStateReleasing : kLicenseStateActive,
|
||||
nullptr);
|
||||
else if (!usage_provider_session_token_.empty())
|
||||
UpdateUsageInfo();
|
||||
StoreLicense(is_release_ ? kLicenseStateReleasing : kLicenseStateActive,
|
||||
nullptr);
|
||||
|
||||
return NO_ERROR;
|
||||
}
|
||||
@@ -1138,23 +1032,6 @@ CdmResponseType CdmSession::GetDecryptHashError(std::string* error_string) {
|
||||
return crypto_session_->GetDecryptHashError(error_string);
|
||||
}
|
||||
|
||||
bool CdmSession::UpdateUsageInfo() {
|
||||
std::string app_id;
|
||||
GetApplicationId(&app_id);
|
||||
|
||||
DeviceFiles::CdmUsageData usage_data;
|
||||
usage_data.provider_session_token = usage_provider_session_token_;
|
||||
usage_data.license_request = key_request_;
|
||||
usage_data.license = key_response_;
|
||||
usage_data.key_set_id = key_set_id_;
|
||||
usage_data.usage_entry = usage_entry_;
|
||||
usage_data.usage_entry_number = usage_entry_number_;
|
||||
|
||||
return file_handle_->UpdateUsageInfo(
|
||||
DeviceFiles::GetUsageInfoFileName(app_id), usage_provider_session_token_,
|
||||
usage_data);
|
||||
}
|
||||
|
||||
void CdmSession::UpdateRequestLatencyTiming(CdmResponseType sts) {
|
||||
if (sts == KEY_ADDED && license_request_latency_.IsStarted()) {
|
||||
metrics_->cdm_session_license_request_latency_ms_.Record(
|
||||
|
||||
Reference in New Issue
Block a user