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

@@ -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)