Add a function named has_encrypted_client_id() check.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=231629247
This commit is contained in:
Fang Yu
2019-01-30 11:07:03 -08:00
parent f234dd036d
commit 1a4cad05a2
23 changed files with 572 additions and 166 deletions

View File

@@ -42,7 +42,6 @@ cc_library(
"//util/endian",
"//util/random:global_id",
"//common:aes_cbc_util",
"//common:certificate_type",
"//common:client_cert",
"//common:crypto_util",
"//common:device_status_list",
@@ -69,9 +68,9 @@ cc_library(
cc_library(
name = "sdk",
srcs = [
"generate_error_response.cc",
"key_control_block.cc",
"parse_content_id.cc",
"generate_error_response.cc",
],
hdrs = [
"generate_error_response.h",
@@ -81,32 +80,18 @@ cc_library(
],
deps = [
"//base",
"//strings",
"@abseil_repo//absl/strings",
"@abseil_repo//absl/synchronization",
"//external:openssl",
"//util/endian",
"//util/gtl:map_util",
"//common:client_cert",
"//common:crypto_util",
"//common:device_status_list",
"//common:error_space",
"//common:random_util",
"//common:rsa_key",
"//common:drm_root_certificate",
"//util:error_space",
"//common:drm_service_certificate",
"//common:signing_key_util",
"//common:error_space",
"//common:status",
"//common:wvm_token_handler",
"//sdk/external/common/wvpl:wvpl_types",
"//protos/public:client_identification_proto",
"//protos/public:device_certificate_status_proto",
"//protos/public:drm_certificate_proto",
"//protos/public:errors_proto",
"//protos/public:license_protocol_proto",
"//protos/public:license_server_sdk_proto",
"//protos/public:provisioned_device_info_proto",
"//protos/public:signed_drm_certificate_proto",
"//protos/public:widevine_pssh_proto",
],
)

View File

@@ -12,7 +12,6 @@
#include "absl/strings/escaping.h"
#include "common/drm_service_certificate.h"
#include "common/error_space.h"
#include "sdk/external/common/wvpl/wvpl_types.h"
#include "protos/public/errors.pb.h"
#include "protos/public/license_protocol.pb.h"

View File

@@ -34,6 +34,12 @@ void DevicesCanHandleOEMCryptoVersionInKCB(const std::string& system_ids) {
devices_can_handle_oemcrypto_version_.end());
}
void KeyIdsForFullDecryptPathTestingInKCB(const std::string& key_ids) {
for (absl::string_view key_id : absl::StrSplit(key_ids, ',')) {
keyids_for_full_decrypt_path_testing_.insert(std::string(key_id));
}
}
bool Generate(
const License::KeyContainer& key_container, uint32_t duration, uint32_t nonce,
const ClientIdentification::ClientCapabilities& client_capabilities,
@@ -136,6 +142,10 @@ bool Generate(
key_container.required_protection().disable_analog_output()) {
control_bits |= kKeyControlFlagsDisableAnalogOutput;
}
if (keyids_for_full_decrypt_path_testing_.find(key_container.id()) !=
keyids_for_full_decrypt_path_testing_.end()) {
control_bits |= kKeyControlFlagsAllowHashVerification;
}
break;
}
case License::KeyContainer::OPERATOR_SESSION: {

View File

@@ -46,6 +46,7 @@ const uint32_t kKeyControlFlagsHdcp_V2_2 = 0x00000800;
const uint32_t kKeyControlFlagsLocalDisplayOnly = 0x00001E00;
const uint32_t kKeyControlFlagsDisableAnalogOutput = 0x00200000;
const uint32_t kKeyControlFlagsSrmVersionRequired = 0x00400000;
const uint32_t kKeyControlFlagsAllowHashVerification = 0x01000000;
// Generate the key control block structuure. |key_control_block| must not be
// null and is used to hold the key control data. Returns true if successful,
@@ -62,10 +63,17 @@ bool Generate(
// the Key Control Block. Otherwise, only 'kctl' or 'kc09' is returned in KCB.
void DevicesCanHandleOEMCryptoVersionInKCB(const std::string& system_ids);
// Specify a comma separated list of key Ids that can support 'full decrypt path
// testing' as specified in go/wvdelta15.
void KeyIdsForFullDecryptPathTestingInKCB(const std::string& key_ids);
// Contains the list of system_id values that can support reflecting OEMCrypto
// version in KCB.
static std::vector<uint32_t> devices_can_handle_oemcrypto_version_;
// KeyIds that are permitted for full decrypt path testing.
static std::set<std::string> keyids_for_full_decrypt_path_testing_;
} // namespace key_control_block
} // namespace widevine
#endif // LICENSE_SERVER_SDK_INTERNAL_KEY_CONTROL_BLOCK_H__

View File

@@ -798,5 +798,39 @@ TEST(KeyControlBlockTest, test_OEMCrypto_Version) {
}
}
TEST(KeyControlBlockTest, test_allow_hash_verification_bit) {
KeyIdsForFullDecryptPathTestingInKCB("TEST_KEY_ID");
uint32_t duration = 0;
uint32_t nonce = 0;
bool has_provider_session_token = true;
uint32_t system_id = 0;
ClientIdentification::ClientCapabilities client_capabilities;
client_capabilities.set_session_token(false);
SessionInit session_init;
License::KeyContainer key_container;
key_container.set_type(License::KeyContainer::CONTENT);
key_container.set_id("TEST_KEY_ID");
// KCB when KeyID for 'full decrypt path testing' matches.
const std::string expected_kcb("6b63746c000000000000000001000008");
ASSERT_TRUE(key_control_block::Generate(
key_container, duration, nonce, client_capabilities,
has_provider_session_token, &session_init, STREAMING, system_id,
key_container.mutable_key_control()->mutable_key_control_block()));
EXPECT_EQ(expected_kcb, absl::BytesToHexString(
key_container.key_control().key_control_block()));
key_container.set_id("KEY_ID_FDP_UNSET");
ASSERT_TRUE(key_control_block::Generate(
key_container, duration, nonce, client_capabilities,
has_provider_session_token, &session_init, STREAMING, system_id,
key_container.mutable_key_control()->mutable_key_control_block()));
EXPECT_NE(expected_kcb, absl::BytesToHexString(
key_container.key_control().key_control_block()));
EXPECT_EQ(
"6b63746c000000000000000000000008",
absl::BytesToHexString(key_container.key_control().key_control_block()));
}
} // namespace key_control_block
} // namespace widevine

