Add EMMG to carry fingerprinting and service blocking info

This commit is contained in:
Widevine Buildbot
2020-09-15 17:24:55 +00:00
parent 535930dc60
commit 8fd98d66f3
14 changed files with 205 additions and 49 deletions

View File

@@ -1,15 +1,9 @@
//////////////////////////////////////////////////////////////////////////////// // Copyright 2017 Google LLC. All rights reserved.
// Copyright 2017 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.
////////////////////////////////////////////////////////////////////////////////
#ifndef COMMON_CERTIFICATE_TYPE_H_ #ifndef VIDEO_WIDEVINE_EXPORT_COMMON_CERTIFICATE_TYPE_H_
#define COMMON_CERTIFICATE_TYPE_H_ #define VIDEO_WIDEVINE_EXPORT_COMMON_CERTIFICATE_TYPE_H_
namespace widevine { namespace video_widevine {
enum CertificateType { enum CertificateType {
kCertificateTypeTesting, kCertificateTypeTesting,
@@ -17,6 +11,6 @@ enum CertificateType {
kCertificateTypeProduction, kCertificateTypeProduction,
}; };
} // namespace widevine } // namespace video_widevine
#endif // COMMON_CERTIFICATE_TYPE_H_ #endif // VIDEO_WIDEVINE_EXPORT_COMMON_CERTIFICATE_TYPE_H_

View File

@@ -1,20 +1,14 @@
//////////////////////////////////////////////////////////////////////////////// // Copyright 2020 Google LLC. All rights reserved.
// Copyright 2020 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: // Description:
// Container of Widevine default security profiless. // Container of Widevine default security profiless.
#ifndef COMMON_DEFAULT_DEVICE_SECURITY_PROFILE_LIST_H_ #ifndef VIDEO_WIDEVINE_EXPORT_COMMON_DEFAULT_DEVICE_SECURITY_PROFILE_LIST_H_
#define COMMON_DEFAULT_DEVICE_SECURITY_PROFILE_LIST_H_ #define VIDEO_WIDEVINE_EXPORT_COMMON_DEFAULT_DEVICE_SECURITY_PROFILE_LIST_H_
#include "common/security_profile_list.h" #include "video/widevine/export/common/security_profile_list.h"
namespace widevine { namespace video_widevine {
class DefaultDeviceSecurityProfileList : public SecurityProfileList { class DefaultDeviceSecurityProfileList : public SecurityProfileList {
public: public:
@@ -34,6 +28,6 @@ class DefaultDeviceSecurityProfileList : public SecurityProfileList {
std::vector<std::string>* default_profile_strings) const; std::vector<std::string>* default_profile_strings) const;
}; };
} // namespace widevine } // namespace video_widevine
#endif // COMMON_DEFAULT_DEVICE_SECURITY_PROFILE_LIST_H_ #endif // VIDEO_WIDEVINE_EXPORT_COMMON_DEFAULT_DEVICE_SECURITY_PROFILE_LIST_H_

View File

@@ -1,26 +1,20 @@
//////////////////////////////////////////////////////////////////////////////// // Copyright 2020 Google LLC. All rights reserved.
// Copyright 2020 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: // Description:
// Container of device security profiles. Security profiles indicate rules // Container of device security profiles. Security profiles indicate rules
// to allow using the profile. The rules are based on DRM capabilities of a // to allow using the profile. The rules are based on DRM capabilities of a
// device. // device.
#ifndef COMMON_SECURITY_PROFILE_LIST_H_ #ifndef VIDEO_WIDEVINE_EXPORT_COMMON_SECURITY_PROFILE_LIST_H_
#define COMMON_SECURITY_PROFILE_LIST_H_ #define VIDEO_WIDEVINE_EXPORT_COMMON_SECURITY_PROFILE_LIST_H_
#include "absl/synchronization/mutex.h" #include "third_party/absl/synchronization/mutex.h"
#include "protos/public/client_identification.pb.h" #include "video/widevine/protos/public/client_identification.proto.h"
#include "protos/public/device_security_profile_data.pb.h" #include "video/widevine/protos/public/device_security_profile_data.proto.h"
#include "protos/public/provisioned_device_info.pb.h" #include "video/widevine/protos/public/provisioned_device_info.proto.h"
#include "protos/public/security_profile.pb.h" #include "video/widevine/protos/public/security_profile.proto.h"
namespace widevine { namespace video_widevine {
using ClientCapabilities = ClientIdentification::ClientCapabilities; using ClientCapabilities = ClientIdentification::ClientCapabilities;
// The SecurityProfileList will hold all security profiles. During license // The SecurityProfileList will hold all security profiles. During license
@@ -82,6 +76,10 @@ class SecurityProfileList {
const ClientIdentification& client_id, const ClientIdentification& client_id,
const ProvisionedDeviceInfo& device_info) const; const ProvisionedDeviceInfo& device_info) const;
int64 GetCurrentTimeSeconds() const;
bool IsProfileActive(const SecurityProfile& profile,
int64 current_time_seconds) const;
mutable absl::Mutex mutex_; mutable absl::Mutex mutex_;
// Security profiles // Security profiles
@@ -89,5 +87,5 @@ class SecurityProfileList {
std::vector<SecurityProfile> security_profiles_ ABSL_GUARDED_BY(mutex_); std::vector<SecurityProfile> security_profiles_ ABSL_GUARDED_BY(mutex_);
}; };
} // namespace widevine } // namespace video_widevine
#endif // COMMON_SECURITY_PROFILE_LIST_H_ #endif // VIDEO_WIDEVINE_EXPORT_COMMON_SECURITY_PROFILE_LIST_H_

View File

@@ -52,7 +52,7 @@ const char kTestEmmgChannelSetup[] = {
'\x01' // parameter_value '\x01' // parameter_value
}; };
const char kTestEmmgStreamSetup[] = { const char kTestEmmgStreamSetupForPrivateData[] = {
'\x02', // protocol_version '\x02', // protocol_version
'\x01', '\x11', // message_type - Stream_setup '\x01', '\x11', // message_type - Stream_setup
'\x00', '\x1f', // message_length '\x00', '\x1f', // message_length
@@ -73,6 +73,27 @@ const char kTestEmmgStreamSetup[] = {
'\x01' // parameter_value - private data '\x01' // parameter_value - private data
}; };
const char kTestEmmgStreamSetupForEmm[] = {
'\x02', // protocol_version
'\x01', '\x11', // message_type - Stream_setup
'\x00', '\x1f', // message_length
'\x00', '\x01', // parameter_type - client_id
'\x00', '\x04', // parameter_length
'\x4a', '\xd4', '\x00', '\x00', // parameter_value
'\x00', '\x03', // parameter_type - data_channel_id
'\x00', '\x02', // parameter_length
'\x00', '\x01', // parameter_value
'\x00', '\x04', // parameter_type - data_stream_id
'\x00', '\x02', // parameter_length
'\x00', '\x01', // parameter_value
'\x00', '\x08', // parameter_type - data_id
'\x00', '\x02', // parameter_length
'\x00', '\x01', // parameter_value
'\x00', '\x07', // parameter_type - data_type
'\x00', '\x01', // parameter_length
'\x00' // parameter_value - emm
};
const char kTestEmmgStreamBwRequest[] = { const char kTestEmmgStreamBwRequest[] = {
'\x02', // protocol_version '\x02', // protocol_version
'\x01', '\x17', // message_type - Stream_BW_request '\x01', '\x17', // message_type - Stream_BW_request
@@ -109,7 +130,7 @@ const char kTestEmmgStreamBwAllocation[] = {
'\x00', '\x32' // parameter_value (50 kbps) '\x00', '\x32' // parameter_value (50 kbps)
}; };
const char kTestEmmgDataProvision[] = { const char kTestEmmgPrivateDataProvision[] = {
'\x02', // protocol_version '\x02', // protocol_version
'\x02', '\x11', // message_type - Data_provision '\x02', '\x11', // message_type - Data_provision
'\x00', '\xda', // message_length '\x00', '\xda', // message_length
@@ -149,10 +170,10 @@ const char kTestEmmgDataProvision[] = {
'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}; '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'};
const char kTestEmptyEmmgDataProvision[] = { const char kTestEmmgEmmDataProvision[] = {
'\x02', // protocol_version '\x02', // protocol_version
'\x02', '\x11', // message_type - Data_provision '\x02', '\x11', // message_type - Data_provision
'\x00', '\x00', // message_length '\x01', '\x96', // message_length
'\x00', '\x01', // parameter_type - client_id '\x00', '\x01', // parameter_type - client_id
'\x00', '\x04', // parameter_length '\x00', '\x04', // parameter_length
'\x4a', '\xd4', '\x00', '\x00', // parameter_value '\x4a', '\xd4', '\x00', '\x00', // parameter_value
@@ -165,9 +186,57 @@ const char kTestEmptyEmmgDataProvision[] = {
'\x00', '\x08', // parameter_type - data_id '\x00', '\x08', // parameter_type - data_id
'\x00', '\x02', // parameter_length '\x00', '\x02', // parameter_length
'\x00', '\x01', // parameter_value '\x00', '\x01', // parameter_value
'\x00', '\x00', // parameter_type - datagram '\x00', '\x05', // parameter_type - datagram
'\x00', '\x00', // parameter_length '\x01', '\x78', // parameter_length
}; // Start of the first TS packet (188 bytes).
'\x47', '\x40', '\x00', '\x10', // TS packet header (4 bytes).
'\x00', // Pointer field (1 byte).
'\x82', '\x70', '\xbe', // Secyion header (3 bytes).
// Start of Widevine EMM.
'\x01', '\x08', '\x00', '\x00', '\x00', '\x00', '\x5f', '\x3d', '\xc1',
'\xfb', '\x00', '\x6b', '\x0a', '\x14', '\x0a', '\x03', '\x43', '\x48',
'\x31', '\x0a', '\x03', '\x43', '\x48', '\x32', '\x12', '\x08', '\x63',
'\x6f', '\x6e', '\x74', '\x72', '\x6f', '\x6c', '\x73', '\x0a', '\x16',
'\x0a', '\x03', '\x43', '\x48', '\x33', '\x12', '\x0f', '\x61', '\x6e',
'\x6f', '\x74', '\x68', '\x65', '\x72', '\x20', '\x63', '\x6f', '\x6e',
'\x74', '\x72', '\x6f', '\x6c', '\x12', '\x18', '\x0a', '\x03', '\x43',
'\x48', '\x31', '\x0a', '\x03', '\x43', '\x48', '\x32', '\x12', '\x06',
'\x47', '\x72', '\x6f', '\x75', '\x70', '\x31', '\x20', '\xd2', '\x85',
'\xd8', '\xcc', '\x04', '\x12', '\x21', '\x0a', '\x03', '\x43', '\x48',
'\x33', '\x12', '\x06', '\x47', '\x72', '\x6f', '\x75', '\x70', '\x32',
'\x12', '\x06', '\x47', '\x72', '\x6f', '\x75', '\x70', '\x33', '\x18',
'\xd2', '\x85', '\xd8', '\xcc', '\x04', '\x20', '\xd3', '\x85', '\xd8',
'\xcc', '\x04', '\x78', '\x78', '\x78', '\x78', '\x78', '\x78', '\x78',
'\x78', '\x78', '\x78', '\x78', '\x78', '\x78', '\x78', '\x78', '\x78',
'\x78', '\x78', '\x78', '\x78', '\x78', '\x78', '\x78', '\x78', '\x78',
'\x78', '\x78', '\x78', '\x78', '\x78', '\x78', '\x78', '\x78', '\x78',
'\x78', '\x78', '\x78', '\x78', '\x78', '\x78', '\x78', '\x78', '\x78',
'\x78', '\x78', '\x78', '\x78', '\x78', '\x78', '\x78', '\x78', '\x78',
'\x78', '\x78', '\x78', '\x78', '\x78', '\x78', '\x78', '\x78', '\x78',
// Start of the second TS packet (188 bytes).
'\x47', '\x00', '\x00', '\x11', // TS packet header (4 bytes).
// Continued Widevine EMM.
'\x78', '\x78', '\x78', '\x78', '\x78', '\x78', '\x78', '\x78', '\x78',
'\x78', '\xff', '\xff', '\xff', '\xff', '\xff', '\xff', '\xff', '\xff',
'\xff', '\xff', '\xff', '\xff', '\xff', '\xff', '\xff', '\xff', '\xff',
'\xff', '\xff', '\xff', '\xff', '\xff', '\xff', '\xff', '\xff', '\xff',
'\xff', '\xff', '\xff', '\xff', '\xff', '\xff', '\xff', '\xff', '\xff',
'\xff', '\xff', '\xff', '\xff', '\xff', '\xff', '\xff', '\xff', '\xff',
'\xff', '\xff', '\xff', '\xff', '\xff', '\xff', '\xff', '\xff', '\xff',
'\xff', '\xff', '\xff', '\xff', '\xff', '\xff', '\xff', '\xff', '\xff',
'\xff', '\xff', '\xff', '\xff', '\xff', '\xff', '\xff', '\xff', '\xff',
'\xff', '\xff', '\xff', '\xff', '\xff', '\xff', '\xff', '\xff', '\xff',
'\xff', '\xff', '\xff', '\xff', '\xff', '\xff', '\xff', '\xff', '\xff',
'\xff', '\xff', '\xff', '\xff', '\xff', '\xff', '\xff', '\xff', '\xff',
'\xff', '\xff', '\xff', '\xff', '\xff', '\xff', '\xff', '\xff', '\xff',
'\xff', '\xff', '\xff', '\xff', '\xff', '\xff', '\xff', '\xff', '\xff',
'\xff', '\xff', '\xff', '\xff', '\xff', '\xff', '\xff', '\xff', '\xff',
'\xff', '\xff', '\xff', '\xff', '\xff', '\xff', '\xff', '\xff', '\xff',
'\xff', '\xff', '\xff', '\xff', '\xff', '\xff', '\xff', '\xff', '\xff',
'\xff', '\xff', '\xff', '\xff', '\xff', '\xff', '\xff', '\xff', '\xff',
'\xff', '\xff', '\xff', '\xff', '\xff', '\xff', '\xff', '\xff', '\xff',
'\xff', '\xff', '\xff', '\xff', '\xff', '\xff', '\xff', '\xff', '\xff',
'\xff', '\xff', '\xff', '\xff'};
const char kTestEmmgStreamCloseRequest[] = { const char kTestEmmgStreamCloseRequest[] = {
'\x02', // protocol_version '\x02', // protocol_version

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,91 @@
////////////////////////////////////////////////////////////////////////////////
// Copyright 2020 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.
////////////////////////////////////////////////////////////////////////////////
#ifndef MEDIA_CAS_PACKAGER_SDK_PUBLIC_WV_CAS_EMM_H_
#define MEDIA_CAS_PACKAGER_SDK_PUBLIC_WV_CAS_EMM_H_
#include <memory>
#include <string>
#include <vector>
#include <cstdint>
#include "common/status.h"
namespace widevine {
namespace cas {
class Emm;
struct WvCasFingerprintingInitParameters {
std::vector<std::string> channels;
std::string control;
};
struct WvCasServiceBlockingInitParameters {
std::vector<std::string> channels;
std::vector<std::string> device_groups;
// Value 0 in start_time means immediate.
int64_t start_time = 0;
int64_t end_time;
};
// Class for generating Widevine CAS EMMs. Widevine CAS EMMs are not used for
// carrying entitlement information. Instead, it is used as an information
// channel carrying information for fingerprinting, service blocking, etc.
// Class WvCasEmm is NOT thread-safe.
class WvCasEmm {
public:
WvCasEmm(const WvCasEmm&) = delete;
WvCasEmm& operator=(const WvCasEmm&) = delete;
virtual ~WvCasEmm();
// Creates and returns a WvCasEmm with the given private ECC signing key.
// Returns a null value if the creation is unsuccessful.
static std::unique_ptr<WvCasEmm> Create(
const std::string& private_ecc_signing_key);
// Replaces current fingerprinting info with |fingerprintings|.
virtual Status SetFingerprinting(
const std::vector<WvCasFingerprintingInitParameters>& fingerprintings);
// Replaces current service blocking info with |service_blockings|.
virtual Status SetServiceBlocking(
const std::vector<WvCasServiceBlockingInitParameters>& service_blockings);
// Constructs an EMM payload with fingerprinting info set by calling
// SetFingerprinting(), and service blocking info set by calling
// SetServiceBlocking().
// Args (all pointer parameters must not be nullptr):
// - |serialized_emm| caller-supplied std::string pointer to receive the EMM.
virtual Status GenerateEmm(std::string* serialized_emm) const;
// Generates EMM that are wrapped in TS packets.
// Args (all pointer parameters must not be nullptr):
// - |pid| program ID for the EMM stream.
// - |continuity_counter| continuity_counter for the TS packet. It will be
// automatically incremented. Only the last 4 bits are used.
// - |packet| a buffer to be used to return the generated TS packet. Must be
// able to hold the maximum possible size of genereated Ts packets
// (kMaxPossibleTsPacketsSizeBytes = 1128 bytes).
// - |packet_size| is the size of the allocated |packet|. It will be updated
// as the number of bytes actually used.
virtual Status GenerateEmmTsPackets(uint16_t pid, uint8_t* continuity_counter,
uint8_t* packet,
ssize_t* packet_size) const;
protected:
explicit WvCasEmm(std::unique_ptr<Emm> emm);
private:
std::unique_ptr<Emm> emm_;
};
} // namespace cas
} // namespace widevine
#endif // MEDIA_CAS_PACKAGER_SDK_PUBLIC_WV_CAS_EMM_H_

View File

@@ -26,11 +26,15 @@ namespace cas {
// server. // server.
// |key_rotation| the encryption uses two keys if set. Two entitlement keys // |key_rotation| the encryption uses two keys if set. Two entitlement keys
// are requested for each track type. // are requested for each track type.
// |group_id| optional field indicates if this is a key used for a group of
// contents. If this field is not empty, entitlement key would be generated
// for the group instead of the single content.
struct EntitlementRequestParams { struct EntitlementRequestParams {
std::string content_id; std::string content_id;
std::string content_provider; std::string content_provider;
std::vector<std::string> track_types; std::vector<std::string> track_types;
bool key_rotation; bool key_rotation;
std::string group_id;
}; };
// WV CAS KeyFetcher. Performs the communication with the Widevine License // WV CAS KeyFetcher. Performs the communication with the Widevine License

View File

@@ -92,6 +92,9 @@ Status CreateWvCasEncryptionRequestJson(const WvCasEncryptionRequest& request,
CasEncryptionRequest request_proto; CasEncryptionRequest request_proto;
request_proto.set_content_id(request.content_id); request_proto.set_content_id(request.content_id);
request_proto.set_provider(request.provider); request_proto.set_provider(request.provider);
if (!request.group_id.empty()) {
request_proto.set_group_id(request.group_id);
}
for (const std::string& track_type : request.track_types) { for (const std::string& track_type : request.track_types) {
request_proto.add_track_types(track_type); request_proto.add_track_types(track_type);
} }
@@ -129,6 +132,7 @@ Status ParseWvCasEncryptionResponseJson(const std::string& response_json,
static_cast<WvCasEncryptionResponse::Status>(response_proto.status()); static_cast<WvCasEncryptionResponse::Status>(response_proto.status());
response->status_message = response_proto.status_message(); response->status_message = response_proto.status_message();
response->content_id = response_proto.content_id(); response->content_id = response_proto.content_id();
response->group_id = response_proto.group_id();
for (const auto& key_info_proto : response_proto.entitlement_keys()) { for (const auto& key_info_proto : response_proto.entitlement_keys()) {
WvCasEncryptionResponse::KeyInfo key_info; WvCasEncryptionResponse::KeyInfo key_info;
key_info.key_id = key_info_proto.key_id(); key_info.key_id = key_info_proto.key_id();

View File

@@ -68,6 +68,7 @@ struct EntitlementKeyInfo {
struct WvCasEncryptionRequest { struct WvCasEncryptionRequest {
std::string content_id; std::string content_id;
std::string provider; std::string provider;
std::string group_id;
// Track types such as "AUDIO", SD" or "HD". // Track types such as "AUDIO", SD" or "HD".
std::vector<std::string> track_types; std::vector<std::string> track_types;
// Indicates if the client is using key rotation. If true, the server will // Indicates if the client is using key rotation. If true, the server will
@@ -104,6 +105,7 @@ struct WvCasEncryptionResponse {
Status status; Status status;
std::string status_message; std::string status_message;
std::string content_id; std::string content_id;
std::string group_id;
std::vector<KeyInfo> entitlement_keys; std::vector<KeyInfo> entitlement_keys;
}; };