Update license_protocol and client_identification protos

[ Merge of http://go/wvgerrit/65442 ]

This also requires the removal of sub session related code as references
were removed from the proto.

Bug: 119077124
Test: WV unit/integration tests
Change-Id: Ida1a591afc267ec97344e5bba00bbf401887a202
This commit is contained in:
Rahul Frias
2018-11-05 10:08:53 -08:00
parent 87b3c3cbe7
commit d8cc5481e3
3 changed files with 64 additions and 170 deletions

View File

@@ -50,30 +50,6 @@ using video_widevine::LicenseRequest_ContentIdentification_WebmDeprecated;
using video_widevine::SignedDrmDeviceCertificate;
using video_widevine::SignedMessage;
static std::vector<CryptoKey> ExtractSubSessionKeys(const License& license) {
std::vector<CryptoKey> key_array;
// Extract sub session key(s)
for (int i = 0; i < license.key_size(); ++i) {
CryptoKey key;
switch (license.key(i).type()) {
case License_KeyContainer::SUB_SESSION:
key.set_key_data(license.key(i).key());
key.set_key_data_iv(license.key(i).iv());
key.set_key_id(license.key(i).id());
key.set_track_label(license.key(i).track_label());
key_array.push_back(key);
break;
default:
// Ignore all but SUB_SESSION key types.
break;
}
}
return key_array;
}
static std::vector<CryptoKey> ExtractEntitlementKeys(const License& license) {
std::vector<CryptoKey> key_array;
@@ -194,22 +170,6 @@ static std::vector<CryptoKey> ExtractContentKeys(const License& license) {
}
}
std::vector<CryptoKey> sub_session_keys = ExtractSubSessionKeys(license);
// Match the track label from the key arrays and add sub_license_key_id to
// the content key array.
LOGV("Received %d subsession keys", sub_session_keys.size());
if (!sub_session_keys.empty()) {
for (size_t i = 0; i < key_array.size(); ++i) {
if (key_array[i].track_label().empty()) continue;
for (size_t x = 0; x < sub_session_keys.size(); ++x) {
if (sub_session_keys[x].track_label() == key_array[i].track_label()) {
key_array[i].set_sub_session_key_id(sub_session_keys[x].key_id());
key_array[i].set_sub_session_key(sub_session_keys[x].key_data());
}
}
}
}
return key_array;
}
@@ -387,13 +347,6 @@ CdmResponseType CdmLicense::PrepareKeyRequest(
keyc.track_label().empty()) {
return LICENSE_REQUEST_INVALID_SUBLICENSE;
}
LicenseRequest::SubSessionData* sub_session_data =
license_request.add_sub_session_data();
sub_session_data->set_sub_session_key_id(
embedded_key_data[i].sub_session_key_id());
sub_session_data->set_nonce(nonce);
sub_session_data->set_track_label(keyc.track_label());
}
license_request.set_protocol_version(video_widevine::VERSION_2_1);

View File

