Merges to android Pi release (part 6)

These are a set of CLs merged from the wv cdm repo to the android repo.

* Enable Cast for Android Things build.

  Author: Thoren Paulson <thoren@google.com>

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

  Added a path to make_cast_libwvlevel3 for Android Things. Added the new
  system id to the preprocessor guards in android_keybox.cpp. Guarded the
  references to stderr in page_allocator.cpp because for some reason they
  don't get resolved when we link against the resulting library.

  BUG: 63443584

* Resolve memory leaks in use of OpenSSL.

  Author: Gene Morgan <gmorgan@google.com>

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

  Use of EVP_CIPHER_CTX requires a call to EVP_CIPHER_CTX_cleanup().

* Memory leak in OpenSSL RSA key handling.

  Author: Gene Morgan <gmorgan@google.com>

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

  This fixes a range of tests. --gtest_filter="CdmDecrypt*" runs
  five tests and still loses 5 objects totalling 1320 bytes (down
  from 6200 bytes).

* Unit test and mock OEMCrypto memory leaks.

  Author: Gene Morgan <gmorgan@google.com>

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

  More memory leak cleanup. All remaining leaks are due
  to calls to CRYPTO_malloc() without the matching free
  (i.e., calls into openssl).

* Clean up memory leaks in tests.

  Author: Gene Morgan <gmorgan@google.com>

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

  This is the first pass at cleaning up memory leaks. These leaks
  were affecting a lot of tests, making it hard to identify more
  serious leaks.

  Switch to unique_ptr<> pointers for CdmEngine in
  generic_crypto_unittest tests for FileSystem object in
  mock OEMCrypto's CryptoEngine object.

* Fix broken tests - linux-only & address sanitizer failures.

  Author: Gene Morgan <gmorgan@google.com>

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

  Fix broken test:
    WvCdmEnginePreProvTestStaging.ServiceCertificateInitialNoneTest

  Fix failures found by address sanitizer:
    DeviceFilesUsageInfoTest.RetrieveByProviderSessionToken
    DeviceFilesUsageInfoTest.UpdateUsageInfo

  NOTE: address sanitizer cannot handle EXPECT_CALL macros containing
  a call with a Contains matcher as an argument, e.g.:

  EXPECT_CALL(file,
              Write(Contains(certificate, wrapped_private_key, 0),
                    Gt(certificate.size() + wrapped_private_key.size())))

  The address sanitizer reports a crash, issues a report, and stops. A
  temporary fix is to replace the "Contains()" argument with "_".

* Usage license handling corrections

  Author: Rahul Frias <rfrias@google.com>

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

  Validate that offline licenses that do not contain a provider session
  token are not handled by the TEE.

  BUG: 38490468

  Test: WV Unit/integration tests, GtsMediaTestCases,
        WvCdmRequestLicenseTest.ReleaseRetryL3OfflineKeySessionUsageDisabledTest

* UsageTableEntry::CopyOldUsageEntry memcpy read out of range.

  Author: Gene Morgan <gmorgan@google.com>

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

  The function copies the pst from a variable length input vector
  into a 256 byte character array. But the length argument was a
  fixed value - MAC_KEY_SIZE. Depending on the actual PST length this
  can lead to memcpy reading out of bounds or the PST getting truncated.

BUG: 71650075
Test: Not currently passing. Will be addressed in a subsequent
  commit in the chain.

Change-Id: I81a4593d7d04d0ef6069ce48d0601b6fbdd85de9
This commit is contained in:
Rahul Frias
2018-01-09 22:56:21 -08:00
parent b7c9ad57c9
commit 00da44bb68
63 changed files with 977 additions and 582 deletions

View File

