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"
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"
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
;
55 using base::MessageLoop
;
56 using content::BrowserThread
;
57 namespace safe_browsing
{
59 // A SafeBrowsingDatabaseManager implementation that returns a fixed result for
61 class MockSafeBrowsingDatabaseManager
: public SafeBrowsingDatabaseManager
{
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
));
73 virtual ~MockSafeBrowsingDatabaseManager() {}
74 DISALLOW_COPY_AND_ASSIGN(MockSafeBrowsingDatabaseManager
);
77 class FakeSafeBrowsingService
: public SafeBrowsingService
{
79 FakeSafeBrowsingService() { }
81 // Returned pointer has the same lifespan as the database_manager_ refcounted
83 MockSafeBrowsingDatabaseManager
* mock_database_manager() {
84 return mock_database_manager_
;
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
{ }
98 MockSafeBrowsingDatabaseManager
* mock_database_manager_
;
100 DISALLOW_COPY_AND_ASSIGN(FakeSafeBrowsingService
);
103 class MockBinaryFeatureExtractor
: public BinaryFeatureExtractor
{
105 MockBinaryFeatureExtractor() {}
106 MOCK_METHOD2(CheckSignature
, void(const base::FilePath
&,
107 ClientDownloadRequest_SignatureInfo
*));
108 MOCK_METHOD2(ExtractImageHeaders
, void(const base::FilePath
&,
109 ClientDownloadRequest_ImageHeaders
*));
112 virtual ~MockBinaryFeatureExtractor() {}
115 DISALLOW_COPY_AND_ASSIGN(MockBinaryFeatureExtractor
);
118 class TestURLFetcherWatcher
: public net::TestURLFetcherDelegateForTests
{
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
;
133 virtual void OnChunkUpload(int fetcher_id
) OVERRIDE
{}
134 virtual void OnRequestEnd(int fetcher_id
) OVERRIDE
{}
136 int WaitForRequest() {
142 net::TestURLFetcherFactory
* factory_
;
144 base::RunLoop run_loop_
;
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
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(
181 std::vector
<SBFullHash
>(),
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
,
189 base::Bind(&OnSafeBrowsingResult
,
190 base::Owned(check
)));
193 class DownloadProtectionServiceTest
: public testing::Test
{
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();
211 base::FilePath source_path
;
212 ASSERT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT
, &source_path
));
213 testdata_path_
= source_path
214 .AppendASCII("chrome")
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();
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
)) {
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();
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
),
283 net::CertificateList certs
=
284 net::X509Certificate::CreateCertificateListFromBytes(
287 net::X509Certificate::FORMAT_PEM_CERT_SEQUENCE
);
288 return certs
.empty() ? NULL
: certs
[0];
292 // Helper functions for FlushThreadMessageLoops.
293 void RunAllPendingAndQuitUI() {
294 base::MessageLoop::current()->RunUntilIdle();
295 BrowserThread::PostTask(
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(
310 base::Bind(&DownloadProtectionServiceTest::RunAllPendingAndQuitUI
,
311 base::Unretained(this)));
314 void FlushMessageLoop(BrowserThread::ID thread
) {
315 BrowserThread::PostTask(
318 base::Bind(&DownloadProtectionServiceTest::PostRunMessageLoopTask
,
319 base::Unretained(this), thread
));
320 MessageLoop::current()->Run();
324 void CheckDoneCallback(
325 DownloadProtectionService::DownloadCheckResult result
) {
328 MessageLoop::current()->Quit();
331 void SyncCheckDoneCallback(
332 DownloadProtectionService::DownloadCheckResult result
) {
337 void SendURLFetchComplete(net::TestURLFetcher
* fetcher
) {
338 fetcher
->delegate()->OnURLFetchComplete(fetcher
);
341 testing::AssertionResult
IsResult(
342 DownloadProtectionService::DownloadCheckResult expected
) {
344 return testing::AssertionFailure() << "No result";
346 return result_
== expected
?
347 testing::AssertionSuccess() :
348 testing::AssertionFailure() << "Expected " << expected
<<
353 scoped_refptr
<FakeSafeBrowsingService
> sb_service_
;
354 scoped_refptr
<MockBinaryFeatureExtractor
> binary_feature_extractor_
;
355 DownloadProtectionService
* download_service_
;
356 DownloadProtectionService::DownloadCheckResult 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(
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(
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
;
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
, _
))
431 EXPECT_CALL(*binary_feature_extractor_
.get(), ExtractImageHeaders(a_tmp
, _
))
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(
448 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
449 base::Unretained(this)));
450 MessageLoop::current()->Run();
452 EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS
));
454 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE
));
457 // Check that the referrer is not matched against the whitelist.
458 referrer
= GURL("http://www.google.com/");
459 download_service_
->CheckClientDownload(
461 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
462 base::Unretained(this)));
463 MessageLoop::current()->Run();
465 EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS
));
467 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE
));
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(
474 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
475 base::Unretained(this)));
476 MessageLoop::current()->Run();
478 EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS
));
480 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE
));
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(
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(
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
, _
))
569 EXPECT_CALL(*binary_feature_extractor_
.get(), ExtractImageHeaders(a_tmp
, _
))
572 download_service_
->CheckClientDownload(
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.
581 factory
.SetFakeResponse(
582 DownloadProtectionService::GetDownloadRequestUrl(),
583 response
.SerializePartialAsString(),
584 net::HTTP_OK
, net::URLRequestStatus::SUCCESS
);
586 download_service_
->CheckClientDownload(
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(
606 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
607 base::Unretained(this)));
608 MessageLoop::current()->Run();
609 EXPECT_FALSE(DownloadFeedbackService::GetPingsForDownloadForTesting(
610 item
, &feedback_ping
, &feedback_response
));
612 EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS
));
614 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE
));
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(
626 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
627 base::Unretained(this)));
628 MessageLoop::current()->Run();
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
);
638 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE
));
641 // If the response is dangerous_host the result should also be marked as
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(
651 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
652 base::Unretained(this)));
653 MessageLoop::current()->Run();
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
);
660 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE
));
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(
673 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
674 base::Unretained(this)));
675 MessageLoop::current()->Run();
677 EXPECT_TRUE(IsResult(DownloadProtectionService::POTENTIALLY_UNWANTED
));
679 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE
));
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
, _
))
717 EXPECT_CALL(*binary_feature_extractor_
.get(), ExtractImageHeaders(a_tmp
, _
))
720 download_service_
->CheckClientDownload(
722 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
723 base::Unretained(this)));
724 MessageLoop::current()->Run();
726 EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS
));
728 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE
));
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(
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(
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
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(
812 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
813 base::Unretained(this)));
814 MessageLoop::current()->Run();
816 EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS
));
818 EXPECT_TRUE(IsResult(DownloadProtectionService::SAFE
));
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(
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
, _
))
899 EXPECT_CALL(*binary_feature_extractor_
.get(), ExtractImageHeaders(a_tmp
, _
))
902 EXPECT_FALSE(download_service_
->IsSupportedDownload(item
, a_crx
));
903 download_service_
->CheckClientDownload(
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(
946 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
947 base::Unretained(this)));
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
);
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",
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(
990 base::Bind(&DownloadProtectionServiceTest::SendURLFetchComplete
,
991 base::Unretained(this), fetcher
));
992 MessageLoop::current()->Run();
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(
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
);
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",
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(
1064 base::Bind(&DownloadProtectionServiceTest::SendURLFetchComplete
,
1065 base::Unretained(this), fetcher
));
1066 MessageLoop::current()->Run();
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());
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(
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
);
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());
1140 RequestContainsResource(request
,
1141 ClientDownloadRequest::DOWNLOAD_REDIRECT
,
1142 "http://www.google.com/",
1144 EXPECT_TRUE(RequestContainsResource(request
,
1145 ClientDownloadRequest::DOWNLOAD_URL
,
1146 "http://www.google.com/bla.exe",
1148 EXPECT_TRUE(RequestContainsResource(request
,
1149 ClientDownloadRequest::TAB_URL
,
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(
1168 base::Bind(&DownloadProtectionServiceTest::SendURLFetchComplete
,
1169 base::Unretained(this),
1171 MessageLoop::current()->Run();
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
)
1184 reinterpret_cast<history::ContextID
>(1),
1188 content::PAGE_TRANSITION_TYPED
,
1189 history::SOURCE_BROWSED
,
1192 TestURLFetcherWatcher
fetcher_watcher(&factory
);
1193 download_service_
->CheckClientDownload(
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
);
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());
1215 RequestContainsResource(request
,
1216 ClientDownloadRequest::DOWNLOAD_REDIRECT
,
1217 "http://www.google.com/",
1219 EXPECT_TRUE(RequestContainsResource(request
,
1220 ClientDownloadRequest::DOWNLOAD_URL
,
1221 "http://www.google.com/bla.exe",
1223 EXPECT_TRUE(RequestContainsResource(request
,
1224 ClientDownloadRequest::TAB_REDIRECT
,
1225 "http://tab.com/ref1",
1227 EXPECT_TRUE(RequestContainsResource(request
,
1228 ClientDownloadRequest::TAB_REDIRECT
,
1229 "http://tab.com/ref2",
1231 EXPECT_TRUE(RequestContainsResource(request
,
1232 ClientDownloadRequest::TAB_URL
,
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(
1245 base::Bind(&DownloadProtectionServiceTest::SendURLFetchComplete
,
1246 base::Unretained(this),
1248 MessageLoop::current()->Run();
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(
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
),
1283 download_service_
->CheckDownloadUrl(
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()))
1294 CheckDownloadUrlDone(SB_THREAT_TYPE_URL_MALWARE
),
1296 download_service_
->CheckDownloadUrl(
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
),
1308 CheckDownloadUrlDone(SB_THREAT_TYPE_BINARY_MALWARE_URL
),
1310 download_service_
->CheckDownloadUrl(
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(
1351 base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback
,
1352 base::Unretained(this)));
1354 // The request should time out because the HTTP request hasn't returned
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(
1394 base::Bind(&DownloadProtectionServiceTest::SyncCheckDoneCallback
,
1395 base::Unretained(this)));
1396 // MockDownloadItem going out of scope triggers the OnDownloadDestroyed
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
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