Minor change

This commit is contained in:
Lu Chen
2020-02-25 13:16:44 -08:00
parent d71d62d272
commit ed5a1d5db1
18 changed files with 358 additions and 103 deletions

View File

@@ -69,6 +69,7 @@ cc_library(
":client_id_util",
"@abseil_repo//absl/synchronization",
"//protos/public:client_identification_cc_proto",
"//protos/public:device_common_cc_proto",
"//protos/public:provisioned_device_info_cc_proto",
"//protos/public:security_profile_cc_proto",
],
@@ -83,6 +84,8 @@ cc_test(
"//base",
"//external:protobuf",
"//testing:gunit_main",
"@abseil_repo//absl/memory",
"//protos/public:device_common_cc_proto",
"//protos/public:security_profile_cc_proto",
],
)
@@ -196,6 +199,7 @@ cc_library(
hdrs = ["device_info_util.h"],
deps = [
"@abseil_repo//absl/strings",
"//protos/public:device_common_cc_proto",
"//protos/public:provisioned_device_info_cc_proto",
],
)

View File

@@ -21,6 +21,7 @@
#include "common/signing_key_util.h"
#include "protos/public/drm_certificate.pb.h"
#include "protos/public/errors.pb.h"
#include "protos/public/license_protocol.pb.h"
#include "protos/public/signed_drm_certificate.pb.h"
namespace widevine {
@@ -80,6 +81,10 @@ class ClientCertAlgorithmRSA : public ClientCertAlgorithm {
return wrapped_session_key_;
}
SignedMessage::SessionKeyType session_key_type() const override {
return SignedMessage::WRAPPED_AES_KEY;
}
private:
std::unique_ptr<RsaPublicKey> rsa_public_key_;
std::string session_key_;
@@ -159,6 +164,10 @@ class ClientCertAlgorithmECC : public ClientCertAlgorithm {
return ephemeral_public_key_;
}
SignedMessage::SessionKeyType session_key_type() const override {
return SignedMessage::EPHERMERAL_ECC_PUBLIC_KEY;
}
private:
std::unique_ptr<ECPublicKey> client_ecc_public_key_;
std::string ephemeral_public_key_;

View File

@@ -40,6 +40,11 @@ class ClientCertAlgorithm {
// field of a license response. This key may be either an encrypted aes key,
// or the bytes of an ephemeral public key.
virtual const std::string& wrapped_session_key() const = 0;
// Returns information on the type session key used in this format. This value
// is intended to be included in the SignedMessage::session_key_type field of
// a license response.
virtual SignedMessage::SessionKeyType session_key_type() const = 0;
};
class CertificateClientCert : public ClientCert {
@@ -62,6 +67,9 @@ class CertificateClientCert : public ClientCert {
return algorithm_->wrapped_session_key();
}
const std::string& key() const override { return algorithm_->session_key(); }
SignedMessage::SessionKeyType key_type() const override {
return algorithm_->session_key_type();
}
const std::string& serial_number() const override {
return device_cert_.serial_number();
}

View File

@@ -60,6 +60,7 @@ class ClientCert {
virtual const std::string& encrypted_key() const = 0;
virtual const std::string& key() const = 0;
virtual SignedMessage::SessionKeyType key_type() const = 0;
virtual const std::string& serial_number() const = 0;
virtual const std::string& service_id() const = 0;
virtual const std::string& signing_key() const = 0;

View File

@@ -20,6 +20,9 @@
namespace widevine {
const char kModDrmMake[] = "company_name";
const char kModDrmModel[] = "model_name";
void AddClientInfo(ClientIdentification* client_id, absl::string_view name,
absl::string_view value) {
ClientIdentification_NameValue* nv = client_id->add_client_info();

View File

@@ -19,6 +19,9 @@
namespace widevine {
extern const char kModDrmMake[];
extern const char kModDrmModel[];
// Append the given name/value pair to client_id->client_info(). Does not
// check for duplicates.
void AddClientInfo(ClientIdentification* client_id, absl::string_view name,

View File

@@ -28,13 +28,17 @@ bool GetCoreProvisioningResponse(
const std::string& serialized_provisioning_response,
const std::string& request_core_message,
std::string* response_core_message) {
if (request_core_message.empty()) {
return false;
}
oemcrypto_core_message::ODK_ProvisioningRequest odk_provisioning_request;
CoreProvisioningRequestFromMessage(request_core_message,
&odk_provisioning_request);
CreateCoreProvisioningResponseFromProto(serialized_provisioning_response,
odk_provisioning_request,
response_core_message);
return true;
if (CoreProvisioningRequestFromMessage(request_core_message,
&odk_provisioning_request)) {
return CreateCoreProvisioningResponseFromProto(
serialized_provisioning_response, odk_provisioning_request,
response_core_message);
}
return false;
}
bool GetCoreRenewalOrReleaseLicenseResponse(

View File

@@ -10,6 +10,7 @@
#include "common/device_info_util.h"
#include "absl/strings/ascii.h"
#include "protos/public/device_common.pb.h"
namespace widevine {
bool IsMatchedMakeModel(const std::string& expected_make,
@@ -29,10 +30,10 @@ bool VerifyMakeModel(const ProvisionedDeviceInfo& device_info,
make_from_client, model_from_client)) {
return true;
}
for (ProvisionedDeviceInfo::ModelInfo product_info :
device_info.model_info()) {
if (IsMatchedMakeModel(product_info.manufacturer(), product_info.model(),
make_from_client, model_from_client)) {
for (DeviceModel product_info : device_info.model_info()) {
if (IsMatchedMakeModel(product_info.manufacturer(),
product_info.model_name(), make_from_client,
model_from_client)) {
return true;
}
}

View File

@@ -88,6 +88,7 @@ class MockClientCert : public ClientCert {
ProtocolVersion protocol_version));
MOCK_CONST_METHOD0(serial_number, const std::string &());
MOCK_CONST_METHOD0(key, const std::string &());
MOCK_CONST_METHOD0(key_type, SignedMessage::SessionKeyType());
MOCK_CONST_METHOD0(service_id, const std::string &());
MOCK_CONST_METHOD0(encrypted_key, const std::string &());
MOCK_CONST_METHOD0(signing_key, const std::string &());

View File

@@ -31,6 +31,9 @@ class KeyboxClientCert : public ClientCert {
const std::string& encrypted_key() const override { return unimplemented_; }
const std::string& key() const override { return device_key_; }
SignedMessage::SessionKeyType key_type() const override {
return SignedMessage::WRAPPED_AES_KEY;
}
const std::string& serial_number() const override { return serial_number_; }
const std::string& service_id() const override { return unimplemented_; }
const std::string& signing_key() const override { return signing_key_; }

View File

@@ -13,14 +13,15 @@
#include "common/client_id_util.h"
#include "protos/public/client_identification.pb.h"
#include "protos/public/device_common.pb.h"
#include "protos/public/provisioned_device_info.pb.h"
#include "protos/public/security_profile.pb.h"
namespace widevine {
using ClientCapabilities = ClientIdentification::ClientCapabilities;
const char kModDrmMake[] = "company_name";
const char kModDrmModel[] = "model_name";
SecurityProfileList::SecurityProfileList(const std::string& profile_namespace)
: profile_namespace_(profile_namespace) {}
int SecurityProfileList::Init() { return AddDefaultProfiles(); }
@@ -30,28 +31,28 @@ int SecurityProfileList::AddDefaultProfiles() {
const bool make_model_not_verified = false;
SecurityProfile profile;
PopulateProfile(SecurityProfile::SECURITY_PROFILE_LEVEL_1,
PopulateProfile(SecurityProfile::SECURITY_PROFILE_LEVEL_1, "WVSP1",
ClientCapabilities::HDCP_NONE,
ClientCapabilities::ANALOG_OUTPUT_UNKNOWN, oemcrypto_8,
make_model_not_verified, ProvisionedDeviceInfo::LEVEL_3,
kResourceTierLow, &profile);
InsertProfile(profile);
PopulateProfile(SecurityProfile::SECURITY_PROFILE_LEVEL_2,
PopulateProfile(SecurityProfile::SECURITY_PROFILE_LEVEL_2, "WVSP2",
ClientCapabilities::HDCP_NONE,
ClientCapabilities::ANALOG_OUTPUT_SUPPORTS_CGMS_A,
oemcrypto_12, make_model_not_verified,
ProvisionedDeviceInfo::LEVEL_2, kResourceTierLow, &profile);
InsertProfile(profile);
PopulateProfile(SecurityProfile::SECURITY_PROFILE_LEVEL_3,
PopulateProfile(SecurityProfile::SECURITY_PROFILE_LEVEL_3, "WVSP3",
ClientCapabilities::HDCP_V1,
ClientCapabilities::ANALOG_OUTPUT_SUPPORTS_CGMS_A,
oemcrypto_12, make_model_not_verified,
ProvisionedDeviceInfo::LEVEL_1, kResourceTierMed, &profile);
InsertProfile(profile);
PopulateProfile(SecurityProfile::SECURITY_PROFILE_LEVEL_4,
PopulateProfile(SecurityProfile::SECURITY_PROFILE_LEVEL_4, "WVSP4",
ClientCapabilities::HDCP_V2_2,
ClientCapabilities::ANALOG_OUTPUT_SUPPORTS_CGMS_A,
oemcrypto_12, make_model_not_verified,
@@ -61,31 +62,15 @@ int SecurityProfileList::AddDefaultProfiles() {
return security_profiles_.size();
}
SecurityProfile::Level SecurityProfileList::GetProfileLevel(
SecurityProfile::Level SecurityProfileList::GetBestProfileLevel(
const ClientIdentification& client_id,
const ProvisionedDeviceInfo& device_info,
SecurityProfile::DrmInfo* drm_info) const {
// Iterate through each SP starting from the strictest first.
absl::ReaderMutexLock lock(&mutex_);
// Profile list is assumed to be sorted.
for (auto& profile : security_profiles_) {
if (profile.min_security_requirements().security_level() <
device_info.security_level()) {
continue;
}
if (profile.min_security_requirements().oemcrypto_version() >
client_id.client_capabilities().oem_crypto_api_version()) {
continue;
}
if (profile.min_output_requirements().hdcp_version() >
client_id.client_capabilities().max_hdcp_version()) {
continue;
}
if (profile.min_output_requirements().analog_output_capabilities() >
client_id.client_capabilities().analog_output_capabilities()) {
continue;
}
if (profile.min_security_requirements().resource_rating_tier() >
client_id.client_capabilities().resource_rating_tier()) {
if (!IsProfileAllowed(profile, client_id, device_info)) {
continue;
}
if (drm_info != nullptr) {
@@ -96,6 +81,42 @@ SecurityProfile::Level SecurityProfileList::GetProfileLevel(
return SecurityProfile::SECURITY_PROFILE_LEVEL_UNDEFINED;
}
int SecurityProfileList::GetAllowedProfilesFromList(
const std::vector<std::string>& profiles_to_check,
const ClientIdentification& client_id,
const ProvisionedDeviceInfo& device_info,
std::vector<std::string>* profiles_to_allow) const {
if (profiles_to_allow == nullptr) {
return 0;
}
absl::ReaderMutexLock lock(&mutex_);
for (auto& profile_name : profiles_to_check) {
SecurityProfile profile;
if (GetProfileByName(profile_name, &profile)) {
if (IsProfileAllowed(profile, client_id, device_info)) {
profiles_to_allow->push_back(profile.name());
}
}
}
return profiles_to_allow->size();
}
int SecurityProfileList::GetAllowedProfiles(
const ClientIdentification& client_id,
const ProvisionedDeviceInfo& device_info,
std::vector<std::string>* profiles_to_allow) const {
if (profiles_to_allow == nullptr) {
return 0;
}
absl::ReaderMutexLock lock(&mutex_);
for (auto& profile : security_profiles_) {
if (IsProfileAllowed(profile, client_id, device_info)) {
profiles_to_allow->push_back(profile.name());
}
}
return profiles_to_allow->size();
}
bool SecurityProfileList::GetDrmInfo(const ClientIdentification& client_id,
const ProvisionedDeviceInfo& device_info,
SecurityProfile::DrmInfo* drm_info) const {
@@ -115,14 +136,14 @@ bool SecurityProfileList::GetDrmInfo(const ClientIdentification& client_id,
drm_info->mutable_security()->set_request_model_info_status(false);
drm_info->mutable_request_model_info()->set_manufacturer(
GetClientInfo(client_id, kModDrmMake));
drm_info->mutable_request_model_info()->set_model(
drm_info->mutable_request_model_info()->set_model_name(
GetClientInfo(client_id, kModDrmModel));
drm_info->set_system_id(device_info.system_id());
return true;
}
bool SecurityProfileList::PopulateProfile(
const SecurityProfile::Level profile_level,
const SecurityProfile::Level profile_level, const std::string& profile_name,
const ClientCapabilities::HdcpVersion min_hdcp_version,
const ClientCapabilities::AnalogOutputCapabilities
analog_output_capabilities,
@@ -134,6 +155,7 @@ bool SecurityProfileList::PopulateProfile(
return false;
}
profile_to_create->set_level(profile_level);
profile_to_create->set_name(profile_name);
profile_to_create->mutable_min_output_requirements()->set_hdcp_version(
min_hdcp_version);
profile_to_create->mutable_min_output_requirements()
@@ -149,8 +171,8 @@ bool SecurityProfileList::PopulateProfile(
return true;
}
bool SecurityProfileList::GetProfile(SecurityProfile::Level level,
SecurityProfile* security_profile) {
bool SecurityProfileList::GetProfileByLevel(
SecurityProfile::Level level, SecurityProfile* security_profile) const {
absl::ReaderMutexLock lock(&mutex_);
for (auto& profile : security_profiles_) {
if (profile.level() == level) {
@@ -163,10 +185,27 @@ bool SecurityProfileList::GetProfile(SecurityProfile::Level level,
return false;
}
bool SecurityProfileList::GetProfileByName(
const std::string& name, SecurityProfile* security_profile) const {
absl::ReaderMutexLock lock(&mutex_);
for (auto& profile : security_profiles_) {
if (profile.name() == name) {
if (security_profile != nullptr) {
*security_profile = profile;
}
return true;
}
}
return false;
}
bool SecurityProfileList::InsertProfile(
const SecurityProfile& profile_to_insert) {
// Check if profile already exist.
if (GetProfile(profile_to_insert.level(), nullptr)) {
if (GetProfileByLevel(profile_to_insert.level(), nullptr)) {
return false;
}
if (GetProfileByName(profile_to_insert.name(), nullptr)) {
return false;
}
absl::WriterMutexLock lock(&mutex_);
@@ -182,4 +221,30 @@ bool SecurityProfileList::CompareProfileLevel(const SecurityProfile& p1,
return (p1.level() > p2.level());
}
bool SecurityProfileList::IsProfileAllowed(
const SecurityProfile& profile, const ClientIdentification& client_id,
const ProvisionedDeviceInfo& device_info) const {
if (profile.min_security_requirements().security_level() <
device_info.security_level()) {
return false;
}
if (profile.min_security_requirements().oemcrypto_version() >
client_id.client_capabilities().oem_crypto_api_version()) {
return false;
}
if (profile.min_output_requirements().hdcp_version() >
client_id.client_capabilities().max_hdcp_version()) {
return false;
}
if (profile.min_output_requirements().analog_output_capabilities() >
client_id.client_capabilities().analog_output_capabilities()) {
return false;
}
if (profile.min_security_requirements().resource_rating_tier() >
client_id.client_capabilities().resource_rating_tier()) {
return false;
}
return true;
}
} // namespace widevine

View File

@@ -32,7 +32,7 @@ const uint32_t kResourceTierHigh = 3;
class SecurityProfileList {
public:
SecurityProfileList() {}
explicit SecurityProfileList(const std::string& profile_namespace);
~SecurityProfileList() {}
// Initialize the security profile list. The list is initially empty, this
@@ -44,24 +44,11 @@ class SecurityProfileList {
// if successfully inserted, false if unable to insert.
bool InsertProfile(const SecurityProfile& profile_to_insert);
// Return the highest security level based on the device capabilities.
// If |drm_info| is not null, |drm_info| is populated with the device data.
SecurityProfile::Level GetProfileLevel(
const ClientIdentification& client_id,
const ProvisionedDeviceInfo& device_info,
SecurityProfile::DrmInfo* drm_info) const;
// Return the device security capabilities. |drm_info| is populated with
// data from |client_id| and |device_info|. |drm_info| must not be null and
// is owned by the caller.
bool GetDrmInfo(const ClientIdentification& client_id,
const ProvisionedDeviceInfo& device_info,
SecurityProfile::DrmInfo* drm_info) const;
// Populate |profile_to_create| with the specified output protections and
// security parameters. All input parameters are used hence should be set.
bool PopulateProfile(
const SecurityProfile::Level profile_level,
const std::string& profile_name,
const ClientCapabilities::HdcpVersion min_hdcp_version,
const ClientCapabilities::AnalogOutputCapabilities
analog_output_capabilities,
@@ -70,11 +57,45 @@ class SecurityProfileList {
const uint32_t resource_rating_tier,
SecurityProfile* profile_to_create) const;
// Return the highest security level based on the device capabilities.
// If |drm_info| is not null, |drm_info| is populated with the device data.
SecurityProfile::Level GetBestProfileLevel(
const ClientIdentification& client_id,
const ProvisionedDeviceInfo& device_info,
SecurityProfile::DrmInfo* drm_info) const;
// Populates |profiles_to_allow| with a list of profiles that meet the
// requirements for the this device. The number of profiles is returned.
int GetAllowedProfiles(const ClientIdentification& client_id,
const ProvisionedDeviceInfo& device_info,
std::vector<std::string>* profiles_to_allow) const;
// Populates |profiles_allow| with a list of profiles from the specified
// |profiles_to_check| list that meet the requirements for the this device.
// The number of profiles is returned.
int GetAllowedProfilesFromList(
const std::vector<std::string>& profiles_to_check,
const ClientIdentification& client_id,
const ProvisionedDeviceInfo& device_info,
std::vector<std::string>* profiles_to_allow) const;
// Return true if a profile exist matching the specified |level|.
// |security_profile| is owned by the caller and is populated if a profile
// exist.
bool GetProfile(SecurityProfile::Level level,
SecurityProfile* security_profile);
bool GetProfileByLevel(SecurityProfile::Level level,
SecurityProfile* security_profile) const;
// Return true if a profile exist matching the specified |name|.
// |security_profile| is owned by the caller and is populated if a profile
// exist.
bool GetProfileByName(const std::string& name,
SecurityProfile* security_profile) const;
// Return the device security capabilities. |drm_info| is populated with
// data from |client_id| and |device_info|. |drm_info| must not be null and
// is owned by the caller.
bool GetDrmInfo(const ClientIdentification& client_id,
const ProvisionedDeviceInfo& device_info,
SecurityProfile::DrmInfo* drm_info) const;
private:
// Initialize the list with Widevine default profiles. The size of the
@@ -84,12 +105,14 @@ class SecurityProfileList {
static bool CompareProfileLevel(const SecurityProfile& p1,
const SecurityProfile& p2);
bool IsProfileAllowed(const SecurityProfile& profile,
const ClientIdentification& client_id,
const ProvisionedDeviceInfo& device_info) const;
mutable absl::Mutex mutex_;
// Widevine security profiles
// Security profiles
std::string profile_namespace_;
std::vector<SecurityProfile> security_profiles_ ABSL_GUARDED_BY(mutex_);
// Custom security profiles
std::map<std::string, SecurityProfile> custom_security_profiles_
ABSL_GUARDED_BY(mutex_);
};
} // namespace widevine

View File

@@ -12,6 +12,8 @@
#include "google/protobuf/util/message_differencer.h"
#include "testing/gmock.h"
#include "testing/gunit.h"
#include "absl/memory/memory.h"
#include "protos/public/device_common.pb.h"
#include "protos/public/security_profile.pb.h"
namespace widevine {
@@ -47,6 +49,8 @@ class SecurityProfileListTest : public ::testing::Test {
->set_resource_rating_tier(kResourceTierHigh);
test_profile_1_.mutable_min_security_requirements()
->set_request_model_info_status(make_model_not_verified);
std::string profile_namespace = "widevine_test";
profile_list_ = absl::make_unique<SecurityProfileList>(profile_namespace);
ClientIdentification_NameValue *nv = client_id_.add_client_info();
nv->set_name(kMakeName);
@@ -65,7 +69,7 @@ class SecurityProfileListTest : public ::testing::Test {
device_info_.set_system_id(kSystemId);
}
SecurityProfile test_profile_1_;
SecurityProfileList profile_list_;
std::unique_ptr<SecurityProfileList> profile_list_;
ClientIdentification client_id_;
ProvisionedDeviceInfo device_info_;
};
@@ -73,19 +77,24 @@ class SecurityProfileListTest : public ::testing::Test {
TEST_F(SecurityProfileListTest, InsertProfile) {
// This test will not initialize the SecurityProfileList, hence it's empty.
// Insert test profile 1 into the list.
EXPECT_TRUE(profile_list_.InsertProfile(test_profile_1_));
// Should not allow insertion of an alreadfy existing level.
EXPECT_FALSE(profile_list_.InsertProfile(test_profile_1_));
EXPECT_TRUE(profile_list_->InsertProfile(test_profile_1_));
// Should not allow insertion of an already existing level.
EXPECT_FALSE(profile_list_->InsertProfile(test_profile_1_));
SecurityProfile profile;
ASSERT_EQ(SecurityProfile::SECURITY_PROFILE_LEVEL_1,
profile_list_.GetProfile(test_profile_1_.level(), &profile));
// Should not allow insertion of an already existing name.
// Make sure the level is not the same as already inserted level_1.
profile.set_level(SecurityProfile::SECURITY_PROFILE_LEVEL_2);
profile.set_name(test_profile_1_.name());
EXPECT_FALSE(profile_list_->InsertProfile(test_profile_1_));
ASSERT_TRUE(profile_list_->GetProfileByLevel(
SecurityProfile::SECURITY_PROFILE_LEVEL_1, &profile));
EXPECT_TRUE(
google::protobuf::util::MessageDifferencer::Equals(test_profile_1_, profile));
}
TEST_F(SecurityProfileListTest, GetDrmInfo) {
SecurityProfile::DrmInfo drm_info;
ASSERT_TRUE(profile_list_.GetDrmInfo(client_id_, device_info_, &drm_info));
ASSERT_TRUE(profile_list_->GetDrmInfo(client_id_, device_info_, &drm_info));
EXPECT_EQ(client_id_.client_capabilities().max_hdcp_version(),
drm_info.output().hdcp_version());
EXPECT_EQ(client_id_.client_capabilities().analog_output_capabilities(),
@@ -102,12 +111,12 @@ TEST_F(SecurityProfileListTest, GetDrmInfo) {
// make_mode status is currently hard-coded to false.
EXPECT_EQ(false, drm_info.security().request_model_info_status());
EXPECT_EQ(kMakeValue, drm_info.request_model_info().manufacturer());
EXPECT_EQ(kModelValue, drm_info.request_model_info().model());
EXPECT_EQ(kModelValue, drm_info.request_model_info().model_name());
}
TEST_F(SecurityProfileListTest, ProfileLevels) {
SecurityProfile::DrmInfo drm_info;
profile_list_.Init();
profile_list_->Init();
client_id_.mutable_client_capabilities()->set_max_hdcp_version(
ClientCapabilities::HDCP_NONE);
@@ -119,21 +128,24 @@ TEST_F(SecurityProfileListTest, ProfileLevels) {
device_info_.set_security_level(ProvisionedDeviceInfo::LEVEL_3);
// Lowest profile level requires OEMCrypto version 8.
ASSERT_EQ(SecurityProfile::SECURITY_PROFILE_LEVEL_UNDEFINED,
profile_list_.GetProfileLevel(client_id_, device_info_, &drm_info));
ASSERT_EQ(
SecurityProfile::SECURITY_PROFILE_LEVEL_UNDEFINED,
profile_list_->GetBestProfileLevel(client_id_, device_info_, &drm_info));
// Move up to profile 1
client_id_.mutable_client_capabilities()->set_oem_crypto_api_version(8);
ASSERT_EQ(SecurityProfile::SECURITY_PROFILE_LEVEL_1,
profile_list_.GetProfileLevel(client_id_, device_info_, &drm_info));
ASSERT_EQ(
SecurityProfile::SECURITY_PROFILE_LEVEL_1,
profile_list_->GetBestProfileLevel(client_id_, device_info_, &drm_info));
// Move up to profile 2
client_id_.mutable_client_capabilities()->set_analog_output_capabilities(
ClientCapabilities::ANALOG_OUTPUT_SUPPORTS_CGMS_A);
client_id_.mutable_client_capabilities()->set_oem_crypto_api_version(12);
device_info_.set_security_level(ProvisionedDeviceInfo::LEVEL_2);
ASSERT_EQ(SecurityProfile::SECURITY_PROFILE_LEVEL_2,
profile_list_.GetProfileLevel(client_id_, device_info_, &drm_info));
ASSERT_EQ(
SecurityProfile::SECURITY_PROFILE_LEVEL_2,
profile_list_->GetBestProfileLevel(client_id_, device_info_, &drm_info));
// Move up to profile 3
client_id_.mutable_client_capabilities()->set_max_hdcp_version(
@@ -141,16 +153,59 @@ TEST_F(SecurityProfileListTest, ProfileLevels) {
device_info_.set_security_level(ProvisionedDeviceInfo::LEVEL_1);
client_id_.mutable_client_capabilities()->set_resource_rating_tier(
kResourceTierMed);
ASSERT_EQ(SecurityProfile::SECURITY_PROFILE_LEVEL_3,
profile_list_.GetProfileLevel(client_id_, device_info_, &drm_info));
ASSERT_EQ(
SecurityProfile::SECURITY_PROFILE_LEVEL_3,
profile_list_->GetBestProfileLevel(client_id_, device_info_, &drm_info));
// Move up to profile 4
client_id_.mutable_client_capabilities()->set_max_hdcp_version(
ClientCapabilities::HDCP_V2_2);
client_id_.mutable_client_capabilities()->set_resource_rating_tier(
kResourceTierHigh);
ASSERT_EQ(SecurityProfile::SECURITY_PROFILE_LEVEL_4,
profile_list_.GetProfileLevel(client_id_, device_info_, &drm_info));
ASSERT_EQ(
SecurityProfile::SECURITY_PROFILE_LEVEL_4,
profile_list_->GetBestProfileLevel(client_id_, device_info_, &drm_info));
}
TEST_F(SecurityProfileListTest, FindProfile) {
// This test will not initialize the SecurityProfileList, hence it's empty.
// Insert test profile 1 into the list.
SecurityProfile profile1;
profile1.set_level(SecurityProfile::SECURITY_PROFILE_LEVEL_1);
profile1.set_name("profile1");
SecurityProfile profile2;
profile2.set_level(SecurityProfile::SECURITY_PROFILE_LEVEL_2);
profile2.set_name("profile2");
SecurityProfile profile3;
profile3.set_level(SecurityProfile::SECURITY_PROFILE_LEVEL_3);
profile3.set_name("profile3");
// Insert profiles 1 & 2, but not 3..
EXPECT_TRUE(profile_list_->InsertProfile(profile1));
EXPECT_TRUE(profile_list_->InsertProfile(profile2));
// Find the profile by its level.
SecurityProfile profile;
EXPECT_TRUE(profile_list_->GetProfileByLevel(profile1.level(), &profile));
EXPECT_EQ(profile1.name(), profile.name());
EXPECT_EQ(profile1.level(), profile.level());
EXPECT_TRUE(profile_list_->GetProfileByLevel(profile2.level(), &profile));
EXPECT_EQ(profile2.name(), profile.name());
EXPECT_EQ(profile2.level(), profile.level());
EXPECT_FALSE(profile_list_->GetProfileByName(profile3.name(), nullptr));
// Find the profile by its name.
EXPECT_TRUE(profile_list_->GetProfileByName(profile1.name(), &profile));
EXPECT_EQ(profile1.name(), profile.name());
EXPECT_EQ(profile1.level(), profile.level());
EXPECT_TRUE(profile_list_->GetProfileByName(profile2.name(), &profile));
EXPECT_EQ(profile2.name(), profile.name());
EXPECT_EQ(profile2.level(), profile.level());
EXPECT_FALSE(profile_list_->GetProfileByName(profile3.name(), nullptr));
}
} // namespace security_profile