@@ -14,6 +14,7 @@
#include "file_store.h"
#include "initialization_data.h"
#include "lock.h"
#include "metrics_collections.h"
#include "oemcrypto_adapter.h"
#include "scoped_ptr.h"
#include "service_certificate.h"
@@ -290,7 +291,7 @@ class CdmEngine {
// dead lock.
virtual void OnTimerEvent();
virtual metrics::MetricsGroup* GetMetrics() { return &metrics_; }
virtual metrics::EngineMetrics* GetMetrics() { return &metrics_; }
private:
// private methods
@@ -320,7 +321,7 @@ class CdmEngine {
* ensure that all data has been properly recorded in the group before
* it is published.
*/
metrics::MetricsGroup metrics_;
metrics::EngineMetrics metrics_;
metrics::TimerMetric life_span_;
CdmSessionMap session_map_;

View File

@@ -12,7 +12,7 @@
#include "file_store.h"
#include "initialization_data.h"
#include "license.h"
#include "metrics_group.h"
#include "metrics_collections.h"
#include "oemcrypto_adapter.h"
#include "policy_engine.h"
#include "scoped_ptr.h"
@@ -28,13 +28,30 @@ class UsageTableHeader;
class CdmSession {
public:
CdmSession(FileSystem* file_system);
// Creates a new instance of the CdmSession with the given |file_system|
// and |metrics| parameters. Both parameters are owned by the caller and
// must remain in scope througout the scope of the new instance. |metrics|
// must not be null.
CdmSession(FileSystem* file_system, metrics::SessionMetrics* metrics);
virtual ~CdmSession();
void Close() { closed_ = true; }
bool IsClosed() { return closed_; }
// Initializes this instance of CdmSession with the given property set.
// |cdm_client_property_set| MAY be null, is owned by the caller,
// and must remain in scope throughout the scope of this session.
virtual CdmResponseType Init(CdmClientPropertySet* cdm_client_property_set);
// Initializes this instance of CdmSession with the given parmeters.
// All parameters are owned by the caller.
// |service_certificate| is caller owned, cannot be null, and must be in
// scope as long as the session is in scope.
// |cdm_client_property_set| is caller owned, may be null, but must be
// in scope as long as the session is in scope.
// |forced_session_id| is caller owned and may be null.
// |event_listener| is caller owned, may be null, but must be in scope
// as long as the session is in scope.
virtual CdmResponseType Init(ServiceCertificate* service_certificate,
CdmClientPropertySet* cdm_client_property_set,
const CdmSessionId* forced_session_id,
@@ -171,7 +188,7 @@ class CdmSession {
CdmSigningAlgorithm algorithm,
const std::string& signature);
virtual metrics::MetricsGroup* GetMetrics() { return &metrics_; }
virtual metrics::SessionMetrics* GetMetrics() { return metrics_; }
private:
friend class CdmSessionTest;
@@ -190,20 +207,14 @@ class CdmSession {
void set_file_handle(DeviceFiles* file_handle);
// instance variables
/*
* The metrics group must be the first variable declared to ensure
* that it is the last member destroyed so that no child members
* try to use a reference to it after it is destroyed. This will
* ensure that all data has been properly recorded in the group before
* it is published.
*/
metrics::MetricsGroup metrics_;
metrics::SessionMetrics* metrics_;
metrics::CryptoMetrics* crypto_metrics_;
metrics::TimerMetric life_span_;
bool initialized_;
bool closed_; // Session closed, but final shared_ptr has not been released.
CdmSessionId session_id_;
FileSystem* file_system_;
scoped_ptr<CdmLicense> license_parser_;
scoped_ptr<CryptoSession> crypto_session_;
scoped_ptr<PolicyEngine> policy_engine_;

View File

@@ -7,7 +7,7 @@
#include "crypto_session.h"
#include "license_protocol.pb.h"
#include "metrics_group.h"
#include "metrics_collections.h"
#include "oemcrypto_adapter.h"
#include "scoped_ptr.h"
#include "wv_cdm_types.h"
@@ -21,7 +21,7 @@ class ServiceCertificate;
class CertificateProvisioning {
public:
CertificateProvisioning(metrics::MetricsGroup* metrics,
CertificateProvisioning(metrics::CryptoMetrics* metrics,
ServiceCertificate* service_certificate) :
crypto_session_(metrics),
cert_type_(kCertificateWidevine),

View File

@@ -9,7 +9,7 @@
#include "OEMCryptoCENC.h"
#include "lock.h"
#include "metrics_group.h"
#include "metrics_collections.h"
#include "oemcrypto_adapter.h"
#include "timer_metric.h"
#include "wv_cdm_types.h"
@@ -36,7 +36,10 @@ class CryptoSession {
bool rsa_cast;
};
CryptoSession(metrics::MetricsGroup* metrics);
// Creates an instance of CryptoSession with the given |crypto_metrics|.
// |crypto_metrics| is owned by the caller, must NOT be null, and must
// exist as long as the new CryptoSession exists.
explicit CryptoSession(metrics::CryptoMetrics* crypto_metrics);
virtual ~CryptoSession();
virtual bool GetClientToken(std::string* client_token);
@@ -220,7 +223,7 @@ class CryptoSession {
static bool initialized_;
static int session_count_;
metrics::MetricsGroup* metrics_;
metrics::CryptoMetrics* metrics_;
metrics::TimerMetric life_span_;
bool open_;

View File

@@ -9,9 +9,8 @@
#include "device_files.h"
#include "file_store.h"
#include "lock.h"
#include "metrics_group.h"
#include "metrics_collections.h"
#include "scoped_ptr.h"
#include "timer_metric.h"
#include "wv_cdm_types.h"
namespace wvcdm {
@@ -67,29 +66,29 @@ class UsageTableHeader {
// should not be in use by any open CryptoSession objects when calls
// to DeleteEntry and MoveEntry are made.
CdmResponseType DeleteEntry(uint32_t usage_entry_number, DeviceFiles* handle,
metrics::MetricsGroup* metrics);
metrics::CryptoMetrics* metrics);
private:
CdmResponseType MoveEntry(uint32_t from /* usage entry number */,
const CdmUsageEntry& from_usage_entry,
uint32_t to /* usage entry number */,
DeviceFiles* handle,
metrics::MetricsGroup* metrics);
metrics::CryptoMetrics* metrics);
CdmResponseType GetEntry(uint32_t usage_entry_number, DeviceFiles* handle,
CdmUsageEntry* usage_entry);
CdmResponseType StoreEntry(uint32_t usage_entry_number, DeviceFiles* handle,
const CdmUsageEntry& usage_entry);
CdmResponseType Shrink(metrics::MetricsGroup* metrics,
CdmResponseType Shrink(metrics::CryptoMetrics* metrics,
uint32_t number_of_usage_entries_to_delete);
CdmResponseType UpgradeFromUsageTable(DeviceFiles* handle,
metrics::MetricsGroup* metrics);
metrics::CryptoMetrics* metrics);
bool UpgradeLicensesFromUsageTable(DeviceFiles* handle,
metrics::MetricsGroup* metrics);
metrics::CryptoMetrics* metrics);
bool UpgradeUsageInfoFromUsageTable(DeviceFiles* handle,
metrics::MetricsGroup* metrics);
metrics::CryptoMetrics* metrics);
virtual bool is_inited() { return is_inited_; }

View File

@@ -77,6 +77,7 @@ static const std::string QUERY_VALUE_SECURITY_LEVEL_L1 = "L1";
static const std::string QUERY_VALUE_SECURITY_LEVEL_L2 = "L2";
static const std::string QUERY_VALUE_SECURITY_LEVEL_L3 = "L3";
static const std::string QUERY_VALUE_SECURITY_LEVEL_UNKNOWN = "Unknown";
static const std::string QUERY_VALUE_SECURITY_LEVEL_DEFAULT = "Default";
static const std::string QUERY_VALUE_DISCONNECTED = "Disconnected";
static const std::string QUERY_VALUE_UNPROTECTED = "Unprotected";
static const std::string QUERY_VALUE_HDCP_V1 = "HDCP-1.x";

View File

@@ -16,7 +16,6 @@
#include "file_store.h"
#include "license_protocol.pb.h"
#include "log.h"
#include "metrics_front_end.h"
#include "properties.h"
#include "string_conversions.h"
#include "wv_cdm_constants.h"
@@ -188,7 +187,8 @@ CdmResponseType CdmEngine::OpenSession(
CloseExpiredReleaseSessions();
scoped_ptr<CdmSession> new_session(new CdmSession(file_system_));
scoped_ptr<CdmSession> new_session(new CdmSession(file_system_,
metrics_.AddSession()));
CdmResponseType sts = new_session->Init(&service_certificate_, property_set,
forced_session_id, event_listener);
if (sts != NO_ERROR) {
@@ -545,13 +545,13 @@ CdmResponseType CdmEngine::QueryStatus(SecurityLevel security_level,
const std::string& query_token,
std::string* query_response) {
LOGI("CdmEngine::QueryStatus");
CryptoSession crypto_session(&metrics_);
CryptoSession crypto_session(metrics_.GetCryptoMetrics());
if (security_level == kLevel3) {
CdmResponseType status;
M_TIME(
status = crypto_session.Open(
kLevel3),
&metrics_,
metrics_.GetCryptoMetrics(),
crypto_session_open_,
status,
kLevel3);
@@ -567,7 +567,7 @@ CdmResponseType CdmEngine::QueryStatus(SecurityLevel security_level,
CdmSecurityLevel level;
M_TIME(
level = crypto_session.GetSecurityLevel(),
&metrics_,
metrics_.GetCryptoMetrics(),
crypto_session_get_security_level_,
level);
switch (level) {
@@ -594,7 +594,7 @@ CdmResponseType CdmEngine::QueryStatus(SecurityLevel security_level,
M_TIME(
got_id = crypto_session.GetExternalDeviceUniqueId(
&deviceId),
&metrics_,
metrics_.GetCryptoMetrics(),
crypto_session_get_device_unique_id_,
got_id);
if (!got_id) {
@@ -609,7 +609,7 @@ CdmResponseType CdmEngine::QueryStatus(SecurityLevel security_level,
M_TIME(
got_id = crypto_session.GetSystemId(
&system_id),
&metrics_,
metrics_.GetCryptoMetrics(),
crypto_session_get_system_id_,
got_id,
system_id);
@@ -646,7 +646,7 @@ CdmResponseType CdmEngine::QueryStatus(SecurityLevel security_level,
M_TIME(
got_info = crypto_session.UsageInformationSupport(
&supports_usage_reporting),
&metrics_,
metrics_.GetCryptoMetrics(),
crypto_session_usage_information_support_,
got_info);
if (!got_info) {
@@ -854,7 +854,8 @@ CdmResponseType CdmEngine::GetProvisioningRequest(
if (NULL == cert_provisioning_.get()) {
cert_provisioning_.reset(
new CertificateProvisioning(&metrics_, &service_certificate_));
new CertificateProvisioning(metrics_.GetCryptoMetrics(),
&service_certificate_));
}
CdmResponseType ret = cert_provisioning_->GetProvisioningRequest(
cert_provisioning_requested_security_level_, cert_type, cert_authority,
@@ -896,12 +897,12 @@ CdmResponseType CdmEngine::HandleProvisioningResponse(
if (NULL == cert_provisioning_.get()) {
// Certificate provisioning object has been released. Check if a concurrent
// provisioning attempt has succeeded before declaring failure.
CryptoSession crypto_session(&metrics_);
CryptoSession crypto_session(metrics_.GetCryptoMetrics());
CdmResponseType status;
M_TIME(
status = crypto_session.Open(
cert_provisioning_requested_security_level_),
&metrics_,
metrics_.GetCryptoMetrics(),
crypto_session_open_,
status,
cert_provisioning_requested_security_level_);
@@ -914,7 +915,7 @@ CdmResponseType CdmEngine::HandleProvisioningResponse(
CdmSecurityLevel security_level;
M_TIME(
security_level = crypto_session.GetSecurityLevel(),
&metrics_,
metrics_.GetCryptoMetrics(),
crypto_session_get_security_level_,
security_level);
if (!IsProvisioned(security_level)) {
@@ -968,14 +969,15 @@ CdmResponseType CdmEngine::Unprovision(CdmSecurityLevel security_level) {
}
CdmResponseType CdmEngine::DeleteUsageTable(CdmSecurityLevel security_level) {
scoped_ptr<CryptoSession> crypto_session(new CryptoSession(&metrics_));
scoped_ptr<CryptoSession> crypto_session(
new CryptoSession(metrics_.GetCryptoMetrics()));
CdmResponseType status;
M_TIME(
status = crypto_session->Open(
security_level == kSecurityLevelL3 ?
kLevel3 :
kLevelDefault),
&metrics_,
metrics_.GetCryptoMetrics(),
crypto_session_open_,
status,
security_level == kSecurityLevelL3 ? kLevel3 : kLevelDefault);
@@ -986,11 +988,12 @@ CdmResponseType CdmEngine::DeleteUsageTable(CdmSecurityLevel security_level) {
}
M_TIME(
status = crypto_session->DeleteAllUsageReports(),
&metrics_,
metrics_.GetCryptoMetrics(),
crypto_session_delete_all_usage_reports_,
status);
if (status != NO_ERROR) {
LOGE("CdmEngine::DeleteUsageTable: error deleteing usage reports: %d", status);
LOGE("CdmEngine::DeleteUsageTable: error deleteing usage reports: %d",
status);
}
return status;
}
@@ -1049,7 +1052,8 @@ CdmResponseType CdmEngine::DeleteUsageRecord(const std::string& app_id,
}
// Got provider token. Remove from OEMCrypto.
scoped_ptr<CryptoSession> crypto_session(new CryptoSession(&metrics_));
scoped_ptr<CryptoSession> crypto_session(
new CryptoSession(metrics_.GetCryptoMetrics()));
CdmResponseType status = crypto_session->Open(
security_level == kSecurityLevelL3 ? kLevel3 : kLevelDefault);
if (status == NO_ERROR) {
@@ -1079,7 +1083,7 @@ CdmResponseType CdmEngine::GetUsageInfo(const std::string& app_id,
}
usage_property_set_->set_security_level(kLevelDefault);
usage_property_set_->set_app_id(app_id);
usage_session_.reset(new CdmSession(file_system_));
usage_session_.reset(new CdmSession(file_system_, metrics_.AddSession()));
CdmResponseType status = usage_session_->Init(usage_property_set_.get());
if (NO_ERROR != status) {
LOGE("CdmEngine::GetUsageInfo: session init error: %d", status);
@@ -1099,7 +1103,7 @@ CdmResponseType CdmEngine::GetUsageInfo(const std::string& app_id,
ssid, &usage_data)) {
usage_property_set_->set_security_level(kLevel3);
usage_property_set_->set_app_id(app_id);
usage_session_.reset(new CdmSession(file_system_));
usage_session_.reset(new CdmSession(file_system_, metrics_.AddSession()));
status = usage_session_->Init(usage_property_set_.get());
if (NO_ERROR != status) {
LOGE("CdmEngine::GetUsageInfo: session init error");
@@ -1176,7 +1180,7 @@ CdmResponseType CdmEngine::GetUsageInfo(const std::string& app_id,
usage_property_set_->set_security_level(requested_security_level);
usage_property_set_->set_app_id(app_id);
usage_session_.reset(new CdmSession(file_system_));
usage_session_.reset(new CdmSession(file_system_, metrics_.AddSession()));
CdmResponseType status = usage_session_->Init(usage_property_set_.get());
if (NO_ERROR != status) {
@@ -1257,7 +1261,8 @@ CdmResponseType CdmEngine::ReleaseAllUsageInfo(
}
// Got at least one provider token. Remove from OEMCrypto.
scoped_ptr<CryptoSession> crypto_session(new CryptoSession(&metrics_));
scoped_ptr<CryptoSession> crypto_session(
new CryptoSession(metrics_.GetCryptoMetrics()));
CdmResponseType status = crypto_session->Open(
security_level == kSecurityLevelL3 ? kLevel3 : kLevelDefault);
if (status == NO_ERROR) {
@@ -1285,7 +1290,7 @@ CdmResponseType CdmEngine::ReleaseAllUsageInfo(const std::string& app_id) {
? kLevel3
: kLevelDefault;
usage_property_set_->set_security_level(security_level);
usage_session_.reset(new CdmSession(file_system_));
usage_session_.reset(new CdmSession(file_system_, metrics_.AddSession()));
usage_session_->Init(usage_property_set_.get());
switch (usage_session_->get_usage_support_type()) {
@@ -1730,19 +1735,20 @@ void CdmEngine::DeleteAllUsageReportsUponFactoryReset() {
if (!file_system_->Exists(device_base_path_level1) &&
!file_system_->Exists(device_base_path_level3)) {
scoped_ptr<CryptoSession> crypto_session(new CryptoSession(&metrics_));
scoped_ptr<CryptoSession> crypto_session(
new CryptoSession(metrics_.GetCryptoMetrics()));
CdmResponseType status;
M_TIME(
status = crypto_session->Open(
cert_provisioning_requested_security_level_),
&metrics_,
metrics_.GetCryptoMetrics(),
crypto_session_open_,
status,
cert_provisioning_requested_security_level_);
if (NO_ERROR == status) {
M_TIME(
status = crypto_session->DeleteAllUsageReports(),
&metrics_,
metrics_.GetCryptoMetrics(),
crypto_session_delete_all_usage_reports_,
status);
if (NO_ERROR != status) {

View File

@@ -12,7 +12,6 @@
#include "clock.h"
#include "file_store.h"
#include "log.h"
#include "metrics_front_end.h"
#include "properties.h"
#include "string_conversions.h"
#include "wv_cdm_constants.h"
@@ -25,10 +24,10 @@ const size_t kKeySetIdLength = 14;
namespace wvcdm {
CdmSession::CdmSession(FileSystem* file_system) :
CdmSession::CdmSession(FileSystem* file_system,
metrics::SessionMetrics* metrics) :
metrics_(metrics),
initialized_(false),
closed_(false),
crypto_session_(new CryptoSession(&metrics_)),
file_handle_(new DeviceFiles(file_system)),
license_received_(false),
is_offline_(false),
@@ -45,6 +44,9 @@ CdmSession::CdmSession(FileSystem* file_system) :
usage_entry_number_(0),
mock_license_parser_in_use_(false),
mock_policy_engine_in_use_(false) {
assert(metrics_); // metrics_ must not be null.
crypto_metrics_ = metrics_->GetCryptoMetrics();
crypto_session_.reset(new CryptoSession(crypto_metrics_));
life_span_.Start();
}
@@ -55,7 +57,10 @@ CdmSession::~CdmSession() {
}
Properties::RemoveSessionPropertySet(session_id_);
M_RECORD(&metrics_, cdm_session_life_span_, life_span_.AsMs());
if (metrics_) {
M_RECORD(metrics_, cdm_session_life_span_, life_span_.AsMs());
metrics_->SetCompleted();
}
}
CdmResponseType CdmSession::Init(
@@ -80,16 +85,15 @@ CdmResponseType CdmSession::Init(
}
CdmResponseType sts;
M_TIME(
sts = crypto_session_->Open(
requested_security_level_),
&metrics_,
sts = crypto_session_->Open(requested_security_level_),
crypto_metrics_,
crypto_session_open_,
sts,
requested_security_level_);
if (NO_ERROR != sts) return sts;
M_TIME(
security_level_ = crypto_session_->GetSecurityLevel(),
&metrics_,
crypto_metrics_,
crypto_session_get_security_level_,
security_level_);
if (!file_handle_->Init(security_level_)) {
@@ -126,7 +130,7 @@ CdmResponseType CdmSession::Init(
M_TIME(
get_client_token_sts = crypto_session_->GetClientToken(
&client_token),
&metrics_,
crypto_metrics_,
crypto_session_get_token_,
get_client_token_sts);
if (!get_client_token_sts) {
@@ -144,7 +148,7 @@ CdmResponseType CdmSession::Init(
M_TIME(
load_cert_sts = crypto_session_->LoadCertificatePrivateKey(
wrapped_key),
&metrics_,
crypto_metrics_,
crypto_session_load_certificate_private_key_,
load_cert_sts);
if(!load_cert_sts) {
@@ -166,6 +170,7 @@ CdmResponseType CdmSession::Init(
session_id_ =
Properties::AlwaysUseKeySetIds() ? key_set_id_ : GenerateSessionId();
metrics_->SetSessionId(session_id_);
if (session_id_.empty()) {
LOGE("CdmSession::Init: empty session ID");
@@ -222,14 +227,20 @@ CdmResponseType CdmSession::RestoreOfflineSession(
return GET_RELEASED_LICENSE_ERROR;
}
std::string provider_session_token;
if (usage_support_type_ == kUsageEntrySupport) {
CdmResponseType sts = usage_table_header_->LoadEntry(crypto_session_.get(),
usage_entry_,
usage_entry_number_);
if (sts != NO_ERROR) {
LOGE("CdmSession::RestoreOfflineSession: failed to load usage entry = %d",
sts);
return sts;
if (!license_parser_->ExtractProviderSessionToken(
key_response_, &provider_session_token)) {
provider_session_token.clear();
} else {
CdmResponseType sts =
usage_table_header_->LoadEntry(crypto_session_.get(), usage_entry_,
usage_entry_number_);
if (sts != NO_ERROR) {
LOGE("CdmSession::RestoreOfflineSession: failed to load usage entry = "
"%d", sts);
return sts;
}
}
}
@@ -246,7 +257,8 @@ CdmResponseType CdmSession::RestoreOfflineSession(
}
}
if (usage_support_type_ == kUsageEntrySupport) {
if (usage_support_type_ == kUsageEntrySupport &&
!provider_session_token.empty()) {
CdmResponseType sts =
usage_table_header_->UpdateEntry(crypto_session_.get(), &usage_entry_);
if (sts != NO_ERROR) {
@@ -432,7 +444,8 @@ CdmResponseType CdmSession::AddKey(const CdmKeyResponse& key_response) {
if (sts != KEY_ADDED) {
CdmResponseType sts =
usage_table_header_->DeleteEntry(usage_entry_number_,
file_handle_.get(), &metrics_);
file_handle_.get(),
crypto_metrics_);
if (sts != NO_ERROR) {
LOGW("CdmSession::AddKey: Delete usage entry failed = %d", sts);
}
@@ -449,8 +462,10 @@ CdmResponseType CdmSession::AddKey(const CdmKeyResponse& key_response) {
license_parser_->provider_session_token().c_str());
if (is_offline_ || has_provider_session_token()) {
if (usage_support_type_ == kUsageEntrySupport)
if (has_provider_session_token() &&
usage_support_type_ == kUsageEntrySupport) {
usage_table_header_->UpdateEntry(crypto_session_.get(), &usage_entry_);
}
if (!is_offline_)
usage_provider_session_token_ =
@@ -614,7 +629,8 @@ CdmResponseType CdmSession::GenerateReleaseRequest(
if (KEY_MESSAGE != status) return status;
if (usage_support_type_ == kUsageEntrySupport) {
if (has_provider_session_token() &&
usage_support_type_ == kUsageEntrySupport) {
status = usage_table_header_->UpdateEntry(crypto_session_.get(),
&usage_entry_);
if (status != NO_ERROR) {
@@ -645,7 +661,8 @@ CdmResponseType CdmSession::ReleaseKey(const CdmKeyResponse& key_response) {
if (is_offline_ || has_provider_session_token()) {
DeleteLicense();
if (usage_support_type_ == kUsageEntrySupport) {
if (usage_support_type_ == kUsageEntrySupport &&
has_provider_session_token()) {
sts = DeleteUsageEntry(usage_entry_number_);
if (NO_ERROR != sts) return sts;
}
@@ -654,7 +671,8 @@ CdmResponseType CdmSession::ReleaseKey(const CdmKeyResponse& key_response) {
}
CdmResponseType CdmSession::DeleteUsageEntry(uint32_t usage_entry_number) {
if (usage_support_type_ != kUsageEntrySupport) {
if (usage_support_type_ != kUsageEntrySupport ||
!has_provider_session_token()) {
LOGE("CdmSession::DeleteUsageEntry: Unexpected usage type supported: %d",
usage_support_type_);
return INCORRECT_USAGE_SUPPORT_TYPE_1;
@@ -664,10 +682,10 @@ CdmResponseType CdmSession::DeleteUsageEntry(uint32_t usage_entry_number) {
// it, so close and reopen session.
CdmResponseType sts;
crypto_session_->Close();
crypto_session_.reset(new CryptoSession(&metrics_));
crypto_session_.reset(new CryptoSession(crypto_metrics_));
M_TIME(
sts = crypto_session_->Open(requested_security_level_),
&metrics_,
crypto_metrics_,
crypto_session_open_,
sts,
requested_security_level_);
@@ -688,7 +706,7 @@ CdmResponseType CdmSession::DeleteUsageEntry(uint32_t usage_entry_number) {
return usage_table_header_->DeleteEntry(usage_entry_number,
file_handle_.get(),
&metrics_);
crypto_metrics_);
}
bool CdmSession::IsKeyLoaded(const KeyId& key_id) {
@@ -838,7 +856,7 @@ CdmResponseType CdmSession::DeleteMultipleUsageInformation(
M_TIME(
sts = crypto_session_->DeleteMultipleUsageInformation(
provider_session_tokens),
&metrics_,
crypto_metrics_,
crypto_session_delete_multiple_usage_information_,
sts);
return sts;
@@ -852,7 +870,7 @@ CdmResponseType CdmSession::UpdateUsageTableInformation() {
if (sts == NO_ERROR && usage_support_type == kUsageTableSupport) {
M_TIME(
sts = crypto_session_->UpdateUsageInformation(),
&metrics_,
crypto_metrics_,
crypto_session_update_usage_information_,
sts);
return sts;
@@ -862,7 +880,8 @@ CdmResponseType CdmSession::UpdateUsageTableInformation() {
}
CdmResponseType CdmSession::UpdateUsageEntryInformation() {
if (usage_support_type_ != kUsageEntrySupport) {
if (usage_support_type_ != kUsageEntrySupport ||
!has_provider_session_token()) {
LOGE("CdmSession::UpdateUsageEntryInformation: Unexpected usage type "
"supported: %d", usage_support_type_);
return INCORRECT_USAGE_SUPPORT_TYPE_2;
@@ -900,7 +919,7 @@ CdmResponseType CdmSession::GenericEncrypt(const std::string& in_buffer,
iv,
algorithm,
out_buffer),
&metrics_,
crypto_metrics_,
crypto_session_generic_encrypt_,
sts,
metrics::Pow2Bucket(in_buffer.size()),
@@ -925,7 +944,7 @@ CdmResponseType CdmSession::GenericDecrypt(const std::string& in_buffer,
iv,
algorithm,
out_buffer),
&metrics_,
crypto_metrics_,
crypto_session_generic_decrypt_,
sts,
metrics::Pow2Bucket(in_buffer.size()),
@@ -948,7 +967,7 @@ CdmResponseType CdmSession::GenericSign(const std::string& message,
key_id,
algorithm,
signature),
&metrics_,
crypto_metrics_,
crypto_session_generic_sign_,
sts,
metrics::Pow2Bucket(message.size()),
@@ -967,7 +986,7 @@ CdmResponseType CdmSession::GenericVerify(const std::string& message,
key_id,
algorithm,
signature),
&metrics_,
crypto_metrics_,
crypto_session_generic_verify_,
sts,
metrics::Pow2Bucket(message.size()),

View File

@@ -12,7 +12,6 @@
#include "crypto_key.h"
#include "log.h"
#include "metrics_front_end.h"
#include "openssl/sha.h"
#include "properties.h"
#include "pst_report.h"
@@ -45,7 +44,7 @@ uint64_t CryptoSession::request_id_index_ = 0;
UsageTableHeader* CryptoSession::usage_table_header_l1_ = NULL;
UsageTableHeader* CryptoSession::usage_table_header_l3_ = NULL;
CryptoSession::CryptoSession(metrics::MetricsGroup* metrics)
CryptoSession::CryptoSession(metrics::CryptoMetrics* metrics)
: metrics_(metrics),
open_(false),
update_usage_table_after_close_session_(false),
@@ -234,34 +233,43 @@ bool CryptoSession::GetProvisioningToken(std::string* token) {
CdmSecurityLevel CryptoSession::GetSecurityLevel() {
LOGV("CryptoSession::GetSecurityLevel");
if (!initialized_) {
M_RECORD(metrics_, oemcrypto_security_level_, 0,
kSecurityLevelUninitialized, requested_security_level_);
return kSecurityLevelUninitialized;
}
std::string security_level;
M_TIME(
security_level = OEMCrypto_SecurityLevel(
requested_security_level_),
metrics_,
oemcrypto_security_level_,
security_level,
requested_security_level_);
wvcdm::metrics::TimerMetric timer;
timer.Start();
std::string security_level =
OEMCrypto_SecurityLevel(requested_security_level_);
double clock_time = timer.AsUs();
if ((security_level.size() != 2) || (security_level.at(0) != 'L')) {
M_RECORD(metrics_, oemcrypto_security_level_, clock_time,
kSecurityLevelUnknown, requested_security_level_);
return kSecurityLevelUnknown;
}
CdmSecurityLevel cdm_security_level;
switch (security_level.at(1)) {
case '1':
return kSecurityLevelL1;
cdm_security_level = kSecurityLevelL1;
break;
case '2':
return kSecurityLevelL2;
cdm_security_level = kSecurityLevelL2;
break;
case '3':
return kSecurityLevelL3;
cdm_security_level = kSecurityLevelL3;
break;
default:
return kSecurityLevelUnknown;
cdm_security_level = kSecurityLevelUnknown;
break;
}
return kSecurityLevelUnknown;
M_RECORD(metrics_, oemcrypto_security_level_, clock_time,
cdm_security_level, requested_security_level_);
return cdm_security_level;
}
bool CryptoSession::GetInternalDeviceUniqueId(std::string* device_id) {
@@ -444,8 +452,10 @@ uint8_t CryptoSession::GetSecurityPatchLevel() {
}
CdmResponseType CryptoSession::Open(SecurityLevel requested_security_level) {
LOGV("CryptoSession::Open: Lock: requested_security_level: %d",
requested_security_level);
LOGD("CryptoSession::Open: Lock: requested_security_level: %s",
requested_security_level == kLevel3
? QUERY_VALUE_SECURITY_LEVEL_L3.c_str()
: QUERY_VALUE_SECURITY_LEVEL_DEFAULT.c_str());
AutoLock auto_lock(crypto_lock_);
if (!initialized_) return UNKNOWN_ERROR;
if (open_) return NO_ERROR;
@@ -719,6 +729,10 @@ CdmResponseType CryptoSession::LoadKeys(
} else if (OEMCrypto_ERROR_TOO_MANY_KEYS == sts) {
LOGE("CryptoSession::LoadKeys: OEMCrypto_LoadKeys error=%d", sts);
result = INSUFFICIENT_CRYPTO_RESOURCES;
} else if (OEMCrypto_ERROR_USAGE_TABLE_UNRECOVERABLE == sts) {
// Handle vendor specific error
LOGE("CryptoSession::LoadKeys: OEMCrypto_LoadKeys error=%d", sts);
result = NEED_PROVISIONING;
} else {
LOGE("CryptoSession::LoadKeys: OEMCrypto_LoadKeys error=%d", sts);
result = LOAD_KEY_ERROR;
@@ -1750,11 +1764,15 @@ bool CryptoSession::GetSrmVersion(uint16_t* srm_version) {
}
OEMCryptoResult status = OEMCrypto_GetCurrentSRMVersion(srm_version);
if (OEMCrypto_SUCCESS != status) {
LOGW("OEMCrypto_GetCurrentSRMVersion fails with %d", status);
return false;
switch (status) {
case OEMCrypto_SUCCESS:
return true;
case OEMCrypto_ERROR_NOT_IMPLEMENTED:
return false;
default:
LOGW("OEMCrypto_GetCurrentSRMVersion fails with %d", status);
return false;
}
return true;
}
bool CryptoSession::IsSrmUpdateSupported() {

View File

@@ -163,7 +163,7 @@ bool DeviceFiles::ExtractDeviceInfo(const std::string& device_certificate,
uint32_t* system_id) {
LOGI("ExtractDeviceInfo Entry");
if (!serial_number && !system_id) {
LOGE("Invalid paramters to DeviceFiles::ExtractDeviceInfo");
LOGE("DeviceFiles::ExtractDeviceInfo: invalid parameter.");
return false;
}
@@ -1239,7 +1239,7 @@ bool DeviceFiles::FileExists(const std::string& name) {
bool DeviceFiles::ListFiles(std::vector<std::string>* names) {
std::string path;
if (!Properties::GetDeviceFilesBasePath(security_level_, &path)) {
LOGW("DeviceFiles::RemoveFile: Unable to get base path");
LOGW("DeviceFiles::ListFiles: Unable to get base path");
return false;
}
return file_system_->List(path, names);

View File

@@ -486,13 +486,11 @@ CdmResponseType CdmLicense::HandleKeyResponse(
license.policy().can_persist())
is_offline_ = true;
LOGV("Get Provider_session_token:");
if (license.id().has_provider_session_token()) {
if (license.id().has_provider_session_token())
provider_session_token_ = license.id().provider_session_token();
LOGV("Provider_session_token=%s", provider_session_token_.c_str());
} else {
LOGV("NO Provider_session_token");
}
LOGV("provider_session_token: %s", provider_session_token_.empty() ?
"N/A" : provider_session_token_.c_str());
if (license.policy().has_renewal_server_url()) {
server_url_ = license.policy().renewal_server_url();
@@ -803,7 +801,8 @@ bool CdmLicense::ExtractProviderSessionToken(
return false;
}
if (license.id().has_provider_session_token()) {
if (license.id().has_provider_session_token() &&
!license.id().provider_session_token().empty()) {
*provider_session_token = license.id().provider_session_token();
return true;
}

View File

@@ -29,8 +29,7 @@
#include "level3.h"
#include "lock.h"
#include "log.h"
#include "metrics_front_end.h"
#include "metrics_group.h"
#include "metrics_collections.h"
#include "properties.h"
#include "wv_cdm_constants.h"
@@ -41,6 +40,8 @@ using wvcdm::kLevel3;
namespace {
static const size_t kMaxGenericEncryptChunkSize = 100*1024;
const OEMCryptoResult kOemCryptoResultVendorSpecificError1 =
static_cast<OEMCryptoResult>(10008);
typedef struct {
const uint8_t* key_id;
@@ -375,6 +376,162 @@ void clear_cache_function(void *page, size_t len) {
#endif
}
// The WatchDog looks after a worker thread that is trying to initialize L3.
// Once in a rare while, the L3 init does not finish and eats up CPU cycles.
// If that happens, the watchdog thread will give up and return an error.
class WatchDog {
public:
// Created by main thread.
WatchDog() {
pthread_mutex_init(&mutex_, NULL);
pthread_cond_init(&condition_, NULL);
status_ = OEMCrypto_SUCCESS;
gave_up_ = false;
}
// Deleted by either thread.
~WatchDog() {
pthread_cond_destroy(&condition_);
}
// Starts worker thread.
void StartThread() {
running_ = true;
if(pthread_create(&thread_, NULL, RunWatchDog, this)) {
LOGE("Could not create watch dog thread.");
status_ = OEMCrypto_ERROR_INIT_FAILED;
running_ = false;
return;
}
}
// Function called by new worker thread in pthread_create.
static void *RunWatchDog(void *watcher) {
WatchDog* dog = reinterpret_cast<WatchDog *>(watcher);
dog->DoInit();
dog->SignalDoneAndCleanUp();
return NULL;
}
// Called by worker thread.
void DoInit() {
std::string base_path;
wvcdm::Properties::GetDeviceFilesBasePath(wvcdm::kSecurityLevelL3,
&base_path);
status_ = Level3_Initialize(clear_cache_function,
base_path.c_str());
}
std::string FailureFilename() {
std::string path;
if (!wvcdm::Properties::GetDeviceFilesBasePath(wvcdm::kSecurityLevelL3,
&path)) {
LOGW("WatchDog::FailureFilename: Unable to get base path");
return "/data/l3_failure_file";
}
path += "l3_failure_file";
return path;
}
// Check to see if the failure file was created before that last abort.
void CheckForPreviousFailure(wvcdm::metrics::CryptoMetrics* metrics) {
wvcdm::FileSystem file_system;
std::string filename = FailureFilename();
if (!file_system.Exists(filename)) return;
wvcdm::File* file = file_system.Open(filename, file_system.kReadOnly);
if (file) {
uint32_t flag = 0;
ssize_t size = sizeof(flag);
ssize_t size_read = file->Read(reinterpret_cast<char*>(&flag), size);
file->Close();
file_system.Remove(filename);
if (size == size_read && flag) {
LOGE("Previous L3 Init failed.");
if (metrics == nullptr) return;
M_RECORD(
metrics,
oemcrypto_initialization_mode_,
NO_TIME,
wvcdm::metrics::OEMCrypto_INITIALIZED_L3_INITIALIZATION_FAILED);
}
}
}
// Save the failure file before we abort.
void SaveFailureInformation() {
wvcdm::FileSystem file_system;
std::string filename = FailureFilename();
LOGD("failure filename = %s", filename.c_str());
wvcdm::File* file = file_system.Open(
filename, file_system.kCreate | file_system.kTruncate);
if (!file) {
LOGE("Could not create file %s", filename.c_str());
return;
}
uint32_t flag = 0x6261640a; // bad
ssize_t size = sizeof(flag);
ssize_t size_written = file->Write(reinterpret_cast<char*>(&flag), size);
file->Close();
if (size != size_written) {
LOGE("Wrote %d bytes, not %d, to file %s", size_written, size,
filename.c_str());
} else {
LOGE("I wrote %d to %s", size_written, filename.c_str());
}
}
// Called by worker thread after DoInit has finshed.
void SignalDoneAndCleanUp() {
pthread_mutex_lock(&mutex_);
running_ = false;
pthread_cond_signal(&condition_);
// If the main thread gave up, it won't delete this, so we must.
bool should_delete = gave_up_;
pthread_mutex_unlock(&mutex_);
// https://isocpp.org/wiki/faq/freestore-mgmt#delete-this
if (should_delete) delete this;
}
// Called by main thread to wait for worker thread.
OEMCryptoResult WaitForStatusAndCleanUp() {
pthread_mutex_lock(&mutex_);
struct timespec time_to_giveup;
clock_gettime(CLOCK_REALTIME, &time_to_giveup);
time_to_giveup.tv_sec += 5; // wait 5 seconds.
if (running_) {
pthread_cond_timedwait(&condition_, &mutex_, &time_to_giveup);
}
if (running_) {
gave_up_ = true;
status_ = OEMCrypto_ERROR_INIT_FAILED;
LOGE("XXX WATCH DOG ERROR XXX");
SaveFailureInformation();
// This is controversial. The argument for an abort here is that if we
// do not abort, we will suck all the life out of the user's battery. By
// saving information to the file system, above, we can still track
// metrics.
abort();
}
// If we gave up waiting for init thread, we should not delete the mutex
// out from under it.
bool should_delete = !gave_up_;
OEMCryptoResult status = status_;
pthread_mutex_unlock(&mutex_);
if (should_delete) delete this;
return status;
}
OEMCryptoResult status() { return status_; }
private:
OEMCryptoResult status_;
pthread_t thread_;
pthread_mutex_t mutex_;
pthread_cond_t condition_;
bool running_;
bool gave_up_;
};
struct LevelSession {
FunctionPointers* fcn;
OEMCrypto_SESSION session;
@@ -423,17 +580,20 @@ class Adapter {
* To avoid changing the function signature and function contract - declare
* a one-off metrics group to collect detailed information about how
* oemcrypto was intialized.
*
* TODO(blueeyes): Refactor this to allow Initialize to provide the
* details to the caller or to use the metrics instance provided by
* the caller.
*/
wvcdm::metrics::MetricsGroup metrics;
wvcdm::metrics::CryptoMetrics metrics;
level1_ = FunctionPointers(); // start with all null pointers.
level3_ = FunctionPointers(); // start with all null pointers.
LoadLevel3();
std::string base_path;
wvcdm::Properties::GetDeviceFilesBasePath(wvcdm::kSecurityLevelL3,
&base_path);
OEMCryptoResult result = Level3_Initialize(clear_cache_function,
base_path.c_str());
WatchDog *watcher = new WatchDog();
watcher->CheckForPreviousFailure(&metrics);
watcher->StartThread();
OEMCryptoResult result = watcher->WaitForStatusAndCleanUp();
if (Level3_IsInApp()) {
M_RECORD(
&metrics,
@@ -472,7 +632,7 @@ class Adapter {
wvcdm::metrics::OEMCrypto_INITIALIZED_USING_L3_L1_OPEN_FAILED);
return result;
}
if (LoadLevel1(metrics)) {
if (LoadLevel1(&metrics)) {
LOGD("OEMCrypto_Initialize Level 1 success. I will use level 1.");
} else {
level1_ = FunctionPointers(); // revert to all null pointers.
@@ -483,7 +643,10 @@ class Adapter {
return result;
}
bool LoadLevel1(wvcdm::metrics::MetricsGroup& metrics) {
bool LoadLevel1(wvcdm::metrics::CryptoMetrics* metrics) {
if (metrics == nullptr) {
return false;
}
level1_valid_ = true;
const uint32_t kMinimumVersion = 8;
const uint32_t kMaximumVersion = 13;
@@ -493,7 +656,7 @@ class Adapter {
LOOKUP_ALL(8, Terminate, OEMCrypto_Terminate);
if (!level1_valid_) {
M_RECORD(
&metrics,
metrics,
oemcrypto_initialization_mode_,
NO_TIME,
wvcdm::metrics::OEMCrypto_INITIALIZED_USING_L3_INVALID_L1);
@@ -503,7 +666,7 @@ class Adapter {
if (st != OEMCrypto_SUCCESS) {
LOGW("Could not initialize L1. Falling Back to L3.");
M_RECORD(
&metrics,
metrics,
oemcrypto_initialization_mode_,
NO_TIME,
wvcdm::metrics::OEMCrypto_INITIALIZED_USING_L3_COULD_NOT_INITIALIZE_L1);
@@ -511,7 +674,7 @@ class Adapter {
}
level1_.version = level1_.APIVersion();
M_RECORD(
&metrics,
metrics,
oemcrypto_l1_api_version_,
NO_TIME,
level1_.version,
@@ -520,7 +683,7 @@ class Adapter {
LOGW("liboemcrypto.so is version %d, not %d. Falling Back to L3.",
level1_.version, kMinimumVersion);
M_RECORD(
&metrics,
metrics,
oemcrypto_initialization_mode_,
NO_TIME,
wvcdm::metrics::OEMCrypto_INITIALIZED_USING_L3_WRONG_L1_VERSION);
@@ -598,7 +761,7 @@ class Adapter {
// If we have a valid keybox, initialization is done. We're good.
if (OEMCrypto_SUCCESS == level1_.IsKeyboxValid()) {
M_RECORD(
&metrics,
metrics,
oemcrypto_initialization_mode_,
NO_TIME,
wvcdm::metrics::OEMCrypto_INITIALIZED_USING_L1_WITH_KEYBOX);
@@ -610,7 +773,7 @@ class Adapter {
if (level1_.version > 11 &&
(level1_.GetProvisioningMethod() == OEMCrypto_OEMCertificate)) {
M_RECORD(
&metrics,
metrics,
oemcrypto_initialization_mode_,
NO_TIME,
wvcdm::metrics::OEMCrypto_INITIALIZED_USING_L1_WITH_PROVISIONING_3_0);
@@ -630,13 +793,13 @@ class Adapter {
LOGE("OEMCrypto uses cert as identification, but cdm does not!");
LOGE("This will not work on a production device.");
M_RECORD(
&metrics,
metrics,
oemcrypto_initialization_mode_,
NO_TIME,
wvcdm::metrics::OEMCrypto_INITIALIZED_USING_L1_CERTIFICATE_MIX);
} else {
M_RECORD(
&metrics,
metrics,
oemcrypto_initialization_mode_,
NO_TIME,
wvcdm::metrics::OEMCrypto_INITIALIZED_USING_L1_WITH_CERTIFICATE);
@@ -649,7 +812,7 @@ class Adapter {
LOGW("Bad Level 1 Keybox. Falling Back to L3.");
level1_.Terminate();
M_RECORD(
&metrics,
metrics,
oemcrypto_initialization_mode_,
NO_TIME,
wvcdm::metrics::OEMCrypto_INITIALIZED_USING_L3_BAD_KEYBOX);
@@ -661,7 +824,7 @@ class Adapter {
LOGW("Could not open %s. Falling Back to L3.", filename.c_str());
level1_.Terminate();
M_RECORD(
&metrics,
metrics,
oemcrypto_initialization_mode_,
NO_TIME,
wvcdm::metrics::OEMCrypto_INITIALIZED_USING_L3_COULD_NOT_OPEN_FACTORY_KEYBOX);
@@ -675,7 +838,7 @@ class Adapter {
filename.c_str());
level1_.Terminate();
M_RECORD(
&metrics,
metrics,
oemcrypto_initialization_mode_,
NO_TIME,
wvcdm::metrics::OEMCrypto_INITIALIZED_USING_L3_COULD_NOT_INSTALL_KEYBOX);
@@ -683,7 +846,7 @@ class Adapter {
}
LOGI("Installed keybox from %s", filename.c_str());
M_RECORD(
&metrics,
metrics,
oemcrypto_initialization_mode_,
NO_TIME,
wvcdm::metrics::OEMCrypto_INITIALIZED_USING_L1_INSTALLED_KEYBOX);
@@ -1156,18 +1319,26 @@ extern "C" OEMCryptoResult OEMCrypto_LoadKeys(
} else {
if (pair.fcn->LoadKeys_V9_or_V10 == NULL)
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
return pair.fcn->LoadKeys_V9_or_V10(pair.session, message, message_length,
signature, signature_length,
enc_mac_key_iv, enc_mac_key, num_keys,
&key_array_v10[0], pst, pst_length);
OEMCryptoResult result = pair.fcn->LoadKeys_V9_or_V10(
pair.session, message, message_length, signature, signature_length,
enc_mac_key_iv, enc_mac_key, num_keys, &key_array_v10[0], pst,
pst_length);
// Convert a vendor specific error, to make it actionable
if (result == kOemCryptoResultVendorSpecificError1)
result = OEMCrypto_ERROR_USAGE_TABLE_UNRECOVERABLE;
return result;
}
} else {
if (pair.fcn->version < 13) {
if (pair.fcn->LoadKeys_V11_or_V12 == NULL)
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
return pair.fcn->LoadKeys_V11_or_V12(
OEMCryptoResult result = pair.fcn->LoadKeys_V11_or_V12(
pair.session, message, message_length, signature, signature_length,
enc_mac_key_iv, enc_mac_key, num_keys, key_array, pst, pst_length);
// Convert a vendor specific error, to make it actionable
if (result == kOemCryptoResultVendorSpecificError1)
result = OEMCrypto_ERROR_USAGE_TABLE_UNRECOVERABLE;
return result;
} else {
if (pair.fcn->LoadKeys == NULL) return OEMCrypto_ERROR_NOT_IMPLEMENTED;
return pair.fcn->LoadKeys(pair.session, message, message_length,

View File

@@ -94,6 +94,7 @@ bool AesCbcKey::Encrypt(const std::string& in, std::string* out,
reinterpret_cast<uint8_t*>(&(*iv)[0])) == 0) {
LOGE("AesCbcKey::Encrypt: AES CBC setup failure: %s",
ERR_error_string(ERR_get_error(), NULL));
EVP_CIPHER_CTX_cleanup(&ctx);
return false;
}
@@ -105,6 +106,7 @@ bool AesCbcKey::Encrypt(const std::string& in, std::string* out,
in.size()) == 0) {
LOGE("AesCbcKey::Encrypt: encryption failure: %s",
ERR_error_string(ERR_get_error(), NULL));
EVP_CIPHER_CTX_cleanup(&ctx);
return false;
}
@@ -113,8 +115,10 @@ bool AesCbcKey::Encrypt(const std::string& in, std::string* out,
&padding) == 0) {
LOGE("AesCbcKey::Encrypt: PKCS7 padding failure: %s",
ERR_error_string(ERR_get_error(), NULL));
EVP_CIPHER_CTX_cleanup(&ctx);
return false;
}
EVP_CIPHER_CTX_cleanup(&ctx);
out->resize(out_length + padding);
return true;
@@ -178,6 +182,7 @@ bool RsaPublicKey::Encrypt(const std::string& clear_message,
return false;
}
FreeKey(key);
return true;
}
@@ -256,10 +261,15 @@ bool RsaPublicKey::VerifySignature(const std::string& message,
return false;
}
EVP_PKEY *pkey = EVP_PKEY_new();
if (pkey == NULL ||
EVP_PKEY_set1_RSA(pkey, rsa_key) != 1) {
if (pkey == NULL) {
LOGE("RsaPublicKey::VerifySignature: EVP_PKEY allocation failed");
FreeKey(rsa_key);
return false;
}
if (EVP_PKEY_set1_RSA(pkey, rsa_key) != 1) {
LOGE("RsaPublicKey::VerifySignature: failed to wrap key in an EVP_PKEY");
FreeKey(rsa_key);
EVP_PKEY_free(pkey);
return false;
}
FreeKey(rsa_key);

View File

@@ -5,7 +5,6 @@
#include "crypto_session.h"
#include "license.h"
#include "log.h"
#include "metrics_group.h"
namespace {
std::string kEmptyString;
@@ -139,7 +138,7 @@ CdmResponseType UsageTableHeader::UpdateEntry(CryptoSession* crypto_session,
CdmResponseType UsageTableHeader::DeleteEntry(uint32_t usage_entry_number,
DeviceFiles* handle,
metrics::MetricsGroup* metrics) {
metrics::CryptoMetrics* metrics) {
LOGV("UsageTableHeader::DeleteEntry: Lock");
AutoLock auto_lock(usage_table_header_lock_);
if (usage_entry_number >= usage_entry_info_.size())
@@ -188,14 +187,13 @@ CdmResponseType UsageTableHeader::DeleteEntry(uint32_t usage_entry_number,
number_of_entries_to_be_deleted =
usage_entry_info_.size() - swap_entry_number;
}
return Shrink(metrics, number_of_entries_to_be_deleted);
}
CdmResponseType UsageTableHeader::MoveEntry(
uint32_t from_usage_entry_number, const CdmUsageEntry& from_usage_entry,
uint32_t to_usage_entry_number, DeviceFiles* handle,
metrics::MetricsGroup* metrics) {
metrics::CryptoMetrics* metrics) {
LOGV("UsageTableHeader::MoveEntry");
// crypto_session points to an object whose scope is this method or a test
@@ -372,7 +370,7 @@ CdmResponseType UsageTableHeader::StoreEntry(uint32_t usage_entry_number,
}
CdmResponseType UsageTableHeader::Shrink(
metrics::MetricsGroup* metrics,
metrics::CryptoMetrics* metrics,
uint32_t number_of_usage_entries_to_delete) {
if (usage_entry_info_.empty()) {
LOGE("UsageTableHeader::Shrink: usage entry info table unexpectedly empty");
@@ -413,14 +411,14 @@ CdmResponseType UsageTableHeader::Shrink(
}
CdmResponseType UsageTableHeader::UpgradeFromUsageTable(
DeviceFiles* handle, metrics::MetricsGroup* metrics) {
DeviceFiles* handle, metrics::CryptoMetrics* metrics) {
UpgradeLicensesFromUsageTable(handle, metrics);
UpgradeUsageInfoFromUsageTable(handle, metrics);
return NO_ERROR;
}
bool UsageTableHeader::UpgradeLicensesFromUsageTable(
DeviceFiles* handle, metrics::MetricsGroup* metrics) {
DeviceFiles* handle, metrics::CryptoMetrics* metrics) {
// Fetch the key set IDs for each offline license. For each license
// * retrieve the provider session token,
// * create a new usage entry
@@ -509,7 +507,7 @@ bool UsageTableHeader::UpgradeLicensesFromUsageTable(
}
bool UsageTableHeader::UpgradeUsageInfoFromUsageTable(
DeviceFiles* handle, metrics::MetricsGroup* metrics) {
DeviceFiles* handle, metrics::CryptoMetrics* metrics) {
// Fetch all usage files. For each file retrieve all the usage info records
// within the file. For each piece of usage information
// * create a new usage entry

View File

@@ -12,6 +12,7 @@
#include "cdm_engine.h"
#include "config_test_env.h"
#include "initialization_data.h"
#include "file_store.h"
#include "license_request.h"
#include "log.h"
#include "OEMCryptoCENC.h"
@@ -118,6 +119,10 @@ class WvCdmEnginePreProvTest : public testing::Test {
virtual ~WvCdmEnginePreProvTest() {}
virtual void SetUp() {
session_opened_ = false;
}
virtual void OpenSession() {
CdmResponseType status =
cdm_engine_.OpenSession(g_key_system, NULL, NULL, &session_id_);
if (status == NEED_PROVISIONING) {
@@ -129,6 +134,12 @@ class WvCdmEnginePreProvTest : public testing::Test {
}
virtual void TearDown() {
if (cdm_engine_.IsProvisioned(kSecurityLevelL1)) {
cdm_engine_.Unprovision(kSecurityLevelL1);
}
if (cdm_engine_.IsProvisioned(kSecurityLevelL3)) {
cdm_engine_.Unprovision(kSecurityLevelL3);
}
if (session_opened_) {
cdm_engine_.CloseSession(session_id_);
session_opened_ = false;

View File

@@ -144,8 +144,7 @@ using ::testing::StrEq;
class CdmSessionTest : public ::testing::Test {
protected:
virtual void SetUp() {
service_cert_ = new ServiceCertificate;
cdm_session_.reset(new CdmSession(NULL));
cdm_session_.reset(new CdmSession(NULL, &metrics_));
// Inject testing mocks.
license_parser_ = new MockCdmLicense(cdm_session_->session_id());
cdm_session_->set_license_parser(license_parser_);
@@ -157,12 +156,18 @@ class CdmSessionTest : public ::testing::Test {
cdm_session_->set_file_handle(file_handle_);
}
virtual void TearDown() {
// Force the cdm_session_ to be deleted. This enforces a requirement that
// the CDM session metrics exist at least as long as the CDM session.
cdm_session_.reset();
}
metrics::SessionMetrics metrics_;
scoped_ptr<CdmSession> cdm_session_;
MockCdmLicense* license_parser_;
MockCryptoSession* crypto_session_;
MockPolicyEngine* policy_engine_;
MockDeviceFiles* file_handle_;
ServiceCertificate* service_cert_;
};
TEST_F(CdmSessionTest, InitWithBuiltInCertificate) {

View File

@@ -2780,7 +2780,7 @@ TEST_P(DeviceFilesUsageInfoTest, RetrieveByProviderSessionToken) {
std::string path = device_base_path_ + file_name;
size_t max_index_by_app_id = 0;
for (size_t i = 0; i <= sizeof(kUsageInfoTestData) / sizeof(UsageInfo); ++i) {
for (size_t i = 0; i < sizeof(kUsageInfoTestData) / sizeof(UsageInfo); ++i) {
if (app_id == kUsageInfoTestData[i].app_id) max_index_by_app_id = i;
}
std::string file_data =
@@ -2840,7 +2840,7 @@ TEST_P(DeviceFilesUsageInfoTest, UpdateUsageInfo) {
std::vector<std::string> usage_data_fields;
size_t max_index_by_app_id = 0;
for (size_t i = 0; i <= sizeof(kUsageInfoTestData) / sizeof(UsageInfo); ++i) {
for (size_t i = 0; i < sizeof(kUsageInfoTestData) / sizeof(UsageInfo); ++i) {
if (app_id == kUsageInfoTestData[i].app_id) {
max_index_by_app_id = i;

View File

@@ -7,6 +7,7 @@
#include <arpa/inet.h>
#include <gtest/gtest.h>
#include <memory>
#include <string>
#include "cdm_engine.h"
@@ -15,6 +16,7 @@
#include "log.h"
#include "oec_session_util.h"
#include "../../oemcrypto/mock/src/oemcrypto_key_mock.h"
#include "properties.h"
#include "string_conversions.h"
#include "url_request.h"
#include "wv_cdm_constants.h"
@@ -81,22 +83,21 @@ class WvGenericOperationsTest : public testing::Test {
virtual void SetUp() {
::testing::Test::SetUp();
ConfigTestEnv config(kContentProtectionStagingPlusProv30);
ConfigTestEnv config(kContentProtectionStagingLicense);
Properties::set_provisioning_messages_are_binary(false);
g_provisioning_service_certificate.assign(
config.provisioning_service_certificate());
g_license_service_certificate.assign(config.license_service_certificate());
g_provisioning_server.assign(config.provisioning_server());
cdm_engine_ = NULL;
// TODO(fredgc or gmorgan): This should be updated for provisioning 3.0
// Load test keybox. This keybox will be used by any CryptoSession
// created by the CDM under test.
ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_LoadTestKeybox());
// Perform CdmEngine setup
cdm_engine_ = new CdmEngine(&file_system_);
cdm_engine_.reset(new CdmEngine(&file_system_));
Provision();
@@ -124,7 +125,7 @@ class WvGenericOperationsTest : public testing::Test {
virtual void TearDown() {
oec_util_session_.close();
if (cdm_engine_ != NULL) {
if (cdm_engine_.get() != NULL) {
cdm_engine_->CloseSession(session_id_);
}
// OEMCrypto_Terminate() will be performed during the test class's
@@ -246,25 +247,12 @@ class WvGenericOperationsTest : public testing::Test {
LOGV("WvCdmEnginePreProvTest::Provision: http_message: \n%s\n",
http_message.c_str());
// extract provisioning response from received message
// Extracts signed response from JSON string, decodes base64 signed response
const std::string kMessageStart = "\"signedResponse\": \"";
const std::string kMessageEnd = "\"";
std::string base64_response;
EXPECT_TRUE (ExtractSignedMessage(http_message, kMessageStart, kMessageEnd,
&base64_response)) <<
"Failed to extract signed serialized response from JSON response";
LOGV("WvCdmEnginePreProvTest::Provision: extracted response "
"message: \n%s\n", base64_response.c_str());
ASSERT_EQ(NO_ERROR,
cdm_engine_->HandleProvisioningResponse(base64_response,
cdm_engine_->HandleProvisioningResponse(http_message,
&cert, &wrapped_key));
ASSERT_EQ(NO_ERROR,
cdm_engine_->SetServiceCertificate(
g_license_service_certificate));
cdm_engine_->SetServiceCertificate(g_license_service_certificate));
}
// This CryptoSession object handles Initialization and Termination
@@ -274,7 +262,7 @@ class WvGenericOperationsTest : public testing::Test {
CryptoSession crypto_session_;
FileSystem file_system_;
CdmEngine* cdm_engine_;
std::unique_ptr<CdmEngine> cdm_engine_;
std::string key_msg_;
std::string session_id_;
std::string server_url_;

View File

@@ -81,7 +81,6 @@ class MockCdmEventListener : public WvCdmEventListener {
class PolicyEngineConstraintsTest : public Test {
protected:
virtual void SetUp() {
mock_clock_ = new NiceMock<MockClock>();
current_time_ = 0;
policy_engine_.reset(new PolicyEngine(kSessionId, &mock_event_listener_,

View File

@@ -4,7 +4,6 @@
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <string>
#include "crypto_session.h"
#include "properties.h"
#include "string_conversions.h"
#include "wv_cdm_constants.h"
@@ -42,26 +41,9 @@ const std::string kTestSignedCertificate = a2bs_hex(
} // unnamed namespace
class MockCryptoSession : public CryptoSession {
public:
MockCryptoSession() : CryptoSession(NULL) { }
MOCK_METHOD2(GetRandom, bool(size_t, uint8_t*));
};
class ServiceCertificateTest : public ::testing::Test {
protected:
virtual void SetUp() { crypto_session_ = new MockCryptoSession(); }
virtual void TearDown() {
if (crypto_session_) delete crypto_session_;
}
void CreateServiceCertificate() {
service_certificate_ = new ServiceCertificate();
}
ServiceCertificate* service_certificate_;
MockCryptoSession* crypto_session_;
ServiceCertificate service_certificate_;
};
class StubCdmClientPropertySet : public CdmClientPropertySet {
@@ -78,11 +60,11 @@ class StubCdmClientPropertySet : public CdmClientPropertySet {
virtual bool use_privacy_mode() const { return use_privacy_mode_; }
virtual const std::string& service_certificate() const {
return service_certificate_;
return raw_service_certificate_;
}
virtual void set_service_certificate(const std::string& cert) {
service_certificate_ = cert;
raw_service_certificate_ = cert;
}
virtual bool is_session_sharing_enabled() const {
@@ -99,7 +81,7 @@ class StubCdmClientPropertySet : public CdmClientPropertySet {
private:
std::string security_level_;
std::string service_certificate_;
std::string raw_service_certificate_;
bool use_privacy_mode_;
bool is_session_sharing_enabled_;
uint32_t session_sharing_id_;
@@ -107,11 +89,8 @@ class StubCdmClientPropertySet : public CdmClientPropertySet {
};
TEST_F(ServiceCertificateTest, InitSuccess) {
MockCryptoSession crypto_session;
CreateServiceCertificate();
service_certificate_->Init(kTestSessionId1);
EXPECT_FALSE(service_certificate_->has_certificate());
service_certificate_.Init(kTestSessionId1);
EXPECT_FALSE(service_certificate_.has_certificate());
}
TEST_F(ServiceCertificateTest, InitPrivacyModeRequired) {
@@ -122,9 +101,8 @@ TEST_F(ServiceCertificateTest, InitPrivacyModeRequired) {
Properties::Init();
Properties::AddSessionPropertySet(kTestSessionId1, &property_set);
CreateServiceCertificate();
service_certificate_->Init(kTestSessionId1);
EXPECT_FALSE(service_certificate_->has_certificate());
service_certificate_.Init(kTestSessionId1);
EXPECT_FALSE(service_certificate_.has_certificate());
}
TEST_F(ServiceCertificateTest, InitServiceCertificatePresent) {
@@ -136,13 +114,12 @@ TEST_F(ServiceCertificateTest, InitServiceCertificatePresent) {
Properties::Init();
Properties::AddSessionPropertySet(kTestSessionId1, &property_set);
CreateServiceCertificate();
std::string service_certificate;
std::string raw_service_certificate;
EXPECT_TRUE(Properties::GetServiceCertificate(kTestSessionId1,
&service_certificate));
&raw_service_certificate));
EXPECT_EQ(NO_ERROR,
service_certificate_->Init(service_certificate));
EXPECT_TRUE(service_certificate_->has_certificate());
service_certificate_.Init(raw_service_certificate));
EXPECT_TRUE(service_certificate_.has_certificate());
}
TEST_F(ServiceCertificateTest, SetServiceCertificate) {
@@ -153,9 +130,8 @@ TEST_F(ServiceCertificateTest, SetServiceCertificate) {
Properties::Init();
Properties::AddSessionPropertySet(kTestSessionId1, &property_set);
CreateServiceCertificate();
EXPECT_EQ(NO_ERROR, service_certificate_->Init(kTestSignedCertificate));
EXPECT_TRUE(service_certificate_->has_certificate());
EXPECT_EQ(NO_ERROR, service_certificate_.Init(kTestSignedCertificate));
EXPECT_TRUE(service_certificate_.has_certificate());
}
}

View File

@@ -395,7 +395,7 @@ TEST_F(UsageTableHeaderTest, UpdateEntry) {
TEST_F(UsageTableHeaderTest, DeleteEntry_InvalidUsageEntryNumber) {
Init(kSecurityLevelL1, kUsageTableHeader, kUsageEntryInfoVector);
uint32_t usage_entry_number = kUsageEntryInfoVector.size();
metrics::MetricsGroup metrics;
metrics::CryptoMetrics metrics;
EXPECT_NE(NO_ERROR, usage_table_header_->DeleteEntry(
usage_entry_number, device_files_, &metrics));
@@ -426,7 +426,7 @@ TEST_F(UsageTableHeaderTest, DeleteEntry_CryptoSessionError) {
Init(kSecurityLevelL1, kUsageTableHeader, usage_entry_info_vector);
uint32_t usage_entry_number_to_be_deleted =
usage_entry_info_vector.size() - 1; // kUsageEntryInfoOfflineLicense2
metrics::MetricsGroup metrics;
metrics::CryptoMetrics metrics;
EXPECT_CALL(*crypto_session_, Open(kLevelDefault)).WillOnce(Return(NO_ERROR));
EXPECT_CALL(
@@ -462,7 +462,7 @@ TEST_F(UsageTableHeaderTest, DeleteEntry_LastOfflineEntry) {
Init(kSecurityLevelL1, kUsageTableHeader, usage_entry_info_vector);
uint32_t usage_entry_number_to_be_deleted =
usage_entry_info_vector.size() - 1; // kUsageEntryInfoOfflineLicense2
metrics::MetricsGroup metrics;
metrics::CryptoMetrics metrics;
EXPECT_CALL(*crypto_session_, Open(kLevelDefault)).WillOnce(Return(NO_ERROR));
EXPECT_CALL(
@@ -507,7 +507,7 @@ TEST_F(UsageTableHeaderTest, DeleteEntry_LastSecureStopEntry) {
Init(kSecurityLevelL1, kUsageTableHeader, usage_entry_info_vector);
uint32_t usage_entry_number_to_be_deleted =
usage_entry_info_vector.size() - 1; // kUsageEntryInfoSecureStop2
metrics::MetricsGroup metrics;
metrics::CryptoMetrics metrics;
EXPECT_CALL(*crypto_session_, Open(kLevelDefault)).WillOnce(Return(NO_ERROR));
EXPECT_CALL(
@@ -558,7 +558,7 @@ TEST_F(UsageTableHeaderTest,
Init(kSecurityLevelL1, kUsageTableHeader, usage_entry_info_vector);
uint32_t usage_entry_number_to_be_deleted =
usage_entry_info_vector.size() - 3; // kUsageEntryInfoOfflineLicense1
metrics::MetricsGroup metrics;
metrics::CryptoMetrics metrics;
device_files_->DeleteAllLicenses();
EXPECT_CALL(*crypto_session_, Open(kLevelDefault)).WillOnce(Return(NO_ERROR));
@@ -608,7 +608,7 @@ TEST_F(UsageTableHeaderTest, DeleteEntry_LastSecureStopEntriesAreMissing) {
Init(kSecurityLevelL1, kUsageTableHeader, usage_entry_info_vector);
uint32_t usage_entry_number_to_be_deleted =
usage_entry_info_vector.size() - 3; // kUsageEntryInfoSecureStop1
metrics::MetricsGroup metrics;
metrics::CryptoMetrics metrics;
EXPECT_CALL(*crypto_session_, Open(kLevelDefault)).WillOnce(Return(NO_ERROR));
EXPECT_CALL(
@@ -671,7 +671,7 @@ TEST_F(UsageTableHeaderTest,
Init(kSecurityLevelL1, kUsageTableHeader, usage_entry_info_vector);
uint32_t usage_entry_number_to_be_deleted =
usage_entry_info_vector.size() - 3; // kUsageEntryInfoOfflineLicense1
metrics::MetricsGroup metrics;
metrics::CryptoMetrics metrics;
EXPECT_TRUE(device_files_->StoreLicense(
usage_entry_info_vector[usage_entry_info_vector.size() - 1].key_set_id,
@@ -739,7 +739,7 @@ TEST_F(UsageTableHeaderTest,
usage_entry_info_vector.size() - 3; // kUsageEntryInfoSecureStop1
uint32_t usage_entry_number_after_deleted_entry =
usage_entry_number_to_be_deleted + 1;
metrics::MetricsGroup metrics;
metrics::CryptoMetrics metrics;
EXPECT_CALL(*crypto_session_, Open(kLevelDefault)).WillOnce(Return(NO_ERROR));
EXPECT_CALL(
@@ -812,7 +812,7 @@ TEST_F(UsageTableHeaderTest, DeleteEntry_LastEntriesAreStorageTypeUnknown) {
Init(kSecurityLevelL1, kUsageTableHeader, usage_entry_info_vector);
uint32_t usage_entry_number_to_be_deleted =
usage_entry_info_vector.size() - 3; // kUsageEntryInfoOfflineLicense3
metrics::MetricsGroup metrics;
metrics::CryptoMetrics metrics;
EXPECT_CALL(*crypto_session_, Open(kLevelDefault)).WillOnce(Return(NO_ERROR));
EXPECT_CALL(
@@ -867,7 +867,7 @@ TEST_F(UsageTableHeaderTest,
usage_entry_info_vector.size() - 3; // kUsageEntryInfoOfflineLicense1
uint32_t last_usage_entry_number =
usage_entry_info_vector.size() - 1; // kUsageEntryInfoOfflineLicense3
metrics::MetricsGroup metrics;
metrics::CryptoMetrics metrics;
EXPECT_TRUE(device_files_->StoreLicense(
usage_entry_info_vector[last_usage_entry_number].key_set_id,
@@ -933,7 +933,7 @@ TEST_F(UsageTableHeaderTest,
usage_entry_info_vector.size() - 3; // kUsageEntryInfoSecureStop1
uint32_t last_usage_entry_number =
usage_entry_info_vector.size() - 1; // kUsageEntryInfoSecureStop3
metrics::MetricsGroup metrics;
metrics::CryptoMetrics metrics;
EXPECT_CALL(*crypto_session_, Open(kLevelDefault)).WillOnce(Return(NO_ERROR));
EXPECT_CALL(*crypto_session_,
@@ -1007,7 +1007,7 @@ TEST_F(UsageTableHeaderTest,
usage_entry_info_vector.size() - 5; // kUsageEntryInfoOfflineLicense1
uint32_t last_valid_usage_entry_number =
usage_entry_info_vector.size() - 3; // kUsageEntryInfoOfflineLicense3
metrics::MetricsGroup metrics;
metrics::CryptoMetrics metrics;
EXPECT_TRUE(device_files_->StoreLicense(
usage_entry_info_vector[last_valid_usage_entry_number].key_set_id,
@@ -1085,7 +1085,7 @@ TEST_F(UsageTableHeaderTest,
usage_entry_info_vector.size() - 5; // kUsageEntryInfoOfflineLicense1
uint32_t last_valid_usage_entry_number =
usage_entry_info_vector.size() - 3; // kUsageEntryInfoOfflineLicense3
metrics::MetricsGroup metrics;
metrics::CryptoMetrics metrics;
EXPECT_CALL(*crypto_session_, Open(kLevelDefault))
.Times(2)
@@ -1157,7 +1157,7 @@ TEST_F(UsageTableHeaderTest, DeleteEntry_LastEntryIsOffline) {
usage_entry_info_vector.size() - 3; // kUsageEntryInfoOfflineLicense1
uint32_t last_usage_entry_number =
usage_entry_info_vector.size() - 1; // kUsageEntryInfoOfflineLicense3
metrics::MetricsGroup metrics;
metrics::CryptoMetrics metrics;
EXPECT_TRUE(device_files_->StoreLicense(
usage_entry_info_vector[last_usage_entry_number].key_set_id,
@@ -1271,7 +1271,7 @@ TEST_F(UsageTableHeaderTest, DeleteEntry_LastEntryIsSecureStop) {
usage_entry_info_vector.size() - 3; // kUsageEntryInfoSecureStop1
uint32_t last_usage_entry_number =
usage_entry_info_vector.size() - 1; // kUsageEntryInfoSecureStop3
metrics::MetricsGroup metrics;
metrics::CryptoMetrics metrics;
EXPECT_CALL(*crypto_session_, Open(kLevelDefault))
.Times(2)
@@ -1371,7 +1371,7 @@ TEST_F(UsageTableHeaderTest, DeleteEntry_LastEntriesAreOfflineAndUnknknown) {
usage_entry_info_vector.size() - 5; // kUsageEntryInfoOfflineLicense1
uint32_t last_valid_usage_entry_number =
usage_entry_info_vector.size() - 3; // kUsageEntryInfoOfflineLicense3
metrics::MetricsGroup metrics;
metrics::CryptoMetrics metrics;
EXPECT_TRUE(device_files_->StoreLicense(
usage_entry_info_vector[last_valid_usage_entry_number].key_set_id,
@@ -1490,7 +1490,7 @@ TEST_F(UsageTableHeaderTest, DeleteEntry_LastEntriesAreSecureStopAndUnknknown) {
usage_entry_info_vector.size() - 5; // kUsageEntryInfoSecureStop1
uint32_t last_valid_usage_entry_number =
usage_entry_info_vector.size() - 3; // kUsageEntryInfoSecureStop3
metrics::MetricsGroup metrics;
metrics::CryptoMetrics metrics;
EXPECT_CALL(*crypto_session_, Open(kLevelDefault))
.Times(2)