Source release 17.1.0
This commit is contained in:
159
cdm/src/cdm.cpp
159
cdm/src/cdm.cpp
@@ -1,11 +1,11 @@
|
||||
// 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.
|
||||
// source code may only be used and distributed under the Widevine License
|
||||
// Agreement.
|
||||
#include "cdm.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <limits.h> // LLONG_MAX
|
||||
#include <string.h> // memcpy
|
||||
#include <string.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
@@ -37,13 +37,50 @@
|
||||
namespace widevine {
|
||||
|
||||
using namespace wvcdm;
|
||||
using namespace wvutil;
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr const char* kNoSandboxId = "";
|
||||
constexpr char kNoSandboxId[] = "";
|
||||
const int64_t kPolicyTimerDurationMilliseconds = 5000;
|
||||
void* const kPolicyTimerContext = nullptr;
|
||||
|
||||
#define STRINGIFY(PARAM) #PARAM
|
||||
|
||||
bool isClientInfoValid(const char* tag, const char* value) {
|
||||
constexpr char kForbiddenSeparator[] = " | ";
|
||||
constexpr char kForbiddenPercent[] = "%";
|
||||
if (value[0] == '\0') {
|
||||
LOGE("%s may not be empty, but it is.", tag);
|
||||
return false;
|
||||
}
|
||||
if (strstr(value, kForbiddenSeparator) != nullptr) {
|
||||
LOGE("%s may not contain \"%s\", but it's \"%s\"", tag, kForbiddenSeparator,
|
||||
value);
|
||||
return false;
|
||||
}
|
||||
if (strstr(value, kForbiddenPercent) != nullptr) {
|
||||
LOGE("%s may not contain \"%s\", but it's \"%s\"", tag, kForbiddenPercent,
|
||||
value);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool clientInfoIsValid() {
|
||||
return isClientInfoValid(STRINGIFY(CLIENT_COMPANY_NAME),
|
||||
CLIENT_COMPANY_NAME) &&
|
||||
isClientInfoValid(STRINGIFY(CLIENT_MODEL_NAME), CLIENT_MODEL_NAME) &&
|
||||
isClientInfoValid(STRINGIFY(CLIENT_MODEL_YEAR), CLIENT_MODEL_YEAR) &&
|
||||
isClientInfoValid(STRINGIFY(CLIENT_PRODUCT_NAME),
|
||||
CLIENT_PRODUCT_NAME) &&
|
||||
isClientInfoValid(STRINGIFY(CLIENT_DEVICE_NAME), CLIENT_DEVICE_NAME) &&
|
||||
isClientInfoValid(STRINGIFY(CLIENT_ARCH_NAME), CLIENT_ARCH_NAME) &&
|
||||
isClientInfoValid(STRINGIFY(CLIENT_PLATFORM), CLIENT_PLATFORM) &&
|
||||
isClientInfoValid(STRINGIFY(CLIENT_FORM_FACTOR), CLIENT_FORM_FACTOR) &&
|
||||
isClientInfoValid(STRINGIFY(CLIENT_VERSION), CLIENT_VERSION);
|
||||
}
|
||||
|
||||
struct HostType {
|
||||
Cdm::IStorage* storage;
|
||||
Cdm::IClock* clock;
|
||||
@@ -197,11 +234,13 @@ class CdmImpl final : public Cdm, public WvCdmEventListener {
|
||||
|
||||
Status getRobustnessLevel(RobustnessLevel* level) override;
|
||||
|
||||
Status getSystemId(uint32_t* id) override;
|
||||
|
||||
Status getResourceRatingTier(uint32_t* tier) override;
|
||||
|
||||
Status getOemCryptoBuildInfo(std::string* build_info) override;
|
||||
|
||||
bool isProvisioned() override;
|
||||
ProvisioningStatus getProvisioningStatus() override;
|
||||
|
||||
Status getProvisioningRequest(std::string* request) override;
|
||||
|
||||
@@ -446,6 +485,27 @@ Cdm::Status CdmImpl::getRobustnessLevel(RobustnessLevel* level) {
|
||||
return kSuccess;
|
||||
}
|
||||
|
||||
Cdm::Status CdmImpl::getSystemId(uint32_t* id) {
|
||||
if (id == nullptr) {
|
||||
LOGE("Missing id parameter to receive system ID.");
|
||||
return kTypeError;
|
||||
}
|
||||
|
||||
std::string id_string;
|
||||
const CdmResponseType result =
|
||||
cdm_engine_->QueryStatus(kLevelDefault, QUERY_KEY_SYSTEM_ID, &id_string);
|
||||
if (result == SYSTEM_INVALIDATED_ERROR) {
|
||||
LOGE("System invalidated");
|
||||
return kSystemStateLost;
|
||||
} else if (result != NO_ERROR) {
|
||||
LOGE("Unexpected error %d", static_cast<int>(result));
|
||||
return kUnexpectedError;
|
||||
}
|
||||
|
||||
*id = static_cast<uint32_t>(std::stoul(id_string));
|
||||
return kSuccess;
|
||||
}
|
||||
|
||||
Cdm::Status CdmImpl::getResourceRatingTier(uint32_t* tier) {
|
||||
if (tier == nullptr) {
|
||||
LOGE("Missing tier parameter to receive resource rating tier.");
|
||||
@@ -492,8 +552,22 @@ Cdm::Status CdmImpl::getOemCryptoBuildInfo(std::string* build_info) {
|
||||
return kSuccess;
|
||||
}
|
||||
|
||||
bool CdmImpl::isProvisioned() {
|
||||
return cdm_engine_->IsProvisioned(kSecurityLevelL1);
|
||||
Cdm::ProvisioningStatus CdmImpl::getProvisioningStatus() {
|
||||
const CdmProvisioningStatus status =
|
||||
cdm_engine_->GetProvisioningStatus(kSecurityLevelL1);
|
||||
switch (status) {
|
||||
case CdmProvisioningStatus::kProvisioned:
|
||||
return kProvisioned;
|
||||
case CdmProvisioningStatus::kNeedsDrmCertProvisioning:
|
||||
return kNeedsDrmCertProvisioning;
|
||||
case CdmProvisioningStatus::kNeedsOemCertProvisioning:
|
||||
return kNeedsOemCertProvisioning;
|
||||
case CdmProvisioningStatus::kUnknownProvisionStatus:
|
||||
LOGW("Unknown provisioning status");
|
||||
return kUnknownProvisionStatus;
|
||||
}
|
||||
LOGE("Unexpected provisioning status %d", static_cast<int>(status));
|
||||
return kUnknownProvisionStatus;
|
||||
}
|
||||
|
||||
Cdm::Status CdmImpl::getProvisioningRequest(std::string* request) {
|
||||
@@ -1654,17 +1728,16 @@ Cdm::Status CdmImpl::ConvertHdcpLevel(const std::string& query_value,
|
||||
|
||||
// static
|
||||
Cdm::Status Cdm::initialize(SecureOutputType secure_output_type,
|
||||
const ClientInfo& client_info, IStorage* storage,
|
||||
IClock* clock, ITimer* timer, LogLevel verbosity) {
|
||||
return initialize(secure_output_type, client_info, storage, clock, timer,
|
||||
verbosity, kNoSandboxId);
|
||||
IStorage* storage, IClock* clock, ITimer* timer,
|
||||
LogLevel verbosity) {
|
||||
return initialize(secure_output_type, storage, clock, timer, verbosity,
|
||||
kNoSandboxId);
|
||||
}
|
||||
|
||||
// static
|
||||
Cdm::Status Cdm::initialize(SecureOutputType secure_output_type,
|
||||
const ClientInfo& client_info, IStorage* storage,
|
||||
IClock* clock, ITimer* timer, LogLevel verbosity,
|
||||
const std::string& sandbox_id) {
|
||||
IStorage* storage, IClock* clock, ITimer* timer,
|
||||
LogLevel verbosity, const std::string& sandbox_id) {
|
||||
// Specify the maximum severity of message that will be output to
|
||||
// the console. See core/include/log.h for the valid priority values.
|
||||
g_cutoff = static_cast<LogPriority>(verbosity);
|
||||
@@ -1679,11 +1752,7 @@ Cdm::Status Cdm::initialize(SecureOutputType secure_output_type,
|
||||
return kTypeError;
|
||||
}
|
||||
|
||||
if (client_info.product_name.empty() || client_info.company_name.empty() ||
|
||||
client_info.model_name.empty()) {
|
||||
LOGE("Client info requires product_name, company_name, model_name!");
|
||||
return kTypeError;
|
||||
}
|
||||
if (!clientInfoIsValid()) return kUnexpectedError;
|
||||
|
||||
if (!storage || !clock || !timer) {
|
||||
LOGE("All interfaces are required!");
|
||||
@@ -1691,7 +1760,6 @@ Cdm::Status Cdm::initialize(SecureOutputType secure_output_type,
|
||||
}
|
||||
|
||||
PropertiesCE::SetSecureOutputType(secure_output_type);
|
||||
PropertiesCE::SetClientInfo(client_info);
|
||||
if (sandbox_id != kNoSandboxId) PropertiesCE::SetSandboxId(sandbox_id);
|
||||
Properties::Init();
|
||||
host.storage = storage;
|
||||
@@ -1704,6 +1772,53 @@ Cdm::Status Cdm::initialize(SecureOutputType secure_output_type,
|
||||
// static
|
||||
const char* Cdm::version() { return CDM_VERSION; }
|
||||
|
||||
// static
|
||||
Cdm::Status Cdm::getClientInfo(ClientInfo* client_info) {
|
||||
if (client_info == nullptr) {
|
||||
LOGE("Missing client_info parameter.");
|
||||
return kTypeError;
|
||||
}
|
||||
|
||||
if (!clientInfoIsValid()) return kUnexpectedError;
|
||||
|
||||
if (!Properties::GetCompanyName(&client_info->company_name)) {
|
||||
LOGE("Unable to get Company Name.");
|
||||
return kUnexpectedError;
|
||||
}
|
||||
|
||||
if (!Properties::GetModelName(&client_info->model_name)) {
|
||||
LOGE("Unable to get Model Name.");
|
||||
return kUnexpectedError;
|
||||
}
|
||||
|
||||
if (!Properties::GetModelYear(&client_info->model_year)) {
|
||||
LOGE("Unable to get Model Year.");
|
||||
return kUnexpectedError;
|
||||
}
|
||||
|
||||
if (!Properties::GetDeviceName(&client_info->device_name)) {
|
||||
LOGE("Unable to get Device Name.");
|
||||
return kUnexpectedError;
|
||||
}
|
||||
|
||||
if (!Properties::GetProductName(&client_info->product_name)) {
|
||||
LOGE("Unable to get Product Name.");
|
||||
return kUnexpectedError;
|
||||
}
|
||||
|
||||
if (!Properties::GetArchitectureName(&client_info->arch_name)) {
|
||||
LOGE("Unable to get Architecture Name.");
|
||||
return kUnexpectedError;
|
||||
}
|
||||
|
||||
if (!Properties::GetBuildInfo(&client_info->build_info)) {
|
||||
LOGE("Unable to get Build Info.");
|
||||
return kUnexpectedError;
|
||||
}
|
||||
|
||||
return kSuccess;
|
||||
}
|
||||
|
||||
// static
|
||||
Cdm* Cdm::create(IEventListener* listener, IStorage* storage,
|
||||
bool privacy_mode) {
|
||||
@@ -1739,7 +1854,7 @@ Cdm* Cdm::create(IEventListener* listener, IStorage* storage, bool privacy_mode,
|
||||
} // namespace widevine
|
||||
|
||||
// Missing symbols from core:
|
||||
namespace wvcdm {
|
||||
namespace wvutil {
|
||||
|
||||
using namespace widevine;
|
||||
|
||||
@@ -1840,4 +1955,4 @@ bool FileSystem::List(const std::string&,
|
||||
return file_names && impl_->storage_->list(file_names);
|
||||
}
|
||||
|
||||
} // namespace wvcdm
|
||||
} // namespace wvutil
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// 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.
|
||||
// source code may only be used and distributed under the Widevine License
|
||||
// Agreement.
|
||||
//
|
||||
// Log - implemented using stderr.
|
||||
|
||||
@@ -11,9 +11,9 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
namespace wvcdm {
|
||||
namespace wvutil {
|
||||
|
||||
LogPriority g_cutoff = LOG_WARN;
|
||||
LogPriority g_cutoff = CDM_LOG_WARN;
|
||||
|
||||
void InitLogging() {}
|
||||
|
||||
@@ -39,4 +39,4 @@ void Log(const char* file, const char* function, int line, LogPriority level,
|
||||
fflush(stderr);
|
||||
}
|
||||
|
||||
} // namespace wvcdm
|
||||
} // namespace wvutil
|
||||
|
||||
@@ -1,9 +1,15 @@
|
||||
// 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.
|
||||
// source code may only be used and distributed under the Widevine License
|
||||
// Agreement.
|
||||
#include "properties_ce.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "cdm_version.h"
|
||||
#include "compiler_detection.h"
|
||||
#include "log.h"
|
||||
#include "properties.h"
|
||||
|
||||
@@ -19,16 +25,20 @@ std::string sandbox_id_;
|
||||
|
||||
widevine::Cdm::SecureOutputType secure_output_type_ =
|
||||
widevine::Cdm::kNoSecureOutput;
|
||||
widevine::Cdm::ClientInfo client_info_;
|
||||
|
||||
bool GetValue(const std::string& source, std::string* output) {
|
||||
if (!output) {
|
||||
bool GetValue(const char* source, std::string* output) {
|
||||
if (!source || !output) {
|
||||
return false;
|
||||
}
|
||||
*output = source;
|
||||
return source.size() != 0;
|
||||
return source[0] != '\0';
|
||||
}
|
||||
|
||||
constexpr char kBuildInfo[] = CLIENT_VERSION
|
||||
" | " CLIENT_PLATFORM " | " CLIENT_FORM_FACTOR " | " CLIENT_ARCH_NAME
|
||||
" | CE CDM " CDM_VERSION " | " CPU_ARCH_MESSAGE " | " LOGGING_MESSAGE
|
||||
" | " BUILD_FLAVOR_MESSAGE;
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace widevine {
|
||||
@@ -63,14 +73,6 @@ Cdm::SecureOutputType PropertiesCE::GetSecureOutputType() {
|
||||
return secure_output_type_;
|
||||
}
|
||||
|
||||
// static
|
||||
void PropertiesCE::SetClientInfo(const Cdm::ClientInfo& client_info) {
|
||||
client_info_ = client_info;
|
||||
}
|
||||
|
||||
// static
|
||||
Cdm::ClientInfo PropertiesCE::GetClientInfo() { return client_info_; }
|
||||
|
||||
// static
|
||||
void PropertiesCE::SetProvisioningMessagesAreBinary(bool new_setting) {
|
||||
set_provisioning_messages_to_binary_ = new_setting;
|
||||
@@ -100,32 +102,37 @@ void Properties::InitOnce() {
|
||||
|
||||
// static
|
||||
bool Properties::GetCompanyName(std::string* company_name) {
|
||||
return GetValue(client_info_.company_name, company_name);
|
||||
return GetValue(CLIENT_COMPANY_NAME, company_name);
|
||||
}
|
||||
|
||||
// static
|
||||
bool Properties::GetModelName(std::string* model_name) {
|
||||
return GetValue(client_info_.model_name, model_name);
|
||||
return GetValue(CLIENT_MODEL_NAME, model_name);
|
||||
}
|
||||
|
||||
// static
|
||||
bool Properties::GetModelYear(std::string* model_year) {
|
||||
return GetValue(CLIENT_MODEL_YEAR, model_year);
|
||||
}
|
||||
|
||||
// static
|
||||
bool Properties::GetArchitectureName(std::string* arch_name) {
|
||||
return GetValue(client_info_.arch_name, arch_name);
|
||||
return GetValue(CLIENT_ARCH_NAME, arch_name);
|
||||
}
|
||||
|
||||
// static
|
||||
bool Properties::GetDeviceName(std::string* device_name) {
|
||||
return GetValue(client_info_.device_name, device_name);
|
||||
return GetValue(CLIENT_DEVICE_NAME, device_name);
|
||||
}
|
||||
|
||||
// static
|
||||
bool Properties::GetProductName(std::string* product_name) {
|
||||
return GetValue(client_info_.product_name, product_name);
|
||||
return GetValue(CLIENT_PRODUCT_NAME, product_name);
|
||||
}
|
||||
|
||||
// static
|
||||
bool Properties::GetBuildInfo(std::string* build_info) {
|
||||
return GetValue(client_info_.build_info, build_info);
|
||||
return GetValue(kBuildInfo, build_info);
|
||||
}
|
||||
|
||||
// static
|
||||
@@ -151,7 +158,13 @@ bool Properties::GetFactoryKeyboxPath(std::string*) {
|
||||
// static
|
||||
bool Properties::GetOEMCryptoPath(std::string* path) {
|
||||
if (path == nullptr) return false;
|
||||
*path = "liboemcrypto.so";
|
||||
// Using an environment variable is useful for testing.
|
||||
const char* env_path = getenv("LIBOEMCRYPTO_PATH");
|
||||
if (env_path) {
|
||||
*path = std::string(env_path);
|
||||
} else {
|
||||
*path = "liboemcrypto.so";
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user