Add a function named has_encrypted_client_id() check.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=231629247
This commit is contained in:
Fang Yu
2019-01-30 11:07:03 -08:00
parent f234dd036d
commit 1a4cad05a2
23 changed files with 572 additions and 166 deletions

View File

@@ -37,7 +37,7 @@ git_repository(
git_repository(
name = "googletest_repo",
commit = "9816b96a6ddc0430671693df90192bbee57108b6", # 2017-08-11
commit = "b6cd405286ed8635ece71c72f118e659f4ade3fb", # 2019-01-04
remote = "https://github.com/google/googletest.git",
)

View File

@@ -9,6 +9,7 @@
#ifndef COMMON_STATUS_H_
#define COMMON_STATUS_H_
#include <iosfwd>
#include <string>
#include "util/error_space.h"

View File

@@ -9,8 +9,10 @@
#include "common/string_util.h"
#include <bitset>
#include <cstddef>
#include <sstream>
#include <string>
#include "common/status.h"
namespace widevine {

View File

@@ -42,7 +42,6 @@ cc_library(
"//util/endian",
"//util/random:global_id",
"//common:aes_cbc_util",
"//common:certificate_type",
"//common:client_cert",
"//common:crypto_util",
"//common:device_status_list",
@@ -69,9 +68,9 @@ cc_library(
cc_library(
name = "sdk",
srcs = [
"generate_error_response.cc",
"key_control_block.cc",
"parse_content_id.cc",
"generate_error_response.cc",
],
hdrs = [
"generate_error_response.h",
@@ -81,32 +80,18 @@ cc_library(
],
deps = [
"//base",
"//strings",
"@abseil_repo//absl/strings",
"@abseil_repo//absl/synchronization",
"//external:openssl",
"//util/endian",
"//util/gtl:map_util",
"//common:client_cert",
"//common:crypto_util",
"//common:device_status_list",
"//common:error_space",
"//common:random_util",
"//common:rsa_key",
"//common:drm_root_certificate",
"//util:error_space",
"//common:drm_service_certificate",
"//common:signing_key_util",
"//common:error_space",
"//common:status",
"//common:wvm_token_handler",
"//sdk/external/common/wvpl:wvpl_types",
"//protos/public:client_identification_proto",
"//protos/public:device_certificate_status_proto",
"//protos/public:drm_certificate_proto",
"//protos/public:errors_proto",
"//protos/public:license_protocol_proto",
"//protos/public:license_server_sdk_proto",
"//protos/public:provisioned_device_info_proto",
"//protos/public:signed_drm_certificate_proto",
"//protos/public:widevine_pssh_proto",
],
)

View File

@@ -12,7 +12,6 @@
#include "absl/strings/escaping.h"
#include "common/drm_service_certificate.h"
#include "common/error_space.h"
#include "sdk/external/common/wvpl/wvpl_types.h"
#include "protos/public/errors.pb.h"
#include "protos/public/license_protocol.pb.h"

View File

@@ -34,6 +34,12 @@ void DevicesCanHandleOEMCryptoVersionInKCB(const std::string& system_ids) {
devices_can_handle_oemcrypto_version_.end());
}
void KeyIdsForFullDecryptPathTestingInKCB(const std::string& key_ids) {
for (absl::string_view key_id : absl::StrSplit(key_ids, ',')) {
keyids_for_full_decrypt_path_testing_.insert(std::string(key_id));
}
}
bool Generate(
const License::KeyContainer& key_container, uint32_t duration, uint32_t nonce,
const ClientIdentification::ClientCapabilities& client_capabilities,
@@ -136,6 +142,10 @@ bool Generate(
key_container.required_protection().disable_analog_output()) {
control_bits |= kKeyControlFlagsDisableAnalogOutput;
}
if (keyids_for_full_decrypt_path_testing_.find(key_container.id()) !=
keyids_for_full_decrypt_path_testing_.end()) {
control_bits |= kKeyControlFlagsAllowHashVerification;
}
break;
}
case License::KeyContainer::OPERATOR_SESSION: {

View File

@@ -46,6 +46,7 @@ const uint32_t kKeyControlFlagsHdcp_V2_2 = 0x00000800;
const uint32_t kKeyControlFlagsLocalDisplayOnly = 0x00001E00;
const uint32_t kKeyControlFlagsDisableAnalogOutput = 0x00200000;
const uint32_t kKeyControlFlagsSrmVersionRequired = 0x00400000;
const uint32_t kKeyControlFlagsAllowHashVerification = 0x01000000;
// Generate the key control block structuure. |key_control_block| must not be
// null and is used to hold the key control data. Returns true if successful,
@@ -62,10 +63,17 @@ bool Generate(
// the Key Control Block. Otherwise, only 'kctl' or 'kc09' is returned in KCB.
void DevicesCanHandleOEMCryptoVersionInKCB(const std::string& system_ids);
// Specify a comma separated list of key Ids that can support 'full decrypt path
// testing' as specified in go/wvdelta15.
void KeyIdsForFullDecryptPathTestingInKCB(const std::string& key_ids);
// Contains the list of system_id values that can support reflecting OEMCrypto
// version in KCB.
static std::vector<uint32_t> devices_can_handle_oemcrypto_version_;
// KeyIds that are permitted for full decrypt path testing.
static std::set<std::string> keyids_for_full_decrypt_path_testing_;
} // namespace key_control_block
} // namespace widevine
#endif // LICENSE_SERVER_SDK_INTERNAL_KEY_CONTROL_BLOCK_H__

View File

@@ -798,5 +798,39 @@ TEST(KeyControlBlockTest, test_OEMCrypto_Version) {
}
}
TEST(KeyControlBlockTest, test_allow_hash_verification_bit) {
KeyIdsForFullDecryptPathTestingInKCB("TEST_KEY_ID");
uint32_t duration = 0;
uint32_t nonce = 0;
bool has_provider_session_token = true;
uint32_t system_id = 0;
ClientIdentification::ClientCapabilities client_capabilities;
client_capabilities.set_session_token(false);
SessionInit session_init;
License::KeyContainer key_container;
key_container.set_type(License::KeyContainer::CONTENT);
key_container.set_id("TEST_KEY_ID");
// KCB when KeyID for 'full decrypt path testing' matches.
const std::string expected_kcb("6b63746c000000000000000001000008");
ASSERT_TRUE(key_control_block::Generate(
key_container, duration, nonce, client_capabilities,
has_provider_session_token, &session_init, STREAMING, system_id,
key_container.mutable_key_control()->mutable_key_control_block()));
EXPECT_EQ(expected_kcb, absl::BytesToHexString(
key_container.key_control().key_control_block()));
key_container.set_id("KEY_ID_FDP_UNSET");
ASSERT_TRUE(key_control_block::Generate(
key_container, duration, nonce, client_capabilities,
has_provider_session_token, &session_init, STREAMING, system_id,
key_container.mutable_key_control()->mutable_key_control_block()));
EXPECT_NE(expected_kcb, absl::BytesToHexString(
key_container.key_control().key_control_block()));
EXPECT_EQ(
"6b63746c000000000000000000000008",
absl::BytesToHexString(key_container.key_control().key_control_block()));
}
} // namespace key_control_block
} // namespace widevine

View File

@@ -64,9 +64,10 @@ Status ParseCencId(const LicenseRequest::ContentIdentification& content_id,
ContentInfo* content_info) {
content_info->set_init_data_type(
LicenseRequest::ContentIdentification::InitData::CENC);
for (int idx = 0; idx < content_id.cenc_id_deprecated().pssh_size(); ++idx) {
for (int idx = 0; idx < content_id.widevine_pssh_data().pssh_data_size();
++idx) {
Status status =
AddWidevinePsshInfo(content_id.cenc_id_deprecated().pssh(idx),
AddWidevinePsshInfo(content_id.widevine_pssh_data().pssh_data(idx),
content_info->add_content_info_entry());
if (!status.ok()) return status;
}
@@ -214,11 +215,10 @@ Status ParseContentId(const LicenseRequest::ContentIdentification& content_id,
content_info->Clear();
switch (content_id.content_id_variant_case()) {
case LicenseRequest_ContentIdentification::kCencIdDeprecated:
case LicenseRequest_ContentIdentification::kWidevinePsshData:
return ParseCencId(content_id, content_info);
case LicenseRequest_ContentIdentification::kWebmIdDeprecated:
return AddWebmKeyId(content_id.webm_id_deprecated().header(),
content_info);
case LicenseRequest_ContentIdentification::kWebmKeyId:
return AddWebmKeyId(content_id.webm_key_id().header(), content_info);
case LicenseRequest_ContentIdentification::kInitData:
return ParseInitData(content_id, content_info);
default:

View File

@@ -93,7 +93,7 @@ const uint8_t kNonPsshBox[] = {
void MakeDeprecatedWebmContentId(
const std::string& key_id, LicenseRequest::ContentIdentification* content_id) {
content_id->Clear();
content_id->mutable_webm_id_deprecated()->set_header(key_id);
content_id->mutable_webm_key_id()->set_header(key_id);
}
void MakeInitDataWebmContentId(
@@ -120,7 +120,7 @@ void MakeDeprecatedCencContentId(
const std::string& pssh_data,
LicenseRequest::ContentIdentification* content_id) {
content_id->Clear();
*content_id->mutable_cenc_id_deprecated()->add_pssh() = pssh_data;
*content_id->mutable_widevine_pssh_data()->add_pssh_data() = pssh_data;
}
void MakeInitDataCencContentId(

View File

@@ -8,9 +8,9 @@
#include "license_server_sdk/internal/session_impl.h"
#include <stddef.h>
#include <string.h>
#include <time.h>
#include <cstddef>
#include <cstring>
#include <ctime>
#include <list>
#include <memory>
#include <string>
@@ -440,12 +440,12 @@ Status SessionImpl::GetRequestId(std::string* request_id) const {
*request_id = content_id.init_data().request_id();
return OkStatus();
}
if (content_id.has_cenc_id_deprecated()) {
*request_id = content_id.cenc_id_deprecated().request_id();
if (content_id.has_widevine_pssh_data()) {
*request_id = content_id.widevine_pssh_data().request_id();
return OkStatus();
}
if (content_id.has_webm_id_deprecated()) {
*request_id = content_id.webm_id_deprecated().request_id();
if (content_id.has_webm_key_id()) {
*request_id = content_id.webm_key_id().request_id();
return OkStatus();
}
return Status(error_space, INVALID_CONTENT_ID_TYPE,
@@ -464,12 +464,12 @@ Status SessionImpl::GetLicenseType(LicenseType* license_type) const {
*license_type = content_id.init_data().license_type();
return OkStatus();
}
if (content_id.has_cenc_id_deprecated()) {
*license_type = content_id.cenc_id_deprecated().license_type();
if (content_id.has_widevine_pssh_data()) {
*license_type = content_id.widevine_pssh_data().license_type();
return OkStatus();
}
if (content_id.has_webm_id_deprecated()) {
*license_type = content_id.webm_id_deprecated().license_type();
if (content_id.has_webm_key_id()) {
*license_type = content_id.webm_key_id().license_type();
return OkStatus();
}
if (content_id.has_existing_license()) {

View File

@@ -36,7 +36,7 @@ class SessionUsage;
const uint32_t kMajorVersion = 4;
const uint32_t kMinorVersion = 5;
const uint32_t kRelease = 1;
const uint32_t kRelease = 2;
const uint32_t kMasterSigningKeySizeBytes = 16;
const uint32_t kSigningKeySizeBytes = 64;

View File

@@ -408,7 +408,7 @@ const char kGoodVmpData[] =
"c68c3b167b257c4a64afb2fbe7eb66544d92480ec595d1c025b335b1fba7a2a49c884900"
"c2fd7a4d5a9d820a4a4fd98624e02938195bf312d05b";
class MockCDPush {};
class MockSrm {};
} // anonymous namespace
class MockSessionImpl : public SessionImpl {
@@ -667,19 +667,19 @@ class SessionTest : public ::testing::Test {
client_capabilities;
if (init_data_type ==
LicenseRequest::ContentIdentification::InitData::WEBM) {
LicenseRequest::ContentIdentification::WebmDeprecated* webm_id =
request.mutable_content_id()->mutable_webm_id_deprecated();
LicenseRequest::ContentIdentification::WebmKeyId* webm_id =
request.mutable_content_id()->mutable_webm_key_id();
webm_id->set_header("0123456789ABCDEF");
webm_id->set_license_type(license_type);
webm_id->set_request_id("myCoolRequest, Dude!");
} else {
LicenseRequest::ContentIdentification::CencDeprecated* cenc_id =
request.mutable_content_id()->mutable_cenc_id_deprecated();
LicenseRequest::ContentIdentification::WidevinePsshData* cenc_id =
request.mutable_content_id()->mutable_widevine_pssh_data();
widevine::WidevinePsshData wv_pssh;
wv_pssh.set_protection_scheme(kProtectionScheme);
std::string pssh_string;
wv_pssh.SerializeToString(&pssh_string);
cenc_id->add_pssh(pssh_string);
cenc_id->add_pssh_data(pssh_string);
cenc_id->set_license_type(license_type);
cenc_id->set_request_id("myCool-CENC-Request, Dude!");
}
@@ -731,12 +731,11 @@ class SessionTest : public ::testing::Test {
*request.mutable_client_id()->mutable_client_capabilities() =
client_capabilities;
request.mutable_content_id()->mutable_webm_id_deprecated()->set_header(
request.mutable_content_id()->mutable_webm_key_id()->set_header(
"0123456789ABCDEF");
request.mutable_content_id()
->mutable_webm_id_deprecated()
->set_license_type(STREAMING);
request.mutable_content_id()->mutable_webm_id_deprecated()->set_request_id(
request.mutable_content_id()->mutable_webm_key_id()->set_license_type(
STREAMING);
request.mutable_content_id()->mutable_webm_key_id()->set_request_id(
"myCoolRequest, Dude!");
if (request_type != LicenseRequest::NEW) {
request.mutable_content_id()
@@ -777,12 +776,11 @@ class SessionTest : public ::testing::Test {
request.mutable_client_id()->set_token(GenerateSignedDrmCertificate(
kValidSystemId, kValidSerialNumber, false));
request.mutable_content_id()->mutable_webm_id_deprecated()->set_header(
request.mutable_content_id()->mutable_webm_key_id()->set_header(
"0123456789ABCDEF");
request.mutable_content_id()
->mutable_webm_id_deprecated()
->set_license_type(STREAMING);
request.mutable_content_id()->mutable_webm_id_deprecated()->set_request_id(
request.mutable_content_id()->mutable_webm_key_id()->set_license_type(
STREAMING);
request.mutable_content_id()->mutable_webm_key_id()->set_request_id(
"myCoolRequest, Dude!");
request.set_type(LicenseRequest::NEW);
request.set_request_time(time(nullptr));
@@ -804,7 +802,7 @@ class SessionTest : public ::testing::Test {
const ClientIdentification::ClientCapabilities& client_capabilities,
const LicenseRequest::ContentIdentification::InitData::InitDataType
init_data_type,
MockCDPush* cdpush, License* license) {
MockSrm* srm, License* license) {
// Parse LicenseRequest from request_msg for comparison
// the one returned from SessionImpl::Create().
SignedMessage signed_request;
@@ -1017,7 +1015,7 @@ class SessionTest : public ::testing::Test {
init_data_type) {
ValidateBasicRequestResponse(request_msg, client_capabilities,
init_data_type,
/* cdpush= */ nullptr,
/* srm= */ nullptr,
/* license= */ nullptr);
}
@@ -1720,11 +1718,11 @@ TEST_F(SessionTest, BasicRequestDrmCertificateResponseEmptyToken) {
request.mutable_client_id()->set_type(
ClientIdentification::DRM_DEVICE_CERTIFICATE);
request.mutable_client_id()->set_token("invalid");
request.mutable_content_id()->mutable_webm_id_deprecated()->set_header(
request.mutable_content_id()->mutable_webm_key_id()->set_header(
"0123456789ABCDEF");
request.mutable_content_id()->mutable_webm_id_deprecated()->set_license_type(
request.mutable_content_id()->mutable_webm_key_id()->set_license_type(
STREAMING);
request.mutable_content_id()->mutable_webm_id_deprecated()->set_request_id(
request.mutable_content_id()->mutable_webm_key_id()->set_request_id(
"myInvalidRequest, Dude!");
request.set_type(LicenseRequest::NEW);
request.set_request_time(time(nullptr));
@@ -2155,7 +2153,7 @@ TEST_P(SessionTestRenewal, LicenseRenewalWithSerialNumber) {
kValidSessionUsage, false);
}
INSTANTIATE_TEST_CASE_P(SystemIdVariations, SessionTestRenewal,
INSTANTIATE_TEST_SUITE_P(SystemIdVariations, SessionTestRenewal,
::testing::Bool());
TEST_F(SessionTest, InvalidRenewalKeySigningKey_2_0) {
@@ -2550,11 +2548,11 @@ TEST_F(SessionTest, EncryptedClientIdentification) {
GenerateSignedDrmCertificate(kValidSystemId, kValidSerialNumber, false));
EncryptClientIdentification(client_id, serial_number, provider_id,
request.mutable_encrypted_client_id());
request.mutable_content_id()->mutable_webm_id_deprecated()->set_header(
request.mutable_content_id()->mutable_webm_key_id()->set_header(
"0123456789ABCDEF");
request.mutable_content_id()->mutable_webm_id_deprecated()->set_license_type(
request.mutable_content_id()->mutable_webm_key_id()->set_license_type(
STREAMING);
request.mutable_content_id()->mutable_webm_id_deprecated()->set_request_id(
request.mutable_content_id()->mutable_webm_key_id()->set_request_id(
"request id");
request.set_type(LicenseRequest::NEW);
request.set_request_time(54322);
@@ -3073,7 +3071,7 @@ TEST_F(SessionTest, GenerateDeviceStatusListRequest) {
}
INSTANTIATE_TEST_CASE_P(SessionVmpTests, SessionVmpTest,
INSTANTIATE_TEST_SUITE_P(SessionVmpTests, SessionVmpTest,
::testing::Values(PLATFORM_NO_VERIFICATION,
PLATFORM_UNVERIFIED,
PLATFORM_TAMPERED,

View File

@@ -89,6 +89,10 @@ cc_test(
"//testing:gunit",
"//testing:gunit_main",
"@abseil_repo//absl/memory",
"@abseil_repo//absl/strings",
"//common:certificate_type",
"//common:drm_root_certificate",
"//sdk/external/common/wvpl:wvpl_types",
"//protos/public:errors_proto",
],
)

View File

@@ -26,7 +26,9 @@ PlatformVerificationStatus WvPLCASProxySession::VerifyPlatform() {
WvPLCASProxySession::WvPLCASProxySession(
const widevine::DrmRootCertificate* drm_root_certificate,
const std::string& cas_license_request_from_cdm)
: WvPLSDKSession(drm_root_certificate) {}
: WvPLSDKSession(drm_root_certificate) {
license_request_from_cdm_ = cas_license_request_from_cdm;
}
} // namespace wv_pl_sdk
} // namespace widevine_server

View File

@@ -11,7 +11,72 @@
#include "testing/gmock.h"
#include "testing/gunit.h"
#include "absl/memory/memory.h"
#include "absl/strings/escaping.h"
#include "common/certificate_type.h"
#include "common/drm_root_certificate.h"
#include "sdk/external/common/wvpl/wvpl_types.h"
#include "protos/public/errors.pb.h"
using widevine::DrmRootCertificate;
using widevine::kCertificateTypeTesting;
using widevine::SIGNED_MESSAGE_PARSE_ERROR;
namespace error = widevine::error;
namespace {
const char kValidRequestFromCdm[] =
"080712b90b0a840b080112ed090aae02080212108b8832fb7921b3e65419c6112f96d1"
"ce18e4edd4e105228e023082010a0282010100a729e70e43515708819fe6c62f9fc26e"
"a9f2300bd5cca79131b46997cc2822a8479a58ea287b7dceada6b77290cd0df3f7a98b"
"d4e91907631bfc4065afe93b08f95a5799f7391252de6a3d0a0e502dc116c0e0853c87"
"5e5ebff843858c322f2c06017d423981a7a41070ff8eae0c2ac135491187eb227907b1"
"185ecb76cd3f26eb0259a3e6c177c35ade2c07aa243d29599e251a6ab4dbb9bea00112"
"7bd39765bd40a1bb23b883b10ab829adde17311b90295059570936f0ee5ec6bdaba0be"
"07adbff30505537c67f1004daf469e6d760024f6f07095687fde35a62651b504beeaca"
"79282ce83001a914fdd9eface7e6d15959abee536b3c4cb53e573b39128d0203010001"
"2899201280023231afb3b643ea7db3095fdca3fe8df49e299d2b19fe9da7ab5f286ef2"
"17a08226bd0d530e9683fbb78edecca7d8bc3f1f9ac03a53a8d48029c0f490a6af301b"
"da27316e5920409a5a889acba49539d1d92c0b784b181da114f3bb45edbc7bba7cddfa"
"6e599500e92f8c0dd11ecebebb80fec73273d5c620bf30b30c0be1a90f1b86ea913497"
"39d961b589ce1b1b83d31e135e489b752a32431ad1bd6e8b6986dbd0c98073872b5349"
"11fc8ebfa528c62f6969b6d4b5079a640b02fa5989cccac708d4130e4686020f8b50f9"
"ea38f82424293555f82fc920ad33f41398b532fe01e28b50f76d35349835328714969b"
"ab67f68eb3cc30aac5d271fff3e1b1c9621ab6050ab00208011210084d60bc65937db6"
"ac7f992b41ecf5f218a2d38a8c05228e023082010a0282010100991b357bb714decac1"
"e70eaa36d1d0834df24a3d10369f90a22734a3ad4aebccfc2432bdd6dcd1ffd75699ba"
"5608c4457972d27c47abcff8c88cd9900938260b8c85795327b2aef3a1db27e8b96203"
"9284d602c6a74c6a143a67be64a16a1c8f44fafadac242ceb6d8ade9c4d4542ebd3ee9"
"d2a0a71eb7a4ccf916e02f26793b0c13a4921c3eed49c5c96cd455598ede040ce472b0"
"15a9af3cda82c49792aa7f6bbfbf4667293b44ec7429c39a038911ce1fe462c35e95c2"
"64d363343c3adb944fa2aabdba0fb61c402797585f3dfb796f6ce1dcf3b79c9887be98"
"1470ecbcb048e59e564fc3ad2c4b860f70aa468fb66c4a2847eec755ade89bd6225740"
"c9a502030100012899203001128003212de141c13057c1987218dd7fbc2dc9f84c82f9"
"1f5b163d0370c7069387c70c90c3060f0504573c6e0bd3acb984fc3ab7b221a77d3733"
"324d670a9a5eea64691d5666a9b67dd367803cd5753bd75ea7239bec0c008297695771"
"ce203c60898d4f264ad55d3d01c96f66d6fb6c53d1928a60ad040d7d48e9c83d6849c2"
"48e45c0f95bbb8cd0b1feee4458c5c60ab0d52e1fb0f8ee98766af9cf93307578657e8"
"00f1a4ed3f6a00e8951b2158f45cfcc2f7e5e5cc3d7f04ea2be34aa8dd49ebd78c618c"
"1404e308257e502aac8df00d52a8985301bfe5e6e784d77b0bc52c935a8b183fb5afed"
"25a5855a77fcf2715c907611624a58b037d819857bab926bee4d560277089efb070fb3"
"f5385d1dde1e486d8f32d253de8692e3098e35b3192647e79544cf0fb28b362133e942"
"97781cf3f68960531667ee74e7026bd72137eb1ddd057834cf1dabe8d7069f88acb4b7"
"a402470f2801264bb49c3bfee24fc640a46374d6c10bc7d2b960792d11da5086ab8ccf"
"f46180c243c395d22f1a9e4f6b021a130a0c636f6d70616e795f6e616d651203777777"
"1a110a0a6d6f64656c5f6e616d6512037777771a200a0c70726f647563745f6e616d65"
"12105769646576696e6543617354657374731a260a116172636869746563747572655f"
"6e616d6512116172636869746563747572655f6e616d651a1a0a0b6465766963655f6e"
"616d65120b6465766963655f6e616d653202280e12200a1e0a1c1a0d7769646576696e"
"655f746573742209436173547346616b655802180120e4edd4e105301538d3a2fbfe02"
"1a80020570d7809a297c640bc56234cfea3687e747dcbf8e6cc326de6a1102fecc43ec"
"674c02e5c8d31109a1ac7f2cb52f44a6b2b410a6d2632bb841ead6437be510efa7c8a5"
"02de1e734e057b9ac65eec6361afaf3b71f074ff37428580067d856d4bfbecef170d11"
"d5cb631bcf31193a66156b06a16119d0d19381cd57cacb0aeb6b6e5b3e427c8117be13"
"7b662332a1a80f48e599675325b5b8afd4010f7850ba332fa78eaf0ddeef7086890cce"
"194631e3d205cb459a7e1ff11b54791ef394b74fb8a729d0104b00e17b9e05c5d42fac"
"923f98d43aedc70ab0733039eb22f35c6961e4587085a14c4a9ace1db00508843e79ee"
"ba68321b559fbdfdf04c88813cdd";
} // namespace
namespace widevine_server {
namespace wv_pl_sdk {
@@ -21,9 +86,8 @@ namespace wv_pl_sdk {
class WvPLCASProxySessionTest : public testing::Test {
protected:
void SetUp() override {
// TODO(user): Fill out with valid CAS License request.
const std::string request = "";
wvpl_cas_proxy_session_ = new WvPLCASProxySession(nullptr, request);
ASSERT_OK(DrmRootCertificate::CreateByType(kCertificateTypeTesting,
&drm_root_cert_));
}
bool IsChromeCDM() { return wvpl_cas_proxy_session_->IsChromeCDM(); }
@@ -32,24 +96,62 @@ class WvPLCASProxySessionTest : public testing::Test {
return wvpl_cas_proxy_session_->VerifyPlatform();
}
void Create(const std::string& request) {
wvpl_cas_proxy_session_ = new WvPLCASProxySession(
drm_root_cert_.get(), absl::HexStringToBytes(request));
}
WvPLStatus Parse() { return wvpl_cas_proxy_session_->ParseLicenseRequest(); }
~WvPLCASProxySessionTest() override { delete wvpl_cas_proxy_session_; }
private:
WvPLCASProxySession* wvpl_cas_proxy_session_;
std::unique_ptr<DrmRootCertificate> drm_root_cert_;
};
TEST_F(WvPLCASProxySessionTest, GetVersionString) {
Create(kValidRequestFromCdm);
std::string version = std::to_string(kMajorVersion) + "." +
std::to_string(kMinorVersion) + "." +
std::to_string(kRelease);
EXPECT_EQ(version, WvPLCASProxySession::GetVersionString());
}
TEST_F(WvPLCASProxySessionTest, IsChromeCDM) { EXPECT_FALSE(IsChromeCDM()); }
TEST_F(WvPLCASProxySessionTest, IsChromeCDM) {
Create(kValidRequestFromCdm);
EXPECT_FALSE(IsChromeCDM());
}
TEST_F(WvPLCASProxySessionTest, VerifyPlatform) {
Create(kValidRequestFromCdm);
EXPECT_EQ(PLATFORM_NO_VERIFICATION, VerifyPlatform());
}
TEST_F(WvPLCASProxySessionTest, ParseValidLicenseRequest) {
Create(kValidRequestFromCdm);
WvPLStatus status = Parse();
EXPECT_TRUE(status.ok());
WvPLClientInfo client_info;
status = wvpl_cas_proxy_session_->GetClientInfo(&client_info);
EXPECT_TRUE(status.ok());
std::map<std::string, std::string> names_values = client_info.names_values();
EXPECT_GT(names_values.size(), 0);
for (const auto name_value : names_values) {
}
}
TEST_F(WvPLCASProxySessionTest, ParseEmptyLicenseRequest) {
Create("");
WvPLStatus status = Parse();
EXPECT_EQ(SIGNED_MESSAGE_PARSE_ERROR, status.error_code());
}
TEST_F(WvPLCASProxySessionTest, ParseBadLicenseRequest) {
Create("289920300112ed090aae02080");
WvPLStatus status = Parse();
EXPECT_EQ(SIGNED_MESSAGE_PARSE_ERROR, status.error_code());
}
} // namespace wv_pl_sdk
} // namespace widevine_server

View File

@@ -280,13 +280,13 @@ enum ProtocolVersion {
message LicenseRequest {
message ContentIdentification {
message CencDeprecated {
repeated bytes pssh = 1;
message WidevinePsshData {
repeated bytes pssh_data = 1;
optional LicenseType license_type = 2;
optional bytes request_id = 3; // Opaque, client-specified.
}
message WebmDeprecated {
message WebmKeyId {
optional bytes header = 1;
optional LicenseType license_type = 2;
optional bytes request_id = 3; // Opaque, client-specified.
@@ -313,8 +313,8 @@ message LicenseRequest {
oneof content_id_variant {
// Exactly one of these must be present.
CencDeprecated cenc_id_deprecated = 1;
WebmDeprecated webm_id_deprecated = 2;
WidevinePsshData widevine_pssh_data = 1;
WebmKeyId webm_key_id = 2;
ExistingLicense existing_license = 3;
InitData init_data = 4;
}

View File

@@ -80,6 +80,7 @@ cc_library(
"//common:drm_service_certificate",
"//common:sha_util",
"//common:status",
"//common:vmp_checker",
"//license_server_sdk/internal:sdk",
"//protos/public:device_certificate_status_proto",
"//protos/public:errors_proto",
@@ -111,6 +112,7 @@ cc_library(
"//common:sha_util",
"//common:status",
"//common:verified_media_pipeline",
"//common:vmp_checker",
"//license_server_sdk/internal:sdk",
"//protos/public:client_identification_proto",
"//protos/public:device_certificate_status_proto",

View File

@@ -17,6 +17,7 @@
#include "common/error_space.h"
#include "common/sha_util.h"
#include "common/status.h"
#include "common/vmp_checker.h"
#include "license_server_sdk/internal/generate_error_response.h"
#include "protos/public/device_certificate_status.pb.h"
#include "protos/public/errors.pb.h"
@@ -32,6 +33,7 @@ using widevine::kCertificateTypeProduction;
using widevine::kCertificateTypeTesting;
using widevine::ProvisionedDeviceInfo;
using widevine::SignedDeviceCertificateStatusList;
using widevine::VmpChecker;
using widevine::crypto_util::EncryptAesCbc;
namespace error = widevine::error;
@@ -89,7 +91,8 @@ WvPLStatus WvPLSDKEnvironment::SetDrmServiceCertificate(
if (wvpl_status.ok()) {
is_service_certificate_loaded_ = true;
}
return wvpl_status;
return VmpChecker::Instance()->SelectCertificateType(
drm_root_certificate()->type());
}
bool WvPLSDKEnvironment::GenerateErrorResponse(

View File

@@ -127,7 +127,9 @@ class WvPLSDKEnvironment {
const widevine::ProvisionedDeviceInfo& provisioned_device_info);
static std::map<std::string, std::string>* GetConfigValue();
friend class WvPLSDKSession;
friend class WvPLProxySession;
friend class WvPLProxySessionTest;
friend class WvPLSessionTest;
};

View File

@@ -58,6 +58,58 @@ using widevine::WidevinePsshData;
namespace error = widevine::error;
namespace {
void CopyHdcpSrmRule(
widevine_server::wv_pl_sdk::HdcpSrmRule hdcp_srm_rule,
License::KeyContainer::OutputProtection* output_protection) {
DCHECK(output_protection);
if (output_protection == nullptr) {
return;
}
switch (hdcp_srm_rule) {
case widevine_server::wv_pl_sdk::HDCP_SRM_RULE_NONE:
output_protection->set_hdcp_srm_rule(
License::KeyContainer::OutputProtection::HDCP_SRM_RULE_NONE);
break;
case widevine_server::wv_pl_sdk::CURRENT_SRM:
output_protection->set_hdcp_srm_rule(
License::KeyContainer::OutputProtection::CURRENT_SRM);
break;
default:
break;
}
}
// Copy the |cgms_value| into the key container.
void CopyCGMS(widevine_server::wv_pl_sdk::CGMS cgms_value,
License::KeyContainer::OutputProtection* output_protection) {
DCHECK(output_protection);
if (output_protection == nullptr) {
return;
}
switch (cgms_value) {
case widevine_server::wv_pl_sdk::CGMS_NONE:
output_protection->set_cgms_flags(
License::KeyContainer::OutputProtection::CGMS_NONE);
break;
case widevine_server::wv_pl_sdk::COPY_FREE:
output_protection->set_cgms_flags(
License::KeyContainer::OutputProtection::COPY_FREE);
break;
case widevine_server::wv_pl_sdk::COPY_ONCE:
output_protection->set_cgms_flags(
License::KeyContainer::OutputProtection::COPY_ONCE);
break;
case widevine_server::wv_pl_sdk::COPY_NEVER:
output_protection->set_cgms_flags(
License::KeyContainer::OutputProtection::COPY_NEVER);
break;
default:
break;
}
}
} // namespace
namespace widevine_server {
namespace wv_pl_sdk {
namespace {
@@ -224,6 +276,10 @@ void WvPLSDKSession::CopySessionState(
if (session_state == nullptr) {
return;
}
if (!has_session_state_) {
// Do not populate SessionState protobuf if WvPLSessionState was not set.
return;
}
if (wvpl_session_state.license_counter() > 0) {
session_state->set_license_counter(wvpl_session_state.license_counter());
}
@@ -315,49 +371,64 @@ void WvPLSDKSession::CopyHDCP(
}
void WvPLSDKSession::CopyOutputProtection(
const WvPLKey& wvpl_key, License::KeyContainer* sdk_key_container) {
DCHECK(sdk_key_container);
if (!sdk_key_container) {
return;
}
const WvPLOutputProtection& wvpl_output_protection,
License::KeyContainer::OutputProtection* output_protection) {
// Transfer HDCP from required output protection value.
CopyHDCP(wvpl_key.output_protection().hdcp(),
sdk_key_container->mutable_required_protection());
CopyHDCP(wvpl_output_protection.hdcp(), output_protection);
CopySecurityLevel(wvpl_key.output_protection(), wvpl_key.track_type(),
sdk_key_container);
output_protection->set_disable_analog_output(
wvpl_output_protection.disable_analog_output());
sdk_key_container->mutable_required_protection()->set_disable_analog_output(
wvpl_key.output_protection().disable_analog_output());
sdk_key_container->mutable_required_protection()->set_disable_digital_output(
wvpl_key.output_protection().disable_digital_output());
if (wvpl_key.output_protection().disable_digital_output()) {
sdk_key_container->mutable_required_protection()->set_hdcp(
if (wvpl_output_protection.disable_digital_output()) {
output_protection->set_hdcp(
License::KeyContainer::OutputProtection::HDCP_NO_DIGITAL_OUTPUT);
}
// Transfer HDCP from requested output protection value.
CopyCGMS(wvpl_key.output_protection().cgms(),
sdk_key_container->mutable_required_protection());
if (wvpl_key.requested_output_protection().hdcp() != HDCP_NONE) {
CopyHDCP(wvpl_key.requested_output_protection().hdcp(),
sdk_key_container->mutable_requested_protection());
CopyCGMS(wvpl_output_protection.cgms(), output_protection);
CopyHdcpSrmRule(wvpl_output_protection.hdcp_srm_rule(), output_protection);
if (wvpl_output_protection.hdcp() != HDCP_NONE) {
CopyHDCP(wvpl_output_protection.hdcp(), output_protection);
}
if (wvpl_key.requested_output_protection().disable_analog_output()) {
sdk_key_container->mutable_requested_protection()
->set_disable_analog_output(
wvpl_key.requested_output_protection().disable_analog_output());
if (wvpl_output_protection.disable_analog_output()) {
output_protection->set_disable_analog_output(
wvpl_output_protection.disable_analog_output());
}
if (wvpl_key.requested_output_protection().disable_digital_output()) {
sdk_key_container->mutable_requested_protection()->set_hdcp(
if (wvpl_output_protection.disable_digital_output()) {
output_protection->set_hdcp(
License::KeyContainer::OutputProtection::HDCP_NO_DIGITAL_OUTPUT);
}
if (wvpl_key.requested_output_protection().cgms() != CGMS_NONE) {
CopyCGMS(wvpl_key.requested_output_protection().cgms(),
sdk_key_container->mutable_requested_protection());
if (wvpl_output_protection.cgms() != CGMS_NONE) {
CopyCGMS(wvpl_output_protection.cgms(), output_protection);
}
}
void WvPLSDKSession::CopyKey(const WvPLKey& wvpl_key,
License::KeyContainer* sdk_key_container) {
DCHECK(sdk_key_container);
if (!sdk_key_container) {
return;
}
sdk_key_container->set_id(wvpl_key.key_id());
sdk_key_container->set_key(wvpl_key.key_bytes());
switch (wvpl_key.key_type()) {
case CONTENT:
sdk_key_container->set_type(License::KeyContainer::CONTENT);
break;
case ENTITLEMENT:
sdk_key_container->set_type(License::KeyContainer::ENTITLEMENT);
break;
default:
break;
}
CopySecurityLevel(wvpl_key.output_protection(), wvpl_key.track_type(),
sdk_key_container);
CopyOutputProtection(wvpl_key.output_protection(),
sdk_key_container->mutable_required_protection());
CopyOutputProtection(wvpl_key.requested_output_protection(),
sdk_key_container->mutable_requested_protection());
// Transfer Video resultion constraints.
const std::vector<WvPLVideoResolutionConstraint>& video_constraints =
wvpl_key.video_resolution_constraints();
@@ -372,35 +443,6 @@ void WvPLSDKSession::CopyOutputProtection(
}
}
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) {
@@ -454,6 +496,8 @@ WvPLStatus WvPLSDKSession::ParseLicenseRequest() {
if (signed_message_request_from_cdm_ != nullptr) {
switch (signed_message_request_from_cdm_->type()) {
case SignedMessage::LICENSE_REQUEST:
// TODO(user): Add CAS enum(s) to message_type_ in wvpl_types.h.
case SignedMessage::CAS_LICENSE_REQUEST:
message_type_ = LICENSE_REQUEST;
DCHECK(signed_message_request_from_cdm_);
sdk_license_request_ = absl::make_unique<LicenseRequest>();
@@ -497,6 +541,7 @@ WvPLStatus WvPLSDKSession::ParseLicenseRequest() {
"Unable to decrypt EncryptedClientIdentification in "
"the license request");
}
has_encrypted_client_id_ = true;
has_client_id_ = true;
}
if (client_id_->has_token() &&
@@ -526,8 +571,20 @@ WvPLStatus WvPLSDKSession::ParseLicenseRequest() {
has_pssh_data_ = true;
}
}
request_type_ =
static_cast<LicenseRequestType>(sdk_license_request_->type());
switch (sdk_license_request_->type()) {
case LicenseRequest::NEW:
request_type_ = LicenseRequestType::NEW;
break;
case LicenseRequest::RENEWAL:
request_type_ = LicenseRequestType::RENEWAL;
break;
case LicenseRequest::RELEASE:
request_type_ = LicenseRequestType::RELEASE;
break;
default:
request_type_ = LicenseRequestType::REQUEST_TYPE_UNSPECIFIED;
break;
}
}
return OkStatus();
}
@@ -551,6 +608,7 @@ WvPLStatus WvPLSDKSession::GetClientInfo(WvPLClientInfo* client_info) const {
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);
@@ -607,9 +665,21 @@ WvPLStatus WvPLSDKSession::VerifyRemoteAttestation() {
signed_message_request_from_cdm_->msg(),
signed_message_request_from_cdm_->remote_attestation(),
&remote_attestation_cert_serial_number_);
if (!ra_status.ok()) {
if (ra_status.error_message().find(
"remote-attestation-client-id-decrypt-failed") != std::string::npos) {
return WvPLStatus(error_space, error::INVALID_ARGUMENT,
"Remote Attestation Certificate decryption failed");
}
return ra_status;
}
if (remote_attestation_cert_serial_number_.empty()) {
return WvPLStatus(error_space, error::INVALID_ARGUMENT,
"remote_attestation_cert_serial_number is empty");
}
return OkStatus();
}
}
WvPLStatus WvPLSDKSession::GetClientCapabilities(
WvPLClientCapabilities* client_capabilities) const {
@@ -700,7 +770,7 @@ WvPLStatus WvPLSDKSession::GetPsshData(
return WvPLStatus(error_space, error::INVALID_ARGUMENT,
"sdk_license_request_ is null");
}
if (request_type() == LicenseRequestType::NEW) {
if (sdk_license_request_->type() == LicenseRequest::NEW) {
ContentInfo content_info;
WvPLStatus status = widevine::ParseContentId(
sdk_license_request_->content_id(), &content_info);
@@ -754,14 +824,12 @@ WvPLStatus WvPLSDKSession::GetPsshData(
content_info.content_info_entry(i).key_ids(idx));
}
}
return status;
} else {
return WvPLStatus(error_space, error::INVALID_ARGUMENT,
"Failed to get pssh data. Widevine PSSH not found.");
}
}
// A PSSH with the widevine header wasn't found, so return error.
return WvPLStatus(error_space, error::NOT_FOUND,
"Failed to get pssh data. Widevine PSSH not found.");
}
*wvpl_widevine_pssh_data = pssh_data_;
return OkStatus();
@@ -836,6 +904,20 @@ uint32_t WvPLSDKSession::GetSystemId() const {
return *system_id_;
}
std::string WvPLSDKSession::session_id() const {
DCHECK(sdk_license_request_);
const LicenseRequest::ContentIdentification& content_id =
sdk_license_request_->content_id();
if (content_id.existing_license().license_id().has_session_id())
return content_id.existing_license().license_id().session_id();
else if (content_id.has_widevine_pssh_data())
return content_id.widevine_pssh_data().request_id();
else if (content_id.has_webm_key_id())
return content_id.webm_key_id().request_id();
else
return std::string();
}
bool WvPLSDKSession::is_offline_license() const {
DCHECK(sdk_license_request_);
if (sdk_license_request_ == nullptr) return false;
@@ -846,13 +928,12 @@ bool WvPLSDKSession::is_offline_license() const {
if (content_id.has_init_data()) {
return content_id.init_data().license_type() == widevine::OFFLINE;
}
if (content_id.has_cenc_id_deprecated()) {
return content_id.cenc_id_deprecated().license_type() ==
if (content_id.has_widevine_pssh_data()) {
return content_id.widevine_pssh_data().license_type() ==
widevine::OFFLINE;
}
if (content_id.has_webm_id_deprecated()) {
return content_id.webm_id_deprecated().license_type() ==
widevine::OFFLINE;
if (content_id.has_webm_key_id()) {
return content_id.webm_key_id().license_type() == widevine::OFFLINE;
}
if (content_id.has_existing_license()) {
return content_id.existing_license().license_id().type() ==

View File

@@ -113,6 +113,39 @@ class WvPLSDKSession {
*/
virtual bool is_offline_license() const;
/**
* A session id that remains constant throughout a session. All license
* and heartbeat requests in a session have the same session id.
*
* @return string.
*/
virtual std::string session_id() const;
/**
* Returns the license request contains client id or not.
*
* @return bool.
*/
virtual bool has_client_id() const { return has_client_id_; }
/**
* Returns true if remote_attestation_cert_serial_number is not empty.
* Otherwise return false.
*
* @return bool.
*/
virtual bool remote_attestation_verified() {
return !remote_attestation_cert_serial_number_.empty();
}
/**
* Returns true if license request has encrypted_client_id. Otherwise return
* false.
*
* @return bool.
*/
virtual bool has_encrypted_client_id() { return has_encrypted_client_id_; }
protected:
const widevine::DrmRootCertificate* drm_root_certificate_;
std::string user_agent_;
@@ -132,6 +165,9 @@ class WvPLSDKSession {
std::string remote_attestation_cert_serial_number_;
std::unique_ptr<widevine::LicenseRequest> sdk_license_request_;
LicenseRequestType request_type_;
bool has_session_state_ = false;
bool has_encrypted_client_id_ = false;
virtual WvPLStatus VerifyRemoteAttestation();
// Returns the WvPL Client Capabilities information for the license request
@@ -140,11 +176,25 @@ class WvPLSDKSession {
const widevine::ClientIdentification& client_id,
WvPLClientCapabilities* client_capabilities) const;
// Copies/translates the output protection from a WvPL Key into an SDK
// Copy and translates the Key fields from a WvPL Key into an SDK
// key container.
void CopyOutputProtection(
const WvPLKey& wvpl_key,
// Copies
// (1) key id
// (2) key
// (3) video_resolution_constraints
// (4) output protection using CopyOutputProtection
// (5) security_level using CopySecurityLevel
// Translates
// (1) key type
void CopyKey(const WvPLKey& wvpl_key,
widevine::License_KeyContainer* sdk_key_container);
// Copies/translates output_protection in WvPL Key into an SDK key container.
void CopyOutputProtection(
const WvPLOutputProtection& wvpl_output_protection,
widevine::License_KeyContainer_OutputProtection* output_protection);
// Copies/translatessecurity_level in WvPL Key into an SDK key container.
virtual void CopySecurityLevel(
const WvPLOutputProtection& output_protection, TrackType track_type,
widevine::License_KeyContainer* key_container);
@@ -154,12 +204,6 @@ class WvPLSDKSession {
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,

View File

@@ -20,6 +20,7 @@
// 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.
// TODO(user) Expose Hdcpsrmrule into WvPLHdcpSrmRule.java.
namespace widevine_server {
namespace wv_pl_sdk {
@@ -40,6 +41,7 @@ enum KeyType {
ENTITLEMENT = 2
};
// LINT.IfChange
enum LicenseType {
STREAMING = 1,
OFFLINE = 2,
@@ -48,6 +50,7 @@ enum LicenseType {
/**
* Represents the type of message. This struct is used by Proxy SDK.
*/
// LINT.IfChange
enum MessageType {
UNKNOWN = 0,
LICENSE_REQUEST = 1,
@@ -95,6 +98,11 @@ enum SecurityLevel {
HW_SECURE_ALL = 5
};
enum HdcpSrmRule {
HDCP_SRM_RULE_NONE = 0,
CURRENT_SRM = 1,
};
enum DeviceSecurityLevel {
DEVICE_LEVEL_UNSPECIFIED = 0,
DEVICE_LEVEL_1 = 1,
@@ -125,6 +133,41 @@ enum AnalogOutputCapabilities {
ANALOG_OUTPUT_SUPPORTS_CGMS_A = 3,
};
/*
* Defines the type wrapper for wvpl request.
*/
struct WvPLRequestType {
WvPLRequestType() {
message_type_ = UNKNOWN;
license_type_ = STREAMING;
license_request_type_ = REQUEST_TYPE_UNSPECIFIED;
}
void set_message_type(MessageType message_type) {
message_type_ = message_type;
}
MessageType message_type() const { return message_type_; }
void set_license_type(LicenseType license_type) {
license_type_ = license_type;
}
LicenseType license_type() const { return license_type_; }
void set_license_request_type(LicenseRequestType license_request_type) {
license_request_type_ = license_request_type;
}
LicenseRequestType license_request_type() const {
return license_request_type_;
}
// Type of the message, default value is UNKNOWN.
MessageType message_type_;
// Type of the license, default value is Streaming.
LicenseType license_type_;
// Type of the license request, default value is REQUEST_TYPE_UNSPECIFIED.
LicenseRequestType license_request_type_;
};
struct WvPLPlaybackPolicy {
WvPLPlaybackPolicy() {
license_duration_seconds_ = 0;
@@ -370,6 +413,7 @@ struct WvPLVideoResolutionConstraint {
struct WvPLOutputProtection {
WvPLOutputProtection() {
hdcp_ = HDCP_NONE;
hdcp_srm_rule_ = HDCP_SRM_RULE_NONE;
secure_data_path_ = false;
security_level_ = SECURITY_LEVEL_UNDEFINED;
disable_analog_output_ = false;
@@ -412,9 +456,17 @@ struct WvPLOutputProtection {
CGMS cgms() const { return cgms_; }
void set_hdcp_srm_rule(HdcpSrmRule hdcp_srm_rule) {
hdcp_srm_rule_ = hdcp_srm_rule;
}
HdcpSrmRule hdcp_srm_rule() const { return hdcp_srm_rule_; }
// Indicates whether HDCP is required on digital outputs. Default is None.
HDCP hdcp_;
HdcpSrmRule hdcp_srm_rule_;
// Crypto operations and handling of the media must be performed within a
// hardware backed trusted environment. Default is false.
bool secure_data_path_;
@@ -932,6 +984,83 @@ struct WvPLWidevinePsshData {
std::list<WvPLEntitledKey> entitled_keys_;
};
struct WvPLCasKey {
WvPLCasKey() {}
void set_odd_key_id(const std::string& odd_key_id) {
odd_key_id_ = odd_key_id;
}
const std::string& odd_key_id() const { return odd_key_id_; }
void set_odd_key_bytes(const std::string& odd_key_bytes) {
odd_key_bytes_ = odd_key_bytes;
}
const std::string& odd_key_bytes() const { return odd_key_bytes_; }
void set_even_key_id(const std::string& even_key_id) {
even_key_id_ = even_key_id;
}
const std::string& even_key_id() const { return even_key_id_; }
void set_even_key_bytes(const std::string& even_key_bytes) {
even_key_bytes_ = even_key_bytes;
}
const std::string& even_key_bytes() const { return even_key_bytes_; }
void set_track_type(const TrackType track_type) { track_type_ = track_type; }
TrackType track_type() const { return track_type_; }
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_;
}
void set_key_type(const KeyType key_type) { key_type_ = key_type; }
KeyType key_type() const { return key_type_; }
// 'Odd' Key slot identifier.
std::string odd_key_id_;
// 'Odd' Key slot.
std::string odd_key_bytes_;
// 'Even' Key slot identifier.
std::string even_key_id_;
// 'Even' Key slot.
std::string even_key_bytes_;
// track type.
TrackType track_type_ = TRACK_TYPE_UNSPECIFIED;
// Required output protection.
WvPLOutputProtection output_protection_;
// Requested output protection.
WvPLOutputProtection requested_output_protection_;
// Key type from the KeyType enumeration.
KeyType key_type_ = ENTITLEMENT;
};
} // namespace wv_pl_sdk
} // namespace widevine_server