Merges to android Pi release (part 3)
These are a set of CLs merged from the wv cdm repo to the android repo. * Add CDM status return for decrypt blocked by HDCP. Author: Gene Morgan <gmorgan@google.com> [ Merge of http://go/wvgerrit/28062 ] New status code is kKeyUsageBlockedByPolicy. It is returned by the decrypt() call instead of kDecryptError or kNoKey. Also shuffled the CDM status returns to define the EME-aligned codes first, and added comments to highlight the differences in handling. BUG: 37540672 * Change division and mod ops to relocatables Author: Srujan Gaddam <srujzs@google.com> [ Merge of http://go/wvgerrit/28600 ] This is similar to I2dad1028acf295288cd10817a2bcff2513c053c9. We should be using the relocatable functions instead of the native division and mod operations. * Cleanup Encrypted ClientID in provisioning request Author: Gene Morgan <gmorgan@google.com> [ Merge of http://go/wvgerrit/28083 ] b/36897239 Staging server does not support it (or the client is not constructing it properly). Leave it disabled pending investigation. * Certificate Provisioning fixes. Author: Gene Morgan <gmorgan@google.com> [ Merge of http://go/wvgerrit/28066 ] Partial fix for BUG: 37482676 Partial fix for BUG: 37481392 Update service certificates, get rid of DEV/QA root certificate. Provisioning request and response are base64 (web-safe) encoded. Response is optionally JSON-wrapped. Change ConfigTestEnv; clearer comments and a closer match to reality. BUG: 71650075 Test: Not currently passing. Will be addressed in a subsequent commit in the chain. Change-Id: I79d3c4bf1124e5e0d3e4d40baead65a8266ea874
This commit is contained in:
@@ -99,11 +99,6 @@ bool CdmEngine::GetServiceCertificateRequest(CdmKeyMessage* request) {
|
||||
SignedMessage message;
|
||||
message.set_type(SignedMessage::SERVICE_CERTIFICATE_REQUEST);
|
||||
message.SerializeToString(request);
|
||||
|
||||
// Convert to base64.
|
||||
std::vector<uint8_t> request_vector(request->begin(), request->end());
|
||||
std::string request_b64 = Base64SafeEncodeNoPad(request_vector);
|
||||
request->swap(request_b64);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -118,16 +113,8 @@ CdmResponseType CdmEngine::ParseServiceCertificateResponse(
|
||||
return INVALID_PARAMETERS_ENG_24;
|
||||
}
|
||||
|
||||
// The response is base64 encoded - decode it before parsing the string.
|
||||
std::string padded_response(response);
|
||||
while (padded_response.size() % 4 != 0) {
|
||||
padded_response = padded_response + "=";
|
||||
}
|
||||
std::vector<uint8_t> raw_message = Base64SafeDecode(padded_response);
|
||||
std::string raw_string(raw_message.begin(), raw_message.end());
|
||||
|
||||
SignedMessage signed_response;
|
||||
if (!signed_response.ParseFromString(raw_string)) {
|
||||
if (!signed_response.ParseFromString(response)) {
|
||||
LOGE(
|
||||
"CdmEngine::ParseServiceCertificateResponse: cannot parse response");
|
||||
return PARSE_RESPONSE_ERROR_1;
|
||||
@@ -157,7 +144,8 @@ CdmResponseType CdmEngine::ParseServiceCertificateResponse(
|
||||
return PARSE_RESPONSE_ERROR_3;
|
||||
} else {
|
||||
LOGE(
|
||||
"CdmEngine::ParseServiceCertificateResponse: response is wrong type");
|
||||
"CdmEngine::ParseServiceCertificateResponse: response (%d) is "
|
||||
"wrong type", signed_response.type());
|
||||
return PARSE_RESPONSE_ERROR_4;
|
||||
}
|
||||
return NO_ERROR;
|
||||
@@ -1079,8 +1067,11 @@ CdmResponseType CdmEngine::GetUsageInfo(const std::string& app_id,
|
||||
CdmKeyMessage license_request;
|
||||
CdmKeyResponse license_response;
|
||||
std::string usage_entry;
|
||||
if (!handle.RetrieveUsageInfo(app_id, ssid, &license_request,
|
||||
&license_response, &usage_entry)) {
|
||||
uint32_t usage_entry_number = 0;
|
||||
if (!handle.RetrieveUsageInfo(DeviceFiles::GetUsageInfoFileName(app_id),
|
||||
ssid, &license_request,
|
||||
&license_response, &usage_entry,
|
||||
&usage_entry_number)) {
|
||||
usage_property_set_->set_security_level(kLevel3);
|
||||
usage_property_set_->set_app_id(app_id);
|
||||
usage_session_.reset(new CdmSession(file_system_));
|
||||
@@ -1093,8 +1084,10 @@ CdmResponseType CdmEngine::GetUsageInfo(const std::string& app_id,
|
||||
LOGE("CdmEngine::GetUsageInfo: device file init error");
|
||||
return GET_USAGE_INFO_ERROR_2;
|
||||
}
|
||||
if (!handle.RetrieveUsageInfo(app_id, ssid, &license_request,
|
||||
&license_response, &usage_entry)) {
|
||||
if (!handle.RetrieveUsageInfo(DeviceFiles::GetUsageInfoFileName(app_id),
|
||||
ssid, &license_request,
|
||||
&license_response, &usage_entry,
|
||||
&usage_entry_number)) {
|
||||
// No entry found for that ssid.
|
||||
return USAGE_INFO_NOT_FOUND;
|
||||
}
|
||||
@@ -1120,6 +1113,7 @@ CdmResponseType CdmEngine::GetUsageInfo(const std::string& app_id,
|
||||
usage_info->clear();
|
||||
return status;
|
||||
}
|
||||
|
||||
return KEY_MESSAGE;
|
||||
}
|
||||
|
||||
@@ -1135,7 +1129,9 @@ CdmResponseType CdmEngine::GetUsageInfo(const std::string& app_id,
|
||||
do {
|
||||
status = GetUsageInfo(app_id, security_level, usage_info);
|
||||
|
||||
if (KEY_MESSAGE == status && !usage_info->empty()) return status;
|
||||
if (KEY_MESSAGE == status && !usage_info->empty()) {
|
||||
return status;
|
||||
}
|
||||
} while (KEY_CANCELED == status);
|
||||
|
||||
security_level = (kLevel3 == security_level) ? kLevelDefault : kLevel3;
|
||||
@@ -1172,7 +1168,8 @@ CdmResponseType CdmEngine::GetUsageInfo(const std::string& app_id,
|
||||
}
|
||||
|
||||
std::vector<std::pair<CdmKeyMessage, CdmKeyResponse> > license_info;
|
||||
if (!handle.RetrieveUsageInfo(app_id, &license_info)) {
|
||||
if (!handle.RetrieveUsageInfo(DeviceFiles::GetUsageInfoFileName(app_id),
|
||||
&license_info)) {
|
||||
LOGE("CdmEngine::GetUsageInfo: unable to read usage information");
|
||||
return GET_USAGE_INFO_ERROR_4;
|
||||
}
|
||||
@@ -1262,7 +1259,9 @@ CdmResponseType CdmEngine::ReleaseAllUsageInfo(const std::string& app_id) {
|
||||
DeviceFiles handle(file_system_);
|
||||
if (handle.Init(static_cast<CdmSecurityLevel>(j))) {
|
||||
std::vector<std::string> provider_session_tokens;
|
||||
if (!handle.DeleteAllUsageInfoForApp(app_id, &provider_session_tokens)) {
|
||||
if (!handle.DeleteAllUsageInfoForApp(
|
||||
DeviceFiles::GetUsageInfoFileName(app_id),
|
||||
&provider_session_tokens)) {
|
||||
LOGE("CdmEngine::ReleaseAllUsageInfo: failed to delete L%d secure"
|
||||
"stops", j);
|
||||
status = RELEASE_ALL_USAGE_INFO_ERROR_1;
|
||||
@@ -1338,11 +1337,15 @@ CdmResponseType CdmEngine::LoadUsageSession(const CdmKeySetId& key_set_id,
|
||||
std::string app_id;
|
||||
session->GetApplicationId(&app_id);
|
||||
|
||||
std::string provider_session_token;
|
||||
CdmKeyMessage key_message;
|
||||
CdmKeyResponse key_response;
|
||||
std::string usage_entry;
|
||||
if (!handle.RetrieveUsageInfoByKeySetId(app_id, key_set_id, &key_message,
|
||||
&key_response, &usage_entry)) {
|
||||
uint32_t usage_entry_number = 0;
|
||||
if (!handle.RetrieveUsageInfoByKeySetId(
|
||||
DeviceFiles::GetUsageInfoFileName(app_id), key_set_id,
|
||||
&provider_session_token, &key_message, &key_response,
|
||||
&usage_entry, &usage_entry_number)) {
|
||||
LOGE("CdmEngine::LoadUsageSession: unable to find usage information");
|
||||
return LOAD_USAGE_INFO_MISSING;
|
||||
}
|
||||
|
||||
@@ -189,13 +189,14 @@ CdmResponseType CdmSession::RestoreOfflineSession(
|
||||
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)) {
|
||||
&app_parameters_, &usage_entry, &usage_entry_number)) {
|
||||
LOGE("CdmSession::Init failed to retrieve license. key set id = %s",
|
||||
key_set_id.c_str());
|
||||
return GET_LICENSE_ERROR;
|
||||
@@ -345,6 +346,10 @@ CdmResponseType CdmSession::AddKey(const CdmKeyResponse& key_response) {
|
||||
license_received_ = true;
|
||||
key_response_ = key_response;
|
||||
|
||||
LOGV("AddKey: provider_session_token (size=%d) =%s",
|
||||
license_parser_->provider_session_token().size(),
|
||||
license_parser_->provider_session_token().c_str());
|
||||
|
||||
if (is_offline_ || !license_parser_->provider_session_token().empty()) {
|
||||
sts = StoreLicense();
|
||||
if (sts != NO_ERROR) return sts;
|
||||
@@ -598,9 +603,12 @@ 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_, app_id, key_set_id_,
|
||||
usage_entry)) {
|
||||
key_response_,
|
||||
DeviceFiles::GetUsageInfoFileName(app_id),
|
||||
key_set_id_, usage_entry,
|
||||
usage_entry_number)) {
|
||||
LOGE("CdmSession::StoreLicense: Unable to store usage info");
|
||||
return STORE_USAGE_INFO_ERROR;
|
||||
}
|
||||
@@ -609,12 +617,14 @@ 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);
|
||||
policy_engine_->GetGracePeriodEndTime(), app_parameters_, usage_entry,
|
||||
usage_entry_number);
|
||||
}
|
||||
|
||||
CdmResponseType CdmSession::ReleaseCrypto() {
|
||||
@@ -632,7 +642,8 @@ bool CdmSession::DeleteLicense() {
|
||||
std::string app_id;
|
||||
GetApplicationId(&app_id);
|
||||
return file_handle_->DeleteUsageInfo(
|
||||
app_id, license_parser_->provider_session_token());
|
||||
DeviceFiles::GetUsageInfoFileName(app_id),
|
||||
license_parser_->provider_session_token());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -66,7 +66,7 @@ void ExtractAndDecodeSignedMessage(const std::string& provisioning_response,
|
||||
result->assign(decoded_message.begin(), decoded_message.end());
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace
|
||||
|
||||
namespace wvcdm {
|
||||
// Protobuf generated classes.
|
||||
@@ -190,7 +190,7 @@ CdmResponseType CertificateProvisioning::GetProvisioningRequest(
|
||||
client_id->set_type(token_type);
|
||||
|
||||
#if 0 // TODO(gmorgan) Encrypt ClientIdentification. Pending Design.
|
||||
if (service_certificate_->HasCertificate()) {
|
||||
if (service_certificate_->has_certificate()) {
|
||||
EncryptedClientIdentification* encrypted_client_id =
|
||||
provisioning_request.mutable_encrypted_client_id();
|
||||
CdmResponseType status;
|
||||
@@ -279,9 +279,9 @@ CdmResponseType CertificateProvisioning::HandleProvisioningResponse(
|
||||
FileSystem* file_system, const CdmProvisioningResponse& response,
|
||||
std::string* cert, std::string* wrapped_key) {
|
||||
|
||||
std::string raw_string;
|
||||
// The response is base64 encoded in a JSON wrapper.
|
||||
// Extract it and decode it. If errors, return an empty string.
|
||||
std::string raw_string;
|
||||
ExtractAndDecodeSignedMessage(response, &raw_string);
|
||||
|
||||
if (raw_string.empty()) {
|
||||
|
||||
@@ -41,6 +41,8 @@ using video_widevine_client::sdk::
|
||||
UsageTableInfo_UsageEntryInfo_UsageEntryStorage_LICENSE;
|
||||
using video_widevine_client::sdk::
|
||||
UsageTableInfo_UsageEntryInfo_UsageEntryStorage_USAGE_INFO;
|
||||
using video_widevine_client::sdk::
|
||||
UsageTableInfo_UsageEntryInfo_UsageEntryStorage_UNKNOWN;
|
||||
|
||||
using video_widevine::SignedDrmDeviceCertificate;
|
||||
using video_widevine::DrmDeviceCertificate;
|
||||
@@ -218,7 +220,8 @@ bool DeviceFiles::StoreLicense(
|
||||
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 CdmUsageEntry& usage_entry) {
|
||||
const CdmUsageEntry& usage_entry,
|
||||
const uint32_t usage_entry_number) {
|
||||
if (!initialized_) {
|
||||
LOGW("DeviceFiles::StoreLicense: not initialized");
|
||||
return false;
|
||||
@@ -260,6 +263,7 @@ bool DeviceFiles::StoreLicense(
|
||||
app_params->set_value(iter->second);
|
||||
}
|
||||
license->set_usage_entry(usage_entry);
|
||||
license->set_usage_entry_number(usage_entry_number);
|
||||
|
||||
std::string serialized_file;
|
||||
file.SerializeToString(&serialized_file);
|
||||
@@ -274,7 +278,8 @@ 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, CdmUsageEntry* usage_entry) {
|
||||
CdmAppParameterMap* app_parameters, CdmUsageEntry* usage_entry,
|
||||
uint32_t* usage_entry_number) {
|
||||
if (!initialized_) {
|
||||
LOGW("DeviceFiles::RetrieveLicense: not initialized");
|
||||
return false;
|
||||
@@ -329,6 +334,7 @@ bool DeviceFiles::RetrieveLicense(
|
||||
license.app_parameters(i).value();
|
||||
}
|
||||
*usage_entry = license.usage_entry();
|
||||
*usage_entry_number = license.usage_entry_number();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -422,21 +428,21 @@ bool DeviceFiles::UnreserveLicenseId(const std::string& key_set_id) {
|
||||
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& usage_info_file_name,
|
||||
const std::string& key_set_id,
|
||||
const CdmUsageEntry& usage_entry) {
|
||||
const std::string& usage_entry,
|
||||
uint32_t usage_entry_number) {
|
||||
if (!initialized_) {
|
||||
LOGW("DeviceFiles::StoreUsageInfo: not initialized");
|
||||
return false;
|
||||
}
|
||||
|
||||
video_widevine_client::sdk::File file;
|
||||
std::string file_name = GetUsageInfoFileName(app_id);
|
||||
if (!FileExists(file_name)) {
|
||||
if (!FileExists(usage_info_file_name)) {
|
||||
file.set_type(video_widevine_client::sdk::File::USAGE_INFO);
|
||||
file.set_version(video_widevine_client::sdk::File::VERSION_1);
|
||||
} else {
|
||||
if (!RetrieveHashedFile(file_name, &file)) {
|
||||
if (!RetrieveHashedFile(usage_info_file_name, &file)) {
|
||||
LOGW("DeviceFiles::StoreUsageInfo: Unable to parse file");
|
||||
return false;
|
||||
}
|
||||
@@ -451,10 +457,11 @@ bool DeviceFiles::StoreUsageInfo(const std::string& provider_session_token,
|
||||
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);
|
||||
provider_session->set_usage_entry_number(usage_entry_number);
|
||||
|
||||
std::string serialized_file;
|
||||
file.SerializeToString(&serialized_file);
|
||||
return StoreFileWithHash(file_name, serialized_file);
|
||||
return StoreFileWithHash(usage_info_file_name, serialized_file);
|
||||
}
|
||||
|
||||
bool DeviceFiles::ListUsageRecords(const std::string& app_id,
|
||||
@@ -528,15 +535,14 @@ bool DeviceFiles::GetProviderSessionToken(const std::string& app_id,
|
||||
return false;
|
||||
}
|
||||
|
||||
bool DeviceFiles::DeleteUsageInfo(const std::string& app_id,
|
||||
bool DeviceFiles::DeleteUsageInfo(const std::string& usage_info_file_name,
|
||||
const std::string& provider_session_token) {
|
||||
if (!initialized_) {
|
||||
LOGW("DeviceFiles::DeleteUsageInfo: not initialized");
|
||||
return false;
|
||||
}
|
||||
video_widevine_client::sdk::File file;
|
||||
std::string file_name = GetUsageInfoFileName(app_id);
|
||||
if (!RetrieveHashedFile(file_name, &file)) return false;
|
||||
if (!RetrieveHashedFile(usage_info_file_name, &file)) return false;
|
||||
|
||||
UsageInfo* usage_info = file.mutable_usage_info();
|
||||
int index = 0;
|
||||
@@ -565,11 +571,11 @@ bool DeviceFiles::DeleteUsageInfo(const std::string& app_id,
|
||||
|
||||
std::string serialized_file;
|
||||
file.SerializeToString(&serialized_file);
|
||||
return StoreFileWithHash(file_name, serialized_file);
|
||||
return StoreFileWithHash(usage_info_file_name, serialized_file);
|
||||
}
|
||||
|
||||
bool DeviceFiles::DeleteAllUsageInfoForApp(
|
||||
const std::string& app_id,
|
||||
const std::string& usage_info_file_name,
|
||||
std::vector<std::string>* provider_session_tokens) {
|
||||
if (!initialized_) {
|
||||
LOGW("DeviceFiles::DeleteAllUsageInfoForApp: not initialized");
|
||||
@@ -581,22 +587,21 @@ bool DeviceFiles::DeleteAllUsageInfoForApp(
|
||||
}
|
||||
provider_session_tokens->clear();
|
||||
|
||||
std::string file_name = GetUsageInfoFileName(app_id);
|
||||
if (!FileExists(file_name)) return true;
|
||||
if (!FileExists(usage_info_file_name)) return true;
|
||||
|
||||
video_widevine_client::sdk::File file;
|
||||
if (RetrieveHashedFile(file_name, &file)) {
|
||||
if (RetrieveHashedFile(usage_info_file_name, &file)) {
|
||||
for (int i = 0; i < file.usage_info().sessions_size(); ++i) {
|
||||
provider_session_tokens->push_back(file.usage_info().sessions(i).token());
|
||||
}
|
||||
} else {
|
||||
LOGW("DeviceFiles::DeleteAllUsageInfoForApp: Unable to retrieve file");
|
||||
}
|
||||
return RemoveFile(file_name);
|
||||
return RemoveFile(usage_info_file_name);
|
||||
}
|
||||
|
||||
bool DeviceFiles::RetrieveUsageInfo(
|
||||
const std::string& app_id,
|
||||
const std::string& usage_info_file_name,
|
||||
std::vector<std::pair<CdmKeyMessage, CdmKeyResponse> >* usage_info) {
|
||||
if (!initialized_) {
|
||||
LOGW("DeviceFiles::RetrieveUsageInfo: not initialized");
|
||||
@@ -610,14 +615,14 @@ bool DeviceFiles::RetrieveUsageInfo(
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string file_name = GetUsageInfoFileName(app_id);
|
||||
if (!FileExists(file_name) || GetFileSize(file_name) == 0) {
|
||||
if (!FileExists(usage_info_file_name) ||
|
||||
GetFileSize(usage_info_file_name) == 0) {
|
||||
usage_info->resize(0);
|
||||
return true;
|
||||
}
|
||||
|
||||
video_widevine_client::sdk::File file;
|
||||
if (!RetrieveHashedFile(file_name, &file)) {
|
||||
if (!RetrieveHashedFile(usage_info_file_name, &file)) {
|
||||
LOGW("DeviceFiles::RetrieveUsageInfo: Unable to parse file");
|
||||
return false;
|
||||
}
|
||||
@@ -632,19 +637,19 @@ bool DeviceFiles::RetrieveUsageInfo(
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DeviceFiles::RetrieveUsageInfo(const std::string& app_id,
|
||||
bool DeviceFiles::RetrieveUsageInfo(const std::string& usage_info_file_name,
|
||||
const std::string& provider_session_token,
|
||||
CdmKeyMessage* license_request,
|
||||
CdmKeyResponse* license_response,
|
||||
CdmUsageEntry* usage_entry) {
|
||||
std::string* usage_entry,
|
||||
uint32_t* usage_entry_number) {
|
||||
if (!initialized_) {
|
||||
LOGW("DeviceFiles::RetrieveUsageInfo: not initialized");
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string file_name = GetUsageInfoFileName(app_id);
|
||||
video_widevine_client::sdk::File file;
|
||||
if (!RetrieveHashedFile(file_name, &file)) {
|
||||
if (!RetrieveHashedFile(usage_info_file_name, &file)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -654,6 +659,8 @@ bool DeviceFiles::RetrieveUsageInfo(const std::string& app_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();
|
||||
*usage_entry_number =
|
||||
file.usage_info().sessions(index).usage_entry_number();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -662,28 +669,32 @@ bool DeviceFiles::RetrieveUsageInfo(const std::string& app_id,
|
||||
}
|
||||
|
||||
bool DeviceFiles::RetrieveUsageInfoByKeySetId(
|
||||
const std::string& app_id,
|
||||
const std::string& usage_info_file_name,
|
||||
const std::string& key_set_id,
|
||||
std::string* provider_session_token,
|
||||
CdmKeyMessage* license_request,
|
||||
CdmKeyResponse* license_response,
|
||||
CdmUsageEntry* usage_entry) {
|
||||
std::string* usage_entry,
|
||||
uint32_t* usage_entry_number) {
|
||||
if (!initialized_) {
|
||||
LOGW("DeviceFiles::RetrieveUsageInfoByKeySetId: not initialized");
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string file_name = GetUsageInfoFileName(app_id);
|
||||
video_widevine_client::sdk::File file;
|
||||
if (!RetrieveHashedFile(file_name, &file)) {
|
||||
if (!RetrieveHashedFile(usage_info_file_name, &file)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int index = 0;
|
||||
for (; index < file.usage_info().sessions_size(); ++index) {
|
||||
if (file.usage_info().sessions(index).key_set_id() == key_set_id) {
|
||||
*provider_session_token = file.usage_info().sessions(index).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();
|
||||
*usage_entry_number =
|
||||
file.usage_info().sessions(index).usage_entry_number();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -691,6 +702,97 @@ bool DeviceFiles::RetrieveUsageInfoByKeySetId(
|
||||
return false;
|
||||
}
|
||||
|
||||
bool DeviceFiles::StoreUsageInfo(const std::string& usage_info_file_name,
|
||||
const std::vector<CdmUsageData>& usage_data) {
|
||||
if (!initialized_) {
|
||||
LOGW("DeviceFiles::StoreUsageInfo: not initialized");
|
||||
return false;
|
||||
}
|
||||
|
||||
video_widevine_client::sdk::File file;
|
||||
file.set_type(video_widevine_client::sdk::File::USAGE_INFO);
|
||||
file.set_version(video_widevine_client::sdk::File::VERSION_1);
|
||||
|
||||
UsageInfo* usage_info = file.mutable_usage_info();
|
||||
for (size_t i = 0; i < usage_data.size(); ++i) {
|
||||
UsageInfo_ProviderSession* provider_session = usage_info->add_sessions();
|
||||
|
||||
provider_session->set_token(usage_data[i].provider_session_token.data(),
|
||||
usage_data[i].provider_session_token.size());
|
||||
provider_session->set_license_request(usage_data[i].license_request.data(),
|
||||
usage_data[i].license_request.size());
|
||||
provider_session->set_license(usage_data[i].license.data(),
|
||||
usage_data[i].license.size());
|
||||
provider_session->set_key_set_id(usage_data[i].key_set_id.data(),
|
||||
usage_data[i].key_set_id.size());
|
||||
provider_session->set_usage_entry(usage_data[i].usage_entry);
|
||||
provider_session->set_usage_entry_number(usage_data[i].usage_entry_number);
|
||||
}
|
||||
|
||||
std::string serialized_file;
|
||||
file.SerializeToString(&serialized_file);
|
||||
return StoreFileWithHash(usage_info_file_name, serialized_file);
|
||||
}
|
||||
|
||||
bool DeviceFiles::RetrieveUsageInfo(const std::string& usage_info_file_name,
|
||||
std::vector<CdmUsageData>* usage_data) {
|
||||
|
||||
if (!initialized_) {
|
||||
LOGW("DeviceFiles::RetrieveUsageInfo: not initialized");
|
||||
return false;
|
||||
}
|
||||
|
||||
video_widevine_client::sdk::File file;
|
||||
if (!RetrieveHashedFile(usage_info_file_name, &file)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
usage_data->resize(file.usage_info().sessions_size());
|
||||
for (int i = 0; i < file.usage_info().sessions_size(); ++i) {
|
||||
(*usage_data)[i].provider_session_token =
|
||||
file.usage_info().sessions(i).token();
|
||||
(*usage_data)[i].license_request =
|
||||
file.usage_info().sessions(i).license_request();
|
||||
(*usage_data)[i].license = file.usage_info().sessions(i).license();
|
||||
(*usage_data)[i].key_set_id = file.usage_info().sessions(i).key_set_id();
|
||||
(*usage_data)[i].usage_entry = file.usage_info().sessions(i).usage_entry();
|
||||
(*usage_data)[i].usage_entry_number =
|
||||
file.usage_info().sessions(i).usage_entry_number();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool DeviceFiles::ListUsageInfoFiles(
|
||||
std::vector<std::string>* usage_info_file_names) {
|
||||
if (!initialized_) {
|
||||
LOGW("DeviceFiles::ListUsageInfoFiles: not initialized");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get list of filenames
|
||||
std::vector<std::string> filenames;
|
||||
if (!ListFiles(&filenames)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Scan list of all filenames and return only usage info filenames
|
||||
usage_info_file_names->clear();
|
||||
for (size_t i = 0; i < filenames.size(); i++) {
|
||||
std::string* name = &filenames[i];
|
||||
std::size_t pos_prefix = name->find(kUsageInfoFileNamePrefix);
|
||||
std::size_t pos_suffix = name->find(kUsageInfoFileNameExt);
|
||||
if (pos_prefix == std::string::npos ||
|
||||
pos_suffix == std::string::npos) {
|
||||
// Skip this file - extension does not match
|
||||
continue;
|
||||
}
|
||||
|
||||
usage_info_file_names->push_back(*name);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DeviceFiles::StoreHlsAttributes(
|
||||
const std::string& key_set_id, const CdmHlsMethod method,
|
||||
const std::vector<uint8_t>& media_segment_iv) {
|
||||
@@ -790,7 +892,7 @@ bool DeviceFiles::DeleteHlsAttributes(const std::string& key_set_id) {
|
||||
|
||||
bool DeviceFiles::StoreUsageTableInfo(
|
||||
const CdmUsageTableHeader& usage_table_header,
|
||||
const std::vector<DeviceFiles::UsageEntryInfo>& usage_entry_info) {
|
||||
const std::vector<CdmUsageEntryInfo>& usage_entry_info) {
|
||||
if (!initialized_) {
|
||||
LOGW("DeviceFiles::StoreUsageTableHeader: not initialized");
|
||||
return false;
|
||||
@@ -807,23 +909,23 @@ bool DeviceFiles::StoreUsageTableInfo(
|
||||
for (size_t i = 0; i < usage_entry_info.size(); ++i) {
|
||||
UsageTableInfo_UsageEntryInfo* info =
|
||||
usage_table_info->add_usage_entry_info();
|
||||
info->set_key_set_id(usage_entry_info[i].key_set_id);
|
||||
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);
|
||||
info->set_usage_info_file_name(
|
||||
usage_entry_info[i].usage_info_file_name);
|
||||
break;
|
||||
case kStorageUnknown:
|
||||
default:
|
||||
LOGW("DeviceFiles::StoreUsageTableHeader: unknown storage type: %d",
|
||||
usage_entry_info[i].storage_type);
|
||||
return false;
|
||||
info->set_storage(
|
||||
UsageTableInfo_UsageEntryInfo_UsageEntryStorage_UNKNOWN);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -835,7 +937,7 @@ bool DeviceFiles::StoreUsageTableInfo(
|
||||
|
||||
bool DeviceFiles::RetrieveUsageTableInfo(
|
||||
CdmUsageTableHeader* usage_table_header,
|
||||
std::vector<DeviceFiles::UsageEntryInfo>* usage_entry_info) {
|
||||
std::vector<CdmUsageEntryInfo>* usage_entry_info) {
|
||||
if (!initialized_) {
|
||||
LOGW("DeviceFiles::RetrieveUsageTableInfo: not initialized");
|
||||
return false;
|
||||
@@ -879,21 +981,20 @@ bool DeviceFiles::RetrieveUsageTableInfo(
|
||||
for (int i = 0; i < usage_table_info.usage_entry_info_size(); ++i) {
|
||||
const UsageTableInfo_UsageEntryInfo& info =
|
||||
usage_table_info.usage_entry_info(i);
|
||||
(*usage_entry_info)[i].key_set_id = info.key_set_id();
|
||||
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();
|
||||
(*usage_entry_info)[i].usage_info_file_name =
|
||||
info.usage_info_file_name();
|
||||
break;
|
||||
case UsageTableInfo_UsageEntryInfo_UsageEntryStorage_UNKNOWN:
|
||||
default:
|
||||
LOGW("DeviceFiles::RetrieveUsageTableInfo: Unknown storage type: %d",
|
||||
info.storage());
|
||||
return false;
|
||||
(*usage_entry_info)[i].storage_type = kStorageUnknown;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -44,6 +44,7 @@ message License {
|
||||
// ignored if there is no grace period.
|
||||
optional int64 grace_period_end_time = 11 [default = 0];
|
||||
optional bytes usage_entry = 12;
|
||||
optional int64 usage_entry_number = 13;
|
||||
}
|
||||
|
||||
message UsageInfo {
|
||||
@@ -53,6 +54,7 @@ message UsageInfo {
|
||||
optional bytes license = 3;
|
||||
optional bytes key_set_id = 4;
|
||||
optional bytes usage_entry = 5;
|
||||
optional int64 usage_entry_number = 6;
|
||||
}
|
||||
|
||||
repeated ProviderSession sessions = 1;
|
||||
@@ -72,12 +74,12 @@ message UsageTableInfo {
|
||||
enum UsageEntryStorage {
|
||||
LICENSE = 1;
|
||||
USAGE_INFO = 2;
|
||||
UNKNOWN = 3;
|
||||
}
|
||||
|
||||
optional UsageEntryStorage storage = 1;
|
||||
optional bytes key_set_id = 2; // used if storage is LICENSE
|
||||
optional bytes provider_session_token = 3; // used if storage is USAGE_INFO
|
||||
optional bytes app_id = 4; // used if storage is USAGE_INFO
|
||||
optional bytes key_set_id = 2;
|
||||
optional bytes usage_info_file_name = 3; // hash of the app_id
|
||||
}
|
||||
|
||||
optional bytes usage_table_header = 1;
|
||||
|
||||
@@ -205,8 +205,7 @@ CdmResponseType CdmLicense::PrepareKeyRequest(
|
||||
return INVALID_PARAMETERS_LIC_7;
|
||||
}
|
||||
|
||||
// If privacy mode and no service certificate, initiate a
|
||||
// service certificate request.
|
||||
// If privacy mode, must have service certificate
|
||||
if (Properties::UsePrivacyMode(session_id_) &&
|
||||
!service_certificate_->has_certificate()) {
|
||||
LOGE("CdmLicense::PrepareKeyRequest: failure with privacy mode - "
|
||||
@@ -479,8 +478,13 @@ CdmResponseType CdmLicense::HandleKeyResponse(
|
||||
license.policy().can_persist())
|
||||
is_offline_ = true;
|
||||
|
||||
if (license.id().has_provider_session_token())
|
||||
LOGV("Get Provider_session_token:");
|
||||
if (license.id().has_provider_session_token()) {
|
||||
provider_session_token_ = license.id().provider_session_token();
|
||||
LOGV("Provider_session_token=%s", provider_session_token_.c_str());
|
||||
} else {
|
||||
LOGV("NO Provider_session_token");
|
||||
}
|
||||
|
||||
if (license.policy().has_renewal_server_url()) {
|
||||
server_url_ = license.policy().renewal_server_url();
|
||||
@@ -797,6 +801,7 @@ bool CdmLicense::GetClientTokenType(
|
||||
case kClientTokenOemCert:
|
||||
default:
|
||||
// shouldn't happen
|
||||
LOGE("GetClientTokenType: BAD TOKEN TYPE");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -980,7 +985,7 @@ CdmResponseType CdmLicense::PrepareContentId(
|
||||
if (!init_data.IsEmpty()) {
|
||||
cenc_content_id->add_pssh(init_data.data());
|
||||
} else {
|
||||
LOGE("CdmLicense::PrepareKeyRequest: ISO-CENC init data not available");
|
||||
LOGE("CdmLicense::PrepareContentId: ISO-CENC init data not available");
|
||||
return CENC_INIT_DATA_UNAVAILABLE;
|
||||
}
|
||||
|
||||
@@ -994,7 +999,7 @@ CdmResponseType CdmLicense::PrepareContentId(
|
||||
if (!init_data.IsEmpty()) {
|
||||
webm_content_id->set_header(init_data.data());
|
||||
} else {
|
||||
LOGE("CdmLicense::PrepareKeyRequest: WebM init data not available");
|
||||
LOGE("CdmLicense::PrepareContentId: WebM init data not available");
|
||||
return WEBM_INIT_DATA_UNAVAILABLE;
|
||||
}
|
||||
|
||||
@@ -1002,7 +1007,7 @@ CdmResponseType CdmLicense::PrepareContentId(
|
||||
return PREPARE_WEBM_CONTENT_ID_FAILED;
|
||||
}
|
||||
} else {
|
||||
LOGE("CdmLicense::PrepareKeyRequest: no support for init data type (%s)",
|
||||
LOGE("CdmLicense::PrepareContentId: no support for init data type (%s)",
|
||||
init_data.type().c_str());
|
||||
return UNSUPPORTED_INIT_DATA_FORMAT;
|
||||
}
|
||||
|
||||
@@ -103,7 +103,15 @@ bool LicenseKeys::ApplyStatusChange(CdmKeyStatus new_status,
|
||||
return keys_changed;
|
||||
}
|
||||
|
||||
CdmKeyStatus LicenseKeys::GetKeyStatus(const KeyId& key_id) {
|
||||
if (keys_.count(key_id) == 0) {
|
||||
return kKeyStatusKeyUnknown;
|
||||
}
|
||||
return keys_[key_id]->GetKeyStatus();
|
||||
}
|
||||
|
||||
void LicenseKeys::ExtractKeyStatuses(CdmKeyStatusMap* content_keys) {
|
||||
content_keys->clear();
|
||||
for (LicenseKeyStatusIterator it = keys_.begin(); it != keys_.end(); ++it) {
|
||||
if (it->second->IsContentKey()) {
|
||||
const KeyId key_id = it->first;
|
||||
|
||||
@@ -47,6 +47,10 @@ bool PolicyEngine::CanDecryptContent(const KeyId& key_id) {
|
||||
}
|
||||
}
|
||||
|
||||
CdmKeyStatus PolicyEngine::GetKeyStatus(const KeyId& key_id) {
|
||||
return license_keys_->GetKeyStatus(key_id);
|
||||
}
|
||||
|
||||
void PolicyEngine::InitDevice(CryptoSession* crypto_session) {
|
||||
current_resolution_ = HDCP_UNSPECIFIED_VIDEO_RESOLUTION;
|
||||
next_device_check_ = 0;
|
||||
@@ -101,7 +105,9 @@ void PolicyEngine::OnTimerEvent() {
|
||||
// Test to determine if renewal should be attempted.
|
||||
switch (license_state_) {
|
||||
case kLicenseStateCanPlay: {
|
||||
if (HasRenewalDelayExpired(current_time)) renewal_needed = true;
|
||||
if (HasRenewalDelayExpired(current_time)) {
|
||||
renewal_needed = true;
|
||||
}
|
||||
// HDCP may change, so force a check.
|
||||
NotifyKeysChange(kKeyStatusUsable);
|
||||
break;
|
||||
@@ -113,7 +119,9 @@ void PolicyEngine::OnTimerEvent() {
|
||||
}
|
||||
|
||||
case kLicenseStateWaitingLicenseUpdate: {
|
||||
if (HasRenewalRetryIntervalExpired(current_time)) renewal_needed = true;
|
||||
if (HasRenewalRetryIntervalExpired(current_time)) {
|
||||
renewal_needed = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -429,6 +437,10 @@ bool PolicyEngine::HasRenewalRetryIntervalExpired(int64_t current_time) {
|
||||
next_renewal_time_ <= current_time;
|
||||
}
|
||||
|
||||
// Apply a key status to the current keys.
|
||||
// If this represents a new key status, perform a notification callback.
|
||||
// NOTE: if the new status is kKeyStatusUsable, the HDCP check may result in an
|
||||
// override to kKeyStatusOutputNotAllowed.
|
||||
void PolicyEngine::NotifyKeysChange(CdmKeyStatus new_status) {
|
||||
bool keys_changed;
|
||||
bool has_new_usable_key = false;
|
||||
|
||||
@@ -11,110 +11,6 @@
|
||||
|
||||
namespace {
|
||||
// Service certificate for Google/Widevine Provisioning and License servers.
|
||||
static const unsigned char kRootCertForDev[] = {
|
||||
0x0a, 0x9c, 0x03, 0x08, 0x00, 0x12, 0x01, 0x00,
|
||||
0x18, 0xc3, 0x94, 0x88, 0x8b, 0x05, 0x22, 0x8e,
|
||||
0x03, 0x30, 0x82, 0x01, 0x8a, 0x02, 0x82, 0x01,
|
||||
0x81, 0x00, 0xc0, 0x00, 0x36, 0x6f, 0x8e, 0xe9,
|
||||
0xcf, 0x86, 0xdb, 0xcd, 0xdd, 0x4e, 0xfd, 0xcd,
|
||||
0x45, 0xbf, 0x6d, 0x96, 0x05, 0x00, 0xb8, 0x72,
|
||||
0xff, 0x9c, 0xb4, 0x39, 0xa8, 0xd8, 0xc0, 0x09,
|
||||
0x73, 0xc0, 0x24, 0x6a, 0x39, 0x4d, 0x36, 0x3f,
|
||||
0x9a, 0xe4, 0xb8, 0x76, 0xdc, 0x34, 0xe3, 0xee,
|
||||
0x5f, 0xdd, 0x13, 0x20, 0x08, 0xdc, 0x4e, 0x6f,
|
||||
0x4e, 0x9f, 0xc0, 0x36, 0xf9, 0xce, 0xc6, 0xb7,
|
||||
0xdb, 0xe0, 0x51, 0x2d, 0x30, 0x0b, 0xae, 0x0a,
|
||||
0x20, 0xd2, 0x29, 0x3c, 0x2c, 0x1d, 0x87, 0x65,
|
||||
0xeb, 0x5f, 0x93, 0xd7, 0x3f, 0x12, 0x08, 0x50,
|
||||
0x0e, 0x55, 0xf3, 0xf1, 0x19, 0xee, 0x18, 0x21,
|
||||
0x6e, 0xea, 0xb6, 0x0a, 0x4a, 0x0b, 0x9c, 0x72,
|
||||
0x37, 0xeb, 0x0b, 0x68, 0xfc, 0x52, 0x46, 0x62,
|
||||
0xd0, 0xa2, 0x99, 0x66, 0xe2, 0x2b, 0x74, 0xdd,
|
||||
0x5c, 0xaf, 0x9a, 0x03, 0xc4, 0x5d, 0x93, 0xfb,
|
||||
0xcd, 0x45, 0x9a, 0xee, 0xfb, 0x7b, 0x18, 0x94,
|
||||
0xc1, 0x8c, 0x82, 0x34, 0x7f, 0x02, 0x12, 0x21,
|
||||
0xfc, 0x40, 0xc1, 0x50, 0xc9, 0xf4, 0x7c, 0xd5,
|
||||
0x96, 0xbe, 0x55, 0x7f, 0x3c, 0x1d, 0x70, 0x34,
|
||||
0xb4, 0xa2, 0x03, 0xc4, 0x3f, 0x89, 0x60, 0xe4,
|
||||
0x24, 0x09, 0x1a, 0x74, 0xc4, 0xb6, 0x39, 0xf0,
|
||||
0x34, 0x60, 0x8e, 0xa7, 0x5f, 0x02, 0x7f, 0xb9,
|
||||
0x2a, 0xc5, 0xaa, 0xb2, 0x4c, 0x34, 0xd3, 0x5a,
|
||||
0x5d, 0xfa, 0x07, 0xf2, 0xb9, 0xb3, 0xc1, 0xba,
|
||||
0xab, 0xbe, 0x89, 0x99, 0xe3, 0x6d, 0x9b, 0xa9,
|
||||
0xd3, 0xaf, 0x2a, 0x08, 0x76, 0xf3, 0x0e, 0xc9,
|
||||
0xe0, 0xb3, 0xbf, 0x51, 0x0c, 0xc5, 0xf4, 0xf3,
|
||||
0x15, 0x7b, 0x08, 0x11, 0x8f, 0x61, 0x1f, 0x61,
|
||||
0x64, 0xdb, 0x15, 0x84, 0x5b, 0x8a, 0xd1, 0x28,
|
||||
0x40, 0xde, 0xc5, 0x32, 0xb5, 0xad, 0xad, 0x65,
|
||||
0x4c, 0xf5, 0xf7, 0xd1, 0x90, 0x14, 0x5d, 0xc2,
|
||||
0x85, 0x98, 0xcc, 0xe9, 0xe6, 0x95, 0x42, 0xe1,
|
||||
0x3e, 0xfc, 0x7f, 0xc4, 0x49, 0xed, 0x9c, 0xe4,
|
||||
0x49, 0x3f, 0x03, 0x1b, 0x0d, 0xa0, 0xfb, 0xf5,
|
||||
0x38, 0x49, 0xd2, 0xdf, 0xa3, 0x88, 0xb2, 0x76,
|
||||
0x93, 0x08, 0x20, 0x18, 0xfe, 0xdc, 0x72, 0x6c,
|
||||
0x6e, 0xbf, 0x61, 0x37, 0x03, 0xdb, 0xe5, 0x72,
|
||||
0x68, 0xe0, 0x99, 0x2f, 0xb9, 0xe0, 0x2e, 0xbb,
|
||||
0x9f, 0x96, 0x36, 0x61, 0xaa, 0x2d, 0xa4, 0x93,
|
||||
0xe8, 0x50, 0x58, 0xe6, 0x61, 0xe1, 0x14, 0xcf,
|
||||
0xac, 0x86, 0x98, 0x7f, 0x3c, 0x67, 0x16, 0xce,
|
||||
0xb8, 0x70, 0x90, 0x3a, 0x5a, 0xd4, 0xe1, 0xe2,
|
||||
0x35, 0x98, 0xbf, 0x93, 0x41, 0x11, 0xb2, 0x44,
|
||||
0xb2, 0x64, 0xc2, 0xe7, 0x09, 0x45, 0xb7, 0x6f,
|
||||
0xb0, 0xbd, 0x6e, 0xe8, 0x67, 0xfa, 0x8d, 0xd4,
|
||||
0xfa, 0x4b, 0xef, 0xa8, 0x9d, 0x8a, 0x0a, 0xd9,
|
||||
0x14, 0x77, 0x09, 0x11, 0x9e, 0xc3, 0x50, 0x14,
|
||||
0x6c, 0x45, 0x02, 0x03, 0x01, 0x00, 0x01, 0x12,
|
||||
0x80, 0x03, 0x17, 0x01, 0x60, 0x24, 0xe1, 0xfd,
|
||||
0x75, 0x60, 0x17, 0x5c, 0x5e, 0x6f, 0x9f, 0x7f,
|
||||
0xdf, 0xee, 0xf0, 0xf7, 0x7d, 0xb2, 0x50, 0x65,
|
||||
0x36, 0x26, 0x14, 0x19, 0x01, 0x5e, 0x98, 0x94,
|
||||
0x65, 0x97, 0x83, 0xaa, 0x4a, 0x2b, 0x98, 0x2e,
|
||||
0x02, 0xf3, 0xb2, 0xc9, 0xb2, 0xed, 0xd3, 0x1b,
|
||||
0x20, 0x27, 0x9e, 0xe1, 0x25, 0xc7, 0x86, 0xf0,
|
||||
0x66, 0x68, 0x5d, 0xd2, 0x3d, 0xa7, 0xbb, 0xbc,
|
||||
0x22, 0xfc, 0x29, 0xfa, 0x17, 0x16, 0xf4, 0xa2,
|
||||
0x00, 0x10, 0x87, 0xb4, 0x5d, 0x51, 0x45, 0x6b,
|
||||
0xc8, 0xf4, 0x6b, 0xcc, 0x92, 0x91, 0xe7, 0xa7,
|
||||
0x93, 0xbc, 0xc7, 0x2e, 0xdc, 0xac, 0x82, 0x2b,
|
||||
0x85, 0x56, 0x7b, 0xae, 0xf2, 0xd8, 0xda, 0xa6,
|
||||
0xd7, 0xfa, 0x6d, 0x70, 0x2a, 0x2e, 0xcf, 0x69,
|
||||
0xef, 0x57, 0x91, 0xa7, 0xaa, 0x40, 0x15, 0x4a,
|
||||
0x49, 0x1b, 0xbc, 0x36, 0xbb, 0x1c, 0x94, 0x33,
|
||||
0x36, 0x61, 0x22, 0x9d, 0x22, 0x66, 0xf0, 0x88,
|
||||
0x5e, 0x7c, 0x3c, 0xa5, 0xff, 0x81, 0xcf, 0x1a,
|
||||
0x44, 0xa1, 0x2b, 0xdf, 0xc9, 0x3d, 0xd5, 0xc7,
|
||||
0xc7, 0x3a, 0x75, 0xac, 0x29, 0xfa, 0xfd, 0x5b,
|
||||
0xda, 0xf5, 0x8f, 0xd9, 0xdf, 0x08, 0xa4, 0x8d,
|
||||
0x19, 0x4a, 0xa4, 0x79, 0x6e, 0x47, 0xf6, 0x07,
|
||||
0xe0, 0xbd, 0xbf, 0x30, 0x3a, 0xf9, 0xf5, 0xc0,
|
||||
0x90, 0x6d, 0x70, 0x27, 0x44, 0xa8, 0x5e, 0x70,
|
||||
0xcd, 0x43, 0x3e, 0xaf, 0xf0, 0xd7, 0x20, 0xd3,
|
||||
0x5e, 0x97, 0x2d, 0x32, 0x1a, 0x3d, 0x2d, 0x0f,
|
||||
0x0f, 0xcf, 0xac, 0x4e, 0x88, 0x75, 0x98, 0x6c,
|
||||
0xfa, 0xe8, 0x42, 0x58, 0x99, 0xaa, 0x45, 0x0c,
|
||||
0x41, 0x0c, 0x6e, 0x27, 0x58, 0x57, 0xd2, 0x5b,
|
||||
0x82, 0x3d, 0x75, 0x2f, 0x9e, 0xf3, 0xe4, 0x00,
|
||||
0xcf, 0x91, 0x48, 0x25, 0xca, 0x98, 0xf2, 0x91,
|
||||
0x6b, 0x41, 0xa5, 0xe8, 0xcd, 0x64, 0xa7, 0x2e,
|
||||
0x78, 0xc7, 0x76, 0x82, 0x3f, 0xf8, 0x57, 0x8a,
|
||||
0x9d, 0x78, 0x25, 0xad, 0xf3, 0x1a, 0x8b, 0xfc,
|
||||
0x83, 0x9a, 0x98, 0x87, 0xe4, 0x55, 0x3e, 0x1c,
|
||||
0xa7, 0x80, 0x8f, 0xd6, 0x76, 0xab, 0x03, 0xc7,
|
||||
0x05, 0x66, 0xc3, 0xa0, 0x4c, 0x33, 0x1f, 0x39,
|
||||
0x74, 0x1b, 0x2a, 0xbf, 0xe6, 0xb0, 0x9f, 0x6b,
|
||||
0xc1, 0xd6, 0xd3, 0xf4, 0x46, 0x9b, 0xf3, 0xab,
|
||||
0xca, 0x2e, 0x88, 0x3d, 0x84, 0x5f, 0xc9, 0x9b,
|
||||
0x47, 0xbb, 0x57, 0x64, 0x08, 0x0e, 0x18, 0x74,
|
||||
0x83, 0x44, 0xd4, 0xc3, 0x18, 0x97, 0xcf, 0x89,
|
||||
0x6a, 0x49, 0x51, 0xc6, 0xff, 0x8d, 0x39, 0xc5,
|
||||
0x23, 0xf9, 0xd5, 0x01, 0xd7, 0x2f, 0xa9, 0xa5,
|
||||
0x5d, 0xa9, 0xf3, 0xc9, 0xfd, 0xc4, 0x52, 0x19,
|
||||
0x7d, 0xf6, 0xa4, 0x2c, 0x0c, 0xa0, 0x07, 0xdf,
|
||||
0x7b, 0x44, 0xd7, 0xe5, 0xbf, 0x57, 0x87, 0xc9,
|
||||
0x8c, 0xfe, 0x30, 0xb2, 0x89, 0x5d, 0x00, 0x03,
|
||||
0x3b, 0xe5
|
||||
};
|
||||
|
||||
static const unsigned char kRootCertForProd[] = {
|
||||
0x0a, 0x9c, 0x03, 0x08, 0x00, 0x12, 0x01, 0x00,
|
||||
0x18, 0xdd, 0x94, 0x88, 0x8b, 0x05, 0x22, 0x8e,
|
||||
@@ -231,14 +127,8 @@ using video_widevine::SignedDrmDeviceCertificate;
|
||||
using video_widevine::SignedMessage;
|
||||
|
||||
CdmResponseType ServiceCertificate::Init(const std::string& certificate) {
|
||||
// TODO(tinskip): Get rid of conditional compilation.
|
||||
#if defined(QA_TEST_SERVER)
|
||||
std::string root_cert_str(reinterpret_cast<const char*>(&kRootCertForDev[0]),
|
||||
sizeof(kRootCertForDev));
|
||||
#else
|
||||
std::string root_cert_str(reinterpret_cast<const char*>(&kRootCertForProd[0]),
|
||||
sizeof(kRootCertForProd));
|
||||
#endif // !defined(QA_TEST_SERVER);
|
||||
|
||||
// Load root cert public key. Don't bother verifying it.
|
||||
SignedDrmDeviceCertificate signed_root_cert;
|
||||
|
||||
@@ -229,7 +229,7 @@ std::vector<uint8_t> Base64Decode(const std::string& b64_input) {
|
||||
}
|
||||
|
||||
// Decode for Filename-friendly base64 encoding (RFC4648), commonly referred
|
||||
// as Base64WebSafeDecode.
|
||||
// as Base64WebSafeDecode. Add padding if needed.
|
||||
std::vector<uint8_t> Base64SafeDecode(const std::string& b64_input) {
|
||||
if (b64_input.empty()) {
|
||||
return std::vector<uint8_t>();
|
||||
|
||||
Reference in New Issue
Block a user