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