Squashed merge 3 CLs.

1. "Change CdmResponseType from enum into a struct"
Merged from http://go/wvgerrit/163199
Bug: 253271674

2. "Log request information when server returns 401"
Bug: 260760387
Bug: 186031735
Merged from http://go/wvgerrit/162798

3. "Specify server version on the command line"
Bug: 251599048
Merged from http://go/wvgerrit/158897

Test: build android.hardware.drm-service.widevine
Test: Netflix and Play Movies & TV
Test: build_and_run_all_unit_tests.sh

Bug: 253271674
Change-Id: I70c950acce070609ee0343920ec68e66b058bc23
This commit is contained in:
Robert Shih
2022-11-16 10:02:18 -08:00
committed by Edwin Wong
parent ac9641ae13
commit 096b0eda5a
46 changed files with 1726 additions and 1443 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -29,7 +29,7 @@
#define RETURN_STATUS_IF_NULL(PARAM) \
if ((PARAM) == nullptr) { \
LOGE("Output parameter |" STRINGIFY(PARAM) "| not provided"); \
return PARAMETER_NULL; \
return CdmResponseType(PARAMETER_NULL); \
}
#define RETURN_FALSE_IF_NULL(PARAM) \
@@ -46,7 +46,7 @@ const size_t kKeySetIdLength = 14;
template <typename T>
void SetErrorDetail(int* error_detail, T error_code) {
if (error_detail != nullptr) {
*error_detail = error_code;
*error_detail = static_cast<int>(error_code);
}
}
@@ -118,7 +118,7 @@ CdmResponseType CdmSession::Init(CdmClientPropertySet* cdm_client_property_set,
bool forced_level3) {
if (initialized_) {
LOGE("Failed due to previous initialization");
return REINIT_ERROR;
return CdmResponseType(REINIT_ERROR);
}
if ((cdm_client_property_set && cdm_client_property_set->security_level() ==
@@ -144,7 +144,7 @@ CdmResponseType CdmSession::Init(CdmClientPropertySet* cdm_client_property_set,
if (!file_handle_->Init(security_level_)) {
LOGE("Unable to initialize file handle");
return SESSION_FILE_HANDLE_INIT_ERROR;
return CdmResponseType(SESSION_FILE_HANDLE_INIT_ERROR);
}
bool has_support = false;
@@ -159,7 +159,7 @@ CdmResponseType CdmSession::Init(CdmClientPropertySet* cdm_client_property_set,
// The actual validation and loading of a certificate will happen when
// a key request is generated or an offline license is loaded.
if (!file_handle_->HasCertificate(atsc_mode_enabled_))
return NEED_PROVISIONING;
return CdmResponseType(NEED_PROVISIONING);
if (forced_session_id) {
key_set_id_ = *forced_session_id;
@@ -178,7 +178,7 @@ CdmResponseType CdmSession::Init(CdmClientPropertySet* cdm_client_property_set,
if (session_id_.empty()) {
LOGE("Empty session ID");
return EMPTY_SESSION_ID;
return CdmResponseType(EMPTY_SESSION_ID);
}
if (cdm_client_property_set)
Properties::AddSessionPropertySet(session_id_, cdm_client_property_set);
@@ -196,13 +196,13 @@ CdmResponseType CdmSession::Init(CdmClientPropertySet* cdm_client_property_set,
if (!license_parser_->Init(Properties::UsePrivacyMode(session_id_),
service_certificate, crypto_session_.get(),
policy_engine_.get()))
return LICENSE_PARSER_INIT_ERROR;
return CdmResponseType(LICENSE_PARSER_INIT_ERROR);
license_received_ = false;
is_initial_decryption_ = true;
initialized_ = true;
closed_ = false;
return NO_ERROR;
return CdmResponseType(NO_ERROR);
}
CdmResponseType CdmSession::RestoreOfflineSession(const CdmKeySetId& key_set_id,
@@ -210,7 +210,7 @@ CdmResponseType CdmSession::RestoreOfflineSession(const CdmKeySetId& key_set_id,
int* error_detail) {
if (!initialized_) {
LOGE("CDM session not initialized");
return NOT_INITIALIZED_ERROR;
return CdmResponseType(NOT_INITIALIZED_ERROR);
}
if (!key_set_id_.empty()) {
file_handle_->UnreserveLicenseId(key_set_id_);
@@ -219,7 +219,7 @@ CdmResponseType CdmSession::RestoreOfflineSession(const CdmKeySetId& key_set_id,
LOGE(
"Disallow multiple offline license restores or restoring a license if "
"a license has already been loaded");
return RESTORE_OFFLINE_LICENSE_ERROR_3;
return CdmResponseType(RESTORE_OFFLINE_LICENSE_ERROR_3);
}
key_set_id_ = key_set_id;
@@ -233,8 +233,9 @@ CdmResponseType CdmSession::RestoreOfflineSession(const CdmKeySetId& key_set_id,
DeviceFiles::ResponseTypeToString(sub_error_code),
IdToString(key_set_id));
SetErrorDetail(error_detail, sub_error_code);
return sub_error_code == DeviceFiles::kFileNotFound ? KEYSET_ID_NOT_FOUND_4
: GET_LICENSE_ERROR;
return sub_error_code == DeviceFiles::kFileNotFound
? CdmResponseType(KEYSET_ID_NOT_FOUND_4)
: CdmResponseType(GET_LICENSE_ERROR);
}
offline_init_data_ = std::move(license_data.pssh_data);
key_request_ = std::move(license_data.license_request);
@@ -266,7 +267,7 @@ CdmResponseType CdmSession::RestoreOfflineSession(const CdmKeySetId& key_set_id,
LOGE("Invalid offline license state: state = %s, license_type = %s",
CdmOfflineLicenseStateToString(license_data.state),
CdmLicenseTypeToString(license_type));
return GET_RELEASED_LICENSE_ERROR;
return CdmResponseType(GET_RELEASED_LICENSE_ERROR);
}
std::string provider_session_token;
@@ -278,7 +279,7 @@ CdmResponseType CdmSession::RestoreOfflineSession(const CdmKeySetId& key_set_id,
sign_fake_request = true; // TODO(b/169483174): remove this line.
} else if (!VerifyOfflineUsageEntry()) {
LOGE("License usage entry is invalid, cannot restore");
return LICENSE_USAGE_ENTRY_MISSING;
return CdmResponseType(LICENSE_USAGE_ENTRY_MISSING);
} else {
CdmResponseType sts = usage_table_header_->LoadEntry(
crypto_session_.get(), usage_entry_, usage_entry_number_);
@@ -286,7 +287,7 @@ CdmResponseType CdmSession::RestoreOfflineSession(const CdmKeySetId& key_set_id,
if (sts == LOAD_USAGE_ENTRY_INVALID_SESSION) {
LOGE("License loaded in different session: key_set_id = %s",
IdToString(key_set_id));
return USAGE_ENTRY_ALREADY_LOADED;
return CdmResponseType(USAGE_ENTRY_ALREADY_LOADED);
}
if (sts != NO_ERROR) {
LOGE("Failed to load usage entry: status = %d", static_cast<int>(sts));
@@ -317,8 +318,8 @@ CdmResponseType CdmSession::RestoreOfflineSession(const CdmKeySetId& key_set_id,
license_data.drm_certificate, key_request_, key_response_);
if (result != NO_ERROR) {
SetErrorDetail(error_detail, result);
return RELEASE_LICENSE_ERROR_1;
SetErrorDetail(error_detail, result.Enum());
return CdmResponseType(RELEASE_LICENSE_ERROR_1);
}
} else {
result = license_parser_->RestoreOfflineLicense(
@@ -327,8 +328,8 @@ CdmResponseType CdmSession::RestoreOfflineSession(const CdmKeySetId& key_set_id,
license_data.last_playback_time, license_data.grace_period_end_time,
this);
if (result != NO_ERROR) {
SetErrorDetail(error_detail, result);
return RESTORE_OFFLINE_LICENSE_ERROR_2;
SetErrorDetail(error_detail, result.Enum());
return CdmResponseType(RESTORE_OFFLINE_LICENSE_ERROR_2);
}
}
@@ -348,14 +349,14 @@ CdmResponseType CdmSession::RestoreOfflineSession(const CdmKeySetId& key_set_id,
is_offline_ = true;
is_release_ = license_type == kLicenseTypeRelease;
has_license_been_restored_ = true;
return KEY_ADDED;
return CdmResponseType(KEY_ADDED);
}
CdmResponseType CdmSession::RestoreUsageSession(
const DeviceFiles::CdmUsageData& usage_data, int* error_detail) {
if (!initialized_) {
LOGE("CDM session not initialized");
return NOT_INITIALIZED_ERROR;
return CdmResponseType(NOT_INITIALIZED_ERROR);
}
if (!key_set_id_.empty()) {
file_handle_->UnreserveLicenseId(key_set_id_);
@@ -371,7 +372,7 @@ CdmResponseType CdmSession::RestoreUsageSession(
usage_data.drm_certificate, usage_data.wrapped_private_key);
if (status != NO_ERROR) return status;
CdmResponseType sts = NO_ERROR;
CdmResponseType sts(NO_ERROR);
if (supports_usage_info()) {
sts = usage_table_header_->LoadEntry(crypto_session_.get(), usage_entry_,
usage_entry_number_);
@@ -387,7 +388,7 @@ CdmResponseType CdmSession::RestoreUsageSession(
if (sts != NO_ERROR) {
SetErrorDetail(error_detail, sts);
return RELEASE_LICENSE_ERROR_2;
return CdmResponseType(RELEASE_LICENSE_ERROR_2);
}
if (supports_usage_info()) {
@@ -405,7 +406,7 @@ CdmResponseType CdmSession::RestoreUsageSession(
license_received_ = true;
is_offline_ = false;
is_release_ = true;
return KEY_ADDED;
return CdmResponseType(KEY_ADDED);
}
// This is a thin wrapper that initiates the latency metric.
@@ -429,7 +430,7 @@ CdmResponseType CdmSession::GenerateKeyRequestInternal(
const CdmAppParameterMap& app_parameters, CdmKeyRequest* key_request) {
if (!initialized_) {
LOGE("CDM session not initialized");
return NOT_INITIALIZED_ERROR;
return CdmResponseType(NOT_INITIALIZED_ERROR);
}
RETURN_STATUS_IF_NULL(key_request);
@@ -457,7 +458,7 @@ CdmResponseType CdmSession::GenerateKeyRequestInternal(
return license_parser_->HandleEmbeddedKeyData(init_data);
default:
LOGE("Unrecognized license type: %d", static_cast<int>(license_type));
return INVALID_LICENSE_TYPE;
return CdmResponseType(INVALID_LICENSE_TYPE);
}
if (is_release_) {
@@ -479,15 +480,15 @@ CdmResponseType CdmSession::GenerateKeyRequestInternal(
if (!init_data.is_supported()) {
LOGW("Unsupported init data type: %s", init_data.type().c_str());
return UNSUPPORTED_INIT_DATA;
return CdmResponseType(UNSUPPORTED_INIT_DATA);
}
if (init_data.IsEmpty() && !license_parser_->HasInitData()) {
LOGW("Init data absent");
return INIT_DATA_NOT_FOUND;
return CdmResponseType(INIT_DATA_NOT_FOUND);
}
if (is_offline_ && key_set_id_.empty()) {
LOGE("Key set ID not set");
return KEY_REQUEST_ERROR_1;
return CdmResponseType(KEY_REQUEST_ERROR_1);
}
// Attempt to load provisioned private key if available.
CdmResponseType status = LoadPrivateKey();
@@ -504,7 +505,7 @@ CdmResponseType CdmSession::GenerateKeyRequestInternal(
offline_init_data_ = init_data.data();
offline_release_server_url_ = key_request->url;
}
return KEY_MESSAGE;
return CdmResponseType(KEY_MESSAGE);
}
// This thin wrapper allows us to update metrics.
@@ -518,12 +519,12 @@ CdmResponseType CdmSession::AddKey(const CdmKeyResponse& key_response) {
CdmResponseType CdmSession::AddKeyInternal(const CdmKeyResponse& key_response) {
if (!initialized_) {
LOGE("Not initialized");
return NOT_INITIALIZED_ERROR;
return CdmResponseType(NOT_INITIALIZED_ERROR);
}
if (is_release_) {
const CdmResponseType sts = ReleaseKey(key_response);
return (sts == NO_ERROR) ? KEY_ADDED : sts;
return (sts == NO_ERROR) ? CdmResponseType(KEY_ADDED) : sts;
}
if (license_received_) { // renewal
return RenewKey(key_response);
@@ -571,7 +572,8 @@ CdmResponseType CdmSession::AddKeyInternal(const CdmKeyResponse& key_response) {
}
}
if (sts != KEY_ADDED) return (sts == KEY_ERROR) ? ADD_KEY_ERROR : sts;
if (sts != KEY_ADDED)
return (sts == KEY_ERROR) ? CdmResponseType(ADD_KEY_ERROR) : sts;
license_received_ = true;
key_response_ = key_response;
@@ -594,13 +596,13 @@ CdmResponseType CdmSession::AddKeyInternal(const CdmKeyResponse& key_response) {
}
has_license_been_loaded_ = true;
return KEY_ADDED;
return CdmResponseType(KEY_ADDED);
}
CdmResponseType CdmSession::QueryStatus(CdmQueryMap* query_response) {
if (!initialized_) {
LOGE("CDM session not initialized");
return NOT_INITIALIZED_ERROR;
return CdmResponseType(NOT_INITIALIZED_ERROR);
}
RETURN_STATUS_IF_NULL(query_response);
@@ -623,9 +625,9 @@ CdmResponseType CdmSession::QueryStatus(CdmQueryMap* query_response) {
QUERY_VALUE_SECURITY_LEVEL_UNKNOWN;
break;
default:
return INVALID_QUERY_KEY;
return CdmResponseType(INVALID_QUERY_KEY);
}
return NO_ERROR;
return CdmResponseType(NO_ERROR);
}
CdmResponseType CdmSession::SetServiceCertificate(
@@ -646,19 +648,19 @@ CdmResponseType CdmSession::QueryOemCryptoSessionId(
CdmQueryMap* query_response) {
if (!initialized_) {
LOGE("CDM session not initialized");
return NOT_INITIALIZED_ERROR;
return CdmResponseType(NOT_INITIALIZED_ERROR);
}
RETURN_STATUS_IF_NULL(query_response);
(*query_response)[QUERY_KEY_OEMCRYPTO_SESSION_ID] =
std::to_string(crypto_session_->oec_session_id());
return NO_ERROR;
return CdmResponseType(NO_ERROR);
}
// Decrypt() - Accept encrypted buffer and return decrypted data.
CdmResponseType CdmSession::Decrypt(const CdmDecryptionParametersV16& params) {
if (!initialized_) {
return NOT_INITIALIZED_ERROR;
return CdmResponseType(NOT_INITIALIZED_ERROR);
}
bool is_protected = std::any_of(
@@ -677,18 +679,19 @@ CdmResponseType CdmSession::Decrypt(const CdmDecryptionParametersV16& params) {
// the security level is not high enough yet.
if (is_protected) {
if (!policy_engine_->CanDecryptContent(params.key_id)) {
if (policy_engine_->IsLicenseForFuture()) return DECRYPT_NOT_READY;
if (policy_engine_->IsLicenseForFuture())
return CdmResponseType(DECRYPT_NOT_READY);
if (!policy_engine_->IsSufficientOutputProtection(params.key_id)) {
LOGE("Key use prohibited as HDCP or resolution requirements not met");
return INSUFFICIENT_OUTPUT_PROTECTION;
return CdmResponseType(INSUFFICIENT_OUTPUT_PROTECTION);
}
return NEED_KEY;
return CdmResponseType(NEED_KEY);
}
if (!policy_engine_->CanUseKeyForSecurityLevel(params.key_id)) {
LOGE(
"Key use prohibited as security level requirements in the policy"
" not met");
return KEY_PROHIBITED_FOR_SECURITY_LEVEL;
return CdmResponseType(KEY_PROHIBITED_FOR_SECURITY_LEVEL);
}
}
@@ -715,7 +718,7 @@ CdmResponseType CdmSession::Decrypt(const CdmDecryptionParametersV16& params) {
const int64_t current_time = clock.GetCurrentTime();
if (policy_engine_->HasLicenseOrRentalOrPlaybackDurationExpired(
current_time)) {
return NEED_KEY;
return CdmResponseType(NEED_KEY);
}
}
@@ -728,7 +731,7 @@ CdmResponseType CdmSession::Decrypt(const CdmDecryptionParametersV16& params) {
CdmResponseType CdmSession::GenerateRenewalRequest(CdmKeyRequest* key_request) {
if (!initialized_) {
LOGE("CDM session not initialized");
return NOT_INITIALIZED_ERROR;
return CdmResponseType(NOT_INITIALIZED_ERROR);
}
RETURN_STATUS_IF_NULL(key_request);
@@ -744,14 +747,14 @@ CdmResponseType CdmSession::GenerateRenewalRequest(CdmKeyRequest* key_request) {
}
key_request_type_ = key_request->type;
license_request_latency_.Start(); // Start or restart timer.
return KEY_MESSAGE;
return CdmResponseType(KEY_MESSAGE);
}
// RenewKey() - Accept renewal response and update key info.
CdmResponseType CdmSession::RenewKey(const CdmKeyResponse& key_response) {
if (!initialized_) {
LOGE("CDM session not initialized");
return NOT_INITIALIZED_ERROR;
return CdmResponseType(NOT_INITIALIZED_ERROR);
}
CdmResponseType sts = license_parser_->HandleKeyUpdateResponse(
/* is renewal */ true,
@@ -760,20 +763,21 @@ CdmResponseType CdmSession::RenewKey(const CdmKeyResponse& key_response) {
// Record the timing on success.
UpdateRequestLatencyTiming(sts);
if (sts != KEY_ADDED) return (sts == KEY_ERROR) ? RENEW_KEY_ERROR_1 : sts;
if (sts != KEY_ADDED)
return (sts == KEY_ERROR) ? CdmResponseType(RENEW_KEY_ERROR_1) : sts;
if (is_offline_) {
offline_key_renewal_response_ = key_response;
if (!StoreLicense(kLicenseStateActive, nullptr /* error_detail */))
return RENEW_KEY_ERROR_2;
return CdmResponseType(RENEW_KEY_ERROR_2);
}
return KEY_ADDED;
return CdmResponseType(KEY_ADDED);
}
CdmResponseType CdmSession::GenerateReleaseRequest(CdmKeyRequest* key_request) {
if (!initialized_) {
LOGE("CDM session not initialized");
return NOT_INITIALIZED_ERROR;
return CdmResponseType(NOT_INITIALIZED_ERROR);
}
RETURN_STATUS_IF_NULL(key_request);
is_release_ = true;
@@ -798,24 +802,24 @@ CdmResponseType CdmSession::GenerateReleaseRequest(CdmKeyRequest* key_request) {
if (is_offline_) { // Mark license as being released
if (!StoreLicense(kLicenseStateReleasing, nullptr))
return RELEASE_KEY_REQUEST_ERROR;
return CdmResponseType(RELEASE_KEY_REQUEST_ERROR);
} else if (!usage_provider_session_token_.empty()) {
if (supports_usage_info()) {
if (!UpdateUsageInfo()) return RELEASE_USAGE_INFO_FAILED;
if (!UpdateUsageInfo()) return CdmResponseType(RELEASE_USAGE_INFO_FAILED);
}
}
key_request_type_ = key_request->type;
license_request_latency_.Start(); // Start or restart timer.
return KEY_MESSAGE;
return CdmResponseType(KEY_MESSAGE);
}
// ReleaseKey() - Accept release response and release license.
CdmResponseType CdmSession::ReleaseKey(const CdmKeyResponse& key_response) {
if (!initialized_) {
LOGE("CDM session not initialized");
return NOT_INITIALIZED_ERROR;
return CdmResponseType(NOT_INITIALIZED_ERROR);
}
CdmResponseType sts = license_parser_->HandleKeyUpdateResponse(
/* is renewal */ false,
@@ -823,7 +827,8 @@ CdmResponseType CdmSession::ReleaseKey(const CdmKeyResponse& key_response) {
// Record the timing on success.
UpdateRequestLatencyTiming(sts);
if (sts != KEY_ADDED) return (sts == KEY_ERROR) ? RELEASE_KEY_ERROR : sts;
if (sts != KEY_ADDED)
return (sts == KEY_ERROR) ? CdmResponseType(RELEASE_KEY_ERROR) : sts;
return RemoveLicense();
}
@@ -831,11 +836,11 @@ CdmResponseType CdmSession::ReleaseKey(const CdmKeyResponse& key_response) {
CdmResponseType CdmSession::DeleteUsageEntry(uint32_t usage_entry_number) {
if (!initialized_) {
LOGE("CDM session not initialized");
return NOT_INITIALIZED_ERROR;
return CdmResponseType(NOT_INITIALIZED_ERROR);
}
if (!supports_usage_info()) {
LOGE("Cannot delete entry, usage table not supported");
return INCORRECT_USAGE_SUPPORT_TYPE_1;
return CdmResponseType(INCORRECT_USAGE_SUPPORT_TYPE_1);
}
// The usage entry cannot be deleted if it has a crypto session handling
@@ -856,7 +861,7 @@ CdmResponseType CdmSession::DeleteUsageEntry(uint32_t usage_entry_number) {
if (usage_table_header_ == nullptr) {
LOGE("Usage table header unavailable");
return INCORRECT_USAGE_SUPPORT_TYPE_1;
return CdmResponseType(INCORRECT_USAGE_SUPPORT_TYPE_1);
}
sts = usage_table_header_->InvalidateEntry(
@@ -910,32 +915,32 @@ bool CdmSession::GenerateKeySetId(bool atsc_mode_enabled,
CdmResponseType CdmSession::StoreLicense() {
if (is_temporary_) {
LOGE("Session type prohibits storage");
return STORAGE_PROHIBITED;
return CdmResponseType(STORAGE_PROHIBITED);
}
if (is_offline_) {
if (key_set_id_.empty()) {
LOGE("No key set ID");
return EMPTY_KEYSET_ID;
return CdmResponseType(EMPTY_KEYSET_ID);
}
if (!license_parser_->is_offline()) {
LOGE("License policy prohibits storage");
return OFFLINE_LICENSE_PROHIBITED;
return CdmResponseType(OFFLINE_LICENSE_PROHIBITED);
}
if (!StoreLicense(kLicenseStateActive, nullptr)) {
LOGE("Unable to store license");
return STORE_LICENSE_ERROR_1;
return CdmResponseType(STORE_LICENSE_ERROR_1);
}
return NO_ERROR;
return CdmResponseType(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;
return CdmResponseType(STORE_LICENSE_ERROR_2);
}
std::string app_id;
@@ -955,9 +960,9 @@ CdmResponseType CdmSession::StoreLicense() {
file_handle_->DeleteAllUsageInfoForApp(
DeviceFiles::GetUsageInfoFileName(app_id), &provider_session_tokens);
return STORE_USAGE_INFO_ERROR;
return CdmResponseType(STORE_USAGE_INFO_ERROR);
}
return NO_ERROR;
return CdmResponseType(NO_ERROR);
}
bool CdmSession::StoreLicense(CdmOfflineLicenseState state, int* error_detail) {
@@ -995,7 +1000,7 @@ CdmResponseType CdmSession::RemoveKeys() {
crypto_metrics_, crypto_session_open_, sts, requested_security_level_);
policy_engine_.reset(
new PolicyEngine(session_id_, nullptr, crypto_session_.get()));
return NO_ERROR;
return CdmResponseType(NO_ERROR);
}
CdmResponseType CdmSession::RemoveLicense() {
@@ -1005,7 +1010,7 @@ CdmResponseType CdmSession::RemoveLicense() {
}
DeleteLicenseFile();
}
return NO_ERROR;
return CdmResponseType(NO_ERROR);
}
bool CdmSession::DeleteLicenseFile() {
@@ -1054,10 +1059,10 @@ CdmResponseType CdmSession::UpdateUsageEntryInformation() {
LOGE("Unexpected state: usage_support = %s, PST present = %s, ",
supports_usage_info() ? "true" : "false",
has_provider_session_token() ? "yes" : "no");
return INCORRECT_USAGE_SUPPORT_TYPE_2;
return CdmResponseType(INCORRECT_USAGE_SUPPORT_TYPE_2);
}
CdmResponseType sts = NO_ERROR;
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
// UpdateUsageEntryInformation.
@@ -1073,7 +1078,7 @@ CdmResponseType CdmSession::UpdateUsageEntryInformation() {
else if (!usage_provider_session_token_.empty())
UpdateUsageInfo();
return NO_ERROR;
return CdmResponseType(NO_ERROR);
}
CdmResponseType CdmSession::GenericEncrypt(const std::string& in_buffer,
@@ -1190,7 +1195,7 @@ CdmResponseType CdmSession::LoadPrivateKey() {
if (file_handle_->RetrieveCertificate(atsc_mode_enabled_, &drm_certificate,
&private_key, nullptr, &system_id) !=
DeviceFiles::kCertificateValid) {
return NEED_PROVISIONING;
return CdmResponseType(NEED_PROVISIONING);
}
return LoadPrivateKey(drm_certificate, private_key);
@@ -1208,7 +1213,7 @@ CdmResponseType CdmSession::LoadPrivateOrLegacyKey(
if (file_handle_->RetrieveLegacyCertificate(
&drm_certificate, &wrapped_private_key, nullptr, nullptr) !=
DeviceFiles::kCertificateValid)
return NEED_PROVISIONING;
return CdmResponseType(NEED_PROVISIONING);
return LoadPrivateKey(drm_certificate, wrapped_private_key);
}
@@ -1221,19 +1226,19 @@ CdmResponseType CdmSession::LoadPrivateKey(
crypto_metrics_, crypto_session_load_certificate_private_key_,
load_cert_sts);
switch (load_cert_sts) {
switch (load_cert_sts.Enum()) {
case NO_ERROR:
metrics_->drm_certificate_key_type_.Record(
DrmKeyTypeToMetricValue(private_key.type()));
drm_certificate_ = drm_certificate;
wrapped_private_key_ = std::move(private_key);
return NO_ERROR;
return CdmResponseType(NO_ERROR);
case SESSION_LOST_STATE_ERROR:
case SYSTEM_INVALIDATED_ERROR:
return load_cert_sts;
default:
return NEED_PROVISIONING;
return CdmResponseType(NEED_PROVISIONING);
}
}

View File

@@ -123,7 +123,7 @@ CdmResponseType CertificateProvisioning::SetSpoidParameter(
ProvisioningRequest* request) {
if (!request) {
LOGE("Output parameter |request| is not provided");
return PARAMETER_NULL;
return CdmResponseType(PARAMETER_NULL);
}
if (!spoid.empty()) {
// Use the SPOID that has been pre-provided
@@ -133,7 +133,7 @@ CdmResponseType CertificateProvisioning::SetSpoidParameter(
LOGE(
"Failed to set provider ID: "
"Service certificate provider ID is empty");
return SERVICE_CERTIFICATE_PROVIDER_ID_EMPTY;
return CdmResponseType(SERVICE_CERTIFICATE_PROVIDER_ID_EMPTY);
}
request->set_provider_id(service_certificate_->provider_id());
} else if (origin != EMPTY_ORIGIN) {
@@ -149,7 +149,7 @@ CdmResponseType CertificateProvisioning::SetSpoidParameter(
}
request->set_stable_id(device_unique_id + origin);
} // No else clause, by design. It is valid to do nothing.
return NO_ERROR;
return CdmResponseType(NO_ERROR);
}
// Return the provisioning protocol version - dictated by OEMCrypto
@@ -191,7 +191,7 @@ CdmResponseType CertificateProvisioning::GetProvisioningRequestInternal(
if (!request || !default_url) {
LOGE("Output parameter |%s| is not provided",
request ? "default_url" : "request");
return CERT_PROVISIONING_REQUEST_ERROR_1;
return CdmResponseType(CERT_PROVISIONING_REQUEST_ERROR_1);
}
default_url->assign(kProvisioningServerUrl);
@@ -223,7 +223,7 @@ CdmResponseType CertificateProvisioning::GetProvisioningRequestInternal(
if (status != NO_ERROR) {
LOGE("Failed to generate a nonce: status = %d", static_cast<int>(status));
return status == NONCE_GENERATION_ERROR
? CERT_PROVISIONING_NONCE_GENERATION_ERROR
? CdmResponseType(CERT_PROVISIONING_NONCE_GENERATION_ERROR)
: status;
}
@@ -243,7 +243,7 @@ CdmResponseType CertificateProvisioning::GetProvisioningRequestInternal(
break;
default:
LOGE("Unknown certificate type: %d", static_cast<int>(cert_type));
return CERT_PROVISIONING_INVALID_CERT_TYPE;
return CdmResponseType(CERT_PROVISIONING_INVALID_CERT_TYPE);
}
cert_type_ = cert_type;
@@ -269,7 +269,7 @@ CdmResponseType CertificateProvisioning::GetProvisioningRequestInternal(
if (request_signature.empty()) {
LOGE("Request signature is empty");
return CERT_PROVISIONING_REQUEST_ERROR_4;
return CdmResponseType(CERT_PROVISIONING_REQUEST_ERROR_4);
}
SignedProvisioningMessage signed_provisioning_msg;
@@ -289,7 +289,7 @@ CdmResponseType CertificateProvisioning::GetProvisioningRequestInternal(
} else {
*request = std::move(serialized_request);
}
return NO_ERROR;
return CdmResponseType(NO_ERROR);
}
CdmResponseType CertificateProvisioning::GetProvisioning40RequestInternal(
@@ -298,19 +298,19 @@ CdmResponseType CertificateProvisioning::GetProvisioning40RequestInternal(
std::string* default_url) {
if (!crypto_session_->IsOpen()) {
LOGE("Crypto session is not open");
return PROVISIONING_4_CRYPTO_SESSION_NOT_OPEN;
return CdmResponseType(PROVISIONING_4_CRYPTO_SESSION_NOT_OPEN);
}
if (file_system == nullptr) {
LOGE("file_system is nullptr but is required in provisioning 4");
return PROVISIONING_4_FILE_SYSTEM_IS_NULL;
return CdmResponseType(PROVISIONING_4_FILE_SYSTEM_IS_NULL);
}
const CdmSecurityLevel security_level = crypto_session_->GetSecurityLevel();
wvutil::FileSystem global_file_system;
DeviceFiles global_file_handle(&global_file_system);
if (!global_file_handle.Init(security_level)) {
LOGE("Failed to initialize global DeviceFiles");
return PROVISIONING_4_FAILED_TO_INITIALIZE_DEVICE_FILES;
return CdmResponseType(PROVISIONING_4_FAILED_TO_INITIALIZE_DEVICE_FILES);
}
ProvisioningRequest provisioning_request;
@@ -415,7 +415,7 @@ CdmResponseType CertificateProvisioning::GetProvisioning40RequestInternal(
} else {
*request = std::move(serialized_request);
}
return NO_ERROR;
return CdmResponseType(NO_ERROR);
}
CdmResponseType CertificateProvisioning::FillEncryptedClientId(
@@ -433,7 +433,7 @@ CertificateProvisioning::FillEncryptedClientIdWithAdditionalParameter(
ProvisioningRequest& provisioning_request,
const ServiceCertificate& service_certificate) {
if (!crypto_session_->IsOpen()) {
return UNKNOWN_ERROR;
return CdmResponseType(UNKNOWN_ERROR);
}
wvcdm::ClientIdentification id;
@@ -447,7 +447,7 @@ CertificateProvisioning::FillEncryptedClientIdWithAdditionalParameter(
if (!service_certificate.has_certificate()) {
LOGE("Service certificate not staged");
return CERT_PROVISIONING_EMPTY_SERVICE_CERTIFICATE;
return CdmResponseType(CERT_PROVISIONING_EMPTY_SERVICE_CERTIFICATE);
}
// Encrypt client identification
@@ -461,7 +461,7 @@ CdmResponseType CertificateProvisioning::HandleProvisioning40Response(
ProvisioningResponse provisioning_response;
if (response_message.empty() ||
!provisioning_response.ParseFromString(response_message)) {
return PROVISIONING_4_RESPONSE_FAILED_TO_PARSE_MESSAGE;
return CdmResponseType(PROVISIONING_4_RESPONSE_FAILED_TO_PARSE_MESSAGE);
}
if (provisioning_response.has_status() &&
provisioning_response.status() != ProvisioningResponse::NO_ERROR) {
@@ -469,9 +469,9 @@ CdmResponseType CertificateProvisioning::HandleProvisioning40Response(
switch (provisioning_response.status()) {
case ProvisioningResponse::REVOKED_DEVICE_CREDENTIALS:
case ProvisioningResponse::REVOKED_DEVICE_SERIES:
return DEVICE_REVOKED;
return CdmResponseType(DEVICE_REVOKED);
default:
return PROVISIONING_4_RESPONSE_HAS_ERROR_STATUS;
return CdmResponseType(PROVISIONING_4_RESPONSE_HAS_ERROR_STATUS);
}
}
@@ -479,12 +479,12 @@ CdmResponseType CertificateProvisioning::HandleProvisioning40Response(
provisioning_response.device_certificate();
if (device_certificate.empty()) {
LOGE("Provisioning response has no certificate");
return PROVISIONING_4_RESPONSE_HAS_NO_CERTIFICATE;
return CdmResponseType(PROVISIONING_4_RESPONSE_HAS_NO_CERTIFICATE);
}
if (provisioning_40_wrapped_private_key_.empty()) {
LOGE("No private key was generated");
return PROVISIONING_4_NO_PRIVATE_KEY;
return CdmResponseType(PROVISIONING_4_NO_PRIVATE_KEY);
}
const CryptoWrappedKey private_key(provisioning_40_key_type_,
provisioning_40_wrapped_private_key_);
@@ -495,7 +495,7 @@ CdmResponseType CertificateProvisioning::HandleProvisioning40Response(
DeviceFiles global_file_handle(&global_file_system);
if (!global_file_handle.Init(security_level)) {
LOGE("Failed to initialize global DeviceFiles");
return PROVISIONING_4_FAILED_TO_INITIALIZE_DEVICE_FILES_2;
return CdmResponseType(PROVISIONING_4_FAILED_TO_INITIALIZE_DEVICE_FILES_2);
}
// Check the stage of the provisioning by checking if an OEM cert is already
@@ -505,23 +505,24 @@ CdmResponseType CertificateProvisioning::HandleProvisioning40Response(
if (!global_file_handle.StoreOemCertificate(device_certificate,
private_key)) {
LOGE("Failed to store provisioning 4 OEM certificate");
return PROVISIONING_4_FAILED_TO_STORE_OEM_CERTIFICATE;
return CdmResponseType(PROVISIONING_4_FAILED_TO_STORE_OEM_CERTIFICATE);
}
} else {
// The response is assumed to be an DRM cert.
DeviceFiles per_origin_file_handle(file_system);
if (!per_origin_file_handle.Init(security_level)) {
LOGE("Failed to initialize per-origin DeviceFiles");
return PROVISIONING_4_FAILED_TO_INITIALIZE_DEVICE_FILES_3;
return CdmResponseType(
PROVISIONING_4_FAILED_TO_INITIALIZE_DEVICE_FILES_3);
}
if (!per_origin_file_handle.StoreCertificate(device_certificate,
private_key)) {
LOGE("Failed to store provisioning 4 DRM certificate");
return PROVISIONING_4_FAILED_TO_STORE_DRM_CERTIFICATE;
return CdmResponseType(PROVISIONING_4_FAILED_TO_STORE_DRM_CERTIFICATE);
}
}
return NO_ERROR;
return CdmResponseType(NO_ERROR);
}
// The response message consists of a device certificate and the
@@ -537,7 +538,7 @@ CdmResponseType CertificateProvisioning::HandleProvisioningResponse(
std::string* wrapped_key) {
if (response_message.empty()) {
LOGE("Provisioning response message is empty");
return CERT_PROVISIONING_RESPONSE_ERROR_1;
return CdmResponseType(CERT_PROVISIONING_RESPONSE_ERROR_1);
}
std::string response;
@@ -551,7 +552,7 @@ CdmResponseType CertificateProvisioning::HandleProvisioningResponse(
if (!result || response.empty()) {
LOGE("Provisioning response message is an invalid JSON/base64 string: %s",
response.c_str());
return CERT_PROVISIONING_RESPONSE_ERROR_1;
return CdmResponseType(CERT_PROVISIONING_RESPONSE_ERROR_1);
}
}
@@ -561,7 +562,7 @@ CdmResponseType CertificateProvisioning::HandleProvisioningResponse(
SignedProvisioningMessage signed_response;
if (!signed_response.ParseFromString(response)) {
LOGE("Failed to parse signed provisioining response");
return CERT_PROVISIONING_RESPONSE_ERROR_2;
return CdmResponseType(CERT_PROVISIONING_RESPONSE_ERROR_2);
}
if (signed_response.provisioning_type() ==
@@ -585,7 +586,7 @@ CdmResponseType CertificateProvisioning::HandleProvisioningResponse(
error = true;
}
if (error) return CERT_PROVISIONING_RESPONSE_ERROR_3;
if (error) return CdmResponseType(CERT_PROVISIONING_RESPONSE_ERROR_3);
const std::string& signed_message = signed_response.message();
const std::string& signature = signed_response.signature();
@@ -594,7 +595,7 @@ CdmResponseType CertificateProvisioning::HandleProvisioningResponse(
ProvisioningResponse provisioning_response;
if (!provisioning_response.ParseFromString(signed_message)) {
LOGE("Failed to parse provisioning response");
return CERT_PROVISIONING_RESPONSE_ERROR_4;
return CdmResponseType(CERT_PROVISIONING_RESPONSE_ERROR_4);
}
if (provisioning_response.has_status()) {
@@ -607,9 +608,9 @@ CdmResponseType CertificateProvisioning::HandleProvisioningResponse(
break;
case ProvisioningResponse::REVOKED_DEVICE_CREDENTIALS:
case ProvisioningResponse::REVOKED_DEVICE_SERIES:
return DEVICE_REVOKED;
return CdmResponseType(DEVICE_REVOKED);
default:
return CERT_PROVISIONING_RESPONSE_ERROR_10;
return CdmResponseType(CERT_PROVISIONING_RESPONSE_ERROR_10);
}
}
@@ -632,19 +633,19 @@ CdmResponseType CertificateProvisioning::HandleProvisioningResponse(
if (cert_type_ == kCertificateX509) {
*cert = device_cert_data;
*wrapped_key = private_key.key();
return NO_ERROR;
return CdmResponseType(NO_ERROR);
}
// Need to parse cert for key type.
SignedDrmCertificate signed_device_cert;
if (!signed_device_cert.ParseFromString(device_cert_data)) {
LOGE("Failed to parse signed DRM certificate");
return CERT_PROVISIONING_RESPONSE_ERROR_9;
return CdmResponseType(CERT_PROVISIONING_RESPONSE_ERROR_9);
}
DrmCertificate device_cert;
if (!device_cert.ParseFromString(signed_device_cert.drm_certificate())) {
LOGE("Failed to parse DRM certificate");
return CERT_PROVISIONING_RESPONSE_ERROR_9;
return CdmResponseType(CERT_PROVISIONING_RESPONSE_ERROR_9);
}
if (!device_cert.has_algorithm()) {
LOGW("DRM certificate does not specify algorithm type, assuming RSA");
@@ -662,7 +663,7 @@ CdmResponseType CertificateProvisioning::HandleProvisioningResponse(
default:
LOGE("Unknown DRM key type: algorithm = %d",
static_cast<int>(device_cert.algorithm()));
return CERT_PROVISIONING_RESPONSE_ERROR_9;
return CdmResponseType(CERT_PROVISIONING_RESPONSE_ERROR_9);
}
}
@@ -671,14 +672,14 @@ CdmResponseType CertificateProvisioning::HandleProvisioningResponse(
DeviceFiles handle(file_system);
if (!handle.Init(security_level)) {
LOGE("Failed to initialize DeviceFiles");
return CERT_PROVISIONING_RESPONSE_ERROR_7;
return CdmResponseType(CERT_PROVISIONING_RESPONSE_ERROR_7);
}
if (!handle.StoreCertificate(device_cert_data, private_key)) {
LOGE("Failed to store provisioning certificate");
return CERT_PROVISIONING_RESPONSE_ERROR_8;
return CdmResponseType(CERT_PROVISIONING_RESPONSE_ERROR_8);
}
return NO_ERROR;
return CdmResponseType(NO_ERROR);
}
// Provisioning response is a base64-encoded protobuf, optionally within a

View File

@@ -72,39 +72,39 @@ CdmResponseType ClientIdentification::InitForProvisioningRequest(
const std::string& client_token, CryptoSession* crypto_session) {
if (crypto_session == nullptr) {
LOGE("Crypto session not provided");
return PARAMETER_NULL;
return CdmResponseType(PARAMETER_NULL);
}
is_license_request_ = false;
client_token_ = client_token;
crypto_session_ = crypto_session;
return NO_ERROR;
return CdmResponseType(NO_ERROR);
}
CdmResponseType ClientIdentification::InitForLicenseRequest(
const std::string& client_token, CryptoSession* crypto_session) {
if (crypto_session == nullptr) {
LOGE("Crypto session not provided");
return PARAMETER_NULL;
return CdmResponseType(PARAMETER_NULL);
}
if (client_token.empty()) {
LOGE("Client token is empty");
return PARAMETER_NULL;
return CdmResponseType(PARAMETER_NULL);
}
is_license_request_ = true;
client_token_ = client_token;
crypto_session_ = crypto_session;
return NO_ERROR;
return CdmResponseType(NO_ERROR);
}
CdmResponseType ClientIdentification::InitForOtaKeyboxProvisioning(
CryptoSession* crypto_session) {
if (crypto_session == nullptr) {
LOGE("Crypto session not provided");
return PARAMETER_NULL;
return CdmResponseType(PARAMETER_NULL);
}
is_okp_request_ = true;
crypto_session_ = crypto_session;
return NO_ERROR;
return CdmResponseType(NO_ERROR);
}
/*
@@ -131,7 +131,7 @@ CdmResponseType ClientIdentification::Prepare(
video_widevine::ClientIdentification::TokenType token_type;
if (!GetProvisioningTokenType(&token_type)) {
LOGE("Failed to get provisioning token type");
return CLIENT_IDENTIFICATION_TOKEN_ERROR_1;
return CdmResponseType(CLIENT_IDENTIFICATION_TOKEN_ERROR_1);
}
client_id->set_type(token_type);
@@ -140,8 +140,7 @@ CdmResponseType ClientIdentification::Prepare(
CdmResponseType status =
crypto_session_->GetProvisioningToken(&token, &additional_token);
if (status != NO_ERROR) {
LOGE("Failed to get provisioning token: status = %d",
static_cast<int>(status));
LOGE("Failed to get provisioning token: status = %d", status.Enum());
return status;
}
client_id->set_token(token);
@@ -221,7 +220,7 @@ CdmResponseType ClientIdentification::Prepare(
if (is_okp_request_) {
// Capabilities is not important for OTA keybox provisionining.
return NO_ERROR;
return CdmResponseType(NO_ERROR);
}
ClientCapabilities* client_capabilities =
@@ -365,7 +364,7 @@ CdmResponseType ClientIdentification::Prepare(
}
}
return NO_ERROR;
return CdmResponseType(NO_ERROR);
}
bool ClientIdentification::GetProvisioningTokenType(

View File

@@ -33,22 +33,36 @@
// Example: STRINGIFY(this_argument) -> "this_argument"
#define STRINGIFY(PARAM) #PARAM
namespace {
bool WrapIfNecessary(bool ret_value) { return ret_value; }
wvcdm::CdmResponseType WrapIfNecessary(wvcdm::CdmResponseEnum ret_value) {
return wvcdm::CdmResponseType(ret_value);
}
wvcdm::CdmSecurityLevel WrapIfNecessary(wvcdm::CdmSecurityLevel ret_value) {
return ret_value;
}
OEMCryptoResult WrapIfNecessary(OEMCryptoResult ret_value) { return ret_value; }
} // namespace
#define RETURN_IF_NULL(PARAM, ret_value) \
if ((PARAM) == nullptr) { \
LOGE("Output parameter |" STRINGIFY(PARAM) "| not provided"); \
return ret_value; \
return WrapIfNecessary(ret_value); \
}
#define RETURN_IF_UNINITIALIZED(ret_value) \
if (!IsInitialized()) { \
LOGE("Crypto session is not initialized"); \
return ret_value; \
return WrapIfNecessary(ret_value); \
}
#define RETURN_IF_NOT_OPEN(ret_value) \
if (!open_) { \
LOGE("Crypto session is not open"); \
return ret_value; \
return WrapIfNecessary(ret_value); \
}
#ifdef HAS_DUAL_KEY
@@ -104,7 +118,7 @@ constexpr size_t kMaxExternalDeviceIdLength = 64;
// are not universal but are OEMCrypto method specific. Those will be
// specified in the CryptoSession method rather than here.
CdmResponseType MapOEMCryptoResult(OEMCryptoResult result,
CdmResponseType default_status,
CdmResponseEnum default_status,
const char* crypto_session_method) {
if (result != OEMCrypto_SUCCESS) {
LOGE("Mapping OEMCrypto result: crypto_session_method = %s, result = %d",
@@ -114,17 +128,17 @@ CdmResponseType MapOEMCryptoResult(OEMCryptoResult result,
switch (result) {
case OEMCrypto_SUCCESS:
return NO_ERROR;
return CdmResponseType(NO_ERROR);
case OEMCrypto_ERROR_NOT_IMPLEMENTED:
return NOT_IMPLEMENTED_ERROR;
return CdmResponseType(NOT_IMPLEMENTED_ERROR);
case OEMCrypto_ERROR_TOO_MANY_SESSIONS:
return INSUFFICIENT_CRYPTO_RESOURCES;
return CdmResponseType(INSUFFICIENT_CRYPTO_RESOURCES);
case OEMCrypto_ERROR_SESSION_LOST_STATE:
return SESSION_LOST_STATE_ERROR;
return CdmResponseType(SESSION_LOST_STATE_ERROR);
case OEMCrypto_ERROR_SYSTEM_INVALIDATED:
return SYSTEM_INVALIDATED_ERROR;
return CdmResponseType(SYSTEM_INVALIDATED_ERROR);
default:
return default_status;
return CdmResponseType(default_status);
}
}
@@ -323,10 +337,10 @@ CdmResponseType CryptoSession::GetProvisioningMethod(
LOGE("OEMCrypto_GetProvisioningMethod failed: method = %d",
static_cast<int>(method));
metrics_->oemcrypto_provisioning_method_.SetError(method);
return GET_PROVISIONING_METHOD_ERROR;
return CdmResponseType(GET_PROVISIONING_METHOD_ERROR);
}
*token_type = type;
return NO_ERROR;
return CdmResponseType(NO_ERROR);
}
void CryptoSession::Init() {
@@ -531,7 +545,7 @@ CdmResponseType CryptoSession::GetTokenFromKeybox(
if (requested_security_level_ != kLevelDefault) return false;
return needs_keybox_provisioning_;
});
if (keybox_provisioning_required) return NEED_PROVISIONING;
if (keybox_provisioning_required) return CdmResponseType(NEED_PROVISIONING);
size_t key_data_length = KEYBOX_KEY_DATA_SIZE;
key_data->assign(key_data_length, '\0');
@@ -545,7 +559,7 @@ CdmResponseType CryptoSession::GetTokenFromKeybox(
});
if (OEMCrypto_SUCCESS == status) {
key_data->resize(key_data_length);
return NO_ERROR;
return CdmResponseType(NO_ERROR);
}
key_data->clear();
return MapOEMCryptoResult(status, GET_TOKEN_FROM_KEYBOX_ERROR,
@@ -567,7 +581,7 @@ CdmResponseType CryptoSession::GetTokenFromOemCert(
oem_cert->assign(oem_token_);
return true;
});
if (cache_success) return NO_ERROR;
if (cache_success) return CdmResponseType(NO_ERROR);
size_t oem_cert_length = CERTIFICATE_DATA_SIZE;
oem_cert->assign(oem_cert_length, '\0');
@@ -592,7 +606,7 @@ CdmResponseType CryptoSession::GetTokenFromOemCert(
oem_cert->resize(oem_cert_length);
WithOecSessionLock("GetTokenFromOemCert - set cache",
[&] { oem_token_ = *oem_cert; });
return NO_ERROR;
return CdmResponseType(NO_ERROR);
}
oem_cert->clear();
return MapOEMCryptoResult(status, GET_TOKEN_FROM_OEM_CERT_ERROR,
@@ -610,17 +624,18 @@ CdmResponseType CryptoSession::GetProvisioningToken(
RequestedSecurityLevel requested_security_level, std::string* token,
std::string* additional_token) {
if (token == nullptr || additional_token == nullptr) {
metrics_->crypto_session_get_token_.Increment(PARAMETER_NULL);
metrics_->crypto_session_get_token_.Increment(
CdmResponseType(PARAMETER_NULL));
RETURN_IF_NULL(token, PARAMETER_NULL);
RETURN_IF_NULL(additional_token, PARAMETER_NULL);
}
if (!IsInitialized()) {
metrics_->crypto_session_get_token_.Increment(
CRYPTO_SESSION_NOT_INITIALIZED);
return CRYPTO_SESSION_NOT_INITIALIZED;
CdmResponseType(CRYPTO_SESSION_NOT_INITIALIZED));
return CdmResponseType(CRYPTO_SESSION_NOT_INITIALIZED);
}
CdmResponseType status = UNKNOWN_CLIENT_TOKEN_TYPE;
CdmResponseType status(UNKNOWN_CLIENT_TOKEN_TYPE);
if (pre_provision_token_type_ == kClientTokenKeybox) {
status = GetTokenFromKeybox(requested_security_level, token);
} else if (pre_provision_token_type_ == kClientTokenOemCert) {
@@ -703,7 +718,7 @@ CdmResponseType CryptoSession::GetInternalDeviceUniqueId(
// implemented, so the OEMCrypto can continue to report the same device ID.
if (sts == OEMCrypto_SUCCESS) {
device_id->resize(device_id_length);
return NO_ERROR;
return CdmResponseType(NO_ERROR);
}
device_id->clear();
@@ -728,7 +743,7 @@ CdmResponseType CryptoSession::GetInternalDeviceUniqueId(
LOGD("Using null device ID");
constexpr size_t kKeyboxDeviceIdLength = 32;
device_id->assign(kKeyboxDeviceIdLength, '\0');
return NO_ERROR;
return CdmResponseType(NO_ERROR);
}
return MapOEMCryptoResult(sts, GET_DEVICE_ID_ERROR,
@@ -746,7 +761,7 @@ CdmResponseType CryptoSession::GetExternalDeviceUniqueId(
// the large OEM Public Cert to a smaller value.
*device_id = Sha256Hash(*device_id);
}
return NO_ERROR;
return CdmResponseType(NO_ERROR);
}
bool CryptoSession::GetApiVersion(uint32_t* version) {
@@ -823,7 +838,7 @@ CdmResponseType CryptoSession::GetProvisioningId(std::string* provisioning_id) {
(*provisioning_id)[i] = ~value;
}
return NO_ERROR;
return CdmResponseType(NO_ERROR);
}
if (pre_provision_token_type_ == kClientTokenKeybox) {
std::string token;
@@ -834,15 +849,15 @@ CdmResponseType CryptoSession::GetProvisioningId(std::string* provisioning_id) {
if (token.size() < 24) {
LOGE("Keybox token size too small: %zu", token.size());
return KEYBOX_TOKEN_TOO_SHORT;
return CdmResponseType(KEYBOX_TOKEN_TOO_SHORT);
}
provisioning_id->assign(reinterpret_cast<char*>(&token[8]), 16);
return NO_ERROR;
return CdmResponseType(NO_ERROR);
}
LOGE("Unsupported pre-provision token type: %d",
static_cast<int>(pre_provision_token_type_));
return UNKNOWN_CLIENT_TOKEN_TYPE;
return CdmResponseType(UNKNOWN_CLIENT_TOKEN_TYPE);
}
uint8_t CryptoSession::GetSecurityPatchLevel() {
@@ -859,7 +874,7 @@ CdmResponseType CryptoSession::Open(
LOGD("Opening crypto session: requested_security_level = %s",
RequestedSecurityLevelToString(requested_security_level));
RETURN_IF_UNINITIALIZED(CRYPTO_SESSION_NOT_INITIALIZED);
if (open_) return NO_ERROR;
if (open_) return CdmResponseType(NO_ERROR);
if (!SetUpUsageTableHeader(requested_security_level)) {
// Ignore errors since we do not know when a session is opened,
@@ -922,9 +937,9 @@ CdmResponseType CryptoSession::Open(
if (!GetApiVersion(&api_version_)) {
LOGE("Failed to get API version");
return USAGE_SUPPORT_GET_API_FAILED;
return CdmResponseType(USAGE_SUPPORT_GET_API_FAILED);
}
return NO_ERROR;
return CdmResponseType(NO_ERROR);
}
void CryptoSession::Close() {
@@ -992,7 +1007,7 @@ CdmResponseType CryptoSession::PrepareAndSignLicenseRequest(
if (static_cast<int>(sts) == kRsaSsaPssSignatureLengthError) {
LOGE("OEMCrypto PrepareAndSignLicenseRequest result = %d",
static_cast<int>(sts));
return NEED_PROVISIONING;
return CdmResponseType(NEED_PROVISIONING);
}
return MapOEMCryptoResult(sts, GENERATE_SIGNATURE_ERROR,
"PrepareAndSignLicenseRequest");
@@ -1019,7 +1034,7 @@ CdmResponseType CryptoSession::PrepareAndSignLicenseRequest(
*core_message = std::move(combined_message);
// Truncate combined message to only contain the core message.
core_message->resize(core_message_length);
return NO_ERROR;
return CdmResponseType(NO_ERROR);
}
// TODO(b/174412779): Remove when b/170704368 is fixed.
// Temporary workaround. If this error is returned the only way to
@@ -1027,7 +1042,7 @@ CdmResponseType CryptoSession::PrepareAndSignLicenseRequest(
if (static_cast<int>(sts) == kRsaSsaPssSignatureLengthError) {
LOGE("OEMCrypto PrepareAndSignLicenseRequest result = %d",
static_cast<int>(sts));
return NEED_PROVISIONING;
return CdmResponseType(NEED_PROVISIONING);
}
return MapOEMCryptoResult(sts, GENERATE_SIGNATURE_ERROR,
"PrepareAndSignLicenseRequest");
@@ -1042,7 +1057,7 @@ CdmResponseType CryptoSession::UseSecondaryKey(bool dual_key) {
return MapOEMCryptoResult(sts, LOAD_KEY_ERROR, "UseSecondaryKey");
#else
return NO_ERROR;
return CdmResponseType(NO_ERROR);
#endif
}
@@ -1070,13 +1085,13 @@ CdmResponseType CryptoSession::LoadLicense(const std::string& signed_message,
switch (sts) {
case OEMCrypto_SUCCESS:
return KEY_ADDED;
return CdmResponseType(KEY_ADDED);
case OEMCrypto_ERROR_BUFFER_TOO_LARGE:
LOGE("LoadLicense buffer too large: size = %zu", combined_message.size());
return LOAD_LICENSE_ERROR;
return CdmResponseType(LOAD_LICENSE_ERROR);
case OEMCrypto_ERROR_TOO_MANY_KEYS:
LOGE("Too many keys in license");
return INSUFFICIENT_CRYPTO_RESOURCES;
return CdmResponseType(INSUFFICIENT_CRYPTO_RESOURCES);
default:
break;
}
@@ -1089,11 +1104,11 @@ CdmResponseType CryptoSession::PrepareAndSignRenewalRequest(
LOGV("Preparing and signing renewal request: id = %u", oec_session_id_);
if (signature == nullptr) {
LOGE("Output parameter |signature| not provided");
return PARAMETER_NULL;
return CdmResponseType(PARAMETER_NULL);
}
if (core_message == nullptr) {
LOGE("Output parameter |core_message| not provided");
return PARAMETER_NULL;
return CdmResponseType(PARAMETER_NULL);
}
OEMCryptoResult sts;
@@ -1139,7 +1154,7 @@ CdmResponseType CryptoSession::PrepareAndSignRenewalRequest(
*core_message = std::move(combined_message);
// Truncate combined message to only contain the core message.
core_message->resize(core_message_length);
return NO_ERROR;
return CdmResponseType(NO_ERROR);
}
return MapOEMCryptoResult(sts, GENERATE_SIGNATURE_ERROR,
"PrepareAndSignRenewalRequest");
@@ -1161,11 +1176,11 @@ CdmResponseType CryptoSession::LoadRenewal(const std::string& signed_message,
metrics_, oemcrypto_load_renewal_, sts);
});
if (sts == OEMCrypto_SUCCESS) {
return KEY_ADDED;
return CdmResponseType(KEY_ADDED);
}
if (sts == OEMCrypto_ERROR_BUFFER_TOO_LARGE) {
LOGE("Buffer too large: size = %zu", combined_message.size());
return LOAD_RENEWAL_ERROR;
return CdmResponseType(LOAD_RENEWAL_ERROR);
}
return MapOEMCryptoResult(sts, LOAD_RENEWAL_ERROR, "LoadRenewal");
}
@@ -1176,11 +1191,11 @@ CdmResponseType CryptoSession::PrepareAndSignProvisioningRequest(
LOGV("Preparing and signing provisioning request: id = %u", oec_session_id_);
if (signature == nullptr) {
LOGE("Output parameter |signature| not provided");
return PARAMETER_NULL;
return CdmResponseType(PARAMETER_NULL);
}
if (core_message == nullptr) {
LOGE("Output parameter |core_message| not provided");
return PARAMETER_NULL;
return CdmResponseType(PARAMETER_NULL);
}
if (pre_provision_token_type_ == kClientTokenKeybox) {
@@ -1194,7 +1209,7 @@ CdmResponseType CryptoSession::PrepareAndSignProvisioningRequest(
}
} else {
LOGE("Unknown method %d", pre_provision_token_type_);
return UNKNOWN_CLIENT_TOKEN_TYPE;
return CdmResponseType(UNKNOWN_CLIENT_TOKEN_TYPE);
}
OEMCryptoResult sts;
@@ -1240,7 +1255,7 @@ CdmResponseType CryptoSession::PrepareAndSignProvisioningRequest(
*core_message = std::move(combined_message);
// Truncate combined message to only contain the core message.
core_message->resize(core_message_length);
return NO_ERROR;
return CdmResponseType(NO_ERROR);
}
return MapOEMCryptoResult(sts, GENERATE_SIGNATURE_ERROR,
"PrepareAndSignProvisioningRequest");
@@ -1254,19 +1269,19 @@ CdmResponseType CryptoSession::LoadEntitledContentKeys(
switch (sts) {
case OEMCrypto_SUCCESS:
return KEY_ADDED;
return CdmResponseType(KEY_ADDED);
case OEMCrypto_ERROR_INSUFFICIENT_RESOURCES:
return INSUFFICIENT_CRYPTO_RESOURCES;
return CdmResponseType(INSUFFICIENT_CRYPTO_RESOURCES);
case OEMCrypto_ERROR_INVALID_CONTEXT:
return NOT_AN_ENTITLEMENT_SESSION;
return CdmResponseType(NOT_AN_ENTITLEMENT_SESSION);
case OEMCrypto_KEY_NOT_ENTITLED:
return NO_MATCHING_ENTITLEMENT_KEY;
return CdmResponseType(NO_MATCHING_ENTITLEMENT_KEY);
case OEMCrypto_ERROR_SESSION_LOST_STATE:
return SESSION_LOST_STATE_ERROR;
return CdmResponseType(SESSION_LOST_STATE_ERROR);
case OEMCrypto_ERROR_SYSTEM_INVALIDATED:
return SYSTEM_INVALIDATED_ERROR;
return CdmResponseType(SYSTEM_INVALIDATED_ERROR);
default:
return LOAD_ENTITLED_CONTENT_KEYS_ERROR;
return CdmResponseType(LOAD_ENTITLED_CONTENT_KEYS_ERROR);
}
}
@@ -1310,11 +1325,12 @@ CdmResponseType CryptoSession::GetBootCertificateChain(
LOGV("requested_security_level = %s",
RequestedSecurityLevelToString(requested_security_level));
if (pre_provision_token_type_ != kClientTokenBootCertChain) {
return PROVISIONING_TYPE_IS_NOT_BOOT_CERTIFICATE_CHAIN_ERROR;
return CdmResponseType(
PROVISIONING_TYPE_IS_NOT_BOOT_CERTIFICATE_CHAIN_ERROR);
}
if (requested_security_level != kLevelDefault) {
LOGE("CDM only supports L1 BCC");
return NOT_IMPLEMENTED_ERROR;
return CdmResponseType(NOT_IMPLEMENTED_ERROR);
}
size_t bcc_length = 0;
@@ -1340,7 +1356,7 @@ CdmResponseType CryptoSession::GetBootCertificateChain(
}
bcc->resize(bcc_length);
additional_signature->resize(additional_signature_length);
return NO_ERROR;
return CdmResponseType(NO_ERROR);
}
CdmResponseType CryptoSession::GenerateCertificateKeyPair(
@@ -1402,10 +1418,10 @@ CdmResponseType CryptoSession::GenerateCertificateKeyPair(
} else {
LOGE("Unexpected key type returned from GenerateCertificateKeyPair: %d",
static_cast<int>(oemcrypto_key_type));
return GENERATE_CERTIFICATE_KEY_PAIR_UNKNOWN_TYPE_ERROR;
return CdmResponseType(GENERATE_CERTIFICATE_KEY_PAIR_UNKNOWN_TYPE_ERROR);
}
return NO_ERROR;
return CdmResponseType(NO_ERROR);
}
CdmResponseType CryptoSession::LoadOemCertificatePrivateKey(
@@ -1442,36 +1458,36 @@ CdmResponseType CryptoSession::SelectKey(const std::string& key_id,
switch (sts) {
// SelectKey errors.
case OEMCrypto_SUCCESS:
return NO_ERROR;
return CdmResponseType(NO_ERROR);
case OEMCrypto_ERROR_KEY_EXPIRED:
return NEED_KEY;
return CdmResponseType(NEED_KEY);
case OEMCrypto_ERROR_INVALID_SESSION:
return INVALID_SESSION_1;
return CdmResponseType(INVALID_SESSION_1);
case OEMCrypto_ERROR_NO_DEVICE_KEY:
return NO_DEVICE_KEY_1;
return CdmResponseType(NO_DEVICE_KEY_1);
case OEMCrypto_ERROR_NO_CONTENT_KEY:
return NO_CONTENT_KEY_2;
return CdmResponseType(NO_CONTENT_KEY_2);
case OEMCrypto_ERROR_CONTROL_INVALID:
case OEMCrypto_ERROR_KEYBOX_INVALID:
return UNKNOWN_SELECT_KEY_ERROR_2;
return CdmResponseType(UNKNOWN_SELECT_KEY_ERROR_2);
case OEMCrypto_ERROR_INSUFFICIENT_RESOURCES:
return INSUFFICIENT_CRYPTO_RESOURCES;
return CdmResponseType(INSUFFICIENT_CRYPTO_RESOURCES);
case OEMCrypto_ERROR_UNKNOWN_FAILURE:
return UNKNOWN_SELECT_KEY_ERROR_1;
return CdmResponseType(UNKNOWN_SELECT_KEY_ERROR_1);
case OEMCrypto_ERROR_ANALOG_OUTPUT:
return ANALOG_OUTPUT_ERROR;
return CdmResponseType(ANALOG_OUTPUT_ERROR);
case OEMCrypto_ERROR_INSUFFICIENT_HDCP:
return INSUFFICIENT_OUTPUT_PROTECTION;
return CdmResponseType(INSUFFICIENT_OUTPUT_PROTECTION);
// LoadEntitledContentKeys errors.
// |key_session_| may make calls to OEMCrypto_LoadEntitledContentKeys
// if the key selected has not yet been loaded.
case OEMCrypto_ERROR_INVALID_CONTEXT:
return NOT_AN_ENTITLEMENT_SESSION;
return CdmResponseType(NOT_AN_ENTITLEMENT_SESSION);
case OEMCrypto_KEY_NOT_ENTITLED:
return NO_MATCHING_ENTITLEMENT_KEY;
return CdmResponseType(NO_MATCHING_ENTITLEMENT_KEY);
// Obsolete errors.
case OEMCrypto_KEY_NOT_LOADED:
return NO_CONTENT_KEY_3;
return CdmResponseType(NO_CONTENT_KEY_3);
// Catch all else.
default:
return MapOEMCryptoResult(sts, UNKNOWN_SELECT_KEY_ERROR_2, "SelectKey");
@@ -1524,7 +1540,7 @@ CdmResponseType CryptoSession::GenerateRsaSignature(const std::string& message,
if (OEMCrypto_SUCCESS == sts) {
// Trim signature buffer and done
signature->resize(length);
return NO_ERROR;
return CdmResponseType(NO_ERROR);
}
if (OEMCrypto_ERROR_SHORT_BUFFER != sts) {
break;
@@ -1565,22 +1581,23 @@ size_t CryptoSession::GetMaxSubsampleRegionSize() {
CdmResponseType CryptoSession::Decrypt(
const CdmDecryptionParametersV16& params) {
if (!is_destination_buffer_type_valid_) {
if (!SetDestinationBufferType()) return UNKNOWN_ERROR;
if (!SetDestinationBufferType()) return CdmResponseType(UNKNOWN_ERROR);
}
OEMCryptoBufferType output_descriptor_type =
params.is_secure ? destination_buffer_type_ : OEMCrypto_BufferType_Clear;
if (params.is_secure &&
output_descriptor_type == OEMCrypto_BufferType_Clear) {
return SECURE_BUFFER_REQUIRED;
return CdmResponseType(SECURE_BUFFER_REQUIRED);
}
if (params.samples.size() == 0) return CANNOT_DECRYPT_ZERO_SAMPLES;
if (params.samples.size() == 0)
return CdmResponseType(CANNOT_DECRYPT_ZERO_SAMPLES);
if (std::any_of(std::begin(params.samples), std::end(params.samples),
[](const CdmDecryptionSample& sample) -> bool {
return sample.subsamples.size() == 0;
})) {
return CANNOT_DECRYPT_ZERO_SUBSAMPLES;
return CdmResponseType(CANNOT_DECRYPT_ZERO_SUBSAMPLES);
}
// Convert all the sample and subsample definitions to OEMCrypto structs.
@@ -1671,11 +1688,12 @@ CdmResponseType CryptoSession::Decrypt(
// Check that the total size is valid
if (sample_size != oec_sample.buffers.input_data_length)
return SAMPLE_AND_SUBSAMPLE_SIZE_MISMATCH;
return CdmResponseType(SAMPLE_AND_SUBSAMPLE_SIZE_MISMATCH);
// Set up the sample's IV
if (is_any_subsample_protected) {
if (sizeof(oec_sample.iv) != sample.iv.size()) return INVALID_IV_SIZE;
if (sizeof(oec_sample.iv) != sample.iv.size())
return CdmResponseType(INVALID_IV_SIZE);
memcpy(oec_sample.iv, sample.iv.data(), sizeof(oec_sample.iv));
} else {
memset(oec_sample.iv, 0, sizeof(oec_sample.iv));
@@ -1732,28 +1750,28 @@ CdmResponseType CryptoSession::Decrypt(
switch (sts) {
case OEMCrypto_SUCCESS:
case OEMCrypto_WARNING_MIXED_OUTPUT_PROTECTION:
return NO_ERROR;
return CdmResponseType(NO_ERROR);
case OEMCrypto_ERROR_INSUFFICIENT_RESOURCES:
return INSUFFICIENT_CRYPTO_RESOURCES;
return CdmResponseType(INSUFFICIENT_CRYPTO_RESOURCES);
case OEMCrypto_ERROR_KEY_EXPIRED:
return NEED_KEY;
return CdmResponseType(NEED_KEY);
case OEMCrypto_ERROR_INVALID_SESSION:
return INVALID_SESSION_2;
return CdmResponseType(INVALID_SESSION_2);
case OEMCrypto_ERROR_DECRYPT_FAILED:
case OEMCrypto_ERROR_UNKNOWN_FAILURE:
return DECRYPT_ERROR;
return CdmResponseType(DECRYPT_ERROR);
case OEMCrypto_ERROR_INSUFFICIENT_HDCP:
return INSUFFICIENT_OUTPUT_PROTECTION;
return CdmResponseType(INSUFFICIENT_OUTPUT_PROTECTION);
case OEMCrypto_ERROR_ANALOG_OUTPUT:
return ANALOG_OUTPUT_ERROR;
return CdmResponseType(ANALOG_OUTPUT_ERROR);
case OEMCrypto_ERROR_OUTPUT_TOO_LARGE:
return OUTPUT_TOO_LARGE_ERROR;
return CdmResponseType(OUTPUT_TOO_LARGE_ERROR);
case OEMCrypto_ERROR_SESSION_LOST_STATE:
return SESSION_LOST_STATE_ERROR;
return CdmResponseType(SESSION_LOST_STATE_ERROR);
case OEMCrypto_ERROR_SYSTEM_INVALIDATED:
return SYSTEM_INVALIDATED_ERROR;
return CdmResponseType(SYSTEM_INVALIDATED_ERROR);
default:
return UNKNOWN_ERROR;
return CdmResponseType(UNKNOWN_ERROR);
}
}
@@ -1816,15 +1834,15 @@ CdmResponseType CryptoSession::DeactivateUsageInformation(
switch (status) {
case OEMCrypto_SUCCESS:
return NO_ERROR;
return CdmResponseType(NO_ERROR);
case OEMCrypto_ERROR_INVALID_CONTEXT:
return KEY_CANCELED;
return CdmResponseType(KEY_CANCELED);
case OEMCrypto_ERROR_SESSION_LOST_STATE:
return SESSION_LOST_STATE_ERROR;
return CdmResponseType(SESSION_LOST_STATE_ERROR);
case OEMCrypto_ERROR_SYSTEM_INVALIDATED:
return SYSTEM_INVALIDATED_ERROR;
return CdmResponseType(SYSTEM_INVALIDATED_ERROR);
default:
return DEACTIVATE_USAGE_ENTRY_ERROR;
return CdmResponseType(DEACTIVATE_USAGE_ENTRY_ERROR);
}
}
@@ -1880,12 +1898,13 @@ CdmResponseType CryptoSession::GenerateUsageReport(
"Parsed usage report smaller than expected: "
"usage_length = %zu, report_size = %zu",
usage_length, pst_report.report_size());
return NO_ERROR; // usage report available but no duration information
return CdmResponseType(
NO_ERROR); // usage report available but no duration information
}
if (kUnused == pst_report.status()) {
*usage_duration_status = kUsageDurationPlaybackNotBegun;
return NO_ERROR;
return CdmResponseType(NO_ERROR);
}
LOGV("OEMCrypto_PST_Report.status: %d\n",
static_cast<int>(pst_report.status()));
@@ -1905,7 +1924,7 @@ CdmResponseType CryptoSession::GenerateUsageReport(
if (kInactiveUnused == pst_report.status()) {
*usage_duration_status = kUsageDurationPlaybackNotBegun;
return NO_ERROR;
return CdmResponseType(NO_ERROR);
}
// Before OEMCrypto v13, When usage report state is inactive, we have to
// deduce whether the license was ever used.
@@ -1914,13 +1933,13 @@ CdmResponseType CryptoSession::GenerateUsageReport(
pst_report.seconds_since_license_received() <
pst_report.seconds_since_first_decrypt())) {
*usage_duration_status = kUsageDurationPlaybackNotBegun;
return NO_ERROR;
return CdmResponseType(NO_ERROR);
}
*usage_duration_status = kUsageDurationsValid;
*seconds_since_started = pst_report.seconds_since_first_decrypt();
*seconds_since_last_played = pst_report.seconds_since_last_decrypt();
return NO_ERROR;
return CdmResponseType(NO_ERROR);
}
bool CryptoSession::IsAntiRollbackHwPresent() {
@@ -1965,7 +1984,7 @@ CdmResponseType CryptoSession::LoadProvisioning(
LOGV("Loading provisioning certificate: id = %u", oec_session_id_);
if (wrapped_private_key == nullptr) {
LOGE("Missing wrapped |wrapped_private_key|");
return PARAMETER_NULL;
return CdmResponseType(PARAMETER_NULL);
}
const std::string combined_message = core_message + signed_message;
@@ -2003,7 +2022,7 @@ CdmResponseType CryptoSession::LoadProvisioning(
if (status == OEMCrypto_SUCCESS) {
wrapped_private_key->resize(wrapped_private_key_length);
return NO_ERROR;
return CdmResponseType(NO_ERROR);
}
wrapped_private_key->clear();
return MapOEMCryptoResult(status, LOAD_PROVISIONING_ERROR,
@@ -2137,13 +2156,13 @@ CdmResponseType CryptoSession::GetSrmVersion(uint16_t* srm_version) {
// returned.
switch (status) {
case OEMCrypto_SUCCESS:
return NO_ERROR;
return CdmResponseType(NO_ERROR);
case OEMCrypto_LOCAL_DISPLAY_ONLY:
LOGD("No SRM: Local display only");
return NO_SRM_VERSION;
return CdmResponseType(NO_SRM_VERSION);
case OEMCrypto_ERROR_NOT_IMPLEMENTED:
LOGD("No SRM: Not implemented");
return NO_SRM_VERSION;
return CdmResponseType(NO_SRM_VERSION);
default:
return MapOEMCryptoResult(status, GET_SRM_VERSION_ERROR,
"GetCurrentSRMVersion");
@@ -2366,15 +2385,15 @@ CdmResponseType CryptoSession::GetDecryptHashError(std::string* error_string) {
error_string->assign(std::to_string(sts));
error_string->append(",");
error_string->append(std::to_string(failed_frame_number));
return NO_ERROR;
return CdmResponseType(NO_ERROR);
case OEMCrypto_ERROR_SESSION_LOST_STATE:
return SESSION_LOST_STATE_ERROR;
return CdmResponseType(SESSION_LOST_STATE_ERROR);
case OEMCrypto_ERROR_SYSTEM_INVALIDATED:
return SYSTEM_INVALIDATED_ERROR;
return CdmResponseType(SYSTEM_INVALIDATED_ERROR);
case OEMCrypto_ERROR_UNKNOWN_FAILURE:
case OEMCrypto_ERROR_NOT_IMPLEMENTED:
default:
return GET_DECRYPT_HASH_ERROR;
return CdmResponseType(GET_DECRYPT_HASH_ERROR);
}
}
@@ -2389,7 +2408,7 @@ CdmResponseType CryptoSession::GenericEncrypt(const std::string& in_buffer,
OEMCrypto_Algorithm oec_algorithm = OEMCrypto_AES_CBC_128_NO_PADDING;
if (iv.size() != GenericEncryptionBlockSize(algorithm) ||
!GetGenericEncryptionAlgorithm(algorithm, &oec_algorithm)) {
return INVALID_PARAMETERS_ENG_13;
return CdmResponseType(INVALID_PARAMETERS_ENG_13);
}
if (out_buffer->size() < in_buffer.size()) {
@@ -2422,20 +2441,20 @@ CdmResponseType CryptoSession::GenericEncrypt(const std::string& in_buffer,
switch (sts) {
case OEMCrypto_SUCCESS:
return NO_ERROR;
return CdmResponseType(NO_ERROR);
case OEMCrypto_ERROR_KEY_EXPIRED:
return NEED_KEY;
return CdmResponseType(NEED_KEY);
case OEMCrypto_ERROR_NO_CONTENT_KEY:
case OEMCrypto_KEY_NOT_LOADED: // obsolete in v15.
return KEY_NOT_FOUND_3;
return CdmResponseType(KEY_NOT_FOUND_3);
case OEMCrypto_ERROR_OUTPUT_TOO_LARGE:
return OUTPUT_TOO_LARGE_ERROR;
return CdmResponseType(OUTPUT_TOO_LARGE_ERROR);
case OEMCrypto_ERROR_SESSION_LOST_STATE:
return SESSION_LOST_STATE_ERROR;
return CdmResponseType(SESSION_LOST_STATE_ERROR);
case OEMCrypto_ERROR_SYSTEM_INVALIDATED:
return SYSTEM_INVALIDATED_ERROR;
return CdmResponseType(SYSTEM_INVALIDATED_ERROR);
default:
return UNKNOWN_ERROR;
return CdmResponseType(UNKNOWN_ERROR);
}
}
@@ -2450,7 +2469,7 @@ CdmResponseType CryptoSession::GenericDecrypt(const std::string& in_buffer,
OEMCrypto_Algorithm oec_algorithm = OEMCrypto_AES_CBC_128_NO_PADDING;
if (iv.size() != GenericEncryptionBlockSize(algorithm) ||
!GetGenericEncryptionAlgorithm(algorithm, &oec_algorithm)) {
return INVALID_PARAMETERS_ENG_14;
return CdmResponseType(INVALID_PARAMETERS_ENG_14);
}
if (out_buffer->size() < in_buffer.size()) {
@@ -2483,20 +2502,20 @@ CdmResponseType CryptoSession::GenericDecrypt(const std::string& in_buffer,
switch (sts) {
case OEMCrypto_SUCCESS:
return NO_ERROR;
return CdmResponseType(NO_ERROR);
case OEMCrypto_ERROR_KEY_EXPIRED:
return NEED_KEY;
return CdmResponseType(NEED_KEY);
case OEMCrypto_ERROR_NO_CONTENT_KEY:
case OEMCrypto_KEY_NOT_LOADED: // obsolete in v15.
return KEY_NOT_FOUND_4;
return CdmResponseType(KEY_NOT_FOUND_4);
case OEMCrypto_ERROR_OUTPUT_TOO_LARGE:
return OUTPUT_TOO_LARGE_ERROR;
return CdmResponseType(OUTPUT_TOO_LARGE_ERROR);
case OEMCrypto_ERROR_SESSION_LOST_STATE:
return SESSION_LOST_STATE_ERROR;
return CdmResponseType(SESSION_LOST_STATE_ERROR);
case OEMCrypto_ERROR_SYSTEM_INVALIDATED:
return SYSTEM_INVALIDATED_ERROR;
return CdmResponseType(SYSTEM_INVALIDATED_ERROR);
default:
return UNKNOWN_ERROR;
return CdmResponseType(UNKNOWN_ERROR);
}
}
@@ -2509,7 +2528,7 @@ CdmResponseType CryptoSession::GenericSign(const std::string& message,
OEMCrypto_Algorithm oec_algorithm = OEMCrypto_HMAC_SHA256;
if (!GetGenericSigningAlgorithm(algorithm, &oec_algorithm)) {
return INVALID_PARAMETERS_ENG_15;
return CdmResponseType(INVALID_PARAMETERS_ENG_15);
}
OEMCryptoResult sts;
@@ -2538,7 +2557,7 @@ CdmResponseType CryptoSession::GenericSign(const std::string& message,
if (OEMCrypto_SUCCESS == sts) {
// Trim signature buffer and done
signature->resize(length);
return NO_ERROR;
return CdmResponseType(NO_ERROR);
}
if (OEMCrypto_ERROR_SHORT_BUFFER != sts) {
break;
@@ -2552,18 +2571,18 @@ CdmResponseType CryptoSession::GenericSign(const std::string& message,
switch (sts) {
case OEMCrypto_ERROR_KEY_EXPIRED:
return NEED_KEY;
return CdmResponseType(NEED_KEY);
case OEMCrypto_ERROR_NO_CONTENT_KEY:
case OEMCrypto_KEY_NOT_LOADED: // obsolete in v15.
return KEY_NOT_FOUND_5;
return CdmResponseType(KEY_NOT_FOUND_5);
case OEMCrypto_ERROR_OUTPUT_TOO_LARGE:
return OUTPUT_TOO_LARGE_ERROR;
return CdmResponseType(OUTPUT_TOO_LARGE_ERROR);
case OEMCrypto_ERROR_SESSION_LOST_STATE:
return SESSION_LOST_STATE_ERROR;
return CdmResponseType(SESSION_LOST_STATE_ERROR);
case OEMCrypto_ERROR_SYSTEM_INVALIDATED:
return SYSTEM_INVALIDATED_ERROR;
return CdmResponseType(SYSTEM_INVALIDATED_ERROR);
default:
return UNKNOWN_ERROR;
return CdmResponseType(UNKNOWN_ERROR);
}
}
@@ -2575,7 +2594,7 @@ CdmResponseType CryptoSession::GenericVerify(const std::string& message,
OEMCrypto_Algorithm oec_algorithm = OEMCrypto_HMAC_SHA256;
if (!GetGenericSigningAlgorithm(algorithm, &oec_algorithm)) {
return INVALID_PARAMETERS_ENG_16;
return CdmResponseType(INVALID_PARAMETERS_ENG_16);
}
// TODO(jfore): We need to select a key with a cipher mode and algorithm
@@ -2602,20 +2621,20 @@ CdmResponseType CryptoSession::GenericVerify(const std::string& message,
switch (sts) {
case OEMCrypto_SUCCESS:
return NO_ERROR;
return CdmResponseType(NO_ERROR);
case OEMCrypto_ERROR_KEY_EXPIRED:
return NEED_KEY;
return CdmResponseType(NEED_KEY);
case OEMCrypto_ERROR_NO_CONTENT_KEY:
case OEMCrypto_KEY_NOT_LOADED: // obsolete in v15.
return KEY_NOT_FOUND_6;
return CdmResponseType(KEY_NOT_FOUND_6);
case OEMCrypto_ERROR_OUTPUT_TOO_LARGE:
return OUTPUT_TOO_LARGE_ERROR;
return CdmResponseType(OUTPUT_TOO_LARGE_ERROR);
case OEMCrypto_ERROR_SESSION_LOST_STATE:
return SESSION_LOST_STATE_ERROR;
return CdmResponseType(SESSION_LOST_STATE_ERROR);
case OEMCrypto_ERROR_SYSTEM_INVALIDATED:
return SYSTEM_INVALIDATED_ERROR;
return CdmResponseType(SYSTEM_INVALIDATED_ERROR);
default:
return UNKNOWN_ERROR;
return CdmResponseType(UNKNOWN_ERROR);
}
}
@@ -2653,7 +2672,7 @@ CdmResponseType CryptoSession::CreateUsageTableHeader(
switch (result) {
case OEMCrypto_SUCCESS:
usage_table_header->resize(usage_table_header_size);
return NO_ERROR;
return CdmResponseType(NO_ERROR);
default:
return MapOEMCryptoResult(result, CREATE_USAGE_TABLE_ERROR,
"CreateUsageTableHeader");
@@ -2686,18 +2705,18 @@ CdmResponseType CryptoSession::LoadUsageTableHeader(
switch (result) {
case OEMCrypto_SUCCESS:
case OEMCrypto_WARNING_GENERATION_SKEW:
return NO_ERROR;
return CdmResponseType(NO_ERROR);
case OEMCrypto_ERROR_GENERATION_SKEW:
return LOAD_USAGE_HEADER_GENERATION_SKEW;
return CdmResponseType(LOAD_USAGE_HEADER_GENERATION_SKEW);
case OEMCrypto_ERROR_SIGNATURE_FAILURE:
return LOAD_USAGE_HEADER_SIGNATURE_FAILURE;
return CdmResponseType(LOAD_USAGE_HEADER_SIGNATURE_FAILURE);
case OEMCrypto_ERROR_BAD_MAGIC:
return LOAD_USAGE_HEADER_BAD_MAGIC;
return CdmResponseType(LOAD_USAGE_HEADER_BAD_MAGIC);
case OEMCrypto_ERROR_SYSTEM_INVALIDATED:
return SYSTEM_INVALIDATED_ERROR;
return CdmResponseType(SYSTEM_INVALIDATED_ERROR);
case OEMCrypto_ERROR_UNKNOWN_FAILURE:
default:
return LOAD_USAGE_HEADER_UNKNOWN_ERROR;
return CdmResponseType(LOAD_USAGE_HEADER_UNKNOWN_ERROR);
}
}
@@ -2732,9 +2751,9 @@ CdmResponseType CryptoSession::ShrinkUsageTableHeader(
switch (result) {
case OEMCrypto_SUCCESS:
usage_table_header->resize(usage_table_header_len);
return NO_ERROR;
return CdmResponseType(NO_ERROR);
case OEMCrypto_ERROR_ENTRY_IN_USE:
return SHRINK_USAGE_TABLE_HEADER_ENTRY_IN_USE;
return CdmResponseType(SHRINK_USAGE_TABLE_HEADER_ENTRY_IN_USE);
default:
return MapOEMCryptoResult(result, SHRINK_USAGE_TABLE_HEADER_UNKNOWN_ERROR,
"ShrinkUsageTableHeader");
@@ -2759,15 +2778,15 @@ CdmResponseType CryptoSession::CreateUsageEntry(uint32_t* entry_number) {
switch (result) {
case OEMCrypto_SUCCESS:
return NO_ERROR;
return CdmResponseType(NO_ERROR);
case OEMCrypto_ERROR_INSUFFICIENT_RESOURCES:
return INSUFFICIENT_CRYPTO_RESOURCES;
return CdmResponseType(INSUFFICIENT_CRYPTO_RESOURCES);
case OEMCrypto_ERROR_SESSION_LOST_STATE:
return SESSION_LOST_STATE_ERROR;
return CdmResponseType(SESSION_LOST_STATE_ERROR);
case OEMCrypto_ERROR_SYSTEM_INVALIDATED:
return SYSTEM_INVALIDATED_ERROR;
return CdmResponseType(SYSTEM_INVALIDATED_ERROR);
default:
return CREATE_USAGE_ENTRY_UNKNOWN_ERROR;
return CdmResponseType(CREATE_USAGE_ENTRY_UNKNOWN_ERROR);
}
}
@@ -2796,17 +2815,17 @@ CdmResponseType CryptoSession::LoadUsageEntry(
switch (result) {
case OEMCrypto_SUCCESS:
case OEMCrypto_WARNING_GENERATION_SKEW:
return NO_ERROR;
return CdmResponseType(NO_ERROR);
case OEMCrypto_ERROR_INVALID_SESSION:
// This case is special, as it could imply that the provided
// session ID is invalid (CDM internal bug), or that the entry
// being loaded is already in use in a different session.
// It is up to the caller to handle this.
return LOAD_USAGE_ENTRY_INVALID_SESSION;
return CdmResponseType(LOAD_USAGE_ENTRY_INVALID_SESSION);
case OEMCrypto_ERROR_GENERATION_SKEW:
return LOAD_USAGE_ENTRY_GENERATION_SKEW;
return CdmResponseType(LOAD_USAGE_ENTRY_GENERATION_SKEW);
case OEMCrypto_ERROR_SIGNATURE_FAILURE:
return LOAD_USAGE_ENTRY_SIGNATURE_FAILURE;
return CdmResponseType(LOAD_USAGE_ENTRY_SIGNATURE_FAILURE);
default:
return MapOEMCryptoResult(result, LOAD_USAGE_ENTRY_UNKNOWN_ERROR,
"LoadUsageEntry");
@@ -2868,7 +2887,7 @@ CdmResponseType CryptoSession::MoveUsageEntry(uint32_t new_entry_number) {
case OEMCrypto_ERROR_ENTRY_IN_USE:
LOGW("OEMCrypto_MoveEntry failed: Destination index in use: index = %u",
new_entry_number);
return MOVE_USAGE_ENTRY_DESTINATION_IN_USE;
return CdmResponseType(MOVE_USAGE_ENTRY_DESTINATION_IN_USE);
default:
return MapOEMCryptoResult(result, MOVE_USAGE_ENTRY_UNKNOWN_ERROR,
"MoveUsageEntry");
@@ -3219,7 +3238,7 @@ CdmResponseType CryptoSession::PrepareOtaProvisioningRequest(
"PrepareOtaProvisioningRequest");
if (buffer_length == 0) {
LOGE("OTA request size is zero");
return UNKNOWN_ERROR;
return CdmResponseType(UNKNOWN_ERROR);
}
request->resize(buffer_length);
uint8_t* buf = reinterpret_cast<uint8_t*>(&request->front());

View File

@@ -261,7 +261,7 @@ CdmResponseType CdmLicense::PrepareKeyRequest(
CdmKeyMessage* signed_request, std::string* server_url) {
if (!initialized_) {
LOGE("CdmLicense not initialized");
return LICENSE_PARSER_NOT_INITIALIZED_4;
return CdmResponseType(LICENSE_PARSER_NOT_INITIALIZED_4);
}
client_token_ = client_token;
if (init_data.IsEmpty() && stored_init_data_) {
@@ -273,19 +273,19 @@ CdmResponseType CdmLicense::PrepareKeyRequest(
wrapped_keys_ = init_data.ExtractWrappedKeys();
if (!init_data.is_supported()) {
LOGE("Unsupported init data type: type = %s", init_data.type().c_str());
return INVALID_PARAMETERS_LIC_3;
return CdmResponseType(INVALID_PARAMETERS_LIC_3);
}
if (init_data.IsEmpty()) {
LOGE("Init data is empty");
return INVALID_PARAMETERS_LIC_4;
return CdmResponseType(INVALID_PARAMETERS_LIC_4);
}
if (signed_request == nullptr) {
LOGE("Output parameter |signed_request| not provided");
return INVALID_PARAMETERS_LIC_6;
return CdmResponseType(INVALID_PARAMETERS_LIC_6);
}
if (server_url == nullptr) {
LOGE("Output parameter |server_url| not provided");
return INVALID_PARAMETERS_LIC_7;
return CdmResponseType(INVALID_PARAMETERS_LIC_7);
}
// If privacy mode and no service certificate, depending on platform
@@ -293,17 +293,18 @@ CdmResponseType CdmLicense::PrepareKeyRequest(
if (use_privacy_mode_ && !service_certificate_.has_certificate()) {
if (!Properties::allow_service_certificate_requests()) {
LOGE("Privacy mode failure: No service certificate");
return PRIVACY_MODE_ERROR_1;
return CdmResponseType(PRIVACY_MODE_ERROR_1);
}
stored_init_data_.reset(new InitializationData(init_data));
if (!ServiceCertificate::GetRequest(signed_request)) {
LOGE("Failed to prepare service certificated request");
return LICENSE_REQUEST_SERVICE_CERTIFICATE_GENERATION_ERROR;
return CdmResponseType(
LICENSE_REQUEST_SERVICE_CERTIFICATE_GENERATION_ERROR);
}
return KEY_MESSAGE;
return CdmResponseType(KEY_MESSAGE);
}
const std::string& request_id = crypto_session_->request_id();
@@ -325,14 +326,14 @@ CdmResponseType CdmLicense::PrepareKeyRequest(
// of the license response.
status = crypto_session_->GenerateNonce(&license_nonce_);
switch (status) {
switch (status.Enum()) {
case NO_ERROR:
break;
case SESSION_LOST_STATE_ERROR:
case SYSTEM_INVALIDATED_ERROR:
return status;
default:
return LICENSE_REQUEST_NONCE_GENERATION_ERROR;
return CdmResponseType(LICENSE_REQUEST_NONCE_GENERATION_ERROR);
}
license_request.set_key_control_nonce(license_nonce_);
license_request.set_protocol_version(video_widevine::VERSION_2_1);
@@ -358,7 +359,7 @@ CdmResponseType CdmLicense::PrepareKeyRequest(
if (license_request_signature.empty()) {
LOGE("License request signature is empty");
signed_request->clear();
return EMPTY_LICENSE_REQUEST;
return CdmResponseType(EMPTY_LICENSE_REQUEST);
}
// Put serialized license request and signature together
@@ -371,7 +372,7 @@ CdmResponseType CdmLicense::PrepareKeyRequest(
signed_message.SerializeToString(signed_request);
*server_url = server_url_;
return KEY_MESSAGE;
return CdmResponseType(KEY_MESSAGE);
}
// TODO(b/166007195): Remove this.
@@ -381,7 +382,7 @@ CdmResponseType CdmLicense::PrepareKeyUpdateReload(CdmSession* cdm_session) {
LOGW("Unknown API Version");
api_version = 16;
}
if (api_version != 16) return NO_ERROR;
if (api_version != 16) return CdmResponseType(NO_ERROR);
// To work around b/166010609, we ask OEMCrypto to prepare an unused renewal
// request. This lets the ODK library update its clock saying when the renewal
// was signed.
@@ -399,26 +400,26 @@ CdmResponseType CdmLicense::PrepareKeyUpdateRequest(
std::string* server_url) {
if (!initialized_) {
LOGE("CdmLicense not initialized");
return LICENSE_PARSER_NOT_INITIALIZED_1;
return CdmResponseType(LICENSE_PARSER_NOT_INITIALIZED_1);
}
if (signed_request == nullptr) {
LOGE("Output parameter |signed_request| not provided");
return INVALID_PARAMETERS_LIC_1;
return CdmResponseType(INVALID_PARAMETERS_LIC_1);
}
if (server_url == nullptr) {
LOGE("Output parameter |server_url| not provided");
return INVALID_PARAMETERS_LIC_2;
return CdmResponseType(INVALID_PARAMETERS_LIC_2);
}
if (is_renewal && !policy_engine_->CanRenew()) {
LOGE("License renewal prohibited");
return LICENSE_RENEWAL_PROHIBITED;
return CdmResponseType(LICENSE_RENEWAL_PROHIBITED);
}
if (renew_with_client_id_) {
if (use_privacy_mode_ && !service_certificate_.has_certificate()) {
LOGE("Privacy mode failure: No service certificate");
return PRIVACY_MODE_ERROR_2;
return CdmResponseType(PRIVACY_MODE_ERROR_2);
}
}
@@ -465,7 +466,7 @@ CdmResponseType CdmLicense::PrepareKeyUpdateRequest(
if (NO_ERROR == status)
current_license->set_session_usage_table_entry(usage_report);
else
return GENERATE_USAGE_REPORT_ERROR;
return CdmResponseType(GENERATE_USAGE_REPORT_ERROR);
}
}
@@ -495,7 +496,7 @@ CdmResponseType CdmLicense::PrepareKeyUpdateRequest(
if (license_request_signature.empty()) {
LOGE("License request signature is empty");
return EMPTY_LICENSE_RENEWAL;
return CdmResponseType(EMPTY_LICENSE_RENEWAL);
}
// Put serialize license request and signature together
@@ -507,27 +508,27 @@ CdmResponseType CdmLicense::PrepareKeyUpdateRequest(
signed_message.SerializeToString(signed_request);
*server_url = server_url_;
return KEY_MESSAGE;
return CdmResponseType(KEY_MESSAGE);
}
CdmResponseType CdmLicense::HandleKeyResponse(
bool is_restore, const CdmKeyResponse& license_response) {
if (!initialized_) {
LOGE("CdmLicense not initialized");
return LICENSE_PARSER_NOT_INITIALIZED_2;
return CdmResponseType(LICENSE_PARSER_NOT_INITIALIZED_2);
}
// Clear the latest service version when we receive a new response.
latest_service_version_.Clear();
if (license_response.empty()) {
LOGE("License response is empty");
return EMPTY_LICENSE_RESPONSE_1;
return CdmResponseType(EMPTY_LICENSE_RESPONSE_1);
}
SignedMessage signed_response;
if (!signed_response.ParseFromString(license_response)) {
LOGE("Unable to parse signed license response");
return INVALID_LICENSE_RESPONSE;
return CdmResponseType(INVALID_LICENSE_RESPONSE);
}
latest_service_version_ = signed_response.service_version_info();
@@ -540,7 +541,7 @@ CdmResponseType CdmLicense::HandleKeyResponse(
if (status != NO_ERROR) return status;
status = service_certificate_.Init(signed_certificate);
return (status == NO_ERROR) ? NEED_KEY : status;
return (status == NO_ERROR) ? CdmResponseType(NEED_KEY) : status;
}
if (signed_response.type() == SignedMessage::ERROR_RESPONSE)
@@ -549,12 +550,12 @@ CdmResponseType CdmLicense::HandleKeyResponse(
if (signed_response.type() != SignedMessage::LICENSE) {
LOGE("Unrecognized signed message type: type = %d",
static_cast<int>(signed_response.type()));
return INVALID_LICENSE_TYPE;
return CdmResponseType(INVALID_LICENSE_TYPE);
}
if (!signed_response.has_signature()) {
LOGE("License response is not signed");
return LICENSE_RESPONSE_NOT_SIGNED;
return CdmResponseType(LICENSE_RESPONSE_NOT_SIGNED);
}
const std::string& signed_message = signed_response.msg();
@@ -564,12 +565,12 @@ CdmResponseType CdmLicense::HandleKeyResponse(
License license;
if (!license.ParseFromString(signed_message)) {
LOGE("Unable to parse license response");
return LICENSE_RESPONSE_PARSE_ERROR_1;
return CdmResponseType(LICENSE_RESPONSE_PARSE_ERROR_1);
}
if (!signed_response.has_session_key()) {
LOGE("Signed response has no session keys present");
return SESSION_KEYS_NOT_FOUND;
return CdmResponseType(SESSION_KEYS_NOT_FOUND);
}
CdmResponseType status = crypto_session_->GenerateDerivedKeys(
key_request_, signed_response.session_key());
@@ -597,7 +598,7 @@ CdmResponseType CdmLicense::HandleKeyResponse(
"MAC key/IV size error: expected = %zu/%zu, "
"actual = %zu/%zu (key/iv)",
kLicenseMacKeySize, KEY_IV_SIZE, mac_keys.size(), mac_key_iv.size());
return KEY_SIZE_ERROR_1;
return CdmResponseType(KEY_SIZE_ERROR_1);
}
}
@@ -614,7 +615,7 @@ CdmResponseType CdmLicense::HandleKeyResponse(
}
if (key_array.empty()) {
LOGE("No content keys");
return NO_CONTENT_KEY;
return CdmResponseType(NO_CONTENT_KEY);
}
license_key_type_ = key_type;
@@ -645,7 +646,7 @@ CdmResponseType CdmLicense::HandleKeyResponse(
crypto_session_->UseSecondaryKey(signed_response.using_secondary_key());
if (status != NO_ERROR) return status;
CdmResponseType resp = NO_CONTENT_KEY;
CdmResponseType resp(NO_CONTENT_KEY);
if (kLicenseKeyTypeEntitlement == key_type) {
resp =
HandleEntitlementKeyResponse(is_restore, signed_message, core_message,
@@ -661,17 +662,17 @@ CdmResponseType CdmLicense::HandleKeyUpdateResponse(
bool is_renewal, bool is_restore, const CdmKeyResponse& license_response) {
if (!initialized_) {
LOGE("CdmLicense not initialized");
return LICENSE_PARSER_NOT_INITIALIZED_3;
return CdmResponseType(LICENSE_PARSER_NOT_INITIALIZED_3);
}
if (license_response.empty()) {
LOGE("License response is empty");
return EMPTY_LICENSE_RESPONSE_2;
return CdmResponseType(EMPTY_LICENSE_RESPONSE_2);
}
SignedMessage signed_response;
if (!signed_response.ParseFromString(license_response)) {
LOGE("Unable to parse signed message");
return LICENSE_RESPONSE_PARSE_ERROR_2;
return CdmResponseType(LICENSE_RESPONSE_PARSE_ERROR_2);
}
switch (signed_response.type()) {
@@ -682,7 +683,7 @@ CdmResponseType CdmLicense::HandleKeyUpdateResponse(
default:
LOGE("Unrecognized signed message type: type = %d",
static_cast<int>(signed_response.type()));
return INVALID_LICENSE_TYPE;
return CdmResponseType(INVALID_LICENSE_TYPE);
}
const std::string& signed_message = signed_response.msg();
@@ -691,23 +692,23 @@ CdmResponseType CdmLicense::HandleKeyUpdateResponse(
if (is_renewal && core_message.empty()) {
LOGE("Renewal response is missing |core_message| field");
return CORE_MESSAGE_NOT_FOUND;
return CdmResponseType(CORE_MESSAGE_NOT_FOUND);
}
if (signature.empty()) {
LOGE("Update key response is missing signature");
return SIGNATURE_NOT_FOUND;
return CdmResponseType(SIGNATURE_NOT_FOUND);
}
License license;
if (!license.ParseFromString(signed_message)) {
LOGE("Unable to parse license from signed message");
return LICENSE_RESPONSE_PARSE_ERROR_3;
return CdmResponseType(LICENSE_RESPONSE_PARSE_ERROR_3);
}
if (!license.has_id()) {
LOGE("License ID not present");
return LICENSE_ID_NOT_FOUND;
return CdmResponseType(LICENSE_ID_NOT_FOUND);
}
if (license.policy().has_always_include_client_id()) {
@@ -715,9 +716,10 @@ CdmResponseType CdmLicense::HandleKeyUpdateResponse(
}
if (!is_renewal) {
if (!license.id().has_provider_session_token()) return KEY_ADDED;
if (!license.id().has_provider_session_token())
return CdmResponseType(KEY_ADDED);
provider_session_token_ = license.id().provider_session_token();
return KEY_ADDED;
return CdmResponseType(KEY_ADDED);
}
if (license.policy().has_renewal_server_url() &&
@@ -753,12 +755,12 @@ CdmResponseType CdmLicense::RestoreOfflineLicense(
CdmSession* cdm_session) {
if (license_request.empty()) {
LOGE("License request is empty");
return EMPTY_LICENSE_REQUEST_2;
return CdmResponseType(EMPTY_LICENSE_REQUEST_2);
}
if (license_response.empty()) {
LOGE("License response is empty");
return EMPTY_LICENSE_RESPONSE_3;
return CdmResponseType(EMPTY_LICENSE_RESPONSE_3);
}
client_token_ = client_token;
@@ -766,14 +768,14 @@ CdmResponseType CdmLicense::RestoreOfflineLicense(
SignedMessage signed_request;
if (!signed_request.ParseFromString(license_request)) {
LOGE("Failed to parse license request");
return PARSE_REQUEST_ERROR_1;
return CdmResponseType(PARSE_REQUEST_ERROR_1);
}
if (signed_request.type() != SignedMessage::LICENSE_REQUEST) {
LOGE("Unexpected license request type: expected = %d, actual = %d",
static_cast<int>(SignedMessage::LICENSE_REQUEST),
static_cast<int>(signed_request.type()));
return INVALID_LICENSE_REQUEST_TYPE_1;
return CdmResponseType(INVALID_LICENSE_REQUEST_TYPE_1);
}
key_request_ = signed_request.msg();
@@ -832,7 +834,7 @@ CdmResponseType CdmLicense::RestoreOfflineLicense(
policy_engine_->RestorePlaybackTimes(playback_start_time, last_playback_time,
grace_period_end_time);
return NO_ERROR;
return CdmResponseType(NO_ERROR);
}
CdmResponseType CdmLicense::RestoreLicenseForRelease(
@@ -840,12 +842,12 @@ CdmResponseType CdmLicense::RestoreLicenseForRelease(
const CdmKeyResponse& license_response) {
if (license_request.empty()) {
LOGE("License request is empty");
return EMPTY_LICENSE_REQUEST_3;
return CdmResponseType(EMPTY_LICENSE_REQUEST_3);
}
if (license_response.empty()) {
LOGE("License response is empty");
return EMPTY_LICENSE_RESPONSE_4;
return CdmResponseType(EMPTY_LICENSE_RESPONSE_4);
}
client_token_ = client_token;
@@ -853,14 +855,14 @@ CdmResponseType CdmLicense::RestoreLicenseForRelease(
SignedMessage signed_request;
if (!signed_request.ParseFromString(license_request)) {
LOGE("Failed to parse signed license request");
return PARSE_REQUEST_ERROR_2;
return CdmResponseType(PARSE_REQUEST_ERROR_2);
}
if (signed_request.type() != SignedMessage::LICENSE_REQUEST) {
LOGE("Unexpected signed license request type: expected = %d, actual = %d",
static_cast<int>(SignedMessage::LICENSE_REQUEST),
static_cast<int>(signed_request.type()));
return INVALID_LICENSE_REQUEST_TYPE_2;
return CdmResponseType(INVALID_LICENSE_REQUEST_TYPE_2);
}
key_request_ = signed_request.msg();
@@ -868,30 +870,30 @@ CdmResponseType CdmLicense::RestoreLicenseForRelease(
SignedMessage signed_response;
if (!signed_response.ParseFromString(license_response)) {
LOGE("Failed to parse signed license response");
return LICENSE_RESPONSE_PARSE_ERROR_4;
return CdmResponseType(LICENSE_RESPONSE_PARSE_ERROR_4);
}
if (SignedMessage::LICENSE != signed_response.type()) {
LOGE("Unexpected signed license response type: expected = %d, actual = %d",
static_cast<int>(SignedMessage::LICENSE),
static_cast<int>(signed_response.type()));
return INVALID_LICENSE_TYPE_2;
return CdmResponseType(INVALID_LICENSE_TYPE_2);
}
if (!signed_response.has_signature()) {
LOGE("License response is not signed");
return SIGNATURE_NOT_FOUND_2;
return CdmResponseType(SIGNATURE_NOT_FOUND_2);
}
if (!signed_response.has_oemcrypto_core_message()) {
LOGE("License response is missing core message");
return CORE_MESSAGE_NOT_FOUND;
return CdmResponseType(CORE_MESSAGE_NOT_FOUND);
}
License license;
if (!license.ParseFromString(signed_response.msg())) {
LOGE("Failed to parse license response");
return LICENSE_RESPONSE_PARSE_ERROR_5;
return CdmResponseType(LICENSE_RESPONSE_PARSE_ERROR_5);
}
if (license.has_provider_client_token())
@@ -905,12 +907,12 @@ CdmResponseType CdmLicense::RestoreLicenseForRelease(
if (!signed_response.has_session_key()) {
LOGE("No session keys present");
return SESSION_KEYS_NOT_FOUND_2;
return CdmResponseType(SESSION_KEYS_NOT_FOUND_2);
}
if (!license.id().has_provider_session_token()) {
CdmResponseType result = HandleKeyResponse(false, license_response);
return result == KEY_ADDED ? NO_ERROR : result;
return result == KEY_ADDED ? CdmResponseType(NO_ERROR) : result;
}
if (license.policy().has_renewal_server_url())
@@ -919,7 +921,7 @@ CdmResponseType CdmLicense::RestoreLicenseForRelease(
// If the policy engine already has keys, they will now expire.
// If the policy engine does not already have keys, this will not add any.
policy_engine_->SetLicenseForRelease(license);
return NO_ERROR;
return CdmResponseType(NO_ERROR);
}
bool CdmLicense::IsKeyLoaded(const KeyId& key_id) {
@@ -967,19 +969,20 @@ CdmResponseType CdmLicense::HandleKeyErrorResponse(
LicenseError license_error;
if (!license_error.ParseFromString(signed_message.msg())) {
LOGE("Failed to parse license error response");
return KEY_ERROR;
return CdmResponseType(KEY_ERROR);
}
// TODO(b/261185349) Add new field in CdmResponseType to handle license_error
switch (license_error.error_code()) {
case LicenseError::INVALID_DRM_DEVICE_CERTIFICATE:
return NEED_PROVISIONING;
return CdmResponseType(NEED_PROVISIONING);
case LicenseError::REVOKED_DRM_DEVICE_CERTIFICATE:
return DEVICE_REVOKED;
return CdmResponseType(DEVICE_REVOKED);
case LicenseError::SERVICE_UNAVAILABLE:
default:
LOGW("Unknown error type: error_code = %d",
static_cast<int>(license_error.error_code()));
return KEY_ERROR;
return CdmResponseType(KEY_ERROR);
}
}
@@ -989,7 +992,7 @@ CdmResponseType CdmLicense::PrepareClientId(
wvcdm::ClientIdentification id;
if (client_token_.empty()) {
LOGE("Client token not set when preparing client ID");
return CLIENT_TOKEN_NOT_SET;
return CdmResponseType(CLIENT_TOKEN_NOT_SET);
}
CdmResponseType status =
@@ -1004,7 +1007,7 @@ CdmResponseType CdmLicense::PrepareClientId(
if (Properties::UsePrivacyMode(session_id_)) {
if (!service_certificate_.has_certificate()) {
LOGE("Service certificate not staged");
return PRIVACY_MODE_ERROR_3;
return CdmResponseType(PRIVACY_MODE_ERROR_3);
}
EncryptedClientIdentification* encrypted_client_id =
license_request->mutable_encrypted_client_id();
@@ -1017,7 +1020,7 @@ CdmResponseType CdmLicense::PrepareClientId(
}
return status;
}
return NO_ERROR;
return CdmResponseType(NO_ERROR);
}
CdmResponseType CdmLicense::PrepareContentId(
@@ -1035,11 +1038,11 @@ CdmResponseType CdmLicense::PrepareContentId(
widevine_pssh_data->add_pssh_data(init_data.data());
} else {
LOGE("ISO-CENC init data not available");
return CENC_INIT_DATA_UNAVAILABLE;
return CdmResponseType(CENC_INIT_DATA_UNAVAILABLE);
}
if (!SetTypeAndId(license_type, request_id, widevine_pssh_data)) {
return PREPARE_CENC_CONTENT_ID_FAILED;
return CdmResponseType(PREPARE_CENC_CONTENT_ID_FAILED);
}
} else if (init_data.is_webm()) {
LicenseRequest_ContentIdentification_WebmKeyId* webm_key_id =
@@ -1049,17 +1052,17 @@ CdmResponseType CdmLicense::PrepareContentId(
webm_key_id->set_header(init_data.data());
} else {
LOGE("WebM init data not available");
return WEBM_INIT_DATA_UNAVAILABLE;
return CdmResponseType(WEBM_INIT_DATA_UNAVAILABLE);
}
if (!SetTypeAndId(license_type, request_id, webm_key_id)) {
return PREPARE_WEBM_CONTENT_ID_FAILED;
return CdmResponseType(PREPARE_WEBM_CONTENT_ID_FAILED);
}
} else {
LOGE("Unsupported init data type: type = %s", init_data.type().c_str());
return UNSUPPORTED_INIT_DATA_FORMAT;
return CdmResponseType(UNSUPPORTED_INIT_DATA_FORMAT);
}
return NO_ERROR;
return CdmResponseType(NO_ERROR);
}
CdmResponseType CdmLicense::HandleContentKeyResponse(
@@ -1068,7 +1071,7 @@ CdmResponseType CdmLicense::HandleContentKeyResponse(
const video_widevine::License& license) {
if (key_array.empty()) {
LOGE("No content keys provided");
return NO_CONTENT_KEY;
return CdmResponseType(NO_CONTENT_KEY);
}
const CdmResponseType resp = crypto_session_->LoadLicense(
msg, core_message, signature, kLicenseKeyTypeContent);
@@ -1088,7 +1091,7 @@ CdmResponseType CdmLicense::HandleEntitlementKeyResponse(
const video_widevine::License& license) {
if (key_array.empty()) {
LOGE("No entitlement keys provided");
return NO_CONTENT_KEY;
return CdmResponseType(NO_CONTENT_KEY);
}
const CdmResponseType resp = crypto_session_->LoadLicense(
msg, core_message, signature, kLicenseKeyTypeEntitlement);
@@ -1120,7 +1123,7 @@ CdmResponseType CdmLicense::HandleNewEntitledKeys(
"Entitled content key too small: "
"expected = %zu, actual = %zu (bytes)",
CONTENT_KEY_SIZE, content_key.size());
return KEY_SIZE_ERROR_2;
return CdmResponseType(KEY_SIZE_ERROR_2);
} else if (content_key.size() > CONTENT_KEY_SIZE) {
content_key.resize(CONTENT_KEY_SIZE);
}
@@ -1142,7 +1145,7 @@ CdmResponseType CdmLicense::HandleNewEntitledKeys(
loaded_keys_.insert(wk.key_id());
}
policy_engine_->SetEntitledLicenseKeys(wrapped_keys);
return KEY_ADDED;
return CdmResponseType(KEY_ADDED);
}
template <typename T>

View File

@@ -129,21 +129,21 @@ CdmResponseType OtaKeyboxProvisioner::GetProvisioningRequest(
std::string* request, std::string* default_url) {
if (request == nullptr) {
LOGE("Output |request| is null");
return PARAMETER_NULL;
return CdmResponseType(PARAMETER_NULL);
}
if (default_url == nullptr) {
LOGE("Output |default_url| is null");
return PARAMETER_NULL;
return CdmResponseType(PARAMETER_NULL);
}
if (IsProvisioned()) {
LOGW("Already provisioned");
CleanUp();
return OKP_ALREADY_PROVISIONED;
return CdmResponseType(OKP_ALREADY_PROVISIONED);
}
if (!crypto_session_) {
LOGE("Crypto session has been released, OKP unavailable");
// Caller should not reuse provisioner after failure.
return UNKNOWN_ERROR;
return CdmResponseType(UNKNOWN_ERROR);
}
// Step 1: Generate raw request from OEMCrypto.
std::string ota_request_data;
@@ -155,8 +155,7 @@ CdmResponseType OtaKeyboxProvisioner::GetProvisioningRequest(
CleanUp();
return result;
} else if (result != NO_ERROR) {
LOGE("Failed to generate OKP request: status = %d",
static_cast<int>(result));
LOGE("Failed to generate OKP request: status = %d", result.Enum());
return result;
}
// Step 2: Wrap in ProvisioningRequest.
@@ -165,7 +164,7 @@ CdmResponseType OtaKeyboxProvisioner::GetProvisioningRequest(
result = client_id_.Prepare(kEmptyAppParameters, kEmptyString, client_id);
if (result != NO_ERROR) {
LOGW("Failed to prepare client ID, continuing without: result = %d",
static_cast<int>(result));
result.Enum());
client_id->Clear();
}
LOGI("OTA request generated");
@@ -189,36 +188,36 @@ CdmResponseType OtaKeyboxProvisioner::GetProvisioningRequest(
request_generated_ = true;
CertificateProvisioning::GetProvisioningServerUrl(default_url);
return NO_ERROR;
return CdmResponseType(NO_ERROR);
}
CdmResponseType OtaKeyboxProvisioner::HandleProvisioningResponse(
const std::string& response) {
if (response.empty()) {
LOGE("Signed provisioning message is empty");
return EMPTY_PROVISIONING_RESPONSE;
return CdmResponseType(EMPTY_PROVISIONING_RESPONSE);
}
if (IsProvisioned()) {
LOGD("Already provisioned");
response_received_ = true;
CleanUp();
return NO_ERROR;
return CdmResponseType(NO_ERROR);
}
if (!request_generated_) {
LOGE("Received response without generating request");
return UNKNOWN_ERROR;
return CdmResponseType(UNKNOWN_ERROR);
}
if (!crypto_session_) {
LOGE("Crypto session has been released, OKP unavailable");
// Caller should not reuse provisioner after failure.
return UNKNOWN_ERROR;
return CdmResponseType(UNKNOWN_ERROR);
}
std::string decoded_response;
if (!wvcdm::Properties::provisioning_messages_are_binary()) {
if (!CertificateProvisioning::ExtractAndDecodeSignedMessage(
response, &decoded_response)) {
LOGE("Failed to extract OKP provisioning response");
return PARSE_OKP_RESPONSE_ERROR;
return CdmResponseType(PARSE_OKP_RESPONSE_ERROR);
}
} else {
decoded_response = response;
@@ -227,38 +226,38 @@ CdmResponseType OtaKeyboxProvisioner::HandleProvisioningResponse(
SignedProvisioningMessage signed_response;
if (!signed_response.ParseFromString(decoded_response)) {
LOGE("Failed to parse SignedProvisioningMessage");
return PARSE_OKP_RESPONSE_ERROR;
return CdmResponseType(PARSE_OKP_RESPONSE_ERROR);
}
if (!signed_response.has_message()) {
LOGE("Signed response is missing message");
return PARSE_OKP_RESPONSE_ERROR;
return CdmResponseType(PARSE_OKP_RESPONSE_ERROR);
}
if (signed_response.provisioning_type() !=
SignedProvisioningMessage::ANDROID_ATTESTATION_KEYBOX_OTA) {
LOGE("Unexpected protocol type/version: protocol_type = %d",
static_cast<int>(signed_response.provisioning_type()));
return PARSE_OKP_RESPONSE_ERROR;
return CdmResponseType(PARSE_OKP_RESPONSE_ERROR);
}
// Step 2: Unwrap from ProvisioningResponse.
ProvisioningResponse prov_response;
if (!prov_response.ParseFromString(signed_response.message())) {
LOGE("Failed to parse ProvisioningResponse");
return PARSE_OKP_RESPONSE_ERROR;
return CdmResponseType(PARSE_OKP_RESPONSE_ERROR);
}
if (!prov_response.has_android_ota_keybox_response()) {
LOGE("Missing OTA keybox response message");
return PARSE_OKP_RESPONSE_ERROR;
return CdmResponseType(PARSE_OKP_RESPONSE_ERROR);
}
const OtaResponse& ota_response = prov_response.android_ota_keybox_response();
if (!ota_response.has_ota_response()) {
LOGE("Missing OTA keybox response data");
return PARSE_OKP_RESPONSE_ERROR;
return CdmResponseType(PARSE_OKP_RESPONSE_ERROR);
}
// Step 3: Load response.
const std::string ota_response_data = ota_response.ota_response();
if (ota_response_data.empty()) {
LOGE("Raw OTA response is empty");
return PARSE_OKP_RESPONSE_ERROR;
return CdmResponseType(PARSE_OKP_RESPONSE_ERROR);
}
const CdmResponseType result = crypto_session_->LoadOtaProvisioning(
kProductionKeybox, ota_response_data);

View File

@@ -283,7 +283,7 @@ CdmResponseType PolicyEngine::Query(CdmQueryMap* query_response) {
if (license_state_ == kLicenseStateInitial) {
query_response->clear();
return NO_ERROR;
return CdmResponseType(NO_ERROR);
}
(*query_response)[QUERY_KEY_LICENSE_TYPE] =
@@ -307,19 +307,19 @@ CdmResponseType PolicyEngine::Query(CdmQueryMap* query_response) {
(*query_response)[QUERY_KEY_RENEWAL_SERVER_URL] =
policy_timers_->get_policy().renewal_server_url();
return NO_ERROR;
return CdmResponseType(NO_ERROR);
}
CdmResponseType PolicyEngine::QueryKeyAllowedUsage(
const KeyId& key_id, CdmKeyAllowedUsage* key_usage) {
if (key_usage == nullptr) {
LOGE("Output parameter |key_usage| not provided");
return PARAMETER_NULL;
return CdmResponseType(PARAMETER_NULL);
}
if (license_keys_->GetAllowedUsage(key_id, key_usage)) {
return NO_ERROR;
return CdmResponseType(NO_ERROR);
}
return KEY_NOT_FOUND_1;
return CdmResponseType(KEY_NOT_FOUND_1);
}
bool PolicyEngine::CanUseKeyForSecurityLevel(const KeyId& key_id) {

View File

@@ -143,17 +143,17 @@ CdmResponseType ServiceCertificate::Init(const std::string& certificate) {
SignedDrmCertificate signed_root_cert;
if (!signed_root_cert.ParseFromString(root_cert_str)) {
LOGE("Failed to deserialize signed root certificate");
return DEVICE_CERTIFICATE_ERROR_1;
return CdmResponseType(DEVICE_CERTIFICATE_ERROR_1);
}
DrmCertificate root_cert;
if (!root_cert.ParseFromString(signed_root_cert.drm_certificate())) {
LOGE("Failed to deserialize root certificate");
return DEVICE_CERTIFICATE_ERROR_1;
return CdmResponseType(DEVICE_CERTIFICATE_ERROR_1);
}
RsaPublicKey root_key;
if (!root_key.Init(root_cert.public_key())) {
LOGE("Failed to load root certificate public key");
return DEVICE_CERTIFICATE_ERROR_1;
return CdmResponseType(DEVICE_CERTIFICATE_ERROR_1);
}
// Load the provided service certificate.
@@ -161,7 +161,7 @@ CdmResponseType ServiceCertificate::Init(const std::string& certificate) {
SignedDrmCertificate signed_service_cert;
if (!signed_service_cert.ParseFromString(certificate)) {
LOGE("Failed to parse signed service certificate");
return DEVICE_CERTIFICATE_ERROR_2;
return CdmResponseType(DEVICE_CERTIFICATE_ERROR_2);
}
#ifdef ACCEPT_TEST_CERT
@@ -170,14 +170,14 @@ CdmResponseType ServiceCertificate::Init(const std::string& certificate) {
if (!root_key.VerifySignature(signed_service_cert.drm_certificate(),
signed_service_cert.signature())) {
LOGE("Failed to verify service certificate signature");
return DEVICE_CERTIFICATE_ERROR_3;
return CdmResponseType(DEVICE_CERTIFICATE_ERROR_3);
}
#endif
DrmCertificate service_cert;
if (!service_cert.ParseFromString(signed_service_cert.drm_certificate())) {
LOGE("Failed to parse service certificate");
return DEVICE_CERTIFICATE_ERROR_2;
return CdmResponseType(DEVICE_CERTIFICATE_ERROR_2);
}
if (service_cert.type() != video_widevine::DrmCertificate_Type_SERVICE) {
LOGE(
@@ -185,7 +185,7 @@ CdmResponseType ServiceCertificate::Init(const std::string& certificate) {
"type = %d, expected_type = %d",
static_cast<int>(service_cert.type()),
static_cast<int>(video_widevine::DrmCertificate_Type_SERVICE));
return DEVICE_CERTIFICATE_ERROR_3;
return CdmResponseType(DEVICE_CERTIFICATE_ERROR_3);
}
// Service certificate passes all checks - set up its RSA public key.
@@ -193,7 +193,7 @@ CdmResponseType ServiceCertificate::Init(const std::string& certificate) {
if (!public_key_->Init(service_cert.public_key())) {
public_key_.reset();
LOGE("Failed to load service certificate public key");
return DEVICE_CERTIFICATE_ERROR_2;
return CdmResponseType(DEVICE_CERTIFICATE_ERROR_2);
}
// Have service certificate and its public key - keep relevant fields.
@@ -202,33 +202,34 @@ CdmResponseType ServiceCertificate::Init(const std::string& certificate) {
provider_id_ = service_cert.provider_id();
has_certificate_ = true;
return NO_ERROR;
return CdmResponseType(NO_ERROR);
}
CdmResponseType ServiceCertificate::VerifySignedMessage(
const std::string& message, const std::string& signature) const {
if (!public_key_) {
LOGE("Service certificate not set");
return DEVICE_CERTIFICATE_ERROR_4;
return CdmResponseType(DEVICE_CERTIFICATE_ERROR_4);
}
if (!public_key_->VerifySignature(message, signature))
return CLIENT_ID_RSA_ENCRYPT_ERROR; // TODO(tinskip): Need new error code.
return CdmResponseType(
CLIENT_ID_RSA_ENCRYPT_ERROR); // TODO(tinskip): Need new error code.
return NO_ERROR;
return CdmResponseType(NO_ERROR);
}
CdmResponseType ServiceCertificate::EncryptRsaOaep(
const std::string& plaintext, std::string* ciphertext) const {
if (!public_key_) {
LOGE("Service certificate not set");
return DEVICE_CERTIFICATE_ERROR_4;
return CdmResponseType(DEVICE_CERTIFICATE_ERROR_4);
}
if (!public_key_->Encrypt(plaintext, ciphertext))
return CLIENT_ID_RSA_ENCRYPT_ERROR;
return CdmResponseType(CLIENT_ID_RSA_ENCRYPT_ERROR);
return NO_ERROR;
return CdmResponseType(NO_ERROR);
}
CdmResponseType ServiceCertificate::EncryptClientId(
@@ -245,8 +246,9 @@ CdmResponseType ServiceCertificate::EncryptClientId(
if (status != NO_ERROR) {
LOGE("GetRandom failed for key: status = %d", static_cast<int>(status));
return (status == RANDOM_GENERATION_ERROR) ? CLIENT_ID_GENERATE_RANDOM_ERROR
: status;
return (status == RANDOM_GENERATION_ERROR)
? CdmResponseType(CLIENT_ID_GENERATE_RANDOM_ERROR)
: status;
}
status =
@@ -254,15 +256,17 @@ CdmResponseType ServiceCertificate::EncryptClientId(
if (status != NO_ERROR) {
LOGE("GetRandom failed for IV: status = %d", static_cast<int>(status));
return (status == RANDOM_GENERATION_ERROR) ? CLIENT_ID_GENERATE_RANDOM_ERROR
: status;
return (status == RANDOM_GENERATION_ERROR)
? CdmResponseType(CLIENT_ID_GENERATE_RANDOM_ERROR)
: status;
}
std::string id, enc_id, enc_key;
clear_client_id->SerializeToString(&id);
AesCbcKey aes;
if (!aes.Init(key)) return CLIENT_ID_AES_INIT_ERROR;
if (!aes.Encrypt(id, &enc_id, &iv)) return CLIENT_ID_AES_ENCRYPT_ERROR;
if (!aes.Init(key)) return CdmResponseType(CLIENT_ID_AES_INIT_ERROR);
if (!aes.Encrypt(id, &enc_id, &iv))
return CdmResponseType(CLIENT_ID_AES_ENCRYPT_ERROR);
CdmResponseType encrypt_result = EncryptRsaOaep(key, &enc_key);
if (encrypt_result != NO_ERROR) return encrypt_result;
@@ -270,7 +274,7 @@ CdmResponseType ServiceCertificate::EncryptClientId(
encrypted_client_id->set_encrypted_client_id_iv(iv);
encrypted_client_id->set_encrypted_privacy_key(enc_key);
encrypted_client_id->set_encrypted_client_id(enc_id);
return NO_ERROR;
return CdmResponseType(NO_ERROR);
}
bool ServiceCertificate::GetRequest(CdmKeyMessage* request) {
@@ -288,39 +292,39 @@ CdmResponseType ServiceCertificate::ParseResponse(const std::string& response,
std::string* certificate) {
if (response.empty()) {
LOGE("Response is empty");
return EMPTY_RESPONSE_ERROR_1;
return CdmResponseType(EMPTY_RESPONSE_ERROR_1);
}
if (certificate == nullptr) {
LOGE("Output parameter |certificate| not provided");
return INVALID_PARAMETERS_ENG_24;
return CdmResponseType(INVALID_PARAMETERS_ENG_24);
}
SignedMessage signed_response;
if (!signed_response.ParseFromString(response)) {
LOGE("Failed to parse signed response");
return PARSE_RESPONSE_ERROR_1;
return CdmResponseType(PARSE_RESPONSE_ERROR_1);
}
if (signed_response.type() == SignedMessage::ERROR_RESPONSE) {
LicenseError license_error;
if (!license_error.ParseFromString(signed_response.msg())) {
LOGE("Failed to parse license error");
return PARSE_RESPONSE_ERROR_2;
return CdmResponseType(PARSE_RESPONSE_ERROR_2);
}
LOGE("Server response contains error: error_code = %d",
static_cast<int>(license_error.error_code()));
return PARSE_RESPONSE_ERROR_3;
return CdmResponseType(PARSE_RESPONSE_ERROR_3);
}
if (signed_response.type() != SignedMessage::SERVICE_CERTIFICATE) {
LOGE("Unexpected response type: type = %d, expected_type = %d",
static_cast<int>(signed_response.type()),
static_cast<int>(SignedMessage::SERVICE_CERTIFICATE));
return PARSE_RESPONSE_ERROR_4;
return CdmResponseType(PARSE_RESPONSE_ERROR_4);
}
certificate->assign(signed_response.msg());
return NO_ERROR;
return CdmResponseType(NO_ERROR);
}
} // namespace wvcdm

View File

@@ -53,8 +53,7 @@ bool SystemIdExtractor::ExtractSystemId(uint32_t* system_id) {
crypto_session_->GetProvisioningMethod(security_level_, &type);
if (status != NO_ERROR) {
LOGE("Failed to get provisioning method: security_level = %s, status = %d",
RequestedSecurityLevelToString(security_level_),
static_cast<int>(status));
RequestedSecurityLevelToString(security_level_), status.Enum());
return false;
}
bool success = false;
@@ -122,8 +121,7 @@ bool SystemIdExtractor::ExtractSystemIdProv20(uint32_t* system_id) {
}
if (status != NO_ERROR) {
LOGE("Failed to get keybox data: security_level = %s, status = %d",
RequestedSecurityLevelToString(security_level_),
static_cast<int>(status));
RequestedSecurityLevelToString(security_level_), status.Enum());
return false;
}
if (!ExtractSystemIdFromKeyboxData(key_data, system_id)) {
@@ -139,8 +137,7 @@ bool SystemIdExtractor::ExtractSystemIdProv30(uint32_t* system_id) {
crypto_session_->GetTokenFromOemCert(security_level_, &oem_cert);
if (status != NO_ERROR) {
LOGE("Failed to get OEM certificate: security_level = %s, status = %d",
RequestedSecurityLevelToString(security_level_),
static_cast<int>(status));
RequestedSecurityLevelToString(security_level_), status.Enum());
return false;
}
if (!ExtractSystemIdFromOemCert(oem_cert, system_id)) {

View File

@@ -205,8 +205,7 @@ bool UsageTableHeader::RestoreTable(CryptoSession* const crypto_session) {
const CdmResponseType status = crypto_session->LoadUsageTableHeader(
requested_security_level_, usage_table_header_);
if (status != NO_ERROR) {
LOGE("Failed to load usage table header: sts = %d",
static_cast<int>(status));
LOGE("Failed to load usage table header: sts = %d", status.Enum());
return false;
}
@@ -300,7 +299,7 @@ CdmResponseType UsageTableHeader::AddEntry(
return status;
}
StoreTable();
return NO_ERROR;
return CdmResponseType(NO_ERROR);
}
CdmResponseType UsageTableHeader::LoadEntry(CryptoSession* crypto_session,
@@ -315,7 +314,7 @@ CdmResponseType UsageTableHeader::LoadEntry(CryptoSession* crypto_session,
"Requested usage entry number is larger than table size: "
"usage_entry_number = %u, table_size = %zu",
usage_entry_number, usage_entry_info_.size());
return USAGE_INVALID_LOAD_ENTRY;
return CdmResponseType(USAGE_INVALID_LOAD_ENTRY);
}
}
metrics::CryptoMetrics* metrics = crypto_session->GetCryptoMetrics();
@@ -339,7 +338,7 @@ CdmResponseType UsageTableHeader::UpdateEntry(uint32_t usage_entry_number,
if (usage_entry_number >= usage_entry_info_.size()) {
LOGE("Usage entry number %u is larger than usage entry size %zu",
usage_entry_number, usage_entry_info_.size());
return USAGE_INVALID_PARAMETERS_2;
return CdmResponseType(USAGE_INVALID_PARAMETERS_2);
}
CdmResponseType status =
@@ -349,7 +348,7 @@ CdmResponseType UsageTableHeader::UpdateEntry(uint32_t usage_entry_number,
usage_entry_info_[usage_entry_number].last_use_time = GetCurrentTime();
StoreTable();
return NO_ERROR;
return CdmResponseType(NO_ERROR);
}
CdmResponseType UsageTableHeader::InvalidateEntry(
@@ -372,7 +371,7 @@ CdmResponseType UsageTableHeader::InvalidateEntryInternal(
"Usage entry number is larger than table size: "
"usage_entry_number = %u, table_size = %zu",
usage_entry_number, usage_entry_info_.size());
return USAGE_INVALID_PARAMETERS_1;
return CdmResponseType(USAGE_INVALID_PARAMETERS_1);
}
usage_entry_info_[usage_entry_number].Clear();
@@ -395,13 +394,13 @@ CdmResponseType UsageTableHeader::InvalidateEntryInternal(
}
if (status == SYSTEM_INVALIDATED_ERROR) {
LOGE("Invalidate entry failed due to system invalidation error");
return SYSTEM_INVALIDATED_ERROR;
return CdmResponseType(SYSTEM_INVALIDATED_ERROR);
}
} else {
StoreTable();
}
return NO_ERROR;
return CdmResponseType(NO_ERROR);
}
size_t UsageTableHeader::UsageInfoCount() const {
@@ -426,7 +425,7 @@ bool UsageTableHeader::OpenSessionCheck(CryptoSession* const crypto_session) {
LOGE(
"Cannot initialize usage table header with open crypto session: "
"status = %d, count = %zu",
static_cast<int>(status), session_count);
status.Enum(), session_count);
return false;
}
return true;
@@ -460,7 +459,7 @@ bool UsageTableHeader::CapacityCheck(CryptoSession* const crypto_session) {
local_crypto_session->Open(requested_security_level_);
if (status != NO_ERROR) {
LOGE("Failed to open crypto session for capacity test: sts = %d",
static_cast<int>(status));
status.Enum());
return false;
}
@@ -468,8 +467,7 @@ bool UsageTableHeader::CapacityCheck(CryptoSession* const crypto_session) {
status = AddEntry(local_crypto_session, true, kDummyKeySetId, kEmptyString,
kEmptyString, &temporary_usage_entry_number);
if (status != NO_ERROR) {
LOGE("Failed to add entry for capacity test: sts = %d",
static_cast<int>(status));
LOGE("Failed to add entry for capacity test: sts = %d", status.Enum());
return false;
}
@@ -478,7 +476,7 @@ bool UsageTableHeader::CapacityCheck(CryptoSession* const crypto_session) {
/* defrag_table = */ true, device_files_.get(), metrics);
if (status != NO_ERROR) {
LOGE("Failed to invalidate entry for capacity test: sts = %d",
static_cast<int>(status));
status.Enum());
return false;
}
if (usage_entry_info_.size() > temporary_usage_entry_number) {
@@ -528,7 +526,7 @@ CdmResponseType UsageTableHeader::CreateEntry(
"New entry number is smaller than table size: "
"entry_info_number = %u, table_size = %zu",
*usage_entry_number, usage_entry_info_.size());
return USAGE_INVALID_NEW_ENTRY;
return CdmResponseType(USAGE_INVALID_NEW_ENTRY);
}
LOGI("usage_entry_number = %u", *usage_entry_number);
const size_t previous_size = usage_entry_info_.size();
@@ -543,7 +541,7 @@ CdmResponseType UsageTableHeader::CreateEntry(
}
}
usage_entry_info_[*usage_entry_number].Clear();
return NO_ERROR;
return CdmResponseType(NO_ERROR);
}
CdmResponseType UsageTableHeader::RelocateNewEntry(
@@ -552,7 +550,7 @@ CdmResponseType UsageTableHeader::RelocateNewEntry(
const uint32_t initial_entry_number = *usage_entry_number;
if (initial_entry_number == kMinimumEntryNumber) {
// First entry in the table.
return NO_ERROR;
return CdmResponseType(NO_ERROR);
}
uint32_t unoccupied_entry_number = initial_entry_number;
for (uint32_t i = kMinimumEntryNumber; i < initial_entry_number; i++) {
@@ -563,7 +561,7 @@ CdmResponseType UsageTableHeader::RelocateNewEntry(
}
if (unoccupied_entry_number == initial_entry_number) {
// No open position.
return NO_ERROR;
return CdmResponseType(NO_ERROR);
}
const CdmResponseType status =
crypto_session->MoveUsageEntry(unoccupied_entry_number);
@@ -571,7 +569,7 @@ CdmResponseType UsageTableHeader::RelocateNewEntry(
// Not unexpected, there is a window of time between releasing the
// entry and closing the OEMCrypto session.
LOGD("Released entry still in use: index = %u", unoccupied_entry_number);
return NO_ERROR;
return CdmResponseType(NO_ERROR);
}
if (status != NO_ERROR) return status;
LOGI("Entry moved: from_index = %u, to_index = %u", initial_entry_number,
@@ -580,7 +578,7 @@ CdmResponseType UsageTableHeader::RelocateNewEntry(
usage_entry_info_[unoccupied_entry_number] =
std::move(usage_entry_info_[initial_entry_number]);
usage_entry_info_[initial_entry_number].Clear();
return NO_ERROR;
return CdmResponseType(NO_ERROR);
}
bool UsageTableHeader::IsEntryUnoccupied(
@@ -641,7 +639,7 @@ CdmResponseType UsageTableHeader::RefitTable(
if (!IsEntryUnoccupied(usage_entry_number)) break;
++entries_to_remove;
}
if (entries_to_remove == 0) return NO_ERROR;
if (entries_to_remove == 0) return CdmResponseType(NO_ERROR);
const uint32_t new_size = old_size - entries_to_remove;
const CdmResponseType status = crypto_session->ShrinkUsageTableHeader(
requested_security_level_, new_size, &usage_table_header_);
@@ -652,13 +650,13 @@ CdmResponseType UsageTableHeader::RefitTable(
// Safe to assume table state is not invalidated.
LOGW("Unexpected entry in use: range = [%u, %zu]", new_size,
usage_entry_info_.size() - 1);
return NO_ERROR;
return CdmResponseType(NO_ERROR);
}
if (status != NO_ERROR) return status;
LOGD("Table shrunk: old_size = %zu, new_size = %u", usage_entry_info_.size(),
new_size);
usage_entry_info_.resize(new_size);
return NO_ERROR;
return CdmResponseType(NO_ERROR);
}
CdmResponseType UsageTableHeader::MoveEntry(
@@ -720,7 +718,7 @@ CdmResponseType UsageTableHeader::MoveEntry(
StoreTable();
StoreEntry(to_usage_entry_number, device_files, usage_entry);
return NO_ERROR;
return CdmResponseType(NO_ERROR);
}
CdmResponseType UsageTableHeader::GetEntry(uint32_t usage_entry_number,
@@ -741,7 +739,7 @@ CdmResponseType UsageTableHeader::GetEntry(uint32_t usage_entry_number,
&sub_error_code)) {
LOGE("Failed to retrieve license: status = %d",
static_cast<int>(sub_error_code));
return USAGE_GET_ENTRY_RETRIEVE_LICENSE_FAILED;
return CdmResponseType(USAGE_GET_ENTRY_RETRIEVE_LICENSE_FAILED);
}
entry_number = license_data.usage_entry_number;
@@ -761,7 +759,7 @@ CdmResponseType UsageTableHeader::GetEntry(uint32_t usage_entry_number,
&provider_session_token, &license_request, &license, usage_entry,
&entry_number, &drm_certificate, &wrapped_private_key)) {
LOGE("Failed to retrieve usage information");
return USAGE_GET_ENTRY_RETRIEVE_USAGE_INFO_FAILED;
return CdmResponseType(USAGE_GET_ENTRY_RETRIEVE_USAGE_INFO_FAILED);
}
break;
}
@@ -771,7 +769,7 @@ CdmResponseType UsageTableHeader::GetEntry(uint32_t usage_entry_number,
"Cannot retrieve usage information with unknown storage type: "
"storage_type = %d",
static_cast<int>(usage_entry_info_[usage_entry_number].storage_type));
return USAGE_GET_ENTRY_RETRIEVE_INVALID_STORAGE_TYPE;
return CdmResponseType(USAGE_GET_ENTRY_RETRIEVE_INVALID_STORAGE_TYPE);
}
if (usage_entry_number != entry_number) {
@@ -779,10 +777,10 @@ CdmResponseType UsageTableHeader::GetEntry(uint32_t usage_entry_number,
"Usage entry number mismatch: expected_usage_entry_number = %u, "
"retrieved_usage_entry_number = %u",
usage_entry_number, entry_number);
return USAGE_ENTRY_NUMBER_MISMATCH;
return CdmResponseType(USAGE_ENTRY_NUMBER_MISMATCH);
}
return NO_ERROR;
return CdmResponseType(NO_ERROR);
}
CdmResponseType UsageTableHeader::StoreEntry(uint32_t usage_entry_number,
@@ -804,7 +802,7 @@ CdmResponseType UsageTableHeader::StoreEntry(uint32_t usage_entry_number,
&sub_error_code)) {
LOGE("Failed to retrieve license: status = %s",
DeviceFiles::ResponseTypeToString(sub_error_code));
return USAGE_STORE_ENTRY_RETRIEVE_LICENSE_FAILED;
return CdmResponseType(USAGE_STORE_ENTRY_RETRIEVE_LICENSE_FAILED);
}
// Update.
@@ -814,7 +812,7 @@ CdmResponseType UsageTableHeader::StoreEntry(uint32_t usage_entry_number,
if (!device_files->StoreLicense(license_data, &sub_error_code)) {
LOGE("Failed to store license: status = %s",
DeviceFiles::ResponseTypeToString(sub_error_code));
return USAGE_STORE_LICENSE_FAILED;
return CdmResponseType(USAGE_STORE_LICENSE_FAILED);
}
break;
}
@@ -831,7 +829,7 @@ CdmResponseType UsageTableHeader::StoreEntry(uint32_t usage_entry_number,
&provider_session_token, &key_request, &key_response, &entry,
&entry_number, &drm_certificate, &wrapped_private_key)) {
LOGE("Failed to retrieve usage information");
return USAGE_STORE_ENTRY_RETRIEVE_USAGE_INFO_FAILED;
return CdmResponseType(USAGE_STORE_ENTRY_RETRIEVE_USAGE_INFO_FAILED);
}
device_files->DeleteUsageInfo(
usage_entry_info_[usage_entry_number].usage_info_file_name,
@@ -842,7 +840,7 @@ CdmResponseType UsageTableHeader::StoreEntry(uint32_t usage_entry_number,
usage_entry_info_[usage_entry_number].key_set_id, usage_entry,
usage_entry_number, drm_certificate, wrapped_private_key)) {
LOGE("Failed to store usage information");
return USAGE_STORE_USAGE_INFO_FAILED;
return CdmResponseType(USAGE_STORE_USAGE_INFO_FAILED);
}
break;
}
@@ -852,9 +850,9 @@ CdmResponseType UsageTableHeader::StoreEntry(uint32_t usage_entry_number,
"Cannot retrieve usage information with unknown storage type: "
"storage_type = %d",
static_cast<int>(usage_entry_info_[usage_entry_number].storage_type));
return USAGE_STORE_ENTRY_RETRIEVE_INVALID_STORAGE_TYPE;
return CdmResponseType(USAGE_STORE_ENTRY_RETRIEVE_INVALID_STORAGE_TYPE);
}
return NO_ERROR;
return CdmResponseType(NO_ERROR);
}
bool UsageTableHeader::StoreTable() {
@@ -876,7 +874,7 @@ CdmResponseType UsageTableHeader::Shrink(
number_of_usage_entries_to_delete);
if (usage_entry_info_.empty()) {
LOGE("Usage entry info table unexpectedly empty");
return NO_USAGE_ENTRIES;
return CdmResponseType(NO_USAGE_ENTRIES);
}
if (usage_entry_info_.size() < number_of_usage_entries_to_delete) {
@@ -888,7 +886,7 @@ CdmResponseType UsageTableHeader::Shrink(
static_cast<uint32_t>(usage_entry_info_.size());
}
if (number_of_usage_entries_to_delete == 0) return NO_ERROR;
if (number_of_usage_entries_to_delete == 0) return CdmResponseType(NO_ERROR);
// crypto_session points to an object whose scope is this method or a test
// object whose scope is the lifetime of this class
@@ -923,7 +921,7 @@ CdmResponseType UsageTableHeader::DefragTable(DeviceFiles* device_files,
// Special case 0: Empty table, do nothing.
if (usage_entry_info_.empty()) {
LOGD("Table empty, nothing to defrag");
return NO_ERROR;
return CdmResponseType(NO_ERROR);
}
// Step 1: Create a list of entries to be removed from the table.
@@ -943,7 +941,7 @@ CdmResponseType UsageTableHeader::DefragTable(DeviceFiles* device_files,
// needs to be done.
if (entries_to_remove.empty()) {
LOGD("No entries are invalid");
return NO_ERROR;
return CdmResponseType(NO_ERROR);
}
// Step 2: Create a list of entries to be moved from the end of the
@@ -1027,7 +1025,7 @@ CdmResponseType UsageTableHeader::DefragTable(DeviceFiles* device_files,
status = MoveEntry(from_entry_number, from_entry, to_entry_number,
device_files, metrics);
switch (status) {
switch (status.Enum()) {
case NO_ERROR: {
entries_to_remove.pop_back();
entries_to_move.pop_back();
@@ -1091,7 +1089,7 @@ CdmResponseType UsageTableHeader::DefragTable(DeviceFiles* device_files,
// For all other cases, it may not be safe to proceed, even to
// shrink the table.
LOGE("Unrecoverable error occurred while defragging table: status = %d",
static_cast<int>(status));
status.Enum());
return status;
}
} // End switch case.
@@ -1129,7 +1127,7 @@ CdmResponseType UsageTableHeader::DefragTable(DeviceFiles* device_files,
if (to_remove == 0) {
LOGD("Defrag completed without shrinking table");
StoreTable();
return NO_ERROR;
return CdmResponseType(NO_ERROR);
}
// Step 6: Shrink table to the new size.
@@ -1143,7 +1141,7 @@ CdmResponseType UsageTableHeader::ReleaseOldestEntry(
uint32_t entry_number_to_delete;
if (!GetRemovalCandidate(&entry_number_to_delete)) {
LOGE("Could not determine which license to remove");
return UNKNOWN_ERROR;
return CdmResponseType(UNKNOWN_ERROR);
}
const CdmUsageEntryInfo& usage_entry_info =
usage_entry_info_[entry_number_to_delete];
@@ -1159,14 +1157,13 @@ CdmResponseType UsageTableHeader::ReleaseOldestEntry(
device_files_.get(), metrics);
if (status != NO_ERROR) {
LOGE("Failed to invalidate oldest entry: status = %d",
static_cast<int>(status));
LOGE("Failed to invalidate oldest entry: status = %d", status.Enum());
return status;
}
// Record metrics on success.
RecordLruEventMetrics(metrics, staleness, storage_type);
return NO_ERROR;
return CdmResponseType(NO_ERROR);
}
// Test only method.

View File

@@ -143,8 +143,8 @@ const char* CdmProductionReadinessToString(CdmProductionReadiness readiness) {
return UnknownValueRep(readiness);
}
const char* CdmResponseTypeToString(CdmResponseType cdm_response_type) {
switch (cdm_response_type) {
const char* CdmResponseEnumToString(CdmResponseEnum cdm_response_enum) {
switch (cdm_response_enum) {
case NO_ERROR:
return "NO_ERROR";
case UNKNOWN_ERROR:
@@ -820,7 +820,7 @@ const char* CdmResponseTypeToString(CdmResponseType cdm_response_type) {
case PROVISIONING_4_FAILED_TO_INITIALIZE_DEVICE_FILES_3:
return "PROVISIONING_4_FAILED_TO_INITIALIZE_DEVICE_FILES_3";
}
return UnknownEnumValueToString(static_cast<int>(cdm_response_type));
return UnknownEnumValueToString(cdm_response_enum);
}
const char* UnknownEnumValueToString(int value) {