Merges to android Pi release (part 4)

These are a set of CLs merged from the wv cdm repo to the android repo.

* Correct RELEASE_ALL_USAGE_INFO_ERRORs

  Author: Rahul Frias <rfrias@google.com>

  [ Merge of http://go/wvgerrit/28742 ]

  RELEASE_ALL_USAGE_INFO_ERROR_4 and 5 were introduced and made use of in
  http://go/wvgerrit/24022 (branch: oc-dev). The error code definitions
  were merged over in http://go/wvgerrit/24602.

  When http://go/wvgerrit/24622 from cdm_partners_3.2 was merged to master
  (http://go/wvgerrit/27723) there was conflict in error codes. The error
  codes were adjusted to RELEASE_ALL_USAGE_INFO_ERROR_3 and 4
  and were made use of.

  To avoid renaming the errors between oc-dev and master, new errors
  RELEASE_ALL_USAGE_INFO_ERROR_6 and 7 have been added to handle the
  scenarios noted in the merge from cdm_partner_3.2. The other
  errors have been reverted back to RELEASE_ALL_USAGE_INFO_ERROR_4 and 5.
  They will be used when http://go/wvgerrit/24602 is merged.

* Address compilation issues

  Author: Rahul Frias <rfrias@google.com>

  [ Merge of http://go/wvgerrit/28740 ]

  These changes enable compilation of most of the cdm code on android
  expect for OEMCrypto unit tests (b/62739406) on wv master.

* Add property for binary/base64 provisioning msgs.

  Author: Gene Morgan <gmorgan@google.com>

  [ Merge of http://go/wvgerrit/28074 ]

  Property is "provisioning_messages_are_binary". Its default setting is
  false in the CE CDM, but it can be overridden by integrators.

  Added section to integration guide that discusses Provisioning Server
  message formats and the new property.

  Link: https://docs.google.com/document/d/1cBVbhgrajLpDe2W3_vzLzUqzpdDt73chvm4_sZlZlS8/edit#heading=h.hgxw53ddw7jo

BUG: 71650075
Test: Not currently passing. Will be addressed in a subsequent
      commit in the chain.

Change-Id: I9168193819974d1ff65d9a94dbd762e45ecc43ca
This commit is contained in:
Rahul Frias
2018-01-09 17:10:23 -08:00
parent 11068accd2
commit 169d0b6cb6
46 changed files with 1260 additions and 741 deletions

View File

@@ -17,6 +17,7 @@
#include "string_conversions.h"
#include "wv_cdm_constants.h"
#include "wv_cdm_event_listener.h"
#include "usage_table_header.h"
namespace {
const size_t kKeySetIdLength = 14;
@@ -39,8 +40,20 @@ CdmSession::CdmSession(FileSystem* file_system) :
has_decrypted_since_last_report_(false),
is_initial_usage_update_(true),
is_usage_update_needed_(false),
usage_support_type_(kNonSecureUsageSupport),
usage_table_header_(NULL),
usage_entry_number_(0),
mock_license_parser_in_use_(false),
mock_policy_engine_in_use_(false) {
CdmResponseType sts =
crypto_session_->GetUsageSupportType(&usage_support_type_);
if (sts != NO_ERROR) {
LOGW("CdmSession::CdmSession: Failed to get usage support type");
}
if (usage_support_type_ == kUsageEntrySupport)
usage_table_header_ = UsageTableHeader::GetInstance(file_system,
crypto_session_.get());
life_span_.Start();
}
@@ -188,28 +201,37 @@ CdmResponseType CdmSession::RestoreOfflineSession(
int64_t playback_start_time;
int64_t last_playback_time;
int64_t grace_period_end_time;
std::string usage_entry;
uint32_t usage_entry_number = 0;
if (!file_handle_->RetrieveLicense(
key_set_id, &license_state, &offline_init_data_, &key_request_,
&key_response_, &offline_key_renewal_request_,
&offline_key_renewal_response_, &offline_release_server_url_,
&playback_start_time, &last_playback_time, &grace_period_end_time,
&app_parameters_, &usage_entry, &usage_entry_number)) {
LOGE("CdmSession::Init failed to retrieve license. key set id = %s",
key_set_id.c_str());
&app_parameters_, &usage_entry_, &usage_entry_number_)) {
LOGE("CdmSession::RestoreOfflineSession: failed to retrieve license. "
"key set id = %s", key_set_id.c_str());
return GET_LICENSE_ERROR;
}
// Do not restore a released offline license, unless a release retry
if (!(license_type == kLicenseTypeRelease ||
license_state == DeviceFiles::kLicenseStateActive)) {
LOGE("CdmSession::Init invalid offline license state = %d, type = %d",
license_state, license_type);
LOGE("CdmSession::RestoreOfflineSession: invalid offline license state = "
"%d, type = %d", license_state, license_type);
return GET_RELEASED_LICENSE_ERROR;
}
if (usage_support_type_ == kUsageEntrySupport) {
CdmResponseType sts = usage_table_header_->LoadEntry(crypto_session_.get(),
usage_entry_,
usage_entry_number_);
if (sts != NO_ERROR) {
LOGE("CdmSession::RestoreOfflineSession: failed to load usage entry = %d",
sts);
return sts;
}
}
if (license_type == kLicenseTypeRelease) {
if (!license_parser_->RestoreLicenseForRelease(key_request_,
key_response_)) {
@@ -223,6 +245,20 @@ CdmResponseType CdmSession::RestoreOfflineSession(
}
}
if (usage_support_type_ == kUsageEntrySupport) {
CdmResponseType sts =
usage_table_header_->UpdateEntry(crypto_session_.get(), &usage_entry_);
if (sts != NO_ERROR) {
LOGE("CdmSession::RestoreOfflineSession failed to update usage entry = "
"%d", sts);
return sts;
}
if (!StoreLicense(license_state)) {
LOGW("CdmSession::RestoreUsageSession: unable to save updated usage "
"info");
}
}
license_received_ = true;
is_offline_ = true;
is_release_ = license_type == kLicenseTypeRelease;
@@ -230,14 +266,45 @@ CdmResponseType CdmSession::RestoreOfflineSession(
}
CdmResponseType CdmSession::RestoreUsageSession(
const CdmKeyMessage& key_request, const CdmKeyResponse& key_response) {
key_request_ = key_request;
key_response_ = key_response;
const DeviceFiles::CdmUsageData& usage_data) {
if (!key_set_id_.empty()) {
file_handle_->UnreserveLicenseId(key_set_id_);
}
key_set_id_ = usage_data.key_set_id;
key_request_ = usage_data.license_request;
key_response_ = usage_data.license;
usage_entry_ = usage_data.usage_entry;
usage_entry_number_ = usage_data.usage_entry_number;
usage_provider_session_token_ = usage_data.provider_session_token;
if (usage_support_type_ == kUsageEntrySupport) {
CdmResponseType sts = usage_table_header_->LoadEntry(
crypto_session_.get(), usage_entry_, usage_entry_number_);
if (sts != NO_ERROR) {
LOGE("CdmSession::RestoreUsageSession: failed to load usage entry = %d",
sts);
return sts;
}
}
if (!license_parser_->RestoreLicenseForRelease(key_request_, key_response_)) {
return RELEASE_LICENSE_ERROR_2;
}
if (usage_support_type_ == kUsageEntrySupport) {
CdmResponseType sts =
usage_table_header_->UpdateEntry(crypto_session_.get(), &usage_entry_);
if (sts != NO_ERROR) {
LOGE("CdmSession::RestoreUsageSession: failed to update usage entry: %d",
sts);
return sts;
}
if (!UpdateUsageInfo()) {
LOGW("CdmSession::RestoreUsageSession: unable to save updated usage "
"info");
}
}
license_received_ = true;
is_offline_ = false;
is_release_ = true;
@@ -339,7 +406,36 @@ CdmResponseType CdmSession::AddKey(const CdmKeyResponse& key_response) {
} else if (license_received_) { // renewal
return RenewKey(key_response);
} else {
CdmResponseType sts = license_parser_->HandleKeyResponse(key_response);
// If usage table header+entries are supported, preprocess the license
// to see if it has a provider session token. If so a new entry needs
// to be created.
CdmResponseType sts;
std::string provider_session_token;
if (usage_support_type_ == kUsageEntrySupport) {
if (license_parser_->ExtractProviderSessionToken(
key_response, &provider_session_token) &&
!provider_session_token.empty()) {
std::string app_id;
GetApplicationId(&app_id);
sts = usage_table_header_->AddEntry(
crypto_session_.get(), is_offline_, key_set_id_,
DeviceFiles::GetUsageInfoFileName(app_id), &usage_entry_number_);
if (sts != NO_ERROR) return sts;
}
}
sts = license_parser_->HandleKeyResponse(key_response);
// Update or delete entry if usage table header+entries are supported
if (usage_support_type_ == kUsageEntrySupport &&
!provider_session_token.empty()) {
if (sts != KEY_ADDED) {
CdmResponseType sts =
usage_table_header_->DeleteEntry(usage_entry_number_);
if (sts != NO_ERROR) {
LOGW("CdmSession::AddKey: Delete usage entry failed = %d", sts);
}
}
}
if (sts != KEY_ADDED) return (sts == KEY_ERROR) ? ADD_KEY_ERROR : sts;
@@ -351,6 +447,13 @@ CdmResponseType CdmSession::AddKey(const CdmKeyResponse& key_response) {
license_parser_->provider_session_token().c_str());
if (is_offline_ || !license_parser_->provider_session_token().empty()) {
if (usage_support_type_ == kUsageEntrySupport)
usage_table_header_->UpdateEntry(crypto_session_.get(), &usage_entry_);
if (!is_offline_)
usage_provider_session_token_ =
license_parser_->provider_session_token();
sts = StoreLicense();
if (sts != NO_ERROR) return sts;
}
@@ -510,9 +613,24 @@ CdmResponseType CdmSession::GenerateReleaseRequest(
if (KEY_MESSAGE != status) return status;
if (usage_support_type_ == kUsageEntrySupport) {
status = usage_table_header_->UpdateEntry(crypto_session_.get(),
&usage_entry_);
if (status != NO_ERROR) {
LOGE("CdmSession::GenerateReleaseRequest: Update usage entry failed = "
"%d", status);
return status;
}
}
if (is_offline_) { // Mark license as being released
if (!StoreLicense(DeviceFiles::kLicenseStateReleasing))
return RELEASE_KEY_REQUEST_ERROR;
} else if (!usage_provider_session_token_.empty()) {
if (usage_support_type_ == kUsageEntrySupport) {
if (!UpdateUsageInfo())
return RELEASE_USAGE_INFO_FAILED;
}
}
return KEY_MESSAGE;
}
@@ -525,10 +643,38 @@ CdmResponseType CdmSession::ReleaseKey(const CdmKeyResponse& key_response) {
if (is_offline_ || !license_parser_->provider_session_token().empty()) {
DeleteLicense();
// Deletion of usage entry cannot occur while in use by a crypto session.
// So close and reopen after deletion.
if (usage_support_type_ == kUsageEntrySupport) {
crypto_session_->Close();
CdmResponseType sts = usage_table_header_->DeleteEntry(usage_entry_number_);
if (sts != NO_ERROR) return sts;
M_TIME(
sts = crypto_session_->Open(requested_security_level_),
&metrics_,
crypto_session_open_,
sts,
requested_security_level_);
if (NO_ERROR != sts) return sts;
}
}
return NO_ERROR;
}
CdmResponseType CdmSession::DeleteUsageEntry(
const DeviceFiles::CdmUsageData& usage_data) {
if (usage_support_type_ != kUsageEntrySupport) {
LOGE("CdmSession::DeleteUsageEntry: Unexpected usage type supported: %d",
usage_support_type_);
return INCORRECT_USAGE_SUPPORT_TYPE_1;
}
return usage_table_header_->DeleteEntry(usage_data.usage_entry_number);
}
bool CdmSession::IsKeyLoaded(const KeyId& key_id) {
return license_parser_->IsKeyLoaded(key_id);
}
@@ -602,13 +748,11 @@ CdmResponseType CdmSession::StoreLicense() {
std::string app_id;
GetApplicationId(&app_id);
std::string usage_entry;
uint32_t usage_entry_number = 0;
if (!file_handle_->StoreUsageInfo(provider_session_token, key_request_,
key_response_,
DeviceFiles::GetUsageInfoFileName(app_id),
key_set_id_, usage_entry,
usage_entry_number)) {
key_set_id_, usage_entry_,
usage_entry_number_)) {
LOGE("CdmSession::StoreLicense: Unable to store usage info");
return STORE_USAGE_INFO_ERROR;
}
@@ -616,15 +760,13 @@ CdmResponseType CdmSession::StoreLicense() {
}
bool CdmSession::StoreLicense(DeviceFiles::LicenseState state) {
std::string usage_entry;
uint32_t usage_entry_number = 0;
return file_handle_->StoreLicense(
key_set_id_, state, offline_init_data_, key_request_, key_response_,
offline_key_renewal_request_, offline_key_renewal_response_,
offline_release_server_url_, policy_engine_->GetPlaybackStartTime(),
policy_engine_->GetLastPlaybackTime(),
policy_engine_->GetGracePeriodEndTime(), app_parameters_, usage_entry,
usage_entry_number);
policy_engine_->GetGracePeriodEndTime(), app_parameters_, usage_entry_,
usage_entry_number_);
}
CdmResponseType CdmSession::ReleaseCrypto() {
@@ -686,14 +828,43 @@ CdmResponseType CdmSession::DeleteMultipleUsageInformation(
return sts;
}
CdmResponseType CdmSession::UpdateUsageInformation() {
CdmResponseType sts;
M_TIME(
sts = crypto_session_->UpdateUsageInformation(),
&metrics_,
crypto_session_update_usage_information_,
sts);
return sts;
CdmResponseType CdmSession::UpdateUsageTableInformation() {
CdmUsageSupportType usage_support_type;
CdmResponseType sts =
crypto_session_->GetUsageSupportType(&usage_support_type);
if (sts == NO_ERROR && usage_support_type == kUsageTableSupport) {
M_TIME(
sts = crypto_session_->UpdateUsageInformation(),
&metrics_,
crypto_session_update_usage_information_,
sts);
return sts;
}
return NO_ERROR; // Ignore
}
CdmResponseType CdmSession::UpdateUsageEntryInformation() {
if (usage_support_type_ != kUsageEntrySupport) {
LOGE("CdmSession::UpdateUsageEntryInformation: Unexpected usage type "
"supported: %d", usage_support_type_);
return INCORRECT_USAGE_SUPPORT_TYPE_2;
}
CdmResponseType sts = usage_table_header_->UpdateEntry(crypto_session_.get(),
&usage_entry_);
if (sts != NO_ERROR) return sts;
if (is_offline_)
StoreLicense(is_release_
? DeviceFiles::kLicenseStateReleasing
: DeviceFiles::kLicenseStateActive);
else if (!usage_provider_session_token_.empty())
UpdateUsageInfo();
return NO_ERROR;
}
CdmResponseType CdmSession::GenericEncrypt(const std::string& in_buffer,
@@ -788,6 +959,24 @@ CdmResponseType CdmSession::GenericVerify(const std::string& message,
return sts;
}
bool CdmSession::UpdateUsageInfo() {
std::string app_id;
GetApplicationId(&app_id);
DeviceFiles::CdmUsageData usage_data;
usage_data.provider_session_token = usage_provider_session_token_;
usage_data.license_request = key_request_;
usage_data.license = key_response_;
usage_data.key_set_id = key_set_id_;
usage_data.usage_entry = usage_entry_;
usage_data.usage_entry_number = usage_entry_number_;
return file_handle_->UpdateUsageInfo(
DeviceFiles::GetUsageInfoFileName(app_id),
usage_provider_session_token_,
usage_data);
}
// For testing only - takes ownership of pointers
void CdmSession::set_license_parser(CdmLicense* license_parser) {