Merges to android Pi release (part: 1)
Below are a set of CLs being merged from the wv cdm repo to the android repo. * Fix handling of OEM Cert public key. Author: Srujan Gaddam <srujzs@google.com> [ Merge of http://go/wvgerrit/27921 ] This is a potential fix for b/36656190. Set aside public key on first call to get the public key, and use it afterwards. This gets rid of extra calls to OEMCrypto_GetOEMPublicCertificate(), which has side-effect of staging the OEM private key. This also fixes a problem where the public cert string was not being trimmed to match the size returned by OEMCrypto_GetOEMPublicCertificate(). * Complete provisioning request/response for Provisioning 3.0 Author: Gene Morgan <gmorgan@google.com> [ Merge of http://go/wvgerrit/27780 ] Fix bug on provisioning request path where GenerateDerivedKeys() was being called when preparing to generate the signature. Add message signature verification, and call correct OEMCrypto routine to rewrap the private key (OEMCrypto_RewrapDeviceRSAKey30). * Implement Cdm::deleteAllUsageRecords() Author: Gene Morgan <gmorgan@google.com> [ Merge of http://go/wvgerrit/27780 ] Delete all usage records for current origin. Removes usage records from file system and retains the PSTs. The deletes any usage entries matching those PSTs held by OEMCrypto. BUG: 35319024 * Remove stringencoders library from third_party. Author: Jacob Trimble <modmaker@google.com> [ Merge of http://go/wvgerrit/27585 ] We have a fork of the stringencoders library that we use for base64 encoding. This reimplements base64 encoding to remove the extra dependency and to reduce the amount of code. * Add Cdm::deleteUsageRecord() based on key_set_id. Author: Gene Morgan <gmorgan@google.com> [ Merge of http://go/wvgerrit/27605 ] Delete specified usage record from file system usage info and from OEMCrypto. BUG: 35319024 * Modifiable OEMCrypto Author: Fred Gylys-Colwell <fredgc@google.com> [ Merge of http://go/wvgerrit/24729 ] This CL adds a new variant of the OEMCrypto mock code that adjusts its behavior based on a configuration file. This is intended for testing. For example, a tester can set current_hdcp to 2 in the options.txt file, push it to the device, and verify that a license is granted for HDCP 2.0. Then the tester can edit the value of current_hdcp to 1 and push the file to the device. Playback should stop because the license is no longer valid. This variant uses a real level 1 liboemcrypto.so to push data to a secure buffer. That means we can test playback for a license that requires secure buffers on an Android device with real secure buffers. BUG: 35141278 BUG: 37353534 BUG: 71650075 Test: Not currently passing. Will be addressed in a subsequent commit in the chain. Change-Id: I58443c510919e992bb455192e70373490a00e2b6
This commit is contained in:
@@ -53,6 +53,9 @@ const std::pair<const std::string *, const std::string *> kBase64TestVectors[] =
|
||||
make_pair(&kTwoBytesOverData, &kTwoBytesOverB64Data),
|
||||
make_pair(&kTestData, &kB64TestData)};
|
||||
|
||||
const std::string kBase64ErrorVectors[] = {"Foo$sa", "Foo\x99\x23\xfa\02",
|
||||
"Foo==Foo", "FooBa"};
|
||||
|
||||
std::string ConvertToBase64WebSafe(const std::string &std_base64_string) {
|
||||
std::string str(std_base64_string);
|
||||
for (size_t i = 0; i < str.size(); ++i) {
|
||||
@@ -89,9 +92,19 @@ TEST_P(Base64EncodeDecodeTest, WebSafeEncodeDecodeTest) {
|
||||
EXPECT_STREQ(encoded_string.data(), b64_string.data());
|
||||
}
|
||||
|
||||
class Base64ErrorDecodeTest : public ::testing::TestWithParam<std::string> {};
|
||||
|
||||
TEST_P(Base64ErrorDecodeTest, EncoderErrors) {
|
||||
std::vector<uint8_t> result = Base64Decode(GetParam());
|
||||
EXPECT_EQ(0u, result.size());
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(ExecutesBase64Test, Base64EncodeDecodeTest,
|
||||
::testing::ValuesIn(kBase64TestVectors));
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(ExecutesBase64Test, Base64ErrorDecodeTest,
|
||||
::testing::ValuesIn(kBase64ErrorVectors));
|
||||
|
||||
class HtoNLL64Test : public ::testing::Test {};
|
||||
|
||||
TEST_F(HtoNLL64Test, PositiveNumber) {
|
||||
|
||||
@@ -52,7 +52,7 @@ class WvCdmEngineTest : public testing::Test {
|
||||
g_client_auth.assign(config.client_auth());
|
||||
g_key_system.assign(config.key_system());
|
||||
g_wrong_key_id.assign(config.wrong_key_id());
|
||||
g_license_server.assign(config.license_server_url());
|
||||
g_license_server.assign(config.license_server());
|
||||
g_key_id_pssh.assign(a2bs_hex(config.key_id()));
|
||||
|
||||
// Extract the key ID from the PSSH box.
|
||||
|
||||
@@ -99,8 +99,7 @@ class MockDeviceFiles : public DeviceFiles {
|
||||
|
||||
class MockCryptoSession : public CryptoSession {
|
||||
public:
|
||||
MockCryptoSession(metrics::CryptoMetrics* crypto_metrics)
|
||||
: CryptoSession(crypto_metrics) { }
|
||||
MockCryptoSession() : CryptoSession(NULL) { }
|
||||
MOCK_METHOD1(GetClientToken, bool(std::string*));
|
||||
MOCK_METHOD1(GetProvisioningToken, bool(std::string*));
|
||||
MOCK_METHOD0(GetPreProvisionTokenType, CdmClientTokenType());
|
||||
@@ -142,11 +141,11 @@ class CdmSessionTest : public ::testing::Test {
|
||||
protected:
|
||||
virtual void SetUp() {
|
||||
service_cert_ = new ServiceCertificate;
|
||||
cdm_session_.reset(new CdmSession(NULL, &metrics_));
|
||||
cdm_session_.reset(new CdmSession(NULL));
|
||||
// Inject testing mocks.
|
||||
license_parser_ = new MockCdmLicense(cdm_session_->session_id());
|
||||
cdm_session_->set_license_parser(license_parser_);
|
||||
crypto_session_ = new MockCryptoSession(&crypto_metrics_);
|
||||
crypto_session_ = new MockCryptoSession();
|
||||
cdm_session_->set_crypto_session(crypto_session_);
|
||||
policy_engine_ = new MockPolicyEngine();
|
||||
cdm_session_->set_policy_engine(policy_engine_);
|
||||
@@ -154,16 +153,8 @@ 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_;
|
||||
metrics::CryptoMetrics crypto_metrics_;
|
||||
MockCryptoSession* crypto_session_;
|
||||
MockPolicyEngine* policy_engine_;
|
||||
MockDeviceFiles* file_handle_;
|
||||
|
||||
@@ -2,21 +2,23 @@
|
||||
|
||||
#include "config_test_env.h"
|
||||
|
||||
#include "string_conversions.h"
|
||||
|
||||
namespace wvcdm {
|
||||
|
||||
namespace {
|
||||
|
||||
const std::string kWidevineKeySystem = "com.widevine.alpha";
|
||||
|
||||
// QA/Test server
|
||||
const std::string kQALicenseServerUrl =
|
||||
"http://0.widevine-qa-wls.licenseserver.widevine-license-qa.lf.borg.google.com/";
|
||||
const std::string kQAServiceCertificate = "";
|
||||
const std::string kQAProvisioningServerUrl = "http://www-googleapis-test.sandbox.google.com/certificateprovisioning/v1/devicecertificates/create"
|
||||
"?key=AIzaSyB-5OLKTx2iU5mko18DfdwK5611JIjbUhE";
|
||||
|
||||
|
||||
// Content Protection license server (UAT) data
|
||||
const std::string kCpUatLicenseServer =
|
||||
"http://widevine-proxy.appspot.com/proxy";
|
||||
const std::string kUatProvisioningServerUrl =
|
||||
"https://staging-www.sandbox.googleapis.com/"
|
||||
"certificateprovisioning/v1/devicecertificates/create"
|
||||
"?key=AIzaSyB-5OLKTx2iU5mko18DfdwK5611JIjbUhE";
|
||||
const std::string kCpClientAuth = "";
|
||||
const std::string kCpKeyId =
|
||||
"00000042" // blob size
|
||||
@@ -26,7 +28,7 @@ const std::string kCpKeyId =
|
||||
"00000022" // pssh data size
|
||||
// pssh data:
|
||||
"08011a0d7769646576696e655f746573"
|
||||
"74220f73747265616d696e675f636c69" // "streaming_clip1"
|
||||
"74220f73747265616d696e675f636c69"
|
||||
"7031";
|
||||
const std::string kCpOfflineKeyId =
|
||||
"00000040" // blob size
|
||||
@@ -36,26 +38,7 @@ const std::string kCpOfflineKeyId =
|
||||
"00000020" // pssh data size
|
||||
// pssh data:
|
||||
"08011a0d7769646576696e655f746573"
|
||||
"74220d6f66666c696e655f636c697032"; // "offline_clip2"
|
||||
const CdmInitData kCpStagingSrmOuputProtectionRequired =
|
||||
"0000003d" // blob size
|
||||
"70737368" // "pssh"
|
||||
"00000000" // flags
|
||||
"edef8ba979d64acea3c827dcd51d21ed" // Widevine system id
|
||||
"0000001d" // pssh data size
|
||||
// pssh data:
|
||||
"08011a0d7769646576696e655f746573"
|
||||
"74220a74656172735f73726d32"; // "tears_srm2"
|
||||
const CdmInitData kCpStagingSrmOuputProtectionRequested =
|
||||
"0000003d" // blob size
|
||||
"70737368" // "pssh"
|
||||
"00000000" // flags
|
||||
"edef8ba979d64acea3c827dcd51d21ed" // Widevine system id
|
||||
"0000001d" // pssh data size
|
||||
// pssh data:
|
||||
"08011a0d7769646576696e655f746573"
|
||||
"74220a74656172735f73726d32"; // "tears_srm1"
|
||||
const CdmInitData kEmptyData;
|
||||
"74220d6f66666c696e655f636c697032";
|
||||
const std::string kCpUatServiceCertificate =
|
||||
"0ABF020803121028703454C008F63618ADE7443DB6C4C8188BE7F99005228E023082010A02"
|
||||
"82010100B52112B8D05D023FCC5D95E2C251C1C649B4177CD8D2BEEF355BB06743DE661E3D"
|
||||
@@ -78,46 +61,9 @@ const std::string kCpUatServiceCertificate =
|
||||
"7C0011E0F5B38E4E298ED2CB301EB4564965F55C5D79757A250A4EB9C84AB3E6539F6B6FDF"
|
||||
"56899EA29914";
|
||||
|
||||
const std::string kCpProductionLicenseServer =
|
||||
"https://widevine-proxy.appspot.com/proxy";
|
||||
const std::string kProductionProvisioningServerUrl =
|
||||
"https://www.googleapis.com/"
|
||||
"certificateprovisioning/v1/devicecertificates/create"
|
||||
"?key=AIzaSyB-5OLKTx2iU5mko18DfdwK5611JIjbUhE";
|
||||
// NOTE: Provider ID = staging.google.com
|
||||
const std::string kCpProductionServiceCertificate =
|
||||
"0ABF020803121028703454C008F63618ADE7443DB6C4C8188BE7F9900522"
|
||||
"8E023082010A0282010100B52112B8D05D023FCC5D95E2C251C1C649B417"
|
||||
"7CD8D2BEEF355BB06743DE661E3D2ABC3182B79946D55FDC08DFE9540781"
|
||||
"5E9A6274B322A2C7F5E067BB5F0AC07A89D45AEA94B2516F075B66EF811D"
|
||||
"0D26E1B9A6B894F2B9857962AA171C4F66630D3E4C602718897F5E1EF9B6"
|
||||
"AAF5AD4DBA2A7E14176DF134A1D3185B5A218AC05A4C41F081EFFF80A3A0"
|
||||
"40C50B09BBC740EEDCD8F14D675A91980F92CA7DDC646A06ADAD5101F74A"
|
||||
"0E498CC01F00532BAC217850BD905E90923656B7DFEFEF42486767F33EF6"
|
||||
"283D4F4254AB72589390BEE55808F1D668080D45D893C2BCA2F74D60A0C0"
|
||||
"D0A0993CEF01604703334C3638139486BC9DAF24FD67A07F9AD943020301"
|
||||
"00013A1273746167696E672E676F6F676C652E636F6D128003983E303526"
|
||||
"75F40BA715FC249BDAE5D4AC7249A2666521E43655739529721FF880E0AA"
|
||||
"EFC5E27BC980DAEADABF3FC386D084A02C82537848CC753FF497B011A7DA"
|
||||
"97788A00E2AA6B84CD7D71C07A48EBF61602CCA5A3F32030A7295C30DA91"
|
||||
"5B91DC18B9BC9593B8DE8BB50F0DEDC12938B8E9E039CDDE18FA82E81BB0"
|
||||
"32630FE955D85A566CE154300BF6D4C1BD126966356B287D657B18CE63D0"
|
||||
"EFD45FC5269E97EAB11CB563E55643B26FF49F109C2101AFCAF35B832F28"
|
||||
"8F0D9D45960E259E85FB5D24DBD2CF82764C5DD9BF727EFBE9C861F86932"
|
||||
"1F6ADE18905F4D92F9A6DA6536DB8475871D168E870BB2303CF70C6E9784"
|
||||
"C93D2DE845AD8262BE7E0D4E2E4A0759CEF82D109D2592C72429F8C01742"
|
||||
"BAE2B3DECADBC33C3E5F4BAF5E16ECB74EADBAFCB7C6705F7A9E3B6F3940"
|
||||
"383F9C5116D202A20C9229EE969C2519718303B50D0130C3352E06B014D8"
|
||||
"38540F8A0C227C0011E0F5B38E4E298ED2CB301EB4564965F55C5D79757A"
|
||||
"250A4EB9C84AB3E6539F6B6FDF56899EA29914";
|
||||
|
||||
// Content Protection license server (staging) data
|
||||
const std::string kCpStagingLicenseServer =
|
||||
"https://proxy.staging.widevine.com/proxy";
|
||||
const std::string kStagingProvisioningServerUrl =
|
||||
"https://staging-www.sandbox.googleapis.com/"
|
||||
"certificateprovisioning/v1/devicecertificates/create"
|
||||
"?key=AIzaSyB-5OLKTx2iU5mko18DfdwK5611JIjbUhE";
|
||||
"http://wv-staging-proxy.appspot.com/proxy";
|
||||
const std::string kCpStagingServiceCertificate =
|
||||
"0AC102080312101705B917CC1204868B06333A2F772A8C1882B4829205228E023082010A02"
|
||||
"8201010099ED5B3B327DAB5E24EFC3B62A95B598520AD5BCCB37503E0645B814D876B8DF40"
|
||||
@@ -178,17 +124,21 @@ const std::string kWrongKeyId =
|
||||
"0901121094889920e8d6520098577df8"
|
||||
"f2dd5546";
|
||||
|
||||
// URL of provisioning server (returned by GetProvisioningRequest())
|
||||
const std::string kProductionProvisioningServerUrl =
|
||||
"https://www.googleapis.com/"
|
||||
"certificateprovisioning/v1/devicecertificates/create"
|
||||
"?key=AIzaSyB-5OLKTx2iU5mko18DfdwK5611JIjbUhE";
|
||||
|
||||
const ConfigTestEnv::LicenseServerConfiguration license_servers[] = {
|
||||
{kGooglePlayServer, kGpLicenseServer, "", kGpClientAuth, kGpKeyId,
|
||||
kGpOfflineKeyId, kProductionProvisioningServerUrl},
|
||||
{kContentProtectionProductionServer, kCpProductionLicenseServer,
|
||||
kCpProductionServiceCertificate, kCpClientAuth, kCpKeyId, kCpOfflineKeyId,
|
||||
kProductionProvisioningServerUrl},
|
||||
{kContentProtectionUatServer, kCpUatLicenseServer, kCpUatServiceCertificate,
|
||||
kCpClientAuth, kCpKeyId, kCpOfflineKeyId, kUatProvisioningServerUrl},
|
||||
{kGooglePlayServer, kGpLicenseServer, kGpClientAuth, kGpKeyId,
|
||||
kGpOfflineKeyId, ""},
|
||||
{kContentProtectionUatServer, kCpUatLicenseServer, kCpClientAuth,
|
||||
kCpKeyId, kCpOfflineKeyId, kCpUatServiceCertificate},
|
||||
{kContentProtectionStagingServer, kCpStagingLicenseServer,
|
||||
kCpStagingServiceCertificate, kCpClientAuth, kCpKeyId, kCpOfflineKeyId,
|
||||
kStagingProvisioningServerUrl},
|
||||
kCpClientAuth, kCpKeyId, kCpOfflineKeyId, kCpStagingServiceCertificate},
|
||||
{kContentProtectionTestQAServer, kQALicenseServerUrl,
|
||||
kCpClientAuth, kCpKeyId, kCpOfflineKeyId, kQAServiceCertificate},
|
||||
};
|
||||
|
||||
} // namespace
|
||||
@@ -219,45 +169,13 @@ ConfigTestEnv::ConfigTestEnv(LicenseServerId server_id, bool streaming,
|
||||
}
|
||||
|
||||
void ConfigTestEnv::Init(LicenseServerId server_id) {
|
||||
server_id_ = server_id;
|
||||
client_auth_ = license_servers[server_id].client_tag;
|
||||
key_id_ = license_servers[server_id].key_id;
|
||||
key_system_ = kWidevineKeySystem;
|
||||
license_server_url_ = license_servers[server_id].license_server_url;
|
||||
provisioning_server_url_ = license_servers[server_id].provisioning_server_url;
|
||||
service_certificate_ = license_servers[server_id].license_service_certificate;
|
||||
license_server_ = license_servers[server_id].url;
|
||||
provisioning_server_url_ = kProductionProvisioningServerUrl;
|
||||
service_certificate_ = license_servers[server_id].service_certificate;
|
||||
wrong_key_id_ = kWrongKeyId;
|
||||
}
|
||||
|
||||
const CdmInitData ConfigTestEnv::GetInitData(ContentId content_id) {
|
||||
switch (content_id) {
|
||||
case kContentIdStreaming:
|
||||
return wvcdm::a2bs_hex(kCpKeyId);
|
||||
case kContentIdOffline:
|
||||
return wvcdm::a2bs_hex(kCpOfflineKeyId);
|
||||
case kContentIdStagingSrmOuputProtectionRequested:
|
||||
return wvcdm::a2bs_hex(kCpStagingSrmOuputProtectionRequested);
|
||||
case kContentIdStagingSrmOuputProtectionRequired:
|
||||
return wvcdm::a2bs_hex(kCpStagingSrmOuputProtectionRequired);
|
||||
default:
|
||||
return kEmptyData;
|
||||
}
|
||||
}
|
||||
|
||||
const std::string& ConfigTestEnv::GetLicenseServerUrl(
|
||||
LicenseServerId license_server_id) {
|
||||
switch (license_server_id) {
|
||||
case kGooglePlayServer:
|
||||
return kGpLicenseServer;
|
||||
case kContentProtectionUatServer:
|
||||
return kCpUatLicenseServer;
|
||||
case kContentProtectionStagingServer:
|
||||
return kCpStagingLicenseServer;
|
||||
case kContentProtectionProductionServer:
|
||||
return kCpProductionLicenseServer;
|
||||
default:
|
||||
return kEmptyData;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace wvcdm
|
||||
|
||||
@@ -11,30 +11,19 @@ typedef enum {
|
||||
kGooglePlayServer,
|
||||
kContentProtectionUatServer,
|
||||
kContentProtectionStagingServer,
|
||||
kContentProtectionProductionServer,
|
||||
kContentProtectionTestQAServer,
|
||||
} LicenseServerId;
|
||||
|
||||
// Identifies content used in tests. Specify Prod/Uat/Staging if content
|
||||
// has been registered across license services.
|
||||
enum ContentId {
|
||||
kContentIdStreaming,
|
||||
kContentIdOffline,
|
||||
kContentIdStagingSrmOuputProtectionRequested,
|
||||
kContentIdStagingSrmOuputProtectionRequired,
|
||||
};
|
||||
|
||||
// Configures default test environment.
|
||||
class ConfigTestEnv {
|
||||
public:
|
||||
|
||||
typedef struct {
|
||||
LicenseServerId id;
|
||||
std::string license_server_url;
|
||||
std::string license_service_certificate;
|
||||
std::string url;
|
||||
std::string client_tag;
|
||||
std::string key_id;
|
||||
std::string offline_key_id;
|
||||
std::string provisioning_server_url;
|
||||
std::string service_certificate;
|
||||
} LicenseServerConfiguration;
|
||||
|
||||
explicit ConfigTestEnv(LicenseServerId server_id);
|
||||
@@ -46,7 +35,7 @@ class ConfigTestEnv {
|
||||
const std::string& client_auth() const { return client_auth_; }
|
||||
const KeyId& key_id() const { return key_id_; }
|
||||
const CdmKeySystem& key_system() const { return key_system_; }
|
||||
const std::string& license_server_url() const { return license_server_url_; }
|
||||
const std::string& license_server() const { return license_server_; }
|
||||
const std::string& provisioning_server_url() const {
|
||||
return provisioning_server_url_;
|
||||
}
|
||||
@@ -55,19 +44,12 @@ class ConfigTestEnv {
|
||||
}
|
||||
const KeyId& wrong_key_id() const { return wrong_key_id_; }
|
||||
|
||||
static const CdmInitData GetInitData(ContentId content_id);
|
||||
static const std::string& GetLicenseServerUrl(
|
||||
LicenseServerId license_server_id);
|
||||
|
||||
void set_key_id(KeyId& key_id) { key_id_.assign(key_id); }
|
||||
void set_key_system(CdmKeySystem& key_system) {
|
||||
key_system_.assign(key_system);
|
||||
}
|
||||
void set_license_server(std::string& license_server) {
|
||||
license_server_url_.assign(license_server);
|
||||
}
|
||||
void set_provisioning_server(std::string& provisioning_server) {
|
||||
provisioning_server_url_.assign(provisioning_server);
|
||||
license_server_.assign(license_server);
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -76,11 +58,10 @@ class ConfigTestEnv {
|
||||
std::string client_auth_;
|
||||
KeyId key_id_;
|
||||
CdmKeySystem key_system_;
|
||||
std::string license_server_url_;
|
||||
std::string license_server_;
|
||||
std::string provisioning_server_url_;
|
||||
std::string service_certificate_;
|
||||
KeyId wrong_key_id_;
|
||||
LicenseServerId server_id_;
|
||||
|
||||
CORE_DISALLOW_COPY_AND_ASSIGN(ConfigTestEnv);
|
||||
};
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -36,6 +36,8 @@ class WvGenericOperationsTest : public testing::Test {
|
||||
virtual void SetUp() {
|
||||
::testing::Test::SetUp();
|
||||
|
||||
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.
|
||||
@@ -68,7 +70,9 @@ class WvGenericOperationsTest : public testing::Test {
|
||||
|
||||
virtual void TearDown() {
|
||||
oec_util_session_.close();
|
||||
cdm_engine_->CloseSession(session_id_);
|
||||
if (cdm_engine_ != NULL) {
|
||||
cdm_engine_->CloseSession(session_id_);
|
||||
}
|
||||
// OEMCrypto_Terminate() will be performed during the test class's
|
||||
// destruction (specifically by the CryptoSession destructor)
|
||||
}
|
||||
|
||||
@@ -392,16 +392,14 @@ TEST_F(LicenseKeysTest, CanDecrypt) {
|
||||
EXPECT_FALSE(license_keys_.CanDecryptContent(os_key));
|
||||
bool new_usable_keys = false;
|
||||
bool any_change = false;
|
||||
CdmKeyStatus status = kKeyStatusUsable;
|
||||
any_change = license_keys_.ApplyStatusChange(&status, NULL, NULL,
|
||||
any_change = license_keys_.ApplyStatusChange(kKeyStatusUsable,
|
||||
&new_usable_keys);
|
||||
EXPECT_TRUE(any_change);
|
||||
EXPECT_TRUE(new_usable_keys);
|
||||
EXPECT_TRUE(license_keys_.CanDecryptContent(c_key));
|
||||
EXPECT_FALSE(license_keys_.CanDecryptContent(os_key));
|
||||
|
||||
status = kKeyStatusExpired;
|
||||
any_change = license_keys_.ApplyStatusChange(&status, NULL, NULL,
|
||||
any_change = license_keys_.ApplyStatusChange(kKeyStatusExpired,
|
||||
&new_usable_keys);
|
||||
EXPECT_TRUE(any_change);
|
||||
EXPECT_FALSE(new_usable_keys);
|
||||
@@ -507,7 +505,6 @@ TEST_F(LicenseKeysTest, ExtractKeyStatuses) {
|
||||
TEST_F(LicenseKeysTest, KeyStatusChanges) {
|
||||
bool new_usable_keys = false;
|
||||
bool any_change = false;
|
||||
CdmKeyStatus status;
|
||||
CdmKeyStatusMap key_status_map;
|
||||
StageOperatorSessionKeys();
|
||||
StageContentKeys();
|
||||
@@ -517,8 +514,7 @@ TEST_F(LicenseKeysTest, KeyStatusChanges) {
|
||||
ExpectKeyStatusesEqual(key_status_map, kKeyStatusInternalError);
|
||||
|
||||
// change to pending
|
||||
status = kKeyStatusPending;
|
||||
any_change = license_keys_.ApplyStatusChange(&status, NULL, NULL,
|
||||
any_change = license_keys_.ApplyStatusChange(kKeyStatusPending,
|
||||
&new_usable_keys);
|
||||
EXPECT_TRUE(any_change);
|
||||
EXPECT_FALSE(new_usable_keys);
|
||||
@@ -530,8 +526,7 @@ TEST_F(LicenseKeysTest, KeyStatusChanges) {
|
||||
ExpectKeyStatusesEqual(key_status_map, kKeyStatusPending);
|
||||
|
||||
// change to pending (again)
|
||||
status = kKeyStatusPending;
|
||||
any_change = license_keys_.ApplyStatusChange(&status, NULL, NULL,
|
||||
any_change = license_keys_.ApplyStatusChange(kKeyStatusPending,
|
||||
&new_usable_keys);
|
||||
EXPECT_FALSE(any_change);
|
||||
EXPECT_FALSE(new_usable_keys);
|
||||
@@ -543,8 +538,7 @@ TEST_F(LicenseKeysTest, KeyStatusChanges) {
|
||||
ExpectKeyStatusesEqual(key_status_map, kKeyStatusPending);
|
||||
|
||||
// change to usable
|
||||
status = kKeyStatusUsable;
|
||||
any_change = license_keys_.ApplyStatusChange(&status, NULL, NULL,
|
||||
any_change = license_keys_.ApplyStatusChange(kKeyStatusUsable,
|
||||
&new_usable_keys);
|
||||
EXPECT_TRUE(any_change);
|
||||
EXPECT_TRUE(new_usable_keys);
|
||||
@@ -556,8 +550,7 @@ TEST_F(LicenseKeysTest, KeyStatusChanges) {
|
||||
ExpectKeyStatusesEqual(key_status_map, kKeyStatusUsable);
|
||||
|
||||
// change to usable (again)
|
||||
status = kKeyStatusUsable;
|
||||
any_change = license_keys_.ApplyStatusChange(&status, NULL, NULL,
|
||||
any_change = license_keys_.ApplyStatusChange(kKeyStatusUsable,
|
||||
&new_usable_keys);
|
||||
EXPECT_FALSE(any_change);
|
||||
EXPECT_FALSE(new_usable_keys);
|
||||
@@ -569,8 +562,7 @@ TEST_F(LicenseKeysTest, KeyStatusChanges) {
|
||||
ExpectKeyStatusesEqual(key_status_map, kKeyStatusUsable);
|
||||
|
||||
// change to expired
|
||||
status = kKeyStatusExpired;
|
||||
any_change = license_keys_.ApplyStatusChange(&status, NULL, NULL,
|
||||
any_change = license_keys_.ApplyStatusChange(kKeyStatusExpired,
|
||||
&new_usable_keys);
|
||||
EXPECT_TRUE(any_change);
|
||||
EXPECT_FALSE(new_usable_keys);
|
||||
@@ -585,14 +577,10 @@ TEST_F(LicenseKeysTest, KeyStatusChanges) {
|
||||
TEST_F(LicenseKeysTest, HdcpChanges) {
|
||||
bool new_usable_keys = false;
|
||||
bool any_change = false;
|
||||
CdmKeyStatus status;
|
||||
uint32_t resolution;
|
||||
CryptoSession::HdcpCapability hdcp_level;
|
||||
CdmKeyStatusMap key_status_map;
|
||||
StageHdcpKeys();
|
||||
|
||||
status = kKeyStatusUsable;
|
||||
any_change = license_keys_.ApplyStatusChange(&status, NULL, NULL,
|
||||
any_change = license_keys_.ApplyStatusChange(kKeyStatusUsable,
|
||||
&new_usable_keys);
|
||||
EXPECT_TRUE(any_change);
|
||||
EXPECT_TRUE(new_usable_keys);
|
||||
@@ -610,11 +598,9 @@ TEST_F(LicenseKeysTest, HdcpChanges) {
|
||||
EXPECT_TRUE(license_keys_.MeetsConstraints(ck_sw_crypto_HDCP_NO_OUTPUT));
|
||||
EXPECT_TRUE(license_keys_.MeetsConstraints(ck_hw_secure_HDCP_NO_OUTPUT));
|
||||
|
||||
status = kKeyStatusUsable;
|
||||
resolution = 100;
|
||||
hdcp_level = HDCP_NONE;
|
||||
any_change = license_keys_.ApplyStatusChange(&status, &resolution,
|
||||
&hdcp_level, &new_usable_keys);
|
||||
license_keys_.ApplyConstraints(100, HDCP_NONE);
|
||||
any_change = license_keys_.ApplyStatusChange(kKeyStatusUsable,
|
||||
&new_usable_keys);
|
||||
|
||||
EXPECT_TRUE(any_change);
|
||||
EXPECT_FALSE(new_usable_keys);
|
||||
@@ -637,11 +623,9 @@ TEST_F(LicenseKeysTest, HdcpChanges) {
|
||||
ExpectKeyStatusEqual(key_status_map, ck_hw_secure_HDCP_V2_1,
|
||||
kKeyStatusOutputNotAllowed);
|
||||
|
||||
status = kKeyStatusUsable;
|
||||
resolution = 100;
|
||||
hdcp_level = HDCP_V1;
|
||||
any_change = license_keys_.ApplyStatusChange(&status, &resolution,
|
||||
&hdcp_level, &new_usable_keys);
|
||||
license_keys_.ApplyConstraints(100, HDCP_V1);
|
||||
any_change = license_keys_.ApplyStatusChange(kKeyStatusUsable,
|
||||
&new_usable_keys);
|
||||
|
||||
EXPECT_FALSE(any_change);
|
||||
EXPECT_FALSE(new_usable_keys);
|
||||
@@ -664,11 +648,9 @@ TEST_F(LicenseKeysTest, HdcpChanges) {
|
||||
ExpectKeyStatusEqual(key_status_map, ck_sw_crypto_HDCP_V2_1,
|
||||
kKeyStatusOutputNotAllowed);
|
||||
|
||||
status = kKeyStatusUsable;
|
||||
resolution = 100;
|
||||
hdcp_level = HDCP_V2_2;
|
||||
any_change = license_keys_.ApplyStatusChange(&status, &resolution,
|
||||
&hdcp_level, &new_usable_keys);
|
||||
license_keys_.ApplyConstraints(100, HDCP_V2_2);
|
||||
any_change = license_keys_.ApplyStatusChange(kKeyStatusUsable,
|
||||
&new_usable_keys);
|
||||
|
||||
EXPECT_TRUE(any_change);
|
||||
EXPECT_TRUE(new_usable_keys);
|
||||
@@ -692,11 +674,9 @@ TEST_F(LicenseKeysTest, HdcpChanges) {
|
||||
ExpectKeyStatusEqual(key_status_map, ck_sw_crypto_HDCP_NO_OUTPUT,
|
||||
kKeyStatusOutputNotAllowed);
|
||||
|
||||
status = kKeyStatusUsable;
|
||||
resolution = 100;
|
||||
hdcp_level = HDCP_NO_DIGITAL_OUTPUT;
|
||||
any_change = license_keys_.ApplyStatusChange(&status, &resolution,
|
||||
&hdcp_level, &new_usable_keys);
|
||||
license_keys_.ApplyConstraints(100, HDCP_NO_DIGITAL_OUTPUT);
|
||||
any_change = license_keys_.ApplyStatusChange(kKeyStatusUsable,
|
||||
&new_usable_keys);
|
||||
|
||||
EXPECT_TRUE(any_change);
|
||||
EXPECT_TRUE(new_usable_keys);
|
||||
@@ -720,11 +700,9 @@ TEST_F(LicenseKeysTest, HdcpChanges) {
|
||||
ExpectKeyStatusEqual(key_status_map, ck_hw_secure_HDCP_NO_OUTPUT,
|
||||
kKeyStatusUsable);
|
||||
|
||||
status = kKeyStatusUsable;
|
||||
resolution = 100;
|
||||
hdcp_level = HDCP_NONE;
|
||||
any_change = license_keys_.ApplyStatusChange(&status, &resolution,
|
||||
&hdcp_level, &new_usable_keys);
|
||||
license_keys_.ApplyConstraints(100, HDCP_NONE);
|
||||
any_change = license_keys_.ApplyStatusChange(kKeyStatusUsable,
|
||||
&new_usable_keys);
|
||||
|
||||
EXPECT_TRUE(any_change);
|
||||
EXPECT_FALSE(new_usable_keys);
|
||||
@@ -752,15 +730,11 @@ TEST_F(LicenseKeysTest, HdcpChanges) {
|
||||
TEST_F(LicenseKeysTest, ConstraintChanges) {
|
||||
bool new_usable_keys = false;
|
||||
bool any_change = false;
|
||||
CdmKeyStatus status;
|
||||
uint32_t resolution;
|
||||
CryptoSession::HdcpCapability hdcp_level;
|
||||
CdmKeyStatusMap key_status_map;
|
||||
StageConstraintKeys();
|
||||
|
||||
// No constraints set by device
|
||||
status = kKeyStatusUsable;
|
||||
any_change = license_keys_.ApplyStatusChange(&status, NULL, NULL,
|
||||
any_change = license_keys_.ApplyStatusChange(kKeyStatusUsable,
|
||||
&new_usable_keys);
|
||||
EXPECT_TRUE(any_change);
|
||||
EXPECT_TRUE(new_usable_keys);
|
||||
@@ -775,11 +749,9 @@ TEST_F(LicenseKeysTest, ConstraintChanges) {
|
||||
EXPECT_TRUE(license_keys_.MeetsConstraints(ck_NO_HDCP_dual_res));
|
||||
|
||||
// Low-res device, no HDCP support
|
||||
status = kKeyStatusUsable;
|
||||
resolution = dev_lo_res;
|
||||
hdcp_level = HDCP_NONE;
|
||||
any_change = license_keys_.ApplyStatusChange(&status, &resolution,
|
||||
&hdcp_level, &new_usable_keys);
|
||||
license_keys_.ApplyConstraints(dev_lo_res, HDCP_NONE);
|
||||
any_change = license_keys_.ApplyStatusChange(kKeyStatusUsable,
|
||||
&new_usable_keys);
|
||||
|
||||
EXPECT_TRUE(any_change);
|
||||
EXPECT_FALSE(new_usable_keys);
|
||||
@@ -799,11 +771,9 @@ TEST_F(LicenseKeysTest, ConstraintChanges) {
|
||||
kKeyStatusOutputNotAllowed);
|
||||
|
||||
// Hi-res device, HDCP_V1 support
|
||||
status = kKeyStatusUsable;
|
||||
resolution = dev_hi_res;
|
||||
hdcp_level = HDCP_V1;
|
||||
any_change = license_keys_.ApplyStatusChange(&status, &resolution,
|
||||
&hdcp_level, &new_usable_keys);
|
||||
license_keys_.ApplyConstraints(dev_hi_res, HDCP_V1);
|
||||
any_change = license_keys_.ApplyStatusChange(kKeyStatusUsable,
|
||||
&new_usable_keys);
|
||||
|
||||
EXPECT_TRUE(any_change);
|
||||
EXPECT_TRUE(new_usable_keys);
|
||||
@@ -823,11 +793,9 @@ TEST_F(LicenseKeysTest, ConstraintChanges) {
|
||||
kKeyStatusOutputNotAllowed);
|
||||
|
||||
// Lo-res device, HDCP V2.2 support
|
||||
status = kKeyStatusUsable;
|
||||
resolution = dev_lo_res;
|
||||
hdcp_level = HDCP_V2_2;
|
||||
any_change = license_keys_.ApplyStatusChange(&status, &resolution,
|
||||
&hdcp_level, &new_usable_keys);
|
||||
license_keys_.ApplyConstraints(dev_lo_res, HDCP_V2_2);
|
||||
any_change = license_keys_.ApplyStatusChange(kKeyStatusUsable,
|
||||
&new_usable_keys);
|
||||
|
||||
EXPECT_TRUE(any_change);
|
||||
EXPECT_TRUE(new_usable_keys);
|
||||
@@ -848,11 +816,9 @@ TEST_F(LicenseKeysTest, ConstraintChanges) {
|
||||
kKeyStatusOutputNotAllowed);
|
||||
|
||||
// Hi-res device, Maximal HDCP support
|
||||
status = kKeyStatusUsable;
|
||||
resolution = dev_hi_res;
|
||||
hdcp_level = HDCP_NO_DIGITAL_OUTPUT;
|
||||
any_change = license_keys_.ApplyStatusChange(&status, &resolution,
|
||||
&hdcp_level, &new_usable_keys);
|
||||
license_keys_.ApplyConstraints(dev_hi_res, HDCP_NO_DIGITAL_OUTPUT);
|
||||
any_change = license_keys_.ApplyStatusChange(kKeyStatusUsable,
|
||||
&new_usable_keys);
|
||||
|
||||
EXPECT_TRUE(any_change);
|
||||
EXPECT_TRUE(new_usable_keys);
|
||||
@@ -873,11 +839,9 @@ TEST_F(LicenseKeysTest, ConstraintChanges) {
|
||||
kKeyStatusUsable);
|
||||
|
||||
// Lo-res device, no HDCP support
|
||||
status = kKeyStatusUsable;
|
||||
resolution = dev_lo_res;
|
||||
hdcp_level = HDCP_NONE;
|
||||
any_change = license_keys_.ApplyStatusChange(&status, &resolution,
|
||||
&hdcp_level, &new_usable_keys);
|
||||
license_keys_.ApplyConstraints(dev_lo_res, HDCP_NONE);
|
||||
any_change = license_keys_.ApplyStatusChange(kKeyStatusUsable,
|
||||
&new_usable_keys);
|
||||
|
||||
EXPECT_TRUE(any_change);
|
||||
EXPECT_TRUE(new_usable_keys);
|
||||
@@ -898,11 +862,9 @@ TEST_F(LicenseKeysTest, ConstraintChanges) {
|
||||
kKeyStatusOutputNotAllowed);
|
||||
|
||||
// Too-high-res -- all keys rejected
|
||||
status = kKeyStatusUsable;
|
||||
resolution = dev_top_res;
|
||||
hdcp_level = HDCP_NONE;
|
||||
any_change = license_keys_.ApplyStatusChange(&status, &resolution,
|
||||
&hdcp_level, &new_usable_keys);
|
||||
license_keys_.ApplyConstraints(dev_top_res, HDCP_NONE);
|
||||
any_change = license_keys_.ApplyStatusChange(kKeyStatusUsable,
|
||||
&new_usable_keys);
|
||||
|
||||
EXPECT_TRUE(any_change);
|
||||
EXPECT_FALSE(new_usable_keys);
|
||||
|
||||
@@ -81,8 +81,7 @@ const std::string kLicenseRequestSignature = a2bs_hex(
|
||||
|
||||
class MockCryptoSession : public CryptoSession {
|
||||
public:
|
||||
MockCryptoSession(metrics::CryptoMetrics* crypto_metrics)
|
||||
: CryptoSession(crypto_metrics) { }
|
||||
MockCryptoSession() : CryptoSession(NULL) { }
|
||||
MOCK_METHOD0(IsOpen, bool());
|
||||
MOCK_METHOD1(GenerateRequestId, bool(std::string*));
|
||||
MOCK_METHOD1(UsageInformationSupport, bool(bool*));
|
||||
@@ -132,7 +131,7 @@ class CdmLicenseTest : public ::testing::Test {
|
||||
protected:
|
||||
virtual void SetUp() {
|
||||
clock_ = new MockClock();
|
||||
crypto_session_ = new MockCryptoSession(&crypto_metrics_);
|
||||
crypto_session_ = new MockCryptoSession();
|
||||
init_data_ = new MockInitializationData(CENC_INIT_DATA_FORMAT,
|
||||
kCencInitDataHdr + kCencPssh);
|
||||
policy_engine_ = new MockPolicyEngine(crypto_session_);
|
||||
@@ -153,7 +152,6 @@ class CdmLicenseTest : public ::testing::Test {
|
||||
|
||||
CdmLicense* cdm_license_;
|
||||
MockClock* clock_;
|
||||
metrics::CryptoMetrics crypto_metrics_;
|
||||
MockCryptoSession* crypto_session_;
|
||||
MockInitializationData* init_data_;
|
||||
MockPolicyEngine* policy_engine_;
|
||||
@@ -193,7 +191,7 @@ TEST_F(CdmLicenseTest, InitWithNullServiceCert) {
|
||||
|
||||
CreateCdmLicense();
|
||||
EXPECT_TRUE(cdm_license_->Init(NULL, kToken, kClientTokenDrmCert,
|
||||
crypto_session_, policy_engine_));
|
||||
crypto_session_, policy_engine_));
|
||||
}
|
||||
|
||||
TEST_F(CdmLicenseTest, PrepareKeyRequestValidation) {
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
// Copyright 2016 Google Inc. All Rights Reserved.
|
||||
|
||||
#include <iostream>
|
||||
#include <tuple>
|
||||
|
||||
#include <gmock/gmock.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "crypto_session.h"
|
||||
#include "license.h"
|
||||
#include "policy_engine.h"
|
||||
@@ -16,8 +14,6 @@
|
||||
// protobuf generated classes.
|
||||
using video_widevine::License;
|
||||
using video_widevine::License_Policy;
|
||||
using video_widevine::LicenseType;
|
||||
using video_widevine::OFFLINE;
|
||||
using video_widevine::STREAMING;
|
||||
|
||||
namespace wvcdm {
|
||||
@@ -80,47 +76,14 @@ class MockCdmEventListener : public WvCdmEventListener {
|
||||
int64_t new_expiry_time_seconds));
|
||||
};
|
||||
|
||||
struct LicenseTypeParam {
|
||||
std::string name;
|
||||
LicenseType license_type;
|
||||
bool can_persist;
|
||||
};
|
||||
|
||||
const LicenseTypeParam kStreamingParam{"Streaming", STREAMING, false};
|
||||
const LicenseTypeParam kOfflineParam{"Offline", OFFLINE, true};
|
||||
|
||||
void PrintTo(const LicenseTypeParam& param, std::ostream* os) {
|
||||
*os << param.name;
|
||||
}
|
||||
|
||||
struct LicenseRenewalParam {
|
||||
std::string name;
|
||||
bool can_renew;
|
||||
int64_t renewal_delay_seconds;
|
||||
};
|
||||
|
||||
const LicenseRenewalParam kNoRenewalParam{"Cannot Renew", false, 0};
|
||||
const LicenseRenewalParam kShortRenewalParam{"Short Renewal Delay", true, 1};
|
||||
const LicenseRenewalParam kLongRenewalParam{"Long Renewal Delay", true, 60};
|
||||
|
||||
void PrintTo(const LicenseRenewalParam& param, std::ostream* os) {
|
||||
*os << param.name;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
class PolicyEngineConstraintsTest
|
||||
: public TestWithParam<std::tuple<LicenseTypeParam, LicenseRenewalParam>> {
|
||||
class PolicyEngineConstraintsTest : public Test {
|
||||
protected:
|
||||
virtual void SetUp() {
|
||||
mock_clock_ = new NiceMock<MockClock>();
|
||||
current_time_ = 0;
|
||||
|
||||
// mock_event_listener_ is a StrictMock, but we don't care about renewal
|
||||
// calls for these tests and want to ignore them.
|
||||
EXPECT_CALL(mock_event_listener_, OnSessionRenewalNeeded(_))
|
||||
.Times(AtLeast(0));
|
||||
|
||||
policy_engine_.reset(new PolicyEngine(kSessionId, &mock_event_listener_,
|
||||
&crypto_session_));
|
||||
InjectMockClock();
|
||||
@@ -146,25 +109,19 @@ class PolicyEngineConstraintsTest
|
||||
}
|
||||
|
||||
void SetupLicense() {
|
||||
LicenseTypeParam typeParam;
|
||||
LicenseRenewalParam renewalParam;
|
||||
std::tie(typeParam, renewalParam) = GetParam();
|
||||
|
||||
license_.set_license_start_time(current_time_);
|
||||
|
||||
LicenseIdentification* id = license_.mutable_id();
|
||||
id->set_version(1);
|
||||
id->set_type(typeParam.license_type);
|
||||
id->set_type(STREAMING);
|
||||
|
||||
License_Policy* policy = license_.mutable_policy();
|
||||
policy = license_.mutable_policy();
|
||||
policy->set_can_play(true);
|
||||
policy->set_can_persist(typeParam.can_persist);
|
||||
policy->set_can_renew(renewalParam.can_renew);
|
||||
policy->set_can_persist(false);
|
||||
policy->set_rental_duration_seconds(kRentalDuration);
|
||||
policy->set_playback_duration_seconds(kPlaybackDuration);
|
||||
policy->set_license_duration_seconds(kStreamingLicenseDuration);
|
||||
policy->set_renewal_delay_seconds(renewalParam.renewal_delay_seconds);
|
||||
|
||||
KeyList* keys = license_.mutable_key();
|
||||
|
||||
@@ -255,23 +212,35 @@ class PolicyEngineConstraintsTest
|
||||
License license_;
|
||||
};
|
||||
|
||||
TEST_P(PolicyEngineConstraintsTest, IsPermissiveWithoutAResolution) {
|
||||
TEST_F(PolicyEngineConstraintsTest, IsPermissiveWithoutAResolution) {
|
||||
EXPECT_CALL(*mock_clock_, GetCurrentTime()).Times(2);
|
||||
EXPECT_CALL(mock_event_listener_, OnExpirationUpdate(kSessionId, _));
|
||||
ExpectSessionKeysChange(kKeyStatusUsable, true);
|
||||
|
||||
{
|
||||
Sequence key_change;
|
||||
ExpectSessionKeysChanges(kKeyId1, kKeyStatusUsable,
|
||||
kKeyId2, kKeyStatusOutputNotAllowed,
|
||||
kKeyId3, kKeyStatusUsable,
|
||||
kKeyId4, kKeyStatusOutputNotAllowed, true);
|
||||
}
|
||||
|
||||
EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _))
|
||||
.WillRepeatedly(
|
||||
DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT),
|
||||
Return(false)));
|
||||
|
||||
policy_engine_->SetLicense(license_);
|
||||
policy_engine_->OnTimerEvent();
|
||||
|
||||
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId1));
|
||||
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId2));
|
||||
EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId2));
|
||||
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId3));
|
||||
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId4));
|
||||
EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId4));
|
||||
EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId5));
|
||||
EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId6));
|
||||
}
|
||||
|
||||
TEST_P(PolicyEngineConstraintsTest, HandlesResolutionsBasedOnConstraints) {
|
||||
TEST_F(PolicyEngineConstraintsTest, HandlesResolutionsBasedOnConstraints) {
|
||||
{
|
||||
Sequence time;
|
||||
for (int i=0; i<4; ++i) {
|
||||
@@ -293,7 +262,6 @@ TEST_P(PolicyEngineConstraintsTest, HandlesResolutionsBasedOnConstraints) {
|
||||
DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT),
|
||||
Return(true)));
|
||||
|
||||
|
||||
policy_engine_->SetLicense(license_);
|
||||
policy_engine_->NotifyResolution(1, kTargetRes1);
|
||||
policy_engine_->OnTimerEvent();
|
||||
@@ -323,7 +291,7 @@ TEST_P(PolicyEngineConstraintsTest, HandlesResolutionsBasedOnConstraints) {
|
||||
EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId6));
|
||||
}
|
||||
|
||||
TEST_P(PolicyEngineConstraintsTest,
|
||||
TEST_F(PolicyEngineConstraintsTest,
|
||||
RequestsHdcpImmediatelyAndOnlyAfterInterval) {
|
||||
EXPECT_CALL(*mock_clock_, GetCurrentTime())
|
||||
.WillOnce(Return(0))
|
||||
@@ -331,17 +299,34 @@ TEST_P(PolicyEngineConstraintsTest,
|
||||
EXPECT_CALL(mock_event_listener_, OnExpirationUpdate(kSessionId, _));
|
||||
ExpectSessionKeysChange(kKeyStatusUsable, true);
|
||||
|
||||
{
|
||||
Sequence key_change;
|
||||
ExpectSessionKeysChanges(kKeyId1, kKeyStatusUsable,
|
||||
kKeyId2, kKeyStatusOutputNotAllowed,
|
||||
kKeyId3, kKeyStatusUsable,
|
||||
kKeyId4, kKeyStatusOutputNotAllowed, true);
|
||||
EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _))
|
||||
.WillOnce(
|
||||
DoAll(SetArgPointee<0>(HDCP_V2_2),
|
||||
Return(false)))
|
||||
.WillOnce(
|
||||
DoAll(SetArgPointee<0>(HDCP_V2_2),
|
||||
Return(false)));
|
||||
}
|
||||
int64_t start_time = current_time_ + 5;
|
||||
{
|
||||
InSequence calls;
|
||||
EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _))
|
||||
.WillOnce(
|
||||
DoAll(SetArgPointee<0>(HDCP_V2_2),
|
||||
Return(true)));
|
||||
Return(false)));
|
||||
EXPECT_CALL(*mock_clock_, GetCurrentTime())
|
||||
.WillOnce(Return(start_time + kHdcpInterval / 2))
|
||||
.WillOnce(Return(start_time + kHdcpInterval));
|
||||
EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _))
|
||||
.WillOnce(
|
||||
DoAll(SetArgPointee<0>(HDCP_V2_2),
|
||||
Return(false)))
|
||||
.WillOnce(
|
||||
DoAll(SetArgPointee<0>(HDCP_V2_2),
|
||||
Return(true)));
|
||||
@@ -354,7 +339,7 @@ TEST_P(PolicyEngineConstraintsTest,
|
||||
policy_engine_->OnTimerEvent();
|
||||
}
|
||||
|
||||
TEST_P(PolicyEngineConstraintsTest, DoesNotRequestHdcpWithoutALicense) {
|
||||
TEST_F(PolicyEngineConstraintsTest, DoesNotRequestHdcpWithoutALicense) {
|
||||
EXPECT_CALL(*mock_clock_, GetCurrentTime())
|
||||
.WillOnce(Return(0));
|
||||
EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)).Times(0);
|
||||
@@ -362,7 +347,7 @@ TEST_P(PolicyEngineConstraintsTest, DoesNotRequestHdcpWithoutALicense) {
|
||||
policy_engine_->OnTimerEvent();
|
||||
}
|
||||
|
||||
TEST_P(PolicyEngineConstraintsTest, HandlesConstraintOverridingHdcp) {
|
||||
TEST_F(PolicyEngineConstraintsTest, HandlesConstraintOverridingHdcp) {
|
||||
{
|
||||
Sequence time;
|
||||
for (int i=0; i<3; ++i) {
|
||||
@@ -404,7 +389,7 @@ TEST_P(PolicyEngineConstraintsTest, HandlesConstraintOverridingHdcp) {
|
||||
EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId6));
|
||||
}
|
||||
|
||||
TEST_P(PolicyEngineConstraintsTest, HandlesNoHdcp) {
|
||||
TEST_F(PolicyEngineConstraintsTest, HandlesNoHdcp) {
|
||||
{
|
||||
Sequence time;
|
||||
for (int i=0; i<3; ++i) {
|
||||
@@ -417,14 +402,13 @@ TEST_P(PolicyEngineConstraintsTest, HandlesNoHdcp) {
|
||||
ExpectSessionKeysChanges(kKeyId1, kKeyStatusUsable,
|
||||
kKeyId2, kKeyStatusOutputNotAllowed,
|
||||
kKeyId3, kKeyStatusUsable,
|
||||
kKeyId4, kKeyStatusOutputNotAllowed, false);
|
||||
kKeyId4, kKeyStatusOutputNotAllowed, true);
|
||||
ExpectSessionKeysChanges(kKeyId1, kKeyStatusUsable,
|
||||
kKeyId2, kKeyStatusOutputNotAllowed,
|
||||
kKeyId3, kKeyStatusOutputNotAllowed,
|
||||
kKeyId4, kKeyStatusOutputNotAllowed, false);
|
||||
}
|
||||
EXPECT_CALL(mock_event_listener_, OnExpirationUpdate(kSessionId, _));
|
||||
ExpectSessionKeysChange(kKeyStatusUsable, true);
|
||||
EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _))
|
||||
.WillRepeatedly(
|
||||
DoAll(SetArgPointee<0>(HDCP_NONE),
|
||||
@@ -451,7 +435,7 @@ TEST_P(PolicyEngineConstraintsTest, HandlesNoHdcp) {
|
||||
EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId6));
|
||||
}
|
||||
|
||||
TEST_P(PolicyEngineConstraintsTest, IgnoresHdcpWithoutAResolution) {
|
||||
TEST_F(PolicyEngineConstraintsTest, UsesDefaultHdcpWhenResolutionNotSet) {
|
||||
{
|
||||
Sequence time;
|
||||
for (int i=0; i<2; ++i) {
|
||||
@@ -459,23 +443,30 @@ TEST_P(PolicyEngineConstraintsTest, IgnoresHdcpWithoutAResolution) {
|
||||
.WillOnce(Return(i * 10));
|
||||
}
|
||||
}
|
||||
ExpectSessionKeysChange(kKeyStatusUsable, true);
|
||||
|
||||
{
|
||||
Sequence key_change;
|
||||
ExpectSessionKeysChanges(kKeyId1, kKeyStatusUsable,
|
||||
kKeyId2, kKeyStatusOutputNotAllowed,
|
||||
kKeyId3, kKeyStatusUsable,
|
||||
kKeyId4, kKeyStatusOutputNotAllowed, true);
|
||||
}
|
||||
|
||||
EXPECT_CALL(mock_event_listener_, OnExpirationUpdate(kSessionId, _));
|
||||
EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)).Times(0);
|
||||
|
||||
EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _))
|
||||
.WillRepeatedly(
|
||||
DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT),
|
||||
Return(false)));
|
||||
|
||||
policy_engine_->SetLicense(license_);
|
||||
policy_engine_->OnTimerEvent();
|
||||
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId1));
|
||||
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId2));
|
||||
EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId2));
|
||||
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId3));
|
||||
EXPECT_TRUE(policy_engine_->CanDecryptContent(kKeyId4));
|
||||
EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId4));
|
||||
EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId5));
|
||||
EXPECT_FALSE(policy_engine_->CanDecryptContent(kKeyId6));
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(Default, PolicyEngineConstraintsTest,
|
||||
Combine(
|
||||
Values(kStreamingParam, kOfflineParam),
|
||||
Values(kNoRenewalParam, kShortRenewalParam, kLongRenewalParam)));
|
||||
|
||||
} // namespace wvcdm
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -44,16 +44,13 @@ const std::string kTestSignedCertificate = a2bs_hex(
|
||||
|
||||
class MockCryptoSession : public CryptoSession {
|
||||
public:
|
||||
MockCryptoSession(metrics::CryptoMetrics* crypto_metrics)
|
||||
: CryptoSession(crypto_metrics) { }
|
||||
MockCryptoSession() : CryptoSession(NULL) { }
|
||||
MOCK_METHOD2(GetRandom, bool(size_t, uint8_t*));
|
||||
};
|
||||
|
||||
class ServiceCertificateTest : public ::testing::Test {
|
||||
protected:
|
||||
virtual void SetUp() {
|
||||
crypto_session_ = new MockCryptoSession(&crypto_metrics_);
|
||||
}
|
||||
virtual void SetUp() { crypto_session_ = new MockCryptoSession(); }
|
||||
|
||||
virtual void TearDown() {
|
||||
if (crypto_session_) delete crypto_session_;
|
||||
@@ -64,7 +61,6 @@ class ServiceCertificateTest : public ::testing::Test {
|
||||
}
|
||||
|
||||
ServiceCertificate* service_certificate_;
|
||||
metrics::CryptoMetrics crypto_metrics_;
|
||||
MockCryptoSession* crypto_session_;
|
||||
};
|
||||
|
||||
@@ -111,7 +107,7 @@ class StubCdmClientPropertySet : public CdmClientPropertySet {
|
||||
};
|
||||
|
||||
TEST_F(ServiceCertificateTest, InitSuccess) {
|
||||
MockCryptoSession crypto_session(&crypto_metrics_);
|
||||
MockCryptoSession crypto_session;
|
||||
|
||||
CreateServiceCertificate();
|
||||
service_certificate_->Init(kTestSessionId1);
|
||||
@@ -119,7 +115,6 @@ TEST_F(ServiceCertificateTest, InitSuccess) {
|
||||
}
|
||||
|
||||
TEST_F(ServiceCertificateTest, InitPrivacyModeRequired) {
|
||||
MockCryptoSession crypto_session(&crypto_metrics_);
|
||||
StubCdmClientPropertySet property_set;
|
||||
|
||||
property_set.enable_privacy_mode();
|
||||
@@ -133,7 +128,6 @@ TEST_F(ServiceCertificateTest, InitPrivacyModeRequired) {
|
||||
}
|
||||
|
||||
TEST_F(ServiceCertificateTest, InitServiceCertificatePresent) {
|
||||
MockCryptoSession crypto_session(&crypto_metrics_);
|
||||
StubCdmClientPropertySet property_set;
|
||||
|
||||
property_set.enable_privacy_mode();
|
||||
@@ -143,16 +137,15 @@ TEST_F(ServiceCertificateTest, InitServiceCertificatePresent) {
|
||||
Properties::AddSessionPropertySet(kTestSessionId1, &property_set);
|
||||
|
||||
CreateServiceCertificate();
|
||||
std::string raw_service_certificate;
|
||||
std::string service_certificate;
|
||||
EXPECT_TRUE(Properties::GetServiceCertificate(kTestSessionId1,
|
||||
&raw_service_certificate));
|
||||
&service_certificate));
|
||||
EXPECT_EQ(NO_ERROR,
|
||||
service_certificate_->Init(raw_service_certificate));
|
||||
service_certificate_->Init(service_certificate));
|
||||
EXPECT_TRUE(service_certificate_->HasCertificate());
|
||||
}
|
||||
|
||||
TEST_F(ServiceCertificateTest, SetServiceCertificate) {
|
||||
MockCryptoSession crypto_session(&crypto_metrics_);
|
||||
StubCdmClientPropertySet property_set;
|
||||
|
||||
property_set.enable_privacy_mode();
|
||||
|
||||
@@ -249,6 +249,12 @@ void PrintTo(const enum CdmResponseType& value, ::std::ostream* os) {
|
||||
case RELEASE_ALL_USAGE_INFO_ERROR_2:
|
||||
*os << "RELEASE_ALL_USAGE_INFO_ERROR_2";
|
||||
break;
|
||||
case RELEASE_ALL_USAGE_INFO_ERROR_3:
|
||||
*os << "RELEASE_ALL_USAGE_INFO_ERROR_3";
|
||||
break;
|
||||
case RELEASE_ALL_USAGE_INFO_ERROR_4:
|
||||
*os << "RELEASE_ALL_USAGE_INFO_ERROR_4";
|
||||
break;
|
||||
case RELEASE_KEY_ERROR: *os << "RELEASE_KEY_ERROR";
|
||||
break;
|
||||
case RELEASE_KEY_REQUEST_ERROR: *os << "RELEASE_KEY_REQUEST_ERROR";
|
||||
@@ -302,8 +308,6 @@ void PrintTo(const enum CdmResponseType& value, ::std::ostream* os) {
|
||||
break;
|
||||
case STORE_LICENSE_ERROR_2: *os << "STORE_LICENSE_ERROR_2";
|
||||
break;
|
||||
case STORE_LICENSE_ERROR_4: *os << "STORE_LICENSE_ERROR_4";
|
||||
break;
|
||||
case STORE_USAGE_INFO_ERROR: *os << "STORE_USAGE_INFO_ERROR";
|
||||
break;
|
||||
case UNPROVISION_ERROR_1: *os << "UNPROVISION_ERROR_1";
|
||||
@@ -450,6 +454,8 @@ void PrintTo(const enum CdmResponseType& value, ::std::ostream* os) {
|
||||
break;
|
||||
case INVALID_PARAMETERS_ENG_17: *os << "INVALID_PARAMETERS_ENG_17";
|
||||
break;
|
||||
case INVALID_PARAMETERS_ENG_18: *os << "INVALID_PARAMETERS_ENG_18";
|
||||
break;
|
||||
case CERT_PROVISIONING_CLIENT_TOKEN_ERROR_1:
|
||||
*os << "CERT_PROVISIONING_CLIENT_TOKEN_ERROR_1";
|
||||
break;
|
||||
@@ -478,8 +484,6 @@ void PrintTo(const enum CdmResponseType& value, ::std::ostream* os) {
|
||||
case LOAD_USAGE_HEADER_UNKNOWN_ERROR:
|
||||
*os << "LOAD_USAGE_HEADER_UNKNOWN_ERROR";
|
||||
break;
|
||||
case INVALID_PARAMETERS_ENG_18: *os << "INVALID_PARAMETERS_ENG_18";
|
||||
break;
|
||||
case INSUFFICIENT_CRYPTO_RESOURCES_3:
|
||||
*os << "INSUFFICIENT_CRYPTO_RESOURCES_3";
|
||||
break;
|
||||
@@ -515,8 +519,6 @@ void PrintTo(const enum CdmResponseType& value, ::std::ostream* os) {
|
||||
case COPY_OLD_USAGE_ENTRY_UNKNOWN_ERROR:
|
||||
*os << "COPY_OLD_USAGE_ENTRY_UNKNOWN_ERROR";
|
||||
break;
|
||||
case LIST_LICENSES_ERROR: *os << "LIST_LICENSES_ERROR";
|
||||
break;
|
||||
case INVALID_PARAMETERS_ENG_23:
|
||||
*os << "INVALID_PARAMETERS_ENG_23";
|
||||
break;
|
||||
@@ -552,15 +554,6 @@ void PrintTo(const enum CdmResponseType& value, ::std::ostream* os) {
|
||||
break;
|
||||
case USAGE_INVALID_LOAD_ENTRY: *os << "USAGE_INVALID_LOAD_ENTRY";
|
||||
break;
|
||||
case RELEASE_ALL_USAGE_INFO_ERROR_4:
|
||||
*os << "RELEASE_ALL_USAGE_INFO_ERROR_4";
|
||||
break;
|
||||
case RELEASE_ALL_USAGE_INFO_ERROR_5:
|
||||
*os << "RELEASE_ALL_USAGE_INFO_ERROR_5";
|
||||
break;
|
||||
case RELEASE_ALL_USAGE_INFO_ERROR_6:
|
||||
*os << "RELEASE_ALL_USAGE_INFO_ERROR_6";
|
||||
break;
|
||||
case RELEASE_USAGE_INFO_FAILED: *os << "RELEASE_USAGE_INFO_FAILED";
|
||||
break;
|
||||
case INCORRECT_USAGE_SUPPORT_TYPE_1:
|
||||
@@ -575,8 +568,11 @@ void PrintTo(const enum CdmResponseType& value, ::std::ostream* os) {
|
||||
case KEY_NOT_FOUND_IN_SESSION:
|
||||
*os << "KEY_NOT_FOUND_IN_SESSION";
|
||||
break;
|
||||
case NO_USAGE_ENTRIES:
|
||||
*os << "NO_USAGE_ENTRIES";
|
||||
case NO_USAGE_ENTRIES: *os << "NO_USAGE_ENTRIES";
|
||||
break;
|
||||
case LIST_LICENSE_ERROR_1: *os << "LIST_LICENSE_ERROR_1";
|
||||
break;
|
||||
case LIST_LICENSE_ERROR_2: *os << "LIST_LICENSE_ERROR_2";
|
||||
break;
|
||||
case LIST_USAGE_ERROR_1: *os << "LIST_USAGE_ERROR_1";
|
||||
break;
|
||||
@@ -588,24 +584,6 @@ void PrintTo(const enum CdmResponseType& value, ::std::ostream* os) {
|
||||
break;
|
||||
case DELETE_USAGE_ERROR_3: *os << "DELETE_USAGE_ERROR_3";
|
||||
break;
|
||||
case PRIVACY_MODE_ERROR_1: *os << "PRIVACY_MODE_ERROR_1";
|
||||
break;
|
||||
case PRIVACY_MODE_ERROR_2: *os << "PRIVACY_MODE_ERROR_2";
|
||||
break;
|
||||
case PRIVACY_MODE_ERROR_3: *os << "PRIVACY_MODE_ERROR_3";
|
||||
break;
|
||||
case EMPTY_RESPONSE_ERROR_1: *os << "EMPTY_RESPONSE_ERROR_1";
|
||||
break;
|
||||
case INVALID_PARAMETERS_ENG_24: *os << "INVALID_PARAMETERS_ENG_24";
|
||||
break;
|
||||
case PARSE_RESPONSE_ERROR_1: *os << "PARSE_RESPONSE_ERROR_1";
|
||||
break;
|
||||
case PARSE_RESPONSE_ERROR_2: *os << "PARSE_RESPONSE_ERROR_2";
|
||||
break;
|
||||
case PARSE_RESPONSE_ERROR_3: *os << "PARSE_RESPONSE_ERROR_3";
|
||||
break;
|
||||
case PARSE_RESPONSE_ERROR_4: *os << "PARSE_RESPONSE_ERROR_4";
|
||||
break;
|
||||
|
||||
default:
|
||||
*os << "Unknown CdmResponseType";
|
||||
|
||||
@@ -167,9 +167,9 @@ bool UrlRequest::PostRequest(const std::string& data) {
|
||||
|
||||
bool UrlRequest::PostCertRequestInQueryString(const std::string& data) {
|
||||
std::string path = socket_.resource_path();
|
||||
path.append("&signedRequest=");
|
||||
path.append((path.find('?') == std::string::npos) ? "?" : "&");
|
||||
path.append("signedRequest=");
|
||||
path.append(data);
|
||||
|
||||
return PostRequestWithPath(path, "");
|
||||
}
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ const CdmUsageEntryInfo kUsageEntryInfoSecureStop3 = {
|
||||
.key_set_id = "secure_stop_key_set_3",
|
||||
.usage_info_file_name = "usage_info_file_3"};
|
||||
const CdmUsageEntryInfo kUsageEntryInfoStorageTypeUnknown = {
|
||||
.storage_type = kStorageUnknown,
|
||||
.storage_type = kStorageTypeUnknown,
|
||||
.key_set_id = "",
|
||||
.usage_info_file_name = ""};
|
||||
const std::vector<std::string> kEmptyLicenseList;
|
||||
@@ -140,8 +140,7 @@ class MockDeviceFiles : public DeviceFiles {
|
||||
|
||||
class MockCryptoSession : public CryptoSession {
|
||||
public:
|
||||
MockCryptoSession(metrics::CryptoMetrics* metrics)
|
||||
: CryptoSession(metrics) {}
|
||||
MockCryptoSession() : CryptoSession(NULL) {}
|
||||
MOCK_METHOD1(Open, CdmResponseType(SecurityLevel));
|
||||
MOCK_METHOD1(LoadUsageTableHeader,
|
||||
CdmResponseType(const CdmUsageTableHeader&));
|
||||
@@ -171,7 +170,7 @@ class UsageTableHeaderTest : public ::testing::Test {
|
||||
virtual void SetUp() {
|
||||
// UsageTableHeader will take ownership of the pointer
|
||||
device_files_ = new MockDeviceFiles();
|
||||
crypto_session_ = new MockCryptoSession(&crypto_metrics_);
|
||||
crypto_session_ = new MockCryptoSession();
|
||||
usage_table_header_ = new UsageTableHeader();
|
||||
|
||||
// usage_table_header_ object takes ownership of these objects
|
||||
@@ -197,7 +196,6 @@ class UsageTableHeaderTest : public ::testing::Test {
|
||||
}
|
||||
|
||||
MockDeviceFiles* device_files_;
|
||||
metrics::CryptoMetrics crypto_metrics_;
|
||||
MockCryptoSession* crypto_session_;
|
||||
UsageTableHeader* usage_table_header_;
|
||||
};
|
||||
@@ -252,6 +250,8 @@ TEST_P(UsageTableHeaderInitializationTest, Upgrade_UnableToRetrieveLicenses) {
|
||||
EXPECT_CALL(*crypto_session_, CreateUsageTableHeader(NotNull()))
|
||||
.WillOnce(
|
||||
DoAll(SetArgPointee<0>(kEmptyUsageTableHeader), Return(NO_ERROR)));
|
||||
// TODO: Why not being called?
|
||||
//EXPECT_CALL(*device_files_, DeleteAllLicenses()).WillOnce(Return(true));
|
||||
EXPECT_CALL(*device_files_, StoreUsageTableInfo(kEmptyUsageTableHeader,
|
||||
kEmptyUsageEntryInfoVector))
|
||||
.Times(2)
|
||||
|
||||
Reference in New Issue
Block a user