OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/safe_browsing/signature_evaluator_mac.h" | 5 #include "chrome/browser/safe_browsing/signature_evaluator_mac.h" |
6 | 6 |
7 #include <CoreFoundation/CoreFoundation.h> | 7 #include <CoreFoundation/CoreFoundation.h> |
8 #include <sys/xattr.h> | 8 #include <sys/xattr.h> |
9 | 9 |
10 #include <string> | 10 #include <string> |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
93 base::FilePath("/Applications/Google Chrome.app"), | 93 base::FilePath("/Applications/Google Chrome.app"), |
94 base::FilePath("/Applications/Google Chrome.app/Contents/MacOS/foo"), | 94 base::FilePath("/Applications/Google Chrome.app/Contents/MacOS/foo"), |
95 &output2)); | 95 &output2)); |
96 EXPECT_EQ(output2, "Contents/MacOS/foo"); | 96 EXPECT_EQ(output2, "Contents/MacOS/foo"); |
97 } | 97 } |
98 | 98 |
99 TEST_F(MacSignatureEvaluatorTest, SimpleTest) { | 99 TEST_F(MacSignatureEvaluatorTest, SimpleTest) { |
100 // This is a simple test that checks the validity of a signed executable. | 100 // This is a simple test that checks the validity of a signed executable. |
101 // There is no designated requirement: we only check the embedded signature. | 101 // There is no designated requirement: we only check the embedded signature. |
102 base::FilePath path = testdata_path_.AppendASCII("signedexecutablefat"); | 102 base::FilePath path = testdata_path_.AppendASCII("signedexecutablefat"); |
103 safe_browsing::MacSignatureEvaluator evaluator(path); | 103 MacSignatureEvaluator evaluator(path); |
104 ASSERT_TRUE(evaluator.Initialize()); | 104 ASSERT_TRUE(evaluator.Initialize()); |
105 | 105 |
106 ClientIncidentReport_IncidentData_BinaryIntegrityIncident incident; | 106 ClientIncidentReport_IncidentData_BinaryIntegrityIncident incident; |
107 EXPECT_TRUE(evaluator.PerformEvaluation(&incident)); | 107 EXPECT_TRUE(evaluator.PerformEvaluation(&incident)); |
108 EXPECT_EQ(0, incident.contained_file_size()); | 108 EXPECT_EQ(0, incident.contained_file_size()); |
109 } | 109 } |
110 | 110 |
111 TEST_F(MacSignatureEvaluatorTest, SimpleTestWithDR) { | 111 TEST_F(MacSignatureEvaluatorTest, SimpleTestWithDR) { |
112 // This test checks the signer against a designated requirement description. | 112 // This test checks the signer against a designated requirement description. |
113 base::FilePath path = testdata_path_.AppendASCII("signedexecutablefat"); | 113 base::FilePath path = testdata_path_.AppendASCII("signedexecutablefat"); |
114 std::string requirement( | 114 std::string requirement( |
115 "certificate leaf[subject.CN]=\"untrusted@goat.local\""); | 115 "certificate leaf[subject.CN]=\"untrusted@goat.local\""); |
116 safe_browsing::MacSignatureEvaluator evaluator(path, requirement); | 116 MacSignatureEvaluator evaluator(path, requirement); |
117 ASSERT_TRUE(evaluator.Initialize()); | 117 ASSERT_TRUE(evaluator.Initialize()); |
118 | 118 |
119 ClientIncidentReport_IncidentData_BinaryIntegrityIncident incident; | 119 ClientIncidentReport_IncidentData_BinaryIntegrityIncident incident; |
120 EXPECT_TRUE(evaluator.PerformEvaluation(&incident)); | 120 EXPECT_TRUE(evaluator.PerformEvaluation(&incident)); |
121 EXPECT_EQ(0, incident.contained_file_size()); | 121 EXPECT_EQ(0, incident.contained_file_size()); |
122 } | 122 } |
123 | 123 |
124 TEST_F(MacSignatureEvaluatorTest, SimpleTestWithBadDR) { | 124 TEST_F(MacSignatureEvaluatorTest, SimpleTestWithBadDR) { |
125 // Now test with a designated requirement that does not describe the signer. | 125 // Now test with a designated requirement that does not describe the signer. |
126 base::FilePath path = testdata_path_.AppendASCII("signedexecutablefat"); | 126 base::FilePath path = testdata_path_.AppendASCII("signedexecutablefat"); |
127 safe_browsing::MacSignatureEvaluator evaluator(path, "anchor apple"); | 127 MacSignatureEvaluator evaluator(path, "anchor apple"); |
128 ASSERT_TRUE(evaluator.Initialize()); | 128 ASSERT_TRUE(evaluator.Initialize()); |
129 | 129 |
130 ClientIncidentReport_IncidentData_BinaryIntegrityIncident incident; | 130 ClientIncidentReport_IncidentData_BinaryIntegrityIncident incident; |
131 EXPECT_FALSE(evaluator.PerformEvaluation(&incident)); | 131 EXPECT_FALSE(evaluator.PerformEvaluation(&incident)); |
132 EXPECT_EQ(-67050, incident.sec_error()); | 132 EXPECT_EQ(-67050, incident.sec_error()); |
133 EXPECT_TRUE(incident.has_signature()); | 133 EXPECT_TRUE(incident.has_signature()); |
134 ASSERT_TRUE(incident.has_file_basename()); | 134 ASSERT_TRUE(incident.has_file_basename()); |
135 EXPECT_EQ("signedexecutablefat", incident.file_basename()); | 135 EXPECT_EQ("signedexecutablefat", incident.file_basename()); |
136 } | 136 } |
137 | 137 |
138 TEST_F(MacSignatureEvaluatorTest, SimpleBundleTest) { | 138 TEST_F(MacSignatureEvaluatorTest, SimpleBundleTest) { |
139 // Now test a simple, validly signed bundle. | 139 // Now test a simple, validly signed bundle. |
140 base::FilePath path = testdata_path_.AppendASCII("test-bundle.app"); | 140 base::FilePath path = testdata_path_.AppendASCII("test-bundle.app"); |
141 | 141 |
142 std::string requirement( | 142 std::string requirement( |
143 "certificate leaf[subject.CN]=\"untrusted@goat.local\""); | 143 "certificate leaf[subject.CN]=\"untrusted@goat.local\""); |
144 safe_browsing::MacSignatureEvaluator evaluator(path, requirement); | 144 MacSignatureEvaluator evaluator(path, requirement); |
145 ASSERT_TRUE(evaluator.Initialize()); | 145 ASSERT_TRUE(evaluator.Initialize()); |
146 | 146 |
147 ClientIncidentReport_IncidentData_BinaryIntegrityIncident incident; | 147 ClientIncidentReport_IncidentData_BinaryIntegrityIncident incident; |
148 EXPECT_TRUE(evaluator.PerformEvaluation(&incident)); | 148 EXPECT_TRUE(evaluator.PerformEvaluation(&incident)); |
149 EXPECT_EQ(0, incident.contained_file_size()); | 149 EXPECT_EQ(0, incident.contained_file_size()); |
150 } | 150 } |
151 | 151 |
152 TEST_F(MacSignatureEvaluatorTest, ModifiedMainExecTest32) { | 152 TEST_F(MacSignatureEvaluatorTest, ModifiedMainExecTest32) { |
153 // Now to a test modified, signed bundle. | 153 // Now to a test modified, signed bundle. |
154 base::FilePath path = testdata_path_.AppendASCII("modified-main-exec32.app"); | 154 base::FilePath path = testdata_path_.AppendASCII("modified-main-exec32.app"); |
155 | 155 |
156 std::string requirement( | 156 std::string requirement( |
157 "certificate leaf[subject.CN]=\"untrusted@goat.local\""); | 157 "certificate leaf[subject.CN]=\"untrusted@goat.local\""); |
158 safe_browsing::MacSignatureEvaluator evaluator(path, requirement); | 158 MacSignatureEvaluator evaluator(path, requirement); |
159 ASSERT_TRUE(evaluator.Initialize()); | 159 ASSERT_TRUE(evaluator.Initialize()); |
160 | 160 |
161 ClientIncidentReport_IncidentData_BinaryIntegrityIncident incident; | 161 ClientIncidentReport_IncidentData_BinaryIntegrityIncident incident; |
162 EXPECT_FALSE(evaluator.PerformEvaluation(&incident)); | 162 EXPECT_FALSE(evaluator.PerformEvaluation(&incident)); |
163 EXPECT_EQ(-67061, incident.sec_error()); | 163 EXPECT_EQ(-67061, incident.sec_error()); |
164 EXPECT_EQ(path.BaseName().value(), incident.file_basename()); | 164 EXPECT_EQ(path.BaseName().value(), incident.file_basename()); |
165 EXPECT_FALSE(incident.has_signature()); | 165 EXPECT_FALSE(incident.has_signature()); |
166 EXPECT_FALSE(incident.has_image_headers()); | 166 EXPECT_FALSE(incident.has_image_headers()); |
167 ASSERT_EQ(1, incident.contained_file_size()); | 167 ASSERT_EQ(1, incident.contained_file_size()); |
168 | 168 |
169 const ClientIncidentReport_IncidentData_BinaryIntegrityIncident_ContainedFile& | 169 const ClientIncidentReport_IncidentData_BinaryIntegrityIncident_ContainedFile& |
170 contained_file = incident.contained_file(0); | 170 contained_file = incident.contained_file(0); |
171 EXPECT_EQ(contained_file.relative_path(), "Contents/MacOS/test-bundle"); | 171 EXPECT_EQ(contained_file.relative_path(), "Contents/MacOS/test-bundle"); |
172 EXPECT_TRUE(contained_file.has_signature()); | 172 EXPECT_TRUE(contained_file.has_signature()); |
173 EXPECT_TRUE(contained_file.has_image_headers()); | 173 EXPECT_TRUE(contained_file.has_image_headers()); |
174 } | 174 } |
175 | 175 |
176 TEST_F(MacSignatureEvaluatorTest, ModifiedMainExecTest64) { | 176 TEST_F(MacSignatureEvaluatorTest, ModifiedMainExecTest64) { |
177 // Snow Leopard does not know about the 64-bit slice so this test is | 177 // Snow Leopard does not know about the 64-bit slice so this test is |
178 // irrelevant. | 178 // irrelevant. |
179 if (!base::mac::IsOSLionOrLater()) | 179 if (!base::mac::IsOSLionOrLater()) |
180 return; | 180 return; |
181 | 181 |
182 // Now to a test modified, signed bundle. | 182 // Now to a test modified, signed bundle. |
183 base::FilePath path = testdata_path_.AppendASCII("modified-main-exec64.app"); | 183 base::FilePath path = testdata_path_.AppendASCII("modified-main-exec64.app"); |
184 | 184 |
185 std::string requirement( | 185 std::string requirement( |
186 "certificate leaf[subject.CN]=\"untrusted@goat.local\""); | 186 "certificate leaf[subject.CN]=\"untrusted@goat.local\""); |
187 safe_browsing::MacSignatureEvaluator evaluator(path, requirement); | 187 MacSignatureEvaluator evaluator(path, requirement); |
188 ASSERT_TRUE(evaluator.Initialize()); | 188 ASSERT_TRUE(evaluator.Initialize()); |
189 | 189 |
190 ClientIncidentReport_IncidentData_BinaryIntegrityIncident incident; | 190 ClientIncidentReport_IncidentData_BinaryIntegrityIncident incident; |
191 EXPECT_FALSE(evaluator.PerformEvaluation(&incident)); | 191 EXPECT_FALSE(evaluator.PerformEvaluation(&incident)); |
192 | 192 |
193 EXPECT_EQ(-67061, incident.sec_error()); | 193 EXPECT_EQ(-67061, incident.sec_error()); |
194 EXPECT_EQ(path.BaseName().value(), incident.file_basename()); | 194 EXPECT_EQ(path.BaseName().value(), incident.file_basename()); |
195 EXPECT_FALSE(incident.has_signature()); | 195 EXPECT_FALSE(incident.has_signature()); |
196 EXPECT_FALSE(incident.has_image_headers()); | 196 EXPECT_FALSE(incident.has_image_headers()); |
197 ASSERT_EQ(1, incident.contained_file_size()); | 197 ASSERT_EQ(1, incident.contained_file_size()); |
198 | 198 |
199 const ClientIncidentReport_IncidentData_BinaryIntegrityIncident_ContainedFile& | 199 const ClientIncidentReport_IncidentData_BinaryIntegrityIncident_ContainedFile& |
200 contained_file = incident.contained_file(0); | 200 contained_file = incident.contained_file(0); |
201 EXPECT_EQ(contained_file.relative_path(), "Contents/MacOS/test-bundle"); | 201 EXPECT_EQ(contained_file.relative_path(), "Contents/MacOS/test-bundle"); |
202 EXPECT_TRUE(contained_file.has_signature()); | 202 EXPECT_TRUE(contained_file.has_signature()); |
203 EXPECT_TRUE(contained_file.has_image_headers()); | 203 EXPECT_TRUE(contained_file.has_image_headers()); |
204 } | 204 } |
205 | 205 |
206 TEST_F(MacSignatureEvaluatorTest, ModifiedBundleAndExecTest) { | 206 TEST_F(MacSignatureEvaluatorTest, ModifiedBundleAndExecTest) { |
207 // Now test a modified, signed bundle with resources added and the main | 207 // Now test a modified, signed bundle with resources added and the main |
208 // executable modified. | 208 // executable modified. |
209 base::FilePath path = | 209 base::FilePath path = |
210 testdata_path_.AppendASCII("modified-bundle-and-exec.app"); | 210 testdata_path_.AppendASCII("modified-bundle-and-exec.app"); |
211 | 211 |
212 std::string requirement( | 212 std::string requirement( |
213 "certificate leaf[subject.CN]=\"untrusted@goat.local\""); | 213 "certificate leaf[subject.CN]=\"untrusted@goat.local\""); |
214 safe_browsing::MacSignatureEvaluator evaluator(path, requirement); | 214 MacSignatureEvaluator evaluator(path, requirement); |
215 ASSERT_TRUE(evaluator.Initialize()); | 215 ASSERT_TRUE(evaluator.Initialize()); |
216 | 216 |
217 ClientIncidentReport_IncidentData_BinaryIntegrityIncident incident; | 217 ClientIncidentReport_IncidentData_BinaryIntegrityIncident incident; |
218 EXPECT_FALSE(evaluator.PerformEvaluation(&incident)); | 218 EXPECT_FALSE(evaluator.PerformEvaluation(&incident)); |
219 EXPECT_EQ(-67061, incident.sec_error()); | 219 EXPECT_EQ(-67061, incident.sec_error()); |
220 EXPECT_FALSE(incident.has_signature()); | 220 EXPECT_FALSE(incident.has_signature()); |
221 EXPECT_FALSE(incident.has_image_headers()); | 221 EXPECT_FALSE(incident.has_image_headers()); |
222 EXPECT_EQ(path.BaseName().value(), incident.file_basename()); | 222 EXPECT_EQ(path.BaseName().value(), incident.file_basename()); |
223 ASSERT_EQ(1, incident.contained_file_size()); | 223 ASSERT_EQ(1, incident.contained_file_size()); |
224 | 224 |
(...skipping 15 matching lines...) Expand all Loading... |
240 base::FilePath copied_path = | 240 base::FilePath copied_path = |
241 temp_dir_.path().AppendASCII("modified-bundle.app"); | 241 temp_dir_.path().AppendASCII("modified-bundle.app"); |
242 CHECK(base::CopyDirectory(orig_path, copied_path, true)); | 242 CHECK(base::CopyDirectory(orig_path, copied_path, true)); |
243 | 243 |
244 // Setup the extended attributes, which don't persist in the git repo. | 244 // Setup the extended attributes, which don't persist in the git repo. |
245 ASSERT_TRUE(SetupXattrs( | 245 ASSERT_TRUE(SetupXattrs( |
246 copied_path.AppendASCII("Contents/Resources/Base.lproj/MainMenu.nib"))); | 246 copied_path.AppendASCII("Contents/Resources/Base.lproj/MainMenu.nib"))); |
247 | 247 |
248 std::string requirement( | 248 std::string requirement( |
249 "certificate leaf[subject.CN]=\"untrusted@goat.local\""); | 249 "certificate leaf[subject.CN]=\"untrusted@goat.local\""); |
250 safe_browsing::MacSignatureEvaluator evaluator(copied_path, requirement); | 250 MacSignatureEvaluator evaluator(copied_path, requirement); |
251 ASSERT_TRUE(evaluator.Initialize()); | 251 ASSERT_TRUE(evaluator.Initialize()); |
252 | 252 |
253 ClientIncidentReport_IncidentData_BinaryIntegrityIncident incident; | 253 ClientIncidentReport_IncidentData_BinaryIntegrityIncident incident; |
254 EXPECT_FALSE(evaluator.PerformEvaluation(&incident)); | 254 EXPECT_FALSE(evaluator.PerformEvaluation(&incident)); |
255 | 255 |
256 EXPECT_TRUE(incident.has_file_basename()); | 256 EXPECT_TRUE(incident.has_file_basename()); |
257 EXPECT_EQ(copied_path.BaseName().value(), incident.file_basename()); | 257 EXPECT_EQ(copied_path.BaseName().value(), incident.file_basename()); |
258 EXPECT_FALSE(incident.has_signature()); | 258 EXPECT_FALSE(incident.has_signature()); |
259 EXPECT_FALSE(incident.has_image_headers()); | 259 EXPECT_FALSE(incident.has_image_headers()); |
260 EXPECT_EQ(-67054, incident.sec_error()); | 260 EXPECT_EQ(-67054, incident.sec_error()); |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
319 std::vector<std::string> xattrs_seen; | 319 std::vector<std::string> xattrs_seen; |
320 for (const auto& xattr : mainmenunib->signature().xattr()) { | 320 for (const auto& xattr : mainmenunib->signature().xattr()) { |
321 ASSERT_TRUE(xattr.has_key()); | 321 ASSERT_TRUE(xattr.has_key()); |
322 EXPECT_TRUE(xattr.has_value()); | 322 EXPECT_TRUE(xattr.has_value()); |
323 xattrs_seen.push_back(xattr.key()); | 323 xattrs_seen.push_back(xattr.key()); |
324 } | 324 } |
325 EXPECT_THAT(xattrs_known, ::testing::ContainerEq(xattrs_seen)); | 325 EXPECT_THAT(xattrs_known, ::testing::ContainerEq(xattrs_seen)); |
326 } | 326 } |
327 | 327 |
328 } // namespace safe_browsing | 328 } // namespace safe_browsing |
OLD | NEW |