OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
| 5 #include <windows.h> |
| 6 #include <wintrust.h> |
| 7 |
5 #include "base/files/file_path.h" | 8 #include "base/files/file_path.h" |
6 #include "base/files/memory_mapped_file.h" | 9 #include "base/files/memory_mapped_file.h" |
7 #include "base/path_service.h" | 10 #include "base/path_service.h" |
8 #include "chrome/common/chrome_paths.h" | 11 #include "chrome/common/chrome_paths.h" |
9 #include "chrome/common/safe_browsing/pe_image_reader_win.h" | 12 #include "chrome/common/safe_browsing/pe_image_reader_win.h" |
| 13 #include "testing/gmock/include/gmock/gmock.h" |
10 #include "testing/gtest/include/gtest/gtest.h" | 14 #include "testing/gtest/include/gtest/gtest.h" |
11 | 15 |
| 16 using ::testing::_; |
| 17 using ::testing::Gt; |
| 18 using ::testing::NotNull; |
| 19 using ::testing::Return; |
| 20 using ::testing::StrictMock; |
| 21 |
12 struct TestData { | 22 struct TestData { |
13 const char* filename; | 23 const char* filename; |
14 safe_browsing::PeImageReader::WordSize word_size; | 24 safe_browsing::PeImageReader::WordSize word_size; |
15 WORD machine_identifier; | 25 WORD machine_identifier; |
16 WORD optional_header_size; | 26 WORD optional_header_size; |
17 size_t number_of_sections; | 27 size_t number_of_sections; |
18 size_t number_of_debug_entries; | 28 size_t number_of_debug_entries; |
19 }; | 29 }; |
20 | 30 |
21 // A test fixture parameterized on test data containing the name of a PE image | 31 // A test fixture parameterized on test data containing the name of a PE image |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
148 }; | 158 }; |
149 | 159 |
150 } // namespace | 160 } // namespace |
151 | 161 |
152 INSTANTIATE_TEST_CASE_P(WordSize32, | 162 INSTANTIATE_TEST_CASE_P(WordSize32, |
153 PeImageReaderTest, | 163 PeImageReaderTest, |
154 testing::Values(&kTestData[0])); | 164 testing::Values(&kTestData[0])); |
155 INSTANTIATE_TEST_CASE_P(WordSize64, | 165 INSTANTIATE_TEST_CASE_P(WordSize64, |
156 PeImageReaderTest, | 166 PeImageReaderTest, |
157 testing::Values(&kTestData[1])); | 167 testing::Values(&kTestData[1])); |
| 168 |
| 169 // An object exposing a PeImageReader::EnumCertificatesCallback that invokes a |
| 170 // virtual OnCertificate() method. This method is suitable for mocking in tests. |
| 171 class CertificateReceiver { |
| 172 public: |
| 173 void* AsContext() { return this; } |
| 174 static bool OnCertificateCallback(uint16_t revision, |
| 175 uint16_t certificate_type, |
| 176 const uint8_t* certificate_data, |
| 177 size_t certificate_data_size, |
| 178 void* context) { |
| 179 return reinterpret_cast<CertificateReceiver*>(context)->OnCertificate( |
| 180 revision, certificate_type, certificate_data, certificate_data_size); |
| 181 } |
| 182 |
| 183 protected: |
| 184 CertificateReceiver() {} |
| 185 virtual ~CertificateReceiver() {} |
| 186 virtual bool OnCertificate(uint16_t revision, |
| 187 uint16_t certificate_type, |
| 188 const uint8_t* certificate_data, |
| 189 size_t certificate_data_size) = 0; |
| 190 }; |
| 191 |
| 192 class MockCertificateReceiver : public CertificateReceiver { |
| 193 public: |
| 194 MockCertificateReceiver() {} |
| 195 MOCK_METHOD4(OnCertificate, bool(uint16_t, uint16_t, const uint8_t*, size_t)); |
| 196 |
| 197 private: |
| 198 DISALLOW_COPY_AND_ASSIGN(MockCertificateReceiver); |
| 199 }; |
| 200 |
| 201 struct CertificateTestData { |
| 202 const char* filename; |
| 203 int num_signers; |
| 204 }; |
| 205 |
| 206 // A test fixture parameterized on test data containing the name of a PE image |
| 207 // to parse and the expected values to be read from it. The file is read from |
| 208 // the src/chrome/test/data/safe_browsing/download_protection directory. |
| 209 class PeImageReaderCertificateTest |
| 210 : public testing::TestWithParam<const CertificateTestData*> { |
| 211 protected: |
| 212 PeImageReaderCertificateTest() : expected_data_(GetParam()) {} |
| 213 |
| 214 void SetUp() override { |
| 215 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &data_file_path_)); |
| 216 data_file_path_ = data_file_path_.AppendASCII("safe_browsing"); |
| 217 data_file_path_ = data_file_path_.AppendASCII("download_protection"); |
| 218 data_file_path_ = data_file_path_.AppendASCII(expected_data_->filename); |
| 219 ASSERT_TRUE(data_file_.Initialize(data_file_path_)); |
| 220 ASSERT_TRUE(image_reader_.Initialize(data_file_.data(), |
| 221 data_file_.length())); |
| 222 } |
| 223 |
| 224 const CertificateTestData* expected_data_; |
| 225 base::FilePath data_file_path_; |
| 226 base::MemoryMappedFile data_file_; |
| 227 safe_browsing::PeImageReader image_reader_; |
| 228 }; |
| 229 |
| 230 TEST_P(PeImageReaderCertificateTest, EnumCertificates) { |
| 231 StrictMock<MockCertificateReceiver> receiver; |
| 232 if (expected_data_->num_signers) { |
| 233 EXPECT_CALL(receiver, OnCertificate(WIN_CERT_REVISION_2_0, |
| 234 WIN_CERT_TYPE_PKCS_SIGNED_DATA, |
| 235 NotNull(), |
| 236 Gt(0U))) |
| 237 .Times(expected_data_->num_signers) |
| 238 .WillRepeatedly(Return(true)); |
| 239 } |
| 240 EXPECT_TRUE(image_reader_.EnumCertificates( |
| 241 &CertificateReceiver::OnCertificateCallback, receiver.AsContext())); |
| 242 } |
| 243 |
| 244 TEST_P(PeImageReaderCertificateTest, AbortEnum) { |
| 245 StrictMock<MockCertificateReceiver> receiver; |
| 246 if (expected_data_->num_signers) { |
| 247 // Return false for the first cert, thereby stopping the enumeration. |
| 248 EXPECT_CALL(receiver, OnCertificate(_, _, _, _)).WillOnce(Return(false)); |
| 249 EXPECT_FALSE(image_reader_.EnumCertificates( |
| 250 &CertificateReceiver::OnCertificateCallback, receiver.AsContext())); |
| 251 } else { |
| 252 // An unsigned file always reports true with no invocations of the callback. |
| 253 EXPECT_TRUE(image_reader_.EnumCertificates( |
| 254 &CertificateReceiver::OnCertificateCallback, receiver.AsContext())); |
| 255 } |
| 256 } |
| 257 |
| 258 namespace { |
| 259 |
| 260 const CertificateTestData kCertificateTestData[] = { |
| 261 { |
| 262 "signed.exe", |
| 263 1, |
| 264 }, { |
| 265 "unsigned.exe", |
| 266 0, |
| 267 }, { |
| 268 "wow_helper.exe", |
| 269 1, |
| 270 }, { |
| 271 "signed_twice.exe", |
| 272 2, |
| 273 }, |
| 274 }; |
| 275 |
| 276 } // namespace |
| 277 |
| 278 INSTANTIATE_TEST_CASE_P(SignedExe, |
| 279 PeImageReaderCertificateTest, |
| 280 testing::Values(&kCertificateTestData[0])); |
| 281 INSTANTIATE_TEST_CASE_P(UnsignedExe, |
| 282 PeImageReaderCertificateTest, |
| 283 testing::Values(&kCertificateTestData[1])); |
| 284 INSTANTIATE_TEST_CASE_P(WowHelperExe, |
| 285 PeImageReaderCertificateTest, |
| 286 testing::Values(&kCertificateTestData[2])); |
| 287 INSTANTIATE_TEST_CASE_P(SignedTwiceExe, |
| 288 PeImageReaderCertificateTest, |
| 289 testing::Values(&kCertificateTestData[3])); |
OLD | NEW |