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:
@@ -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",
|
||||
)
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#ifndef COMMON_STATUS_H_
|
||||
#define COMMON_STATUS_H_
|
||||
|
||||
#include <iosfwd>
|
||||
#include <string>
|
||||
|
||||
#include "util/error_space.h"
|
||||
|
||||
@@ -9,8 +9,10 @@
|
||||
#include "common/string_util.h"
|
||||
|
||||
#include <bitset>
|
||||
#include <cstddef>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
#include "common/status.h"
|
||||
|
||||
namespace widevine {
|
||||
|
||||
@@ -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",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -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: {
|
||||
|
||||
@@ -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__
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -26,8 +26,8 @@ namespace widevine {
|
||||
namespace {
|
||||
|
||||
const uint8_t kWidevineSystemId[] = {0xed, 0xef, 0x8b, 0xa9, 0x79, 0xd6,
|
||||
0x4a, 0xce, 0xa3, 0xc8, 0x27, 0xdc,
|
||||
0xd5, 0x1d, 0x21, 0xed};
|
||||
0x4a, 0xce, 0xa3, 0xc8, 0x27, 0xdc,
|
||||
0xd5, 0x1d, 0x21, 0xed};
|
||||
|
||||
void AddKeyIdIfNotFound(const std::string& key_id,
|
||||
ContentInfo::ContentInfoEntry* entry) {
|
||||
@@ -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:
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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()) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,8 +2153,8 @@ TEST_P(SessionTestRenewal, LicenseRenewalWithSerialNumber) {
|
||||
kValidSessionUsage, false);
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(SystemIdVariations, SessionTestRenewal,
|
||||
::testing::Bool());
|
||||
INSTANTIATE_TEST_SUITE_P(SystemIdVariations, SessionTestRenewal,
|
||||
::testing::Bool());
|
||||
|
||||
TEST_F(SessionTest, InvalidRenewalKeySigningKey_2_0) {
|
||||
SessionImpl* session_ptr = nullptr;
|
||||
@@ -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,10 +3071,10 @@ TEST_F(SessionTest, GenerateDeviceStatusListRequest) {
|
||||
}
|
||||
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(SessionVmpTests, SessionVmpTest,
|
||||
::testing::Values(PLATFORM_NO_VERIFICATION,
|
||||
PLATFORM_UNVERIFIED,
|
||||
PLATFORM_TAMPERED,
|
||||
PLATFORM_SOFTWARE_VERIFIED));
|
||||
INSTANTIATE_TEST_SUITE_P(SessionVmpTests, SessionVmpTest,
|
||||
::testing::Values(PLATFORM_NO_VERIFICATION,
|
||||
PLATFORM_UNVERIFIED,
|
||||
PLATFORM_TAMPERED,
|
||||
PLATFORM_SOFTWARE_VERIFIED));
|
||||
|
||||
} // namespace widevine
|
||||
|
||||
@@ -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",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
2
sdk/external/common/wvpl/BUILD
vendored
2
sdk/external/common/wvpl/BUILD
vendored
@@ -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",
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
225
sdk/external/common/wvpl/wvpl_sdk_session.cc
vendored
225
sdk/external/common/wvpl/wvpl_sdk_session.cc
vendored
@@ -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,8 +665,20 @@ 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();
|
||||
}
|
||||
return OkStatus();
|
||||
}
|
||||
|
||||
WvPLStatus WvPLSDKSession::GetClientCapabilities(
|
||||
@@ -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() ==
|
||||
|
||||
62
sdk/external/common/wvpl/wvpl_sdk_session.h
vendored
62
sdk/external/common/wvpl/wvpl_sdk_session.h
vendored
@@ -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.
|
||||
// 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 WvPLKey& wvpl_key,
|
||||
widevine::License_KeyContainer* sdk_key_container);
|
||||
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,
|
||||
|
||||
129
sdk/external/common/wvpl/wvpl_types.h
vendored
129
sdk/external/common/wvpl/wvpl_types.h
vendored
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user