View File

@@ -26,8 +26,8 @@ namespace widevine {
namespace {
const uint8_t kWidevineSystemId[] = {0xed, 0xef, 0x8b, 0xa9, 0x79, 0xd6,
0x4a, 0xce, 0xa3, 0xc8, 0x27, 0xdc,
0xd5, 0x1d, 0x21, 0xed};
0x4a, 0xce, 0xa3, 0xc8, 0x27, 0xdc,
0xd5, 0x1d, 0x21, 0xed};
void AddKeyIdIfNotFound(const std::string& key_id,
ContentInfo::ContentInfoEntry* entry) {
@@ -64,9 +64,10 @@ Status ParseCencId(const LicenseRequest::ContentIdentification& content_id,
ContentInfo* content_info) {
content_info->set_init_data_type(
LicenseRequest::ContentIdentification::InitData::CENC);
for (int idx = 0; idx < content_id.cenc_id_deprecated().pssh_size(); ++idx) {
for (int idx = 0; idx < content_id.widevine_pssh_data().pssh_data_size();
++idx) {
Status status =
AddWidevinePsshInfo(content_id.cenc_id_deprecated().pssh(idx),
AddWidevinePsshInfo(content_id.widevine_pssh_data().pssh_data(idx),
content_info->add_content_info_entry());
if (!status.ok()) return status;
}
@@ -214,11 +215,10 @@ Status ParseContentId(const LicenseRequest::ContentIdentification& content_id,
content_info->Clear();
switch (content_id.content_id_variant_case()) {
case LicenseRequest_ContentIdentification::kCencIdDeprecated:
case LicenseRequest_ContentIdentification::kWidevinePsshData:
return ParseCencId(content_id, content_info);
case LicenseRequest_ContentIdentification::kWebmIdDeprecated:
return AddWebmKeyId(content_id.webm_id_deprecated().header(),
content_info);
case LicenseRequest_ContentIdentification::kWebmKeyId:
return AddWebmKeyId(content_id.webm_key_id().header(), content_info);
case LicenseRequest_ContentIdentification::kInitData:
return ParseInitData(content_id, content_info);
default:

View File

@@ -93,7 +93,7 @@ const uint8_t kNonPsshBox[] = {
void MakeDeprecatedWebmContentId(
const std::string& key_id, LicenseRequest::ContentIdentification* content_id) {
content_id->Clear();
content_id->mutable_webm_id_deprecated()->set_header(key_id);
content_id->mutable_webm_key_id()->set_header(key_id);
}
void MakeInitDataWebmContentId(
@@ -120,7 +120,7 @@ void MakeDeprecatedCencContentId(
const std::string& pssh_data,
LicenseRequest::ContentIdentification* content_id) {
content_id->Clear();
*content_id->mutable_cenc_id_deprecated()->add_pssh() = pssh_data;
*content_id->mutable_widevine_pssh_data()->add_pssh_data() = pssh_data;
}
void MakeInitDataCencContentId(

View File

@@ -8,9 +8,9 @@
#include "license_server_sdk/internal/session_impl.h"
#include <stddef.h>
#include <string.h>
#include <time.h>
#include <cstddef>
#include <cstring>
#include <ctime>
#include <list>
#include <memory>
#include <string>
@@ -440,12 +440,12 @@ Status SessionImpl::GetRequestId(std::string* request_id) const {
*request_id = content_id.init_data().request_id();
return OkStatus();
}
if (content_id.has_cenc_id_deprecated()) {
*request_id = content_id.cenc_id_deprecated().request_id();
if (content_id.has_widevine_pssh_data()) {
*request_id = content_id.widevine_pssh_data().request_id();
return OkStatus();
}
if (content_id.has_webm_id_deprecated()) {
*request_id = content_id.webm_id_deprecated().request_id();
if (content_id.has_webm_key_id()) {
*request_id = content_id.webm_key_id().request_id();
return OkStatus();
}
return Status(error_space, INVALID_CONTENT_ID_TYPE,
@@ -464,12 +464,12 @@ Status SessionImpl::GetLicenseType(LicenseType* license_type) const {
*license_type = content_id.init_data().license_type();
return OkStatus();
}
if (content_id.has_cenc_id_deprecated()) {
*license_type = content_id.cenc_id_deprecated().license_type();
if (content_id.has_widevine_pssh_data()) {
*license_type = content_id.widevine_pssh_data().license_type();
return OkStatus();
}
if (content_id.has_webm_id_deprecated()) {
*license_type = content_id.webm_id_deprecated().license_type();
if (content_id.has_webm_key_id()) {
*license_type = content_id.webm_key_id().license_type();
return OkStatus();
}
if (content_id.has_existing_license()) {

View File

@@ -36,7 +36,7 @@ class SessionUsage;
const uint32_t kMajorVersion = 4;
const uint32_t kMinorVersion = 5;
const uint32_t kRelease = 1;
const uint32_t kRelease = 2;
const uint32_t kMasterSigningKeySizeBytes = 16;
const uint32_t kSigningKeySizeBytes = 64;

View File

@@ -408,7 +408,7 @@ const char kGoodVmpData[] =
"c68c3b167b257c4a64afb2fbe7eb66544d92480ec595d1c025b335b1fba7a2a49c884900"
"c2fd7a4d5a9d820a4a4fd98624e02938195bf312d05b";
class MockCDPush {};
class MockSrm {};
} // anonymous namespace
class MockSessionImpl : public SessionImpl {
@@ -667,19 +667,19 @@ class SessionTest : public ::testing::Test {
client_capabilities;
if (init_data_type ==
LicenseRequest::ContentIdentification::InitData::WEBM) {
LicenseRequest::ContentIdentification::WebmDeprecated* webm_id =
request.mutable_content_id()->mutable_webm_id_deprecated();
LicenseRequest::ContentIdentification::WebmKeyId* webm_id =
request.mutable_content_id()->mutable_webm_key_id();
webm_id->set_header("0123456789ABCDEF");
webm_id->set_license_type(license_type);
webm_id->set_request_id("myCoolRequest, Dude!");
} else {
LicenseRequest::ContentIdentification::CencDeprecated* cenc_id =
request.mutable_content_id()->mutable_cenc_id_deprecated();
LicenseRequest::ContentIdentification::WidevinePsshData* cenc_id =
request.mutable_content_id()->mutable_widevine_pssh_data();
widevine::WidevinePsshData wv_pssh;
wv_pssh.set_protection_scheme(kProtectionScheme);
std::string pssh_string;
wv_pssh.SerializeToString(&pssh_string);
cenc_id->add_pssh(pssh_string);
cenc_id->add_pssh_data(pssh_string);
cenc_id->set_license_type(license_type);
cenc_id->set_request_id("myCool-CENC-Request, Dude!");
}
@@ -731,12 +731,11 @@ class SessionTest : public ::testing::Test {
*request.mutable_client_id()->mutable_client_capabilities() =
client_capabilities;
request.mutable_content_id()->mutable_webm_id_deprecated()->set_header(
request.mutable_content_id()->mutable_webm_key_id()->set_header(
"0123456789ABCDEF");
request.mutable_content_id()
->mutable_webm_id_deprecated()
->set_license_type(STREAMING);
request.mutable_content_id()->mutable_webm_id_deprecated()->set_request_id(
request.mutable_content_id()->mutable_webm_key_id()->set_license_type(
STREAMING);
request.mutable_content_id()->mutable_webm_key_id()->set_request_id(
"myCoolRequest, Dude!");
if (request_type != LicenseRequest::NEW) {
request.mutable_content_id()
@@ -777,12 +776,11 @@ class SessionTest : public ::testing::Test {
request.mutable_client_id()->set_token(GenerateSignedDrmCertificate(
kValidSystemId, kValidSerialNumber, false));
request.mutable_content_id()->mutable_webm_id_deprecated()->set_header(
request.mutable_content_id()->mutable_webm_key_id()->set_header(
"0123456789ABCDEF");
request.mutable_content_id()
->mutable_webm_id_deprecated()
->set_license_type(STREAMING);
request.mutable_content_id()->mutable_webm_id_deprecated()->set_request_id(
request.mutable_content_id()->mutable_webm_key_id()->set_license_type(
STREAMING);
request.mutable_content_id()->mutable_webm_key_id()->set_request_id(
"myCoolRequest, Dude!");
request.set_type(LicenseRequest::NEW);
request.set_request_time(time(nullptr));
@@ -804,7 +802,7 @@ class SessionTest : public ::testing::Test {
const ClientIdentification::ClientCapabilities& client_capabilities,
const LicenseRequest::ContentIdentification::InitData::InitDataType
init_data_type,
MockCDPush* cdpush, License* license) {
MockSrm* srm, License* license) {
// Parse LicenseRequest from request_msg for comparison
// the one returned from SessionImpl::Create().
SignedMessage signed_request;
@@ -1017,7 +1015,7 @@ class SessionTest : public ::testing::Test {
init_data_type) {
ValidateBasicRequestResponse(request_msg, client_capabilities,
init_data_type,
/* cdpush= */ nullptr,
/* srm= */ nullptr,
/* license= */ nullptr);
}
@@ -1720,11 +1718,11 @@ TEST_F(SessionTest, BasicRequestDrmCertificateResponseEmptyToken) {
request.mutable_client_id()->set_type(
ClientIdentification::DRM_DEVICE_CERTIFICATE);
request.mutable_client_id()->set_token("invalid");
request.mutable_content_id()->mutable_webm_id_deprecated()->set_header(
request.mutable_content_id()->mutable_webm_key_id()->set_header(
"0123456789ABCDEF");
request.mutable_content_id()->mutable_webm_id_deprecated()->set_license_type(
request.mutable_content_id()->mutable_webm_key_id()->set_license_type(
STREAMING);
request.mutable_content_id()->mutable_webm_id_deprecated()->set_request_id(
request.mutable_content_id()->mutable_webm_key_id()->set_request_id(
"myInvalidRequest, Dude!");
request.set_type(LicenseRequest::NEW);
request.set_request_time(time(nullptr));
@@ -2155,8 +2153,8 @@ TEST_P(SessionTestRenewal, LicenseRenewalWithSerialNumber) {
kValidSessionUsage, false);
}
INSTANTIATE_TEST_CASE_P(SystemIdVariations, SessionTestRenewal,
::testing::Bool());
INSTANTIATE_TEST_SUITE_P(SystemIdVariations, SessionTestRenewal,
::testing::Bool());
TEST_F(SessionTest, InvalidRenewalKeySigningKey_2_0) {
SessionImpl* session_ptr = nullptr;
@@ -2550,11 +2548,11 @@ TEST_F(SessionTest, EncryptedClientIdentification) {
GenerateSignedDrmCertificate(kValidSystemId, kValidSerialNumber, false));
EncryptClientIdentification(client_id, serial_number, provider_id,
request.mutable_encrypted_client_id());
request.mutable_content_id()->mutable_webm_id_deprecated()->set_header(
request.mutable_content_id()->mutable_webm_key_id()->set_header(
"0123456789ABCDEF");
request.mutable_content_id()->mutable_webm_id_deprecated()->set_license_type(
request.mutable_content_id()->mutable_webm_key_id()->set_license_type(
STREAMING);
request.mutable_content_id()->mutable_webm_id_deprecated()->set_request_id(
request.mutable_content_id()->mutable_webm_key_id()->set_request_id(
"request id");
request.set_type(LicenseRequest::NEW);
request.set_request_time(54322);
@@ -3073,10 +3071,10 @@ TEST_F(SessionTest, GenerateDeviceStatusListRequest) {
}
INSTANTIATE_TEST_CASE_P(SessionVmpTests, SessionVmpTest,
::testing::Values(PLATFORM_NO_VERIFICATION,
PLATFORM_UNVERIFIED,
PLATFORM_TAMPERED,
PLATFORM_SOFTWARE_VERIFIED));
INSTANTIATE_TEST_SUITE_P(SessionVmpTests, SessionVmpTest,
::testing::Values(PLATFORM_NO_VERIFICATION,
PLATFORM_UNVERIFIED,
PLATFORM_TAMPERED,
PLATFORM_SOFTWARE_VERIFIED));
} // namespace widevine