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