Export media_cas_proxy_sdk

This commit is contained in:
Fang Yu
2018-11-14 09:05:33 -08:00
parent 6d0d9d825c
commit 5031d1bc6f
146 changed files with 24654 additions and 0 deletions

117
sdk/external/common/wvpl/BUILD vendored Normal file
View File

@@ -0,0 +1,117 @@
################################################################################
# Copyright 2017 Google LLC.
#
# This software is licensed under the terms defined in the Widevine Master
# License Agreement. For a copy of this agreement, please contact
# widevine-licensing@google.com.
################################################################################
# The public interface of Widevine Proxy SDK for content providers.
package(
default_visibility = ["//visibility:public"],
)
filegroup(
name = "binary_release_files",
srcs = glob(["*.h"]),
)
cc_library(
name = "wvpl_types",
hdrs = [
"wvpl_types.h",
],
deps = [
"//util:status",
],
)
cc_library(
name = "wvpl_sdk_session",
srcs = [
"wvpl_sdk_session.cc",
],
hdrs = [
"wvpl_sdk_environment.h",
"wvpl_sdk_session.h",
],
deps = [
# TODO(user): Refactor these deps as classes that derive from WvPLSDKSession may not rely on license SDK(s).
"//base",
"//util:status",
":wvpl_types",
"//common:certificate_type",
"//common:drm_service_certificate",
"//common:error_space",
"//common:remote_attestation_verifier",
"//common:verified_media_pipeline",
"//license_server_sdk/internal:sdk",
"//protos/public:client_identification_proto",
"//protos/public:device_certificate_status_proto",
"//protos/public:errors_proto",
"//protos/public:license_protocol_proto",
"//protos/public:license_server_sdk_proto",
"//protos/public:provisioned_device_info_proto",
],
)
cc_library(
name = "wvpl_sdk_environment",
srcs = [
"wvpl_sdk_environment.cc",
],
hdrs = [
"wvpl_sdk_environment.h",
],
deps = [
# TODO(user): Refactor these deps as classes that derive from WvPLSDKEnvironment may not rely on license SDK(s).
"//base",
"@abseil_repo//absl/strings",
"@abseil_repo//absl/synchronization",
"//util:status",
":wvpl_types",
"//common:aes_cbc_util",
"//common:certificate_type",
"//common:certificate_util",
"//common:drm_service_certificate",
"//common:error_space",
"//common:sha_util",
"//license_server_sdk/internal:sdk",
"//protos/public:device_certificate_status_proto",
"//protos/public:errors_proto",
"//protos/public:provisioned_device_info_proto",
],
)
cc_library(
name = "sdk",
srcs = glob(
["*.cc"],
),
hdrs = glob(
["*.h"],
),
deps = [
":wvpl_types",
"//base",
"@abseil_repo//absl/strings",
"@abseil_repo//absl/synchronization",
"//util:status",
"//common:aes_cbc_util",
"//common:certificate_type",
"//common:certificate_util",
"//common:drm_service_certificate",
"//common:error_space",
"//common:remote_attestation_verifier",
"//common:sha_util",
"//common:verified_media_pipeline",
"//license_server_sdk/internal:sdk",
"//protos/public:client_identification_proto",
"//protos/public:device_certificate_status_proto",
"//protos/public:errors_proto",
"//protos/public:license_protocol_proto",
"//protos/public:license_server_sdk_proto",
"//protos/public:provisioned_device_info_proto",
],
)

View File

@@ -0,0 +1,202 @@
////////////////////////////////////////////////////////////////////////////////
// Copyright 2017 Google LLC.
//
// This software is licensed under the terms defined in the Widevine Master
// License Agreement. For a copy of this agreement, please contact
// widevine-licensing@google.com.
////////////////////////////////////////////////////////////////////////////////
#include "sdk/external/common/wvpl/wvpl_sdk_environment.h"
#include "glog/logging.h"
#include "absl/strings/escaping.h"
#include "absl/synchronization/mutex.h"
#include "util/status.h"
#include "common/aes_cbc_util.h"
#include "common/certificate_type.h"
#include "common/certificate_util.h"
#include "common/drm_service_certificate.h"
#include "common/error_space.h"
#include "common/sha_util.h"
#include "license_server_sdk/internal/generate_error_response.h"
#include "protos/public/errors.pb.h"
namespace util = widevine::util;
using widevine::AddDrmServiceCertificate;
using widevine::DeviceCertificateStatus;
using widevine::DeviceCertificateStatusList;
using widevine::DrmServiceCertificate;
using widevine::error_space;
using widevine::kCertificateTypeDevelopment;
using widevine::kCertificateTypeProduction;
using widevine::kCertificateTypeTesting;
using widevine::ProvisionedDeviceInfo;
using widevine::SetCertificateStatusList;
using widevine::crypto_util::EncryptAesCbc;
namespace widevine_server {
namespace wv_pl_sdk {
namespace {
// Thread safe class that keeps track of all active devices in the current
// session/environment.
class ProvisionedDeviceInfoMap {
public:
ProvisionedDeviceInfoMap() = default;
// Not copyable or movable (move operations are implicitly disabled).
ProvisionedDeviceInfoMap(const ProvisionedDeviceInfoMap&) = delete;
ProvisionedDeviceInfoMap& operator=(const ProvisionedDeviceInfoMap&) = delete;
const ProvisionedDeviceInfo* FindOrNull(uint32_t system_id) const {
absl::ReaderMutexLock lock(&device_info_mutex_);
const auto it = device_info_map_.find(system_id);
if (it == device_info_map_.end()) return nullptr;
return &it->second;
}
void InsertOrUpdate(const ProvisionedDeviceInfo& device_info) {
absl::WriterMutexLock lock(&device_info_mutex_);
device_info_map_[device_info.system_id()] = device_info;
}
private:
mutable absl::Mutex device_info_mutex_;
// Map from ProvisionedDeviceInfo.system_id to ProvisionedDeviceInfo.
std::map<uint32_t, ProvisionedDeviceInfo> device_info_map_
GUARDED_BY(device_info_mutex_);
};
ProvisionedDeviceInfoMap& GetProvisionedDeviceInfoMap() {
static auto* device_info_map = new ProvisionedDeviceInfoMap();
return *device_info_map;
}
} // namespace
WvPLStatus WvPLSDKEnvironment::SetDrmServiceCertificate(
const std::string& service_certificate, const std::string& service_private_key,
const std::string& service_private_key_passphrase) {
WvPLStatus wvpl_status = AddDrmServiceCertificate(
certificate_type_, service_certificate, service_private_key,
service_private_key_passphrase);
if (!wvpl_status.ok()) return wvpl_status;
wvpl_status = DrmServiceCertificate::ValidateDrmServiceCertificate();
if (wvpl_status.ok()) {
is_service_certificate_loaded_ = true;
}
return wvpl_status;
}
bool WvPLSDKEnvironment::GenerateErrorResponse(
const WvPLStatus& create_session_status, std::string* license_response) {
return widevine::GenerateErrorResponse(create_session_status,
license_response);
}
WvPLStatus WvPLSDKEnvironment::LookupDeviceInfo(
uint32_t system_id, ProvisionedDeviceInfo* provisioned_device_info) {
WvPLStatus status = util::OkStatus();
if (provisioned_device_info == nullptr) {
return WvPLStatus(error_space, util::error::INVALID_ARGUMENT,
"provisioned_device_info should not be null");
}
const ProvisionedDeviceInfoMap& device_info_map =
GetProvisionedDeviceInfoMap();
const ProvisionedDeviceInfo* l_provisioned_device_info =
device_info_map.FindOrNull(system_id);
if (l_provisioned_device_info == nullptr) {
return WvPLStatus(
error_space, widevine::UNSUPPORTED_SYSTEM_ID,
"Widevine SystemID does not exist because it is not found "
"in the device info map");
}
*provisioned_device_info = *l_provisioned_device_info;
return status;
}
WvPLStatus WvPLSDKEnvironment::UpdateProvisionedDeviceInfoMap(
const DeviceCertificateStatusList& certificate_status_list) {
WvPLStatus status = util::OkStatus();
for (const DeviceCertificateStatus& cert_status :
certificate_status_list.certificate_status()) {
if (cert_status.has_device_info()) {
const ProvisionedDeviceInfo device_info = cert_status.device_info();
if (device_info.has_system_id()) {
ProvisionedDeviceInfoMap& device_info_map =
GetProvisionedDeviceInfoMap();
// TODO(user): Parse DeviceState from device to decide whether
// overwrite device_info or not.
device_info_map.InsertOrUpdate(device_info);
} else {
return WvPLStatus(error_space,
widevine::INVALID_CERTIFICATE_STATUS_LIST,
"device-info-missing-system-id");
}
}
}
return status;
}
void WvPLSDKEnvironment::AddDeviceInfo(
const ProvisionedDeviceInfo& provisioned_device_info) {
ProvisionedDeviceInfoMap& device_info_map = GetProvisionedDeviceInfoMap();
device_info_map.InsertOrUpdate(provisioned_device_info);
}
WvPLStatus WvPLSDKEnvironment::GenerateSignature(const std::string& plain_text,
std::string* signature) {
DCHECK(signature);
if (plain_text.empty()) {
return WvPLStatus(error_space, util::error::INVALID_ARGUMENT,
"Plain_text for signature is empty.");
}
if (signature == nullptr) {
return WvPLStatus(error_space, util::error::INVALID_ARGUMENT,
"Signature must not be null.");
}
const std::map<std::string, std::string>* config_values = GetConfigValue();
std::map<std::string, std::string>::const_iterator it =
config_values->find(kDrmCertificateType);
it = config_values->find(kProviderIv);
std::string provider_iv;
std::string provider_key;
if (it != config_values->end()) {
provider_iv = absl::HexStringToBytes((*it).second);
if (provider_iv.empty()) {
return WvPLStatus(error_space, util::error::NOT_FOUND,
"Provider IV is empty.");
}
}
it = config_values->find(kProviderKey);
if (it != config_values->end()) {
provider_key = absl::HexStringToBytes((*it).second);
if (provider_key.empty()) {
return WvPLStatus(error_space, util::error::NOT_FOUND,
"Provider Key is empty.");
}
}
std::string hashed_text = widevine::Sha1_Hash(plain_text);
if (hashed_text.empty()) {
return util::Status(error_space, util::error::INVALID_ARGUMENT,
"Hash for signature is empty.");
} else {
*signature = EncryptAesCbc(provider_key, provider_iv, hashed_text);
if (signature->empty()) {
return util::Status(error_space, util::error::INVALID_ARGUMENT,
"Generated signature failed");
}
}
return util::OkStatus();
}
std::map<std::string, std::string>* WvPLSDKEnvironment::config_values_ =
new std::map<std::string, std::string>();
std::map<std::string, std::string>* WvPLSDKEnvironment::GetConfigValue() {
return config_values_;
}
void WvPLSDKEnvironment::SetConfigValue(
const std::map<std::string, std::string>& config_values) {
config_values_->insert(config_values.begin(), config_values.end());
}
} // namespace wv_pl_sdk
} // namespace widevine_server

