Correct setting of service certificate.

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

The service certificate was setup correctly if specified in mediadrm
properties. If instead the service certificate was later fetched from
the license service, it would not be marked as valid. This led to an
infinite loop of service certificate fetches and processing. This
prevented the license from being fetched and playback failures.

b/34638410

Test: Verified by new service certificate unittests + Hulu playback
using fugu.

Change-Id: I2a4f8754614fccdad3c80d3e13fba0b44d177d61
This commit is contained in:
Rahul Frias
2017-01-27 02:44:38 -08:00
parent ace09c710f
commit ee5aff7706
5 changed files with 198 additions and 11 deletions

View File

@@ -0,0 +1,176 @@
// Copyright 2013 Google Inc. All Rights Reserved.
#include "service_certificate.h"
#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"
#include "wv_cdm_types.h"
namespace wvcdm {
namespace {
const CdmSessionId kTestSessionId1 = "sid1";
const CdmSessionId kTestSessionId2 = "sid2";
const std::string kAppId = "com.example.test";
const std::string kTestSignedCertificate = a2bs_hex(
"0AC102080312101705B917CC1204868B06333A2F772A8C1882B4829205228E023082010A02"
"8201010099ED5B3B327DAB5E24EFC3B62A95B598520AD5BCCB37503E0645B814D876B8DF40"
"510441AD8CE3ADB11BB88C4E725A5E4A9E0795291D58584023A7E1AF0E38A9127939300861"
"0B6F158C878C7E21BFFBFEEA77E1019E1E5781E8A45F46263D14E60E8058A8607ADCE04FAC"
"8457B137A8D67CCDEB33705D983A21FB4EECBD4A10CA47490CA47EAA5D438218DDBAF1CADE"
"3392F13D6FFB6442FD31E1BF40B0C604D1C4BA4C9520A4BF97EEBD60929AFCEEF55BBAF564"
"E2D0E76CD7C55C73A082B996120B8359EDCE24707082680D6F67C6D82C4AC5F3134490A74E"
"EC37AF4B2F010C59E82843E2582F0B6B9F5DB0FC5E6EDF64FBD308B4711BCF1250019C9F5A"
"0902030100013A146C6963656E73652E7769646576696E652E636F6D128003AE347314B5A8"
"35297F271388FB7BB8CB5277D249823CDDD1DA30B93339511EB3CCBDEA04B944B927C12134"
"6EFDBDEAC9D413917E6EC176A10438460A503BC1952B9BA4E4CE0FC4BFC20A9808AAAF4BFC"
"D19C1DCFCDF574CCAC28D1B410416CF9DE8804301CBDB334CAFCD0D40978423A642E54613D"
"F0AFCF96CA4A9249D855E42B3A703EF1767F6A9BD36D6BF82BE76BBF0CBA4FDE59D2ABCC76"
"FEB64247B85C431FBCA52266B619FC36979543FCA9CBBDBBFAFA0E1A55E755A3C7BCE655F9"
"646F582AB9CF70AA08B979F867F63A0B2B7FDB362C5BC4ECD555D85BCAA9C593C383C857D4"
"9DAAB77E40B7851DDFD24998808E35B258E75D78EAC0CA16F7047304C20D93EDE4E8FF1C6F"
"17E6243E3F3DA8FC1709870EC45FBA823A263F0CEFA1F7093B1909928326333705043A29BD"
"A6F9B4342CC8DF543CB1A1182F7C5FFF33F10490FACA5B25360B76015E9C5A06AB8EE02F00"
"D2E8D5986104AACC4DD475FD96EE9CE4E326F21B83C7058577B38732CDDABC6A6BED13FB0D"
"49D38A45EB87A5F4");
} // unnamed namespace
class MockCryptoSession : public CryptoSession {
public:
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_;
};
class StubCdmClientPropertySet : public CdmClientPropertySet {
public:
StubCdmClientPropertySet()
: security_level_(QUERY_VALUE_SECURITY_LEVEL_L1),
use_privacy_mode_(false),
is_session_sharing_enabled_(false),
session_sharing_id_(0),
app_id_(kAppId) {}
virtual const std::string& security_level() const { return security_level_; }
virtual bool use_privacy_mode() const { return use_privacy_mode_; }
virtual const std::string& service_certificate() const {
return service_certificate_;
}
virtual void set_service_certificate(const std::string& cert) {
service_certificate_ = cert;
}
virtual const std::string& device_provisioning_service_certificate() const {
return device_provisioning_service_certificate_;
}
virtual void set_device_provisioning_service_certificate(
const std::string& cert) {
device_provisioning_service_certificate_ = cert;
}
virtual bool is_session_sharing_enabled() const {
return is_session_sharing_enabled_;
}
virtual uint32_t session_sharing_id() const { return session_sharing_id_; }
virtual void set_session_sharing_id(uint32_t id) { session_sharing_id_ = id; }
virtual const std::string& app_id() const { return app_id_; }
void enable_privacy_mode() { use_privacy_mode_ = true; }
private:
std::string security_level_;
std::string service_certificate_;
std::string device_provisioning_service_certificate_;
bool use_privacy_mode_;
bool is_session_sharing_enabled_;
uint32_t session_sharing_id_;
std::string app_id_;
};
TEST_F(ServiceCertificateTest, InitSuccess) {
MockCryptoSession crypto_session;
CreateServiceCertificate();
service_certificate_->Init(kTestSessionId1, &crypto_session);
EXPECT_FALSE(service_certificate_->IsRequired());
EXPECT_FALSE(service_certificate_->IsAvailable());
}
TEST_F(ServiceCertificateTest, InitPrivacyModeRequired) {
MockCryptoSession crypto_session;
StubCdmClientPropertySet property_set;
property_set.enable_privacy_mode();
Properties::Init();
Properties::AddSessionPropertySet(kTestSessionId1, &property_set);
CreateServiceCertificate();
service_certificate_->Init(kTestSessionId1, &crypto_session);
EXPECT_TRUE(service_certificate_->IsRequired());
EXPECT_FALSE(service_certificate_->IsAvailable());
}
TEST_F(ServiceCertificateTest, InitServiceCertificatePresent) {
MockCryptoSession crypto_session;
StubCdmClientPropertySet property_set;
property_set.enable_privacy_mode();
property_set.set_service_certificate(kTestSignedCertificate);
Properties::Init();
Properties::AddSessionPropertySet(kTestSessionId1, &property_set);
CreateServiceCertificate();
service_certificate_->Init(kTestSessionId1, &crypto_session);
EXPECT_TRUE(service_certificate_->IsRequired());
EXPECT_TRUE(service_certificate_->IsAvailable());
}
TEST_F(ServiceCertificateTest, SetServiceCertificate) {
MockCryptoSession crypto_session;
StubCdmClientPropertySet property_set;
property_set.enable_privacy_mode();
Properties::Init();
Properties::AddSessionPropertySet(kTestSessionId1, &property_set);
CreateServiceCertificate();
service_certificate_->Init(kTestSessionId1, &crypto_session);
EXPECT_TRUE(service_certificate_->IsRequired());
EXPECT_FALSE(service_certificate_->IsAvailable());
EXPECT_EQ(NO_ERROR,
service_certificate_->VerifyAndSet(kTestSignedCertificate));
EXPECT_TRUE(service_certificate_->IsRequired());
EXPECT_TRUE(service_certificate_->IsAvailable());
}
}