Source release 14.2.0

This commit is contained in:
John W. Bruce
2018-10-12 19:55:47 -07:00
parent c32e8d0490
commit f51edaba5a
632 changed files with 196557 additions and 66444 deletions

View File

@@ -13,8 +13,7 @@
'../core/test/config_test_env.cpp',
'../core/test/crypto_session_unittest.cpp',
'../core/test/device_files_unittest.cpp',
# TODO(fredgc): generic tests don't work with prov 3.0.
# '../core/test/generic_crypto_unittest.cpp', # currently keybox only
'../core/test/generic_crypto_unittest.cpp',
'../core/test/http_socket.cpp',
'../core/test/initialization_data_unittest.cpp',
'../core/test/license_keys_unittest.cpp',
@@ -24,6 +23,7 @@
'../core/test/policy_engine_unittest.cpp',
'../core/test/service_certificate_unittest.cpp',
'../core/test/shared_ptr_test.cpp',
'../core/test/test_base.cpp',
'../core/test/test_printers.cpp',
'../core/test/url_request.cpp',
'../core/test/usage_table_header_unittest.cpp',

View File

@@ -269,6 +269,13 @@ class CDM_EXPORT Cdm : public ITimerClient {
// A timer interface provided by the application, independent of CDM
// instances.
// See Cdm::initialize().
// Implementations of this class only need to deal with at most one
// outstanding timer per IClient at a time. It is an error for setTimeout() to
// be called while there is already a timer running for that client. It is
// recommended for implementers of this class to cancel the preexisting timer
// and start the new timer if this erroneous situation occurs.
// Timers are non-repeating. If the CDM wants to repeat a timer, it will call
// setTimeout() again inside the timeout callback.
class ITimer {
public:
// This typedef is for backward compatibility with v3.0.0.
@@ -279,7 +286,7 @@ class CDM_EXPORT Cdm : public ITimerClient {
IClient* client,
void* context) = 0;
// Cancel all timers associated with |client|.
// Cancel the timer associated with |client|.
virtual void cancel(IClient *client) = 0;
protected:
@@ -344,9 +351,9 @@ class CDM_EXPORT Cdm : public ITimerClient {
// |storage| defines the storage to use for this instance. By providing
// different objects here for different origins, this parameter can be used to
// provide per-origin storage. It may not be NULL.
// If |privacy_mode| is true, server certificates are required and will be
// If |privacy_mode| is true, service certificates are required and will be
// used to encrypt messages to the license server.
// By using server certificates to encrypt communication with the license
// By using service certificates to encrypt communication with the license
// server, device-identifying information cannot be extracted from the
// license exchange process by an intermediate layer between the CDM and
// the server.
@@ -358,31 +365,39 @@ class CDM_EXPORT Cdm : public ITimerClient {
virtual ~Cdm() {}
// Sets up a service certificate for the CDM. It is used to encrypt
// outgoing messages (the ClientIdentification portion of the license and
// provisioning requests). It also holds the provider ID setting, used in
// the provisioning request.
// If setServiceCertificate() is not called, provider ID will not be set
// in the provisioning request. If this function is not called and
// privacy mode is enabled, a service certificate request will be initiated
// as a preliminary step in the license request.
// The following three methods relate to service certificates. The service
// certificate holds the RSA public key for the server and other fields needed
// for provisioning. It is mandatory if privacy mode is turned on, as it
// is used to encrypt portions of outgoing messages.
// If a certificate has not been installed before generating a provisioning
// request, a default certificate that only works with the Widevine-hosted
// provisioning service will be used.
// It is an error to generate a license request while privacy mode is turned
// on without installing a service certificate first.
// Installs a service certificate from a data buffer.
// This is used when the system or application already knows the certificate
// of the service it wishes to communicate with, either because it is baked
// into the software or because it was previously cached after a call to
// parseServiceCertificateResponse().
virtual Status setServiceCertificate(const std::string& certificate) = 0;
// Create a Service Certificate Request message.
// Generate a Service Certificate Request message.
// This is used to fetch a service certificate from the license server.
// It is needed in cases where the system or application does not have
// a service certificate for the license server.
// The service certificate holds the RSA public key for the server and
// other fields needed for provisioning. It is also needed for privacy mode.
// a service certificate for the license server already.
virtual Status getServiceCertificateRequest(std::string* message) = 0;
// Parse a Service Certificate Response message and extract the certificate.
// Parse a Service Certificate Response message, installing and extracting the
// certificate.
// This is used when fetching a service certificate from the license server.
// The response input is the string returned by the license server
// (see getServiceCertificateRequest()). The service certificate is installed
// if no error is returned. The returned certificate string may be used in
// future sessions as the input to setServiceCertificate(), avoiding extra
// calls to the license server.
// A request should be generated by getServiceCertificateRequest() and sent
// to the license server. The server's response should be passed into this
// method,
// The service certificate is installed if no error is returned. The returned
// certificate string may be used in future sessions as the input to
// setServiceCertificate(), to avoid needing to make a call to the license
// server to get the certificate.
virtual Status parseServiceCertificateResponse(const std::string& response,
std::string* certificate) = 0;

View File

@@ -1,3 +1,3 @@
// Widevine CE CDM Version
#define CDM_VERSION "14.1.2"
#define CDM_VERSION "14.2.0"
#define EME_VERSION "https://www.w3.org/TR/2017/REC-encrypted-media-20170918"

View File

@@ -20,6 +20,7 @@
#include "log.h"
#include "metrics_collections.h"
#include "properties.h"
#include "scoped_ptr.h"
#include "service_certificate.h"
#include "string_conversions.h"
#include "wv_cdm_constants.h"
@@ -1123,7 +1124,8 @@ Cdm::Status CdmImpl::decrypt(const InputBuffer& input,
return kSuccess;
}
if (result == NEED_KEY || result == SESSION_NOT_FOUND_FOR_DECRYPT) {
if (result == NEED_KEY || result == KEY_NOT_FOUND_3 ||
result == SESSION_NOT_FOUND_FOR_DECRYPT) {
LOGE("Key not available.");
return kNoKey;
}
@@ -1409,8 +1411,9 @@ Cdm::Status CdmImpl::ConvertHdcpLevel(const std::string& query_value,
bool VerifyL1() {
metrics::CryptoMetrics throwaway_metrics;
CryptoSession cs(&throwaway_metrics);
return cs.GetSecurityLevel() == kSecurityLevelL1;
scoped_ptr<CryptoSession> cs(
CryptoSession::MakeCryptoSession(&throwaway_metrics));
return cs->GetSecurityLevel() == kSecurityLevelL1;
}
} // namespace

View File

@@ -14,13 +14,16 @@
#include "decryption_test_data.h"
#include "license_request.h"
#include "log.h"
#include "oec_device_features.h"
#include "OEMCryptoCENC.h"
#include "override.h"
#include "properties_ce.h"
#include "scoped_ptr.h"
#include "service_certificate.h"
#include "string_conversions.h"
#include "test_base.h"
#include "test_host.h"
#include "test_printers.h"
#include "url_request.h"
using namespace testing;
@@ -40,11 +43,6 @@ const Cdm::SessionType kBogusSessionType = static_cast<Cdm::SessionType>(-1);
const Cdm::InitDataType kBogusInitDataType = static_cast<Cdm::InitDataType>(-1);
const std::string kBogusSessionId = "asdf";
std::string g_provisioning_server;
std::string g_provisioning_service_certificate;
std::string g_license_server;
std::string g_license_service_certificate;
const std::string kCencInitData = a2bs_hex(
"00000042" // blob size
"70737368" // "pssh"
@@ -189,8 +187,7 @@ const std::string kNewValue = "A New Value";
const std::string kParamName = "PARAM";
const std::string kParamName2 = "PARAM2";
class CdmTest : public Test, public Cdm::IEventListener {
class CdmTest : public WvCdmTestBase, public Cdm::IEventListener {
public:
CdmTest() {}
virtual ~CdmTest() {}
@@ -212,29 +209,11 @@ class CdmTest : public Test, public Cdm::IEventListener {
protected:
virtual void SetUp() OVERRIDE {
ConfigTestEnv config(kContentProtectionUatServer);
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());
g_license_server.assign(config.license_server());
WvCdmTestBase::SetUp();
// Clear anything stored, load default device cert.
g_host->Reset();
// Clear anything stored by OEMCrypto.
ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_Initialize());
int result = OEMCrypto_DeleteOldUsageTable(); // TODO(fredgc): update this.
// Don't fault OEMCrypto implementations without usage tables:
if (result != OEMCrypto_ERROR_NOT_IMPLEMENTED) {
EXPECT_EQ(OEMCrypto_SUCCESS, result);
}
std::string oec_level = OEMCrypto_SecurityLevel();
is_oec_l1_ = (oec_level == "L1");
ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_Terminate());
// Reinit the library.
Cdm::Status status = Cdm::initialize(
Cdm::kNoSecureOutput, PropertiesCE::GetClientInfo(),
@@ -245,21 +224,11 @@ class CdmTest : public Test, public Cdm::IEventListener {
RecreateCdm(true /* privacy_mode */);
}
virtual void TearDown() OVERRIDE {
// So the OEMCrypto nonce flood check does not trigger.
// A 500ms delay allows up to 10 nonces to be generated per test without
// triggering an OEMCrypto error.
usleep(500 * 1000);
}
virtual void Provision() {
cdm_->removeProvisioning();
cdm_->setServiceCertificate(g_provisioning_service_certificate);
}
virtual void TearDown() OVERRIDE { }
void RecreateCdm(bool privacy_mode) {
CreateAdditionalCdm(privacy_mode, &cdm_);
cdm_->setServiceCertificate(g_license_service_certificate);
cdm_->setServiceCertificate(config_.license_service_certificate());
}
void CreateAdditionalCdm(bool privacy_mode, scoped_ptr<Cdm>* cdm) {
@@ -350,7 +319,7 @@ class CdmTest : public Test, public Cdm::IEventListener {
void FetchLicenseFailure(const std::string& message,
int expected_status_code) {
int status_code;
bool ok = Fetch(g_license_server, message, NULL, &status_code);
bool ok = Fetch(config_.license_server(), message, NULL, &status_code);
ASSERT_TRUE(ok);
if (ok) ASSERT_EQ(expected_status_code, status_code);
}
@@ -360,7 +329,7 @@ class CdmTest : public Test, public Cdm::IEventListener {
std::string* session_id,
std::string* message) {
Cdm::Status status;
status = cdm_->setServiceCertificate(g_license_service_certificate);
status = cdm_->setServiceCertificate(config_.license_service_certificate());
ASSERT_EQ(Cdm::kSuccess, status);
status = cdm_->createSession(session_type, session_id);
@@ -398,9 +367,9 @@ class CdmTest : public Test, public Cdm::IEventListener {
std::string license_server;
if (init_data_type == Cdm::kCenc) {
license_server = g_license_server;
license_server = config_.license_server();
} else if (init_data_type == Cdm::kHls) {
license_server = g_license_server;
license_server = config_.license_server();
}
ASSERT_FALSE(license_server.empty());
FetchLicense(license_server, message, response);
@@ -423,7 +392,7 @@ class CdmTest : public Test, public Cdm::IEventListener {
// Acquire a license.
std::string response;
ASSERT_NO_FATAL_FAILURE(FetchLicense(
g_license_server, message, &response));
config_.license_server(), message, &response));
// This license should be accepted, but the keys are not expected to change.
EXPECT_CALL(*this, onKeyStatusesChange(session_id, _)).Times(0);
@@ -434,7 +403,7 @@ class CdmTest : public Test, public Cdm::IEventListener {
std::string GetProvisioningResponse(const std::string& message) {
std::string reply;
std::string uri = g_provisioning_server;
std::string uri = config_.provisioning_server();
LOGV("GetProvisioningResponse: URI: %s", uri.c_str());
LOGV("GetProvisioningResponse: message:\n%s\n", b2a_hex(message).c_str());
@@ -486,7 +455,6 @@ class CdmTest : public Test, public Cdm::IEventListener {
}
scoped_ptr<Cdm> cdm_;
bool is_oec_l1_;
};
@@ -528,6 +496,10 @@ class CdmTestWithDecryptParam : public CdmTest,
public WithParamInterface<DecryptParam> {};
class CdmTestWithRemoveParam : public CdmTest,
public WithParamInterface<bool> {};
class MockTimerClient : public Cdm::ITimer::IClient {
public:
MockTimerClient() {}
@@ -643,7 +615,7 @@ TEST_F(CdmTest, Initialize) {
status = Cdm::initialize(
Cdm::kOpaqueHandle, working_client_info,
g_host, g_host, g_host, static_cast<Cdm::LogLevel>(g_cutoff));
if (is_oec_l1_) {
if (wvoec::global_features.supports_level_1) {
EXPECT_EQ(Cdm::kSuccess, status);
} else {
EXPECT_EQ(Cdm::kNotSupported, status);
@@ -713,12 +685,12 @@ TEST_F(CdmTest, SetServiceCertificate) {
// Set a server certificate with privacy mode disabled - should work.
ASSERT_NO_FATAL_FAILURE(RecreateCdm(false /* privacy_mode */));
Cdm::Status status =
cdm_->setServiceCertificate(g_license_service_certificate);
cdm_->setServiceCertificate(config_.license_service_certificate());
EXPECT_EQ(Cdm::kSuccess, status);
// Can set a server certificate if privacy mode is enabled.
ASSERT_NO_FATAL_FAILURE(RecreateCdm(true /* privacy_mode */));
status = cdm_->setServiceCertificate(g_license_service_certificate);
status = cdm_->setServiceCertificate(config_.license_service_certificate());
EXPECT_EQ(Cdm::kSuccess, status);
// It is invalid to set a malformed cert.
@@ -734,7 +706,7 @@ TEST_F(CdmTest, Provision) {
// Creating a session should succeed.
std::string session_id;
Cdm::Status status;
status = cdm_->setServiceCertificate(g_provisioning_service_certificate);
status = cdm_->setServiceCertificate(config_.provisioning_service_certificate());
EXPECT_EQ(Cdm::kSuccess, status);
status = cdm_->createSession(Cdm::kTemporary, &session_id);
EXPECT_EQ(Cdm::kSuccess, status);
@@ -785,9 +757,10 @@ TEST_F(CdmTest, CreateSession) {
}
TEST_F(CdmTest, GenerateRequest) {
EnsureProvisioned();
std::string session_id;
Cdm::Status status;
status = cdm_->setServiceCertificate(g_license_service_certificate);
status = cdm_->setServiceCertificate(config_.license_service_certificate());
ASSERT_EQ(Cdm::kSuccess, status);
status = cdm_->createSession(Cdm::kTemporary, &session_id);
@@ -878,10 +851,11 @@ TEST_F(CdmTest, GenerateRequest) {
}
TEST_F(CdmTest, Update) {
EnsureProvisioned();
std::string session_id;
std::string message;
Cdm::Status status;
status = cdm_->setServiceCertificate(g_license_service_certificate);
status = cdm_->setServiceCertificate(config_.license_service_certificate());
ASSERT_EQ(Cdm::kSuccess, status);
ASSERT_NO_FATAL_FAILURE(CreateSessionAndGenerateRequest(
@@ -890,7 +864,7 @@ TEST_F(CdmTest, Update) {
// Acquire a license.
std::string response;
ASSERT_NO_FATAL_FAILURE(FetchLicense(
g_license_server, message, &response));
config_.license_server(), message, &response));
// Update the session.
EXPECT_CALL(*this, onKeyStatusesChange(session_id, true));
@@ -914,6 +888,7 @@ TEST_F(CdmTest, Update) {
}
TEST_F(CdmTest, Close) {
EnsureProvisioned();
// Create a temporary session.
std::string session_id;
Cdm::Status status = cdm_->createSession(Cdm::kTemporary, &session_id);
@@ -939,10 +914,11 @@ TEST_F(CdmTest, Close) {
}
TEST_F(CdmTest, LoadTemporary) {
EnsureProvisioned();
std::string session_id;
std::string response;
Cdm::Status status;
status = cdm_->setServiceCertificate(g_license_service_certificate);
status = cdm_->setServiceCertificate(config_.license_service_certificate());
ASSERT_EQ(Cdm::kSuccess, status);
ASSERT_NO_FATAL_FAILURE(CreateSessionAndFetchLicense(
@@ -964,6 +940,7 @@ TEST_F(CdmTest, LoadTemporary) {
}
TEST_F(CdmTest, LoadPersistent) {
EnsureProvisioned();
std::string session_id;
std::string response;
Cdm::Status status;
@@ -996,6 +973,7 @@ TEST_F(CdmTest, LoadPersistent) {
status = cdm_->close(session_id);
ASSERT_EQ(Cdm::kSuccess, status);
g_host->Reset();
EnsureProvisioned();
EXPECT_CALL(*this, onKeyStatusesChange(session_id, _)).Times(0);
status = cdm_->load(session_id);
EXPECT_EQ(Cdm::kSessionNotFound, status);
@@ -1003,6 +981,7 @@ TEST_F(CdmTest, LoadPersistent) {
}
TEST_F(CdmTest, LoadWillFireExpiration) {
EnsureProvisioned();
// There was a bug where calling load() would not start the PolicyEngine timer
// because it was only started in update().
std::string session_id;
@@ -1025,6 +1004,7 @@ TEST_F(CdmTest, LoadWillFireExpiration) {
// TODO(b/110802394): Fix this test or remove auto-provisioning.
TEST_F(CdmTest, DISABLED_PerOriginLoadPersistent) {
EnsureProvisioned();
std::string session_id;
std::string response;
ASSERT_NO_FATAL_FAILURE(CreateSessionAndFetchLicense(
@@ -1046,7 +1026,7 @@ TEST_F(CdmTest, DISABLED_PerOriginLoadPersistent) {
scoped_ptr<Cdm> other_cdm(
Cdm::create(this, &other_host, /* privacy_mode */ true));
ASSERT_TRUE(other_cdm.get());
status = other_cdm->setServiceCertificate(g_license_service_certificate);
status = other_cdm->setServiceCertificate(config_.license_service_certificate());
ASSERT_EQ(Cdm::kSuccess, status);
// Should not be able to load from another origin.
@@ -1212,12 +1192,14 @@ TEST_F(CdmTest, DISABLED_ListUsageRecords) {
}
TEST_F(CdmTest, LoadBogus) {
EnsureProvisioned();
EXPECT_CALL(*this, onKeyStatusesChange(_, _)).Times(0);
Cdm::Status status = cdm_->load(kBogusSessionId);
EXPECT_EQ(Cdm::kSessionNotFound, status);
}
TEST_F(CdmTest, GetKeyStatuses) {
EnsureProvisioned();
std::string session_id;
ASSERT_NO_FATAL_FAILURE(CreateSessionAndUpdate(
Cdm::kTemporary, Cdm::kCenc, &session_id));
@@ -1253,6 +1235,7 @@ TEST_F(CdmTest, GetKeyStatuses) {
}
TEST_F(CdmTest, GetExpiration) {
EnsureProvisioned();
std::string session_id;
ASSERT_NO_FATAL_FAILURE(CreateSessionAndUpdate(
Cdm::kTemporary, Cdm::kCenc, &session_id));
@@ -1285,7 +1268,10 @@ TEST_F(CdmTest, GetExpiration) {
ASSERT_EQ(Cdm::kSessionNotFound, status);
}
TEST_F(CdmTest, Remove) {
TEST_P(CdmTestWithRemoveParam, Remove) {
const bool intermediate_close = GetParam();
EnsureProvisioned();
std::string session_id;
ASSERT_NO_FATAL_FAILURE(CreateSessionAndUpdate(
Cdm::kPersistentLicense, Cdm::kCenc, &session_id));
@@ -1305,10 +1291,22 @@ TEST_F(CdmTest, Remove) {
ASSERT_EQ(Cdm::kSuccess, status);
EXPECT_EQ(Cdm::kReleased, map.begin()->second);
// If we are testing intermediate closing, close the session.
if (intermediate_close) {
status = cdm_->close(session_id);
ASSERT_EQ(Cdm::kSuccess, status);
}
// Post the release message to the license server.
std::string response;
ASSERT_NO_FATAL_FAILURE(FetchLicense(
g_license_server, message, &response));
config_.license_server(), message, &response));
// If we are testing intermediate closing, reopen the session.
if (intermediate_close) {
status = cdm_->load(session_id);
ASSERT_EQ(Cdm::kSuccess, status);
}
// Update the session.
EXPECT_CALL(*this, onRemoveComplete(session_id));
@@ -1339,7 +1337,11 @@ TEST_F(CdmTest, Remove) {
EXPECT_EQ(Cdm::kRangeError, status);
}
INSTANTIATE_TEST_CASE_P(CdmRemoveTest, CdmTestWithRemoveParam, Bool(),
testing::PrintToStringParamName());
TEST_F(CdmTest, ForceRemove) {
EnsureProvisioned();
std::string session_id;
ASSERT_NO_FATAL_FAILURE(CreateSessionAndUpdate(
Cdm::kPersistentLicense, Cdm::kCenc, &session_id));
@@ -1376,6 +1378,7 @@ TEST_F(CdmTest, ForceRemove) {
}
TEST_F(CdmTest, RemoveUsageRecord) {
EnsureProvisioned();
std::string session_id;
ASSERT_NO_FATAL_FAILURE(CreateSessionAndUpdate(
Cdm::kPersistentUsageRecord, Cdm::kCenc, &session_id));
@@ -1398,7 +1401,7 @@ TEST_F(CdmTest, RemoveUsageRecord) {
// Post the release message to the license server.
std::string response;
ASSERT_NO_FATAL_FAILURE(FetchLicense(
g_license_server, message, &response));
config_.license_server(), message, &response));
// Update the session.
EXPECT_CALL(*this, onRemoveComplete(session_id));
@@ -1412,6 +1415,7 @@ TEST_F(CdmTest, RemoveUsageRecord) {
}
TEST_F(CdmTest, RemoveIncomplete) {
EnsureProvisioned();
std::string session_id;
ASSERT_NO_FATAL_FAILURE(CreateSessionAndUpdate(
Cdm::kPersistentLicense, Cdm::kCenc, &session_id));
@@ -1460,7 +1464,7 @@ TEST_F(CdmTest, RemoveIncomplete) {
// Post the release message to the license server.
std::string response;
ASSERT_NO_FATAL_FAILURE(FetchLicense(
g_license_server, message, &response));
config_.license_server(), message, &response));
// Update the session.
EXPECT_CALL(*this, onKeyStatusesChange(session_id, _)).Times(0);
@@ -1475,6 +1479,7 @@ TEST_F(CdmTest, RemoveIncomplete) {
}
TEST_F(CdmTest, RemoveUsageRecordIncomplete) {
EnsureProvisioned();
std::string session_id;
ASSERT_NO_FATAL_FAILURE(CreateSessionAndUpdate(
Cdm::kPersistentUsageRecord, Cdm::kCenc, &session_id));
@@ -1523,7 +1528,7 @@ TEST_F(CdmTest, RemoveUsageRecordIncomplete) {
// Post the release message to the license server.
std::string response;
ASSERT_NO_FATAL_FAILURE(FetchLicense(
g_license_server, message, &response));
config_.license_server(), message, &response));
// Update the session.
EXPECT_CALL(*this, onKeyStatusesChange(session_id, _)).Times(0);
@@ -1538,6 +1543,7 @@ TEST_F(CdmTest, RemoveUsageRecordIncomplete) {
}
TEST_F(CdmTest, RemoveNotLoaded) {
EnsureProvisioned();
// Create a persistent session and then close it.
std::string session_id;
ASSERT_NO_FATAL_FAILURE(CreateSessionAndUpdate(
@@ -1552,11 +1558,12 @@ TEST_F(CdmTest, RemoveNotLoaded) {
}
TEST_F(CdmTest, RequestPersistentLicenseWithWrongInitData) {
EnsureProvisioned();
// Generate a request for a persistent license without using the correct
// persistent content init data.
std::string session_id;
Cdm::Status status;
status = cdm_->setServiceCertificate(g_license_service_certificate);
status = cdm_->setServiceCertificate(config_.license_service_certificate());
ASSERT_EQ(Cdm::kSuccess, status);
status = cdm_->createSession(Cdm::kPersistentLicense, &session_id);
ASSERT_EQ(Cdm::kSuccess, status);
@@ -1574,10 +1581,11 @@ TEST_F(CdmTest, RequestPersistentLicenseWithWrongInitData) {
// TODO(b/34949512): Fix this test so it can be re-enabled.
TEST_F(CdmTest, DISABLED_RequestTemporaryLicenseWithWrongInitData) {
EnsureProvisioned();
// Generate a request for a temporary license using persistent init data.
std::string session_id;
Cdm::Status status;
status = cdm_->setServiceCertificate(g_license_service_certificate);
status = cdm_->setServiceCertificate(config_.license_service_certificate());
ASSERT_EQ(Cdm::kSuccess, status);
status = cdm_->createSession(Cdm::kTemporary, &session_id);
ASSERT_EQ(Cdm::kSuccess, status);
@@ -1593,7 +1601,7 @@ TEST_F(CdmTest, DISABLED_RequestTemporaryLicenseWithWrongInitData) {
// Acquire a license.
std::string response;
ASSERT_NO_FATAL_FAILURE(FetchLicense(
g_license_server, message, &response));
config_.license_server(), message, &response));
// This license should not be accepted.
EXPECT_CALL(*this, onKeyStatusesChange(session_id, false));
@@ -1603,6 +1611,7 @@ TEST_F(CdmTest, DISABLED_RequestTemporaryLicenseWithWrongInitData) {
}
TEST_F(CdmTest, Renewal) {
EnsureProvisioned();
std::string session_id;
ASSERT_NO_FATAL_FAILURE(CreateSessionAndUpdate(
Cdm::kTemporary, Cdm::kCenc, &session_id));
@@ -1634,6 +1643,7 @@ TEST_F(CdmTest, Renewal) {
}
TEST_F(CdmTest, SetAppParameters) {
EnsureProvisioned();
// Must use privacy_mode = false to ensure that the message is in plain-text.
std::string session_id;
ASSERT_NO_FATAL_FAILURE(RecreateCdm(false /* privacy_mode */));
@@ -1714,6 +1724,7 @@ TEST_F(CdmTest, SetAppParameters) {
}
TEST_F(CdmTest, SetVideoResolutionBadSession) {
EnsureProvisioned();
std::string session_id;
ASSERT_NO_FATAL_FAILURE(CreateSessionAndUpdate(
Cdm::kTemporary, Cdm::kCenc, &session_id));
@@ -1725,6 +1736,7 @@ TEST_F(CdmTest, SetVideoResolutionBadSession) {
}
TEST_F(CdmTest, SetVideoResolutionOK) {
EnsureProvisioned();
std::string session_id;
ASSERT_NO_FATAL_FAILURE(CreateSessionAndUpdate(
Cdm::kTemporary, Cdm::kCenc, &session_id));
@@ -1736,6 +1748,7 @@ TEST_F(CdmTest, SetVideoResolutionOK) {
}
TEST_F(CdmTest, SetVideoResolutionOverflow) {
EnsureProvisioned();
std::string session_id;
ASSERT_NO_FATAL_FAILURE(CreateSessionAndUpdate(
Cdm::kTemporary, Cdm::kCenc, &session_id));
@@ -1772,6 +1785,7 @@ TEST_F(CdmTest, GetStatusForHdcpResolution) {
}
TEST_F(CdmTest, HandlesKeyRotationWithOnlyOneLicenseRequest) {
EnsureProvisioned();
std::string session_id;
// TODO(b/77152154):
@@ -1779,7 +1793,7 @@ TEST_F(CdmTest, HandlesKeyRotationWithOnlyOneLicenseRequest) {
// them.
ASSERT_EQ(Cdm::kSuccess,
cdm_->setServiceCertificate(g_license_service_certificate));
cdm_->setServiceCertificate(config_.license_service_certificate()));
ASSERT_EQ(Cdm::kSuccess,
cdm_->createSession(Cdm::kTemporary, &session_id));
@@ -1797,7 +1811,7 @@ TEST_F(CdmTest, HandlesKeyRotationWithOnlyOneLicenseRequest) {
// Send the request to the license server and receive the license response.
std::string license_response;
FetchLicense(g_license_server, license_request, &license_response);
FetchLicense(config_.license_server(), license_request, &license_response);
// Update the session with the new keys.
{
@@ -1849,8 +1863,8 @@ TEST_F(CdmTest, HandlesKeyRotationWithOnlyOneLicenseRequest) {
EXPECT_EQ(kOutputEntitlement1, output_buffer);
}
// TODO(http://b/37286053): Fix this test.
TEST_P(CdmTestWithDecryptParam, DecryptToClearBuffer) {
EnsureProvisioned();
DecryptParam param = GetParam();
Cdm::InputBuffer input;
@@ -1907,26 +1921,17 @@ INSTANTIATE_TEST_CASE_P(CdmDecryptTest, CdmTestWithDecryptParam, Values(
class CdmIndividualizationTest : public CdmTest {
protected:
bool CheckProvisioningSupport() {
uint32_t nonce = 0;
uint8_t buffer[1];
size_t size = 0;
EXPECT_EQ(OEMCrypto_SUCCESS, OEMCrypto_Initialize());
int result = OEMCrypto_RewrapDeviceRSAKey(0, buffer, 0, buffer, 0, &nonce,
buffer, 0, buffer, buffer, &size);
EXPECT_EQ(OEMCrypto_SUCCESS, OEMCrypto_Terminate());
if (result == OEMCrypto_ERROR_NOT_IMPLEMENTED) {
LOGW(
"WARNING: Skipping PerOriginDeviceProvisioning because the device "
"does not support provisioning. If you are using a baked-in "
"certificate, this is expected. Otherwise, something is wrong.");
return false;
}
return true;
if (wvoec::global_features.loads_certificate) return true;
LOGW(
"WARNING: Skipping PerOriginDeviceProvisioning because the device "
"does not support provisioning. If you are using a baked-in "
"certificate, this is expected. Otherwise, something is wrong.");
return false;
}
std::string GetProvisioningResponse(const std::string& message) {
std::string reply;
std::string uri = g_provisioning_server;
std::string uri = config_.provisioning_server();
LOGV("GetProvisioningResponse: URI: %s", uri.c_str());
LOGV("GetProvisioningResponse: message:\n%s\n", message.c_str());
@@ -1951,7 +1956,7 @@ TEST_F(CdmIndividualizationTest, BasicFlow) {
// Provision the device
Cdm::Status status =
cdm_->setServiceCertificate(g_provisioning_service_certificate);
cdm_->setServiceCertificate(config_.provisioning_service_certificate());
EXPECT_EQ(Cdm::kSuccess, status);
std::string message;
status = cdm_->getProvisioningRequest(&message);
@@ -1963,14 +1968,14 @@ TEST_F(CdmIndividualizationTest, BasicFlow) {
// We should now be able to create a session and generate a request.
std::string session_id;
status = cdm_->setServiceCertificate(g_license_service_certificate);
status = cdm_->setServiceCertificate(config_.license_service_certificate());
EXPECT_EQ(Cdm::kSuccess, status);
ASSERT_NO_FATAL_FAILURE(CreateSessionAndGenerateRequest(
Cdm::kTemporary, Cdm::kCenc, &session_id, &message));
// Acquire a license and update the session.
ASSERT_NO_FATAL_FAILURE(FetchLicense(
g_license_server, message, &reply));
config_.license_server(), message, &reply));
EXPECT_CALL(*this, onKeyStatusesChange(session_id, true));
status = updateWithRetry(session_id, reply);
EXPECT_EQ(Cdm::kSuccess, status);
@@ -1987,7 +1992,7 @@ TEST_F(CdmIndividualizationTest, IsProvisioned) {
// Provision the device
Cdm::Status status =
cdm_->setServiceCertificate(g_provisioning_service_certificate);
cdm_->setServiceCertificate(config_.provisioning_service_certificate());
EXPECT_EQ(Cdm::kSuccess, status);
std::string message;
status = cdm_->getProvisioningRequest(&message);
@@ -2011,7 +2016,7 @@ TEST_F(CdmIndividualizationTest, RemoveProvisioning) {
// Provision the device
Cdm::Status status =
cdm_->setServiceCertificate(g_provisioning_service_certificate);
cdm_->setServiceCertificate(config_.provisioning_service_certificate());
EXPECT_EQ(Cdm::kSuccess, status);
std::string message;
status = cdm_->getProvisioningRequest(&message);
@@ -2037,7 +2042,7 @@ TEST_F(CdmIndividualizationTest, HandlesAutomaticProvisioning) {
// Creating a session should succeed.
std::string session_id;
Cdm::Status status =
cdm_->setServiceCertificate(g_provisioning_service_certificate);
cdm_->setServiceCertificate(config_.provisioning_service_certificate());
EXPECT_EQ(Cdm::kSuccess, status);
ASSERT_EQ(Cdm::kSuccess, cdm_->createSession(Cdm::kTemporary, &session_id));
@@ -2057,14 +2062,14 @@ TEST_F(CdmIndividualizationTest, HandlesAutomaticProvisioning) {
Mock::VerifyAndClear(this);
// We should now be able to create a session and generate a request.
status = cdm_->setServiceCertificate(g_license_service_certificate);
status = cdm_->setServiceCertificate(config_.license_service_certificate());
EXPECT_EQ(Cdm::kSuccess, status);
ASSERT_NO_FATAL_FAILURE(CreateSessionAndGenerateRequest(
Cdm::kTemporary, Cdm::kCenc, &session_id, &message));
// Acquire a license and update the session.
ASSERT_NO_FATAL_FAILURE(FetchLicense(
g_license_server, message, &reply));
config_.license_server(), message, &reply));
EXPECT_CALL(*this, onKeyStatusesChange(session_id, true));
status = updateWithRetry(session_id, reply);
EXPECT_EQ(Cdm::kSuccess, status);
@@ -2079,7 +2084,7 @@ TEST_F(CdmIndividualizationTest, WillNotSendRequestTwice) {
// Creating a session should succeed.
Cdm::Status status =
cdm_->setServiceCertificate(g_provisioning_service_certificate);
cdm_->setServiceCertificate(config_.provisioning_service_certificate());
EXPECT_EQ(Cdm::kSuccess, status);
std::string session_id;
ASSERT_EQ(Cdm::kSuccess, cdm_->createSession(Cdm::kTemporary, &session_id));
@@ -2122,7 +2127,7 @@ TEST_F(CdmIndividualizationTest,
// Creating a session should succeed.
Cdm::Status status =
cdm_->setServiceCertificate(g_provisioning_service_certificate);
cdm_->setServiceCertificate(config_.provisioning_service_certificate());
EXPECT_EQ(Cdm::kSuccess, status);
std::string session_id;
ASSERT_EQ(Cdm::kSuccess, cdm_->createSession(Cdm::kTemporary, &session_id));
@@ -2150,7 +2155,7 @@ TEST_F(CdmIndividualizationTest,
Mock::VerifyAndClear(this);
// We should get a license message for the second session.
status = cdm_->setServiceCertificate(g_license_service_certificate);
status = cdm_->setServiceCertificate(config_.license_service_certificate());
EXPECT_EQ(Cdm::kSuccess, status);
EXPECT_CALL(*this, onMessage(session_id2, Cdm::kLicenseRequest, _)).Times(1);
ASSERT_EQ(Cdm::kSuccess,
@@ -2166,7 +2171,7 @@ TEST_F(CdmIndividualizationTest, PropagatesErrorsInUpdate) {
// Creating a session should succeed.
Cdm::Status status =
cdm_->setServiceCertificate(g_provisioning_service_certificate);
cdm_->setServiceCertificate(config_.provisioning_service_certificate());
EXPECT_EQ(Cdm::kSuccess, status);
std::string session_id;
ASSERT_EQ(Cdm::kSuccess, cdm_->createSession(Cdm::kTemporary, &session_id));
@@ -2196,7 +2201,7 @@ TEST_F(CdmIndividualizationTest, OnlyPropagatesErrorsForThisSession) {
// Creating a session should succeed.
Cdm::Status status =
cdm_->setServiceCertificate(g_provisioning_service_certificate);
cdm_->setServiceCertificate(config_.provisioning_service_certificate());
EXPECT_EQ(Cdm::kSuccess, status);
std::string session_id;
ASSERT_EQ(Cdm::kSuccess, cdm_->createSession(Cdm::kTemporary, &session_id));
@@ -2274,7 +2279,7 @@ TEST_F(CdmIndividualizationTest, WillResendOnProvisioningError) {
// Creating a session should succeed.
Cdm::Status status =
cdm_->setServiceCertificate(g_provisioning_service_certificate);
cdm_->setServiceCertificate(config_.provisioning_service_certificate());
EXPECT_EQ(Cdm::kSuccess, status);
std::string session_id;
ASSERT_EQ(Cdm::kSuccess, cdm_->createSession(Cdm::kTemporary, &session_id));

View File

@@ -6,7 +6,6 @@
#include <getopt.h>
#include <gtest/gtest.h>
#include <time.h>
#include <stdio.h>
#if defined(__linux__)
#include <sys/utsname.h>
@@ -14,13 +13,10 @@
#include "cdm.h"
#include "device_cert.h"
#include "log.h"
#include "override.h"
#include "test_host.h"
#include "test_keybox.h"
#if defined(OEMCRYPTO_TESTS)
# include "oec_device_features.h"
#endif
#include "test_base.h"
using namespace widevine;
@@ -30,41 +26,7 @@ int main(int argc, char** argv) {
// Init gtest and let it consume arguments.
::testing::InitGoogleTest(&argc, argv);
// Parse arguments.
int show_usage = 0;
int opt;
int verbosity = 0;
while ((opt = getopt_long(argc, argv, "v", NULL, NULL)) != -1) {
switch (opt) {
case 'v':
++verbosity;
break;
case '?':
show_usage = 1;
break;
}
}
if (show_usage) {
fprintf(stderr, "Usage: %s [-v|-vv|-vvv]\n\n", argv[0]);
return 0;
}
{
FILE* outfile;
outfile = fopen("danger_do_not_use.bin", "w");
if (outfile == NULL) { return 0; }
if (fwrite(&wvcdm_test_auth::kValidKeybox01, 1,
sizeof(wvcdm_test_auth::kValidKeybox01), outfile) != 128) {
fclose(outfile);
return 0;
}
if (fwrite(&wvcdm_test_auth::kTestKeybox, 1,
sizeof(wvcdm_test_auth::kTestKeybox), outfile) != 128) {
fclose(outfile);
return 0;
}
fclose(outfile);
}
if (!wvcdm::WvCdmTestBase::Initialize(argc, argv)) return 0;
// Set up a Host so that tests and initialize the library. This makes these
// services available to the tests. We would do this in the test suite
@@ -91,17 +53,9 @@ int main(int argc, char** argv) {
Cdm::Status status = Cdm::initialize(
Cdm::kNoSecureOutput, client_info, g_host, g_host, g_host,
static_cast<Cdm::LogLevel>(verbosity));
static_cast<Cdm::LogLevel>(wvcdm::g_cutoff));
(void)status; // status is now used when assertions are turned off.
assert(status == Cdm::kSuccess);
#if defined(OEMCRYPTO_TESTS)
// Set up the OEMCrypto test harness.
wvoec::global_features.Initialize(false /* is_cast_receiver */,
false /* force_load_test_keybox */);
::testing::GTEST_FLAG(filter)
= wvoec::global_features.RestrictFilter(::testing::GTEST_FLAG(filter));
#endif
return RUN_ALL_TESTS();
}