| // 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/string_util.h> | 
 | #include <base/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/mock_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_ = StringPrintf("%s-%d-%d", | 
 |                              cert_key_prefix_.c_str(), | 
 |                              server_to_check_, | 
 |                              depth_); | 
 |     kCertChanged = "Updater.ServerCertificateChanged"; | 
 |     kCertFailed = "Updater.ServerCertificateFailed"; | 
 |     CertificateChecker::set_system_state(&mock_system_state_); | 
 |     CertificateChecker::set_openssl_wrapper(&openssl_wrapper_); | 
 |     prefs_ = mock_system_state_.mock_prefs(); | 
 |   } | 
 |  | 
 |   virtual void TearDown() {} | 
 |  | 
 |   MockSystemState mock_system_state_; | 
 |   PrefsMock* prefs_; // shortcut to mock_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(NULL, _, _, _)) | 
 |       .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, NULL)); | 
 | } | 
 |  | 
 | // check certificate change, unchanged | 
 | TEST_F(CertificateCheckerTest, SameCertificate) { | 
 |   EXPECT_CALL(openssl_wrapper_, GetCertificateDigest(NULL, _, _, _)) | 
 |       .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, NULL)); | 
 | } | 
 |  | 
 | // check certificate change, changed | 
 | TEST_F(CertificateCheckerTest, ChangedCertificate) { | 
 |   EXPECT_CALL(openssl_wrapper_, GetCertificateDigest(NULL, _, _, _)) | 
 |       .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, NULL)); | 
 | } | 
 |  | 
 | // 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, NULL)); | 
 | } | 
 |  | 
 | // 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(*mock_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(*mock_system_state_.mock_metrics_lib(), | 
 |               SendUserActionToUMA(_)).Times(0); | 
 |   EXPECT_CALL(*prefs_, SetString(_,_)).Times(0); | 
 |   CertificateChecker::FlushReport(); | 
 | } | 
 |  | 
 | }  // namespace chromeos_update_engine |