Source release 14.1.0

This commit is contained in:
John W. Bruce
2018-06-29 15:59:47 -07:00
parent 3ab70cec4e
commit afa11a48a0
1941 changed files with 557780 additions and 105547 deletions

View File

@@ -1,4 +1,6 @@
// Copyright 2013 Google Inc. All Rights Reserved.
// Copyright 2018 Google LLC. All Rights Reserved. This file and proprietary
// source code may only be used and distributed under the Widevine Master
// License Agreement.
#include "cdm_engine.h"
@@ -28,6 +30,8 @@ const size_t kUsageReportsPerRequest = 1;
namespace wvcdm {
Lock shared_ptr_ref_count_lock_;
class UsagePropertySet : public CdmClientPropertySet {
public:
UsagePropertySet() {}
@@ -70,7 +74,6 @@ CdmEngine::CdmEngine(FileSystem* file_system, const std::string& spoid)
seeded_ = true;
}
life_span_.Start();
metrics_.cdm_engine_creation_time_millis_.Record(clock_.GetCurrentTime());
std::string cdm_version;
@@ -82,18 +85,7 @@ CdmEngine::CdmEngine(FileSystem* file_system, const std::string& spoid)
}
}
CdmEngine::~CdmEngine() {
M_RECORD(&metrics_, cdm_engine_life_span_, life_span_.AsMs());
}
CdmResponseType CdmEngine::SetProvisioningServiceCertificate(
const std::string& certificate) {
return provisioning_service_certificate_.Init(certificate);
}
bool CdmEngine::HasProvisioningServiceCertificate() {
return provisioning_service_certificate_.has_certificate();
}
CdmEngine::~CdmEngine() {}
CdmResponseType CdmEngine::OpenSession(
const CdmKeySystem& key_system, CdmClientPropertySet* property_set,
@@ -149,6 +141,7 @@ CdmResponseType CdmEngine::OpenSession(
return sts;
}
CdmSessionId id = new_session->session_id();
LOGI("CdmEngine::OpenSession: %s", id.c_str());
session_map_.Add(id, new_session.release());
if (session_id) *session_id = id;
@@ -412,11 +405,23 @@ CdmResponseType CdmEngine::RemoveKeys(const CdmSessionId& session_id) {
return SESSION_NOT_FOUND_5;
}
session->ReleaseCrypto();
session->RemoveKeys();
return NO_ERROR;
}
CdmResponseType CdmEngine::RemoveLicense(const CdmSessionId& session_id) {
LOGI("CdmEngine::RemoveLicense");
shared_ptr<CdmSession> session;
if (!session_map_.FindSession(session_id, &session)) {
LOGE("session_id not found = %s", session_id.c_str());
return SESSION_NOT_FOUND_19;
}
return session->RemoveLicense();
}
CdmResponseType CdmEngine::GenerateRenewalRequest(
const CdmSessionId& session_id, CdmKeyRequest* key_request) {
LOGI("CdmEngine::GenerateRenewalRequest");
@@ -761,7 +766,9 @@ CdmResponseType CdmEngine::QueryOemCryptoSessionId(
*/
CdmResponseType CdmEngine::GetProvisioningRequest(
CdmCertificateType cert_type, const std::string& cert_authority,
CdmProvisioningRequest* request, std::string* default_url) {
const std::string& service_certificate, CdmProvisioningRequest* request,
std::string* default_url) {
LOGI("CdmEngine::GetProvisioningRequest");
if (!request) {
LOGE("CdmEngine::GetProvisioningRequest: invalid output parameters");
return INVALID_PROVISIONING_REQUEST_PARAM_1;
@@ -776,8 +783,7 @@ CdmResponseType CdmEngine::GetProvisioningRequest(
if (NULL == cert_provisioning_.get()) {
cert_provisioning_.reset(
new CertificateProvisioning(metrics_.GetCryptoMetrics()));
CdmResponseType status = cert_provisioning_->Init(
provisioning_service_certificate_.certificate());
CdmResponseType status = cert_provisioning_->Init(service_certificate);
if (status != NO_ERROR) return status;
}
CdmResponseType ret = cert_provisioning_->GetProvisioningRequest(
@@ -799,6 +805,7 @@ CdmResponseType CdmEngine::GetProvisioningRequest(
CdmResponseType CdmEngine::HandleProvisioningResponse(
const CdmProvisioningResponse& response, std::string* cert,
std::string* wrapped_key) {
LOGI("CdmEngine::HandleProvisioningResponse");
if (response.empty()) {
LOGE("CdmEngine::HandleProvisioningResponse: Empty provisioning response.");
cert_provisioning_.reset(NULL);
@@ -873,6 +880,19 @@ bool CdmEngine::IsProvisioned(CdmSecurityLevel security_level) {
}
CdmResponseType CdmEngine::Unprovision(CdmSecurityLevel security_level) {
// Devices with baked-in DRM certs cannot be reprovisioned and therefore must
// not be unprovisioned.
CryptoSession crypto_session(metrics_.GetCryptoMetrics());
CdmClientTokenType token_type = kClientTokenUninitialized;
CdmResponseType res = crypto_session.GetProvisioningMethod(
security_level == kSecurityLevelL3 ? kLevel3 : kLevelDefault,
&token_type);
if (res != NO_ERROR) {
return res;
} else if (token_type == kClientTokenDrmCert) {
return DEVICE_CANNOT_REPROVISION;
}
DeviceFiles handle(file_system_);
if (!handle.Init(security_level)) {
LOGE("CdmEngine::Unprovision: unable to initialize device files");
@@ -939,20 +959,22 @@ CdmResponseType CdmEngine::ListStoredLicenses(
return NO_ERROR;
}
CdmResponseType CdmEngine::ListUsageRecords(const std::string& app_id,
CdmSecurityLevel security_level,
std::vector<std::string>* ksids) {
CdmResponseType CdmEngine::ListUsageIds(
const std::string& app_id,
CdmSecurityLevel security_level,
std::vector<std::string>* ksids,
std::vector<std::string>* provider_session_tokens) {
DeviceFiles handle(file_system_);
if (!ksids) {
LOGE("CdmEngine::ListUsageRecords: no response destination");
if (!ksids && !provider_session_tokens) {
LOGE("CdmEngine::ListUsageIds: no response destination");
return INVALID_PARAMETERS_ENG_23;
}
if (!handle.Init(security_level)) {
LOGE("CdmEngine::ListUsageRecords: unable to initialize device files");
LOGE("CdmEngine::ListUsageIds: unable to initialize device files");
return LIST_USAGE_ERROR_1;
}
if (!handle.ListUsageRecords(app_id, ksids)) {
LOGE("CdmEngine::ListUsageRecords: ListUsageRecords call failed");
if (!handle.ListUsageIds(app_id, ksids, provider_session_tokens)) {
LOGE("CdmEngine::ListUsageIds: ListUsageIds call failed");
return LIST_USAGE_ERROR_2;
}
return NO_ERROR;
@@ -1153,8 +1175,8 @@ CdmResponseType CdmEngine::GetUsageInfo(const std::string& app_id,
switch (status) {
case KEY_MESSAGE:
break;
case KEY_CANCELED: // usage information not present in
usage_session_->DeleteLicense(); // OEMCrypto, delete and try again
case KEY_CANCELED: // usage information not present in
usage_session_->DeleteLicenseFile(); // OEMCrypto, delete and try again
usage_info->clear();
break;
default:
@@ -1226,24 +1248,29 @@ CdmResponseType CdmEngine::RemoveAllUsageInfo(const std::string& app_id) {
if (!handle.RetrieveUsageInfo(
DeviceFiles::GetUsageInfoFileName(app_id),
&usage_data)) {
status = REMOVE_ALL_USAGE_INFO_ERROR_4;
LOGW("CdmEngine::RemoveAllUsageInfo: failed to retrieve usage info");
break;
}
if (usage_data.empty()) break;
status = usage_session_->DeleteUsageEntry(
CdmResponseType res = usage_session_->DeleteUsageEntry(
usage_data[0].usage_entry_number);
if (status != NO_ERROR) break;
if (res != NO_ERROR) {
LOGW("CdmEngine::RemoveAllUsageInfo: failed to delete usage "
"entry: error: %d", res);
break;
}
if (!handle.DeleteUsageInfo(
DeviceFiles::GetUsageInfoFileName(app_id),
usage_data[0].provider_session_token)) {
status = REMOVE_ALL_USAGE_INFO_ERROR_6;
LOGW("CdmEngine::RemoveAllUsageInfo: failed to delete usage "
"info");
break;
}
} while (status == NO_ERROR && !usage_data.empty());
} while (!usage_data.empty());
std::vector<std::string> provider_session_tokens;
if (!handle.DeleteAllUsageInfoForApp(
@@ -1282,6 +1309,84 @@ CdmResponseType CdmEngine::RemoveAllUsageInfo(const std::string& app_id) {
return status;
}
CdmResponseType CdmEngine::RemoveUsageInfo(
const std::string& app_id,
const CdmSecureStopId& provider_session_token) {
if (NULL == usage_property_set_.get()) {
usage_property_set_.reset(new UsagePropertySet());
}
usage_property_set_->set_app_id(app_id);
CdmResponseType status = NO_ERROR;
for (int j = kSecurityLevelL1; j < kSecurityLevelUnknown; ++j) {
DeviceFiles handle(file_system_);
if (handle.Init(static_cast<CdmSecurityLevel>(j))) {
SecurityLevel security_level =
static_cast<CdmSecurityLevel>(j) == kSecurityLevelL3
? kLevel3
: kLevelDefault;
usage_property_set_->set_security_level(security_level);
usage_session_.reset(new CdmSession(file_system_, metrics_.AddSession()));
usage_session_->Init(usage_property_set_.get());
std::vector<DeviceFiles::CdmUsageData> usage_data;
CdmKeyMessage license_request;
CdmKeyResponse license_response;
CdmUsageEntry usage_entry;
uint32_t usage_entry_number;
if (!handle.RetrieveUsageInfo(
DeviceFiles::GetUsageInfoFileName(app_id), provider_session_token,
&license_request, &license_response, &usage_entry,
&usage_entry_number)) {
// Try other security level
continue;
}
switch (usage_session_->get_usage_support_type()) {
case kUsageEntrySupport: {
status = usage_session_->DeleteUsageEntry(usage_entry_number);
if (!handle.DeleteUsageInfo(
DeviceFiles::GetUsageInfoFileName(app_id),
provider_session_token)) {
status = REMOVE_USAGE_INFO_ERROR_1;
}
usage_session_.reset(NULL);
return status;
}
case kUsageTableSupport: {
std::vector<std::string> provider_session_tokens;
handle.DeleteUsageInfo(
DeviceFiles::GetUsageInfoFileName(app_id),
provider_session_token);
scoped_ptr<CryptoSession> crypto_session(
new CryptoSession(metrics_.GetCryptoMetrics()));
status = crypto_session->Open(
static_cast<CdmSecurityLevel>(j) == kSecurityLevelL3
? kLevel3 : kLevelDefault);
if (status == NO_ERROR) {
crypto_session->UpdateUsageInformation();
status =
crypto_session->DeleteUsageInformation(provider_session_token);
crypto_session->UpdateUsageInformation();
}
return status;
}
default:
// Ignore
break;
}
} else {
LOGE("CdmEngine::RemoveUsageInfo: failed to initialize L%d devicefiles",
j);
status = REMOVE_USAGE_INFO_ERROR_2;
}
}
usage_session_.reset(NULL);
return REMOVE_USAGE_INFO_ERROR_3;
}
CdmResponseType CdmEngine::ReleaseUsageInfo(
const CdmUsageInfoReleaseMessage& message) {
if (NULL == usage_session_.get()) {
@@ -1358,7 +1463,7 @@ CdmResponseType CdmEngine::LoadUsageSession(const CdmKeySetId& key_set_id,
break;
case KEY_CANCELED:
// usage information not present in OEMCrypto, delete and try again
session->DeleteLicense();
session->DeleteLicenseFile();
break;
default:
LOGE("CdmEngine::LoadUsageSession: generate release request error: %d",
@@ -1594,7 +1699,9 @@ void CdmEngine::OnTimerEvent() {
(*iter)->reset_usage_flags();
switch ((*iter)->get_usage_support_type()) {
case kUsageEntrySupport:
(*iter)->UpdateUsageEntryInformation();
if ((*iter)->has_provider_session_token()) {
(*iter)->UpdateUsageEntryInformation();
}
break;
case kUsageTableSupport:
if (!has_usage_been_updated) {
@@ -1627,6 +1734,11 @@ void CdmEngine::OnKeyReleaseEvent(const CdmKeySetId& key_set_id) {
}
}
CdmResponseType CdmEngine::ValidateServiceCertificate(const std::string& cert) {
ServiceCertificate certificate;
return certificate.Init(cert);
}
std::string CdmEngine::MapHdcpVersion(
CryptoSession::HdcpCapability version) {
switch (version) {