Replace hardcoded parameters
This commit is contained in:
@@ -46,10 +46,9 @@ cc_library(
|
||||
"@abseil_repo//absl/base:core_headers",
|
||||
"//common:status",
|
||||
"//media_cas_packager_sdk/internal:ecm",
|
||||
"//media_cas_packager_sdk/internal:ecm_generator",
|
||||
"//media_cas_packager_sdk/internal:key_fetcher",
|
||||
"//protos/public:media_cas_encryption_proto",
|
||||
"//protos/public:media_cas_proto",
|
||||
"//protos/public:media_cas_cc_proto",
|
||||
"//protos/public:media_cas_encryption_cc_proto",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -65,8 +64,11 @@ cc_library(
|
||||
"@abseil_repo//absl/strings",
|
||||
"//common:status",
|
||||
"//common:string_util",
|
||||
"//protos/public:media_cas_proto",
|
||||
"//protos/public:media_cas_cc_proto",
|
||||
],
|
||||
# Make sure libmedia_cas_packager_sdk links in symbols defined in this
|
||||
# target.
|
||||
alwayslink = 1,
|
||||
)
|
||||
|
||||
cc_test(
|
||||
@@ -77,7 +79,7 @@ cc_test(
|
||||
":wv_cas_ca_descriptor",
|
||||
":wv_cas_types",
|
||||
"//testing:gunit_main",
|
||||
"//protos/public:media_cas_proto",
|
||||
"//protos/public:media_cas_cc_proto",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -96,11 +98,13 @@ cc_library(
|
||||
"//common:status",
|
||||
"//example:constants",
|
||||
"//media_cas_packager_sdk/internal:ecm",
|
||||
"//media_cas_packager_sdk/internal:ecm_generator",
|
||||
"//media_cas_packager_sdk/internal:fixed_key_fetcher",
|
||||
"//media_cas_packager_sdk/internal:mpeg2ts",
|
||||
"//media_cas_packager_sdk/internal:util",
|
||||
],
|
||||
# Make sure libmedia_cas_packager_sdk links in symbols defined in this
|
||||
# target.
|
||||
alwayslink = 1,
|
||||
)
|
||||
|
||||
cc_test(
|
||||
@@ -126,6 +130,7 @@ cc_library(
|
||||
],
|
||||
deps = [
|
||||
"//base",
|
||||
"//external:protobuf",
|
||||
"@abseil_repo//absl/base:core_headers",
|
||||
"@abseil_repo//absl/strings",
|
||||
"@curl_repo//:curl",
|
||||
@@ -133,7 +138,7 @@ cc_library(
|
||||
"//common:signature_util",
|
||||
"//common:status",
|
||||
"//media_cas_packager_sdk/internal:key_fetcher",
|
||||
"//protos/public:media_cas_encryption_proto",
|
||||
"//protos/public:media_cas_encryption_cc_proto",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -149,7 +154,7 @@ cc_test(
|
||||
"//external:protobuf",
|
||||
"//testing:gunit_main",
|
||||
"@abseil_repo//absl/strings",
|
||||
"//protos/public:media_cas_encryption_proto",
|
||||
"//protos/public:media_cas_encryption_cc_proto",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -160,8 +165,12 @@ cc_library(
|
||||
copts = PUBLIC_COPTS,
|
||||
deps = [
|
||||
"//base",
|
||||
"//protos/public:media_cas_encryption_proto",
|
||||
"//external:protobuf",
|
||||
"//protos/public:media_cas_encryption_cc_proto",
|
||||
],
|
||||
# Make sure libmedia_cas_packager_sdk links in symbols defined in this
|
||||
# target.
|
||||
alwayslink = 1,
|
||||
)
|
||||
|
||||
cc_test(
|
||||
@@ -178,6 +187,7 @@ cc_binary(
|
||||
name = "wv_ecmg",
|
||||
srcs = ["wv_ecmg.cc"],
|
||||
deps = [
|
||||
":wv_cas_types",
|
||||
"//base",
|
||||
"@abseil_repo//absl/base:core_headers",
|
||||
"@abseil_repo//absl/strings",
|
||||
|
||||
@@ -45,8 +45,8 @@ static constexpr uint32_t kCaDescriptorTag = 9;
|
||||
// https://en.wikipedia.org/wiki/Conditional_access
|
||||
static constexpr uint32_t kWidevineCaSystemId = 0x4AD4;
|
||||
|
||||
// Value for CA descriptor reserved field.
|
||||
static constexpr uint32_t kUnusedZero = 0;
|
||||
// Value for CA descriptor reserved field should be set to 1.
|
||||
static constexpr uint32_t kReservedBit = 0x0007;
|
||||
|
||||
// The range of valid PIDs, from section 2.4.3.3, and table 2-3.
|
||||
static constexpr uint32_t kMinValidPID = 0x0010;
|
||||
@@ -83,7 +83,7 @@ WvCasStatus WvCasCaDescriptor::GenerateCaDescriptor(
|
||||
// including private bytes.
|
||||
std::bitset<kNumBitsCaDescriptorLengthField> length(descriptor_length);
|
||||
std::bitset<kNumBitsCaSystemIdField> ca_system_id(kWidevineCaSystemId);
|
||||
std::bitset<kNumBitsCaDescriptorReservedField> reserved(kUnusedZero);
|
||||
std::bitset<kNumBitsCaDescriptorReservedField> reserved(kReservedBit);
|
||||
std::bitset<kNumBitsCaDescriptorPidField> pid(ca_pid);
|
||||
|
||||
// Converts bitset to a std::string where each char represents a bit.
|
||||
@@ -110,8 +110,8 @@ size_t WvCasCaDescriptor::CaDescriptorBaseSize() const {
|
||||
return kCaDescriptorBaseSize;
|
||||
}
|
||||
|
||||
std::string WvCasCaDescriptor::GeneratePrivateData(const std::string& provider,
|
||||
const std::string& content_id) const {
|
||||
std::string WvCasCaDescriptor::GeneratePrivateData(
|
||||
const std::string& provider, const std::string& content_id) const {
|
||||
CaDescriptorPrivateData private_data;
|
||||
private_data.set_provider(provider);
|
||||
private_data.set_content_id(content_id);
|
||||
|
||||
@@ -53,10 +53,9 @@ class WvCasCaDescriptor {
|
||||
// section (for an EMM stream) or into a TS Program Map Table section (for an
|
||||
// ECM stream). The descriptor will be 6 bytes plus any bytes added as
|
||||
// (user-defined) private data.
|
||||
virtual WvCasStatus GenerateCaDescriptor(uint16_t ca_pid,
|
||||
const std::string& provider,
|
||||
const std::string& content_id,
|
||||
std::string* serialized_ca_desc) const;
|
||||
virtual WvCasStatus GenerateCaDescriptor(
|
||||
uint16_t ca_pid, const std::string& provider, const std::string& content_id,
|
||||
std::string* serialized_ca_desc) const;
|
||||
|
||||
// Return the base size (before private data is added) of the CA
|
||||
// descriptor. The user can call this to plan the layout of the Table section
|
||||
@@ -65,7 +64,7 @@ class WvCasCaDescriptor {
|
||||
|
||||
// Return private data in the CA descriptor.
|
||||
virtual std::string GeneratePrivateData(const std::string& provider,
|
||||
const std::string& content_id) const;
|
||||
const std::string& content_id) const;
|
||||
};
|
||||
|
||||
} // namespace cas
|
||||
|
||||
@@ -42,7 +42,7 @@ TEST_F(WvCasCaDescriptorTest, BaseSize) {
|
||||
TEST_F(WvCasCaDescriptorTest, BasicGoodGen) {
|
||||
EXPECT_EQ(OK, ca_descriptor_.GenerateCaDescriptor(kTestPid, "", "",
|
||||
&actual_ca_descriptor_));
|
||||
const std::string expected_ca_descriptor("\x09\x04\x4a\xd4\x00\x32", 6);
|
||||
const std::string expected_ca_descriptor("\x09\x04\x4a\xd4\xE0\x32", 6);
|
||||
EXPECT_EQ(expected_ca_descriptor, actual_ca_descriptor_);
|
||||
}
|
||||
|
||||
@@ -61,7 +61,7 @@ TEST_F(WvCasCaDescriptorTest, PidMinOK) {
|
||||
const uint32_t min_pid = 0x10;
|
||||
EXPECT_EQ(OK, ca_descriptor_.GenerateCaDescriptor(min_pid, "", "",
|
||||
&actual_ca_descriptor_));
|
||||
const std::string expected_ca_descriptor("\x09\x04\x4a\xd4\x00\x10", 6);
|
||||
const std::string expected_ca_descriptor("\x09\x04\x4a\xd4\xE0\x10", 6);
|
||||
EXPECT_EQ(expected_ca_descriptor, actual_ca_descriptor_);
|
||||
}
|
||||
|
||||
@@ -69,7 +69,7 @@ TEST_F(WvCasCaDescriptorTest, PidMaxOK) {
|
||||
const uint32_t max_pid = 0x1FFE;
|
||||
EXPECT_EQ(OK, ca_descriptor_.GenerateCaDescriptor(max_pid, "", "",
|
||||
&actual_ca_descriptor_));
|
||||
const std::string expected_ca_descriptor("\x09\x04\x4a\xd4\x1f\xfe");
|
||||
const std::string expected_ca_descriptor("\x09\x04\x4a\xd4\xff\xfe");
|
||||
EXPECT_EQ(expected_ca_descriptor, actual_ca_descriptor_);
|
||||
}
|
||||
|
||||
@@ -82,77 +82,77 @@ TEST_F(WvCasCaDescriptorTest, PidTooHighFail) {
|
||||
TEST_F(WvCasCaDescriptorTest, PidOneByte) {
|
||||
EXPECT_EQ(OK, ca_descriptor_.GenerateCaDescriptor(255, "", "",
|
||||
&actual_ca_descriptor_));
|
||||
const std::string expected_ca_descriptor("\x09\x04\x4a\xd4\x00\xff", 6);
|
||||
const std::string expected_ca_descriptor("\x09\x04\x4a\xd4\xe0\xff", 6);
|
||||
EXPECT_EQ(expected_ca_descriptor, actual_ca_descriptor_);
|
||||
}
|
||||
|
||||
TEST_F(WvCasCaDescriptorTest, PidSecondByte) {
|
||||
EXPECT_EQ(OK, ca_descriptor_.GenerateCaDescriptor(0x1F00, "", "",
|
||||
&actual_ca_descriptor_));
|
||||
const std::string expected_ca_descriptor("\x09\x04\x4a\xd4\x1f\x00", 6);
|
||||
const std::string expected_ca_descriptor("\x09\x04\x4a\xd4\xff\x00", 6);
|
||||
EXPECT_EQ(expected_ca_descriptor, actual_ca_descriptor_);
|
||||
}
|
||||
|
||||
TEST_F(WvCasCaDescriptorTest, PidTwelveBits) {
|
||||
EXPECT_EQ(OK, ca_descriptor_.GenerateCaDescriptor(0xFFF, "", "",
|
||||
&actual_ca_descriptor_));
|
||||
const std::string expected_ca_descriptor("\x09\x04\x4a\xd4\x0f\xff");
|
||||
const std::string expected_ca_descriptor("\x09\x04\x4a\xd4\xef\xff");
|
||||
EXPECT_EQ(expected_ca_descriptor, actual_ca_descriptor_);
|
||||
}
|
||||
|
||||
TEST_F(WvCasCaDescriptorTest, PidThirteenthBit) {
|
||||
EXPECT_EQ(OK, ca_descriptor_.GenerateCaDescriptor(0x1000, "", "",
|
||||
&actual_ca_descriptor_));
|
||||
const std::string expected_ca_descriptor("\x09\x04\x4a\xd4\x10\x00", 6);
|
||||
const std::string expected_ca_descriptor("\x09\x04\x4a\xd4\xf0\x00", 6);
|
||||
EXPECT_EQ(expected_ca_descriptor, actual_ca_descriptor_);
|
||||
}
|
||||
|
||||
TEST_F(WvCasCaDescriptorTest, PidTwelthBit) {
|
||||
EXPECT_EQ(OK, ca_descriptor_.GenerateCaDescriptor(0x800, "", "",
|
||||
&actual_ca_descriptor_));
|
||||
const std::string expected_ca_descriptor("\x09\x04\x4a\xd4\x08\x00", 6);
|
||||
const std::string expected_ca_descriptor("\x09\x04\x4a\xd4\xe8\x00", 6);
|
||||
EXPECT_EQ(expected_ca_descriptor, actual_ca_descriptor_);
|
||||
}
|
||||
|
||||
TEST_F(WvCasCaDescriptorTest, PidElevenththBit) {
|
||||
EXPECT_EQ(OK, ca_descriptor_.GenerateCaDescriptor(0x400, "", "",
|
||||
&actual_ca_descriptor_));
|
||||
const std::string expected_ca_descriptor("\x09\x04\x4a\xd4\x04\x00", 6);
|
||||
const std::string expected_ca_descriptor("\x09\x04\x4a\xd4\xe4\x00", 6);
|
||||
EXPECT_EQ(expected_ca_descriptor, actual_ca_descriptor_);
|
||||
}
|
||||
|
||||
TEST_F(WvCasCaDescriptorTest, PidTenthBit) {
|
||||
EXPECT_EQ(OK, ca_descriptor_.GenerateCaDescriptor(0x200, "", "",
|
||||
&actual_ca_descriptor_));
|
||||
const std::string expected_ca_descriptor("\x09\x04\x4a\xd4\x02\x00", 6);
|
||||
const std::string expected_ca_descriptor("\x09\x04\x4a\xd4\xe2\x00", 6);
|
||||
EXPECT_EQ(expected_ca_descriptor, actual_ca_descriptor_);
|
||||
}
|
||||
|
||||
TEST_F(WvCasCaDescriptorTest, PidNinthBit) {
|
||||
EXPECT_EQ(OK, ca_descriptor_.GenerateCaDescriptor(0x100, "", "",
|
||||
&actual_ca_descriptor_));
|
||||
const std::string expected_ca_descriptor("\x09\x04\x4a\xd4\x01\x00", 6);
|
||||
const std::string expected_ca_descriptor("\x09\x04\x4a\xd4\xe1\x00", 6);
|
||||
EXPECT_EQ(expected_ca_descriptor, actual_ca_descriptor_);
|
||||
}
|
||||
|
||||
TEST_F(WvCasCaDescriptorTest, PrivateDataOnlyProviderIgnored) {
|
||||
EXPECT_EQ(OK, ca_descriptor_.GenerateCaDescriptor(kTestPid, kProvider, "",
|
||||
&actual_ca_descriptor_));
|
||||
const std::string expected_ca_descriptor("\x09\x04\x4a\xd4\x00\x32", 6);
|
||||
const std::string expected_ca_descriptor("\x09\x04\x4a\xd4\xe0\x32", 6);
|
||||
EXPECT_EQ(expected_ca_descriptor, actual_ca_descriptor_);
|
||||
}
|
||||
|
||||
TEST_F(WvCasCaDescriptorTest, PrivateDataOnlyContentIdIgnored) {
|
||||
EXPECT_EQ(OK, ca_descriptor_.GenerateCaDescriptor(kTestPid, "", kContentId,
|
||||
&actual_ca_descriptor_));
|
||||
const std::string expected_ca_descriptor("\x09\x04\x4a\xd4\x00\x32", 6);
|
||||
const std::string expected_ca_descriptor("\x09\x04\x4a\xd4\xe0\x32", 6);
|
||||
EXPECT_EQ(expected_ca_descriptor, actual_ca_descriptor_);
|
||||
}
|
||||
|
||||
TEST_F(WvCasCaDescriptorTest, PrivateData) {
|
||||
EXPECT_EQ(OK, ca_descriptor_.GenerateCaDescriptor(
|
||||
kTestPid, kProvider, kContentId, &actual_ca_descriptor_));
|
||||
const std::string expected_ca_descriptor("\x09\x19\x4a\xd4\x00\x32", 6);
|
||||
const std::string expected_ca_descriptor("\x09\x19\x4a\xd4\xe0\x32", 6);
|
||||
CaDescriptorPrivateData private_data;
|
||||
private_data.set_provider(kProvider);
|
||||
private_data.set_content_id(kContentId);
|
||||
@@ -162,10 +162,13 @@ TEST_F(WvCasCaDescriptorTest, PrivateData) {
|
||||
|
||||
class FakePrivateDataCaDescriptor : public WvCasCaDescriptor {
|
||||
public:
|
||||
void set_private_data(std::string private_data) { private_data_ = private_data; }
|
||||
void set_private_data(std::string private_data) {
|
||||
private_data_ = private_data;
|
||||
}
|
||||
|
||||
std::string GeneratePrivateData(const std::string& provider,
|
||||
const std::string& content_id) const override {
|
||||
std::string GeneratePrivateData(
|
||||
const std::string& provider,
|
||||
const std::string& content_id) const override {
|
||||
return private_data_;
|
||||
}
|
||||
|
||||
@@ -178,7 +181,7 @@ TEST_F(WvCasCaDescriptorTest, PrivateDataOneByte) {
|
||||
fake_descriptor.set_private_data("X");
|
||||
EXPECT_EQ(OK, fake_descriptor.GenerateCaDescriptor(
|
||||
kTestPid, kProvider, kContentId, &actual_ca_descriptor_));
|
||||
const std::string expected_ca_descriptor("\x09\x05\x4a\xd4\x00\x32X", 7);
|
||||
const std::string expected_ca_descriptor("\x09\x05\x4a\xd4\xe0\x32X", 7);
|
||||
EXPECT_EQ(expected_ca_descriptor, actual_ca_descriptor_);
|
||||
}
|
||||
|
||||
@@ -188,7 +191,7 @@ TEST_F(WvCasCaDescriptorTest, PrivateDataMultipleBytes) {
|
||||
fake_descriptor.set_private_data(private_data_bytes);
|
||||
EXPECT_EQ(OK, fake_descriptor.GenerateCaDescriptor(
|
||||
kTestPid, kProvider, kContentId, &actual_ca_descriptor_));
|
||||
const std::string expected_ca_descriptor("\x09\x0e\x4a\xd4\x00\x32", 6);
|
||||
const std::string expected_ca_descriptor("\x09\x0e\x4a\xd4\xe0\x32", 6);
|
||||
EXPECT_EQ(expected_ca_descriptor + private_data_bytes, actual_ca_descriptor_);
|
||||
}
|
||||
|
||||
@@ -198,7 +201,7 @@ TEST_F(WvCasCaDescriptorTest, PrivateDataMaxNumberBytes) {
|
||||
fake_descriptor.set_private_data(private_data_bytes);
|
||||
EXPECT_EQ(OK, fake_descriptor.GenerateCaDescriptor(
|
||||
kTestPid, kProvider, kContentId, &actual_ca_descriptor_));
|
||||
const std::string expected_ca_descriptor("\x09\xff\x4a\xd4\x00\x32", 6);
|
||||
const std::string expected_ca_descriptor("\x09\xff\x4a\xd4\xe0\x32", 6);
|
||||
EXPECT_EQ(expected_ca_descriptor + private_data_bytes, actual_ca_descriptor_);
|
||||
}
|
||||
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
#include "common/status.h"
|
||||
#include "example/constants.h"
|
||||
#include "media_cas_packager_sdk/internal/ecm.h"
|
||||
#include "media_cas_packager_sdk/internal/ecm_generator.h"
|
||||
#include "media_cas_packager_sdk/internal/fixed_key_fetcher.h"
|
||||
#include "media_cas_packager_sdk/internal/mpeg2ts.h"
|
||||
#include "media_cas_packager_sdk/internal/util.h"
|
||||
@@ -115,9 +114,9 @@ WvCasStatus WvCasEcm::GenerateEcm(
|
||||
}
|
||||
std::string even_content_iv_str(even_content_iv, content_iv_size_);
|
||||
std::string even_entitlement_key_id_str(even_entitlement_key_id,
|
||||
kEntitlementKeyIdSizeBytes);
|
||||
kEntitlementKeyIdSizeBytes);
|
||||
std::string even_entitlement_key_str(even_entitlement_key,
|
||||
kEntitlementKeySizeBytes);
|
||||
kEntitlementKeySizeBytes);
|
||||
std::string odd_key_str;
|
||||
if (crypto_mode_ == CryptoMode::kDvbCsa2) {
|
||||
odd_key_str = std::string(odd_key, kCsaContentKeySizeBytes);
|
||||
@@ -127,8 +126,9 @@ WvCasStatus WvCasEcm::GenerateEcm(
|
||||
}
|
||||
std::string odd_content_iv_str(odd_content_iv, content_iv_size_);
|
||||
std::string odd_entitlement_key_id_str(odd_entitlement_key_id,
|
||||
kEntitlementKeyIdSizeBytes);
|
||||
std::string odd_entitlement_key_str(odd_entitlement_key, kEntitlementKeySizeBytes);
|
||||
kEntitlementKeyIdSizeBytes);
|
||||
std::string odd_entitlement_key_str(odd_entitlement_key,
|
||||
kEntitlementKeySizeBytes);
|
||||
|
||||
// Double check some input sizes.
|
||||
if (even_key_str.size() != kContentKeySizeBytes ||
|
||||
@@ -143,7 +143,7 @@ WvCasStatus WvCasEcm::GenerateEcm(
|
||||
}
|
||||
|
||||
// Create an instance of Ecm in order to set the entitlement keys.
|
||||
std::unique_ptr<Ecm> cas_ecm = absl::make_unique<Ecm>();
|
||||
auto cas_ecm = absl::make_unique<Ecm>();
|
||||
std::string entitlement_request;
|
||||
std::string entitlement_response;
|
||||
EcmInitParameters ecm_init_params = CreateEcmInitParameters(
|
||||
@@ -179,23 +179,21 @@ WvCasStatus WvCasEcm::GenerateEcm(
|
||||
}
|
||||
|
||||
// Generate ECM.
|
||||
EcmGenerator ecm_generator;
|
||||
ecm_generator.set_ecm(std::move(cas_ecm));
|
||||
EcmParameters ecm_param;
|
||||
ecm_param.rotation_enabled = key_rotation_enabled_;
|
||||
std::vector<EntitledKeyInfo> keys;
|
||||
keys.reserve(2);
|
||||
// Add even entitlement key.
|
||||
ecm_param.key_params.emplace_back();
|
||||
ecm_param.key_params[0].key_data = even_key_str;
|
||||
ecm_param.key_params[0].wrapped_key_iv = crypto_util::DeriveIv(even_key_str);
|
||||
ecm_param.key_params[0].key_id = crypto_util::DeriveKeyId(even_key_str);
|
||||
ecm_param.key_params[0].content_ivs.push_back(even_content_iv_str);
|
||||
keys.emplace_back();
|
||||
keys[0].key_value = even_key_str;
|
||||
keys[0].wrapped_key_iv = crypto_util::DeriveIv(even_key_str);
|
||||
keys[0].key_id = crypto_util::DeriveKeyId(even_key_str);
|
||||
keys[0].content_iv = even_content_iv_str;
|
||||
// Add odd entitlement key.
|
||||
ecm_param.key_params.emplace_back();
|
||||
ecm_param.key_params[1].key_data = odd_key_str;
|
||||
ecm_param.key_params[1].wrapped_key_iv = crypto_util::DeriveIv(odd_key_str);
|
||||
ecm_param.key_params[1].key_id = crypto_util::DeriveKeyId(odd_key_str);
|
||||
ecm_param.key_params[1].content_ivs.push_back(odd_content_iv_str);
|
||||
*ecm = ecm_generator.GenerateEcm(ecm_param);
|
||||
keys.emplace_back();
|
||||
keys[1].key_value = odd_key_str;
|
||||
keys[1].wrapped_key_iv = crypto_util::DeriveIv(odd_key_str);
|
||||
keys[1].key_id = crypto_util::DeriveKeyId(odd_key_str);
|
||||
keys[1].content_iv = odd_content_iv_str;
|
||||
status = cas_ecm->GenerateEcm(&keys[0], &keys[1], kDefaultTrackTypeSd, ecm);
|
||||
|
||||
size_t expected_ecm_size = content_iv_size_ == 8
|
||||
? kEcmWith8BytesContentIvSizeBytes
|
||||
@@ -239,9 +237,9 @@ WvCasStatus WvCasEcm::GenerateSingleKeyEcm(
|
||||
}
|
||||
std::string even_content_iv_str(even_content_iv, content_iv_size_);
|
||||
std::string even_entitlement_key_id_str(even_entitlement_key_id,
|
||||
kEntitlementKeyIdSizeBytes);
|
||||
kEntitlementKeyIdSizeBytes);
|
||||
std::string even_entitlement_key_str(even_entitlement_key,
|
||||
kEntitlementKeySizeBytes);
|
||||
kEntitlementKeySizeBytes);
|
||||
|
||||
// Double check some input sizes.
|
||||
if (even_key_str.size() != kContentKeySizeBytes) {
|
||||
@@ -254,7 +252,7 @@ WvCasStatus WvCasEcm::GenerateSingleKeyEcm(
|
||||
}
|
||||
|
||||
// Create an instance of Ecm in order to set the entitlement keys.
|
||||
std::unique_ptr<Ecm> cas_ecm = absl::make_unique<Ecm>();
|
||||
auto cas_ecm = absl::make_unique<Ecm>();
|
||||
std::string entitlement_request;
|
||||
std::string entitlement_response;
|
||||
EcmInitParameters ecm_init_params = CreateEcmInitParameters(
|
||||
@@ -290,17 +288,12 @@ WvCasStatus WvCasEcm::GenerateSingleKeyEcm(
|
||||
}
|
||||
|
||||
// Generate ECM.
|
||||
EcmGenerator ecm_generator;
|
||||
ecm_generator.set_ecm(std::move(cas_ecm));
|
||||
EcmParameters ecm_param;
|
||||
ecm_param.rotation_enabled = key_rotation_enabled_;
|
||||
// Add even entitlement key.
|
||||
ecm_param.key_params.emplace_back();
|
||||
ecm_param.key_params[0].key_data = even_key_str;
|
||||
ecm_param.key_params[0].wrapped_key_iv = crypto_util::DeriveIv(even_key_str);
|
||||
ecm_param.key_params[0].key_id = crypto_util::DeriveKeyId(even_key_str);
|
||||
ecm_param.key_params[0].content_ivs.push_back(even_content_iv_str);
|
||||
*ecm = ecm_generator.GenerateEcm(ecm_param);
|
||||
EntitledKeyInfo key;
|
||||
key.key_value = even_key_str;
|
||||
key.wrapped_key_iv = crypto_util::DeriveIv(even_key_str);
|
||||
key.key_id = crypto_util::DeriveKeyId(key.key_value);
|
||||
key.content_iv = even_content_iv_str;
|
||||
status = cas_ecm->GenerateSingleKeyEcm(&key, kDefaultTrackTypeSd, ecm);
|
||||
|
||||
size_t expected_ecm_size = content_iv_size_ == 8
|
||||
? kSingleKeyEcmWith8BytesContentIvSizeBytes
|
||||
@@ -317,7 +310,7 @@ WvCasStatus WvCasEcm::GenerateSingleKeyEcm(
|
||||
WvCasStatus WvCasEcm::GenerateTsPacket(const std::string& ecm, uint16_t pid,
|
||||
uint8_t table_id,
|
||||
uint8_t* continuity_counter,
|
||||
uint8_t* packet) {
|
||||
uint8_t* packet) const {
|
||||
ssize_t bytes_modified = 0;
|
||||
Status status = InsertEcmAsTsPacket(ecm, pid, table_id, continuity_counter,
|
||||
packet, &bytes_modified);
|
||||
|
||||
@@ -118,7 +118,7 @@ class WvCasEcm {
|
||||
// - |pid| program ID for the ECM stream
|
||||
// - |table_id| is the table ID byte put in the section header, it should be
|
||||
// either 0x80 or 0x81. Changing table ID from 0x80 or 0x81 or
|
||||
// 0x81 to 0x80 is used to singal to the client that the key contained
|
||||
// 0x81 to 0x80 is used to signal to the client that the key contained
|
||||
// in the ECM has changed. In other words, if you are building an ECM
|
||||
// with a new key that was not in any previous ECM, you should flip the
|
||||
// table ID so the client knows this is an important ECM it should process.
|
||||
@@ -132,7 +132,7 @@ class WvCasEcm {
|
||||
virtual WvCasStatus GenerateTsPacket(const std::string& ecm, uint16_t pid,
|
||||
uint8_t table_id,
|
||||
uint8_t* continuity_counter,
|
||||
uint8_t* packet);
|
||||
uint8_t* packet) const;
|
||||
|
||||
private:
|
||||
bool initialized_ = false;
|
||||
|
||||
@@ -138,7 +138,7 @@ TEST_F(WvCasEcmTest, GenerateEcm_8BytesContentIv_Ctr_Success) {
|
||||
/* odd_entitlement_key= */ kOddEntitlementKey, &actual_ecm));
|
||||
|
||||
EXPECT_EQ(
|
||||
"4ad40103806576656e5f656e745f6b65795f69642e3d1798a8729c0a316583bd514cf952"
|
||||
"4ad40203806576656e5f656e745f6b65795f69642e3d1798a8729c0a316583bd514cf952"
|
||||
"a94350a82ce961f90b1008c9cdce343b2827827aeb1ba30292c0061d80cf50ce7f657665"
|
||||
"6e5f69762e6f64645f656e745f6b65795f69642e2e34cd74b6b998889aad0e71b44bdd8c"
|
||||
"0e03e31ea68ab80a6ee79f59f0936bc6aa64fe976b6a4a5db2dc7e3ebba4a0bd876f6464"
|
||||
@@ -160,7 +160,7 @@ TEST_F(WvCasEcmTest, GenerateSingleKeyEcm_8BytesContentIv_Ctr_Success) {
|
||||
/* even_entitlement_key= */ kEvenEntitlementKey, &actual_ecm));
|
||||
|
||||
EXPECT_EQ(
|
||||
"4ad40102806576656e5f656e745f6b65795f69642e3d1798a8729c0a316583bd514cf952"
|
||||
"4ad40202806576656e5f656e745f6b65795f69642e3d1798a8729c0a316583bd514cf952"
|
||||
"a94350a82ce961f90b1008c9cdce343b2827827aeb1ba30292c0061d80cf50ce7f657665"
|
||||
"6e5f69762e",
|
||||
absl::BytesToHexString(actual_ecm));
|
||||
@@ -186,7 +186,7 @@ TEST_F(WvCasEcmTest, GenerateEcm_16BytesContentIv_Ctr_Success) {
|
||||
/* odd_entitlement_key= */ kOddEntitlementKey, &actual_ecm));
|
||||
|
||||
EXPECT_EQ(
|
||||
"4ad40103c06576656e5f656e745f6b65795f69642e3d1798a8729c0a316583bd514cf952"
|
||||
"4ad40203c06576656e5f656e745f6b65795f69642e3d1798a8729c0a316583bd514cf952"
|
||||
"a94350a82ce961f90b1008c9cdce343b2827827aeb1ba30292c0061d80cf50ce7f657665"
|
||||
"6e5f69762e2e2e2e2e2e2e2e2e6f64645f656e745f6b65795f69642e2e34cd74b6b99888"
|
||||
"9aad0e71b44bdd8c0e03e31ea68ab80a6ee79f59f0936bc6aa64fe976b6a4a5db2dc7e3e"
|
||||
@@ -209,7 +209,7 @@ TEST_F(WvCasEcmTest, GenerateSingleKeyEcm_16BytesContentIv_Ctr_Success) {
|
||||
/* even_entitlement_key= */ kEvenEntitlementKey, &actual_ecm));
|
||||
|
||||
EXPECT_EQ(
|
||||
"4ad40102c06576656e5f656e745f6b65795f69642e3d1798a8729c0a316583bd514cf952"
|
||||
"4ad40202c06576656e5f656e745f6b65795f69642e3d1798a8729c0a316583bd514cf952"
|
||||
"a94350a82ce961f90b1008c9cdce343b2827827aeb1ba30292c0061d80cf50ce7f657665"
|
||||
"6e5f69762e2e2e2e2e2e2e2e2e",
|
||||
absl::BytesToHexString(actual_ecm));
|
||||
@@ -235,7 +235,7 @@ TEST_F(WvCasEcmTest, GenerateEcm_16BytesContentIv_Cbc_Success) {
|
||||
/* odd_entitlement_key= */ kOddEntitlementKey, &actual_ecm));
|
||||
|
||||
EXPECT_EQ(
|
||||
"4ad40101c06576656e5f656e745f6b65795f69642e3d1798a8729c0a316583bd514cf952"
|
||||
"4ad40201c06576656e5f656e745f6b65795f69642e3d1798a8729c0a316583bd514cf952"
|
||||
"a94350a82ce961f90b1008c9cdce343b2827827aeb1ba30292c0061d80cf50ce7f657665"
|
||||
"6e5f69762e2e2e2e2e2e2e2e2e6f64645f656e745f6b65795f69642e2e34cd74b6b99888"
|
||||
"9aad0e71b44bdd8c0e03e31ea68ab80a6ee79f59f0936bc6aa64fe976b6a4a5db2dc7e3e"
|
||||
@@ -258,7 +258,7 @@ TEST_F(WvCasEcmTest, GenerateSingleKeyEcm_16BytesContentIv_Cbc_Success) {
|
||||
/* even_entitlement_key= */ kEvenEntitlementKey, &actual_ecm));
|
||||
|
||||
EXPECT_EQ(
|
||||
"4ad40100c06576656e5f656e745f6b65795f69642e3d1798a8729c0a316583bd514cf952"
|
||||
"4ad40200c06576656e5f656e745f6b65795f69642e3d1798a8729c0a316583bd514cf952"
|
||||
"a94350a82ce961f90b1008c9cdce343b2827827aeb1ba30292c0061d80cf50ce7f657665"
|
||||
"6e5f69762e2e2e2e2e2e2e2e2e",
|
||||
absl::BytesToHexString(actual_ecm));
|
||||
@@ -284,7 +284,7 @@ TEST_F(WvCasEcmTest, GenerateEcm_8BytesContentIv_Csa_Success) {
|
||||
/* odd_entitlement_key= */ kOddEntitlementKey, &actual_ecm));
|
||||
|
||||
EXPECT_EQ(
|
||||
"4ad40105806576656e5f656e745f6b65795f69642ee9c009a9d6a07c7bc3ca82f39c1f10"
|
||||
"4ad40205806576656e5f656e745f6b65795f69642ee9c009a9d6a07c7bc3ca82f39c1f10"
|
||||
"e6b5f391e74f120cfb876efba02d7f506f0ef185b3398096111dafd86ff7d395a2657665"
|
||||
"6e5f69762e6f64645f656e745f6b65795f69642e2e7f655fe61e99e89e03ac23df98cc02"
|
||||
"1cf21dfe9637c72c3480727ab18332d4ee219e81b8f34c9df2704b0595501832736f6464"
|
||||
@@ -307,7 +307,7 @@ TEST_F(WvCasEcmTest, GenerateSingleKeyEcm_8BytesContentIv_Csa_Success) {
|
||||
/* even_entitlement_key= */ kEvenEntitlementKey, &actual_ecm));
|
||||
|
||||
EXPECT_EQ(
|
||||
"4ad40104806576656e5f656e745f6b65795f69642ee9c009a9d6a07c7bc3ca82f39c1f10"
|
||||
"4ad40204806576656e5f656e745f6b65795f69642ee9c009a9d6a07c7bc3ca82f39c1f10"
|
||||
"e6b5f391e74f120cfb876efba02d7f506f0ef185b3398096111dafd86ff7d395a2657665"
|
||||
"6e5f69762e",
|
||||
absl::BytesToHexString(actual_ecm));
|
||||
@@ -333,7 +333,7 @@ TEST_F(WvCasEcmTest, GenerateEcm_8BytesContentIv_Csa_NulCharInKey_Success) {
|
||||
/* odd_entitlement_key= */ kOddEntitlementKey, &actual_ecm));
|
||||
|
||||
EXPECT_EQ(
|
||||
"4ad40105806576656e5f656e745f6b65795f69642e71ffb7d9500261db7a92974405c2cf"
|
||||
"4ad40205806576656e5f656e745f6b65795f69642e71ffb7d9500261db7a92974405c2cf"
|
||||
"d0b085eb9a85a57dbdb799158e829996988524bf3b3cfe01b28d4474f85ec2991d657665"
|
||||
"6e5f69762e6f64645f656e745f6b65795f69642e2e874aab870ffba640875a4521d3cd57"
|
||||
"02f26d0f9c7e9c69d7059c9ad42b091ec1f151aaa190536f4f330edebe84fe5a786f6464"
|
||||
@@ -357,7 +357,7 @@ TEST_F(WvCasEcmTest,
|
||||
/* even_entitlement_key= */ kEvenEntitlementKey, &actual_ecm));
|
||||
|
||||
EXPECT_EQ(
|
||||
"4ad40104806576656e5f656e745f6b65795f69642e71ffb7d9500261db7a92974405c2cf"
|
||||
"4ad40204806576656e5f656e745f6b65795f69642e71ffb7d9500261db7a92974405c2cf"
|
||||
"d0b085eb9a85a57dbdb799158e829996988524bf3b3cfe01b28d4474f85ec2991d657665"
|
||||
"6e5f69762e",
|
||||
absl::BytesToHexString(actual_ecm));
|
||||
|
||||
@@ -40,8 +40,9 @@ DEFINE_string(signing_iv, "",
|
||||
namespace widevine {
|
||||
namespace cas {
|
||||
|
||||
Status WvCasKeyFetcher::RequestEntitlementKey(const std::string& request_string,
|
||||
std::string* signed_response_string) {
|
||||
Status WvCasKeyFetcher::RequestEntitlementKey(
|
||||
const std::string& request_string,
|
||||
std::string* signed_response_string) const {
|
||||
if (FLAGS_signing_provider.empty() || FLAGS_signing_key.empty() ||
|
||||
FLAGS_signing_iv.empty()) {
|
||||
return Status(
|
||||
@@ -115,7 +116,8 @@ Status WvCasKeyFetcher::RequestEntitlementKey(const std::string& request_string,
|
||||
return OkStatus();
|
||||
}
|
||||
|
||||
size_t AppendToString(void* ptr, size_t size, size_t count, std::string* output) {
|
||||
size_t AppendToString(void* ptr, size_t size, size_t count,
|
||||
std::string* output) {
|
||||
const absl::string_view data(static_cast<char*>(ptr), size * count);
|
||||
absl::StrAppend(output, data);
|
||||
return data.size();
|
||||
@@ -140,8 +142,9 @@ Status WvCasKeyFetcher::MakeHttpRequest(const std::string& signed_request_json,
|
||||
(int64_t)strlen(signed_request_json.c_str()));
|
||||
curl_code = curl_easy_perform(curl);
|
||||
if (curl_code != CURLE_OK) {
|
||||
return Status(error::INTERNAL, "curl_easy_perform() failed: " +
|
||||
std::string(curl_easy_strerror(curl_code)));
|
||||
return Status(error::INTERNAL,
|
||||
"curl_easy_perform() failed: " +
|
||||
std::string(curl_easy_strerror(curl_code)));
|
||||
}
|
||||
curl_easy_cleanup(curl);
|
||||
} else {
|
||||
|
||||
@@ -29,7 +29,7 @@ class WvCasKeyFetcher : public KeyFetcher {
|
||||
WvCasKeyFetcher() = default;
|
||||
WvCasKeyFetcher(const WvCasKeyFetcher&) = delete;
|
||||
WvCasKeyFetcher& operator=(const WvCasKeyFetcher&) = delete;
|
||||
virtual ~WvCasKeyFetcher() = default;
|
||||
~WvCasKeyFetcher() override = default;
|
||||
|
||||
// Get entitlement keys from the license server. Send a
|
||||
// SignedCasEncryptionRequest message to the license server, receive a
|
||||
@@ -40,8 +40,9 @@ class WvCasKeyFetcher : public KeyFetcher {
|
||||
// |signed_response_string| a serialized SignedCasEncryptionResponse
|
||||
// message. It should be passed into
|
||||
// widevine::cas::Ecm::ProcessCasEncryptionResponse().
|
||||
Status RequestEntitlementKey(const std::string& request_string,
|
||||
std::string* signed_response_string) override;
|
||||
Status RequestEntitlementKey(
|
||||
const std::string& request_string,
|
||||
std::string* signed_response_string) const override;
|
||||
|
||||
protected:
|
||||
// Makes a HTTP request to License Server for entitlement key(s).
|
||||
|
||||
@@ -54,8 +54,9 @@ class MockWvCasKeyFetcher : public WvCasKeyFetcher {
|
||||
public:
|
||||
MockWvCasKeyFetcher() : WvCasKeyFetcher() {}
|
||||
~MockWvCasKeyFetcher() override {}
|
||||
MOCK_CONST_METHOD2(MakeHttpRequest, Status(const std::string& signed_request_json,
|
||||
std::string* http_response_json));
|
||||
MOCK_CONST_METHOD2(MakeHttpRequest,
|
||||
Status(const std::string& signed_request_json,
|
||||
std::string* http_response_json));
|
||||
};
|
||||
|
||||
class WvCasKeyFetcherTest : public ::testing::Test {
|
||||
|
||||
@@ -46,9 +46,13 @@ std::string GetWvCasStatusMessage(WvCasStatus status) {
|
||||
|
||||
// Numeric value of crypto mode is the index into strings array.
|
||||
static const char* kCrypoModeStrings[] = {
|
||||
"AesCbc",
|
||||
"AesCtr",
|
||||
"DvbCsa2",
|
||||
"AesCbc", "AesCtr", "DvbCsa2", "DvbCsa3", "AesOfb", "AesScte",
|
||||
};
|
||||
|
||||
// Numeric value of scrambling level is the index into strings array.
|
||||
static const char* kScramblingLevelStrings[] = {
|
||||
"PES",
|
||||
"TS",
|
||||
};
|
||||
|
||||
bool CryptoModeToString(CryptoMode mode, std::string* str) {
|
||||
@@ -69,7 +73,7 @@ bool StringToCryptoMode(const std::string& str, CryptoMode* mode) {
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < arraysize(kCrypoModeStrings); ++i) {
|
||||
if (str.compare(kCrypoModeStrings[i]) == 0) {
|
||||
if (str == kCrypoModeStrings[i]) {
|
||||
*mode = static_cast<CryptoMode>(i);
|
||||
return true;
|
||||
}
|
||||
@@ -78,6 +82,33 @@ bool StringToCryptoMode(const std::string& str, CryptoMode* mode) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ScramblingLevelToString(ScramblingLevel mode, std::string* str) {
|
||||
if (str == nullptr) {
|
||||
return false;
|
||||
}
|
||||
int mode_idx = static_cast<int>(mode);
|
||||
if (mode_idx >= 0 && mode_idx < arraysize(kScramblingLevelStrings)) {
|
||||
*str = kScramblingLevelStrings[mode_idx];
|
||||
return true;
|
||||
}
|
||||
LOG(ERROR) << "Invalid scrambling mode: " << mode_idx;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool StringToScramblingLevel(const std::string& str, ScramblingLevel* mode) {
|
||||
if (mode == nullptr) {
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < arraysize(kScramblingLevelStrings); ++i) {
|
||||
if (str == kScramblingLevelStrings[i]) {
|
||||
*mode = static_cast<ScramblingLevel>(i);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
LOG(ERROR) << "Invalid scrambling mode: " << str;
|
||||
return false;
|
||||
}
|
||||
|
||||
WvCasStatus CreateWvCasEncryptionRequestJson(
|
||||
const WvCasEncryptionRequest& request, std::string* request_json) {
|
||||
CHECK(request_json);
|
||||
|
||||
@@ -52,19 +52,31 @@ enum WvCasStatus {
|
||||
std::string GetWvCasStatusMessage(WvCasStatus status);
|
||||
|
||||
// Crypto mode for encryption / decryption. ENUM value should be consistent with
|
||||
// https://docs.google.com/document/d/1A5vflf8tbKyUheV-xsvfxFqB6YyNLNdsGXYx8ZnhjfY/edit#heading=h.ej4ts3lifoio
|
||||
// ECM V2 definition. Largest supported value for this CryptoMode ENUM is 15.
|
||||
enum class CryptoMode : int {
|
||||
kInvalid = -1,
|
||||
kAesCbc = 0,
|
||||
kAesCtr = 1,
|
||||
kDvbCsa2 = 2,
|
||||
kDvbCsa3 = 3,
|
||||
kAesOfb = 4,
|
||||
kAesScte = 5,
|
||||
};
|
||||
|
||||
enum class ScramblingLevel : int { kPES = 0, kTS = 1 };
|
||||
|
||||
// Returns false if mode is not a valid CryptoMode.
|
||||
bool CryptoModeToString(CryptoMode mode, std::string* str);
|
||||
|
||||
// Returns false if str is not a valid CryptoMode.
|
||||
bool StringToCryptoMode(const std::string& str, CryptoMode* mode);
|
||||
|
||||
// Returns false if mode is not a valid ScramblingLevel.
|
||||
bool ScramblingLevelToString(ScramblingLevel mode, std::string* str);
|
||||
|
||||
// Returns false if str is not a valid ScramblingLevel.
|
||||
bool StringToScramblingLevel(const std::string& str, ScramblingLevel* mode);
|
||||
|
||||
struct WvCasEncryptionRequest {
|
||||
std::string content_id;
|
||||
std::string provider;
|
||||
@@ -111,7 +123,7 @@ struct WvCasEncryptionResponse {
|
||||
// This request JSON can be later put into the 'request' field of a signed
|
||||
// request JSON message.
|
||||
// And that signed JSON message can be sent to Widevine license server for
|
||||
// aquiring entitlement keys.
|
||||
// acquiring entitlement keys.
|
||||
WvCasStatus CreateWvCasEncryptionRequestJson(
|
||||
const WvCasEncryptionRequest& request, std::string* request_json);
|
||||
|
||||
|
||||
@@ -33,6 +33,12 @@ TEST(WvCasTypesTest, CryptoModeToString) {
|
||||
EXPECT_EQ("AesCbc", crypto_mode);
|
||||
ASSERT_TRUE(CryptoModeToString(CryptoMode::kDvbCsa2, &crypto_mode));
|
||||
EXPECT_EQ("DvbCsa2", crypto_mode);
|
||||
ASSERT_TRUE(CryptoModeToString(CryptoMode::kDvbCsa3, &crypto_mode));
|
||||
EXPECT_EQ("DvbCsa3", crypto_mode);
|
||||
ASSERT_TRUE(CryptoModeToString(CryptoMode::kAesOfb, &crypto_mode));
|
||||
EXPECT_EQ("AesOfb", crypto_mode);
|
||||
ASSERT_TRUE(CryptoModeToString(CryptoMode::kAesScte, &crypto_mode));
|
||||
EXPECT_EQ("AesScte", crypto_mode);
|
||||
EXPECT_FALSE(CryptoModeToString(static_cast<CryptoMode>(-1), &crypto_mode));
|
||||
}
|
||||
|
||||
@@ -44,9 +50,34 @@ TEST(WvCasTypesTest, StringToCryptoMode) {
|
||||
EXPECT_EQ(CryptoMode::kAesCbc, crypto_mode);
|
||||
ASSERT_TRUE(StringToCryptoMode("DvbCsa2", &crypto_mode));
|
||||
EXPECT_EQ(CryptoMode::kDvbCsa2, crypto_mode);
|
||||
ASSERT_TRUE(StringToCryptoMode("DvbCsa3", &crypto_mode));
|
||||
EXPECT_EQ(CryptoMode::kDvbCsa3, crypto_mode);
|
||||
ASSERT_TRUE(StringToCryptoMode("AesScte", &crypto_mode));
|
||||
EXPECT_EQ(CryptoMode::kAesScte, crypto_mode);
|
||||
EXPECT_FALSE(StringToCryptoMode("invalid crypto mode", &crypto_mode));
|
||||
}
|
||||
|
||||
TEST(WvCasTypesTest, ScramblingLevelToString) {
|
||||
std::string scrambling_level;
|
||||
ASSERT_TRUE(
|
||||
ScramblingLevelToString(ScramblingLevel::kPES, &scrambling_level));
|
||||
EXPECT_EQ("PES", scrambling_level);
|
||||
ASSERT_TRUE(ScramblingLevelToString(ScramblingLevel::kTS, &scrambling_level));
|
||||
EXPECT_EQ("TS", scrambling_level);
|
||||
EXPECT_FALSE(ScramblingLevelToString(static_cast<ScramblingLevel>(-1),
|
||||
&scrambling_level));
|
||||
}
|
||||
|
||||
TEST(WvCasTypeStatus, StringToScramblingLevel) {
|
||||
ScramblingLevel scrambling_level;
|
||||
ASSERT_TRUE(StringToScramblingLevel("PES", &scrambling_level));
|
||||
EXPECT_EQ(ScramblingLevel::kPES, scrambling_level);
|
||||
ASSERT_TRUE(StringToScramblingLevel("TS", &scrambling_level));
|
||||
EXPECT_EQ(ScramblingLevel::kTS, scrambling_level);
|
||||
EXPECT_FALSE(
|
||||
StringToScramblingLevel("invalid scrambling level", &scrambling_level));
|
||||
}
|
||||
|
||||
TEST(WvCasTypesTest, CreateWvCasEncryptionRequestJson) {
|
||||
WvCasEncryptionRequest request;
|
||||
request.content_id = "test_content_id";
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <netinet/in.h>
|
||||
#include <sys/socket.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <cerrno>
|
||||
#include <cstddef>
|
||||
#include <cstdio>
|
||||
@@ -22,43 +23,50 @@
|
||||
#include "glog/logging.h"
|
||||
#include "absl/strings/str_cat.h"
|
||||
#include "media_cas_packager_sdk/internal/ecmg_client_handler.h"
|
||||
#include "media_cas_packager_sdk/public/wv_cas_types.h"
|
||||
|
||||
static constexpr int32_t kDefaultDelayStart = 200;
|
||||
static constexpr int32_t kDefaultDelayStop = 200;
|
||||
static constexpr int32_t kDefaultEcmRepPeriod = 100;
|
||||
static constexpr int32_t kDefaultMaxCompTime = 100;
|
||||
static constexpr int32_t kAccessCriteriaTransferMode = 1;
|
||||
static constexpr int32_t kAccessCriteriaTransferMode = 0;
|
||||
static constexpr int32_t kNumberOfContentKeys = 2;
|
||||
static constexpr char kDefaultCryptoMode[] = "AesCtr";
|
||||
static constexpr bool kDefaultUseFixedFetcher = false;
|
||||
|
||||
DEFINE_int32(port, 0, "Server port number");
|
||||
|
||||
// ECMG related flags.
|
||||
// TODO(user): Consider adding flags 'ac_delay_start', 'ac_delay_stop',
|
||||
// 'transition_delay_start', 'transition_delay_stop'.
|
||||
DEFINE_int32(delay_start, kDefaultDelayStart,
|
||||
absl::StrCat("This flag sets the DVB SimulCrypt delay_start "
|
||||
"parameter, in milliseconds. Default: ",
|
||||
kDefaultDelayStart, " ms")
|
||||
.c_str());
|
||||
DEFINE_int32(delay_stop, kDefaultDelayStop,
|
||||
absl::StrCat("This flag sets the DVB SimulCrypt delay_stop "
|
||||
"parameter, in milliseconds. Default: ",
|
||||
kDefaultDelayStop, " ms")
|
||||
.c_str());
|
||||
DEFINE_int32(ecm_rep_period, kDefaultEcmRepPeriod,
|
||||
absl::StrCat("It sets the DVB SimulCrypt parameter "
|
||||
"ECM_rep_period, in milliseconds. Default: ",
|
||||
kDefaultEcmRepPeriod, " ms")
|
||||
.c_str());
|
||||
DEFINE_int32(max_comp_time, kDefaultMaxCompTime,
|
||||
absl::StrCat("It sets the DVB SimulCrypt parameter max_comp_time, "
|
||||
"in milliseconds. Default: ",
|
||||
kDefaultMaxCompTime, " ms")
|
||||
.c_str());
|
||||
DEFINE_int32(access_criteria_transfer_mode, kAccessCriteriaTransferMode,
|
||||
absl::StrCat("It sets the DVB SimulCrypt parameter "
|
||||
"access_criteria_transfer_mode. Default: ",
|
||||
kAccessCriteriaTransferMode)
|
||||
.c_str());
|
||||
DEFINE_int32(
|
||||
delay_start, kDefaultDelayStart,
|
||||
"This flag sets the DVB SimulCrypt delay_start parameter, in milliseconds");
|
||||
DEFINE_int32(
|
||||
delay_stop, kDefaultDelayStop,
|
||||
"This flag sets the DVB SimulCrypt delay_stop parameter, in milliseconds");
|
||||
DEFINE_int32(
|
||||
ecm_rep_period, kDefaultEcmRepPeriod,
|
||||
"It sets the DVB SimulCrypt parameter ECM_rep_period, in milliseconds");
|
||||
DEFINE_int32(
|
||||
max_comp_time, kDefaultMaxCompTime,
|
||||
"It sets the DVB SimulCrypt parameter max_comp_time, in milliseconds.");
|
||||
DEFINE_int32(
|
||||
access_criteria_transfer_mode, kAccessCriteriaTransferMode,
|
||||
"If it equals 0, it indicates that the access_criteria parameter is "
|
||||
"required in the CW_provision message only when the contents of this "
|
||||
"parameter change. If it equals 1, it indicates that the ECMG requires the "
|
||||
"access_criteria parameter be present in each CW_provision message.");
|
||||
DEFINE_int32(number_of_content_keys, kNumberOfContentKeys,
|
||||
"It sets the number of content keys (CwPerMsg). Must be 1 (single "
|
||||
"key) or 2 (key rotation enabled). It also sets LeadCw as "
|
||||
"number_of_content_keys - 1.");
|
||||
DEFINE_string(crypto_mode, kDefaultCryptoMode,
|
||||
"Encryption mode. Choices are \"AesCtr\", \"AesCbc\", "
|
||||
"\"DvbCsa2\", \"DvbCsa3\", \"AesOfb\", \"AesScte\".");
|
||||
DEFINE_bool(use_fixed_fetcher, kDefaultUseFixedFetcher,
|
||||
"Use fixed fetcher to fetch mocked entitlement licenses for "
|
||||
"testing purposes.");
|
||||
|
||||
#define LISTEN_QUEUE_SIZE (20)
|
||||
#define BUFFER_SIZE (1024)
|
||||
@@ -73,6 +81,10 @@ void BuildEcmgConfig(EcmgConfig* config) {
|
||||
config->ecm_rep_period = FLAGS_ecm_rep_period;
|
||||
config->max_comp_time = FLAGS_max_comp_time;
|
||||
config->access_criteria_transfer_mode = FLAGS_access_criteria_transfer_mode;
|
||||
config->number_of_content_keys = FLAGS_number_of_content_keys;
|
||||
CHECK(StringToCryptoMode(FLAGS_crypto_mode, &config->crypto_mode))
|
||||
<< "Unknown crypto mode.";
|
||||
config->use_fixed_fetcher = FLAGS_use_fixed_fetcher;
|
||||
}
|
||||
|
||||
void PrintMessage(const std::string& description, const char* const message,
|
||||
@@ -116,6 +128,8 @@ void ServeClient(int socket_fd, EcmgClientHandler* ecmg) {
|
||||
int main(int argc, char** argv) {
|
||||
gflags::ParseCommandLineFlags(&argc, &argv, true);
|
||||
CHECK(FLAGS_port != 0) << "need --port";
|
||||
CHECK(FLAGS_number_of_content_keys == 1 || FLAGS_number_of_content_keys == 2)
|
||||
<< "--number_of_content_keys must be 1 or 2.";
|
||||
|
||||
EcmgConfig ecmg_config;
|
||||
BuildEcmgConfig(&ecmg_config);
|
||||
|
||||
Reference in New Issue
Block a user