View File

@@ -0,0 +1,132 @@
////////////////////////////////////////////////////////////////////////////////
// Copyright 2017 Google LLC.
//
// This software is licensed under the terms defined in the Widevine Master
// License Agreement. For a copy of this agreement, please contact
// widevine-licensing@google.com.
////////////////////////////////////////////////////////////////////////////////
#ifndef SDK_EXTERNAL_COMMON_WVPL_WVPL_SDK_ENVIRONMENT_H_
#define SDK_EXTERNAL_COMMON_WVPL_WVPL_SDK_ENVIRONMENT_H_
#include <string>
#include "common/certificate_type.h"
#include "sdk/external/common/wvpl/wvpl_types.h"
#include "protos/public/device_certificate_status.pb.h"
#include "protos/public/provisioned_device_info.pb.h"
namespace widevine_server {
namespace wv_pl_sdk {
// These fields show the configuration options that can be initialized via
// the implementation classes (WvPLEnvironment and WvPLProxyEnvironment).
const char kDeviceCertificateExpiration[] = "device_certificate_expiration";
const char kAllowUnknownDevice[] = "allow_unknown_device";
const char kProvider[] = "provider";
const char kProviderIv[] = "provider_iv";
const char kProviderKey[] = "provider_key";
const char kApiVerInKcb[] = "api_ver_in_kcb";
const char kLimitUsageStatsToErrorsOnly[] = "limit_usage_stats_to_errors_only";
// Valid values are 'test' and 'prod'.
const char kDrmCertificateType[] = "drm_certificate_type";
/**
* Parent class of SDK environment. This class is not be instantiated directly,
* but its API can be accessed via the derived environment classes.
*/
class WvPLSDKEnvironment {
public:
virtual ~WvPLSDKEnvironment() {}
static void SetConfigValue(const std::map<std::string, std::string>& config_values);
// Generates a license response containing a message generated in response to
// an error condition. |create_session_status| is a previous error status
// returned by the CreateSession(). |license_response| points to a std::string to
// contain the license response and may not be NULL. This method returns true
// if there is an error license to be sent to the client, or false
// otherwise.
static bool GenerateErrorResponse(const WvPLStatus& create_session_status,
std::string* license_response);
/**
* Add a service certificate system-wide at the sdk. |service_certificate|
* is a Google-generated certificate used to authenticate the service
* provider. |service_private_key| is the encrypted PKCS#8 private RSA key
* corresponding to the service certificate. |service_private_key_passphrase|
* is the password required to decrypt |service_private_key|. This is a
* thread-safe call.
*
* @param service_certificate
* @param service_private_key
* @param service_private_key_passphrase
*
* @return WvPLStatus enumeration
*/
virtual WvPLStatus SetDrmServiceCertificate(
const std::string& service_certificate, const std::string& service_private_key,
const std::string& service_private_key_passphrase);
// Returns the DRM Root Certificate type. This would be a setting passed into
// the environment, by a derived class constructor.
virtual std::string GetDrmCertificateType() { return drm_certificate_type_; }
protected:
// Return the signature for the provider specified in the |config_values|
// parameter in the constructor. |signature| is owned by the caller.
static WvPLStatus GenerateSignature(const std::string& plain_text,
std::string* signature);
/**
* Insert or update provisionedDeviceInfoMap with device info in
* certificate_status_list.
*/
static WvPLStatus UpdateProvisionedDeviceInfoMap(
const widevine::DeviceCertificateStatusList&
certificate_status_list);
// Number of seconds until the certificate status list expires after its
// creation time. Default value is 604800 seconds.
uint32_t device_certificate_expiration_seconds_ = 604800;
// "config_values" setting for "kDrmCertificateType".
// Supported values are "test" and "prod". Default value is "prod".
std::string drm_certificate_type_ = "prod";
// name of the provider hosting this service.
std::string provider_;
// value of the "iv" specified for the provider.
std::string* provider_iv_;
// value of the "key" specified for the provider.
std::string* provider_key_;
static std::map<std::string, std::string>* config_values_;
// is_service_certificate_loaded_ is not thread safe.
bool is_service_certificate_loaded_ = false;
// If true, allow devices not in the certificate status list.
bool allow_unknown_device_ = false;
// DRM Certificate type.
widevine::CertificateType certificate_type_ =
widevine::kCertificateTypeProduction;
private:
/**
* Return provisioned_device_info if the device_info_map_ contains system_id.
*
* @return WvPLStatus - Status::OK if success, else error.
*/
static WvPLStatus LookupDeviceInfo(
uint32_t system_id,
widevine::ProvisionedDeviceInfo* provisioned_device_info);
/**
* Add a device to the current environment/session.
*/
static void AddDeviceInfo(
const widevine::ProvisionedDeviceInfo& provisioned_device_info);
static std::map<std::string, std::string>* GetConfigValue();
friend class WvPLSDKSession;
friend class WvPLProxySessionTest;
friend class WvPLSessionTest;
};
} // namespace wv_pl_sdk
} // namespace widevine_server
#endif // SDK_EXTERNAL_COMMON_WVPL_WVPL_SDK_ENVIRONMENT_H_

View File

