1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/safe_browsing/sandboxed_zip_analyzer.h"
10 #include "base/bind_helpers.h"
11 #include "base/files/file_path.h"
12 #include "base/path_service.h"
13 #include "base/run_loop.h"
14 #include "chrome/common/chrome_paths.h"
15 #include "chrome/common/safe_browsing/zip_analyzer_results.h"
16 #include "content/public/test/test_browser_thread_bundle.h"
17 #include "content/public/test/test_utils.h"
18 #include "crypto/sha2.h"
19 #include "testing/gtest/include/gtest/gtest.h"
21 namespace safe_browsing
{
23 class SandboxedZipAnalyzerTest
: public ::testing::Test
{
25 // Constants for validating the data reported by the analyzer.
27 const char* file_basename
;
28 ClientDownloadRequest_DownloadType download_type
;
29 const uint8_t* sha256_digest
;
34 // A helper that provides a SandboxedZipAnalyzer::ResultCallback that will
35 // store a copy of an analyzer's results and then run a closure.
38 ResultsGetter(const base::Closure
& quit_closure
,
39 zip_analyzer::Results
* results
)
40 : quit_closure_(quit_closure
),
43 results
->success
= false;
46 SandboxedZipAnalyzer::ResultCallback
GetCallback() {
47 return base::Bind(&ResultsGetter::OnZipAnalyzerResults
,
48 base::Unretained(this));
52 void OnZipAnalyzerResults(const zip_analyzer::Results
& results
) {
57 base::Closure quit_closure_
;
58 zip_analyzer::Results
* results_
;
59 DISALLOW_COPY_AND_ASSIGN(ResultsGetter
);
62 SandboxedZipAnalyzerTest()
63 : browser_thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP
) {}
65 void SetUp() override
{
66 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA
, &dir_test_data_
));
67 dir_test_data_
= dir_test_data_
.AppendASCII("safe_browsing");
68 dir_test_data_
= dir_test_data_
.AppendASCII("download_protection");
71 // Runs a sandboxed zip analyzer on |file_path|, writing its results into
73 void RunAnalyzer(const base::FilePath
& file_path
,
74 zip_analyzer::Results
* results
) {
76 base::RunLoop run_loop
;
77 ResultsGetter
results_getter(run_loop
.QuitClosure(), results
);
78 scoped_refptr
<SandboxedZipAnalyzer
> analyzer(
79 new SandboxedZipAnalyzer(file_path
, results_getter
.GetCallback()));
84 // Verifies expectations about a binary found by the analyzer.
85 void ExpectBinary(const BinaryData
& data
,
86 const ClientDownloadRequest_ArchivedBinary
& binary
) {
87 ASSERT_TRUE(binary
.has_file_basename());
88 EXPECT_EQ(data
.file_basename
, binary
.file_basename());
89 ASSERT_TRUE(binary
.has_download_type());
90 EXPECT_EQ(data
.download_type
, binary
.download_type());
91 ASSERT_TRUE(binary
.has_digests());
92 ASSERT_TRUE(binary
.digests().has_sha256());
93 EXPECT_EQ(std::string(data
.sha256_digest
,
94 data
.sha256_digest
+ crypto::kSHA256Length
),
95 binary
.digests().sha256());
96 EXPECT_FALSE(binary
.digests().has_sha1());
97 EXPECT_FALSE(binary
.digests().has_md5());
98 ASSERT_TRUE(binary
.has_length());
99 EXPECT_EQ(data
.length
, binary
.length());
100 #if defined(OS_WIN) // ExtractImageFeatures is only implemented for Win.
101 ASSERT_EQ(data
.is_signed
, binary
.has_signature());
102 if (data
.is_signed
) {
103 ASSERT_LT(0, binary
.signature().signed_data_size());
104 ASSERT_NE(0U, binary
.signature().signed_data(0).size());
106 ASSERT_TRUE(binary
.has_image_headers());
107 ASSERT_TRUE(binary
.image_headers().has_pe_headers());
108 EXPECT_TRUE(binary
.image_headers().pe_headers().has_dos_header());
109 EXPECT_TRUE(binary
.image_headers().pe_headers().has_file_header());
110 EXPECT_TRUE(binary
.image_headers().pe_headers().has_optional_headers32());
111 EXPECT_FALSE(binary
.image_headers().pe_headers().has_optional_headers64());
113 ASSERT_FALSE(binary
.has_signature());
114 ASSERT_FALSE(binary
.has_image_headers());
118 static const uint8_t kUnsignedDigest
[];
119 static const uint8_t kSignedDigest
[];
120 static const BinaryData kUnsignedExe
;
121 static const BinaryData kSignedExe
;
123 base::FilePath dir_test_data_
;
124 content::TestBrowserThreadBundle browser_thread_bundle_
;
125 content::InProcessUtilityThreadHelper utility_thread_helper_
;
129 const uint8_t SandboxedZipAnalyzerTest::kUnsignedDigest
[] = {
130 0x1e, 0x95, 0x4d, 0x9c, 0xe0, 0x38, 0x9e, 0x2b, 0xa7, 0x44, 0x72, 0x16,
131 0xf2, 0x17, 0x61, 0xf9, 0x8d, 0x1e, 0x65, 0x40, 0xc2, 0xab, 0xec, 0xdb,
132 0xec, 0xff, 0x57, 0x0e, 0x36, 0xc4, 0x93, 0xdb
134 const uint8_t SandboxedZipAnalyzerTest::kSignedDigest
[] = {
135 0xe1, 0x1f, 0xfa, 0x0c, 0x9f, 0x25, 0x23, 0x44, 0x53, 0xa9, 0xed, 0xd1,
136 0xcb, 0x25, 0x1d, 0x46, 0x10, 0x7f, 0x34, 0xb5, 0x36, 0xad, 0x74, 0x64,
137 0x2a, 0x85, 0x84, 0xac, 0xa8, 0xc1, 0xa8, 0xce
139 const SandboxedZipAnalyzerTest::BinaryData
140 SandboxedZipAnalyzerTest::kUnsignedExe
= {
142 ClientDownloadRequest_DownloadType_WIN_EXECUTABLE
,
147 const SandboxedZipAnalyzerTest::BinaryData
148 SandboxedZipAnalyzerTest::kSignedExe
= {
150 ClientDownloadRequest_DownloadType_WIN_EXECUTABLE
,
156 TEST_F(SandboxedZipAnalyzerTest
, NoBinaries
) {
157 zip_analyzer::Results results
;
158 RunAnalyzer(dir_test_data_
.AppendASCII("zipfile_no_binaries.zip"), &results
);
159 ASSERT_TRUE(results
.success
);
160 EXPECT_FALSE(results
.has_executable
);
161 EXPECT_FALSE(results
.has_archive
);
162 EXPECT_EQ(0, results
.archived_binary
.size());
165 TEST_F(SandboxedZipAnalyzerTest
, OneUnsignedBinary
) {
166 zip_analyzer::Results results
;
167 RunAnalyzer(dir_test_data_
.AppendASCII("zipfile_one_unsigned_binary.zip"),
169 ASSERT_TRUE(results
.success
);
170 EXPECT_TRUE(results
.has_executable
);
171 EXPECT_FALSE(results
.has_archive
);
172 ASSERT_EQ(1, results
.archived_binary
.size());
173 ExpectBinary(kUnsignedExe
, results
.archived_binary
.Get(0));
176 TEST_F(SandboxedZipAnalyzerTest
, TwoBinariesOneSigned
) {
177 zip_analyzer::Results results
;
178 RunAnalyzer(dir_test_data_
.AppendASCII("zipfile_two_binaries_one_signed.zip"),
180 ASSERT_TRUE(results
.success
);
181 EXPECT_TRUE(results
.has_executable
);
182 EXPECT_FALSE(results
.has_archive
);
183 ASSERT_EQ(2, results
.archived_binary
.size());
184 ExpectBinary(kUnsignedExe
, results
.archived_binary
.Get(0));
185 ExpectBinary(kSignedExe
, results
.archived_binary
.Get(1));
188 } // namespace safe_browsing