Fix CanSetServiceCertificate Test

(This is a merge of http://go/wvgerrit/14783)

When validation was added to the service certificate property, it
broke the associated test, which sends random data. It also did not
do any testing of the new validation itself.

This fix makes the validation method on WvContentDecryptionModule
non-static so that it can be mocked and handled appropriately in the
test.

Bug: 21923281
Change-Id: Id5d2315709fce35f9347b3545f594371810349f0
This commit is contained in:
John "Juce" Bruce
2015-06-18 18:54:19 -07:00
parent 968993cd05
commit 89682556ad
4 changed files with 25 additions and 8 deletions

View File

@@ -25,7 +25,6 @@ class WvContentDecryptionModule : public android::RefBase, public TimerHandler {
static bool IsSupported(const std::string& init_data_type); static bool IsSupported(const std::string& init_data_type);
static bool IsCenc(const std::string& init_data_type); static bool IsCenc(const std::string& init_data_type);
static bool IsWebm(const std::string& init_data_type); static bool IsWebm(const std::string& init_data_type);
static bool IsValidServiceCertificate(const std::string& certificate);
// Session related methods // Session related methods
virtual CdmResponseType OpenSession(const CdmKeySystem& key_system, virtual CdmResponseType OpenSession(const CdmKeySystem& key_system,
@@ -116,6 +115,9 @@ class WvContentDecryptionModule : public android::RefBase, public TimerHandler {
virtual void NotifyResolution(const CdmSessionId& session_id, uint32_t width, virtual void NotifyResolution(const CdmSessionId& session_id, uint32_t width,
uint32_t height); uint32_t height);
// Validate a passed-in service certificate
virtual bool IsValidServiceCertificate(const std::string& certificate);
private: private:
uint32_t GenerateSessionSharingId(); uint32_t GenerateSessionSharingId();

View File

@@ -38,11 +38,6 @@ bool WvContentDecryptionModule::IsWebm(const std::string& init_data_type) {
return InitializationData(init_data_type).is_webm(); return InitializationData(init_data_type).is_webm();
} }
bool WvContentDecryptionModule::IsValidServiceCertificate(
const std::string& certificate) {
return CdmLicense::VerifySignedServiceCertificate(certificate) == NO_ERROR;
}
CdmResponseType WvContentDecryptionModule::OpenSession( CdmResponseType WvContentDecryptionModule::OpenSession(
const CdmKeySystem& key_system, CdmClientPropertySet* property_set, const CdmKeySystem& key_system, CdmClientPropertySet* property_set,
const std::string& origin, WvCdmEventListener* event_listener, const std::string& origin, WvCdmEventListener* event_listener,
@@ -214,6 +209,11 @@ void WvContentDecryptionModule::NotifyResolution(const CdmSessionId& session_id,
cdm_engine_->NotifyResolution(session_id, width, height); cdm_engine_->NotifyResolution(session_id, width, height);
} }
bool WvContentDecryptionModule::IsValidServiceCertificate(
const std::string& certificate) {
return CdmLicense::VerifySignedServiceCertificate(certificate) == NO_ERROR;
}
void WvContentDecryptionModule::EnablePolicyTimer() { void WvContentDecryptionModule::EnablePolicyTimer() {
AutoLock auto_lock(policy_timer_lock_); AutoLock auto_lock(policy_timer_lock_);
if (!policy_timer_.IsRunning()) if (!policy_timer_.IsRunning())

View File

@@ -585,8 +585,7 @@ status_t WVDrmPlugin::setPropertyByteArray(const String8& name,
const Vector<uint8_t>& value) { const Vector<uint8_t>& value) {
if (name == "serviceCertificate") { if (name == "serviceCertificate") {
std::string cert(value.begin(), value.end()); std::string cert(value.begin(), value.end());
if (value.isEmpty() || if (value.isEmpty() || mCDM->IsValidServiceCertificate(cert)) {
WvContentDecryptionModule::IsValidServiceCertificate(cert)) {
mPropertySet.set_service_certificate(cert); mPropertySet.set_service_certificate(cert);
} else { } else {
return android::BAD_VALUE; return android::BAD_VALUE;

View File

@@ -92,6 +92,8 @@ class MockCDM : public WvContentDecryptionModule {
MOCK_METHOD1(ReleaseUsageInfo, MOCK_METHOD1(ReleaseUsageInfo,
CdmResponseType(const CdmUsageInfoReleaseMessage&)); CdmResponseType(const CdmUsageInfoReleaseMessage&));
MOCK_METHOD1(IsValidServiceCertificate, bool(const std::string&));
}; };
class MockCrypto : public WVGenericCryptoInterface { class MockCrypto : public WVGenericCryptoInterface {
@@ -1702,6 +1704,8 @@ TEST_F(WVDrmPluginTest, CanSetServiceCertificate) {
Vector<uint8_t> privacyCert; Vector<uint8_t> privacyCert;
privacyCert.appendArray(privacyCertRaw, kPrivacyCertSize); privacyCert.appendArray(privacyCertRaw, kPrivacyCertSize);
std::string strPrivacyCert(reinterpret_cast<char*>(privacyCertRaw),
kPrivacyCertSize);
Vector<uint8_t> emptyVector; Vector<uint8_t> emptyVector;
// Provide expected mock behavior // Provide expected mock behavior
@@ -1721,6 +1725,13 @@ TEST_F(WVDrmPluginTest, CanSetServiceCertificate) {
.Times(AtLeast(0)); .Times(AtLeast(0));
} }
// Validate that the certificate is validated. Accept it once and reject it
// once. Note that there is no expected call for when the certificate is
// cleared.
EXPECT_CALL(*cdm, IsValidServiceCertificate(strPrivacyCert))
.WillOnce(Return(true))
.WillOnce(Return(false));
plugin.openSession(sessionId); plugin.openSession(sessionId);
ASSERT_THAT(propertySet, NotNull()); ASSERT_THAT(propertySet, NotNull());
@@ -1736,6 +1747,11 @@ TEST_F(WVDrmPluginTest, CanSetServiceCertificate) {
res = plugin.setPropertyByteArray(String8("serviceCertificate"), emptyVector); res = plugin.setPropertyByteArray(String8("serviceCertificate"), emptyVector);
ASSERT_EQ(OK, res); ASSERT_EQ(OK, res);
EXPECT_EQ(0u, propertySet->service_certificate().size()); EXPECT_EQ(0u, propertySet->service_certificate().size());
// Test setting a certificate and having it fail
res = plugin.setPropertyByteArray(String8("serviceCertificate"), privacyCert);
ASSERT_NE(OK, res);
EXPECT_EQ(0u, propertySet->service_certificate().size());
} }
TEST_F(WVDrmPluginTest, CanSetSessionSharing) { TEST_F(WVDrmPluginTest, CanSetSessionSharing) {