Update mojo surfaces bindings and mojo/cc/ glue
[chromium-blink-merge.git] / chrome / browser / safe_browsing / download_protection_service_unittest.cc
blob9bbb3b1a578424bd4cdd168e2aea239114c7bb55
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/safe_browsing/download_protection_service.h"
7 #include <map>
8 #include <string>
10 #include "base/base_paths.h"
11 #include "base/bind.h"
12 #include "base/callback.h"
13 #include "base/file_util.h"
14 #include "base/files/file_path.h"
15 #include "base/files/scoped_temp_dir.h"
16 #include "base/memory/ref_counted.h"
17 #include "base/memory/scoped_ptr.h"
18 #include "base/message_loop/message_loop.h"
19 #include "base/path_service.h"
20 #include "base/run_loop.h"
21 #include "base/strings/string_number_conversions.h"
22 #include "base/threading/sequenced_worker_pool.h"
23 #include "chrome/browser/history/history_service.h"
24 #include "chrome/browser/history/history_service_factory.h"
25 #include "chrome/browser/safe_browsing/binary_feature_extractor.h"
26 #include "chrome/browser/safe_browsing/database_manager.h"
27 #include "chrome/browser/safe_browsing/download_feedback_service.h"
28 #include "chrome/browser/safe_browsing/safe_browsing_service.h"
29 #include "chrome/common/safe_browsing/csd.pb.h"
30 #include "chrome/test/base/testing_profile.h"
31 #include "content/public/test/mock_download_item.h"
32 #include "content/public/test/test_browser_thread_bundle.h"
33 #include "content/public/test/test_utils.h"
34 #include "net/cert/x509_certificate.h"
35 #include "net/http/http_status_code.h"
36 #include "net/url_request/test_url_fetcher_factory.h"
37 #include "net/url_request/url_fetcher_delegate.h"
38 #include "net/url_request/url_request_status.h"
39 #include "testing/gmock/include/gmock/gmock.h"
40 #include "testing/gtest/include/gtest/gtest.h"
41 #include "third_party/zlib/google/zip.h"
42 #include "url/gurl.h"
44 using ::testing::Assign;
45 using ::testing::ContainerEq;
46 using ::testing::DoAll;
47 using ::testing::ElementsAre;
48 using ::testing::Mock;
49 using ::testing::NotNull;
50 using ::testing::Return;
51 using ::testing::ReturnRef;
52 using ::testing::SaveArg;
53 using ::testing::StrictMock;
54 using ::testing::_;
55 using base::MessageLoop;
56 using content::BrowserThread;
57 namespace safe_browsing {
58 namespace {
59 // A SafeBrowsingDatabaseManager implementation that returns a fixed result for
60 // a given URL.
61 class MockSafeBrowsingDatabaseManager : public SafeBrowsingDatabaseManager {
62 public:
63 explicit MockSafeBrowsingDatabaseManager(SafeBrowsingService* service)
64 : SafeBrowsingDatabaseManager(service) { }
66 MOCK_METHOD1(MatchDownloadWhitelistUrl, bool(const GURL&));
67 MOCK_METHOD1(MatchDownloadWhitelistString, bool(const std::string&));
68 MOCK_METHOD2(CheckDownloadUrl, bool(
69 const std::vector<GURL>& url_chain,
70 SafeBrowsingDatabaseManager::Client* client));
72 private:
73 virtual ~MockSafeBrowsingDatabaseManager() {}
74 DISALLOW_COPY_AND_ASSIGN(MockSafeBrowsingDatabaseManager);
77 class FakeSafeBrowsingService : public SafeBrowsingService {
78 public:
79 FakeSafeBrowsingService() { }
81 // Returned pointer has the same lifespan as the database_manager_ refcounted
82 // object.
83 MockSafeBrowsingDatabaseManager* mock_database_manager() {
84 return mock_database_manager_;
87 protected:
88 virtual ~FakeSafeBrowsingService() { }
90 virtual SafeBrowsingDatabaseManager* CreateDatabaseManager() OVERRIDE {
91 mock_database_manager_ = new MockSafeBrowsingDatabaseManager(this);
92 return mock_database_manager_;
95 virtual void RegisterAllDelayedAnalysis() OVERRIDE { }
97 private:
98 MockSafeBrowsingDatabaseManager* mock_database_manager_;
100 DISALLOW_COPY_AND_ASSIGN(FakeSafeBrowsingService);
103 class MockBinaryFeatureExtractor : public BinaryFeatureExtractor {
104 public:
105 MockBinaryFeatureExtractor() {}
106 MOCK_METHOD2(CheckSignature, void(const base::FilePath&,
107 ClientDownloadRequest_SignatureInfo*));
108 MOCK_METHOD2(ExtractImageHeaders, void(const base::FilePath&,
109 ClientDownloadRequest_ImageHeaders*));
111 protected:
112 virtual ~MockBinaryFeatureExtractor() {}
114 private:
115 DISALLOW_COPY_AND_ASSIGN(MockBinaryFeatureExtractor);
118 class TestURLFetcherWatcher : public net::TestURLFetcherDelegateForTests {
119 public:
120 explicit TestURLFetcherWatcher(net::TestURLFetcherFactory* factory)
121 : factory_(factory), fetcher_id_(-1) {
122 factory_->SetDelegateForTests(this);
124 ~TestURLFetcherWatcher() {
125 factory_->SetDelegateForTests(NULL);
128 // TestURLFetcherDelegateForTests impl:
129 virtual void OnRequestStart(int fetcher_id) OVERRIDE {
130 fetcher_id_ = fetcher_id;
131 run_loop_.Quit();
133 virtual void OnChunkUpload(int fetcher_id) OVERRIDE {}
134 virtual void OnRequestEnd(int fetcher_id) OVERRIDE {}
136 int WaitForRequest() {
137 run_loop_.Run();
138 return fetcher_id_;
141 private:
142 net::TestURLFetcherFactory* factory_;
143 int fetcher_id_;
144 base::RunLoop run_loop_;
146 } // namespace
148 ACTION_P(SetCertificateContents, contents) {
149 arg1->add_certificate_chain()->add_element()->set_certificate(contents);
152 ACTION_P(SetDosHeaderContents, contents) {
153 arg1->mutable_pe_headers()->set_dos_header(contents);
156 ACTION_P(TrustSignature, certificate_file) {
157 arg1->set_trusted(true);
158 // Add a certificate chain. Note that we add the certificate twice so that
159 // it appears as its own issuer.
160 std::string cert_data;
161 ASSERT_TRUE(base::ReadFileToString(certificate_file, &cert_data));
162 ClientDownloadRequest_CertificateChain* chain =
163 arg1->add_certificate_chain();
164 chain->add_element()->set_certificate(cert_data);
165 chain->add_element()->set_certificate(cert_data);
168 // We can't call OnSafeBrowsingResult directly because SafeBrowsingCheck does
169 // not have any copy constructor which means it can't be stored in a callback
170 // easily. Note: check will be deleted automatically when the callback is
171 // deleted.
172 void OnSafeBrowsingResult(
173 SafeBrowsingDatabaseManager::SafeBrowsingCheck* check) {
174 check->client->OnSafeBrowsingResult(*check);
177 ACTION_P(CheckDownloadUrlDone, threat_type) {
178 SafeBrowsingDatabaseManager::SafeBrowsingCheck* check =
179 new SafeBrowsingDatabaseManager::SafeBrowsingCheck(
180 arg0,
181 std::vector<SBFullHash>(),
182 arg1,
183 safe_browsing_util::BINURL,
184 std::vector<SBThreatType>(1, SB_THREAT_TYPE_BINARY_MALWARE_URL));
185 for (size_t i = 0; i < check->url_results.size(); ++i)
186 check->url_results[i] = threat_type;
187 BrowserThread::PostTask(BrowserThread::IO,
188 FROM_HERE,
189 base::Bind(&OnSafeBrowsingResult,
190 base::Owned(check)));
193 class DownloadProtectionServiceTest : public testing::Test {
194 protected:
195 DownloadProtectionServiceTest()
196 : test_browser_thread_bundle_(
197 content::TestBrowserThreadBundle::IO_MAINLOOP) {
199 virtual void SetUp() {
200 // Start real threads for the IO and File threads so that the DCHECKs
201 // to test that we're on the correct thread work.
202 sb_service_ = new StrictMock<FakeSafeBrowsingService>();
203 sb_service_->Initialize();
204 binary_feature_extractor_ = new StrictMock<MockBinaryFeatureExtractor>();
205 download_service_ = sb_service_->download_protection_service();
206 download_service_->binary_feature_extractor_ = binary_feature_extractor_;
207 download_service_->SetEnabled(true);
208 base::RunLoop().RunUntilIdle();
209 has_result_ = false;
211 base::FilePath source_path;
212 ASSERT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &source_path));
213 testdata_path_ = source_path
214 .AppendASCII("chrome")
215 .AppendASCII("test")
216 .AppendASCII("data")
217 .AppendASCII("safe_browsing")
218 .AppendASCII("download_protection");
221 virtual void TearDown() {
222 sb_service_->ShutDown();
223 // Flush all of the thread message loops to ensure that there are no
224 // tasks currently running.
225 FlushThreadMessageLoops();
226 sb_service_ = NULL;
229 bool RequestContainsResource(const ClientDownloadRequest& request,
230 ClientDownloadRequest::ResourceType type,
231 const std::string& url,
232 const std::string& referrer) {
233 for (int i = 0; i < request.resources_size(); ++i) {
234 if (request.resources(i).url() == url &&
235 request.resources(i).type() == type &&
236 (referrer.empty() || request.resources(i).referrer() == referrer)) {
237 return true;
240 return false;
243 // At this point we only set the server IP for the download itself.
244 bool RequestContainsServerIp(const ClientDownloadRequest& request,
245 const std::string& remote_address) {
246 for (int i = 0; i < request.resources_size(); ++i) {
247 // We want the last DOWNLOAD_URL in the chain.
248 if (request.resources(i).type() == ClientDownloadRequest::DOWNLOAD_URL &&
249 (i + 1 == request.resources_size() ||
250 request.resources(i + 1).type() !=
251 ClientDownloadRequest::DOWNLOAD_URL)) {
252 return remote_address == request.resources(i).remote_ip();
255 return false;
258 // Flushes any pending tasks in the message loops of all threads.
259 void FlushThreadMessageLoops() {
260 BrowserThread::GetBlockingPool()->FlushForTesting();
261 FlushMessageLoop(BrowserThread::IO);
262 base::RunLoop().RunUntilIdle();
265 // Proxy for private method.
266 static void GetCertificateWhitelistStrings(
267 const net::X509Certificate& certificate,
268 const net::X509Certificate& issuer,
269 std::vector<std::string>* whitelist_strings) {
270 DownloadProtectionService::GetCertificateWhitelistStrings(
271 certificate, issuer, whitelist_strings);
274 // Reads a single PEM-encoded certificate from the testdata directory.
275 // Returns NULL on failure.
276 scoped_refptr<net::X509Certificate> ReadTestCertificate(
277 const std::string& filename) {
278 std::string cert_data;
279 if (!base::ReadFileToString(testdata_path_.AppendASCII(filename),
280 &cert_data)) {
281 return NULL;
283 net::CertificateList certs =
284 net::X509Certificate::CreateCertificateListFromBytes(
285 cert_data.data(),
286 cert_data.size(),
287 net::X509Certificate::FORMAT_PEM_CERT_SEQUENCE);
288 return certs.empty() ? NULL : certs[0];
291 private:
292 // Helper functions for FlushThreadMessageLoops.
293 void RunAllPendingAndQuitUI() {
294 base::MessageLoop::current()->RunUntilIdle();
295 BrowserThread::PostTask(
296 BrowserThread::UI,
297 FROM_HERE,
298 base::Bind(&DownloadProtectionServiceTest::QuitMessageLoop,
299 base::Unretained(this)));
302 void QuitMessageLoop() {
303 base::MessageLoop::current()->Quit();
306 void PostRunMessageLoopTask(BrowserThread::ID thread) {
307 BrowserThread::PostTask(
308 thread,
309 FROM_HERE,
310 base::Bind(&DownloadProtectionServiceTest::RunAllPendingAndQuitUI,
311 base::Unretained(this)));
314 void FlushMessageLoop(BrowserThread::ID thread) {
315 BrowserThread::PostTask(
316 BrowserThread::UI,
317 FROM_HERE,
318 base::Bind(&DownloadProtectionServiceTest::PostRunMessageLoopTask,
319 base::Unretained(this), thread));
320 MessageLoop::current()->Run();
323 public:
324 void CheckDoneCallback(
325 DownloadProtectionService::DownloadCheckResult result) {
326 result_ = result;
327 has_result_ = true;
328 MessageLoop::current()->Quit();
331 void SyncCheckDoneCallback(
332 DownloadProtectionService::DownloadCheckResult result) {
333 result_ = result;
334 has_result_ = true;
337 void SendURLFetchComplete(net::TestURLFetcher* fetcher) {
338 fetcher->delegate()->OnURLFetchComplete(fetcher);
341 testing::AssertionResult IsResult(
342 DownloadProtectionService::DownloadCheckResult expected) {
343 if (!has_result_)
344 return testing::AssertionFailure() << "No result";
345 has_result_ = false;
346 return result_ == expected ?
347 testing::AssertionSuccess() :
348 testing::AssertionFailure() << "Expected " << expected <<
349 ", got " << result_;
352 protected:
353 scoped_refptr<FakeSafeBrowsingService> sb_service_;
354 scoped_refptr<MockBinaryFeatureExtractor> binary_feature_extractor_;
355 DownloadProtectionService* download_service_;
356 DownloadProtectionService::DownloadCheckResult result_;
357 bool has_result_;
358 content::TestBrowserThreadBundle test_browser_thread_bundle_;
359 content::InProcessUtilityThreadHelper in_process_utility_thread_helper_;
360 base::FilePath testdata_path_;
363 TEST_F(DownloadProtectionServiceTest, CheckClientDownloadInvalidUrl) {
364 base::FilePath a_tmp(FILE_PATH_LITERAL("a.tmp"));
365 base::FilePath a_exe(FILE_PATH_LITERAL("a.exe"));
366 std::vector<GURL> url_chain;
367 GURL referrer("http://www.google.com/");
369 content::MockDownloadItem item;
370 EXPECT_CALL(item, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp));
371 EXPECT_CALL(item, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_exe));
372 EXPECT_CALL(item, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain));
373 EXPECT_CALL(item, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer));
374 EXPECT_CALL(item, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
375 EXPECT_CALL(item, GetTabReferrerUrl())
376 .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
377 download_service_->CheckClientDownload(
378 &item,
379 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
380 base::Unretained(this)));
381 MessageLoop::current()->Run();
382 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE));
383 Mock::VerifyAndClearExpectations(&item);
385 url_chain.push_back(GURL("file://www.google.com/"));
386 EXPECT_CALL(item, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp));
387 EXPECT_CALL(item, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_exe));
388 EXPECT_CALL(item, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain));
389 EXPECT_CALL(item, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer));
390 EXPECT_CALL(item, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
391 EXPECT_CALL(item, GetTabReferrerUrl())
392 .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
393 download_service_->CheckClientDownload(
394 &item,
395 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
396 base::Unretained(this)));
397 MessageLoop::current()->Run();
398 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE));
401 TEST_F(DownloadProtectionServiceTest, CheckClientDownloadWhitelistedUrl) {
402 // Response to any requests will be DANGEROUS.
403 ClientDownloadResponse response;
404 response.set_verdict(ClientDownloadResponse::DANGEROUS);
405 net::FakeURLFetcherFactory factory(NULL);
406 factory.SetFakeResponse(
407 DownloadProtectionService::GetDownloadRequestUrl(),
408 response.SerializeAsString(),
409 net::HTTP_OK, net::URLRequestStatus::SUCCESS);
411 std::string hash = "hash";
412 base::FilePath a_tmp(FILE_PATH_LITERAL("a.tmp"));
413 base::FilePath a_exe(FILE_PATH_LITERAL("a.exe"));
414 std::vector<GURL> url_chain;
415 GURL referrer;
417 content::MockDownloadItem item;
418 EXPECT_CALL(item, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp));
419 EXPECT_CALL(item, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_exe));
420 EXPECT_CALL(item, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain));
421 EXPECT_CALL(item, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer));
422 EXPECT_CALL(item, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
423 EXPECT_CALL(item, GetTabReferrerUrl())
424 .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
425 EXPECT_CALL(item, GetHash()).WillRepeatedly(ReturnRef(hash));
426 EXPECT_CALL(item, GetReceivedBytes()).WillRepeatedly(Return(100));
427 EXPECT_CALL(item, HasUserGesture()).WillRepeatedly(Return(true));
428 EXPECT_CALL(item, GetRemoteAddress()).WillRepeatedly(Return(""));
429 EXPECT_CALL(*binary_feature_extractor_.get(), CheckSignature(a_tmp, _))
430 .Times(4);
431 EXPECT_CALL(*binary_feature_extractor_.get(), ExtractImageHeaders(a_tmp, _))
432 .Times(4);
434 // We should not get whilelist checks for other URLs than specified below.
435 EXPECT_CALL(*sb_service_->mock_database_manager(),
436 MatchDownloadWhitelistUrl(_)).Times(0);
437 EXPECT_CALL(*sb_service_->mock_database_manager(),
438 MatchDownloadWhitelistUrl(GURL("http://www.evil.com/bla.exe")))
439 .WillRepeatedly(Return(false));
440 EXPECT_CALL(*sb_service_->mock_database_manager(),
441 MatchDownloadWhitelistUrl(GURL("http://www.google.com/a.exe")))
442 .WillRepeatedly(Return(true));
444 // With no referrer and just the bad url, should be marked DANGEROUS.
445 url_chain.push_back(GURL("http://www.evil.com/bla.exe"));
446 download_service_->CheckClientDownload(
447 &item,
448 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
449 base::Unretained(this)));
450 MessageLoop::current()->Run();
451 #if defined(OS_WIN)
452 EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS));
453 #else
454 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE));
455 #endif
457 // Check that the referrer is not matched against the whitelist.
458 referrer = GURL("http://www.google.com/");
459 download_service_->CheckClientDownload(
460 &item,
461 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
462 base::Unretained(this)));
463 MessageLoop::current()->Run();
464 #if defined(OS_WIN)
465 EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS));
466 #else
467 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE));
468 #endif
470 // Redirect from a site shouldn't be checked either.
471 url_chain.insert(url_chain.begin(), GURL("http://www.google.com/redirect"));
472 download_service_->CheckClientDownload(
473 &item,
474 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
475 base::Unretained(this)));
476 MessageLoop::current()->Run();
477 #if defined(OS_WIN)
478 EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS));
479 #else
480 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE));
481 #endif
483 // Only if the final url is whitelisted should it be SAFE.
484 url_chain.push_back(GURL("http://www.google.com/a.exe"));
485 download_service_->CheckClientDownload(
486 &item,
487 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
488 base::Unretained(this)));
489 MessageLoop::current()->Run();
490 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE));
493 TEST_F(DownloadProtectionServiceTest, CheckClientDownloadFetchFailed) {
494 net::FakeURLFetcherFactory factory(NULL);
495 // HTTP request will fail.
496 factory.SetFakeResponse(
497 DownloadProtectionService::GetDownloadRequestUrl(), std::string(),
498 net::HTTP_INTERNAL_SERVER_ERROR, net::URLRequestStatus::FAILED);
500 base::FilePath a_tmp(FILE_PATH_LITERAL("a.tmp"));
501 base::FilePath a_exe(FILE_PATH_LITERAL("a.exe"));
502 std::vector<GURL> url_chain;
503 url_chain.push_back(GURL("http://www.evil.com/a.exe"));
504 GURL referrer("http://www.google.com/");
505 std::string hash = "hash";
507 content::MockDownloadItem item;
508 EXPECT_CALL(item, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp));
509 EXPECT_CALL(item, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_exe));
510 EXPECT_CALL(item, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain));
511 EXPECT_CALL(item, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer));
512 EXPECT_CALL(item, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
513 EXPECT_CALL(item, GetTabReferrerUrl())
514 .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
515 EXPECT_CALL(item, GetHash()).WillRepeatedly(ReturnRef(hash));
516 EXPECT_CALL(item, GetReceivedBytes()).WillRepeatedly(Return(100));
517 EXPECT_CALL(item, HasUserGesture()).WillRepeatedly(Return(true));
518 EXPECT_CALL(item, GetRemoteAddress()).WillRepeatedly(Return(""));
520 EXPECT_CALL(*sb_service_->mock_database_manager(),
521 MatchDownloadWhitelistUrl(_))
522 .WillRepeatedly(Return(false));
523 EXPECT_CALL(*binary_feature_extractor_.get(), CheckSignature(a_tmp, _));
524 EXPECT_CALL(*binary_feature_extractor_.get(), ExtractImageHeaders(a_tmp, _));
526 download_service_->CheckClientDownload(
527 &item,
528 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
529 base::Unretained(this)));
530 MessageLoop::current()->Run();
531 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE));
534 TEST_F(DownloadProtectionServiceTest, CheckClientDownloadSuccess) {
535 ClientDownloadResponse response;
536 response.set_verdict(ClientDownloadResponse::SAFE);
537 net::FakeURLFetcherFactory factory(NULL);
538 // Empty response means SAFE.
539 factory.SetFakeResponse(
540 DownloadProtectionService::GetDownloadRequestUrl(),
541 response.SerializeAsString(),
542 net::HTTP_OK, net::URLRequestStatus::SUCCESS);
544 base::FilePath a_tmp(FILE_PATH_LITERAL("a.tmp"));
545 base::FilePath a_exe(FILE_PATH_LITERAL("a.exe"));
546 std::vector<GURL> url_chain;
547 url_chain.push_back(GURL("http://www.evil.com/a.exe"));
548 GURL referrer("http://www.google.com/");
549 std::string hash = "hash";
551 content::MockDownloadItem item;
552 EXPECT_CALL(item, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp));
553 EXPECT_CALL(item, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_exe));
554 EXPECT_CALL(item, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain));
555 EXPECT_CALL(item, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer));
556 EXPECT_CALL(item, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
557 EXPECT_CALL(item, GetTabReferrerUrl())
558 .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
559 EXPECT_CALL(item, GetHash()).WillRepeatedly(ReturnRef(hash));
560 EXPECT_CALL(item, GetReceivedBytes()).WillRepeatedly(Return(100));
561 EXPECT_CALL(item, HasUserGesture()).WillRepeatedly(Return(true));
562 EXPECT_CALL(item, GetRemoteAddress()).WillRepeatedly(Return(""));
564 EXPECT_CALL(*sb_service_->mock_database_manager(),
565 MatchDownloadWhitelistUrl(_))
566 .WillRepeatedly(Return(false));
567 EXPECT_CALL(*binary_feature_extractor_.get(), CheckSignature(a_tmp, _))
568 .Times(6);
569 EXPECT_CALL(*binary_feature_extractor_.get(), ExtractImageHeaders(a_tmp, _))
570 .Times(6);
572 download_service_->CheckClientDownload(
573 &item,
574 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
575 base::Unretained(this)));
576 MessageLoop::current()->Run();
577 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE));
579 // Invalid response should be safe too.
580 response.Clear();
581 factory.SetFakeResponse(
582 DownloadProtectionService::GetDownloadRequestUrl(),
583 response.SerializePartialAsString(),
584 net::HTTP_OK, net::URLRequestStatus::SUCCESS);
586 download_service_->CheckClientDownload(
587 &item,
588 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
589 base::Unretained(this)));
590 MessageLoop::current()->Run();
591 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE));
592 std::string feedback_ping;
593 std::string feedback_response;
594 EXPECT_FALSE(DownloadFeedbackService::GetPingsForDownloadForTesting(
595 item, &feedback_ping, &feedback_response));
597 // If the response is dangerous the result should also be marked as dangerous.
598 response.set_verdict(ClientDownloadResponse::DANGEROUS);
599 factory.SetFakeResponse(
600 DownloadProtectionService::GetDownloadRequestUrl(),
601 response.SerializeAsString(),
602 net::HTTP_OK, net::URLRequestStatus::SUCCESS);
604 download_service_->CheckClientDownload(
605 &item,
606 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
607 base::Unretained(this)));
608 MessageLoop::current()->Run();
609 EXPECT_FALSE(DownloadFeedbackService::GetPingsForDownloadForTesting(
610 item, &feedback_ping, &feedback_response));
611 #if defined(OS_WIN)
612 EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS));
613 #else
614 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE));
615 #endif
617 // If the response is uncommon the result should also be marked as uncommon.
618 response.set_verdict(ClientDownloadResponse::UNCOMMON);
619 factory.SetFakeResponse(
620 DownloadProtectionService::GetDownloadRequestUrl(),
621 response.SerializeAsString(),
622 net::HTTP_OK, net::URLRequestStatus::SUCCESS);
624 download_service_->CheckClientDownload(
625 &item,
626 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
627 base::Unretained(this)));
628 MessageLoop::current()->Run();
629 #if defined(OS_WIN)
630 EXPECT_TRUE(IsResult(DownloadProtectionService::UNCOMMON));
631 EXPECT_TRUE(DownloadFeedbackService::GetPingsForDownloadForTesting(
632 item, &feedback_ping, &feedback_response));
633 ClientDownloadRequest decoded_request;
634 EXPECT_TRUE(decoded_request.ParseFromString(feedback_ping));
635 EXPECT_EQ(url_chain.back().spec(), decoded_request.url());
636 EXPECT_EQ(response.SerializeAsString(), feedback_response);
637 #else
638 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE));
639 #endif
641 // If the response is dangerous_host the result should also be marked as
642 // dangerous_host.
643 response.set_verdict(ClientDownloadResponse::DANGEROUS_HOST);
644 factory.SetFakeResponse(
645 DownloadProtectionService::GetDownloadRequestUrl(),
646 response.SerializeAsString(),
647 net::HTTP_OK, net::URLRequestStatus::SUCCESS);
649 download_service_->CheckClientDownload(
650 &item,
651 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
652 base::Unretained(this)));
653 MessageLoop::current()->Run();
654 #if defined(OS_WIN)
655 EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS_HOST));
656 EXPECT_TRUE(DownloadFeedbackService::GetPingsForDownloadForTesting(
657 item, &feedback_ping, &feedback_response));
658 EXPECT_EQ(response.SerializeAsString(), feedback_response);
659 #else
660 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE));
661 #endif
663 // If the response is POTENTIALLY_UNWANTED the result should also be marked as
664 // POTENTIALLY_UNWANTED.
665 response.set_verdict(ClientDownloadResponse::POTENTIALLY_UNWANTED);
666 factory.SetFakeResponse(
667 DownloadProtectionService::GetDownloadRequestUrl(),
668 response.SerializeAsString(),
669 net::HTTP_OK, net::URLRequestStatus::SUCCESS);
671 download_service_->CheckClientDownload(
672 &item,
673 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
674 base::Unretained(this)));
675 MessageLoop::current()->Run();
676 #if defined(OS_WIN)
677 EXPECT_TRUE(IsResult(DownloadProtectionService::POTENTIALLY_UNWANTED));
678 #else
679 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE));
680 #endif
683 TEST_F(DownloadProtectionServiceTest, CheckClientDownloadHTTPS) {
684 ClientDownloadResponse response;
685 response.set_verdict(ClientDownloadResponse::DANGEROUS);
686 net::FakeURLFetcherFactory factory(NULL);
687 factory.SetFakeResponse(
688 DownloadProtectionService::GetDownloadRequestUrl(),
689 response.SerializeAsString(),
690 net::HTTP_OK, net::URLRequestStatus::SUCCESS);
692 base::FilePath a_tmp(FILE_PATH_LITERAL("a.tmp"));
693 base::FilePath a_exe(FILE_PATH_LITERAL("a.exe"));
694 std::vector<GURL> url_chain;
695 url_chain.push_back(GURL("http://www.evil.com/a.exe"));
696 GURL referrer("http://www.google.com/");
697 std::string hash = "hash";
699 content::MockDownloadItem item;
700 EXPECT_CALL(item, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp));
701 EXPECT_CALL(item, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_exe));
702 EXPECT_CALL(item, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain));
703 EXPECT_CALL(item, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer));
704 EXPECT_CALL(item, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
705 EXPECT_CALL(item, GetTabReferrerUrl())
706 .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
707 EXPECT_CALL(item, GetHash()).WillRepeatedly(ReturnRef(hash));
708 EXPECT_CALL(item, GetReceivedBytes()).WillRepeatedly(Return(100));
709 EXPECT_CALL(item, HasUserGesture()).WillRepeatedly(Return(true));
710 EXPECT_CALL(item, GetRemoteAddress()).WillRepeatedly(Return(""));
712 EXPECT_CALL(*sb_service_->mock_database_manager(),
713 MatchDownloadWhitelistUrl(_))
714 .WillRepeatedly(Return(false));
715 EXPECT_CALL(*binary_feature_extractor_.get(), CheckSignature(a_tmp, _))
716 .Times(1);
717 EXPECT_CALL(*binary_feature_extractor_.get(), ExtractImageHeaders(a_tmp, _))
718 .Times(1);
720 download_service_->CheckClientDownload(
721 &item,
722 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
723 base::Unretained(this)));
724 MessageLoop::current()->Run();
725 #if defined(OS_WIN)
726 EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS));
727 #else
728 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE));
729 #endif
732 TEST_F(DownloadProtectionServiceTest, CheckClientDownloadZip) {
733 ClientDownloadResponse response;
734 response.set_verdict(ClientDownloadResponse::SAFE);
735 net::FakeURLFetcherFactory factory(NULL);
736 // Empty response means SAFE.
737 factory.SetFakeResponse(
738 DownloadProtectionService::GetDownloadRequestUrl(),
739 response.SerializeAsString(),
740 net::HTTP_OK, net::URLRequestStatus::SUCCESS);
742 base::ScopedTempDir download_dir;
743 ASSERT_TRUE(download_dir.CreateUniqueTempDir());
745 base::FilePath a_tmp(download_dir.path().Append(FILE_PATH_LITERAL("a.tmp")));
746 base::FilePath a_zip(FILE_PATH_LITERAL("a.zip"));
747 std::vector<GURL> url_chain;
748 url_chain.push_back(GURL("http://www.evil.com/a.zip"));
749 GURL referrer("http://www.google.com/");
750 std::string hash = "hash";
752 content::MockDownloadItem item;
753 EXPECT_CALL(item, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp));
754 EXPECT_CALL(item, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_zip));
755 EXPECT_CALL(item, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain));
756 EXPECT_CALL(item, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer));
757 EXPECT_CALL(item, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
758 EXPECT_CALL(item, GetTabReferrerUrl())
759 .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
760 EXPECT_CALL(item, GetHash()).WillRepeatedly(ReturnRef(hash));
761 EXPECT_CALL(item, GetReceivedBytes()).WillRepeatedly(Return(100));
762 EXPECT_CALL(item, HasUserGesture()).WillRepeatedly(Return(true));
763 EXPECT_CALL(item, GetRemoteAddress()).WillRepeatedly(Return(""));
765 // Write out a zip archive to the temporary file. In this case, it
766 // only contains a text file.
767 base::ScopedTempDir zip_source_dir;
768 ASSERT_TRUE(zip_source_dir.CreateUniqueTempDir());
769 std::string file_contents = "dummy file";
770 ASSERT_EQ(static_cast<int>(file_contents.size()), base::WriteFile(
771 zip_source_dir.path().Append(FILE_PATH_LITERAL("file.txt")),
772 file_contents.data(), file_contents.size()));
773 ASSERT_TRUE(zip::Zip(zip_source_dir.path(), a_tmp, false));
775 download_service_->CheckClientDownload(
776 &item,
777 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
778 base::Unretained(this)));
779 MessageLoop::current()->Run();
780 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE));
781 Mock::VerifyAndClearExpectations(sb_service_.get());
782 Mock::VerifyAndClearExpectations(binary_feature_extractor_.get());
784 // Now check with an executable in the zip file as well.
785 ASSERT_EQ(static_cast<int>(file_contents.size()), base::WriteFile(
786 zip_source_dir.path().Append(FILE_PATH_LITERAL("file.exe")),
787 file_contents.data(), file_contents.size()));
788 ASSERT_TRUE(zip::Zip(zip_source_dir.path(), a_tmp, false));
790 EXPECT_CALL(*sb_service_->mock_database_manager(),
791 MatchDownloadWhitelistUrl(_))
792 .WillRepeatedly(Return(false));
794 download_service_->CheckClientDownload(
795 &item,
796 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
797 base::Unretained(this)));
798 MessageLoop::current()->Run();
799 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE));
800 Mock::VerifyAndClearExpectations(binary_feature_extractor_.get());
802 // If the response is dangerous the result should also be marked as
803 // dangerous.
804 response.set_verdict(ClientDownloadResponse::DANGEROUS);
805 factory.SetFakeResponse(
806 DownloadProtectionService::GetDownloadRequestUrl(),
807 response.SerializeAsString(),
808 net::HTTP_OK, net::URLRequestStatus::SUCCESS);
810 download_service_->CheckClientDownload(
811 &item,
812 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
813 base::Unretained(this)));
814 MessageLoop::current()->Run();
815 #if defined(OS_WIN)
816 EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS));
817 #else
818 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE));
819 #endif
820 Mock::VerifyAndClearExpectations(binary_feature_extractor_.get());
823 TEST_F(DownloadProtectionServiceTest, CheckClientDownloadCorruptZip) {
824 base::ScopedTempDir download_dir;
825 ASSERT_TRUE(download_dir.CreateUniqueTempDir());
827 base::FilePath a_tmp(download_dir.path().Append(FILE_PATH_LITERAL("a.tmp")));
828 base::FilePath a_zip(FILE_PATH_LITERAL("a.zip"));
829 std::vector<GURL> url_chain;
830 url_chain.push_back(GURL("http://www.evil.com/a.zip"));
831 GURL referrer("http://www.google.com/");
832 std::string hash = "hash";
834 content::MockDownloadItem item;
835 EXPECT_CALL(item, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp));
836 EXPECT_CALL(item, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_zip));
837 EXPECT_CALL(item, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain));
838 EXPECT_CALL(item, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer));
839 EXPECT_CALL(item, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
840 EXPECT_CALL(item, GetTabReferrerUrl())
841 .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
842 EXPECT_CALL(item, GetHash()).WillRepeatedly(ReturnRef(hash));
843 EXPECT_CALL(item, GetReceivedBytes()).WillRepeatedly(Return(100));
844 EXPECT_CALL(item, HasUserGesture()).WillRepeatedly(Return(true));
845 EXPECT_CALL(item, GetRemoteAddress()).WillRepeatedly(Return(""));
847 std::string file_contents = "corrupt zip file";
848 ASSERT_EQ(static_cast<int>(file_contents.size()), base::WriteFile(
849 a_tmp, file_contents.data(), file_contents.size()));
851 download_service_->CheckClientDownload(
852 &item,
853 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
854 base::Unretained(this)));
855 MessageLoop::current()->Run();
856 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE));
857 Mock::VerifyAndClearExpectations(sb_service_.get());
858 Mock::VerifyAndClearExpectations(binary_feature_extractor_.get());
861 TEST_F(DownloadProtectionServiceTest, CheckClientCrxDownloadSuccess) {
862 ClientDownloadResponse response;
863 // Even if the server verdict is dangerous we should return SAFE because
864 // DownloadProtectionService::IsSupportedDownload() will return false
865 // for crx downloads.
866 response.set_verdict(ClientDownloadResponse::DANGEROUS);
867 net::FakeURLFetcherFactory factory(NULL);
868 // Empty response means SAFE.
869 factory.SetFakeResponse(
870 DownloadProtectionService::GetDownloadRequestUrl(),
871 response.SerializeAsString(),
872 net::HTTP_OK, net::URLRequestStatus::SUCCESS);
874 base::FilePath a_tmp(FILE_PATH_LITERAL("a.tmp"));
875 base::FilePath a_crx(FILE_PATH_LITERAL("a.crx"));
876 std::vector<GURL> url_chain;
877 url_chain.push_back(GURL("http://www.evil.com/a.crx"));
878 GURL referrer("http://www.google.com/");
879 std::string hash = "hash";
881 content::MockDownloadItem item;
882 EXPECT_CALL(item, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp));
883 EXPECT_CALL(item, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_crx));
884 EXPECT_CALL(item, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain));
885 EXPECT_CALL(item, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer));
886 EXPECT_CALL(item, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
887 EXPECT_CALL(item, GetTabReferrerUrl())
888 .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
889 EXPECT_CALL(item, GetHash()).WillRepeatedly(ReturnRef(hash));
890 EXPECT_CALL(item, GetReceivedBytes()).WillRepeatedly(Return(100));
891 EXPECT_CALL(item, HasUserGesture()).WillRepeatedly(Return(true));
892 EXPECT_CALL(item, GetRemoteAddress()).WillRepeatedly(Return(""));
894 EXPECT_CALL(*sb_service_->mock_database_manager(),
895 MatchDownloadWhitelistUrl(_))
896 .WillRepeatedly(Return(false));
897 EXPECT_CALL(*binary_feature_extractor_.get(), CheckSignature(a_tmp, _))
898 .Times(1);
899 EXPECT_CALL(*binary_feature_extractor_.get(), ExtractImageHeaders(a_tmp, _))
900 .Times(1);
902 EXPECT_FALSE(download_service_->IsSupportedDownload(item, a_crx));
903 download_service_->CheckClientDownload(
904 &item,
905 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
906 base::Unretained(this)));
907 MessageLoop::current()->Run();
908 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE));
911 TEST_F(DownloadProtectionServiceTest, CheckClientDownloadValidateRequest) {
912 net::TestURLFetcherFactory factory;
914 base::FilePath tmp_path(FILE_PATH_LITERAL("bla.tmp"));
915 base::FilePath final_path(FILE_PATH_LITERAL("bla.exe"));
916 std::vector<GURL> url_chain;
917 url_chain.push_back(GURL("http://www.google.com/"));
918 url_chain.push_back(GURL("http://www.google.com/bla.exe"));
919 GURL referrer("http://www.google.com/");
920 std::string hash = "hash";
921 std::string remote_address = "10.11.12.13";
923 content::MockDownloadItem item;
924 EXPECT_CALL(item, GetFullPath()).WillRepeatedly(ReturnRef(tmp_path));
925 EXPECT_CALL(item, GetTargetFilePath()).WillRepeatedly(ReturnRef(final_path));
926 EXPECT_CALL(item, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain));
927 EXPECT_CALL(item, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer));
928 EXPECT_CALL(item, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
929 EXPECT_CALL(item, GetTabReferrerUrl())
930 .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
931 EXPECT_CALL(item, GetHash()).WillRepeatedly(ReturnRef(hash));
932 EXPECT_CALL(item, GetReceivedBytes()).WillRepeatedly(Return(100));
933 EXPECT_CALL(item, HasUserGesture()).WillRepeatedly(Return(true));
934 EXPECT_CALL(item, GetRemoteAddress()).WillRepeatedly(Return(remote_address));
936 EXPECT_CALL(*sb_service_->mock_database_manager(),
937 MatchDownloadWhitelistUrl(_))
938 .WillRepeatedly(Return(false));
939 EXPECT_CALL(*binary_feature_extractor_.get(), CheckSignature(tmp_path, _))
940 .WillOnce(SetCertificateContents("dummy cert data"));
941 EXPECT_CALL(*binary_feature_extractor_.get(),
942 ExtractImageHeaders(tmp_path, _))
943 .WillOnce(SetDosHeaderContents("dummy dos header"));
944 download_service_->CheckClientDownload(
945 &item,
946 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
947 base::Unretained(this)));
949 #if !defined(OS_WIN)
950 // SendRequest is not called. Wait for FinishRequest to call our callback.
951 MessageLoop::current()->Run();
952 net::TestURLFetcher* fetcher = factory.GetFetcherByID(0);
953 EXPECT_EQ(NULL, fetcher);
954 #else
955 // Run the message loop(s) until SendRequest is called.
956 FlushThreadMessageLoops();
957 net::TestURLFetcher* fetcher = factory.GetFetcherByID(0);
958 ASSERT_TRUE(fetcher);
959 ClientDownloadRequest request;
960 EXPECT_TRUE(request.ParseFromString(fetcher->upload_data()));
961 EXPECT_EQ("http://www.google.com/bla.exe", request.url());
962 EXPECT_EQ(hash, request.digests().sha256());
963 EXPECT_EQ(item.GetReceivedBytes(), request.length());
964 EXPECT_EQ(item.HasUserGesture(), request.user_initiated());
965 EXPECT_TRUE(RequestContainsServerIp(request, remote_address));
966 EXPECT_EQ(2, request.resources_size());
967 EXPECT_TRUE(RequestContainsResource(request,
968 ClientDownloadRequest::DOWNLOAD_REDIRECT,
969 "http://www.google.com/", ""));
970 EXPECT_TRUE(RequestContainsResource(request,
971 ClientDownloadRequest::DOWNLOAD_URL,
972 "http://www.google.com/bla.exe",
973 referrer.spec()));
974 EXPECT_TRUE(request.has_signature());
975 ASSERT_EQ(1, request.signature().certificate_chain_size());
976 const ClientDownloadRequest_CertificateChain& chain =
977 request.signature().certificate_chain(0);
978 ASSERT_EQ(1, chain.element_size());
979 EXPECT_EQ("dummy cert data", chain.element(0).certificate());
980 EXPECT_TRUE(request.has_image_headers());
981 const ClientDownloadRequest_ImageHeaders& headers =
982 request.image_headers();
983 EXPECT_TRUE(headers.has_pe_headers());
984 EXPECT_TRUE(headers.pe_headers().has_dos_header());
985 EXPECT_EQ("dummy dos header", headers.pe_headers().dos_header());
987 // Simulate the request finishing.
988 base::MessageLoop::current()->PostTask(
989 FROM_HERE,
990 base::Bind(&DownloadProtectionServiceTest::SendURLFetchComplete,
991 base::Unretained(this), fetcher));
992 MessageLoop::current()->Run();
993 #endif
996 // Similar to above, but with an unsigned binary.
997 TEST_F(DownloadProtectionServiceTest,
998 CheckClientDownloadValidateRequestNoSignature) {
999 net::TestURLFetcherFactory factory;
1001 base::FilePath tmp_path(FILE_PATH_LITERAL("bla.tmp"));
1002 base::FilePath final_path(FILE_PATH_LITERAL("bla.exe"));
1003 std::vector<GURL> url_chain;
1004 url_chain.push_back(GURL("http://www.google.com/"));
1005 url_chain.push_back(GURL("ftp://www.google.com/bla.exe"));
1006 GURL referrer("http://www.google.com/");
1007 std::string hash = "hash";
1008 std::string remote_address = "10.11.12.13";
1010 content::MockDownloadItem item;
1011 EXPECT_CALL(item, GetFullPath()).WillRepeatedly(ReturnRef(tmp_path));
1012 EXPECT_CALL(item, GetTargetFilePath()).WillRepeatedly(ReturnRef(final_path));
1013 EXPECT_CALL(item, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain));
1014 EXPECT_CALL(item, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer));
1015 EXPECT_CALL(item, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
1016 EXPECT_CALL(item, GetTabReferrerUrl())
1017 .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
1018 EXPECT_CALL(item, GetHash()).WillRepeatedly(ReturnRef(hash));
1019 EXPECT_CALL(item, GetReceivedBytes()).WillRepeatedly(Return(100));
1020 EXPECT_CALL(item, HasUserGesture()).WillRepeatedly(Return(true));
1021 EXPECT_CALL(item, GetRemoteAddress()).WillRepeatedly(Return(remote_address));
1023 EXPECT_CALL(*sb_service_->mock_database_manager(),
1024 MatchDownloadWhitelistUrl(_))
1025 .WillRepeatedly(Return(false));
1026 EXPECT_CALL(*binary_feature_extractor_.get(), CheckSignature(tmp_path, _));
1027 EXPECT_CALL(*binary_feature_extractor_.get(),
1028 ExtractImageHeaders(tmp_path, _));
1029 download_service_->CheckClientDownload(
1030 &item,
1031 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
1032 base::Unretained(this)));
1034 #if !defined(OS_WIN)
1035 // SendRequest is not called. Wait for FinishRequest to call our callback.
1036 MessageLoop::current()->Run();
1037 net::TestURLFetcher* fetcher = factory.GetFetcherByID(0);
1038 EXPECT_EQ(NULL, fetcher);
1039 #else
1040 // Run the message loop(s) until SendRequest is called.
1041 FlushThreadMessageLoops();
1042 net::TestURLFetcher* fetcher = factory.GetFetcherByID(0);
1043 ASSERT_TRUE(fetcher);
1044 ClientDownloadRequest request;
1045 EXPECT_TRUE(request.ParseFromString(fetcher->upload_data()));
1046 EXPECT_EQ("ftp://www.google.com/bla.exe", request.url());
1047 EXPECT_EQ(hash, request.digests().sha256());
1048 EXPECT_EQ(item.GetReceivedBytes(), request.length());
1049 EXPECT_EQ(item.HasUserGesture(), request.user_initiated());
1050 EXPECT_EQ(2, request.resources_size());
1051 EXPECT_TRUE(RequestContainsResource(request,
1052 ClientDownloadRequest::DOWNLOAD_REDIRECT,
1053 "http://www.google.com/", ""));
1054 EXPECT_TRUE(RequestContainsResource(request,
1055 ClientDownloadRequest::DOWNLOAD_URL,
1056 "ftp://www.google.com/bla.exe",
1057 referrer.spec()));
1058 EXPECT_TRUE(request.has_signature());
1059 EXPECT_EQ(0, request.signature().certificate_chain_size());
1061 // Simulate the request finishing.
1062 base::MessageLoop::current()->PostTask(
1063 FROM_HERE,
1064 base::Bind(&DownloadProtectionServiceTest::SendURLFetchComplete,
1065 base::Unretained(this), fetcher));
1066 MessageLoop::current()->Run();
1067 #endif
1070 // Similar to above, but with tab history.
1071 TEST_F(DownloadProtectionServiceTest,
1072 CheckClientDownloadValidateRequestTabHistory) {
1073 net::TestURLFetcherFactory factory;
1075 base::ScopedTempDir profile_dir;
1076 ASSERT_TRUE(profile_dir.CreateUniqueTempDir());
1077 TestingProfile profile(profile_dir.path());
1078 ASSERT_TRUE(
1079 profile.CreateHistoryService(true /* delete_file */, false /* no_db */));
1081 base::FilePath tmp_path(FILE_PATH_LITERAL("bla.tmp"));
1082 base::FilePath final_path(FILE_PATH_LITERAL("bla.exe"));
1083 std::vector<GURL> url_chain;
1084 url_chain.push_back(GURL("http://www.google.com/"));
1085 url_chain.push_back(GURL("http://www.google.com/bla.exe"));
1086 GURL referrer("http://www.google.com/");
1087 GURL tab_url("http://tab.com/final");
1088 GURL tab_referrer("http://tab.com/referrer");
1089 std::string hash = "hash";
1090 std::string remote_address = "10.11.12.13";
1092 content::MockDownloadItem item;
1093 EXPECT_CALL(item, GetFullPath()).WillRepeatedly(ReturnRef(tmp_path));
1094 EXPECT_CALL(item, GetTargetFilePath()).WillRepeatedly(ReturnRef(final_path));
1095 EXPECT_CALL(item, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain));
1096 EXPECT_CALL(item, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer));
1097 EXPECT_CALL(item, GetTabUrl()).WillRepeatedly(ReturnRef(tab_url));
1098 EXPECT_CALL(item, GetTabReferrerUrl())
1099 .WillRepeatedly(ReturnRef(tab_referrer));
1100 EXPECT_CALL(item, GetHash()).WillRepeatedly(ReturnRef(hash));
1101 EXPECT_CALL(item, GetReceivedBytes()).WillRepeatedly(Return(100));
1102 EXPECT_CALL(item, HasUserGesture()).WillRepeatedly(Return(true));
1103 EXPECT_CALL(item, GetRemoteAddress()).WillRepeatedly(Return(remote_address));
1104 EXPECT_CALL(item, GetBrowserContext()).WillRepeatedly(Return(&profile));
1105 EXPECT_CALL(*sb_service_->mock_database_manager(),
1106 MatchDownloadWhitelistUrl(_))
1107 .WillRepeatedly(Return(false));
1108 EXPECT_CALL(*binary_feature_extractor_.get(), CheckSignature(tmp_path, _))
1109 .WillRepeatedly(SetCertificateContents("dummy cert data"));
1110 EXPECT_CALL(*binary_feature_extractor_.get(),
1111 ExtractImageHeaders(tmp_path, _))
1112 .WillRepeatedly(SetDosHeaderContents("dummy dos header"));
1114 // First test with no history match for the tab URL.
1116 TestURLFetcherWatcher fetcher_watcher(&factory);
1117 download_service_->CheckClientDownload(
1118 &item,
1119 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
1120 base::Unretained(this)));
1122 #if !defined(OS_WIN)
1123 // SendRequest is not called. Wait for FinishRequest to call our callback.
1124 MessageLoop::current()->Run();
1125 net::TestURLFetcher* fetcher = factory.GetFetcherByID(0);
1126 EXPECT_EQ(NULL, fetcher);
1127 #else
1128 EXPECT_EQ(0, fetcher_watcher.WaitForRequest());
1129 net::TestURLFetcher* fetcher = factory.GetFetcherByID(0);
1130 ASSERT_TRUE(fetcher);
1131 ClientDownloadRequest request;
1132 EXPECT_TRUE(request.ParseFromString(fetcher->upload_data()));
1133 EXPECT_EQ("http://www.google.com/bla.exe", request.url());
1134 EXPECT_EQ(hash, request.digests().sha256());
1135 EXPECT_EQ(item.GetReceivedBytes(), request.length());
1136 EXPECT_EQ(item.HasUserGesture(), request.user_initiated());
1137 EXPECT_TRUE(RequestContainsServerIp(request, remote_address));
1138 EXPECT_EQ(3, request.resources_size());
1139 EXPECT_TRUE(
1140 RequestContainsResource(request,
1141 ClientDownloadRequest::DOWNLOAD_REDIRECT,
1142 "http://www.google.com/",
1143 ""));
1144 EXPECT_TRUE(RequestContainsResource(request,
1145 ClientDownloadRequest::DOWNLOAD_URL,
1146 "http://www.google.com/bla.exe",
1147 referrer.spec()));
1148 EXPECT_TRUE(RequestContainsResource(request,
1149 ClientDownloadRequest::TAB_URL,
1150 tab_url.spec(),
1151 tab_referrer.spec()));
1152 EXPECT_TRUE(request.has_signature());
1153 ASSERT_EQ(1, request.signature().certificate_chain_size());
1154 const ClientDownloadRequest_CertificateChain& chain =
1155 request.signature().certificate_chain(0);
1156 ASSERT_EQ(1, chain.element_size());
1157 EXPECT_EQ("dummy cert data", chain.element(0).certificate());
1158 EXPECT_TRUE(request.has_image_headers());
1159 const ClientDownloadRequest_ImageHeaders& headers =
1160 request.image_headers();
1161 EXPECT_TRUE(headers.has_pe_headers());
1162 EXPECT_TRUE(headers.pe_headers().has_dos_header());
1163 EXPECT_EQ("dummy dos header", headers.pe_headers().dos_header());
1165 // Simulate the request finishing.
1166 base::MessageLoop::current()->PostTask(
1167 FROM_HERE,
1168 base::Bind(&DownloadProtectionServiceTest::SendURLFetchComplete,
1169 base::Unretained(this),
1170 fetcher));
1171 MessageLoop::current()->Run();
1172 #endif
1175 // Now try with a history match.
1177 history::RedirectList redirects;
1178 redirects.push_back(GURL("http://tab.com/ref1"));
1179 redirects.push_back(GURL("http://tab.com/ref2"));
1180 redirects.push_back(tab_url);
1181 HistoryServiceFactory::GetForProfile(&profile, Profile::EXPLICIT_ACCESS)
1182 ->AddPage(tab_url,
1183 base::Time::Now(),
1184 reinterpret_cast<history::ContextID>(1),
1186 GURL(),
1187 redirects,
1188 content::PAGE_TRANSITION_TYPED,
1189 history::SOURCE_BROWSED,
1190 false);
1192 TestURLFetcherWatcher fetcher_watcher(&factory);
1193 download_service_->CheckClientDownload(
1194 &item,
1195 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
1196 base::Unretained(this)));
1197 #if !defined(OS_WIN)
1198 // SendRequest is not called. Wait for FinishRequest to call our callback.
1199 MessageLoop::current()->Run();
1200 net::TestURLFetcher* fetcher = factory.GetFetcherByID(0);
1201 EXPECT_EQ(NULL, fetcher);
1202 #else
1203 EXPECT_EQ(0, fetcher_watcher.WaitForRequest());
1204 net::TestURLFetcher* fetcher = factory.GetFetcherByID(0);
1205 ASSERT_TRUE(fetcher);
1206 ClientDownloadRequest request;
1207 EXPECT_TRUE(request.ParseFromString(fetcher->upload_data()));
1208 EXPECT_EQ("http://www.google.com/bla.exe", request.url());
1209 EXPECT_EQ(hash, request.digests().sha256());
1210 EXPECT_EQ(item.GetReceivedBytes(), request.length());
1211 EXPECT_EQ(item.HasUserGesture(), request.user_initiated());
1212 EXPECT_TRUE(RequestContainsServerIp(request, remote_address));
1213 EXPECT_EQ(5, request.resources_size());
1214 EXPECT_TRUE(
1215 RequestContainsResource(request,
1216 ClientDownloadRequest::DOWNLOAD_REDIRECT,
1217 "http://www.google.com/",
1218 ""));
1219 EXPECT_TRUE(RequestContainsResource(request,
1220 ClientDownloadRequest::DOWNLOAD_URL,
1221 "http://www.google.com/bla.exe",
1222 referrer.spec()));
1223 EXPECT_TRUE(RequestContainsResource(request,
1224 ClientDownloadRequest::TAB_REDIRECT,
1225 "http://tab.com/ref1",
1226 ""));
1227 EXPECT_TRUE(RequestContainsResource(request,
1228 ClientDownloadRequest::TAB_REDIRECT,
1229 "http://tab.com/ref2",
1230 ""));
1231 EXPECT_TRUE(RequestContainsResource(request,
1232 ClientDownloadRequest::TAB_URL,
1233 tab_url.spec(),
1234 tab_referrer.spec()));
1235 EXPECT_TRUE(request.has_signature());
1236 ASSERT_EQ(1, request.signature().certificate_chain_size());
1237 const ClientDownloadRequest_CertificateChain& chain =
1238 request.signature().certificate_chain(0);
1239 ASSERT_EQ(1, chain.element_size());
1240 EXPECT_EQ("dummy cert data", chain.element(0).certificate());
1242 // Simulate the request finishing.
1243 base::MessageLoop::current()->PostTask(
1244 FROM_HERE,
1245 base::Bind(&DownloadProtectionServiceTest::SendURLFetchComplete,
1246 base::Unretained(this),
1247 fetcher));
1248 MessageLoop::current()->Run();
1249 #endif
1253 TEST_F(DownloadProtectionServiceTest, TestCheckDownloadUrl) {
1254 std::vector<GURL> url_chain;
1255 url_chain.push_back(GURL("http://www.google.com/"));
1256 url_chain.push_back(GURL("http://www.google.com/bla.exe"));
1257 GURL referrer("http://www.google.com/");
1258 std::string hash = "hash";
1260 content::MockDownloadItem item;
1261 EXPECT_CALL(item, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain));
1262 EXPECT_CALL(item, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer));
1263 EXPECT_CALL(item, GetHash()).WillRepeatedly(ReturnRef(hash));
1265 // CheckDownloadURL returns immediately which means the client object callback
1266 // will never be called. Nevertheless the callback provided to
1267 // CheckClientDownload must still be called.
1268 EXPECT_CALL(*sb_service_->mock_database_manager(),
1269 CheckDownloadUrl(ContainerEq(url_chain), NotNull()))
1270 .WillOnce(Return(true));
1271 download_service_->CheckDownloadUrl(
1272 item,
1273 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
1274 base::Unretained(this)));
1275 MessageLoop::current()->Run();
1276 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE));
1277 Mock::VerifyAndClearExpectations(sb_service_.get());
1279 EXPECT_CALL(*sb_service_->mock_database_manager(),
1280 CheckDownloadUrl(ContainerEq(url_chain), NotNull()))
1281 .WillOnce(DoAll(CheckDownloadUrlDone(SB_THREAT_TYPE_SAFE),
1282 Return(false)));
1283 download_service_->CheckDownloadUrl(
1284 item,
1285 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
1286 base::Unretained(this)));
1287 MessageLoop::current()->Run();
1288 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE));
1289 Mock::VerifyAndClearExpectations(sb_service_.get());
1291 EXPECT_CALL(*sb_service_->mock_database_manager(),
1292 CheckDownloadUrl(ContainerEq(url_chain), NotNull()))
1293 .WillOnce(DoAll(
1294 CheckDownloadUrlDone(SB_THREAT_TYPE_URL_MALWARE),
1295 Return(false)));
1296 download_service_->CheckDownloadUrl(
1297 item,
1298 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
1299 base::Unretained(this)));
1300 MessageLoop::current()->Run();
1301 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE));
1302 Mock::VerifyAndClearExpectations(sb_service_.get());
1304 EXPECT_CALL(*sb_service_->mock_database_manager(),
1305 CheckDownloadUrl(ContainerEq(url_chain),
1306 NotNull()))
1307 .WillOnce(DoAll(
1308 CheckDownloadUrlDone(SB_THREAT_TYPE_BINARY_MALWARE_URL),
1309 Return(false)));
1310 download_service_->CheckDownloadUrl(
1311 item,
1312 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
1313 base::Unretained(this)));
1314 MessageLoop::current()->Run();
1315 EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS));
1318 TEST_F(DownloadProtectionServiceTest, TestDownloadRequestTimeout) {
1319 net::TestURLFetcherFactory factory;
1321 std::vector<GURL> url_chain;
1322 url_chain.push_back(GURL("http://www.evil.com/bla.exe"));
1323 GURL referrer("http://www.google.com/");
1324 base::FilePath tmp_path(FILE_PATH_LITERAL("a.tmp"));
1325 base::FilePath final_path(FILE_PATH_LITERAL("a.exe"));
1326 std::string hash = "hash";
1328 content::MockDownloadItem item;
1329 EXPECT_CALL(item, GetFullPath()).WillRepeatedly(ReturnRef(tmp_path));
1330 EXPECT_CALL(item, GetTargetFilePath()).WillRepeatedly(ReturnRef(final_path));
1331 EXPECT_CALL(item, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain));
1332 EXPECT_CALL(item, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer));
1333 EXPECT_CALL(item, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
1334 EXPECT_CALL(item, GetTabReferrerUrl())
1335 .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
1336 EXPECT_CALL(item, GetHash()).WillRepeatedly(ReturnRef(hash));
1337 EXPECT_CALL(item, GetReceivedBytes()).WillRepeatedly(Return(100));
1338 EXPECT_CALL(item, HasUserGesture()).WillRepeatedly(Return(true));
1339 EXPECT_CALL(item, GetRemoteAddress()).WillRepeatedly(Return(""));
1341 EXPECT_CALL(*sb_service_->mock_database_manager(),
1342 MatchDownloadWhitelistUrl(_))
1343 .WillRepeatedly(Return(false));
1344 EXPECT_CALL(*binary_feature_extractor_.get(), CheckSignature(tmp_path, _));
1345 EXPECT_CALL(*binary_feature_extractor_.get(),
1346 ExtractImageHeaders(tmp_path, _));
1348 download_service_->download_request_timeout_ms_ = 10;
1349 download_service_->CheckClientDownload(
1350 &item,
1351 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
1352 base::Unretained(this)));
1354 // The request should time out because the HTTP request hasn't returned
1355 // anything yet.
1356 MessageLoop::current()->Run();
1357 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE));
1360 TEST_F(DownloadProtectionServiceTest, TestDownloadItemDestroyed) {
1361 net::TestURLFetcherFactory factory;
1363 std::vector<GURL> url_chain;
1364 url_chain.push_back(GURL("http://www.evil.com/bla.exe"));
1365 GURL referrer("http://www.google.com/");
1366 base::FilePath tmp_path(FILE_PATH_LITERAL("a.tmp"));
1367 base::FilePath final_path(FILE_PATH_LITERAL("a.exe"));
1368 std::string hash = "hash";
1371 content::MockDownloadItem item;
1372 EXPECT_CALL(item, GetFullPath()).WillRepeatedly(ReturnRef(tmp_path));
1373 EXPECT_CALL(item, GetTargetFilePath())
1374 .WillRepeatedly(ReturnRef(final_path));
1375 EXPECT_CALL(item, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain));
1376 EXPECT_CALL(item, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer));
1377 EXPECT_CALL(item, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
1378 EXPECT_CALL(item, GetTabReferrerUrl())
1379 .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
1380 EXPECT_CALL(item, GetHash()).WillRepeatedly(ReturnRef(hash));
1381 EXPECT_CALL(item, GetReceivedBytes()).WillRepeatedly(Return(100));
1382 EXPECT_CALL(item, HasUserGesture()).WillRepeatedly(Return(true));
1383 EXPECT_CALL(item, GetRemoteAddress()).WillRepeatedly(Return(""));
1385 EXPECT_CALL(*sb_service_->mock_database_manager(),
1386 MatchDownloadWhitelistUrl(_))
1387 .WillRepeatedly(Return(false));
1388 EXPECT_CALL(*binary_feature_extractor_.get(), CheckSignature(tmp_path, _));
1389 EXPECT_CALL(*binary_feature_extractor_.get(),
1390 ExtractImageHeaders(tmp_path, _));
1392 download_service_->CheckClientDownload(
1393 &item,
1394 base::Bind(&DownloadProtectionServiceTest::SyncCheckDoneCallback,
1395 base::Unretained(this)));
1396 // MockDownloadItem going out of scope triggers the OnDownloadDestroyed
1397 // notification.
1400 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE));
1403 TEST_F(DownloadProtectionServiceTest, GetCertificateWhitelistStrings) {
1404 // We'll pass this cert in as the "issuer", even though it isn't really
1405 // used to sign the certs below. GetCertificateWhitelistStirngs doesn't care
1406 // about this.
1407 scoped_refptr<net::X509Certificate> issuer_cert(
1408 ReadTestCertificate("issuer.pem"));
1409 ASSERT_TRUE(issuer_cert.get());
1410 std::string cert_base = "cert/" + base::HexEncode(
1411 issuer_cert->fingerprint().data,
1412 sizeof(issuer_cert->fingerprint().data));
1414 scoped_refptr<net::X509Certificate> cert(ReadTestCertificate("test_cn.pem"));
1415 ASSERT_TRUE(cert.get());
1416 std::vector<std::string> whitelist_strings;
1417 GetCertificateWhitelistStrings(
1418 *cert.get(), *issuer_cert.get(), &whitelist_strings);
1419 // This also tests escaping of characters in the certificate attributes.
1420 EXPECT_THAT(whitelist_strings, ElementsAre(
1421 cert_base + "/CN=subject%2F%251"));
1423 cert = ReadTestCertificate("test_cn_o.pem");
1424 ASSERT_TRUE(cert.get());
1425 whitelist_strings.clear();
1426 GetCertificateWhitelistStrings(
1427 *cert.get(), *issuer_cert.get(), &whitelist_strings);
1428 EXPECT_THAT(whitelist_strings,
1429 ElementsAre(cert_base + "/CN=subject",
1430 cert_base + "/CN=subject/O=org",
1431 cert_base + "/O=org"));
1433 cert = ReadTestCertificate("test_cn_o_ou.pem");
1434 ASSERT_TRUE(cert.get());
1435 whitelist_strings.clear();
1436 GetCertificateWhitelistStrings(
1437 *cert.get(), *issuer_cert.get(), &whitelist_strings);
1438 EXPECT_THAT(whitelist_strings,
1439 ElementsAre(cert_base + "/CN=subject",
1440 cert_base + "/CN=subject/O=org",
1441 cert_base + "/CN=subject/O=org/OU=unit",
1442 cert_base + "/CN=subject/OU=unit",
1443 cert_base + "/O=org",
1444 cert_base + "/O=org/OU=unit",
1445 cert_base + "/OU=unit"));
1447 cert = ReadTestCertificate("test_cn_ou.pem");
1448 ASSERT_TRUE(cert.get());
1449 whitelist_strings.clear();
1450 GetCertificateWhitelistStrings(
1451 *cert.get(), *issuer_cert.get(), &whitelist_strings);
1452 EXPECT_THAT(whitelist_strings,
1453 ElementsAre(cert_base + "/CN=subject",
1454 cert_base + "/CN=subject/OU=unit",
1455 cert_base + "/OU=unit"));
1457 cert = ReadTestCertificate("test_o.pem");
1458 ASSERT_TRUE(cert.get());
1459 whitelist_strings.clear();
1460 GetCertificateWhitelistStrings(
1461 *cert.get(), *issuer_cert.get(), &whitelist_strings);
1462 EXPECT_THAT(whitelist_strings, ElementsAre(cert_base + "/O=org"));
1464 cert = ReadTestCertificate("test_o_ou.pem");
1465 ASSERT_TRUE(cert.get());
1466 whitelist_strings.clear();
1467 GetCertificateWhitelistStrings(
1468 *cert.get(), *issuer_cert.get(), &whitelist_strings);
1469 EXPECT_THAT(whitelist_strings,
1470 ElementsAre(cert_base + "/O=org",
1471 cert_base + "/O=org/OU=unit",
1472 cert_base + "/OU=unit"));
1474 cert = ReadTestCertificate("test_ou.pem");
1475 ASSERT_TRUE(cert.get());
1476 whitelist_strings.clear();
1477 GetCertificateWhitelistStrings(
1478 *cert.get(), *issuer_cert.get(), &whitelist_strings);
1479 EXPECT_THAT(whitelist_strings, ElementsAre(cert_base + "/OU=unit"));
1481 cert = ReadTestCertificate("test_c.pem");
1482 ASSERT_TRUE(cert.get());
1483 whitelist_strings.clear();
1484 GetCertificateWhitelistStrings(
1485 *cert.get(), *issuer_cert.get(), &whitelist_strings);
1486 EXPECT_THAT(whitelist_strings, ElementsAre());
1488 } // namespace safe_browsing