@@ -0,0 +1,701 @@
////////////////////////////////////////////////////////////////////////////////
// Copyright 2018 Google LLC.
//
// This software is licensed under the terms defined in the Widevine Master
// License Agreement. For a copy of this agreement, please contact
// widevine-licensing@google.com.
////////////////////////////////////////////////////////////////////////////////
#include "sdk/external/common/wvpl/wvpl_sdk_session.h"
#include "glog/logging.h"
#include "util/status.h"
#include "absl/memory/memory.h"
#include "common/drm_service_certificate.h"
#include "common/error_space.h"
#include "common/remote_attestation_verifier.h"
#include "common/verified_media_pipeline.h"
#include "license_server_sdk/internal/client_cert.h"
#include "sdk/external/common/wvpl/wvpl_sdk_environment.h"
#include "sdk/external/common/wvpl/wvpl_types.h"
#include "protos/public/errors.pb.h"
// TODO(user): Mark getProvisionedDeviceInfo as deprecated, move the
// implementation of isChromeCDM, getcontentid, parsePsshdata in wvpl_session
// and wvpl_proxy_session to base class.
// TODO(user): Set SerialNumber and ServiceId field of WvPLDeviceInfo in
// getDeviceInfo function.
// TODO(user): Move the related Copy* function test cases to
// wvpl_sdk_session_test.cc.
// TODO(user): Remove sdk_license_request_ and both proxy and wvpl LSDK set
// signed_message_request_from_cdm_ when create session.
namespace util = widevine::util;
using widevine::ClientIdentification;
using widevine::DrmServiceCertificate;
using widevine::error_space;
using widevine::KeyboxClientCert;
using widevine::License;
using widevine::LicenseRequest;
using widevine::ProvisionedDeviceInfo;
using widevine::RemoteAttestationVerifier;
using widevine::SessionInit;
using widevine::SessionState;
using widevine::SignedMessage;
namespace widevine_server {
namespace wv_pl_sdk {
WvPLSDKSession::~WvPLSDKSession() {}
WvPLStatus WvPLSDKSession::AddKey(const WvPLKey& key) {
keys_.push_back(key);
return util::OkStatus();
}
void WvPLSDKSession::CopyPlaybackPolicy(const WvPLPlaybackPolicy& wvpl_policy,
License::Policy* sdk_policy) {
DCHECK(sdk_policy);
if (sdk_policy == NULL) {
return;
}
// Copy the policy information.
sdk_policy->set_can_play(wvpl_policy.can_play());
sdk_policy->set_can_persist(wvpl_policy.can_persist());
sdk_policy->set_can_renew(wvpl_policy.can_renew());
sdk_policy->set_playback_duration_seconds(
wvpl_policy.playback_duration_seconds());
sdk_policy->set_license_duration_seconds(
wvpl_policy.license_duration_seconds());
sdk_policy->set_renewal_delay_seconds(wvpl_policy.renewal_interval_seconds());
sdk_policy->set_renewal_recovery_duration_seconds(
wvpl_policy.renewal_recovery_duration_seconds());
sdk_policy->set_renewal_retry_interval_seconds(
wvpl_policy.renewal_retry_interval_seconds());
sdk_policy->set_renewal_server_url(wvpl_policy.renewal_url());
sdk_policy->set_renew_with_usage(wvpl_policy.renew_with_usage());
}
void WvPLSDKSession::CopySecurityLevel(
const WvPLOutputProtection& output_protection, TrackType track_type,
License::KeyContainer* key_container) {
switch (output_protection.security_level()) {
case SECURITY_LEVEL_UNDEFINED:
if (output_protection.secure_data_path()) {
key_container->set_level(License::KeyContainer::HW_SECURE_ALL);
} else {
if (IsChromeCDM() && track_type != AUDIO) {
key_container->set_level(License::KeyContainer::SW_SECURE_DECODE);
} else {
key_container->set_level(License::KeyContainer::SW_SECURE_CRYPTO);
}
}
break;
default:
key_container->set_level(
static_cast<License::KeyContainer::SecurityLevel>(
output_protection.security_level()));
break;
}
}
void WvPLSDKSession::CopySessionInit(const WvPLSessionInit& wvpl_session_init,
SessionInit* session_init) {
DCHECK(session_init);
if (session_init == NULL) {
return;
}
if (wvpl_session_init.license_start_time() > 0) {
session_init->set_license_start_time(
wvpl_session_init.license_start_time());
}
if (!wvpl_session_init.session_id().empty()) {
session_init->set_session_id(wvpl_session_init.session_id());
}
if (!wvpl_session_init.purchase_id().empty()) {
session_init->set_purchase_id(wvpl_session_init.purchase_id());
}
if (!wvpl_session_init.master_signing_key().empty()) {
session_init->set_master_signing_key(
wvpl_session_init.master_signing_key());
}
if (!wvpl_session_init.provider_client_token().empty()) {
session_init->set_provider_client_token(
wvpl_session_init.provider_client_token());
}
if (!wvpl_session_init.provider_session_token().empty()) {
session_init->set_provider_session_token(
wvpl_session_init.provider_session_token());
}
session_init->set_override_provider_client_token(
wvpl_session_init.override_provider_client_token());
}
void WvPLSDKSession::CopySessionState(
const WvPLSessionState& wvpl_session_state,
widevine::SessionState* session_state) {
DCHECK(session_state);
if (session_state == nullptr) {
return;
}
if (wvpl_session_state.license_counter() > 0) {
session_state->set_license_counter(wvpl_session_state.license_counter());
}
if (wvpl_session_state.keybox_system_id() > 0) {
session_state->set_keybox_system_id(wvpl_session_state.keybox_system_id());
}
if (!wvpl_session_state.signing_key().empty()) {
session_state->set_signing_key(wvpl_session_state.signing_key());
}
if (!wvpl_session_state.provider_client_token().empty()) {
session_state->set_provider_client_token(
wvpl_session_state.provider_client_token());
}
widevine::LicenseIdentification* license_id =
session_state->mutable_license_id();
widevine_server::wv_pl_sdk::LicenseIdentification wvpl_license_id =
wvpl_session_state.license_id();
LicenseType license_type = wvpl_license_id.type();
switch (license_type) {
case STREAMING:
license_id->set_type(widevine::LicenseType::STREAMING);
break;
case OFFLINE:
license_id->set_type(widevine::LicenseType::OFFLINE);
break;
default:
break;
}
if (wvpl_license_id.version() > 0) {
license_id->set_version(wvpl_license_id.version());
}
if (!wvpl_license_id.request_id().empty()) {
license_id->set_request_id(wvpl_license_id.request_id());
}
if (!wvpl_license_id.session_id().empty()) {
license_id->set_session_id(wvpl_license_id.session_id());
}
if (!wvpl_license_id.purchase_id().empty()) {
license_id->set_purchase_id(wvpl_license_id.purchase_id());
}
if (!wvpl_license_id.provider_session_token().empty()) {
license_id->set_provider_session_token(
wvpl_license_id.provider_session_token());
}
}
MessageType WvPLSDKSession::message_type() const { return message_type_; }
void WvPLSDKSession::CopyHDCP(
HDCP hdcp_value,
License::KeyContainer::OutputProtection* output_protection) {
DCHECK(output_protection);
if (!output_protection) {
return;
}
switch (hdcp_value) {
case HDCP_V1:
output_protection->set_hdcp(
License::KeyContainer::OutputProtection::HDCP_V1);
break;
case HDCP_V2:
output_protection->set_hdcp(
License::KeyContainer::OutputProtection::HDCP_V2);
break;
case HDCP_V2_1:
output_protection->set_hdcp(
License::KeyContainer::OutputProtection::HDCP_V2_1);
break;
case HDCP_V2_2:
output_protection->set_hdcp(
License::KeyContainer::OutputProtection::HDCP_V2_2);
break;
case HDCP_V2_3:
output_protection->set_hdcp(
License::KeyContainer::OutputProtection::HDCP_V2_3);
break;
case HDCP_NONE:
output_protection->set_hdcp(
License::KeyContainer::OutputProtection::HDCP_NONE);
break;
default:
break;
}
}
void WvPLSDKSession::CopyHDCPToClientCapabilities(
ClientIdentification::ClientCapabilities::HdcpVersion hdcp_value,
WvPLClientCapabilities* client_capabilities) const {
DCHECK(client_capabilities);
if (!client_capabilities) {
return;
}
switch (hdcp_value) {
case ClientIdentification::ClientCapabilities::HDCP_NONE:
client_capabilities->set_max_hdcp_version(HDCP_NONE);
break;
case ClientIdentification::ClientCapabilities::HDCP_V1:
client_capabilities->set_max_hdcp_version(HDCP_V1);
break;
case ClientIdentification::ClientCapabilities::HDCP_V2:
client_capabilities->set_max_hdcp_version(HDCP_V2);
break;
case ClientIdentification::ClientCapabilities::HDCP_V2_1:
client_capabilities->set_max_hdcp_version(HDCP_V2_1);
break;
case ClientIdentification::ClientCapabilities::HDCP_V2_2:
client_capabilities->set_max_hdcp_version(HDCP_V2_2);
break;
case ClientIdentification::ClientCapabilities::HDCP_V2_3:
client_capabilities->set_max_hdcp_version(HDCP_V2_3);
break;
case ClientIdentification::ClientCapabilities::HDCP_NO_DIGITAL_OUTPUT:
client_capabilities->set_max_hdcp_version(HDCP_NO_DIGITAL_OUTPUT);
break;
default:
break;
}
}
void WvPLSDKSession::CopyAnalogOutputCapabilities(
ClientIdentification::ClientCapabilities::AnalogOutputCapabilities
analog_output_capabilities,
WvPLClientCapabilities* client_capabilities) const {
DCHECK(client_capabilities);
if (!client_capabilities) {
return;
}
switch (analog_output_capabilities) {
case ClientIdentification::ClientCapabilities::ANALOG_OUTPUT_UNKNOWN:
client_capabilities->set_analog_output_capabilities(
ANALOG_OUTPUT_UNKNOWN);
break;
case ClientIdentification::ClientCapabilities::ANALOG_OUTPUT_NONE:
client_capabilities->set_analog_output_capabilities(ANALOG_OUTPUT_NONE);
break;
case ClientIdentification::ClientCapabilities::ANALOG_OUTPUT_SUPPORTED:
client_capabilities->set_analog_output_capabilities(
ANALOG_OUTPUT_SUPPORTED);
break;
case ClientIdentification::ClientCapabilities::
ANALOG_OUTPUT_SUPPORTS_CGMS_A:
client_capabilities->set_analog_output_capabilities(
ANALOG_OUTPUT_SUPPORTS_CGMS_A);
break;
default:
break;
}
}
void WvPLSDKSession::CopyOutputProtection(
const WvPLKey& wvpl_key, License::KeyContainer* sdk_key_container) {
DCHECK(sdk_key_container);
if (!sdk_key_container) {
return;
}
// Transfer HDCP from required output protection value.
CopyHDCP(wvpl_key.output_protection().hdcp(),
sdk_key_container->mutable_required_protection());
// Transfer HDCP from requested output protection value.
CopyHDCP(wvpl_key.requested_output_protection().hdcp(),
sdk_key_container->mutable_requested_protection());
CopySecurityLevel(wvpl_key.output_protection(), wvpl_key.track_type(),
sdk_key_container);
sdk_key_container->mutable_requested_protection()->set_disable_analog_output(
wvpl_key.output_protection().disable_analog_output());
if (wvpl_key.output_protection().disable_digital_output()) {
sdk_key_container->mutable_required_protection()->set_hdcp(
License::KeyContainer::OutputProtection::HDCP_NO_DIGITAL_OUTPUT);
}
CopyCGMS(wvpl_key.output_protection().cgms(),
sdk_key_container->mutable_requested_protection());
// Transfer Video resultion constraints.
const std::vector<WvPLVideoResolutionConstraint>& video_constraints =
wvpl_key.video_resolution_constraints();
for (std::vector<WvPLVideoResolutionConstraint>::const_iterator it =
video_constraints.begin();
it != video_constraints.end(); ++it) {
License::KeyContainer::VideoResolutionConstraint* video_constraint =
sdk_key_container->mutable_video_resolution_constraints()->Add();
video_constraint->set_min_resolution_pixels(it->min_resolution_pixels());
video_constraint->set_max_resolution_pixels(it->max_resolution_pixels());
CopyHDCP(it->hdcp(), video_constraint->mutable_required_protection());
}
}
void WvPLSDKSession::CopyCGMS(
CGMS cgms_value,
License::KeyContainer::OutputProtection* output_protection) {
DCHECK(output_protection);
if (output_protection == nullptr) {
return;
}
switch (cgms_value) {
case CGMS_NONE:
output_protection->set_cgms_flags(
License::KeyContainer::OutputProtection::CGMS_NONE);
break;
case COPY_FREE:
output_protection->set_cgms_flags(
License::KeyContainer::OutputProtection::COPY_FREE);
break;
case COPY_ONCE:
output_protection->set_cgms_flags(
License::KeyContainer::OutputProtection::COPY_ONCE);
break;
case COPY_NEVER:
output_protection->set_cgms_flags(
License::KeyContainer::OutputProtection::COPY_NEVER);
break;
default:
break;
}
}
void WvPLSDKSession::CopyProvisionedDeviceInfo(
const WvPLDeviceInfo& wvpl_device_info,
widevine::ProvisionedDeviceInfo* device_info) {
DCHECK(device_info);
if (device_info == nullptr) {
return;
}
device_info->set_system_id(wvpl_device_info.system_id());
device_info->set_soc(wvpl_device_info.soc());
device_info->set_manufacturer(wvpl_device_info.manufacturer());
device_info->set_model(wvpl_device_info.model());
device_info->set_device_type(wvpl_device_info.device_type());
device_info->set_test_device(wvpl_device_info.test_device());
switch (wvpl_device_info.security_level()) {
case DEVICE_LEVEL_UNSPECIFIED:
device_info->set_security_level(ProvisionedDeviceInfo::LEVEL_UNSPECIFIED);
break;
case DEVICE_LEVEL_1:
device_info->set_security_level(ProvisionedDeviceInfo::LEVEL_1);
break;
case DEVICE_LEVEL_2:
device_info->set_security_level(ProvisionedDeviceInfo::LEVEL_2);
break;
case DEVICE_LEVEL_3:
device_info->set_security_level(ProvisionedDeviceInfo::LEVEL_3);
break;
default:
break;
}
}
WvPLStatus WvPLSDKSession::ParseLicenseRequest() {
WvPLStatus status = util::OkStatus();
if (license_request_from_cdm_.empty() && sdk_license_request_ == nullptr) {
return WvPLStatus(error_space, widevine::SIGNED_MESSAGE_PARSE_ERROR,
"License request from cdm is empty or null");
}
// This is used by proxy sdk only.
if (!license_request_from_cdm_.empty()) {
signed_message_request_from_cdm_ = absl::make_unique<SignedMessage>();
if (!signed_message_request_from_cdm_->ParseFromString(
license_request_from_cdm_)) {
return WvPLStatus(error_space, widevine::SIGNED_MESSAGE_PARSE_ERROR,
"Unable to parse license request from CDM into "
"SignedMessage");
}
}
// This is used by proxy sdk only.
if (signed_message_request_from_cdm_ != nullptr) {
switch (signed_message_request_from_cdm_->type()) {
case SignedMessage::LICENSE_REQUEST:
message_type_ = LICENSE_REQUEST;
DCHECK(signed_message_request_from_cdm_);
sdk_license_request_ = absl::make_unique<LicenseRequest>();
if (!sdk_license_request_->ParseFromString(
signed_message_request_from_cdm_->msg())) {
return WvPLStatus(error_space,
widevine::LICENSE_REQUEST_PARSE_ERROR,
"Unable to parse license request from CDM into "
"LicenseRequest");
}
break;
case SignedMessage::SERVICE_CERTIFICATE_REQUEST:
message_type_ = SERVICE_CERTIFICATE_REQUEST;
break;
default:
break;
}
}
// This code is used by proxy and wvpl license server sdk.
if (message_type_ == LICENSE_REQUEST) {
// Parse for ClientIdentification in license request.
if (sdk_license_request_->has_client_id() &&
sdk_license_request_->has_encrypted_client_id()) {
return WvPLStatus(
error_space, widevine::MULTIPLE_CLIENT_ID,
"ClientIdentification and EncryptedClientIdentification "
"are both specified in the license request");
}
if (sdk_license_request_->has_client_id()) {
client_id_ = sdk_license_request_->client_id();
has_client_id_ = true;
} else if (sdk_license_request_->has_encrypted_client_id()) {
if (!DrmServiceCertificate::DecryptClientIdentification(
sdk_license_request_->encrypted_client_id(), &client_id_)
.ok()) {
return WvPLStatus(
error_space,
widevine::INVALID_ENCRYPTED_CLIENT_IDENTIFICATION,
"Unable to decrypt EncryptedClientIdentification in "
"the license request");
}
has_client_id_ = true;
}
if (client_id_.has_token()) {
// Get system_id from token field in ClientIdentification.
system_id_ = KeyboxClientCert::GetSystemId(client_id_.token());
has_system_id_ = true;
}
// TODO(user): Consider enforcing missing client id here.
// Verifies platform for license requests and sets Platform Verification
// status.
platform_verification_status_ = VerifyPlatform();
if (sdk_license_request_->type() == LicenseRequest::NEW) {
WvPLWidevinePsshData wvpl_widevine_pssh_data;
status = GetPsshData(&wvpl_widevine_pssh_data);
if (status.ok()) {
pssh_data_ = wvpl_widevine_pssh_data;
has_pssh_data_ = true;
}
}
request_type_ = sdk_license_request_->type();
}
return util::OkStatus();
}
bool WvPLSDKSession::IsChromeCDM() const {
WvPLDeviceInfo sdk_device_info;
if (GetDeviceInfo(&sdk_device_info).ok()) {
return (sdk_device_info.model().find("ChromeCDM-") != std::string::npos);
}
return false;
}
WvPLStatus WvPLSDKSession::GetClientInfo(WvPLClientInfo* client_info) const {
WvPLStatus status = util::OkStatus();
if (client_info == nullptr) {
return WvPLStatus(error_space, util::error::INVALID_ARGUMENT,
"client_info is NULL");
}
if (!has_client_id_) {
return WvPLStatus(
error_space, widevine::MISSING_CLIENT_ID,
"ClientIdentification is not found in the license request");
}
switch (client_id_.client_capabilities().max_hdcp_version()) {
case ClientIdentification::ClientCapabilities::HDCP_NONE:
client_info->set_max_hdcp_version(HDCP_NONE);
break;
case ClientIdentification::ClientCapabilities::HDCP_V1:
client_info->set_max_hdcp_version(HDCP_V1);
break;
case ClientIdentification::ClientCapabilities::HDCP_V2:
client_info->set_max_hdcp_version(HDCP_V2);
break;
case ClientIdentification::ClientCapabilities::HDCP_V2_1:
client_info->set_max_hdcp_version(HDCP_V2_1);
break;
case ClientIdentification::ClientCapabilities::HDCP_V2_2:
client_info->set_max_hdcp_version(HDCP_V2_2);
break;
case ClientIdentification::ClientCapabilities::HDCP_V2_3:
client_info->set_max_hdcp_version(HDCP_V2_3);
break;
case ClientIdentification::ClientCapabilities::HDCP_NO_DIGITAL_OUTPUT:
client_info->set_max_hdcp_version(HDCP_NO_DIGITAL_OUTPUT);
break;
default:
break;
}
if (client_id_.client_capabilities().has_oem_crypto_api_version()) {
client_info->set_oem_crypto_api_version(
client_id_.client_capabilities().oem_crypto_api_version());
}
if (client_id_.has_provider_client_token()) {
client_info->set_provider_client_token(client_id_.provider_client_token());
}
for (const auto& name_value : client_id_.client_info()) {
client_info->set_name_value(name_value.name(), name_value.value());
}
WvPLClientCapabilities client_capabilities;
status = GetClientCapabilities(&client_capabilities);
client_info->set_client_capabilities(client_capabilities);
return status;
}
WvPLStatus WvPLSDKSession::VerifyRemoteAttestation() {
DCHECK(signed_message_request_from_cdm_);
if (!signed_message_request_from_cdm_->has_remote_attestation()) {
return WvPLStatus(error_space, util::error::INTERNAL,
"Remote Attestation not specified");
} else if (!signed_message_request_from_cdm_->remote_attestation()
.has_certificate()) {
return WvPLStatus(error_space, util::error::INVALID_ARGUMENT,
"Remote Attestation Certificate not specified");
} else {
WvPLStatus ra_status =
RemoteAttestationVerifier::get().VerifyRemoteAttestation(
signed_message_request_from_cdm_->msg(),
signed_message_request_from_cdm_->remote_attestation(),
&remote_attestation_cert_serial_number_);
}
return util::OkStatus();
}
WvPLStatus WvPLSDKSession::GetClientCapabilities(
WvPLClientCapabilities* client_capabilities) const {
WvPLStatus status = util::OkStatus();
if (client_capabilities == nullptr) {
return WvPLStatus(error_space, util::error::INVALID_ARGUMENT,
"client_capabilities is NULL");
}
if (!has_client_id_) {
return WvPLStatus(
error_space, widevine::MISSING_CLIENT_ID,
"ClientIdentification is not found in the license request");
}
status = GetWvPLClientCapabilities(client_id_, client_capabilities);
return status;
}
WvPLStatus WvPLSDKSession::GetWvPLClientCapabilities(
const widevine::ClientIdentification& client_id,
WvPLClientCapabilities* client_capabilities) const {
WvPLStatus status = util::OkStatus();
if (client_capabilities == nullptr) {
return WvPLStatus(error_space, util::error::INVALID_ARGUMENT,
"client_capabilities is NULL");
}
CopyHDCPToClientCapabilities(
client_id.client_capabilities().max_hdcp_version(), client_capabilities);
if (client_id.client_capabilities().has_oem_crypto_api_version()) {
client_capabilities->set_oem_crypto_api_version(
client_id.client_capabilities().oem_crypto_api_version());
}
if (client_id.client_capabilities().has_can_disable_analog_output()) {
client_capabilities->set_can_disable_analog_output(true);
}
if (client_id.has_provider_client_token()) {
client_capabilities->set_client_token(true);
}
if (client_id.has_token()) {
client_capabilities->set_session_token(true);
}
if (client_id.client_capabilities().has_video_resolution_constraints()) {
client_capabilities->set_video_resolution_constraints(true);
}
if (client_id.client_capabilities().has_anti_rollback_usage_table()) {
client_capabilities->set_anti_rollback_usage_table(true);
}
if (client_id.client_capabilities().has_srm_version()) {
client_capabilities->set_srm_version(
client_id.client_capabilities().srm_version());
}
if (client_id.client_capabilities().has_can_update_srm()) {
client_capabilities->set_can_update_srm(
client_id.client_capabilities().can_update_srm());
}
CopyAnalogOutputCapabilities(
client_id.client_capabilities().analog_output_capabilities(),
client_capabilities);
for (const auto& key_type :
client_id.client_capabilities().supported_certificate_key_type()) {
switch (key_type) {
case ClientIdentification::ClientCapabilities::RSA_2048:
client_capabilities->add_supported_certificate_key_type(RSA_2048);
break;
case ClientIdentification::ClientCapabilities::RSA_3072:
client_capabilities->add_supported_certificate_key_type(RSA_3072);
break;
default:
break;
}
}
return status;
}
WvPLStatus WvPLSDKSession::GetPsshData(
WvPLWidevinePsshData* wvpl_widevine_pssh_data) const {
DCHECK(wvpl_widevine_pssh_data);
if (wvpl_widevine_pssh_data == nullptr) {
return WvPLStatus(error_space, util::error::INVALID_ARGUMENT,
"wvpl_widevine_pssh_data is null");
}
if (!has_pssh_data_) {
// TODO(b/115784237): Fix calling ParsePsshData within base class.
WvPLStatus status = ParsePsshData(wvpl_widevine_pssh_data);
return status;
}
*wvpl_widevine_pssh_data = pssh_data_;
return util::OkStatus();
}
WvPLStatus WvPLSDKSession::GetDeviceInfo(WvPLDeviceInfo* device_info) const {
WvPLStatus status = util::OkStatus();
if (device_info == nullptr) {
return WvPLStatus(error_space, util::error::INVALID_ARGUMENT,
"device_info is NULL");
}
if (!has_system_id_) {
return WvPLStatus(
error_space, widevine::UNSUPPORTED_SYSTEM_ID,
"Widevine SystemID does not exist because it is not found "
"in the license request");
}
ProvisionedDeviceInfo provisioned_device_info;
status = WvPLSDKEnvironment::LookupDeviceInfo(system_id_,
&provisioned_device_info);
if (!status.ok()) {
return status;
}
device_info->set_system_id(provisioned_device_info.system_id());
if (provisioned_device_info.has_soc()) {
device_info->set_soc(provisioned_device_info.soc());
}
if (provisioned_device_info.has_model()) {
device_info->set_model(provisioned_device_info.model());
}
if (provisioned_device_info.has_device_type()) {
device_info->set_device_type(provisioned_device_info.device_type());
}
if (provisioned_device_info.has_test_device()) {
device_info->set_test_device(provisioned_device_info.test_device());
}
if (provisioned_device_info.has_manufacturer()) {
device_info->set_manufacturer(provisioned_device_info.manufacturer());
}
switch (provisioned_device_info.security_level()) {
case ProvisionedDeviceInfo::LEVEL_UNSPECIFIED:
device_info->set_security_level(DEVICE_LEVEL_UNSPECIFIED);
break;
case ProvisionedDeviceInfo::LEVEL_1:
device_info->set_security_level(DEVICE_LEVEL_1);
break;
case ProvisionedDeviceInfo::LEVEL_2:
device_info->set_security_level(DEVICE_LEVEL_2);
break;
case ProvisionedDeviceInfo::LEVEL_3:
device_info->set_security_level(DEVICE_LEVEL_3);
break;
default:
break;
}
return status;
}
} // namespace wv_pl_sdk
} // namespace widevine_server

