Update SimulCrypt ECMG on injecting entitlement keys
This commit is contained in:
@@ -29,7 +29,7 @@ constexpr char kTestEcmgChannelSetup[] = {
|
||||
constexpr char kTestEcmgChannelSetupWithPrivateParameters[] = {
|
||||
'\x03', // protocol_version
|
||||
'\x00', '\x01', // message_type - Channel_setup
|
||||
'\x00', '\x8c', // message_length
|
||||
'\x00', '\x1e', // message_length
|
||||
'\x00', '\x0e', // parameter_type - ECM_channel_id
|
||||
'\x00', '\x02', // parameter_length
|
||||
'\x00', '\x01', // parameter_value
|
||||
@@ -42,29 +42,7 @@ constexpr char kTestEcmgChannelSetupWithPrivateParameters[] = {
|
||||
'\x80', '\x01', // parameter_type - CRYPTO_MODE
|
||||
'\x00', '\x07', // parameter_length
|
||||
'A', 'e', 's', 'S', 'c', 't', 'e', // parameter_value
|
||||
'\x80', '\x02', // parameter_type - TRACK_TYPES
|
||||
'\x00', '\x02', // parameter_length
|
||||
'S', 'D', // parameter_value
|
||||
'\x80', '\x05', // parameter_type - ENTITLEMENT_ID_KEY_COMBINATION
|
||||
'\x00', '\x30', // parameter_length
|
||||
// parameter_value - ENTITLEMENT_ID (16 bytes)
|
||||
'\x30', '\x31', '\x32', '\x33', '\x34', '\x35', '\x36', '\x37', //
|
||||
'\x30', '\x31', '\x32', '\x33', '\x34', '\x35', '\x36', '\x37', //
|
||||
// parameter_value (continued) - ENTITLEMENT_KEY (32 bytes)
|
||||
'\x30', '\x31', '\x32', '\x33', '\x34', '\x35', '\x36', '\x37', //
|
||||
'\x30', '\x31', '\x32', '\x33', '\x34', '\x35', '\x36', '\x37', //
|
||||
'\x30', '\x31', '\x32', '\x33', '\x34', '\x35', '\x36', '\x37', //
|
||||
'\x30', '\x31', '\x32', '\x33', '\x34', '\x35', '\x36', '\x37', //
|
||||
'\x80', '\x05', // parameter_type - ENTITLEMENT_ID_KEY_COMBINATION
|
||||
'\x00', '\x30', // parameter_length
|
||||
// parameter_value - ENTITLEMENT_ID (16 bytes)
|
||||
'\x61', '\x62', '\x63', '\x64', '\x65', '\x66', '\x67', '\x68', //
|
||||
'\x61', '\x62', '\x63', '\x64', '\x65', '\x66', '\x67', '\x68', //
|
||||
// parameter_value (continued) - ENTITLEMENT_KEY (32 bytes)
|
||||
'\x61', '\x62', '\x63', '\x64', '\x65', '\x66', '\x67', '\x68', //
|
||||
'\x61', '\x62', '\x63', '\x64', '\x65', '\x66', '\x67', '\x68', //
|
||||
'\x61', '\x62', '\x63', '\x64', '\x65', '\x66', '\x67', '\x68', //
|
||||
'\x61', '\x62', '\x63', '\x64', '\x65', '\x66', '\x67', '\x68'};
|
||||
};
|
||||
|
||||
constexpr char kTestEcmgChannelTest[] = {
|
||||
'\x03', // protocol_version
|
||||
@@ -126,7 +104,7 @@ constexpr char kTestEcmgChannelStatus[] = {
|
||||
constexpr char kTestEcmgStreamSetupWithPrivateParameters[] = {
|
||||
'\x03', // protocol_version
|
||||
'\x01', '\x01', // message_type - Stream_setup
|
||||
'\x00', '\x46', // message_length
|
||||
'\x00', '\xae', // message_length
|
||||
'\x00', '\x0e', // parameter_type - ECM_channel_id
|
||||
'\x00', '\x02', // parameter_length
|
||||
'\x00', '\x01', // parameter_value
|
||||
@@ -139,17 +117,37 @@ constexpr char kTestEcmgStreamSetupWithPrivateParameters[] = {
|
||||
'\x00', '\x10', // parameter_type - nominal_CP_duration
|
||||
'\x00', '\x02', // parameter_length
|
||||
'\x00', '\x64', // parameter_value
|
||||
'\x80', '\x03', // parameter_type - STREAM_TRACK_TYPE
|
||||
'\x80', '\x02', // parameter_type - STREAM_TRACK_TYPE
|
||||
'\x00', '\x02', // parameter_length
|
||||
'S', 'D', // parameter_value
|
||||
'\x80', '\x04', // parameter_type - CONTENT_IV
|
||||
'\x80', '\x03', // parameter_type - CONTENT_IV
|
||||
'\x00', '\x10', // parameter_length
|
||||
'\x00', '\x01', '\x02', '\x03', '\x04', '\x05', '\x06', '\x07',
|
||||
'\x08', '\x09', '\x0a', '\x0b', '\x0c', '\x0d', '\x0e', '\x0f',
|
||||
'\x80', '\x04', // parameter_type - CONTENT_IV
|
||||
'\x00', '\x01', '\x02', '\x03', '\x04', '\x05', '\x06', '\x07', //
|
||||
'\x08', '\x09', '\x0a', '\x0b', '\x0c', '\x0d', '\x0e', '\x0f', //
|
||||
'\x80', '\x03', // parameter_type - CONTENT_IV
|
||||
'\x00', '\x10', // parameter_length
|
||||
'\x10', '\x11', '\x12', '\x13', '\x14', '\x15', '\x16', '\x17',
|
||||
'\x18', '\x19', '\x1a', '\x1b', '\x1c', '\x1d', '\x1e', '\x1f'};
|
||||
'\x10', '\x11', '\x12', '\x13', '\x14', '\x15', '\x16', '\x17', //
|
||||
'\x18', '\x19', '\x1a', '\x1b', '\x1c', '\x1d', '\x1e', '\x1f', //
|
||||
'\x80', '\x04', // parameter_type - ENTITLEMENT_ID_KEY_COMBINATION
|
||||
'\x00', '\x30', // parameter_length
|
||||
// parameter_value - ENTITLEMENT_ID (16 bytes)
|
||||
'\x30', '\x31', '\x32', '\x33', '\x34', '\x35', '\x36', '\x37', //
|
||||
'\x30', '\x31', '\x32', '\x33', '\x34', '\x35', '\x36', '\x37', //
|
||||
// parameter_value (continued) - ENTITLEMENT_KEY (32 bytes)
|
||||
'\x30', '\x31', '\x32', '\x33', '\x34', '\x35', '\x36', '\x37', //
|
||||
'\x30', '\x31', '\x32', '\x33', '\x34', '\x35', '\x36', '\x37', //
|
||||
'\x30', '\x31', '\x32', '\x33', '\x34', '\x35', '\x36', '\x37', //
|
||||
'\x30', '\x31', '\x32', '\x33', '\x34', '\x35', '\x36', '\x37', //
|
||||
'\x80', '\x04', // parameter_type - ENTITLEMENT_ID_KEY_COMBINATION
|
||||
'\x00', '\x30', // parameter_length
|
||||
// parameter_value - ENTITLEMENT_ID (16 bytes)
|
||||
'\x61', '\x62', '\x63', '\x64', '\x65', '\x66', '\x67', '\x68', //
|
||||
'\x61', '\x62', '\x63', '\x64', '\x65', '\x66', '\x67', '\x68', //
|
||||
// parameter_value (continued) - ENTITLEMENT_KEY (32 bytes)
|
||||
'\x61', '\x62', '\x63', '\x64', '\x65', '\x66', '\x67', '\x68', //
|
||||
'\x61', '\x62', '\x63', '\x64', '\x65', '\x66', '\x67', '\x68', //
|
||||
'\x61', '\x62', '\x63', '\x64', '\x65', '\x66', '\x67', '\x68', //
|
||||
'\x61', '\x62', '\x63', '\x64', '\x65', '\x66', '\x67', '\x68'};
|
||||
|
||||
constexpr char kTestEcmgStreamSetup[] = {
|
||||
'\x03', // protocol_version
|
||||
@@ -247,7 +245,7 @@ constexpr char kTestEcmgCwProvision[] = {
|
||||
constexpr char kTestEcmgCwProvisionWithAccessCriteria[] = {
|
||||
'\x03', // protocol_version
|
||||
'\x02', '\x01', // message_type - CW_provision
|
||||
'\x00', '\xf4', // message_length
|
||||
'\x00', '\xee', // message_length
|
||||
'\x00', '\x0e', // parameter_type - ECM_channel_id
|
||||
'\x00', '\x02', // parameter_length
|
||||
'\x00', '\x01', // parameter_value
|
||||
@@ -271,28 +269,25 @@ constexpr char kTestEcmgCwProvisionWithAccessCriteria[] = {
|
||||
'\x10', '\x11', '\x12', '\x13', '\x14', '\x15', '\x16', '\x17', //
|
||||
'\x18', '\x19', '\x1a', '\x1b', '\x1c', '\x1d', '\x1e', '\x1f', //
|
||||
'\x00', '\x0d', // parameter_type - access_criteria
|
||||
'\x00', '\xac', // parameter_length
|
||||
'\x00', '\xa6', // parameter_length
|
||||
'\x80', '\x00', // access_criteria parameter_type - AGE_RESTRICTION
|
||||
'\x00', '\x01', // parameter_length
|
||||
'\x00', // parameter_value
|
||||
'\x80', '\x01', // access_criteria parameter_type - CRYPTO_MODE
|
||||
'\x00', '\x07', // parameter_length
|
||||
'A', 'e', 's', 'S', 'c', 't', 'e', // parameter_value
|
||||
'\x80', '\x02', // access_criteria parameter_type - TRACK_TYPES
|
||||
'\x80', '\x02', // access_criteria parameter_type - STREAM_TRACK_TYPE
|
||||
'\x00', '\x02', // parameter_length
|
||||
'S', 'D', // parameter_value
|
||||
'\x80', '\x03', // access_criteria parameter_type - STREAM_TRACK_TYPE
|
||||
'\x00', '\x02', // parameter_length
|
||||
'S', 'D', // parameter_value
|
||||
'\x80', '\x04', // access_criteria parameter_type - CONTENT_IV
|
||||
'\x80', '\x03', // access_criteria parameter_type - CONTENT_IV
|
||||
'\x00', '\x10', // parameter_length
|
||||
'\x00', '\x01', '\x02', '\x03', '\x04', '\x05', '\x06', '\x07', //
|
||||
'\x08', '\x09', '\x0a', '\x0b', '\x0c', '\x0d', '\x0e', '\x0f', //
|
||||
'\x80', '\x04', // access_criteria parameter_type - CONTENT_IV
|
||||
'\x80', '\x03', // access_criteria parameter_type - CONTENT_IV
|
||||
'\x00', '\x10', // parameter_length
|
||||
'\x10', '\x11', '\x12', '\x13', '\x14', '\x15', '\x16', '\x17', //
|
||||
'\x18', '\x19', '\x1a', '\x1b', '\x1c', '\x1d', '\x1e', '\x1f', //
|
||||
'\x80', '\x05', // parameter_type - ENTITLEMENT_ID_KEY_COMBINATION
|
||||
'\x80', '\x04', // parameter_type - ENTITLEMENT_ID_KEY_COMBINATION
|
||||
'\x00', '\x30', // parameter_length
|
||||
// parameter_value - ENTITLEMENT_ID (16 bytes)
|
||||
'\x30', '\x31', '\x32', '\x33', '\x34', '\x35', '\x36', '\x37', //
|
||||
@@ -302,7 +297,7 @@ constexpr char kTestEcmgCwProvisionWithAccessCriteria[] = {
|
||||
'\x30', '\x31', '\x32', '\x33', '\x34', '\x35', '\x36', '\x37', //
|
||||
'\x30', '\x31', '\x32', '\x33', '\x34', '\x35', '\x36', '\x37', //
|
||||
'\x30', '\x31', '\x32', '\x33', '\x34', '\x35', '\x36', '\x37', //
|
||||
'\x80', '\x05', // parameter_type - ENTITLEMENT_ID_KEY_COMBINATION
|
||||
'\x80', '\x04', // parameter_type - ENTITLEMENT_ID_KEY_COMBINATION
|
||||
'\x00', '\x30', // parameter_length
|
||||
// parameter_value - ENTITLEMENT_ID (16 bytes)
|
||||
'\x61', '\x62', '\x63', '\x64', '\x65', '\x66', '\x67', '\x68', //
|
||||
|
||||
@@ -54,11 +54,6 @@ Status ProcessPrivateParameters(const char* const request, uint16_t param_type,
|
||||
params->crypto_mode = std::string(request + *offset, param_length);
|
||||
*offset += param_length;
|
||||
break;
|
||||
case TRACK_TYPES:
|
||||
params->track_types.push_back(
|
||||
std::string(request + *offset, param_length));
|
||||
*offset += param_length;
|
||||
break;
|
||||
case STREAM_TRACK_TYPE:
|
||||
params->stream_track_type = std::string(request + *offset, param_length);
|
||||
*offset += param_length;
|
||||
@@ -722,8 +717,7 @@ void EcmgClientHandler::HandleCwProvision(const EcmgParameters& params,
|
||||
return;
|
||||
}
|
||||
|
||||
// Request entitlement keys if they do not exist yet.
|
||||
if (ecm_ == nullptr) {
|
||||
if (streams_info_.at(params.ecm_stream_id)->ecm == nullptr) {
|
||||
status = CheckAndInitializeEcm(params);
|
||||
if (!status.ok()) {
|
||||
LOG(ERROR) << status.ToString();
|
||||
@@ -758,9 +752,6 @@ Status EcmgClientHandler::UpdateCommonPrivateParameters(
|
||||
}
|
||||
age_restriction_ = params.age_restriction;
|
||||
}
|
||||
if (!params.track_types.empty()) {
|
||||
track_types_.assign(params.track_types.begin(), params.track_types.end());
|
||||
}
|
||||
if (!params.content_ivs.empty()) {
|
||||
if (params.content_ivs.size() < ecmg_config_->number_of_content_keys) {
|
||||
return {error::INVALID_ARGUMENT,
|
||||
@@ -778,10 +769,6 @@ Status EcmgClientHandler::UpdateCommonPrivateParameters(
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!params.entitlement_comb.empty()) {
|
||||
entitlement_comb_.assign(params.entitlement_comb.begin(),
|
||||
params.entitlement_comb.end());
|
||||
}
|
||||
return OkStatus();
|
||||
}
|
||||
|
||||
@@ -825,26 +812,29 @@ Status EcmgClientHandler::UpdateStreamPrivateParameters(
|
||||
stream_info->content_ivs.assign(params.content_ivs.begin(),
|
||||
params.content_ivs.end());
|
||||
}
|
||||
if (!params.entitlement_comb.empty()) {
|
||||
stream_info->entitlement_comb.assign(params.entitlement_comb.begin(),
|
||||
params.entitlement_comb.end());
|
||||
}
|
||||
return OkStatus();
|
||||
}
|
||||
|
||||
Status EcmgClientHandler::CheckAndInitializeEcm(const EcmgParameters& params) {
|
||||
DCHECK(ecm_ == nullptr);
|
||||
DCHECK(streams_info_.contains(params.ecm_stream_id));
|
||||
EcmgStreamInfo* stream_info = streams_info_.at(params.ecm_stream_id).get();
|
||||
DCHECK(stream_info->ecm == nullptr);
|
||||
|
||||
if (stream_info->content_ivs.empty() && content_ivs_.empty()) {
|
||||
return {error::NOT_FOUND, "Content iv not specified."};
|
||||
}
|
||||
if (track_types_.empty()) {
|
||||
return {error::NOT_FOUND, "Track type not specified."};
|
||||
}
|
||||
if (entitlement_comb_.empty()) {
|
||||
if (stream_info->entitlement_comb.empty()) {
|
||||
return {error::NOT_FOUND, "Entitlement key id comb not specified."};
|
||||
}
|
||||
if (entitlement_comb_.size() !=
|
||||
track_types_.size() * ecmg_config_->number_of_content_keys) {
|
||||
if (stream_info->entitlement_comb.size() !=
|
||||
ecmg_config_->number_of_content_keys) {
|
||||
return {error::NOT_FOUND,
|
||||
"Number of injected entitlement keys must equal to number of "
|
||||
"track types * number of content keys per ecm."};
|
||||
"content keys per ecm."};
|
||||
}
|
||||
|
||||
bool key_rotation = ecmg_config_->number_of_content_keys > 1;
|
||||
@@ -862,25 +852,26 @@ Status EcmgClientHandler::CheckAndInitializeEcm(const EcmgParameters& params) {
|
||||
}
|
||||
|
||||
std::vector<EntitlementKeyInfo> entitlements;
|
||||
entitlements.reserve(entitlement_comb_.size());
|
||||
for (size_t i = 0; i < entitlement_comb_.size(); i++) {
|
||||
entitlements.reserve(stream_info->entitlement_comb.size());
|
||||
for (size_t i = 0; i < stream_info->entitlement_comb.size(); i++) {
|
||||
entitlements.emplace_back();
|
||||
EntitlementKeyInfo* entitlement = &entitlements.back();
|
||||
entitlement->track_type = track_types_.at(key_rotation ? i / 2 : i);
|
||||
entitlement->track_type = stream_info->track_type;
|
||||
entitlement->is_even_key = key_rotation ? i % 2 == 0 : true;
|
||||
entitlement->key_id = entitlement_comb_[i].key_id;
|
||||
entitlement->key_value = entitlement_comb_[i].key_value;
|
||||
entitlement->key_id = stream_info->entitlement_comb[i].key_id;
|
||||
entitlement->key_value = stream_info->entitlement_comb[i].key_value;
|
||||
}
|
||||
|
||||
ecm_ = absl::make_unique<Ecm>();
|
||||
return ecm_->Initialize(ecm_init_params, entitlements);
|
||||
stream_info->ecm = absl::make_unique<Ecm>();
|
||||
return stream_info->ecm->Initialize(ecm_init_params, entitlements);
|
||||
}
|
||||
|
||||
Status EcmgClientHandler::BuildEcmDatagram(const EcmgParameters& params,
|
||||
uint8_t* ecm_datagram) const {
|
||||
DCHECK(ecm_datagram);
|
||||
DCHECK(ecm_);
|
||||
DCHECK(streams_info_.contains(params.ecm_stream_id));
|
||||
EcmgStreamInfo* stream_info = streams_info_.at(params.ecm_stream_id).get();
|
||||
DCHECK(stream_info->ecm);
|
||||
|
||||
// Generate serialized ECM.
|
||||
std::vector<EntitledKeyInfo> keys;
|
||||
@@ -901,11 +892,11 @@ Status EcmgClientHandler::BuildEcmDatagram(const EcmgParameters& params,
|
||||
Status status;
|
||||
std::string serialized_ecm;
|
||||
if (ecmg_config_->number_of_content_keys > 1) {
|
||||
status = ecm_->GenerateEcm(&keys[0], &keys[1], stream_info->track_type,
|
||||
&serialized_ecm);
|
||||
status = stream_info->ecm->GenerateEcm(
|
||||
&keys[0], &keys[1], stream_info->track_type, &serialized_ecm);
|
||||
} else {
|
||||
status = ecm_->GenerateSingleKeyEcm(&keys[0], stream_info->track_type,
|
||||
&serialized_ecm);
|
||||
status = stream_info->ecm->GenerateSingleKeyEcm(
|
||||
&keys[0], stream_info->track_type, &serialized_ecm);
|
||||
}
|
||||
if (!status.ok()) {
|
||||
return status;
|
||||
|
||||
@@ -62,9 +62,6 @@ struct EcmgParameters {
|
||||
// User defined paremeters below.
|
||||
uint8_t age_restriction = 0xff; // Assume 0xff (255) is an invalid value.
|
||||
std::string crypto_mode;
|
||||
// All track types that need to be supported in the channel.
|
||||
// Used to request entitlement keys.
|
||||
std::vector<std::string> track_types;
|
||||
std::string stream_track_type;
|
||||
std::vector<std::string> content_ivs; // 8 or 16 bytes, one for each key.
|
||||
std::vector<EntitlementIdKeyComb> entitlement_comb;
|
||||
@@ -77,6 +74,8 @@ struct EcmgStreamInfo {
|
||||
CryptoMode crypto_mode = CryptoMode::kInvalid;
|
||||
// 8 or 16 bytes, one for each key. Will use |content_ivs_| if empty.
|
||||
std::vector<std::string> content_ivs;
|
||||
std::vector<EntitlementIdKeyComb> entitlement_comb;
|
||||
std::unique_ptr<Ecm> ecm;
|
||||
};
|
||||
|
||||
// A class that handles one (and only one) ECMG client.
|
||||
@@ -133,10 +132,7 @@ class EcmgClientHandler {
|
||||
uint16_t channel_id_;
|
||||
|
||||
// Channel specific information.
|
||||
std::unique_ptr<Ecm> ecm_; // |ecm_| is shared within the channel.
|
||||
uint8_t age_restriction_ = 0;
|
||||
std::vector<std::string> track_types_;
|
||||
std::vector<EntitlementIdKeyComb> entitlement_comb_;
|
||||
std::vector<std::string> content_ivs_;
|
||||
|
||||
// Map from ECM_stream_id to EcmgStreamInfo.
|
||||
|
||||
@@ -92,10 +92,8 @@ class EcmgClientHandlerTest : public ::testing::Test {
|
||||
|
||||
void BuildChannelSetupRequest(uint16_t channel_id, uint32_t super_cas_id,
|
||||
uint8_t age_restriction,
|
||||
const std::string& crypto_mode,
|
||||
const std::vector<std::string>& track_types,
|
||||
const std::vector<std::string>& entitlements,
|
||||
char* message, size_t* message_length) {
|
||||
const std::string& crypto_mode, char* message,
|
||||
size_t* message_length) {
|
||||
EXPECT_TRUE(message != nullptr);
|
||||
EXPECT_TRUE(message_length != nullptr);
|
||||
BuildMessageHeader(ECMG_SCS_PROTOCOL_VERSION, ECMG_CHANNEL_SETUP, message,
|
||||
@@ -110,21 +108,6 @@ class EcmgClientHandlerTest : public ::testing::Test {
|
||||
AddParam(CRYPTO_MODE, reinterpret_cast<const uint8_t*>(crypto_mode.c_str()),
|
||||
crypto_mode.size(), message, message_length);
|
||||
}
|
||||
if (!track_types.empty()) {
|
||||
for (const auto& track_type : track_types) {
|
||||
AddParam(TRACK_TYPES,
|
||||
reinterpret_cast<const uint8_t*>(track_type.c_str()),
|
||||
track_type.size(), message, message_length);
|
||||
}
|
||||
}
|
||||
if (!entitlements.empty()) {
|
||||
for (const auto& entitlement : entitlements) {
|
||||
AddParam(ENTITLEMENT_ID_KEY_COMBINATION,
|
||||
reinterpret_cast<const uint8_t*>(entitlement.c_str()),
|
||||
entitlement.size(), message, message_length);
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t total_param_length = *message_length - 5;
|
||||
Host16ToBigEndian(message + 3, &total_param_length);
|
||||
}
|
||||
@@ -132,6 +115,7 @@ class EcmgClientHandlerTest : public ::testing::Test {
|
||||
void BuildStreamSetupRequest(uint16_t channel_id, uint16_t stream_id,
|
||||
uint16_t ecm_id, uint16_t nominal_CP_duration,
|
||||
const std::string& stream_track_type,
|
||||
const std::vector<std::string>& entitlements,
|
||||
const std::vector<std::string>& content_ivs,
|
||||
char* message, size_t* message_length) {
|
||||
EXPECT_TRUE(message != nullptr);
|
||||
@@ -149,6 +133,13 @@ class EcmgClientHandlerTest : public ::testing::Test {
|
||||
reinterpret_cast<const uint8_t*>(stream_track_type.c_str()),
|
||||
stream_track_type.size(), message, message_length);
|
||||
}
|
||||
if (!entitlements.empty()) {
|
||||
for (const auto& entitlement : entitlements) {
|
||||
AddParam(ENTITLEMENT_ID_KEY_COMBINATION,
|
||||
reinterpret_cast<const uint8_t*>(entitlement.c_str()),
|
||||
entitlement.size(), message, message_length);
|
||||
}
|
||||
}
|
||||
if (!content_ivs.empty()) {
|
||||
for (auto& content_iv : content_ivs) {
|
||||
AddParam(CONTENT_IV, reinterpret_cast<const uint8_t*>(content_iv.c_str()),
|
||||
@@ -293,25 +284,29 @@ TEST_F(EcmgClientHandlerTest, SuccessSequenceWithPrivateParameters) {
|
||||
}
|
||||
|
||||
TEST_F(EcmgClientHandlerTest, SuccessSequenceInjectedEntitlements) {
|
||||
BuildChannelSetupRequest(
|
||||
kChannelId, kSuperCasId, kAgeRestriction, kCryptoMode,
|
||||
{kTrackTypesHD, kTrackTypesSD},
|
||||
{absl::StrCat(kEntitlementKeyIdEven, kEntitlementKeyValueEven),
|
||||
absl::StrCat(kEntitlementKeyIdOdd, kEntitlementKeyValueOdd),
|
||||
absl::StrCat(kEntitlementKeyIdEven, kEntitlementKeyValueEven),
|
||||
absl::StrCat(kEntitlementKeyIdOdd, kEntitlementKeyValueOdd)},
|
||||
request_, &request_len_);
|
||||
BuildChannelSetupRequest(kChannelId, kSuperCasId, kAgeRestriction,
|
||||
kCryptoMode, request_, &request_len_);
|
||||
handler_->HandleRequest(request_, response_, &response_len_);
|
||||
EXPECT_EQ(sizeof(kTestEcmgChannelStatus), response_len_);
|
||||
EXPECT_EQ(0, memcmp(kTestEcmgChannelStatus, response_, response_len_));
|
||||
|
||||
BuildStreamSetupRequest(kChannelId, kStreamId, kEcmId, kNominalCpDuration,
|
||||
kTrackTypesSD, {kContentKeyEven, kContentKeyEven},
|
||||
request_, &request_len_);
|
||||
BuildStreamSetupRequest(
|
||||
kChannelId, kStreamId, kEcmId, kNominalCpDuration, kTrackTypesSD,
|
||||
{absl::StrCat(kEntitlementKeyIdEven, kEntitlementKeyValueEven),
|
||||
absl::StrCat(kEntitlementKeyIdOdd, kEntitlementKeyValueOdd)},
|
||||
{kContentKeyEven, kContentKeyEven}, request_, &request_len_);
|
||||
handler_->HandleRequest(request_, response_, &response_len_);
|
||||
EXPECT_EQ(sizeof(kTestEcmgStreamStatus), response_len_);
|
||||
EXPECT_EQ(0, memcmp(kTestEcmgStreamStatus, response_, response_len_));
|
||||
|
||||
BuildStreamSetupRequest(
|
||||
kChannelId, kStreamId + 1, kEcmId, kNominalCpDuration, kTrackTypesHD,
|
||||
{absl::StrCat(kEntitlementKeyIdEven, kEntitlementKeyValueEven),
|
||||
absl::StrCat(kEntitlementKeyIdOdd, kEntitlementKeyValueOdd)},
|
||||
{kContentKeyEven, kContentKeyEven}, request_, &request_len_);
|
||||
handler_->HandleRequest(request_, response_, &response_len_);
|
||||
EXPECT_EQ(sizeof(kTestEcmgStreamStatus), response_len_);
|
||||
|
||||
const std::vector<EcmgCpCwCombination> cp_cw_combination = {
|
||||
{kCpNumber, kContentKeyEven}, {kCpNumber + 1, kContentKeyOdd}};
|
||||
BuildCwProvisionRequest(kChannelId, kStreamId, kCpNumber, cp_cw_combination,
|
||||
@@ -319,8 +314,13 @@ TEST_F(EcmgClientHandlerTest, SuccessSequenceInjectedEntitlements) {
|
||||
handler_->HandleRequest(request_, response_, &response_len_);
|
||||
EXPECT_EQ(sizeof(kTestEcmgEcmResponse), response_len_);
|
||||
EXPECT_EQ(0, memcmp(kTestEcmgEcmResponse, response_, 27));
|
||||
}
|
||||
|
||||
BuildCwProvisionRequest(kChannelId, kStreamId + 1, kCpNumber,
|
||||
cp_cw_combination, request_, &request_len_);
|
||||
handler_->HandleRequest(request_, response_, &response_len_);
|
||||
EXPECT_EQ(sizeof(kTestEcmgEcmResponse), response_len_);
|
||||
}
|
||||
//
|
||||
TEST_F(EcmgClientHandlerTest, SuccessChannelError) {
|
||||
SetupValidChannel();
|
||||
handler_->HandleRequest(kTestEcmgChannelError, response_, &response_len_);
|
||||
@@ -410,11 +410,7 @@ TEST_F(EcmgClientHandlerTest, WrongParameterInsufficientKey) {
|
||||
|
||||
TEST_F(EcmgClientHandlerTest, WrongParameterSuperCasId) {
|
||||
// Setup a channel with an unexpected super cas id (expecting kSuperCasId).
|
||||
BuildChannelSetupRequest(
|
||||
kChannelId, 0, kAgeRestriction, kCryptoMode,
|
||||
{kTrackTypesHD, kTrackTypesSD},
|
||||
{absl::StrCat(kEntitlementKeyIdEven, kEntitlementKeyValueEven),
|
||||
absl::StrCat(kEntitlementKeyIdOdd, kEntitlementKeyValueOdd)},
|
||||
BuildChannelSetupRequest(kChannelId, 0, kAgeRestriction, kCryptoMode,
|
||||
request_, &request_len_);
|
||||
handler_->HandleRequest(request_, response_, &response_len_);
|
||||
CheckChannelError(UNKNOWN_SUPER_CAS_ID_VALUE, response_, response_len_);
|
||||
@@ -423,20 +419,18 @@ TEST_F(EcmgClientHandlerTest, WrongParameterSuperCasId) {
|
||||
TEST_F(EcmgClientHandlerTest, WrongParameterChannelId) {
|
||||
SetupValidChannel();
|
||||
// Setup a stream with an unexpected channel id (expecting kChannelId).
|
||||
BuildStreamSetupRequest(0, kStreamId, kEcmId, kNominalCpDuration,
|
||||
kTrackTypesSD, {kContentKeyEven, kContentKeyEven},
|
||||
request_, &request_len_);
|
||||
BuildStreamSetupRequest(
|
||||
0, kStreamId, kEcmId, kNominalCpDuration, kTrackTypesSD,
|
||||
{absl::StrCat(kEntitlementKeyIdEven, kEntitlementKeyValueEven),
|
||||
absl::StrCat(kEntitlementKeyIdOdd, kEntitlementKeyValueOdd)},
|
||||
{kContentKeyEven, kContentKeyEven}, request_, &request_len_);
|
||||
handler_->HandleRequest(request_, response_, &response_len_);
|
||||
CheckStreamError(UNKNOWN_ECM_CHANNEL_ID_VALUE, response_, response_len_);
|
||||
}
|
||||
|
||||
TEST_F(EcmgClientHandlerTest, WrongParameterCryptoMode) {
|
||||
BuildChannelSetupRequest(
|
||||
kChannelId, kSuperCasId, kAgeRestriction, "someCryptoMode",
|
||||
{kTrackTypesHD, kTrackTypesSD},
|
||||
{absl::StrCat(kEntitlementKeyIdEven, kEntitlementKeyValueEven),
|
||||
absl::StrCat(kEntitlementKeyIdOdd, kEntitlementKeyValueOdd)},
|
||||
request_, &request_len_);
|
||||
BuildChannelSetupRequest(kChannelId, kSuperCasId, kAgeRestriction,
|
||||
"someCryptoMode", request_, &request_len_);
|
||||
handler_->HandleRequest(request_, response_, &response_len_);
|
||||
CheckChannelError(INVALID_VALUE_FOR_DVB_PARAMETER, response_, response_len_);
|
||||
}
|
||||
@@ -451,15 +445,15 @@ TEST_F(EcmgClientHandlerTest, WrongParameterLengthSuperCasId) {
|
||||
|
||||
TEST_F(EcmgClientHandlerTest, NoInjectedEntitlements) {
|
||||
BuildChannelSetupRequest(kChannelId, kSuperCasId, kAgeRestriction,
|
||||
kCryptoMode, {kTrackTypesSD},
|
||||
/*entitlements*/ {}, request_, &request_len_);
|
||||
kCryptoMode, request_, &request_len_);
|
||||
handler_->HandleRequest(request_, response_, &response_len_);
|
||||
EXPECT_EQ(sizeof(kTestEcmgChannelStatus), response_len_);
|
||||
EXPECT_EQ(0, memcmp(kTestEcmgChannelStatus, response_, response_len_));
|
||||
|
||||
BuildStreamSetupRequest(kChannelId, kStreamId, kEcmId, kNominalCpDuration,
|
||||
kTrackTypesSD, {kContentKeyEven, kContentKeyEven},
|
||||
request_, &request_len_);
|
||||
BuildStreamSetupRequest(
|
||||
kChannelId, kStreamId, kEcmId, kNominalCpDuration, kTrackTypesSD,
|
||||
/*entitlements*/ {}, {kContentKeyEven, kContentKeyEven}, request_,
|
||||
&request_len_);
|
||||
handler_->HandleRequest(request_, response_, &response_len_);
|
||||
EXPECT_EQ(sizeof(kTestEcmgStreamStatus), response_len_);
|
||||
EXPECT_EQ(0, memcmp(kTestEcmgStreamStatus, response_, response_len_));
|
||||
@@ -473,19 +467,16 @@ TEST_F(EcmgClientHandlerTest, NoInjectedEntitlements) {
|
||||
}
|
||||
|
||||
TEST_F(EcmgClientHandlerTest, NotEnoughInjectedEntitlements) {
|
||||
BuildChannelSetupRequest(
|
||||
kChannelId, kSuperCasId, kAgeRestriction, kCryptoMode,
|
||||
{kTrackTypesHD, kTrackTypesSD},
|
||||
{absl::StrCat(kEntitlementKeyIdEven, kEntitlementKeyValueEven),
|
||||
absl::StrCat(kEntitlementKeyIdOdd, kEntitlementKeyValueOdd)},
|
||||
request_, &request_len_);
|
||||
BuildChannelSetupRequest(kChannelId, kSuperCasId, kAgeRestriction,
|
||||
kCryptoMode, request_, &request_len_);
|
||||
handler_->HandleRequest(request_, response_, &response_len_);
|
||||
EXPECT_EQ(sizeof(kTestEcmgChannelStatus), response_len_);
|
||||
EXPECT_EQ(0, memcmp(kTestEcmgChannelStatus, response_, response_len_));
|
||||
|
||||
BuildStreamSetupRequest(kChannelId, kStreamId, kEcmId, kNominalCpDuration,
|
||||
kTrackTypesSD, {kContentKeyEven, kContentKeyEven},
|
||||
request_, &request_len_);
|
||||
BuildStreamSetupRequest(
|
||||
kChannelId, kStreamId, kEcmId, kNominalCpDuration, kTrackTypesSD,
|
||||
{absl::StrCat(kEntitlementKeyIdEven, kEntitlementKeyValueEven)},
|
||||
{kContentKeyEven, kContentKeyEven}, request_, &request_len_);
|
||||
handler_->HandleRequest(request_, response_, &response_len_);
|
||||
EXPECT_EQ(sizeof(kTestEcmgStreamStatus), response_len_);
|
||||
EXPECT_EQ(0, memcmp(kTestEcmgStreamStatus, response_, response_len_));
|
||||
@@ -499,19 +490,18 @@ TEST_F(EcmgClientHandlerTest, NotEnoughInjectedEntitlements) {
|
||||
}
|
||||
|
||||
TEST_F(EcmgClientHandlerTest, TooManyInjectedEntitlements) {
|
||||
BuildChannelSetupRequest(
|
||||
kChannelId, kSuperCasId, kAgeRestriction, kCryptoMode, {kTrackTypesSD},
|
||||
{absl::StrCat(kEntitlementKeyIdEven, kEntitlementKeyValueEven),
|
||||
absl::StrCat(kEntitlementKeyIdOdd, kEntitlementKeyValueOdd),
|
||||
absl::StrCat(kEntitlementKeyIdEven, kEntitlementKeyValueEven)},
|
||||
request_, &request_len_);
|
||||
BuildChannelSetupRequest(kChannelId, kSuperCasId, kAgeRestriction,
|
||||
kCryptoMode, request_, &request_len_);
|
||||
handler_->HandleRequest(request_, response_, &response_len_);
|
||||
EXPECT_EQ(sizeof(kTestEcmgChannelStatus), response_len_);
|
||||
EXPECT_EQ(0, memcmp(kTestEcmgChannelStatus, response_, response_len_));
|
||||
|
||||
BuildStreamSetupRequest(kChannelId, kStreamId, kEcmId, kNominalCpDuration,
|
||||
kTrackTypesSD, {kContentKeyEven, kContentKeyEven},
|
||||
request_, &request_len_);
|
||||
BuildStreamSetupRequest(
|
||||
kChannelId, kStreamId, kEcmId, kNominalCpDuration, kTrackTypesSD,
|
||||
{absl::StrCat(kEntitlementKeyIdEven, kEntitlementKeyValueEven),
|
||||
absl::StrCat(kEntitlementKeyIdOdd, kEntitlementKeyValueOdd),
|
||||
absl::StrCat(kEntitlementKeyIdEven, kEntitlementKeyValueEven)},
|
||||
{kContentKeyEven, kContentKeyEven}, request_, &request_len_);
|
||||
handler_->HandleRequest(request_, response_, &response_len_);
|
||||
EXPECT_EQ(sizeof(kTestEcmgStreamStatus), response_len_);
|
||||
EXPECT_EQ(0, memcmp(kTestEcmgStreamStatus, response_, response_len_));
|
||||
|
||||
@@ -63,10 +63,9 @@
|
||||
// User defined ECMG parameter type values - 0x8000 to 0xFFFF.
|
||||
#define AGE_RESTRICTION (0x8000)
|
||||
#define CRYPTO_MODE (0x8001)
|
||||
#define TRACK_TYPES (0x8002)
|
||||
#define STREAM_TRACK_TYPE (0x8003)
|
||||
#define CONTENT_IV (0x8004)
|
||||
#define ENTITLEMENT_ID_KEY_COMBINATION (0x8005)
|
||||
#define STREAM_TRACK_TYPE (0x8002)
|
||||
#define CONTENT_IV (0x8003)
|
||||
#define ENTITLEMENT_ID_KEY_COMBINATION (0x8004)
|
||||
|
||||
// ECMG protocol error values.
|
||||
#define INVALID_MESSAGE (0x0001)
|
||||
|
||||
Reference in New Issue
Block a user