Source release 17.1.1
This commit is contained in:
@@ -36,6 +36,11 @@
|
||||
|
||||
namespace widevine {
|
||||
|
||||
#ifdef HAS_EMBEDDED_CERT
|
||||
extern const uint8_t kDeviceCert[];
|
||||
extern const size_t kDeviceCertSize;
|
||||
#endif
|
||||
|
||||
using namespace wvcdm;
|
||||
using namespace wvutil;
|
||||
|
||||
@@ -45,42 +50,6 @@ 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;
|
||||
@@ -1752,8 +1721,6 @@ Cdm::Status Cdm::initialize(SecureOutputType secure_output_type,
|
||||
return kTypeError;
|
||||
}
|
||||
|
||||
if (!clientInfoIsValid()) return kUnexpectedError;
|
||||
|
||||
if (!storage || !clock || !timer) {
|
||||
LOGE("All interfaces are required!");
|
||||
return kTypeError;
|
||||
@@ -1762,6 +1729,8 @@ Cdm::Status Cdm::initialize(SecureOutputType secure_output_type,
|
||||
PropertiesCE::SetSecureOutputType(secure_output_type);
|
||||
if (sandbox_id != kNoSandboxId) PropertiesCE::SetSandboxId(sandbox_id);
|
||||
Properties::Init();
|
||||
if (!PropertiesCE::ClientInfoIsValid()) return kUnexpectedError;
|
||||
|
||||
host.storage = storage;
|
||||
host.clock = clock;
|
||||
host.timer = timer;
|
||||
@@ -1779,7 +1748,7 @@ Cdm::Status Cdm::getClientInfo(ClientInfo* client_info) {
|
||||
return kTypeError;
|
||||
}
|
||||
|
||||
if (!clientInfoIsValid()) return kUnexpectedError;
|
||||
if (!PropertiesCE::ClientInfoIsValid()) return kUnexpectedError;
|
||||
|
||||
if (!Properties::GetCompanyName(&client_info->company_name)) {
|
||||
LOGE("Unable to get Company Name.");
|
||||
@@ -1912,6 +1881,27 @@ class FileImpl final : public File {
|
||||
const bool truncate_;
|
||||
};
|
||||
|
||||
#ifdef HAS_EMBEDDED_CERT
|
||||
class FileCertImpl final : public File {
|
||||
public:
|
||||
// This Read method only gives correct results for the first call.
|
||||
ssize_t Read(char* buffer, size_t bytes) override {
|
||||
if (!buffer) {
|
||||
LOGW("File::Read: buffer is empty");
|
||||
return -1;
|
||||
}
|
||||
size_t to_copy = std::min(bytes, kDeviceCertSize);
|
||||
memcpy(buffer, kDeviceCert, to_copy);
|
||||
return to_copy;
|
||||
}
|
||||
|
||||
ssize_t Write(const char* buffer, size_t bytes) override {
|
||||
LOGW("File::Write: device cert is read-only.");
|
||||
return -1;
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
class FileSystem::Impl {
|
||||
public:
|
||||
Impl(widevine::Cdm::IStorage* storage) : storage_(storage) {
|
||||
@@ -1931,6 +1921,12 @@ FileSystem::~FileSystem() {}
|
||||
|
||||
std::unique_ptr<File> FileSystem::Open(const std::string& file_path,
|
||||
int flags) {
|
||||
#ifdef HAS_EMBEDDED_CERT
|
||||
if (file_path == kLegacyCertificateFileName) {
|
||||
return std::unique_ptr<File>(new FileCertImpl);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!(flags & kCreate) && !impl_->storage_->exists(file_path)) {
|
||||
return nullptr;
|
||||
}
|
||||
@@ -1939,20 +1935,40 @@ std::unique_ptr<File> FileSystem::Open(const std::string& file_path,
|
||||
}
|
||||
|
||||
bool FileSystem::Exists(const std::string& file_path) {
|
||||
#ifdef HAS_EMBEDDED_CERT
|
||||
if (file_path == kLegacyCertificateFileName) return true;
|
||||
#endif
|
||||
return !file_path.empty() && impl_->storage_->exists(file_path);
|
||||
}
|
||||
|
||||
bool FileSystem::Remove(const std::string& file_path) {
|
||||
#ifdef HAS_EMBEDDED_CERT
|
||||
if (file_path == kLegacyCertificateFileName) {
|
||||
LOGE("Cannot remove device cert when embedded.");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
return impl_->storage_->remove(file_path);
|
||||
}
|
||||
|
||||
ssize_t FileSystem::FileSize(const std::string& file_path) {
|
||||
#ifdef HAS_EMBEDDED_CERT
|
||||
if (file_path == kLegacyCertificateFileName) {
|
||||
return kDeviceCertSize;
|
||||
}
|
||||
#endif
|
||||
return impl_->storage_->size(file_path);
|
||||
}
|
||||
|
||||
bool FileSystem::List(const std::string&,
|
||||
std::vector<std::string>* file_names) {
|
||||
return file_names && impl_->storage_->list(file_names);
|
||||
const bool ret = file_names && impl_->storage_->list(file_names);
|
||||
#ifdef HAS_EMBEDDED_CERT
|
||||
if (ret) {
|
||||
file_names->emplace_back(kLegacyCertificateFileName);
|
||||
}
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
} // namespace wvutil
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "properties_ce.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
@@ -12,6 +13,8 @@
|
||||
#include "compiler_detection.h"
|
||||
#include "log.h"
|
||||
#include "properties.h"
|
||||
#include "read_client_info.h"
|
||||
#include "string_format.h"
|
||||
|
||||
// This anonymous namespace is shared between both the widevine namespace and
|
||||
// wvcdm namespace objects below.
|
||||
@@ -26,6 +29,98 @@ std::string sandbox_id_;
|
||||
widevine::Cdm::SecureOutputType secure_output_type_ =
|
||||
widevine::Cdm::kNoSecureOutput;
|
||||
|
||||
bool client_info_is_valid_;
|
||||
std::string company_name_;
|
||||
std::string model_name_;
|
||||
std::string model_year_;
|
||||
std::string product_name_;
|
||||
std::string device_name_;
|
||||
std::string arch_name_;
|
||||
std::string build_info_;
|
||||
|
||||
bool isClientInfoFieldValid(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;
|
||||
}
|
||||
|
||||
void SetClientInfo() {
|
||||
std::string platform;
|
||||
std::string form_factor;
|
||||
std::string version;
|
||||
|
||||
#if defined(RUNTIME_CLIENT_INFO)
|
||||
if (!widevine::ReadClientInformation(
|
||||
&company_name_, &model_name_, &model_year_, &product_name_,
|
||||
&device_name_, &arch_name_, &platform, &form_factor, &version)) {
|
||||
LOGE("ReadClientInformation failed.");
|
||||
client_info_is_valid_ = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(isClientInfoFieldValid("company_name", company_name_.c_str()) &&
|
||||
isClientInfoFieldValid("model_name", model_name_.c_str()) &&
|
||||
isClientInfoFieldValid("model_year", model_year_.c_str()) &&
|
||||
isClientInfoFieldValid("product_name", product_name_.c_str()) &&
|
||||
isClientInfoFieldValid("device_name", device_name_.c_str()) &&
|
||||
isClientInfoFieldValid("arch_name", arch_name_.c_str()) &&
|
||||
isClientInfoFieldValid("platform", platform.c_str()) &&
|
||||
isClientInfoFieldValid("form_factor", form_factor.c_str()) &&
|
||||
isClientInfoFieldValid("version", version.c_str()))) {
|
||||
client_info_is_valid_ = false;
|
||||
return;
|
||||
}
|
||||
#else
|
||||
if (!(isClientInfoFieldValid("CLIENT_COMPANY_NAME", CLIENT_COMPANY_NAME) &&
|
||||
isClientInfoFieldValid("CLIENT_MODEL_NAME", CLIENT_MODEL_NAME) &&
|
||||
isClientInfoFieldValid("CLIENT_MODEL_YEAR", CLIENT_MODEL_YEAR) &&
|
||||
isClientInfoFieldValid("CLIENT_PRODUCT_NAME", CLIENT_PRODUCT_NAME) &&
|
||||
isClientInfoFieldValid("CLIENT_DEVICE_NAME", CLIENT_DEVICE_NAME) &&
|
||||
isClientInfoFieldValid("CLIENT_ARCH_NAME", CLIENT_ARCH_NAME) &&
|
||||
isClientInfoFieldValid("CLIENT_PLATFORM", CLIENT_PLATFORM) &&
|
||||
isClientInfoFieldValid("CLIENT_FORM_FACTOR", CLIENT_FORM_FACTOR) &&
|
||||
isClientInfoFieldValid("CLIENT_VERSION", CLIENT_VERSION))) {
|
||||
client_info_is_valid_ = false;
|
||||
return;
|
||||
}
|
||||
|
||||
company_name_ = CLIENT_COMPANY_NAME;
|
||||
model_name_ = CLIENT_MODEL_NAME;
|
||||
model_year_ = CLIENT_MODEL_YEAR;
|
||||
product_name_ = CLIENT_PRODUCT_NAME;
|
||||
device_name_ = CLIENT_DEVICE_NAME;
|
||||
arch_name_ = CLIENT_ARCH_NAME;
|
||||
platform = CLIENT_PLATFORM;
|
||||
form_factor = CLIENT_FORM_FACTOR;
|
||||
version = CLIENT_VERSION;
|
||||
#endif
|
||||
|
||||
if (!wvutil::FormatString(
|
||||
&build_info_, "%s | %s | %s | %s | CE CDM %s | %s | %s | %s",
|
||||
version.c_str(), platform.c_str(), form_factor.c_str(),
|
||||
arch_name_.c_str(), CDM_VERSION, CPU_ARCH_MESSAGE, LOGGING_MESSAGE,
|
||||
BUILD_FLAVOR_MESSAGE)) {
|
||||
client_info_is_valid_ = false;
|
||||
LOGE("Formatting the build info failed.");
|
||||
} else {
|
||||
client_info_is_valid_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
bool GetValue(const char* source, std::string* output) {
|
||||
if (!source || !output) {
|
||||
return false;
|
||||
@@ -34,11 +129,6 @@ bool GetValue(const char* source, std::string* output) {
|
||||
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 {
|
||||
@@ -83,6 +173,9 @@ void PropertiesCE::SetSandboxId(const std::string& sandbox_id) {
|
||||
sandbox_id_ = sandbox_id;
|
||||
}
|
||||
|
||||
// static
|
||||
bool PropertiesCE::ClientInfoIsValid() { return client_info_is_valid_; }
|
||||
|
||||
} // namespace widevine
|
||||
|
||||
namespace wvcdm {
|
||||
@@ -97,42 +190,43 @@ void Properties::InitOnce() {
|
||||
device_files_is_a_real_filesystem_ = false;
|
||||
allow_restore_of_offline_licenses_with_release_ = true;
|
||||
delay_oem_crypto_termination_ = false;
|
||||
SetClientInfo();
|
||||
session_property_set_.reset(new CdmClientPropertySetMap());
|
||||
}
|
||||
|
||||
// static
|
||||
bool Properties::GetCompanyName(std::string* company_name) {
|
||||
return GetValue(CLIENT_COMPANY_NAME, company_name);
|
||||
return GetValue(company_name_.c_str(), company_name);
|
||||
}
|
||||
|
||||
// static
|
||||
bool Properties::GetModelName(std::string* model_name) {
|
||||
return GetValue(CLIENT_MODEL_NAME, model_name);
|
||||
return GetValue(model_name_.c_str(), model_name);
|
||||
}
|
||||
|
||||
// static
|
||||
bool Properties::GetModelYear(std::string* model_year) {
|
||||
return GetValue(CLIENT_MODEL_YEAR, model_year);
|
||||
return GetValue(model_year_.c_str(), model_year);
|
||||
}
|
||||
|
||||
// static
|
||||
bool Properties::GetArchitectureName(std::string* arch_name) {
|
||||
return GetValue(CLIENT_ARCH_NAME, arch_name);
|
||||
return GetValue(arch_name_.c_str(), arch_name);
|
||||
}
|
||||
|
||||
// static
|
||||
bool Properties::GetDeviceName(std::string* device_name) {
|
||||
return GetValue(CLIENT_DEVICE_NAME, device_name);
|
||||
return GetValue(device_name_.c_str(), device_name);
|
||||
}
|
||||
|
||||
// static
|
||||
bool Properties::GetProductName(std::string* product_name) {
|
||||
return GetValue(CLIENT_PRODUCT_NAME, product_name);
|
||||
return GetValue(product_name_.c_str(), product_name);
|
||||
}
|
||||
|
||||
// static
|
||||
bool Properties::GetBuildInfo(std::string* build_info) {
|
||||
return GetValue(kBuildInfo, build_info);
|
||||
return GetValue(build_info_.c_str(), build_info);
|
||||
}
|
||||
|
||||
// static
|
||||
|
||||
Reference in New Issue
Block a user