@@ -23,6 +23,22 @@ enum LicenseType {
OFFLINE = 2;
}
enum PlatformVerificationStatus {
// The platform is not verified.
PLATFORM_UNVERIFIED = 0;
// Tampering detected on the platform.
PLATFORM_TAMPERED = 1;
// The platform has been verified by means of software.
PLATFORM_SOFTWARE_VERIFIED = 2;
// The platform has been verified by means of hardware (e.g. secure boot).
PLATFORM_HARDWARE_VERIFIED = 3;
// Platform verification was not performed.
PLATFORM_NO_VERIFICATION = 4;
// Platform and secure storage capability have been verified by means of
// software.
PLATFORM_SECURE_STORAGE_SOFTWARE_VERIFIED = 5;
}
// LicenseIdentification is propagated from LicenseRequest to License,
// incrementing version with each iteration.
message LicenseIdentification {
@@ -98,16 +114,11 @@ message License {
message KeyContainer {
enum KeyType {
// Exactly one key of this type must appear.
SIGNING = 1;
CONTENT = 2;
KEY_CONTROL = 3;
OPERATOR_SESSION = 4;
// TODO(jfore): Drop subsession type once subsession support is removed
// from the cdm. For now, SUB_SESSION is defined as type 6 so that it
// is defined to satisfy the build.
SUB_SESSION = 6;
ENTITLEMENT = 5;
SIGNING = 1; // Exactly one key of this type must appear.
CONTENT = 2; // Content key.
KEY_CONTROL = 3; // Key control block for license renewals. No key.
OPERATOR_SESSION = 4; // wrapped keys for auxiliary crypto operations.
ENTITLEMENT = 5; // Entitlement keys.
}
// The SecurityLevel enumeration allows the server to communicate the level
@@ -152,6 +163,7 @@ message License {
HDCP_V2 = 2;
HDCP_V2_1 = 3;
HDCP_V2_2 = 4;
HDCP_V2_3 = 5;
HDCP_NO_DIGITAL_OUTPUT = 0xff;
}
optional HDCP hdcp = 1 [default = HDCP_NONE];
@@ -164,6 +176,20 @@ message License {
COPY_NEVER = 3;
}
optional CGMS cgms_flags = 2 [default = CGMS_NONE];
enum HdcpSrmRule {
HDCP_SRM_RULE_NONE = 0;
// In 'required_protection', this means most current SRM is required.
// Update the SRM on the device. If update cannot happen,
// do not allow the key.
// In 'requested_protection', this means most current SRM is requested.
// Update the SRM on the device. If update cannot happen,
// allow use of the key anyway.
CURRENT_SRM = 1;
}
optional HdcpSrmRule hdcp_srm_rule = 3 [default = HDCP_SRM_RULE_NONE];
// Optional requirement to indicate analog output is not allowed.
optional bool disable_analog_output = 4 [default = false];
}
message VideoResolutionConstraint {
@@ -218,6 +244,8 @@ message License {
// LicenseRequest.request_time. If this time is not set in the request,
// the local time at the license service is used in this field.
optional int64 license_start_time = 4;
// TODO(b/65054419): Deprecate remote_attestation_verified in favor of
// platform_verification_status, below.
optional bool remote_attestation_verified = 5 [default = false];
// Client token generated by the content provider. Optional.
optional bytes provider_client_token = 6;
@@ -225,12 +253,22 @@ message License {
// specification. Propagated from Widevine PSSH box. Optional.
optional uint32 protection_scheme = 7;
// 8 byte verification field "HDCPDATA" followed by unsigned 32 bit minimum
// HDCP SRM version. Additional details can be found in
// Widevine Modular DRM Security Integration Guide for CENC.
// HDCP SRM version (whether the version is for HDCP1 SRM or HDCP2 SRM
// depends on client max_hdcp_version).
// Additional details can be found in Widevine Modular DRM Security
// Integration Guide for CENC.
optional bytes srm_requirement = 8;
// If present this contains a signed SRM file that should be installed
// on the client device.
// If present this contains a signed SRM file (either HDCP1 SRM or HDCP2 SRM
// depending on client max_hdcp_version) that should be installed on the
// client device.
optional bytes srm_update = 9;
// Indicates the status of any type of platform verification performed by the
// server.
optional PlatformVerificationStatus platform_verification_status = 10
[default = PLATFORM_NO_VERIFICATION];
// IDs of the groups for which keys are delivered in this license, if any.
repeated bytes group_ids = 11;
}
enum ProtocolVersion {
@@ -240,7 +278,7 @@ enum ProtocolVersion {
message LicenseRequest {
message ContentIdentification {
message CencDeprecated {
message CencDeprecated {
repeated bytes pssh = 1;
optional LicenseType license_type = 2;
optional bytes request_id = 3; // Opaque, client-specified.
@@ -271,26 +309,13 @@ message LicenseRequest {
optional bytes request_id = 4;
}
//oneof content_id_variant {
oneof content_id_variant {
// Exactly one of these must be present.
optional CencDeprecated cenc_id_deprecated = 1;
optional WebmDeprecated webm_id_deprecated = 2;
optional ExistingLicense existing_license = 3;
optional InitData init_data = 4;
//}
}
message SubSessionData {
// Required. The key ID for the corresponding SUB_SESSION_KEY. The
// value must match the sub_session_key_id field for a
// corresponding SubLicense message from the PSSH.
optional string sub_session_key_id = 1;
// Required. The nonce for the track.
optional uint32 nonce = 2;
// Required for initial license request used for each CONTENT key_container
// to know which nonce to use for building its key control block.
// Not needed for renewal license request.
optional string track_label = 3;
CencDeprecated cenc_id_deprecated = 1;
WebmDeprecated webm_id_deprecated = 2;
ExistingLicense existing_license = 3;
InitData init_data = 4;
}
}
enum RequestType {
@@ -316,9 +341,6 @@ message LicenseRequest {
optional uint32 key_control_nonce = 7;
// Encrypted ClientIdentification message, used for privacy purposes.
optional EncryptedClientIdentification encrypted_client_id = 8;
// Optional sub session context information. Required for using
// SubLicenses from the PSSH.
repeated SubSessionData sub_session_data = 9;
}
message LicenseError {
@@ -332,7 +354,6 @@ message LicenseError {
// or similar circumstances.
SERVICE_UNAVAILABLE = 3;
}
optional Error error_code = 1;
}
@@ -376,6 +397,9 @@ message SignedMessage {
ERROR_RESPONSE = 3;
SERVICE_CERTIFICATE_REQUEST = 4;
SERVICE_CERTIFICATE = 5;
SUB_LICENSE = 6;
CAS_LICENSE_REQUEST = 7;
CAS_LICENSE = 8;
}
optional MessageType type = 1;
@@ -386,9 +410,9 @@ message SignedMessage {
// request for ChromeOS client devices operating in verified mode. Remote
// attestation challenge data is |msg| field above. Optional.
optional RemoteAttestation remote_attestation = 5;
repeated MetricData metric_data = 6;
}
message GroupKeys {
enum GroupLicenseVersion {
GROUP_LICENSE_VERSION_1 = 0;
@@ -534,6 +558,7 @@ message ClientIdentification {
HDCP_V2 = 2;
HDCP_V2_1 = 3;
HDCP_V2_2 = 4;
HDCP_V2_3 = 5;
HDCP_NO_DIGITAL_OUTPUT = 0xff;
}

View File

@@ -531,88 +531,4 @@ INSTANTIATE_TEST_CASE_P(
EntitledKeyVariant("KeyTooShort", kFakeKeyTooShort, false)),
PrintToStringParamName());
// TODO(jfore): The pssh has changed in ways that are not compatible with
//sublicenses. Restructure or remove sublicense support including this test.
TEST_F(SubLicenseTest, DISABLED_VerifySubSessionData) {
bool usage_information_support = true;
CryptoSession::HdcpCapability current_hdcp_version = HDCP_NO_DIGITAL_OUTPUT;
CryptoSession::HdcpCapability max_hdcp_version = HDCP_V2_1;
uint32_t crypto_session_api_version = 9;
EXPECT_CALL(*crypto_session_, IsOpen()).WillOnce(Return(true));
EXPECT_CALL(*crypto_session_, GenerateRequestId(NotNull()))
.WillOnce(DoAll(SetArgPointee<0>(kCryptoRequestId), Return(true)));
EXPECT_CALL(*crypto_session_, UsageInformationSupport(NotNull()))
.WillOnce(
DoAll(SetArgPointee<0>(usage_information_support), Return(true)));
EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull()))
.WillOnce(DoAll(SetArgPointee<0>(current_hdcp_version),
SetArgPointee<1>(max_hdcp_version), Return(true)));
EXPECT_CALL(*crypto_session_, GetApiVersion(NotNull()))
.WillOnce(
DoAll(SetArgPointee<0>(crypto_session_api_version), Return(true)));
EXPECT_CALL(*clock_, GetCurrentTime()).WillOnce(Return(kLicenseStartTime));
EXPECT_CALL(*crypto_session_, GenerateNonce(NotNull()))
.WillOnce(DoAll(SetArgPointee<0>(kNonce), Return(true)));
EXPECT_CALL(*crypto_session_, PrepareRequest(_, Eq(false), NotNull()))
.WillOnce(
DoAll(SetArgPointee<2>(kLicenseRequestSignature), Return(true)));
EXPECT_CALL(*crypto_session_, GetSupportedCertificateTypes(NotNull()));
// SubLicense session data calls.
// TODO(jfore): These calls are being invoked twice each. This should not
// present a functional problem, but we should investigate why.
EXPECT_CALL(*crypto_session_,
GenerateSubSessionNonce(kSubSessionKeyID1, NotNull(), NotNull()))
.WillRepeatedly(
DoAll(SetArgPointee<1>(true), SetArgPointee<2>(0), Return(true)));
EXPECT_CALL(*crypto_session_,
GenerateSubSessionNonce(kSubSessionKeyID2, NotNull(), NotNull()))
.WillRepeatedly(
DoAll(SetArgPointee<1>(true), SetArgPointee<2>(1), Return(true)));
EXPECT_CALL(*crypto_session_,
GenerateSubSessionNonce(kSubSessionKeyID3, NotNull(), NotNull()))
.WillRepeatedly(
DoAll(SetArgPointee<1>(true), SetArgPointee<2>(2), Return(true)));
CreateCdmLicense();
EXPECT_TRUE(cdm_license_->Init(
kToken, kClientTokenDrmCert, kEmptyString, true,
kDefaultServiceCertificate, crypto_session_, policy_engine_));
CdmAppParameterMap app_parameters;
CdmKeyMessage signed_request;
std::string server_url;
EXPECT_EQ(cdm_license_->PrepareKeyRequest(*init_data_, kLicenseTypeStreaming,
app_parameters, &signed_request,
&server_url),
KEY_MESSAGE);
EXPECT_TRUE(!signed_request.empty());
SignedMessage signed_message;
EXPECT_TRUE(signed_message.ParseFromString(signed_request));
LicenseRequest license_request;
EXPECT_TRUE(license_request.ParseFromString(signed_message.msg()));
EXPECT_EQ(3, license_request.sub_session_data().size());
for (int i = 0; i < license_request.sub_session_data().size(); ++i) {
const video_widevine::LicenseRequest_SubSessionData& sl =
license_request.sub_session_data(i);
EXPECT_EQ(static_cast<unsigned>(i), sl.nonce());
switch (i) {
case 0:
EXPECT_EQ(kSubSessionKeyID1, sl.sub_session_key_id());
EXPECT_EQ("AUDIO", sl.track_label());
break;
case 1:
EXPECT_EQ(kSubSessionKeyID2, sl.sub_session_key_id());
EXPECT_EQ("SD", sl.track_label());
break;
case 3:
EXPECT_EQ(kSubSessionKeyID3, sl.sub_session_key_id());
EXPECT_EQ("HD", sl.track_label());
break;
}
}
}
} // namespace wvcdm