View File

@@ -0,0 +1,198 @@
////////////////////////////////////////////////////////////////////////////////
// Copyright 2018 Google LLC.
//
// This software is licensed under the terms defined in the Widevine Master
// License Agreement. For a copy of this agreement, please contact
// widevine-licensing@google.com.
////////////////////////////////////////////////////////////////////////////////
#ifndef SDK_EXTERNAL_COMMON_WVPL_WVPL_SDK_SESSION_H_
#define SDK_EXTERNAL_COMMON_WVPL_WVPL_SDK_SESSION_H_
#include "sdk/external/common/wvpl/wvpl_types.h"
#include "protos/public/client_identification.pb.h"
#include "protos/public/device_certificate_status.pb.h"
#include "protos/public/license_protocol.pb.h"
#include "protos/public/license_server_sdk.pb.h"
#include "protos/public/provisioned_device_info.pb.h"
namespace widevine {
class SessionInit;
}
namespace widevine_server {
namespace wv_pl_sdk {
class WvPLSDKSession {
public:
virtual ~WvPLSDKSession() = 0;
public:
// Add WvPLKey.
virtual WvPLStatus AddKey(const WvPLKey& key);
// Get the WvPLKey.
virtual const std::vector<WvPLKey>& key() const { return keys_; }
// Set the license policy.
virtual void set_policy(const WvPLPlaybackPolicy& policy) {
policy_ = policy;
}
// Get the license policy.
virtual const WvPLPlaybackPolicy& policy() const { return policy_; }
// Set the Session Init.
virtual void set_session_init(const WvPLSessionInit& session_init) {
session_init_ = session_init;
}
// Get the Session Init.
virtual const WvPLSessionInit& session_init() const { return session_init_; }
virtual bool IsChromeCDM() const;
/**
* Returns the Widevine PSSH data for the license request handled by this
* session.
*
* @param wvpl_widevine_pssh_data.
* @return WvPLStatus - Status::OK if success, else error.
*/
virtual WvPLStatus GetPsshData(
WvPLWidevinePsshData* wvpl_widevine_pssh_data) const;
/**
* Returns the ClientIdentification information for the license request
* handled by this session.
*
* @param client_info
* @return WvPLStatus - Status::OK if success, else error.
*/
virtual WvPLStatus GetClientInfo(WvPLClientInfo* client_info) const;
/**
* Returns the WvPL Client Capabilities information for the license request
* handled by this session.
*
* @param client_capabilities.
* @return WvPLStatus - Status::OK if success, else error.
*/
virtual WvPLStatus GetClientCapabilities(
WvPLClientCapabilities* client_capabilities) const;
/**
* Returns the WvPLDeviceInfo information for the license request
* handled by this session.
*
* @param device_info
* @return WvPLStatus - Status::OK if success, else error.
*/
virtual WvPLStatus GetDeviceInfo(WvPLDeviceInfo* device_info) const;
/**
* Returns the type of the message handled by this session.
*
* @return MessageType enumeration.
*/
virtual MessageType message_type() const;
virtual PlatformVerificationStatus VerifyPlatform() = 0;
virtual widevine::LicenseRequest::RequestType request_type() const {
return request_type_;
}
protected:
uint32_t system_id_ = 0xFFFFFFFF;
std::string user_agent_;
std::vector<WvPLKey> keys_;
WvPLPlaybackPolicy policy_;
WvPLSessionInit session_init_;
WvPLWidevinePsshData pssh_data_;
widevine::ClientIdentification client_id_;
bool has_pssh_data_ = false;
bool has_system_id_ = false;
bool has_client_id_ = false;
MessageType message_type_ = UNKNOWN;
PlatformVerificationStatus platform_verification_status_ =
PLATFORM_NO_VERIFICATION;
std::unique_ptr<widevine::SignedMessage>
signed_message_request_from_cdm_;
std::string license_request_from_cdm_;
std::string remote_attestation_cert_serial_number_;
std::unique_ptr<widevine::LicenseRequest> sdk_license_request_;
widevine::LicenseRequest::RequestType request_type_;
virtual WvPLStatus VerifyRemoteAttestation();
// Returns the WvPL Client Capabilities information for the license request
// handled by this session.
WvPLStatus GetWvPLClientCapabilities(
const widevine::ClientIdentification& client_id,
WvPLClientCapabilities* client_capabilities) const;
// Copies/translates the output protection from a WvPL Key into an SDK
// key container.
void CopyOutputProtection(
const WvPLKey& wvpl_key,
widevine::License_KeyContainer* sdk_key_container);
virtual void CopySecurityLevel(
const WvPLOutputProtection& output_protection, TrackType track_type,
widevine::License::KeyContainer* key_container);
// Copies/translates the policy from a WvPL policy into an SDK policy. A
// helper function for GenerateLicenseRequestAsJSON.
virtual void CopyPlaybackPolicy(const WvPLPlaybackPolicy& wvpl_policy,
widevine::License::Policy* sdk_policy);
// Copy the |cgms_value| into the key container. A helper function for
// GenerateLicenseRequestAsJSON.
virtual void CopyCGMS(CGMS cgms_value,
widevine::License::KeyContainer::OutputProtection*
output_protection);
// Copy the |hdcp_value| into the key container.
virtual void CopyHDCP(HDCP hdcp_value,
widevine::License::KeyContainer::OutputProtection*
output_protection);
// Copy the |hdcp_value| into the client_capabilities.
virtual void CopyHDCPToClientCapabilities(
widevine::ClientIdentification::ClientCapabilities::HdcpVersion
hdcp_value,
WvPLClientCapabilities* client_capabilities) const;
// Copy the |analog_output_capabilities| into the client_capabilities.
virtual void CopyAnalogOutputCapabilities(
widevine::ClientIdentification::ClientCapabilities::
AnalogOutputCapabilities analog_output_capabilities,
WvPLClientCapabilities* client_capabilities) const;
// Copy the WvPLSession Init into Session Init.
virtual void CopySessionInit(const WvPLSessionInit& wvpl_session_init,
widevine::SessionInit* session_init);
// Copy the WvPLDeviceInfo into ProvisionedDeviceInfo.
virtual void CopyProvisionedDeviceInfo(
const WvPLDeviceInfo& wvpl_device_info,
widevine::ProvisionedDeviceInfo* device_info);
// Populate deviceInfo, clientIdentification and psshdata for license request.
WvPLStatus ParseLicenseRequest();
// Copy the WvPLSessionState to SessionState.
void CopySessionState(const WvPLSessionState& wvpl_session_state,
widevine::SessionState* session_state);
private:
/**
* Parses WvPLWidevinePsshData in the new license request.
*
* @return WvPLStatus - Status::OK if success, else error.
*/
virtual WvPLStatus ParsePsshData(
WvPLWidevinePsshData* wvpl_widevine_pssh_data) const = 0;
};
} // namespace wv_pl_sdk
} // namespace widevine_server
#endif // SDK_EXTERNAL_COMMON_WVPL_WVPL_SDK_SESSION_H_

