| // Copyright (c) 2012 The Chromium OS Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| #include <string> | |
| #include <base/strings/string_util.h> | |
| #include <base/strings/stringprintf.h> | |
| #include <gmock/gmock.h> | |
| #include <gtest/gtest.h> | |
| #include <metrics/metrics_library_mock.h> | |
| #include "update_engine/certificate_checker.h" | |
| #include "update_engine/certificate_checker_mock.h" | |
| #include "update_engine/constants.h" | |
| #include "update_engine/fake_system_state.h" | |
| #include "update_engine/prefs_mock.h" | |
| using ::testing::_; | |
| using ::testing::DoAll; | |
| using ::testing::Return; | |
| using ::testing::SetArgumentPointee; | |
| using ::testing::SetArrayArgument; | |
| using std::string; | |
| namespace chromeos_update_engine { | |
| class CertificateCheckerTest : public testing::Test { | |
| public: | |
| CertificateCheckerTest() {} | |
| protected: | |
| virtual void SetUp() { | |
| depth_ = 0; | |
| length_ = 4; | |
| digest_[0] = 0x17; | |
| digest_[1] = 0x7D; | |
| digest_[2] = 0x07; | |
| digest_[3] = 0x5F; | |
| digest_hex_ = "177D075F"; | |
| diff_digest_hex_ = "1234ABCD"; | |
| cert_key_prefix_ = kPrefsUpdateServerCertificate; | |
| server_to_check_ = CertificateChecker::kUpdate; | |
| cert_key_ = base::StringPrintf("%s-%d-%d", | |
| cert_key_prefix_.c_str(), | |
| server_to_check_, | |
| depth_); | |
| kCertChanged = "Updater.ServerCertificateChanged"; | |
| kCertFailed = "Updater.ServerCertificateFailed"; | |
| CertificateChecker::set_system_state(&fake_system_state_); | |
| CertificateChecker::set_openssl_wrapper(&openssl_wrapper_); | |
| prefs_ = fake_system_state_.mock_prefs(); | |
| } | |
| virtual void TearDown() {} | |
| FakeSystemState fake_system_state_; | |
| PrefsMock* prefs_; // shortcut to fake_system_state_.mock_prefs() | |
| OpenSSLWrapperMock openssl_wrapper_; | |
| // Parameters of our mock certificate digest. | |
| int depth_; | |
| unsigned int length_; | |
| unsigned char digest_[4]; | |
| string digest_hex_; | |
| string diff_digest_hex_; | |
| string cert_key_prefix_; | |
| CertificateChecker::ServerToCheck server_to_check_; | |
| string cert_key_; | |
| string kCertChanged; | |
| string kCertFailed; | |
| }; | |
| // check certificate change, new | |
| TEST_F(CertificateCheckerTest, NewCertificate) { | |
| EXPECT_CALL(openssl_wrapper_, GetCertificateDigest(nullptr, _, _, _)) | |
| .WillOnce(DoAll( | |
| SetArgumentPointee<1>(depth_), | |
| SetArgumentPointee<2>(length_), | |
| SetArrayArgument<3>(digest_, digest_ + 4), | |
| Return(true))); | |
| EXPECT_CALL(*prefs_, GetString(cert_key_, _)) | |
| .WillOnce(Return(false)); | |
| EXPECT_CALL(*prefs_, SetString(cert_key_, digest_hex_)) | |
| .WillOnce(Return(true)); | |
| ASSERT_TRUE(CertificateChecker::CheckCertificateChange( | |
| server_to_check_, 1, nullptr)); | |
| } | |
| // check certificate change, unchanged | |
| TEST_F(CertificateCheckerTest, SameCertificate) { | |
| EXPECT_CALL(openssl_wrapper_, GetCertificateDigest(nullptr, _, _, _)) | |
| .WillOnce(DoAll( | |
| SetArgumentPointee<1>(depth_), | |
| SetArgumentPointee<2>(length_), | |
| SetArrayArgument<3>(digest_, digest_ + 4), | |
| Return(true))); | |
| EXPECT_CALL(*prefs_, GetString(cert_key_, _)) | |
| .WillOnce(DoAll( | |
| SetArgumentPointee<1>(digest_hex_), | |
| Return(true))); | |
| EXPECT_CALL(*prefs_, SetString(_, _)).Times(0); | |
| ASSERT_TRUE(CertificateChecker::CheckCertificateChange( | |
| server_to_check_, 1, nullptr)); | |
| } | |
| // check certificate change, changed | |
| TEST_F(CertificateCheckerTest, ChangedCertificate) { | |
| EXPECT_CALL(openssl_wrapper_, GetCertificateDigest(nullptr, _, _, _)) | |
| .WillOnce(DoAll( | |
| SetArgumentPointee<1>(depth_), | |
| SetArgumentPointee<2>(length_), | |
| SetArrayArgument<3>(digest_, digest_ + 4), | |
| Return(true))); | |
| EXPECT_CALL(*prefs_, GetString(cert_key_, _)) | |
| .WillOnce(DoAll( | |
| SetArgumentPointee<1>(diff_digest_hex_), | |
| Return(true))); | |
| EXPECT_CALL(*prefs_, SetString(kPrefsCertificateReportToSendUpdate, | |
| kCertChanged)) | |
| .WillOnce(Return(true)); | |
| EXPECT_CALL(*prefs_, SetString(cert_key_, digest_hex_)) | |
| .WillOnce(Return(true)); | |
| ASSERT_TRUE(CertificateChecker::CheckCertificateChange( | |
| server_to_check_, 1, nullptr)); | |
| } | |
| // check certificate change, failed | |
| TEST_F(CertificateCheckerTest, FailedCertificate) { | |
| EXPECT_CALL(*prefs_, SetString(kPrefsCertificateReportToSendUpdate, | |
| kCertFailed)) | |
| .WillOnce(Return(true)); | |
| EXPECT_CALL(*prefs_, GetString(_, _)).Times(0); | |
| EXPECT_CALL(openssl_wrapper_, GetCertificateDigest(_, _, _, _)).Times(0); | |
| ASSERT_FALSE(CertificateChecker::CheckCertificateChange( | |
| server_to_check_, 0, nullptr)); | |
| } | |
| // flush send report | |
| TEST_F(CertificateCheckerTest, FlushReport) { | |
| EXPECT_CALL(*prefs_, GetString(kPrefsCertificateReportToSendUpdate, _)) | |
| .WillOnce(DoAll( | |
| SetArgumentPointee<1>(kCertChanged), | |
| Return(true))); | |
| EXPECT_CALL(*prefs_, GetString(kPrefsCertificateReportToSendDownload, _)) | |
| .WillOnce(Return(false)); | |
| EXPECT_CALL(*fake_system_state_.mock_metrics_lib(), | |
| SendUserActionToUMA(kCertChanged)) | |
| .WillOnce(Return(true)); | |
| EXPECT_CALL(*prefs_, Delete(kPrefsCertificateReportToSendUpdate)) | |
| .WillOnce(Return(true)); | |
| EXPECT_CALL(*prefs_, SetString(kPrefsCertificateReportToSendDownload, _)) | |
| .Times(0); | |
| CertificateChecker::FlushReport(); | |
| } | |
| // flush nothing to report | |
| TEST_F(CertificateCheckerTest, FlushNothingToReport) { | |
| string empty = ""; | |
| EXPECT_CALL(*prefs_, GetString(kPrefsCertificateReportToSendUpdate, _)) | |
| .WillOnce(DoAll( | |
| SetArgumentPointee<1>(empty), | |
| Return(true))); | |
| EXPECT_CALL(*prefs_, GetString(kPrefsCertificateReportToSendDownload, _)) | |
| .WillOnce(Return(false)); | |
| EXPECT_CALL(*fake_system_state_.mock_metrics_lib(), | |
| SendUserActionToUMA(_)).Times(0); | |
| EXPECT_CALL(*prefs_, SetString(_, _)).Times(0); | |
| CertificateChecker::FlushReport(); | |
| } | |
| } // namespace chromeos_update_engine |