Adds --cxxopt="-D_GLIBCXX_USE_CXX11_ABI=1" to 'bazel build' command in moe_test.sh.
This flag also added to [] and [] ------------- CASDrmLicenseRequest at the proxy. ------------- CAS Proxy SDK version update to 1.1.2. ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=231988012
This commit is contained in:
@@ -35,5 +35,8 @@ cc_binary(
|
|||||||
cc_binary(
|
cc_binary(
|
||||||
name = "wvpl_cas_proxy_session_example",
|
name = "wvpl_cas_proxy_session_example",
|
||||||
srcs = ["wvpl_cas_proxy_session_example.cc"],
|
srcs = ["wvpl_cas_proxy_session_example.cc"],
|
||||||
deps = ["//media_cas_proxy_sdk/external/common/wvpl:wvpl_cas_proxy_session"],
|
deps = [
|
||||||
|
"//media_cas_proxy_sdk/external/common/wvpl:wvpl_cas_proxy_environment",
|
||||||
|
"//media_cas_proxy_sdk/external/common/wvpl:wvpl_cas_proxy_session",
|
||||||
|
],
|
||||||
)
|
)
|
||||||
|
|||||||
33
media_cas_proxy_sdk/external/common/wvpl/BUILD
vendored
33
media_cas_proxy_sdk/external/common/wvpl/BUILD
vendored
@@ -38,7 +38,9 @@ cc_library(
|
|||||||
hdrs = glob(["*.h"]),
|
hdrs = glob(["*.h"]),
|
||||||
deps = [
|
deps = [
|
||||||
"//base",
|
"//base",
|
||||||
|
"@abseil_repo//absl/synchronization",
|
||||||
"//sdk/external/common/wvpl:sdk",
|
"//sdk/external/common/wvpl:sdk",
|
||||||
|
"//protos/public:media_cas_license_proto",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -52,11 +54,16 @@ cc_library(
|
|||||||
],
|
],
|
||||||
copts = PUBLIC_COPTS,
|
copts = PUBLIC_COPTS,
|
||||||
deps = [
|
deps = [
|
||||||
"//base",
|
|
||||||
"@abseil_repo//absl/strings",
|
"@abseil_repo//absl/strings",
|
||||||
|
"@abseil_repo//absl/synchronization",
|
||||||
"//common:error_space",
|
"//common:error_space",
|
||||||
"//sdk/external/common/wvpl:wvpl_sdk_environment",
|
"//common:status",
|
||||||
"//sdk/external/common/wvpl:wvpl_sdk_session",
|
"//sdk/external/common/wvpl:wvpl_sdk_session",
|
||||||
|
"//sdk/external/common/wvpl:wvpl_types",
|
||||||
|
"//protos/public:errors_proto",
|
||||||
|
"//protos/public:license_protocol_proto",
|
||||||
|
"//protos/public:media_cas_encryption_proto",
|
||||||
|
"//protos/public:media_cas_license_proto",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -71,13 +78,14 @@ cc_library(
|
|||||||
],
|
],
|
||||||
copts = PUBLIC_COPTS,
|
copts = PUBLIC_COPTS,
|
||||||
deps = [
|
deps = [
|
||||||
"//base",
|
|
||||||
"@abseil_repo//absl/strings",
|
"@abseil_repo//absl/strings",
|
||||||
|
"@abseil_repo//absl/synchronization",
|
||||||
"//common:certificate_type",
|
"//common:certificate_type",
|
||||||
"//common:drm_root_certificate",
|
"//common:drm_root_certificate",
|
||||||
"//common:error_space",
|
"//common:error_space",
|
||||||
"//sdk/external/common/wvpl:wvpl_sdk_environment",
|
"//sdk/external/common/wvpl:wvpl_sdk_environment",
|
||||||
"//sdk/external/common/wvpl:wvpl_sdk_session",
|
"//sdk/external/common/wvpl:wvpl_sdk_session",
|
||||||
|
"//protos/public:media_cas_license_proto",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -85,6 +93,7 @@ cc_test(
|
|||||||
name = "wvpl_cas_proxy_session_test",
|
name = "wvpl_cas_proxy_session_test",
|
||||||
srcs = ["wvpl_cas_proxy_session_test.cc"],
|
srcs = ["wvpl_cas_proxy_session_test.cc"],
|
||||||
deps = [
|
deps = [
|
||||||
|
":wvpl_cas_proxy_environment",
|
||||||
":wvpl_cas_proxy_session",
|
":wvpl_cas_proxy_session",
|
||||||
"//testing:gunit",
|
"//testing:gunit",
|
||||||
"//testing:gunit_main",
|
"//testing:gunit_main",
|
||||||
@@ -92,7 +101,25 @@ cc_test(
|
|||||||
"@abseil_repo//absl/strings",
|
"@abseil_repo//absl/strings",
|
||||||
"//common:certificate_type",
|
"//common:certificate_type",
|
||||||
"//common:drm_root_certificate",
|
"//common:drm_root_certificate",
|
||||||
|
"//common:status",
|
||||||
"//sdk/external/common/wvpl:wvpl_types",
|
"//sdk/external/common/wvpl:wvpl_types",
|
||||||
"//protos/public:errors_proto",
|
"//protos/public:errors_proto",
|
||||||
|
"//protos/public:license_protocol_proto",
|
||||||
|
"//protos/public:media_cas_encryption_proto",
|
||||||
|
"//protos/public:media_cas_license_proto",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
cc_test(
|
||||||
|
name = "wvpl_cas_proxy_environment_test",
|
||||||
|
srcs = ["wvpl_cas_proxy_environment_test.cc"],
|
||||||
|
deps = [
|
||||||
|
":wvpl_cas_proxy_environment",
|
||||||
|
":wvpl_cas_proxy_session",
|
||||||
|
"//testing:gunit",
|
||||||
|
"//testing:gunit_main",
|
||||||
|
"@abseil_repo//absl/strings",
|
||||||
|
"//common:drm_root_certificate",
|
||||||
|
"//sdk/external/common/wvpl:wvpl_sdk_environment",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -63,7 +63,9 @@ WvPLStatus WvPLCASProxyEnvironment::CreateSession(
|
|||||||
std::unique_ptr<WvPLCASProxySession> wvpl_cas_proxy_session(
|
std::unique_ptr<WvPLCASProxySession> wvpl_cas_proxy_session(
|
||||||
new WvPLCASProxySession(drm_root_certificate_.get(),
|
new WvPLCASProxySession(drm_root_certificate_.get(),
|
||||||
cas_license_request));
|
cas_license_request));
|
||||||
|
status = wvpl_cas_proxy_session->ParseLicenseRequest();
|
||||||
if (status.ok()) {
|
if (status.ok()) {
|
||||||
|
wvpl_cas_proxy_session->set_provider(provider_);
|
||||||
*cas_proxy_session = wvpl_cas_proxy_session.release();
|
*cas_proxy_session = wvpl_cas_proxy_session.release();
|
||||||
}
|
}
|
||||||
return status;
|
return status;
|
||||||
@@ -74,6 +76,13 @@ WvPLStatus WvPLCASProxyEnvironment::SetDeviceCertificateStatusList(
|
|||||||
return WvPLSDKEnvironment::SetDeviceCertificateStatusList(cert_list);
|
return WvPLSDKEnvironment::SetDeviceCertificateStatusList(cert_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WvPLCASProxyEnvironment::DestroySession(
|
||||||
|
WvPLCASProxySession* cas_proxy_session) const {
|
||||||
|
if (cas_proxy_session != nullptr) {
|
||||||
|
delete cas_proxy_session;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
WvPLCASProxyEnvironment::~WvPLCASProxyEnvironment() {}
|
WvPLCASProxyEnvironment::~WvPLCASProxyEnvironment() {}
|
||||||
|
|
||||||
} // namespace wv_pl_sdk
|
} // namespace wv_pl_sdk
|
||||||
|
|||||||
@@ -76,6 +76,13 @@ class WvPLCASProxyEnvironment : public WvPLSDKEnvironment {
|
|||||||
virtual WvPLStatus CreateSession(const std::string& cas_license_request,
|
virtual WvPLStatus CreateSession(const std::string& cas_license_request,
|
||||||
WvPLCASProxySession** cas_proxy_session);
|
WvPLCASProxySession** cas_proxy_session);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes the session
|
||||||
|
*
|
||||||
|
* @param session
|
||||||
|
*/
|
||||||
|
virtual void DestroySession(WvPLCASProxySession* cas_proxy_session) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the certificate status list system-wide.
|
* Set the certificate status list system-wide.
|
||||||
* |cert_list| specifies the device certificate status
|
* |cert_list| specifies the device certificate status
|
||||||
|
|||||||
124
media_cas_proxy_sdk/external/common/wvpl/wvpl_cas_proxy_environment_test.cc
vendored
Normal file
124
media_cas_proxy_sdk/external/common/wvpl/wvpl_cas_proxy_environment_test.cc
vendored
Normal file
@@ -0,0 +1,124 @@
|
|||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Copyright 2018 Google LLC.
|
||||||
|
//
|
||||||
|
// This software is licensed under the terms defined in the Widevine Master
|
||||||
|
// License Agreement. For a copy of this agreement, please contact
|
||||||
|
// widevine-licensing@google.com.
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "media_cas_proxy_sdk/external/common/wvpl/wvpl_cas_proxy_environment.h"
|
||||||
|
#include "testing/gmock.h"
|
||||||
|
#include "testing/gunit.h"
|
||||||
|
#include "absl/strings/escaping.h"
|
||||||
|
#include "media_cas_proxy_sdk/external/common/wvpl/wvpl_cas_proxy_session.h"
|
||||||
|
#include "sdk/external/common/wvpl/wvpl_sdk_environment.h"
|
||||||
|
|
||||||
|
// Optional ::testing aliases. Remove if unused.
|
||||||
|
using ::testing::Test;
|
||||||
|
|
||||||
|
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";
|
||||||
|
|
||||||
|
const char kWidevineTestProvider[] = "widevine_test";
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
namespace widevine_server {
|
||||||
|
namespace wv_pl_sdk {
|
||||||
|
|
||||||
|
// A test fixture is used because protected/private methods will be covered.
|
||||||
|
class WvPLCASProxyEnvironmentTest : public Test {
|
||||||
|
protected:
|
||||||
|
void SetUp() override {
|
||||||
|
std::map<std::string, std::string> config_values;
|
||||||
|
config_values[kDrmCertificateType] = "test";
|
||||||
|
config_values[kProvider] = kWidevineTestProvider;
|
||||||
|
wvpl_cas_proxy_environment_ = new WvPLCASProxyEnvironment(config_values);
|
||||||
|
ASSERT_OK(wvpl_cas_proxy_environment_->Initialize());
|
||||||
|
}
|
||||||
|
|
||||||
|
~WvPLCASProxyEnvironmentTest() override {
|
||||||
|
if (wvpl_cas_proxy_environment_ != nullptr) {
|
||||||
|
delete wvpl_cas_proxy_environment_;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
WvPLCASProxyEnvironment* wvpl_cas_proxy_environment_ = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST_F(WvPLCASProxyEnvironmentTest, CreateSession) {
|
||||||
|
WvPLCASProxySession* wvpl_cas_proxy_session = nullptr;
|
||||||
|
WvPLStatus status = wvpl_cas_proxy_environment_->CreateSession(
|
||||||
|
absl::HexStringToBytes(kValidRequestFromCdm), &wvpl_cas_proxy_session);
|
||||||
|
EXPECT_TRUE(status.ok());
|
||||||
|
std::string json_signed_cas_drm_request;
|
||||||
|
status = wvpl_cas_proxy_session->GenerateLicenseRequestAsJSON(
|
||||||
|
&json_signed_cas_drm_request);
|
||||||
|
EXPECT_TRUE(status.ok());
|
||||||
|
wvpl_cas_proxy_environment_->DestroySession(wvpl_cas_proxy_session);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(WvPLCASProxyEnvironmentTest, CreateProxySessionWithBadLicenseRequest) {
|
||||||
|
WvPLCASProxySession* wvpl_cas_proxy_session = nullptr;
|
||||||
|
const std::string license_request_from_cdm = "AAAAAAAA";
|
||||||
|
WvPLStatus status = wvpl_cas_proxy_environment_->CreateSession(
|
||||||
|
absl::HexStringToBytes(license_request_from_cdm),
|
||||||
|
&wvpl_cas_proxy_session);
|
||||||
|
EXPECT_FALSE(status.ok());
|
||||||
|
EXPECT_TRUE(wvpl_cas_proxy_session == nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace wv_pl_sdk
|
||||||
|
} // namespace widevine_server
|
||||||
@@ -8,10 +8,40 @@
|
|||||||
|
|
||||||
#include "media_cas_proxy_sdk/external/common/wvpl/wvpl_cas_proxy_session.h"
|
#include "media_cas_proxy_sdk/external/common/wvpl/wvpl_cas_proxy_session.h"
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include "google/protobuf/util/json_util.h"
|
||||||
|
#include "absl/strings/escaping.h"
|
||||||
|
#include "common/error_space.h"
|
||||||
|
#include "common/status.h"
|
||||||
|
#include "sdk/external/common/wvpl/wvpl_types.h"
|
||||||
|
#include "protos/public/errors.pb.h"
|
||||||
|
#include "protos/public/license_protocol.pb.h"
|
||||||
|
#include "protos/public/media_cas_encryption.pb.h"
|
||||||
|
#include "protos/public/media_cas_license.pb.h"
|
||||||
|
|
||||||
|
using google::protobuf::util::JsonPrintOptions;
|
||||||
|
using google::protobuf::util::MessageToJsonString;
|
||||||
|
using widevine::CasDrmLicenseRequest;
|
||||||
|
using widevine::CasEncryptionResponse;
|
||||||
|
using widevine::error_space;
|
||||||
|
using widevine::License;
|
||||||
|
using widevine::OkStatus;
|
||||||
|
using widevine::SignedCasDrmRequest;
|
||||||
|
|
||||||
|
namespace error = widevine::error;
|
||||||
|
|
||||||
namespace widevine_server {
|
namespace widevine_server {
|
||||||
namespace wv_pl_sdk {
|
namespace wv_pl_sdk {
|
||||||
|
|
||||||
|
License::KeyContainer::KeyType GetKeyContainerKeyType(const KeyType key_type) {
|
||||||
|
switch (key_type) {
|
||||||
|
case CONTENT:
|
||||||
|
return License::KeyContainer::CONTENT;
|
||||||
|
case ENTITLEMENT:
|
||||||
|
default:
|
||||||
|
return License::KeyContainer::ENTITLEMENT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::string WvPLCASProxySession::GetVersionString() {
|
std::string WvPLCASProxySession::GetVersionString() {
|
||||||
return std::to_string(kMajorVersion) + "." + std::to_string(kMinorVersion) +
|
return std::to_string(kMajorVersion) + "." + std::to_string(kMinorVersion) +
|
||||||
"." + std::to_string(kRelease);
|
"." + std::to_string(kRelease);
|
||||||
@@ -23,6 +53,104 @@ PlatformVerificationStatus WvPLCASProxySession::VerifyPlatform() {
|
|||||||
return PLATFORM_NO_VERIFICATION;
|
return PLATFORM_NO_VERIFICATION;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WvPLStatus WvPLCASProxySession::GenerateLicenseRequestAsJSON(
|
||||||
|
std::string* json_license_request) {
|
||||||
|
if (json_license_request == nullptr) {
|
||||||
|
return WvPLStatus(error_space, ::widevine::error::INVALID_ARGUMENT,
|
||||||
|
"json license_request cannot be nullptr");
|
||||||
|
}
|
||||||
|
CasDrmLicenseRequest cas_drm_license_request;
|
||||||
|
WvPLStatus wvpl_status = BuildCasDrmLicenseRequest(&cas_drm_license_request);
|
||||||
|
if (!wvpl_status.ok()) {
|
||||||
|
return wvpl_status;
|
||||||
|
}
|
||||||
|
std::string json_cas_drm_license_request;
|
||||||
|
JsonPrintOptions options;
|
||||||
|
options.preserve_proto_field_names = true;
|
||||||
|
auto status = MessageToJsonString(cas_drm_license_request,
|
||||||
|
&json_cas_drm_license_request, options);
|
||||||
|
if (!status.ok()) {
|
||||||
|
return WvPLStatus(
|
||||||
|
error_space, error::INTERNAL,
|
||||||
|
"Failed to convert CASDrmLicenseRequest proto to json, error = " +
|
||||||
|
std::string(status.error_message()));
|
||||||
|
}
|
||||||
|
SignedCasDrmRequest signed_cas_drm_request;
|
||||||
|
signed_cas_drm_request.set_request(json_cas_drm_license_request);
|
||||||
|
signed_cas_drm_request.set_signer(provider_);
|
||||||
|
// TODO(user): Fill out signature, client_ip_address, user_agent
|
||||||
|
signed_cas_drm_request.set_provider(provider_);
|
||||||
|
status = MessageToJsonString(signed_cas_drm_request, json_license_request,
|
||||||
|
options);
|
||||||
|
if (!status.ok()) {
|
||||||
|
return WvPLStatus(
|
||||||
|
error_space, error::INTERNAL,
|
||||||
|
"Failed to convert SignedCasDrmRequest proto to json, error = " +
|
||||||
|
std::string(status.error_message()));
|
||||||
|
}
|
||||||
|
return wvpl_status;
|
||||||
|
}
|
||||||
|
|
||||||
|
WvPLStatus WvPLCASProxySession::BuildCasDrmLicenseRequest(
|
||||||
|
CasDrmLicenseRequest* cas_drm_license_request) {
|
||||||
|
if (cas_drm_license_request == nullptr) {
|
||||||
|
return WvPLStatus(error_space, error::INVALID_ARGUMENT,
|
||||||
|
"CAS DRM License Request cannot be null");
|
||||||
|
}
|
||||||
|
if (!cas_drm_license_request->content_key_specs().empty()) {
|
||||||
|
return WvPLStatus(error_space, error::ALREADY_EXISTS,
|
||||||
|
"Content key specs must be empty");
|
||||||
|
}
|
||||||
|
// license_request_from_cdm_ is populated when this session is constructed.
|
||||||
|
cas_drm_license_request->set_payload(license_request_from_cdm_);
|
||||||
|
cas_drm_license_request->set_provider_id(provider_);
|
||||||
|
cas_drm_license_request->set_content_id(pssh_data_.content_id());
|
||||||
|
absl::ReaderMutexLock lock(&cas_keys_mutex_);
|
||||||
|
for (const auto& it : cas_keys_) {
|
||||||
|
if (it.even_key_bytes().empty()) {
|
||||||
|
return WvPLStatus(error_space, widevine::MISSING_EVEN_KEY,
|
||||||
|
"Even Key not specified");
|
||||||
|
} else if (it.even_key_id().empty()) {
|
||||||
|
return WvPLStatus(error_space, widevine::MISSING_EVEN_KEY_ID,
|
||||||
|
"Even KeyID not specified");
|
||||||
|
}
|
||||||
|
License::KeyContainer key_container;
|
||||||
|
CopySecurityLevel(it.output_protection(), it.track_type(), &key_container);
|
||||||
|
CasDrmLicenseRequest::ContentKeySpec* content_key_spec =
|
||||||
|
cas_drm_license_request->add_content_key_specs();
|
||||||
|
content_key_spec->set_security_level(key_container.level());
|
||||||
|
CopyOutputProtection(
|
||||||
|
it.output_protection(),
|
||||||
|
content_key_spec->mutable_required_output_protection());
|
||||||
|
CopyOutputProtection(
|
||||||
|
it.requested_output_protection(),
|
||||||
|
content_key_spec->mutable_requested_output_protection());
|
||||||
|
// Even key
|
||||||
|
CasEncryptionResponse::KeyInfo* even_entitlement_key =
|
||||||
|
content_key_spec->add_entitlement_keys();
|
||||||
|
even_entitlement_key->set_key_slot(CasEncryptionResponse::KeyInfo::EVEN);
|
||||||
|
even_entitlement_key->set_key_id(it.even_key_id());
|
||||||
|
even_entitlement_key->set_key(it.even_key_bytes());
|
||||||
|
even_entitlement_key->set_track_type(TrackTypeToString(it.track_type()));
|
||||||
|
// Odd key
|
||||||
|
CasEncryptionResponse::KeyInfo* odd_entitlement_key =
|
||||||
|
content_key_spec->add_entitlement_keys();
|
||||||
|
odd_entitlement_key->set_key_slot(CasEncryptionResponse::KeyInfo::ODD);
|
||||||
|
odd_entitlement_key->set_key_id(it.odd_key_id());
|
||||||
|
odd_entitlement_key->set_key(it.odd_key_bytes());
|
||||||
|
odd_entitlement_key->set_track_type(TrackTypeToString(it.track_type()));
|
||||||
|
// key type
|
||||||
|
content_key_spec->set_key_type(GetKeyContainerKeyType(it.key_type()));
|
||||||
|
}
|
||||||
|
return OkStatus();
|
||||||
|
}
|
||||||
|
|
||||||
|
WvPLStatus WvPLCASProxySession::AddCasKey(const WvPLCasKey& key) {
|
||||||
|
absl::WriterMutexLock lock(&cas_keys_mutex_);
|
||||||
|
cas_keys_.push_back(key);
|
||||||
|
return OkStatus();
|
||||||
|
}
|
||||||
|
|
||||||
WvPLCASProxySession::WvPLCASProxySession(
|
WvPLCASProxySession::WvPLCASProxySession(
|
||||||
const widevine::DrmRootCertificate* drm_root_certificate,
|
const widevine::DrmRootCertificate* drm_root_certificate,
|
||||||
const std::string& cas_license_request_from_cdm)
|
const std::string& cas_license_request_from_cdm)
|
||||||
|
|||||||
@@ -10,14 +10,17 @@
|
|||||||
#define MEDIA_CAS_PROXY_SDK_EXTERNAL_COMMON_WVPL_WVPL_CAS_PROXY_SESSION_H_
|
#define MEDIA_CAS_PROXY_SDK_EXTERNAL_COMMON_WVPL_WVPL_CAS_PROXY_SESSION_H_
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include "absl/synchronization/mutex.h"
|
||||||
#include "sdk/external/common/wvpl/wvpl_sdk_session.h"
|
#include "sdk/external/common/wvpl/wvpl_sdk_session.h"
|
||||||
|
#include "protos/public/media_cas_license.pb.h"
|
||||||
|
|
||||||
namespace widevine_server {
|
namespace widevine_server {
|
||||||
namespace wv_pl_sdk {
|
namespace wv_pl_sdk {
|
||||||
|
|
||||||
constexpr uint32_t kMajorVersion = 1;
|
constexpr uint32_t kMajorVersion = 1;
|
||||||
constexpr uint32_t kMinorVersion = 0;
|
constexpr uint32_t kMinorVersion = 1;
|
||||||
constexpr uint32_t kRelease = 1;
|
constexpr uint32_t kRelease = 2;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Models a session for Widevine CAS Proxy functionality for
|
* Models a session for Widevine CAS Proxy functionality for
|
||||||
@@ -68,6 +71,18 @@ class WvPLCASProxySession : public WvPLSDKSession {
|
|||||||
*/
|
*/
|
||||||
PlatformVerificationStatus VerifyPlatform() override;
|
PlatformVerificationStatus VerifyPlatform() override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns license request as a JSON string. This std::string is placed in
|
||||||
|
* |license_request|, if successful. Returns OK status upon success, else an
|
||||||
|
* error status.
|
||||||
|
*/
|
||||||
|
WvPLStatus GenerateLicenseRequestAsJSON(std::string* license_request);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a key to the WvPLCasKey collection.
|
||||||
|
*/
|
||||||
|
WvPLStatus AddCasKey(const WvPLCasKey& key);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class WvPLCASProxyEnvironment;
|
friend class WvPLCASProxyEnvironment;
|
||||||
friend class WvPLCASProxyEnvironmentTest;
|
friend class WvPLCASProxyEnvironmentTest;
|
||||||
@@ -76,6 +91,20 @@ class WvPLCASProxySession : public WvPLSDKSession {
|
|||||||
WvPLCASProxySession(
|
WvPLCASProxySession(
|
||||||
const widevine::DrmRootCertificate* drm_root_certificate,
|
const widevine::DrmRootCertificate* drm_root_certificate,
|
||||||
const std::string& cas_license_request_from_cdm);
|
const std::string& cas_license_request_from_cdm);
|
||||||
|
|
||||||
|
WvPLStatus BuildCasDrmLicenseRequest(
|
||||||
|
widevine::CasDrmLicenseRequest* cas_drm_license_request);
|
||||||
|
|
||||||
|
void set_provider(const std::string& provider) { provider_ = provider; }
|
||||||
|
|
||||||
|
// name of the provider hosting this service.
|
||||||
|
std::string provider_;
|
||||||
|
|
||||||
|
// holds all the WvPLCasKey objects. Used when generating a CAS License.
|
||||||
|
std::vector<WvPLCasKey> cas_keys_ GUARDED_BY(cas_keys_mutex_);
|
||||||
|
|
||||||
|
// Mutex to protect the keys owned by this session.
|
||||||
|
mutable absl::Mutex cas_keys_mutex_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace wv_pl_sdk
|
} // namespace wv_pl_sdk
|
||||||
|
|||||||
@@ -8,18 +8,28 @@
|
|||||||
|
|
||||||
#include "media_cas_proxy_sdk/external/common/wvpl/wvpl_cas_proxy_session.h"
|
#include "media_cas_proxy_sdk/external/common/wvpl/wvpl_cas_proxy_session.h"
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include "google/protobuf/util/json_util.h"
|
||||||
#include "testing/gmock.h"
|
#include "testing/gmock.h"
|
||||||
#include "testing/gunit.h"
|
#include "testing/gunit.h"
|
||||||
#include "absl/memory/memory.h"
|
#include "absl/memory/memory.h"
|
||||||
#include "absl/strings/escaping.h"
|
#include "absl/strings/escaping.h"
|
||||||
#include "common/certificate_type.h"
|
#include "common/certificate_type.h"
|
||||||
#include "common/drm_root_certificate.h"
|
#include "common/drm_root_certificate.h"
|
||||||
|
#include "common/status.h"
|
||||||
#include "sdk/external/common/wvpl/wvpl_types.h"
|
#include "sdk/external/common/wvpl/wvpl_types.h"
|
||||||
#include "protos/public/errors.pb.h"
|
#include "protos/public/errors.pb.h"
|
||||||
|
#include "protos/public/license_protocol.pb.h"
|
||||||
|
#include "protos/public/media_cas_license.pb.h"
|
||||||
|
|
||||||
|
using google::protobuf::util::JsonStringToMessage;
|
||||||
|
using widevine::CasDrmLicenseRequest;
|
||||||
using widevine::DrmRootCertificate;
|
using widevine::DrmRootCertificate;
|
||||||
using widevine::kCertificateTypeTesting;
|
using widevine::kCertificateTypeTesting;
|
||||||
|
using widevine::License;
|
||||||
using widevine::SIGNED_MESSAGE_PARSE_ERROR;
|
using widevine::SIGNED_MESSAGE_PARSE_ERROR;
|
||||||
|
using widevine::SignedCasDrmRequest;
|
||||||
|
using widevine::error::ALREADY_EXISTS;
|
||||||
|
using widevine::error::INVALID_ARGUMENT;
|
||||||
|
|
||||||
namespace error = widevine::error;
|
namespace error = widevine::error;
|
||||||
|
|
||||||
@@ -76,6 +86,9 @@ const char kValidRequestFromCdm[] =
|
|||||||
"194631e3d205cb459a7e1ff11b54791ef394b74fb8a729d0104b00e17b9e05c5d42fac"
|
"194631e3d205cb459a7e1ff11b54791ef394b74fb8a729d0104b00e17b9e05c5d42fac"
|
||||||
"923f98d43aedc70ab0733039eb22f35c6961e4587085a14c4a9ace1db00508843e79ee"
|
"923f98d43aedc70ab0733039eb22f35c6961e4587085a14c4a9ace1db00508843e79ee"
|
||||||
"ba68321b559fbdfdf04c88813cdd";
|
"ba68321b559fbdfdf04c88813cdd";
|
||||||
|
|
||||||
|
const char kProvider[] = "widevine_test";
|
||||||
|
const char kContentId[] = "CasTsFake";
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
namespace widevine_server {
|
namespace widevine_server {
|
||||||
@@ -99,13 +112,38 @@ class WvPLCASProxySessionTest : public testing::Test {
|
|||||||
void Create(const std::string& request) {
|
void Create(const std::string& request) {
|
||||||
wvpl_cas_proxy_session_ = new WvPLCASProxySession(
|
wvpl_cas_proxy_session_ = new WvPLCASProxySession(
|
||||||
drm_root_cert_.get(), absl::HexStringToBytes(request));
|
drm_root_cert_.get(), absl::HexStringToBytes(request));
|
||||||
|
wvpl_cas_proxy_session_->set_provider(kProvider);
|
||||||
}
|
}
|
||||||
|
|
||||||
WvPLStatus Parse() { return wvpl_cas_proxy_session_->ParseLicenseRequest(); }
|
WvPLStatus Parse() { return wvpl_cas_proxy_session_->ParseLicenseRequest(); }
|
||||||
|
|
||||||
~WvPLCASProxySessionTest() override { delete wvpl_cas_proxy_session_; }
|
WvPLStatus BuildRequest(CasDrmLicenseRequest* cas_drm_license_request) {
|
||||||
|
return wvpl_cas_proxy_session_->BuildCasDrmLicenseRequest(
|
||||||
|
cas_drm_license_request);
|
||||||
|
}
|
||||||
|
|
||||||
WvPLCASProxySession* wvpl_cas_proxy_session_;
|
WvPLCasKey BuildKey(int index, TrackType track_type, KeyType key_type) {
|
||||||
|
WvPLCasKey wvpl_cas_key;
|
||||||
|
wvpl_cas_key.set_odd_key_id("HD_odd_key_id: " + std::to_string(index));
|
||||||
|
wvpl_cas_key.set_odd_key_bytes("HD_odd_key: " + std::to_string(index));
|
||||||
|
wvpl_cas_key.set_even_key_id("HD_even_key_id: " + std::to_string(index));
|
||||||
|
wvpl_cas_key.set_even_key_bytes("HD_even_key: " + std::to_string(index));
|
||||||
|
wvpl_cas_key.set_track_type(track_type);
|
||||||
|
wvpl_cas_key.set_key_type(ENTITLEMENT);
|
||||||
|
wvpl_cas_key.mutable_output_protection()->set_hdcp(HDCP_V2_2);
|
||||||
|
wvpl_cas_key.mutable_output_protection()->set_security_level(HW_SECURE_ALL);
|
||||||
|
wvpl_cas_key.mutable_output_protection()->set_secure_data_path(true);
|
||||||
|
wvpl_cas_key.mutable_output_protection()->set_cgms(COPY_NEVER);
|
||||||
|
return wvpl_cas_key;
|
||||||
|
}
|
||||||
|
|
||||||
|
~WvPLCASProxySessionTest() override {
|
||||||
|
if (wvpl_cas_proxy_session_ != nullptr) {
|
||||||
|
delete wvpl_cas_proxy_session_;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
WvPLCASProxySession* wvpl_cas_proxy_session_ = nullptr;
|
||||||
std::unique_ptr<DrmRootCertificate> drm_root_cert_;
|
std::unique_ptr<DrmRootCertificate> drm_root_cert_;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -153,5 +191,82 @@ TEST_F(WvPLCASProxySessionTest, ParseBadLicenseRequest) {
|
|||||||
EXPECT_EQ(SIGNED_MESSAGE_PARSE_ERROR, status.error_code());
|
EXPECT_EQ(SIGNED_MESSAGE_PARSE_ERROR, status.error_code());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(WvPLCASProxySessionTest, BuildCasDrmLicenseRequest) {
|
||||||
|
Create(kValidRequestFromCdm);
|
||||||
|
WvPLStatus status = Parse();
|
||||||
|
EXPECT_TRUE(status.ok());
|
||||||
|
CasDrmLicenseRequest cas_drm_license_request;
|
||||||
|
status = BuildRequest(&cas_drm_license_request);
|
||||||
|
EXPECT_TRUE(status.ok());
|
||||||
|
EXPECT_EQ(absl::HexStringToBytes(kValidRequestFromCdm),
|
||||||
|
cas_drm_license_request.payload());
|
||||||
|
EXPECT_EQ(kProvider, cas_drm_license_request.provider_id());
|
||||||
|
EXPECT_EQ(kContentId, cas_drm_license_request.content_id());
|
||||||
|
// No keys were specified in the license request,
|
||||||
|
EXPECT_EQ(0, cas_drm_license_request.content_key_specs().size());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(WvPLCASProxySessionTest, BuildCasDrmLicenseRequestNullProto) {
|
||||||
|
Create(kValidRequestFromCdm);
|
||||||
|
Parse();
|
||||||
|
WvPLStatus status = BuildRequest(nullptr);
|
||||||
|
EXPECT_EQ(INVALID_ARGUMENT, status.error_code());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(WvPLCASProxySessionTest,
|
||||||
|
BuildCasDrmLicenseRequestContentKeySpecsAlreadyExists) {
|
||||||
|
Create(kValidRequestFromCdm);
|
||||||
|
WvPLStatus status = Parse();
|
||||||
|
EXPECT_TRUE(status.ok());
|
||||||
|
CasDrmLicenseRequest cas_drm_license_request;
|
||||||
|
CasDrmLicenseRequest::ContentKeySpec* content_key_spec =
|
||||||
|
cas_drm_license_request.add_content_key_specs();
|
||||||
|
content_key_spec->set_security_level(License::KeyContainer::HW_SECURE_ALL);
|
||||||
|
status = BuildRequest(&cas_drm_license_request);
|
||||||
|
EXPECT_EQ(ALREADY_EXISTS, status.error_code());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(WvPLCASProxySessionTest, BuildCasDrmLicenseRequestWithKeys) {
|
||||||
|
Create(kValidRequestFromCdm);
|
||||||
|
Parse();
|
||||||
|
WvPLCasKey cas_key = BuildKey(0, VIDEO_HD, ENTITLEMENT);
|
||||||
|
WvPLStatus status = wvpl_cas_proxy_session_->AddCasKey(cas_key);
|
||||||
|
EXPECT_TRUE(status.ok());
|
||||||
|
CasDrmLicenseRequest cas_drm_license_request;
|
||||||
|
status = BuildRequest(&cas_drm_license_request);
|
||||||
|
EXPECT_TRUE(status.ok());
|
||||||
|
EXPECT_EQ(absl::HexStringToBytes(kValidRequestFromCdm),
|
||||||
|
cas_drm_license_request.payload());
|
||||||
|
EXPECT_EQ(kProvider, cas_drm_license_request.provider_id());
|
||||||
|
EXPECT_EQ(kContentId, cas_drm_license_request.content_id());
|
||||||
|
EXPECT_EQ(1, cas_drm_license_request.content_key_specs().size());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(WvPLCASProxySessionTest, CreateLicenseRequestAsJSON) {
|
||||||
|
Create(kValidRequestFromCdm);
|
||||||
|
WvPLStatus wvpl_status = Parse();
|
||||||
|
EXPECT_TRUE(wvpl_status.ok());
|
||||||
|
std::string json_signed_cas_drm_request;
|
||||||
|
wvpl_status = wvpl_cas_proxy_session_->GenerateLicenseRequestAsJSON(
|
||||||
|
&json_signed_cas_drm_request);
|
||||||
|
EXPECT_TRUE(wvpl_status.ok());
|
||||||
|
SignedCasDrmRequest signed_cas_drm_request;
|
||||||
|
auto status =
|
||||||
|
JsonStringToMessage(json_signed_cas_drm_request, &signed_cas_drm_request);
|
||||||
|
EXPECT_TRUE(status.ok());
|
||||||
|
EXPECT_EQ(kProvider, signed_cas_drm_request.signer());
|
||||||
|
EXPECT_EQ(kProvider, signed_cas_drm_request.provider());
|
||||||
|
EXPECT_TRUE(!signed_cas_drm_request.request().empty());
|
||||||
|
CasDrmLicenseRequest cas_drm_license_request;
|
||||||
|
status = JsonStringToMessage(signed_cas_drm_request.request(),
|
||||||
|
&cas_drm_license_request);
|
||||||
|
EXPECT_TRUE(status.ok());
|
||||||
|
EXPECT_EQ(absl::HexStringToBytes(kValidRequestFromCdm),
|
||||||
|
cas_drm_license_request.payload());
|
||||||
|
EXPECT_EQ(kProvider, cas_drm_license_request.provider_id());
|
||||||
|
EXPECT_EQ(kContentId, cas_drm_license_request.content_id());
|
||||||
|
EXPECT_EQ(0, cas_drm_license_request.content_key_specs().size());
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace wv_pl_sdk
|
} // namespace wv_pl_sdk
|
||||||
} // namespace widevine_server
|
} // namespace widevine_server
|
||||||
|
|||||||
@@ -33,6 +33,8 @@ proto_library(
|
|||||||
"verified_media_pipeline.proto",
|
"verified_media_pipeline.proto",
|
||||||
"widevine_pssh.proto",
|
"widevine_pssh.proto",
|
||||||
"license_services.proto",
|
"license_services.proto",
|
||||||
|
"media_cas_encryption.proto",
|
||||||
|
"media_cas_license.proto",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -241,3 +243,29 @@ java_proto_library(
|
|||||||
name = "widevine_pssh_java_proto",
|
name = "widevine_pssh_java_proto",
|
||||||
deps = [":widevine_pssh_proto_base"],
|
deps = [":widevine_pssh_proto_base"],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
proto_library(
|
||||||
|
name = "media_cas_license_proto_base",
|
||||||
|
srcs = ["media_cas_license.proto"],
|
||||||
|
deps = [
|
||||||
|
":license_protocol_proto_base",
|
||||||
|
":license_server_sdk_proto_base",
|
||||||
|
":errors_proto_base",
|
||||||
|
":media_cas_encryption_proto_base",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
cc_proto_library(
|
||||||
|
name = "media_cas_license_proto",
|
||||||
|
deps = [":media_cas_license_proto_base"],
|
||||||
|
)
|
||||||
|
|
||||||
|
proto_library(
|
||||||
|
name = "media_cas_encryption_proto_base",
|
||||||
|
srcs = ["media_cas_encryption.proto"],
|
||||||
|
)
|
||||||
|
|
||||||
|
cc_proto_library(
|
||||||
|
name = "media_cas_encryption_proto",
|
||||||
|
deps = [":media_cas_encryption_proto_base"],
|
||||||
|
)
|
||||||
|
|||||||
@@ -239,4 +239,10 @@ enum Errors {
|
|||||||
// Invalid method parameter.
|
// Invalid method parameter.
|
||||||
INVALID_PARAMETER = 170;
|
INVALID_PARAMETER = 170;
|
||||||
|
|
||||||
|
// Even KeyID not specified, CasEncryptionResponse.KeyInfo.KeySlot
|
||||||
|
MISSING_EVEN_KEY_ID = 171;
|
||||||
|
|
||||||
|
// Even Key not specified, CasEncryptionResponse.KeyInfo.KeySlot
|
||||||
|
MISSING_EVEN_KEY = 172;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
74
protos/public/media_cas_encryption.proto
Normal file
74
protos/public/media_cas_encryption.proto
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Copyright 2018 Google LLC.
|
||||||
|
//
|
||||||
|
// This software is licensed under the terms defined in the Widevine Master
|
||||||
|
// License Agreement. For a copy of this agreement, please contact
|
||||||
|
// widevine-licensing@google.com.
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Protocol buffer definitions for Widevine CAS.
|
||||||
|
|
||||||
|
syntax = "proto2";
|
||||||
|
|
||||||
|
option java_package = "com.google.video.widevine.mediacasencryption";
|
||||||
|
|
||||||
|
package widevine;
|
||||||
|
|
||||||
|
message CasEncryptionRequest {
|
||||||
|
optional bytes content_id = 1;
|
||||||
|
optional string provider = 2;
|
||||||
|
// Optional track types such as "AUDIO", SD" or "HD".
|
||||||
|
repeated string track_types = 3;
|
||||||
|
// Indicates if the client is using key rotation. If true, the server will
|
||||||
|
// return one key for EVEN and one key for ODD, otherwise only a single key is
|
||||||
|
// returned.
|
||||||
|
optional bool key_rotation = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
message CasEncryptionResponse {
|
||||||
|
enum Status {
|
||||||
|
STATUS_UNSPECIFIED = 0;
|
||||||
|
OK = 1;
|
||||||
|
SIGNATURE_FAILED = 2;
|
||||||
|
ACCESS_DENIED = 3;
|
||||||
|
INTERNAL_ERROR = 4;
|
||||||
|
INVALID_ARGUMENT = 5;
|
||||||
|
PROVIDER_ID_MISSING = 6;
|
||||||
|
CONTENT_ID_MISSING = 7;
|
||||||
|
TRACK_TYPE_MISSING = 8;
|
||||||
|
}
|
||||||
|
message KeyInfo {
|
||||||
|
enum KeySlot {
|
||||||
|
KEY_SLOT_UNSPECIFIED = 0;
|
||||||
|
SINGLE = 1;
|
||||||
|
EVEN = 2;
|
||||||
|
ODD = 3;
|
||||||
|
};
|
||||||
|
optional bytes key_id = 1;
|
||||||
|
optional bytes key = 2;
|
||||||
|
// Optional label used for the key.
|
||||||
|
optional string track_type = 3;
|
||||||
|
optional KeySlot key_slot = 4;
|
||||||
|
}
|
||||||
|
optional Status status = 1;
|
||||||
|
optional string status_message = 2;
|
||||||
|
optional bytes content_id = 3;
|
||||||
|
repeated KeyInfo entitlement_keys = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
message SignedCasEncryptionRequest {
|
||||||
|
optional bytes request = 1;
|
||||||
|
optional bytes signature = 2;
|
||||||
|
// Identifies the entity sending / signing the request.
|
||||||
|
optional string signer = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message SignedCasEncryptionResponse {
|
||||||
|
// Serialized CasEncryptionResponse message.
|
||||||
|
optional bytes response = 1;
|
||||||
|
optional bytes signature = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message HttpResponse {
|
||||||
|
optional bytes response = 1;
|
||||||
|
}
|
||||||
110
protos/public/media_cas_license.proto
Normal file
110
protos/public/media_cas_license.proto
Normal file
@@ -0,0 +1,110 @@
|
|||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Copyright 2018 Google LLC.
|
||||||
|
//
|
||||||
|
// This software is licensed under the terms defined in the Widevine Master
|
||||||
|
// License Agreement. For a copy of this agreement, please contact
|
||||||
|
// widevine-licensing@google.com.
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Description:
|
||||||
|
// Definitions of the protocol buffer messages used in the Widevine license
|
||||||
|
// exchange protocol for Media CAS.
|
||||||
|
|
||||||
|
syntax = "proto2";
|
||||||
|
|
||||||
|
option java_package = "com.google.video.widevine.mediacaslicense";
|
||||||
|
|
||||||
|
import "protos/public/license_protocol.proto";
|
||||||
|
import "protos/public/license_server_sdk.proto";
|
||||||
|
import "protos/public/media_cas_encryption.proto";
|
||||||
|
|
||||||
|
package widevine;
|
||||||
|
|
||||||
|
message CasDrmLicenseRequest {
|
||||||
|
// The request payload. This is usually the HTTP Post body of a request.
|
||||||
|
// Required.
|
||||||
|
optional bytes payload = 1;
|
||||||
|
// The content provider whose proxy is sending this license request onto the
|
||||||
|
// Widevine license service. Required.
|
||||||
|
optional string provider_id = 2;
|
||||||
|
// An identifier supplied by a content provider, used to identify a piece of
|
||||||
|
// content and derive key IDs and content keys.
|
||||||
|
optional bytes content_id = 3;
|
||||||
|
// A ContentKeySpec identifies a content key by track type name. It also
|
||||||
|
// specifies the policy that should be used for this key.
|
||||||
|
// TODO(user): Consolidate this ContentKeySpec with
|
||||||
|
// ModularDrmLicenseRequest_ContentKeySpec. Both should include a common
|
||||||
|
// ContentKeySpec.
|
||||||
|
message ContentKeySpec {
|
||||||
|
optional License.KeyContainer.SecurityLevel security_level = 1;
|
||||||
|
optional License.KeyContainer.OutputProtection required_output_protection =
|
||||||
|
2;
|
||||||
|
optional License.KeyContainer.OutputProtection requested_output_protection =
|
||||||
|
3;
|
||||||
|
// Optionally specify even, odd or single slot for key rotation.
|
||||||
|
repeated CasEncryptionResponse.KeyInfo entitlement_keys = 4;
|
||||||
|
optional License.KeyContainer.KeyType key_type = 5;
|
||||||
|
}
|
||||||
|
repeated ContentKeySpec content_key_specs = 4;
|
||||||
|
// Policy for the entire license such as playback duration.
|
||||||
|
optional License.Policy policy = 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
message CasDrmLicenseResponse {
|
||||||
|
enum Status {
|
||||||
|
UNKNOWN = 0;
|
||||||
|
OK = 1;
|
||||||
|
SIGNATURE_FAILED = 2;
|
||||||
|
INVALID_LICENSE_CHALLENGE = 3;
|
||||||
|
PROVIDER_ID_MISSING = 4;
|
||||||
|
INVALID_CONTENT_INFO = 5;
|
||||||
|
EMPTY_CONTENT_INFO = 6;
|
||||||
|
CONTENT_ID_MISMATCH = 7;
|
||||||
|
MISSING_CONTENT_ID = 8;
|
||||||
|
MALFORMED_REQUEST = 9;
|
||||||
|
INTERNAL_ERROR = 10;
|
||||||
|
}
|
||||||
|
optional Status status = 1;
|
||||||
|
optional string status_message = 2;
|
||||||
|
// Serialzed bytes for a CAS license.
|
||||||
|
// TODO(user): Until a CAS license protocol is defined, this field is a
|
||||||
|
// serialized License message defined in license_protocol.proto.
|
||||||
|
optional bytes license = 3;
|
||||||
|
// Actual SDK license status as defined in widevine/server/sdk/error.proto.
|
||||||
|
optional uint32 internal_status = 4;
|
||||||
|
// Indicates the type of message in the license response.
|
||||||
|
optional SignedMessage.MessageType message_type = 5;
|
||||||
|
// A subset of data from the Widevine PSSH.
|
||||||
|
message PsshData {
|
||||||
|
repeated bytes key_id = 1;
|
||||||
|
optional bytes content_id = 2;
|
||||||
|
}
|
||||||
|
message LicenseMetadata {
|
||||||
|
optional bytes content_id = 1;
|
||||||
|
repeated bytes key_id = 2;
|
||||||
|
}
|
||||||
|
optional PsshData pssh_data = 6;
|
||||||
|
optional SessionState session_state = 7;
|
||||||
|
optional string content_owner = 8;
|
||||||
|
optional string content_provider = 9;
|
||||||
|
optional LicenseMetadata license_metadata = 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
message SignedCasDrmRequest {
|
||||||
|
optional bytes request = 1;
|
||||||
|
optional bytes signature = 2;
|
||||||
|
// Identifies the entity sending / signing the request. Required if signature
|
||||||
|
// is present.
|
||||||
|
optional string signer = 3;
|
||||||
|
// The IP Address of the portal that is forwarding the request from the
|
||||||
|
// original sender.
|
||||||
|
optional string client_ip_address = 4;
|
||||||
|
// The client software identifier, as used by HTTP.
|
||||||
|
optional string user_agent = 5;
|
||||||
|
optional string provider = 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
message SignedCasDrmResponse {
|
||||||
|
optional bytes response = 1;
|
||||||
|
optional bytes signature = 2;
|
||||||
|
}
|
||||||
45
sdk/external/common/wvpl/wvpl_sdk_session.cc
vendored
45
sdk/external/common/wvpl/wvpl_sdk_session.cc
vendored
@@ -59,6 +59,12 @@ using widevine::WidevinePsshData;
|
|||||||
namespace error = widevine::error;
|
namespace error = widevine::error;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
const char kTrackTypeAudio[] = "AUDIO";
|
||||||
|
const char kTrackTypeHd[] = "HD";
|
||||||
|
const char kTrackTypeSd[] = "SD";
|
||||||
|
const char kTrackTypeUhd1[] = "UHD1";
|
||||||
|
const char kTrackTypeUhd2[] = "UHD2";
|
||||||
|
|
||||||
void CopyHdcpSrmRule(
|
void CopyHdcpSrmRule(
|
||||||
widevine_server::wv_pl_sdk::HdcpSrmRule hdcp_srm_rule,
|
widevine_server::wv_pl_sdk::HdcpSrmRule hdcp_srm_rule,
|
||||||
License::KeyContainer::OutputProtection* output_protection) {
|
License::KeyContainer::OutputProtection* output_protection) {
|
||||||
@@ -571,19 +577,13 @@ WvPLStatus WvPLSDKSession::ParseLicenseRequest() {
|
|||||||
has_pssh_data_ = true;
|
has_pssh_data_ = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
switch (sdk_license_request_->type()) {
|
// Set WvPLRequest Type.
|
||||||
case LicenseRequest::NEW:
|
LicenseRequestType request_type =
|
||||||
request_type_ = LicenseRequestType::NEW;
|
static_cast<LicenseRequestType>(sdk_license_request_->type());
|
||||||
break;
|
type_.set_license_request_type(request_type);
|
||||||
case LicenseRequest::RENEWAL:
|
type_.set_message_type(message_type_);
|
||||||
request_type_ = LicenseRequestType::RENEWAL;
|
if (is_offline_license()) {
|
||||||
break;
|
type_.set_license_type(OFFLINE);
|
||||||
case LicenseRequest::RELEASE:
|
|
||||||
request_type_ = LicenseRequestType::RELEASE;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
request_type_ = LicenseRequestType::REQUEST_TYPE_UNSPECIFIED;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return OkStatus();
|
return OkStatus();
|
||||||
@@ -942,5 +942,24 @@ bool WvPLSDKSession::is_offline_license() const {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const std::string WvPLSDKSession::TrackTypeToString(TrackType track_type) const {
|
||||||
|
switch (track_type) {
|
||||||
|
case AUDIO:
|
||||||
|
return kTrackTypeAudio;
|
||||||
|
case VIDEO_SD:
|
||||||
|
return kTrackTypeSd;
|
||||||
|
case VIDEO_HD:
|
||||||
|
return kTrackTypeHd;
|
||||||
|
case VIDEO_UHD1:
|
||||||
|
return kTrackTypeUhd1;
|
||||||
|
case VIDEO_UHD2:
|
||||||
|
return kTrackTypeUhd2;
|
||||||
|
case TRACK_TYPE_UNSPECIFIED:
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return std::string();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace wv_pl_sdk
|
} // namespace wv_pl_sdk
|
||||||
} // namespace widevine_server
|
} // namespace widevine_server
|
||||||
|
|||||||
8
sdk/external/common/wvpl/wvpl_sdk_session.h
vendored
8
sdk/external/common/wvpl/wvpl_sdk_session.h
vendored
@@ -99,12 +99,14 @@ class WvPLSDKSession {
|
|||||||
* Returns the type of the message handled by this session.
|
* Returns the type of the message handled by this session.
|
||||||
*
|
*
|
||||||
* @return MessageType enumeration.
|
* @return MessageType enumeration.
|
||||||
|
* @deprecated use request_type instead.
|
||||||
|
* @since end of Q1, 2019
|
||||||
*/
|
*/
|
||||||
virtual MessageType message_type() const;
|
virtual MessageType message_type() const;
|
||||||
|
|
||||||
virtual PlatformVerificationStatus VerifyPlatform() = 0;
|
virtual PlatformVerificationStatus VerifyPlatform() = 0;
|
||||||
|
|
||||||
virtual LicenseRequestType request_type() const { return request_type_; }
|
virtual WvPLRequestType request_type() const { return type_; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if the license type is offline, otherwise return false.
|
* Returns true if the license type is offline, otherwise return false.
|
||||||
@@ -164,7 +166,7 @@ class WvPLSDKSession {
|
|||||||
std::string license_request_from_cdm_;
|
std::string license_request_from_cdm_;
|
||||||
std::string remote_attestation_cert_serial_number_;
|
std::string remote_attestation_cert_serial_number_;
|
||||||
std::unique_ptr<widevine::LicenseRequest> sdk_license_request_;
|
std::unique_ptr<widevine::LicenseRequest> sdk_license_request_;
|
||||||
LicenseRequestType request_type_;
|
WvPLRequestType type_;
|
||||||
bool has_session_state_ = false;
|
bool has_session_state_ = false;
|
||||||
bool has_encrypted_client_id_ = false;
|
bool has_encrypted_client_id_ = false;
|
||||||
|
|
||||||
@@ -244,6 +246,8 @@ class WvPLSDKSession {
|
|||||||
uint32_t system_id,
|
uint32_t system_id,
|
||||||
widevine::ProvisionedDeviceInfo* provisioned_device_info) const;
|
widevine::ProvisionedDeviceInfo* provisioned_device_info) const;
|
||||||
|
|
||||||
|
virtual const std::string TrackTypeToString(TrackType track_type) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<uint32_t> system_id_;
|
std::unique_ptr<uint32_t> system_id_;
|
||||||
};
|
};
|
||||||
|
|||||||
9
sdk/external/common/wvpl/wvpl_types.h
vendored
9
sdk/external/common/wvpl/wvpl_types.h
vendored
@@ -1015,12 +1015,13 @@ struct WvPLCasKey {
|
|||||||
|
|
||||||
TrackType track_type() const { return track_type_; }
|
TrackType track_type() const { return track_type_; }
|
||||||
|
|
||||||
void set_output_protection(const WvPLOutputProtection& out_prot) {
|
void set_output_protection(const WvPLOutputProtection& output_protection) {
|
||||||
output_protection_ = out_prot;
|
output_protection_ = output_protection;
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_requested_output_protection(const WvPLOutputProtection& out_prot) {
|
void set_requested_output_protection(
|
||||||
requested_output_protection_ = out_prot;
|
const WvPLOutputProtection& output_protection) {
|
||||||
|
requested_output_protection_ = output_protection;
|
||||||
}
|
}
|
||||||
|
|
||||||
const WvPLOutputProtection& output_protection() const {
|
const WvPLOutputProtection& output_protection() const {
|
||||||
|
|||||||
Reference in New Issue
Block a user