diff --git a/libwvdrmengine/build_and_run_all_unit_tests.sh b/libwvdrmengine/build_and_run_all_unit_tests.sh index b9f26aa8..31c0d78a 100755 --- a/libwvdrmengine/build_and_run_all_unit_tests.sh +++ b/libwvdrmengine/build_and_run_all_unit_tests.sh @@ -64,6 +64,7 @@ try_adb_push $OUT/system/bin/license_unittest try_adb_push $OUT/system/bin/license_keys_unittest try_adb_push $OUT/system/bin/initialization_data_unittest try_adb_push $OUT/system/bin/device_files_unittest +try_adb_push $OUT/system/bin/service_certificate_unittest try_adb_push $OUT/system/bin/timer_unittest try_adb_push $OUT/system/bin/libwvdrmengine_test try_adb_push $OUT/system/bin/buffer_reader_test diff --git a/libwvdrmengine/cdm/core/src/service_certificate.cpp b/libwvdrmengine/cdm/core/src/service_certificate.cpp index 18ed3f8e..bc8d9837 100644 --- a/libwvdrmengine/cdm/core/src/service_certificate.cpp +++ b/libwvdrmengine/cdm/core/src/service_certificate.cpp @@ -95,18 +95,20 @@ bool ServiceCertificate::IsAvailable() { CdmResponseType ServiceCertificate::VerifyAndSet( const std::string& signed_service_certificate) { CdmResponseType status; - std::string certificate; bool has_provider_id; status = VerifyAndExtractFromSignedCertificate(signed_service_certificate, - &certificate, &has_provider_id, + &certificate_, + &has_provider_id, NULL); - if (status == NO_ERROR) { - Properties::SetServiceCertificate(session_id_, certificate); - } else { + if (status != NO_ERROR) { LOGE("ServiceCertificate::VerifyAndSet: verify and extract failed with " "status %d", status); + return status; } - return status; + + Properties::SetServiceCertificate(session_id_, signed_service_certificate); + valid_ = true; + return NO_ERROR; } bool ServiceCertificate::PrepareServiceCertificateRequest( @@ -130,7 +132,7 @@ bool ServiceCertificate::PrepareServiceCertificateRequest( CdmResponseType ServiceCertificate::VerifyAndExtractFromSignedCertificate( const std::string& signed_certificate, std::string* certificate, - bool* has_provider_id, std::string* provider_id) { + bool* /* has_provider_id */, std::string* /* provider_id */) { SignedDrmDeviceCertificate signed_service_certificate; if (!signed_service_certificate.ParseFromString(signed_certificate)) { LOGE( @@ -185,7 +187,8 @@ CdmResponseType ServiceCertificate::VerifyAndExtractFromSignedCertificate( } #endif - if (certificate != NULL) { + if (certificate != NULL && + !signed_service_certificate.drm_certificate().empty()) { *certificate = signed_service_certificate.drm_certificate(); } return NO_ERROR; @@ -246,11 +249,16 @@ bool ServiceCertificate::SetupServiceCertificate() { certificate_.clear(); if (!Properties::GetServiceCertificate(session_id_, &signed_certificate)) { + LOGV("ServiceCertificate::SetupServiceCertificate: no signed service " + "certificate set"); return false; } if (signed_certificate.empty()) { + LOGV("ServiceCertificate::SetupServiceCertificate: service certificate " + "empty"); return false; } + std::string extracted_certificate; std::string extracted_provider_id; bool has_provider_id; @@ -259,9 +267,6 @@ bool ServiceCertificate::SetupServiceCertificate() { &has_provider_id, &extracted_provider_id)) { return false; } - if (extracted_certificate.empty()) { - return false; - } has_provider_id_ = has_provider_id; if (has_provider_id_) { provider_id_ = extracted_provider_id; diff --git a/libwvdrmengine/cdm/core/test/service_certificate_unittest.cpp b/libwvdrmengine/cdm/core/test/service_certificate_unittest.cpp new file mode 100644 index 00000000..94549057 --- /dev/null +++ b/libwvdrmengine/cdm/core/test/service_certificate_unittest.cpp @@ -0,0 +1,176 @@ +// Copyright 2013 Google Inc. All Rights Reserved. + +#include "service_certificate.h" +#include +#include +#include +#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()); +} +} diff --git a/libwvdrmengine/cdm/test/Android.mk b/libwvdrmengine/cdm/test/Android.mk index e764770f..b76ab09e 100644 --- a/libwvdrmengine/cdm/test/Android.mk +++ b/libwvdrmengine/cdm/test/Android.mk @@ -63,6 +63,10 @@ test_name := request_license_test test_src_dir := . include $(LOCAL_PATH)/unit-test.mk +test_name := service_certificate_unittest +test_src_dir := ../core/test +include $(LOCAL_PATH)/unit-test.mk + test_name := timer_unittest test_src_dir := . include $(LOCAL_PATH)/unit-test.mk diff --git a/libwvdrmengine/run_all_unit_tests.sh b/libwvdrmengine/run_all_unit_tests.sh index 3e932b3a..039e1c36 100755 --- a/libwvdrmengine/run_all_unit_tests.sh +++ b/libwvdrmengine/run_all_unit_tests.sh @@ -80,6 +80,7 @@ adb_shell_run license_unittest adb_shell_run license_keys_unittest adb_shell_run initialization_data_unittest adb_shell_run device_files_unittest +adb_shell_run service_certificate_unittest adb_shell_run timer_unittest adb_shell_run buffer_reader_test