931
sdk/external/common/wvpl/wvpl_types.h vendored Normal file
View File

@@ -0,0 +1,931 @@
////////////////////////////////////////////////////////////////////////////////
// Copyright 2017 Google LLC.
//
// This software is licensed under the terms defined in the Widevine Master
// License Agreement. For a copy of this agreement, please contact
// widevine-licensing@google.com.
////////////////////////////////////////////////////////////////////////////////
#ifndef SDK_EXTERNAL_COMMON_WVPL_WVPL_TYPES_H_
#define SDK_EXTERNAL_COMMON_WVPL_WVPL_TYPES_H_
#include <stdint.h>
#include <list>
#include <map>
#include <memory>
#include <vector>
#include "util/status.h"
// TODO(user) Split wvpl_types.h into wvpl_common_types.h ,
// wvpl_license_sdk_types.h, wvpl_proxy_sdk_types.h and
// wvpl_packager_sdk_types.h.
namespace widevine_server {
namespace wv_pl_sdk {
typedef widevine::util::Status WvPLStatus;
typedef uint32_t uint32_t;
typedef int64_t int64_t;
/**
* Represents the key type for the keys that are used when generating a license.
* The generated license includes a key container, which in turn, contains the
* key material, metadata and policy needed to use the key.
*/
enum KeyType {
UNKNOWN_KEY = 0,
// Key used to decrypt media content.
CONTENT = 1,
// Key used for wrapping content keys.
ENTITLEMENT = 2
};
enum LicenseType {
STREAMING = 1,
OFFLINE = 2,
};
/**
* Represents the type of message. This struct is used by Proxy SDK.
*/
enum MessageType {
UNKNOWN = 0,
LICENSE_REQUEST = 1,
SERVICE_CERTIFICATE_REQUEST = 4
};
enum CertificateKeyType {
RSA_2048 = 0,
RSA_3072 = 1,
};
enum PlatformVerificationStatus {
PLATFORM_UNVERIFIED = 0,
PLATFORM_TAMPERED = 1,
PLATFORM_SOFTWARE_VERIFIED = 2,
PLATFORM_HARDWARE_VERIFIED = 3,
PLATFORM_NO_VERIFICATION = 4,
PLATFORM_SECURE_STORAGE_SOFTWARE_VERIFIED = 5
};
// LINT.IfChange
enum HDCP {
HDCP_NONE = 0,
HDCP_V1 = 1,
HDCP_V2 = 2,
HDCP_V2_1 = 3,
HDCP_V2_2 = 4,
HDCP_V2_3 = 5,
HDCP_NO_DIGITAL_OUTPUT = 0xff
};
enum SecurityLevel {
SECURITY_LEVEL_UNDEFINED = 0,
SW_SECURE_CRYPTO = 1,
SW_SECURE_DECODE = 2,
HW_SECURE_CRYPTO = 3,
HW_SECURE_DECODE = 4,
HW_SECURE_ALL = 5
};
enum DeviceSecurityLevel {
DEVICE_LEVEL_UNSPECIFIED = 0,
DEVICE_LEVEL_1 = 1,
DEVICE_LEVEL_2 = 2,
DEVICE_LEVEL_3 = 3
};
enum CGMS {
CGMS_NONE = 42,
COPY_FREE = 0,
COPY_ONCE = 2,
COPY_NEVER = 3,
};
enum TrackType {
TRACK_TYPE_UNSPECIFIED = 0,
AUDIO = 1,
VIDEO_SD = 2,
VIDEO_HD = 3,
VIDEO_UHD1 = 4,
VIDEO_UHD2 = 5,
};
enum AnalogOutputCapabilities {
ANALOG_OUTPUT_UNKNOWN = 0,
ANALOG_OUTPUT_NONE = 1,
ANALOG_OUTPUT_SUPPORTED = 2,
ANALOG_OUTPUT_SUPPORTS_CGMS_A = 3,
};
struct WvPLPlaybackPolicy {
WvPLPlaybackPolicy() {
license_duration_seconds_ = 0;
playback_duration_seconds_ = 0;
renewal_interval_seconds_ = 0;
renewal_recovery_duration_seconds_ = 0;
renewal_retry_interval_seconds_ = 0;
can_play_ = true;
can_renew_ = false;
can_persist_ = false;
}
void set_license_duration_seconds(uint32_t duration) {
license_duration_seconds_ = duration;
}
uint32_t license_duration_seconds() const { return license_duration_seconds_; }
void set_playback_duration_seconds(uint32_t duration) {
playback_duration_seconds_ = duration;
}
uint32_t playback_duration_seconds() const {
return playback_duration_seconds_;
}
void set_renewal_interval_seconds(uint32_t duration) {
renewal_interval_seconds_ = duration;
}
uint32_t renewal_interval_seconds() const { return renewal_interval_seconds_; }
void set_renewal_recovery_duration_seconds(int64_t dur) {
renewal_recovery_duration_seconds_ = dur;
}
int64_t renewal_recovery_duration_seconds() const {
return renewal_recovery_duration_seconds_;
}
void set_renewal_retry_interval_seconds(int64_t retry_interval) {
renewal_retry_interval_seconds_ = retry_interval;
}
int64_t renewal_retry_interval_seconds() const {
return renewal_retry_interval_seconds_;
}
void set_renew_with_usage(bool usage_flag) { renew_with_usage_ = usage_flag; }
bool renew_with_usage() const { return renew_with_usage_; }
void set_renewal_url(const std::string& url) { renewal_url_ = url; }
const std::string& renewal_url() const { return renewal_url_; }
void set_can_play(bool play_flag) { can_play_ = play_flag; }
bool can_play() const { return can_play_; }
void set_can_persist(bool persist_flag) { can_persist_ = persist_flag; }
bool can_persist() const { return can_persist_; }
void set_can_renew(bool renew_flag) { can_renew_ = renew_flag; }
bool can_renew() const { return can_renew_; }
// The license window. Once a license is granted, the number of seconds to use
// this license. Default is 0, indicating unlimited license.
uint32_t license_duration_seconds_;
// The playback window. Once initial playback starts, the number of seconds
// to use the license. Default is 0, indicating unlimited but not to exceed
// the license_duration_window.
uint32_t playback_duration_seconds_;
// How many seconds after license_start_time, before renewal is first
// attempted.
uint32_t renewal_interval_seconds_;
// The window of time, in which playback is allowed to continue while
// renewal is attempted, yet unsuccessful due to backend problems with
// the license server.
int64_t renewal_recovery_duration_seconds_;
// Specifies the delay in seconds between subsequent license
// renewal requests, in case of failure.
int64_t renewal_retry_interval_seconds_;
// Indicates that the license shall be sent for renewal when usage is
// started.
bool renew_with_usage_;
// Renewal requests are sent to this URL.
std::string renewal_url_;
// Indicates that playback of ths content is allowed.
bool can_play_;
// Indicates that the license may be persisted to non-volatile storage for
// offline use.
bool can_persist_;
// Indicates that renewal of this license is allowed.
bool can_renew_;
};
/**
* LicenseIdentification is propagated from LicenseRequest to License,
* incrementing version with each iteration.
* */
struct LicenseIdentification {
LicenseIdentification() {
version_ = 0;
type_ = STREAMING;
}
// |request_id| must be specified in bytes.
void set_request_id(const std::string& request_id) {
request_id_ = request_id;
}
const std::string& request_id() { return request_id_; }
// |session_id| must be specified in bytes.
void set_session_id(const std::string& session_id) {
session_id_ = session_id;
}
const std::string& session_id() { return session_id_; }
// |purchase_id| must be specified in bytes.
void set_purchase_id(const std::string& purchase_id) {
purchase_id_ = purchase_id;
}
const std::string& purchase_id() { return purchase_id_; }
void set_type(LicenseType type) { type_ = type; }
LicenseType type() { return type_; }
uint32_t version() { return version_; }
void set_version(uint32_t version) { version_ = version; }
// |provider_session_token| must be specified in bytes.
void set_provider_session_token(const std::string& provider_session_token) {
provider_session_token_ = provider_session_token;
}
const std::string& provider_session_token() {
return provider_session_token_;
}
// License request id.
std::string request_id_; // NOLINT
// Session identifier for license request.
std::string session_id_; // NOLINT
// Session token for the session. This token is for use by the license
// provider, and is akin to a session cookie. It will be copied to
// LicenseIdentfication::provider_session_token, and sent back in all
std::string provider_session_token_; // NOLINT
// Purchase identifier.
std::string purchase_id_; // NOLINT
// Type of the license, default value is Streaming.
LicenseType type_; // NOLINT
// Version of license request.
uint32_t version_; // NOLINT
};
/**
* This message is used by the server to preserve and restore session state.
* */
struct WvPLSessionState {
WvPLSessionState() {
keybox_system_id_ = 0;
license_counter_ = 0;
}
void set_license_id(const LicenseIdentification& license_id) {
license_id_ = license_id;
}
const LicenseIdentification& license_id() const { return license_id_; }
LicenseIdentification* mutable_license_id() { return &license_id_; }
const std::string& signing_key() const { return signing_key_; }
// |signing_key| must be specified in bytes.
void set_signing_key(const std::string& signing_key) {
signing_key_ = signing_key;
}
uint32_t keybox_system_id() const { return keybox_system_id_; }
void set_keybox_system_id(uint32_t keybox_system_id) {
keybox_system_id_ = keybox_system_id;
}
uint32_t license_counter() const { return license_counter_; }
void set_license_counter(uint32_t license_counter) {
license_counter_ = license_counter;
}
const std::string& provider_client_token() const {
return provider_client_token_;
}
// |provider_client_token| must be specified in bytes.
void set_provider_client_token(const std::string& provider_client_token) {
provider_client_token_ = provider_client_token;
}
// License information propagated from license request to the license.
LicenseIdentification license_id_; // NOLINT
// Provider client token sent back in the license.
std::string provider_client_token_; // NOLINT
// Signing_key should be 512 bits in length to be split into two
// (server || client) HMAC-SHA256 keys.
std::string signing_key_; // NOLINT
// System_id in keybox.
uint32_t keybox_system_id_; // NOLINT
// License counter associated with the |provider_client_token|.
uint32_t license_counter_; // NOLINT
};
struct WvPLVideoResolutionConstraint {
WvPLVideoResolutionConstraint() {
min_resolution_pixels_ = 0;
max_resolution_pixels_ = 0;
hdcp_ = HDCP_NONE;
}
void set_min_resolution_pixels(uint32_t pixels) {
min_resolution_pixels_ = pixels;
}
void set_max_resolution_pixels(uint32_t pixels) {
max_resolution_pixels_ = pixels;
}
void set_hdcp(HDCP hdcp_value) { hdcp_ = hdcp_value; }
HDCP hdcp() const { return hdcp_; }
uint32_t min_resolution_pixels() const { return min_resolution_pixels_; }
uint32_t max_resolution_pixels() const { return max_resolution_pixels_; }
// Minimum and maximum video resolutions in the range (height x width).
uint32_t min_resolution_pixels_;
uint32_t max_resolution_pixels_;
// Optional output protection requirements for this range. If not
// specified, the output protection in WvPLKey applies.
HDCP hdcp_;
};
struct WvPLOutputProtection {
WvPLOutputProtection() {
hdcp_ = HDCP_NONE;
secure_data_path_ = false;
security_level_ = SECURITY_LEVEL_UNDEFINED;
disable_analog_output_ = false;
disable_digital_output_ = false;
cgms_ = CGMS_NONE;
}
void set_hdcp(HDCP hdcp_value) { hdcp_ = hdcp_value; }
HDCP hdcp() const { return hdcp_; }
// Setting true indicates security_level is HW_SECURE_ALL, otherwise the
// default is false which maps to security_level of SW_SECURE_CRYPTO. This
// value is ignored if security_level is set directly.
void set_secure_data_path(bool secure_flag) {
secure_data_path_ = secure_flag;
}
bool secure_data_path() const { return secure_data_path_; }
// Setting security_level directly takes precedence over setting the
// |secure_data_path|. For most applications, there is no need to set the
// security_level directly. Using |secure_data_path| is sufficient.
void set_security_level(SecurityLevel level) { security_level_ = level; }
SecurityLevel security_level() const { return security_level_; }
// Set to true to disable analog output.
void set_disable_analog_output(bool flag) { disable_analog_output_ = flag; }
bool disable_analog_output() const { return disable_analog_output_; }
// Set to true to disable digital output.
void set_disable_digital_output(bool flag) { disable_digital_output_ = flag; }
bool disable_digital_output() const { return disable_digital_output_; }
// CGMS-A setting
void set_cgms(CGMS cgms_value) { cgms_ = cgms_value; }
CGMS cgms() const { return cgms_; }
// Indicates whether HDCP is required on digital outputs. Default is None.
HDCP hdcp_;
// Crypto operations and handling of the media must be performed within a
// hardware backed trusted environment. Default is false.
bool secure_data_path_;
// Security level robustness defined by Widevine. Default is UNDEFINED in
// which case secure_data_path_ is used. If secure_data_path_ is false,
// security_level_ is set to SW_SECURE_CRYPTO. If secure_data_path_ is
// true, security_level_ is set to HW_SECURE_ALL;
SecurityLevel security_level_;
// Set to disable analog output.
bool disable_analog_output_;
// Set to disable digital output.
bool disable_digital_output_;
// CGMS-A analog output.
CGMS cgms_;
};
struct WvPLKey {
WvPLKey() {}
// |key_id| must be specified in bytes.
void set_key_id(const std::string& key_id) { key_id_ = key_id; }
const std::string& key_id() const { return key_id_; }
// |key_bytes| must be specified in bytes.
void set_key_bytes(const std::string& key_bytes) { key_bytes_ = key_bytes; }
const std::string& key_bytes() const { return key_bytes_; }
void set_output_protection(const WvPLOutputProtection& out_prot) {
output_protection_ = out_prot;
}
void set_requested_output_protection(const WvPLOutputProtection& out_prot) {
requested_output_protection_ = out_prot;
}
const WvPLOutputProtection& output_protection() const {
return output_protection_;
}
const WvPLOutputProtection& requested_output_protection() const {
return requested_output_protection_;
}
WvPLOutputProtection* mutable_output_protection() {
return &output_protection_;
}
WvPLOutputProtection* mutable_requested_output_protection() {
return &requested_output_protection_;
}
const std::vector<WvPLVideoResolutionConstraint>
video_resolution_constraints() const {
return video_resolution_constraints_;
}
void AddVideoResolutionConstraint(
const WvPLVideoResolutionConstraint& constraint) {
video_resolution_constraints_.push_back(constraint);
}
void set_track_type(const TrackType track_type) { track_type_ = track_type; }
TrackType track_type() const { return track_type_; }
void set_key_type(const KeyType key_type) { key_type_ = key_type; }
KeyType key_type() const { return key_type_; }
std::string key_id_;
std::string key_bytes_;
WvPLOutputProtection output_protection_;
WvPLOutputProtection requested_output_protection_;
// If the video resolution of the content being decrypted/decoded falls
// within one of the specified ranges, the optional output protections may
// be applied.
std::vector<WvPLVideoResolutionConstraint> video_resolution_constraints_;
TrackType track_type_ = TRACK_TYPE_UNSPECIFIED;
KeyType key_type_ = CONTENT;
};
struct WvPLDeviceInfo {
WvPLDeviceInfo() {
security_level_ = DEVICE_LEVEL_UNSPECIFIED;
system_id_ = 0;
test_device_ = false;
}
void set_system_id(uint32_t system_id) { system_id_ = system_id; }
uint32_t system_id() const { return system_id_; }
void set_soc(const std::string& soc) { soc_ = soc; }
const std::string& soc() const { return soc_; }
void set_manufacturer(const std::string& manufacturer) {
manufacturer_ = manufacturer;
}
const std::string& manufacturer() const { return manufacturer_; }
void set_model(const std::string& model) { model_ = model; }
const std::string& model() const { return model_; }
void set_device_type(const std::string& device_type) {
device_type_ = device_type;
}
const std::string& device_type() const { return device_type_; }
void set_security_level(DeviceSecurityLevel level) {
security_level_ = level;
}
DeviceSecurityLevel security_level() const { return security_level_; }
void set_test_device(bool test_device) { test_device_ = test_device; }
bool test_device() const { return test_device_; }
void set_serial_number(const std::string& serial_number) {
serial_number_ = serial_number;
}
const std::string& serial_number() const { return serial_number_; }
void set_service_id(const std::string& service_id) {
service_id_ = service_id;
}
const std::string& service_id() const { return service_id_; }
// Widevine system ID for this device family.
uint32_t system_id_;
// Name of system-on-a-chip.
std::string soc_;
// Name of manufacturer.
std::string manufacturer_;
// Manufacturer's model name.
std::string model_;
// Type of device (Phone, Tablet, TV, etc).
std::string device_type_;
// Widevine-defined security level.
DeviceSecurityLevel security_level_;
// True if the certificate corresponds to a test (non production) device.
bool test_device_;
// 128-bit globally unique serial number of certificate.
std::string serial_number_;
// Service identifier (web origin) for the provider which owns the
// certificate.
std::string service_id_;
};
// This message is used to hold usage data for each Widevine system Id.
struct WvPLLicenseStatusCounterData {
// Initialize members
WvPLLicenseStatusCounterData() : license_status_(0), status_count_(0) {}
uint32_t license_status_;
// Count of occurences of the above status;
uint32_t status_count_;
};
// This message is used to hold usage data for each device model.
struct WvPLDeviceModelCounterData {
std::string device_model_;
// Key is each status we returned associated with the above model;
std::map<uint32_t, WvPLLicenseStatusCounterData> status_map_;
};
// This message is used to hold usage data for each device make.
struct WvPLDeviceMakeCounterData {
std::string device_make_;
// Key is each model associated with this device make.
std::map<std::string, WvPLDeviceModelCounterData> model_map_;
};
// This message is used to hold usage data for each Widevine system Id.
struct WvPLSystemIdCounterData {
// Initialize members
WvPLSystemIdCounterData() : system_id_(0) {}
uint32_t system_id_;
// Key is each make we handled associated with the above system Id.
std::map<std::string, WvPLDeviceMakeCounterData> make_map_;
};
// This top level message contains aggregated usage data for license requests.
struct WvPLCounterData {
// Initialize members
WvPLCounterData() : start_time_utc_(0), end_time_utc_(0) {}
// Time of the first license in this structure, represented as seconds since
// Unix epoch.
time_t start_time_utc_;
// Time of the last license in this structure, represented as seconds since
// Unix epoch.
time_t end_time_utc_;
// Key is each system Id we handled.
std::map<uint32_t, WvPLSystemIdCounterData> system_id_map_;
};
struct WvPLSessionInit {
WvPLSessionInit()
: license_start_time_(0), override_provider_client_token_(false) {}
// Accessors
void set_session_id(const std::string& session_id) {
session_id_ = session_id;
}
std::string session_id() const { return session_id_; }
void set_purchase_id(const std::string& purchase_id) {
purchase_id_ = purchase_id;
}
std::string purchase_id() const { return purchase_id_; }
void set_master_signing_key(const std::string& master_signing_key) {
master_signing_key_ = master_signing_key;
}
std::string master_signing_key() const { return master_signing_key_; }
void set_license_start_time(const int64_t license_start_time) {
license_start_time_ = license_start_time;
}
int64_t license_start_time() const { return license_start_time_; }
void set_provider_client_token(const std::string& provider_client_token) {
provider_client_token_ = provider_client_token;
}
std::string provider_client_token() const { return provider_client_token_; }
void set_provider_session_token(const std::string& provider_session_token) {
provider_session_token_ = provider_session_token;
}
std::string provider_session_token() const { return provider_session_token_; }
void set_override_provider_client_token(bool override_provider_client_token) {
override_provider_client_token_ = override_provider_client_token;
}
bool override_provider_client_token() const {
return override_provider_client_token_;
}
// Identifier for the session.
std::string session_id_;
// Identifier for the purchased content.
std::string purchase_id_;
// Master signing key should be 128 bits in length.
std::string master_signing_key_;
// signing_key should be 512 bits in length to be split into two
// (server || client) HMAC-SHA256 keys.
std::string signing_key_;
// The reference time in UTC as calculated by the client clock.
int64_t license_start_time_;
// Client token for the session.
std::string provider_client_token_;
// Session token for the session.
std::string provider_session_token_;
// If false and the license request contains a |provider_client_token_|,
// use the token from that request even if |provider_client_token_| is
// specified.
// If true and the license request contains a |provider_client_token_|,
// use |provider_client_token_|.
bool override_provider_client_token_;
};
struct WvPLClientCapabilities {
WvPLClientCapabilities() {}
// Accessors
void set_client_token(bool client_token) { client_token_ = client_token; }
bool client_token() const { return client_token_; }
void set_session_token(bool session_token) { session_token_ = session_token; }
bool session_token() const { return session_token_; }
void set_video_resolution_constraints(bool video_resolution_constraints) {
video_resolution_constraints_ = video_resolution_constraints;
}
bool video_resolution_constraints() const {
return video_resolution_constraints_;
}
void set_max_hdcp_version(HDCP max_hdcp_version) {
max_hdcp_version_ = max_hdcp_version;
}
HDCP max_hdcp_version() const { return max_hdcp_version_; }
void set_oem_crypto_api_version(uint32_t oem_crypto_api_version) {
oem_crypto_api_version_ = oem_crypto_api_version;
}
uint32_t oem_crypto_api_version() const { return oem_crypto_api_version_; }
void set_anti_rollback_usage_table(bool anti_rollback_usage_table) {
anti_rollback_usage_table_ = anti_rollback_usage_table;
}
bool anti_rollback_usage_table() const { return anti_rollback_usage_table_; }
void set_srm_version(uint32_t srm_version) { srm_version_ = srm_version; }
uint32_t srm_version() const { return srm_version_; }
void set_can_update_srm(bool can_update_srm) {
can_update_srm_ = can_update_srm;
}
bool can_update_srm() const { return can_update_srm_; }
void add_supported_certificate_key_type(const CertificateKeyType key_type) {
supported_certificate_key_type_.push_back(key_type);
}
const std::list<CertificateKeyType> supported_certificate_key_type() const {
return supported_certificate_key_type_;
}
void set_analog_output_capabilities(
const AnalogOutputCapabilities analog_output_capabilities) {
analog_output_capabilities_ = analog_output_capabilities;
}
const AnalogOutputCapabilities analog_output_capabilities() const {
return analog_output_capabilities_;
}
void set_can_disable_analog_output(bool can_disable_analog_output) {
can_disable_analog_output_ = can_disable_analog_output;
}
bool can_disable_analog_output() const { return can_disable_analog_output_; }
// Member variables
// Client token generated by the content provider.
bool client_token_ = false;
// A token associated with the client session.
bool session_token_ = false;
// Video resolution constraints. If the video resolution of the
// content being decrypted/decoded falls within one of the specified ranges,
// the required_protections may be applied. Otherwise an error will be
// reported.
// NOTE: Use of this feature is not recommended, as it is only supported on
// a small number of platforms.
bool video_resolution_constraints_ = false;
// The max "High-bandwidth Digital Content Protection" (HDCP) version
// supported by the client.
HDCP max_hdcp_version_ = HDCP_NONE;
// The OEM Crypto API version supported by the client.
uint32_t oem_crypto_api_version_;
// Flag to indicate the key must only be used if the client
// supports anti rollback of the user table. Content provider can query the
// client capabilities to determine if the client support this feature.
bool anti_rollback_usage_table_ = false;
// The client shall report |srm_version| if available.
uint32_t srm_version_;
// A device may have SRM data, and report a version, but may not be capable
// of updating SRM data.
bool can_update_srm_ = false;
// A list of CertificateKeyTypes.
std::list<CertificateKeyType> supported_certificate_key_type_;
// Analog capabilities of the device.
AnalogOutputCapabilities analog_output_capabilities_ = ANALOG_OUTPUT_UNKNOWN;
// Indicates if the device can disable it's analog output.
bool can_disable_analog_output_ = false;
};
/**
* Represents the Client Identification information. In the License Proxy
* SDK, this structure is populated as a result of parsing the license
* request from the CDM. This struct is used by Proxy SDK.
*/
struct WvPLClientInfo {
WvPLClientInfo()
: max_hdcp_version_(HDCP_NONE),
oem_crypto_api_version_(0),
analog_output_capabilities_(ANALOG_OUTPUT_UNKNOWN),
can_disable_analog_output_(false) {}
// Accessors
void set_max_hdcp_version(HDCP max_hdcp_version) {
max_hdcp_version_ = max_hdcp_version;
}
HDCP max_hdcp_version() const { return max_hdcp_version_; }
void set_oem_crypto_api_version(uint32_t oem_crypto_api_version) {
oem_crypto_api_version_ = oem_crypto_api_version;
}
uint32_t oem_crypto_api_version() const { return oem_crypto_api_version_; }
void set_provider_client_token(const std::string& provider_client_token) {
provider_client_token_ = provider_client_token;
}
const std::string& provider_client_token() const {
return provider_client_token_;
}
void set_cdm_version(const std::string& cdm_version) {
cdm_version_ = cdm_version;
}
const std::string& cdm_version() const { return cdm_version_; }
void set_name_value(const std::string& name, const std::string& value) {
names_values_.insert(std::make_pair(name, value));
}
const std::map<std::string, std::string>& names_values() {
return names_values_;
}
void set_analog_output_capabilities(AnalogOutputCapabilities capability) {
analog_output_capabilities_ = capability;
}
const AnalogOutputCapabilities analog_output_capabilities() const {
return analog_output_capabilities_;
}
void set_can_disable_analog_output(bool can_disable) {
can_disable_analog_output_ = can_disable;
}
bool can_disable_analog_output() const { return can_disable_analog_output_; }
const WvPLClientCapabilities client_capabilities() const {
return client_capabilities_;
}
void set_client_capabilities(
const WvPLClientCapabilities& client_capabilities) {
client_capabilities_ = client_capabilities;
}
// Member variables
// The max "High-bandwidth Digital Content Protection" (HDCP) version
// supported by the device.
HDCP max_hdcp_version_;
// The OEM Crypto API version supported by the client.
uint32_t oem_crypto_api_version_;
// The client CDM version.
std::string cdm_version_;
// The client token generated by the content provider.
std::string provider_client_token_;
// Map of other fields specified as name-value pairs representing the
// client.
std::map<std::string, std::string> names_values_;
// Analog capabilities of the device.
AnalogOutputCapabilities analog_output_capabilities_;
// Indicates if the device can disable it's analog output.
bool can_disable_analog_output_;
// Capabilities which not all clients may support. Used for the license
// exchange protocol only.
WvPLClientCapabilities client_capabilities_;
};
struct WvPLEntitledKey {
WvPLEntitledKey() {}
// Accessors.
void set_entitlement_key_id(const std::string& entitlement_key_id) {
entitlement_key_id_ = entitlement_key_id;
}
const std::string& entitlement_key_id() const { return entitlement_key_id_; }
void set_key_id(const std::string& key_id) { key_id_ = key_id; }
const std::string& key_id() const { return key_id_; }
void set_key_bytes(const std::string& key_bytes) { key_bytes_ = key_bytes; }
const std::string& key_bytes() const { return key_bytes_; }
void set_entitlement_key_iv(const std::string& entitlement_key_iv) {
entitlement_key_iv_ = entitlement_key_iv;
}
const std::string& entitlement_key_iv() const { return entitlement_key_iv_; }
void set_entitlement_key_size_bytes(uint32_t entitlement_key_size_bytes) {
entitlement_key_size_bytes_ = entitlement_key_size_bytes;
}
uint32_t entitlement_key_size_bytes() const {
return entitlement_key_size_bytes_;
}
// Member variables.
// ID of entitlement key used for wrapping |key|.
std::string entitlement_key_id_;
// ID of the entitled key.
std::string key_id_;
// Wrapped key.
std::string key_bytes_;
// IV used for wrapping |key|.
std::string entitlement_key_iv_;
// Size of entitlement key used for wrapping |key|.
uint32_t entitlement_key_size_bytes_ = 32;
};
/*
* Defines the 'pssh' box for Common Encryption (CENC).
*/
struct WvPLWidevinePsshData {
WvPLWidevinePsshData() {}
// Accessors
void set_content_id(const std::string& content_id) {
content_id_ = content_id;
}
const std::string content_id() const { return content_id_; }
void set_key_id(const std::string& key_id) { key_ids_.push_back(key_id); }
const std::list<std::string>& key_ids() const { return key_ids_; }
void add_entitled_key(const WvPLEntitledKey& entitled_key) {
entitled_keys_.push_back(entitled_key);
}
const std::list<WvPLEntitledKey>& entitled_keys() const {
return entitled_keys_;
}
// Member variables
// A list of key identifiers, for entitlement keys or content keys.
std::list<std::string> key_ids_;
// The content identifier.
std::string content_id_;
// A list of wrapped keys.
std::list<WvPLEntitledKey> entitled_keys_;
};
} // namespace wv_pl_sdk
} // namespace widevine_server
#endif // SDK_EXTERNAL_COMMON_WVPL_WVPL_TYPES_H_