Infrastructure changes to support big usage tables

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

The usage table redesign will require storing usage table headers
and usage entries in non-secure persistent store. This information
will be signed by the TEE to prevent against modification. New
Storage and retrieval methods have been added for usage table headers,
while usage entries will be stored alongside (offline) licenses and
(secure stops/)usage info.

b/34327459

Test: All unittests, including newly introduced ones other than some
oemcrypto, request_license_test passed. Those tests failed with or without
this CL.

Change-Id: I9b8d6210e33774b0803f8af1711b2d593d467aec
This commit is contained in:
Rahul Frias
2017-01-23 23:09:04 -08:00
parent 65a2c240de
commit 4069e72102
6 changed files with 498 additions and 74 deletions

View File

@@ -34,6 +34,12 @@ using video_widevine_client::sdk::License_LicenseState_RELEASING;
using video_widevine_client::sdk::NameValue;
using video_widevine_client::sdk::UsageInfo;
using video_widevine_client::sdk::UsageInfo_ProviderSession;
using video_widevine_client::sdk::UsageTableInfo;
using video_widevine_client::sdk::UsageTableInfo_UsageEntryInfo;
using video_widevine_client::sdk::
UsageTableInfo_UsageEntryInfo_UsageEntryStorage_LICENSE;
using video_widevine_client::sdk::
UsageTableInfo_UsageEntryInfo_UsageEntryStorage_USAGE_INFO;
namespace {
@@ -43,6 +49,7 @@ const char kUsageInfoFileNamePrefix[] = "usage";
const char kUsageInfoFileNameExt[] = ".bin";
const char kLicenseFileNameExt[] = ".lic";
const char kEmptyFileName[] = "";
const char kUsageTableFileName[] = "usagetable.bin";
const char kWildcard[] = "*";
bool Hash(const std::string& data, std::string* hash) {
@@ -169,7 +176,8 @@ bool DeviceFiles::StoreLicense(
const CdmKeyResponse& license_renewal,
const std::string& release_server_url, int64_t playback_start_time,
int64_t last_playback_time, int64_t grace_period_end_time,
const CdmAppParameterMap& app_parameters) {
const CdmAppParameterMap& app_parameters,
const std::string& usage_entry) {
if (!initialized_) {
LOGW("DeviceFiles::StoreLicense: not initialized");
return false;
@@ -210,6 +218,7 @@ bool DeviceFiles::StoreLicense(
app_params->set_name(iter->first);
app_params->set_value(iter->second);
}
license->set_usage_entry(usage_entry);
std::string serialized_file;
file.SerializeToString(&serialized_file);
@@ -224,7 +233,7 @@ bool DeviceFiles::RetrieveLicense(
CdmKeyMessage* license_renewal_request, CdmKeyResponse* license_renewal,
std::string* release_server_url, int64_t* playback_start_time,
int64_t* last_playback_time, int64_t* grace_period_end_time,
CdmAppParameterMap* app_parameters) {
CdmAppParameterMap* app_parameters, std::string* usage_entry) {
if (!initialized_) {
LOGW("DeviceFiles::RetrieveLicense: not initialized");
return false;
@@ -278,6 +287,7 @@ bool DeviceFiles::RetrieveLicense(
(*app_parameters)[license.app_parameters(i).name()] =
license.app_parameters(i).value();
}
*usage_entry = license.usage_entry();
return true;
}
@@ -340,7 +350,8 @@ bool DeviceFiles::StoreUsageInfo(const std::string& provider_session_token,
const CdmKeyMessage& key_request,
const CdmKeyResponse& key_response,
const std::string& app_id,
const std::string& key_set_id) {
const std::string& key_set_id,
const std::string& usage_entry) {
if (!initialized_) {
LOGW("DeviceFiles::StoreUsageInfo: not initialized");
return false;
@@ -366,6 +377,7 @@ bool DeviceFiles::StoreUsageInfo(const std::string& provider_session_token,
provider_session->set_license_request(key_request.data(), key_request.size());
provider_session->set_license(key_response.data(), key_response.size());
provider_session->set_key_set_id(key_set_id.data(), key_set_id.size());
provider_session->set_usage_entry(usage_entry);
std::string serialized_file;
file.SerializeToString(&serialized_file);
@@ -479,7 +491,8 @@ bool DeviceFiles::RetrieveUsageInfo(
bool DeviceFiles::RetrieveUsageInfo(const std::string& app_id,
const std::string& provider_session_token,
CdmKeyMessage* license_request,
CdmKeyResponse* license_response) {
CdmKeyResponse* license_response,
std::string* usage_entry) {
if (!initialized_) {
LOGW("DeviceFiles::RetrieveUsageInfo: not initialized");
return false;
@@ -496,6 +509,7 @@ bool DeviceFiles::RetrieveUsageInfo(const std::string& app_id,
if (file.usage_info().sessions(index).token() == provider_session_token) {
*license_request = file.usage_info().sessions(index).license_request();
*license_response = file.usage_info().sessions(index).license();
*usage_entry = file.usage_info().sessions(index).usage_entry();
return true;
}
}
@@ -507,7 +521,8 @@ bool DeviceFiles::RetrieveUsageInfoByKeySetId(
const std::string& app_id,
const std::string& key_set_id,
CdmKeyMessage* license_request,
CdmKeyResponse* license_response) {
CdmKeyResponse* license_response,
std::string* usage_entry) {
if (!initialized_) {
LOGW("DeviceFiles::RetrieveUsageInfoByKeySetId: not initialized");
return false;
@@ -524,6 +539,7 @@ bool DeviceFiles::RetrieveUsageInfoByKeySetId(
if (file.usage_info().sessions(index).key_set_id() == key_set_id) {
*license_request = file.usage_info().sessions(index).license_request();
*license_response = file.usage_info().sessions(index).license();
*usage_entry = file.usage_info().sessions(index).usage_entry();
return true;
}
}
@@ -628,6 +644,118 @@ bool DeviceFiles::DeleteHlsAttributes(const std::string& key_set_id) {
return RemoveFile(key_set_id + kHlsAttributesFileNameExt);
}
bool DeviceFiles::StoreUsageTableInfo(
const std::string& usage_table_header,
const std::vector<DeviceFiles::UsageEntryInfo>& usage_entry_info) {
if (!initialized_) {
LOGW("DeviceFiles::StoreUsageTableHeader: not initialized");
return false;
}
// Fill in file information
video_widevine_client::sdk::File file;
file.set_type(video_widevine_client::sdk::File::USAGE_TABLE_INFO);
file.set_version(video_widevine_client::sdk::File::VERSION_1);
UsageTableInfo* usage_table_info = file.mutable_usage_table_info();
usage_table_info->set_usage_table_header(usage_table_header);
for (size_t i = 0; i < usage_entry_info.size(); ++i) {
UsageTableInfo_UsageEntryInfo* info =
usage_table_info->add_usage_entry_info();
switch (usage_entry_info[i].storage_type) {
case kStorageLicense:
info->set_storage(
UsageTableInfo_UsageEntryInfo_UsageEntryStorage_LICENSE);
info->set_key_set_id(usage_entry_info[i].key_set_id);
break;
case kStorageUsageInfo:
info->set_storage(
UsageTableInfo_UsageEntryInfo_UsageEntryStorage_USAGE_INFO);
info->set_provider_session_token(
usage_entry_info[i].provider_session_token);
info->set_app_id(usage_entry_info[i].app_id);
break;
default:
LOGW("DeviceFiles::StoreUsageTableHeader: unknown storage type: %d",
usage_entry_info[i].storage_type);
return false;
}
}
std::string serialized_file;
file.SerializeToString(&serialized_file);
return StoreFileWithHash(GetUsageTableFileName(), serialized_file);
}
bool DeviceFiles::RetrieveUsageTableInfo(
std::string* usage_table_header,
std::vector<DeviceFiles::UsageEntryInfo>* usage_entry_info) {
if (!initialized_) {
LOGW("DeviceFiles::RetrieveUsageTableInfo: not initialized");
return false;
}
if (usage_table_header == NULL) {
LOGW(
"DeviceFiles::RetrieveUsageTableInfo: usage_table_header not provided");
return false;
}
if (usage_entry_info == NULL) {
LOGW("DeviceFiles::RetrieveUsageTableInfo: usage_entry_info not provided");
return false;
}
video_widevine_client::sdk::File file;
if (!RetrieveHashedFile(GetUsageTableFileName(), &file)) {
return false;
}
if (file.type() != video_widevine_client::sdk::File::USAGE_TABLE_INFO) {
LOGW("DeviceFiles::RetrieveUsageTableInfo: Incorrect file type");
return false;
}
if (file.version() != video_widevine_client::sdk::File::VERSION_1) {
LOGW("DeviceFiles::RetrieveUsageTableInfo: Incorrect file version");
return false;
}
if (!file.has_usage_table_info()) {
LOGW("DeviceFiles::RetrieveUsageTableInfo: Usage table info not present");
return false;
}
const UsageTableInfo& usage_table_info = file.usage_table_info();
*usage_table_header = usage_table_info.usage_table_header();
usage_entry_info->resize(usage_table_info.usage_entry_info_size());
for (int i = 0; i < usage_table_info.usage_entry_info_size(); ++i) {
const UsageTableInfo_UsageEntryInfo& info =
usage_table_info.usage_entry_info(i);
switch (info.storage()) {
case UsageTableInfo_UsageEntryInfo_UsageEntryStorage_LICENSE:
(*usage_entry_info)[i].storage_type = kStorageLicense;
(*usage_entry_info)[i].key_set_id = info.key_set_id();
break;
case UsageTableInfo_UsageEntryInfo_UsageEntryStorage_USAGE_INFO:
(*usage_entry_info)[i].storage_type = kStorageUsageInfo;
(*usage_entry_info)[i].provider_session_token =
info.provider_session_token();
(*usage_entry_info)[i].app_id = info.app_id();
break;
default:
LOGW("DeviceFiles::RetrieveUsageTableInfo: Unknown storage type: %d",
info.storage());
return false;
}
}
return true;
}
bool DeviceFiles::StoreFileWithHash(const std::string& name,
const std::string& serialized_file) {
// calculate SHA hash
@@ -796,6 +924,10 @@ std::string DeviceFiles::GetCertificateFileName() {
return kCertificateFileName;
}
std::string DeviceFiles::GetUsageTableFileName() {
return kUsageTableFileName;
}
std::string DeviceFiles::GetHlsAttributesFileNameExtension() {
return kHlsAttributesFileNameExt;
}