blob: e651c141a98d40368a649789333e52013bf54a10 [file] [log] [blame]
license.botbf09a502008-08-24 00:55:551// Copyright (c) 2006-2008 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.
initial.commit09911bf2008-07-26 23:55:294//
5// Program to test the SafeBrowsing protocol parsing v2.1.
6
[email protected]23144032008-09-08 20:51:307#include "base/hash_tables.h"
initial.commit09911bf2008-07-26 23:55:298#include "base/logging.h"
9#include "base/string_util.h"
initial.commit09911bf2008-07-26 23:55:2910#include "chrome/browser/safe_browsing/protocol_parser.h"
11#include "testing/gtest/include/gtest/gtest.h"
12
13
14// Test parsing one add chunk.
15TEST(SafeBrowsingProtocolParsingTest, TestAddChunk) {
16 std::string add_chunk("a:1:4:35\naaaax1111\0032222333344447777\00288889999");
17 add_chunk[13] = '\0';
18
19 // Run the parse.
20 SafeBrowsingProtocolParser parser;
21 bool re_key = false;
22 std::deque<SBChunk> chunks;
23 bool result = parser.ParseChunk(add_chunk.data(),
24 static_cast<int>(add_chunk.length()),
25 "", "", &re_key, &chunks);
26 EXPECT_TRUE(result);
27 EXPECT_FALSE(re_key);
[email protected]954bc8a52008-09-17 18:16:0128 EXPECT_EQ(chunks.size(), static_cast<size_t>(1));
initial.commit09911bf2008-07-26 23:55:2929 EXPECT_EQ(chunks[0].chunk_number, 1);
[email protected]954bc8a52008-09-17 18:16:0130 EXPECT_EQ(chunks[0].hosts.size(), static_cast<size_t>(3));
initial.commit09911bf2008-07-26 23:55:2931
32 EXPECT_EQ(chunks[0].hosts[0].host, 0x61616161);
33 SBEntry* entry = chunks[0].hosts[0].entry;
34 EXPECT_EQ(entry->type(), SBEntry::ADD_PREFIX);
35 EXPECT_EQ(entry->prefix_count(), 0);
36
37 EXPECT_EQ(chunks[0].hosts[1].host, 0x31313131);
38 entry = chunks[0].hosts[1].entry;
39 EXPECT_EQ(entry->type(), SBEntry::ADD_PREFIX);
40 EXPECT_EQ(entry->prefix_count(), 3);
41 EXPECT_EQ(entry->PrefixAt(0), 0x32323232);
42 EXPECT_EQ(entry->PrefixAt(1), 0x33333333);
43 EXPECT_EQ(entry->PrefixAt(2), 0x34343434);
44
45 EXPECT_EQ(chunks[0].hosts[2].host, 0x37373737);
46 entry = chunks[0].hosts[2].entry;
47 EXPECT_EQ(entry->type(), SBEntry::ADD_PREFIX);
48 EXPECT_EQ(entry->prefix_count(), 2);
49 EXPECT_EQ(entry->PrefixAt(0), 0x38383838);
50 EXPECT_EQ(entry->PrefixAt(1), 0x39393939);
51
52 safe_browsing_util::FreeChunks(&chunks);
53}
54
55// Test parsing one add chunk with full hashes.
56TEST(SafeBrowsingProtocolParsingTest, TestAddFullChunk) {
57 std::string add_chunk("a:1:32:69\naaaa");
58 add_chunk.push_back(2);
59
60 SBFullHash full_hash1, full_hash2;
61 for (int i = 0; i < 32; ++i) {
62 full_hash1.full_hash[i] = i % 2 ? 1 : 2;
63 full_hash2.full_hash[i] = i % 2 ? 3 : 4;
64 }
65
66 add_chunk.append(full_hash1.full_hash, 32);
67 add_chunk.append(full_hash2.full_hash, 32);
68
69 // Run the parse.
70 SafeBrowsingProtocolParser parser;
71 bool re_key = false;
72 std::deque<SBChunk> chunks;
73 bool result = parser.ParseChunk(add_chunk.data(),
74 static_cast<int>(add_chunk.length()),
75 "", "", &re_key, &chunks);
76 EXPECT_TRUE(result);
77 EXPECT_FALSE(re_key);
[email protected]954bc8a52008-09-17 18:16:0178 EXPECT_EQ(chunks.size(), static_cast<size_t>(1));
initial.commit09911bf2008-07-26 23:55:2979 EXPECT_EQ(chunks[0].chunk_number, 1);
[email protected]954bc8a52008-09-17 18:16:0180 EXPECT_EQ(chunks[0].hosts.size(), static_cast<size_t>(1));
initial.commit09911bf2008-07-26 23:55:2981
82 EXPECT_EQ(chunks[0].hosts[0].host, 0x61616161);
83 SBEntry* entry = chunks[0].hosts[0].entry;
84 EXPECT_EQ(entry->type(), SBEntry::ADD_FULL_HASH);
85 EXPECT_EQ(entry->prefix_count(), 2);
86 EXPECT_TRUE(entry->FullHashAt(0) == full_hash1);
87 EXPECT_TRUE(entry->FullHashAt(1) == full_hash2);
88
89 safe_browsing_util::FreeChunks(&chunks);
90}
91
92// Test parsing multiple add chunks. We'll use the same chunk as above, and add
93// one more after it.
94TEST(SafeBrowsingProtocolParsingTest, TestAddChunks) {
95 std::string add_chunk("a:1:4:35\naaaax1111\0032222333344447777\00288889999"
96 "a:2:4:13\n5555\002ppppgggg");
97 add_chunk[13] = '\0';
98
99 // Run the parse.
100 SafeBrowsingProtocolParser parser;
101 bool re_key = false;
102 std::deque<SBChunk> chunks;
103 bool result = parser.ParseChunk(add_chunk.data(),
104 static_cast<int>(add_chunk.length()),
105 "", "", &re_key, &chunks);
106 EXPECT_TRUE(result);
107 EXPECT_FALSE(re_key);
[email protected]954bc8a52008-09-17 18:16:01108 EXPECT_EQ(chunks.size(), static_cast<size_t>(2));
initial.commit09911bf2008-07-26 23:55:29109 EXPECT_EQ(chunks[0].chunk_number, 1);
[email protected]954bc8a52008-09-17 18:16:01110 EXPECT_EQ(chunks[0].hosts.size(), static_cast<size_t>(3));
initial.commit09911bf2008-07-26 23:55:29111
112 EXPECT_EQ(chunks[0].hosts[0].host, 0x61616161);
113 SBEntry* entry = chunks[0].hosts[0].entry;
114 EXPECT_EQ(entry->type(), SBEntry::ADD_PREFIX);
115 EXPECT_EQ(entry->prefix_count(), 0);
116
117 EXPECT_EQ(chunks[0].hosts[1].host, 0x31313131);
118 entry = chunks[0].hosts[1].entry;
119 EXPECT_EQ(entry->type(), SBEntry::ADD_PREFIX);
120 EXPECT_EQ(entry->prefix_count(), 3);
121 EXPECT_EQ(entry->PrefixAt(0), 0x32323232);
122 EXPECT_EQ(entry->PrefixAt(1), 0x33333333);
123 EXPECT_EQ(entry->PrefixAt(2), 0x34343434);
124
125 EXPECT_EQ(chunks[0].hosts[2].host, 0x37373737);
126 entry = chunks[0].hosts[2].entry;
127 EXPECT_EQ(entry->type(), SBEntry::ADD_PREFIX);
128 EXPECT_EQ(entry->prefix_count(), 2);
129 EXPECT_EQ(entry->PrefixAt(0), 0x38383838);
130 EXPECT_EQ(entry->PrefixAt(1), 0x39393939);
131
132
133 EXPECT_EQ(chunks[1].chunk_number, 2);
[email protected]954bc8a52008-09-17 18:16:01134 EXPECT_EQ(chunks[1].hosts.size(), static_cast<size_t>(1));
initial.commit09911bf2008-07-26 23:55:29135
136 EXPECT_EQ(chunks[1].hosts[0].host, 0x35353535);
137 entry = chunks[1].hosts[0].entry;
138 EXPECT_EQ(entry->type(), SBEntry::ADD_PREFIX);
139 EXPECT_EQ(entry->prefix_count(), 2);
140 EXPECT_EQ(entry->PrefixAt(0), 0x70707070);
141 EXPECT_EQ(entry->PrefixAt(1), 0x67676767);
142
143 safe_browsing_util::FreeChunks(&chunks);
144}
145
146// Test parsing one add chunk where a hostkey spans several entries.
147TEST(SafeBrowsingProtocolParsingTest, TestAddBigChunk) {
148 std::string add_chunk("a:1:4:1050\naaaaX");
149 add_chunk[add_chunk.size() - 1] |= 0xFF;
150 for (int i = 0; i < 255; ++i)
151 add_chunk.append(StringPrintf("%04d", i));
152
153 add_chunk.append("aaaa");
154 add_chunk.push_back(5);
155 for (int i = 0; i < 5; ++i)
156 add_chunk.append(StringPrintf("001%d", i));
157
158 SafeBrowsingProtocolParser parser;
159 bool re_key = false;
160 std::deque<SBChunk> chunks;
161 bool result = parser.ParseChunk(add_chunk.data(),
162 static_cast<int>(add_chunk.length()),
163 "", "", &re_key, &chunks);
164 EXPECT_TRUE(result);
165 EXPECT_FALSE(re_key);
[email protected]954bc8a52008-09-17 18:16:01166 EXPECT_EQ(chunks.size(), static_cast<size_t>(1));
initial.commit09911bf2008-07-26 23:55:29167 EXPECT_EQ(chunks[0].chunk_number, 1);
168
[email protected]954bc8a52008-09-17 18:16:01169 EXPECT_EQ(chunks[0].hosts.size(), static_cast<size_t>(1));
initial.commit09911bf2008-07-26 23:55:29170
171 const SBChunkHost& host = chunks[0].hosts[0];
172 EXPECT_EQ(host.host, 0x61616161);
173 EXPECT_EQ(host.entry->prefix_count(), 260);
174
175 safe_browsing_util::FreeChunks(&chunks);
176}
177
178// Test parsing one sub chunk.
179TEST(SafeBrowsingProtocolParsingTest, TestSubChunk) {
180 std::string sub_chunk("s:9:4:59\naaaaxkkkk1111\003"
181 "zzzz2222zzzz3333zzzz4444"
182 "7777\002yyyy8888yyyy9999");
183 sub_chunk[13] = '\0';
184
185 // Run the parse.
186 SafeBrowsingProtocolParser parser;
187 bool re_key = false;
188 std::deque<SBChunk> chunks;
189 bool result = parser.ParseChunk(sub_chunk.data(),
190 static_cast<int>(sub_chunk.length()),
191 "", "", &re_key, &chunks);
192 EXPECT_TRUE(result);
193 EXPECT_FALSE(re_key);
[email protected]954bc8a52008-09-17 18:16:01194 EXPECT_EQ(chunks.size(), static_cast<size_t>(1));
initial.commit09911bf2008-07-26 23:55:29195 EXPECT_EQ(chunks[0].chunk_number, 9);
[email protected]954bc8a52008-09-17 18:16:01196 EXPECT_EQ(chunks[0].hosts.size(), static_cast<size_t>(3));
initial.commit09911bf2008-07-26 23:55:29197
198 EXPECT_EQ(chunks[0].hosts[0].host, 0x61616161);
199 SBEntry* entry = chunks[0].hosts[0].entry;
200 EXPECT_EQ(entry->type(), SBEntry::SUB_PREFIX);
201 EXPECT_EQ(entry->chunk_id(), 0x6b6b6b6b);
202 EXPECT_EQ(entry->prefix_count(), 0);
203
204 EXPECT_EQ(chunks[0].hosts[1].host, 0x31313131);
205 entry = chunks[0].hosts[1].entry;
206 EXPECT_EQ(entry->type(), SBEntry::SUB_PREFIX);
207 EXPECT_EQ(entry->prefix_count(), 3);
208 EXPECT_EQ(entry->ChunkIdAtPrefix(0), 0x7a7a7a7a);
209 EXPECT_EQ(entry->PrefixAt(0), 0x32323232);
210 EXPECT_EQ(entry->ChunkIdAtPrefix(1), 0x7a7a7a7a);
211 EXPECT_EQ(entry->PrefixAt(1), 0x33333333);
212 EXPECT_EQ(entry->ChunkIdAtPrefix(2), 0x7a7a7a7a);
213 EXPECT_EQ(entry->PrefixAt(2), 0x34343434);
214
215 EXPECT_EQ(chunks[0].hosts[2].host, 0x37373737);
216 entry = chunks[0].hosts[2].entry;
217 EXPECT_EQ(entry->type(), SBEntry::SUB_PREFIX);
218 EXPECT_EQ(entry->prefix_count(), 2);
219 EXPECT_EQ(entry->ChunkIdAtPrefix(0), 0x79797979);
220 EXPECT_EQ(entry->PrefixAt(0), 0x38383838);
221 EXPECT_EQ(entry->ChunkIdAtPrefix(1), 0x79797979);
222 EXPECT_EQ(entry->PrefixAt(1), 0x39393939);
223
224 safe_browsing_util::FreeChunks(&chunks);
225}
226
227// Test parsing one sub chunk with full hashes.
228TEST(SafeBrowsingProtocolParsingTest, TestSubFullChunk) {
229 std::string sub_chunk("s:1:32:77\naaaa");
230 sub_chunk.push_back(2);
231
232 SBFullHash full_hash1, full_hash2;
233 for (int i = 0; i < 32; ++i) {
234 full_hash1.full_hash[i] = i % 2 ? 1 : 2;
235 full_hash2.full_hash[i] = i % 2 ? 3 : 4;
236 }
237
238 sub_chunk.append("yyyy");
239 sub_chunk.append(full_hash1.full_hash, 32);
240 sub_chunk.append("zzzz");
241 sub_chunk.append(full_hash2.full_hash, 32);
242
243 // Run the parse.
244 SafeBrowsingProtocolParser parser;
245 bool re_key = false;
246 std::deque<SBChunk> chunks;
247 bool result = parser.ParseChunk(sub_chunk.data(),
248 static_cast<int>(sub_chunk.length()),
249 "", "", &re_key, &chunks);
250 EXPECT_TRUE(result);
251 EXPECT_FALSE(re_key);
[email protected]954bc8a52008-09-17 18:16:01252 EXPECT_EQ(chunks.size(), static_cast<size_t>(1));
initial.commit09911bf2008-07-26 23:55:29253 EXPECT_EQ(chunks[0].chunk_number, 1);
[email protected]954bc8a52008-09-17 18:16:01254 EXPECT_EQ(chunks[0].hosts.size(), static_cast<size_t>(1));
initial.commit09911bf2008-07-26 23:55:29255
256 EXPECT_EQ(chunks[0].hosts[0].host, 0x61616161);
257 SBEntry* entry = chunks[0].hosts[0].entry;
258 EXPECT_EQ(entry->type(), SBEntry::SUB_FULL_HASH);
259 EXPECT_EQ(entry->prefix_count(), 2);
260 EXPECT_EQ(entry->ChunkIdAtPrefix(0), 0x79797979);
261 EXPECT_TRUE(entry->FullHashAt(0) == full_hash1);
262 EXPECT_EQ(entry->ChunkIdAtPrefix(1), 0x7a7a7a7a);
263 EXPECT_TRUE(entry->FullHashAt(1) == full_hash2);
264
265 safe_browsing_util::FreeChunks(&chunks);
266}
267
268// Test parsing the SafeBrowsing update response.
269TEST(SafeBrowsingProtocolParsingTest, TestChunkDelete) {
270 std::string add_del("n:1700\ni:phishy\nad:1-7,43-597,44444,99999\n"
271 "i:malware\nsd:21-27,42,171717\n");
272
273 SafeBrowsingProtocolParser parser;
274 int next_query_sec = 0;
275 bool re_key = false;
276 bool reset = false;
277 std::vector<SBChunkDelete> deletes;
278 std::vector<ChunkUrl> urls;
279 EXPECT_TRUE(parser.ParseUpdate(add_del.data(),
280 static_cast<int>(add_del.length()), "",
281 &next_query_sec, &re_key,
282 &reset, &deletes, &urls));
283
284 EXPECT_TRUE(urls.empty());
285 EXPECT_FALSE(re_key);
286 EXPECT_FALSE(reset);
287 EXPECT_EQ(next_query_sec, 1700);
[email protected]954bc8a52008-09-17 18:16:01288 EXPECT_EQ(deletes.size(), static_cast<size_t>(2));
initial.commit09911bf2008-07-26 23:55:29289
[email protected]954bc8a52008-09-17 18:16:01290 EXPECT_EQ(deletes[0].chunk_del.size(), static_cast<size_t>(4));
initial.commit09911bf2008-07-26 23:55:29291 EXPECT_TRUE(deletes[0].chunk_del[0] == ChunkRange(1, 7));
292 EXPECT_TRUE(deletes[0].chunk_del[1] == ChunkRange(43, 597));
293 EXPECT_TRUE(deletes[0].chunk_del[2] == ChunkRange(44444));
294 EXPECT_TRUE(deletes[0].chunk_del[3] == ChunkRange(99999));
295
[email protected]954bc8a52008-09-17 18:16:01296 EXPECT_EQ(deletes[1].chunk_del.size(), static_cast<size_t>(3));
initial.commit09911bf2008-07-26 23:55:29297 EXPECT_TRUE(deletes[1].chunk_del[0] == ChunkRange(21, 27));
298 EXPECT_TRUE(deletes[1].chunk_del[1] == ChunkRange(42));
299 EXPECT_TRUE(deletes[1].chunk_del[2] == ChunkRange(171717));
300
301 // An update response with missing list name.
302
303 next_query_sec = 0;
304 deletes.clear();
305 urls.clear();
306 add_del = "n:1700\nad:1-7,43-597,44444,99999\ni:malware\nsd:4,21-27171717\n";
307 EXPECT_FALSE(parser.ParseUpdate(add_del.data(),
308 static_cast<int>(add_del.length()), "",
309 &next_query_sec, &re_key,
310 &reset, &deletes, &urls));
311}
312
313// Test parsing the SafeBrowsing update response.
314TEST(SafeBrowsingProtocolParsingTest, TestRedirects) {
315 std::string redirects("i:goog-malware-shavar\n"
316 "u:cache.googlevideo.com/safebrowsing/rd/goog-malware-shavar_s_1\n"
317 "u:cache.googlevideo.com/safebrowsing/rd/goog-malware-shavar_s_2\n"
318 "u:cache.googlevideo.com/safebrowsing/rd/goog-malware-shavar_s_3\n"
319 "u:s.ytimg.com/safebrowsing/rd/goog-phish-shavar_a_8641-8800:8641-8689,"
320 "8691-8731,8733-8786\n");
321
322 SafeBrowsingProtocolParser parser;
323 int next_query_sec = 0;
324 bool re_key = false;
325 bool reset = false;
326 std::vector<SBChunkDelete> deletes;
327 std::vector<ChunkUrl> urls;
328 EXPECT_TRUE(parser.ParseUpdate(redirects.data(),
329 static_cast<int>(redirects.length()), "",
330 &next_query_sec, &re_key,
331 &reset, &deletes, &urls));
332
333 EXPECT_FALSE(re_key);
334 EXPECT_FALSE(reset);
[email protected]954bc8a52008-09-17 18:16:01335 EXPECT_EQ(urls.size(), static_cast<size_t>(4));
initial.commit09911bf2008-07-26 23:55:29336 EXPECT_EQ(urls[0].url,
337 "cache.googlevideo.com/safebrowsing/rd/goog-malware-shavar_s_1");
338 EXPECT_EQ(urls[1].url,
339 "cache.googlevideo.com/safebrowsing/rd/goog-malware-shavar_s_2");
340 EXPECT_EQ(urls[2].url,
341 "cache.googlevideo.com/safebrowsing/rd/goog-malware-shavar_s_3");
342 EXPECT_EQ(urls[3].url,
343 "s.ytimg.com/safebrowsing/rd/goog-phish-shavar_a_8641-8800:8641-8689,"
344 "8691-8731,8733-8786");
345 EXPECT_EQ(next_query_sec, 0);
346 EXPECT_TRUE(deletes.empty());
347}
348
349TEST(SafeBrowsingProtocolParsingTest, TestRedirectsWithMac) {
350 std::string redirects("i:goog-phish-shavar\n"
351 "u:s.ytimg.com/safebrowsing/rd/goog-phish-shavar_s_6501-6505:6501-6505,"
352 "pcY6iVeT9-CBQ3fdAF0rpnKjR1Y=\n"
353 "u:s.ytimg.com/safebrowsing/rd/goog-phish-shavar_a_8001-8160:8001-8024,"
354 "8026-8045,8048-8049,8051-8134,8136-8152,8155-8160,"
355 "j6XXAEWnjYk9tVVLBSdQvIEq2Wg=\n");
356
357 SafeBrowsingProtocolParser parser;
358 int next_query_sec = 0;
359 bool re_key = false;
360 bool reset = false;
361 const std::string key("58Lqn5WIP961x3zuLGo5Uw==");
362 std::vector<SBChunkDelete> deletes;
363 std::vector<ChunkUrl> urls;
364 EXPECT_TRUE(parser.ParseUpdate(redirects.data(),
365 static_cast<int>(redirects.length()), key,
366 &next_query_sec, &re_key,
367 &reset, &deletes, &urls));
368
369 EXPECT_FALSE(re_key);
370 EXPECT_FALSE(reset);
[email protected]954bc8a52008-09-17 18:16:01371 EXPECT_EQ(urls.size(), static_cast<size_t>(2));
initial.commit09911bf2008-07-26 23:55:29372 EXPECT_EQ(urls[0].url,
373 "s.ytimg.com/safebrowsing/rd/goog-phish-shavar_s_6501-6505:6501-6505");
374 EXPECT_EQ(urls[0].mac, "pcY6iVeT9-CBQ3fdAF0rpnKjR1Y=");
375 EXPECT_EQ(urls[1].url,
376 "s.ytimg.com/safebrowsing/rd/goog-phish-shavar_a_8001-8160:8001-8024,"
377 "8026-8045,8048-8049,8051-8134,8136-8152,8155-8160");
378 EXPECT_EQ(urls[1].mac, "j6XXAEWnjYk9tVVLBSdQvIEq2Wg=");
379}
380
381// Test parsing various SafeBrowsing protocol headers.
382TEST(SafeBrowsingProtocolParsingTest, TestNextQueryTime) {
383 std::string headers("n:1800\ni:goog-white-shavar\n");
384 SafeBrowsingProtocolParser parser;
385 int next_query_sec = 0;
386 bool re_key = false;
387 bool reset = false;
388 std::vector<SBChunkDelete> deletes;
389 std::vector<ChunkUrl> urls;
390 EXPECT_TRUE(parser.ParseUpdate(headers.data(),
391 static_cast<int>(headers.length()), "",
392 &next_query_sec, &re_key,
393 &reset, &deletes, &urls));
394
395 EXPECT_EQ(next_query_sec, 1800);
396 EXPECT_FALSE(re_key);
397 EXPECT_FALSE(reset);
398 EXPECT_TRUE(deletes.empty());
399 EXPECT_TRUE(urls.empty());
400}
401
402// Test parsing data from a GetHashRequest
403TEST(SafeBrowsingProtocolParsingTest, TestGetHash) {
404 std::string get_hash("goog-phish-shavar:19:96\n"
405 "00112233445566778899aabbccddeeff"
406 "00001111222233334444555566667777"
407 "ffffeeeeddddccccbbbbaaaa99998888");
408 std::vector<SBFullHashResult> full_hashes;
409 bool re_key = false;
410 SafeBrowsingProtocolParser parser;
411 parser.ParseGetHash(get_hash.data(),
412 static_cast<int>(get_hash.length()), "",
413 &re_key,
414 &full_hashes);
415
416 EXPECT_FALSE(re_key);
[email protected]954bc8a52008-09-17 18:16:01417 EXPECT_EQ(full_hashes.size(), static_cast<size_t>(3));
initial.commit09911bf2008-07-26 23:55:29418 EXPECT_EQ(memcmp(&full_hashes[0].hash,
419 "00112233445566778899aabbccddeeff",
420 sizeof(SBFullHash)), 0);
421 EXPECT_EQ(full_hashes[0].list_name, "goog-phish-shavar");
422 EXPECT_EQ(memcmp(&full_hashes[1].hash,
423 "00001111222233334444555566667777",
424 sizeof(SBFullHash)), 0);
425 EXPECT_EQ(full_hashes[1].list_name, "goog-phish-shavar");
426 EXPECT_EQ(memcmp(&full_hashes[2].hash,
427 "ffffeeeeddddccccbbbbaaaa99998888",
428 sizeof(SBFullHash)), 0);
429 EXPECT_EQ(full_hashes[2].list_name, "goog-phish-shavar");
430
431 // Test multiple lists in the GetHash results.
432 std::string get_hash2("goog-phish-shavar:19:32\n"
433 "00112233445566778899aabbccddeeff"
434 "goog-malware-shavar:19:64\n"
435 "cafebeefcafebeefdeaddeaddeaddead"
436 "zzzzyyyyxxxxwwwwvvvvuuuuttttssss");
437 parser.ParseGetHash(get_hash2.data(),
438 static_cast<int>(get_hash2.length()), "",
439 &re_key,
440 &full_hashes);
441
442 EXPECT_FALSE(re_key);
[email protected]954bc8a52008-09-17 18:16:01443 EXPECT_EQ(full_hashes.size(), static_cast<size_t>(3));
initial.commit09911bf2008-07-26 23:55:29444 EXPECT_EQ(memcmp(&full_hashes[0].hash,
445 "00112233445566778899aabbccddeeff",
446 sizeof(SBFullHash)), 0);
447 EXPECT_EQ(full_hashes[0].list_name, "goog-phish-shavar");
448 EXPECT_EQ(memcmp(&full_hashes[1].hash,
449 "cafebeefcafebeefdeaddeaddeaddead",
450 sizeof(SBFullHash)), 0);
451 EXPECT_EQ(full_hashes[1].list_name, "goog-malware-shavar");
452 EXPECT_EQ(memcmp(&full_hashes[2].hash,
453 "zzzzyyyyxxxxwwwwvvvvuuuuttttssss",
454 sizeof(SBFullHash)), 0);
455 EXPECT_EQ(full_hashes[2].list_name, "goog-malware-shavar");
456}
457
458TEST(SafeBrowsingProtocolParsingTest, TestGetHashWithMac) {
initial.commit09911bf2008-07-26 23:55:29459 const unsigned char get_hash[] = {
460 0x32, 0x56, 0x74, 0x6f, 0x6b, 0x36, 0x64, 0x41,
461 0x51, 0x72, 0x65, 0x51, 0x62, 0x38, 0x51, 0x68,
462 0x59, 0x45, 0x57, 0x51, 0x57, 0x4d, 0x52, 0x65,
463 0x42, 0x63, 0x41, 0x3d, 0x0a, 0x67, 0x6f, 0x6f,
464 0x67, 0x2d, 0x70, 0x68, 0x69, 0x73, 0x68, 0x2d,
465 0x73, 0x68, 0x61, 0x76, 0x61, 0x72, 0x3a, 0x36,
466 0x31, 0x36, 0x39, 0x3a, 0x33, 0x32, 0x0a, 0x17,
467 0x7f, 0x03, 0x42, 0x28, 0x1c, 0x31, 0xb9, 0x0b,
468 0x1c, 0x7b, 0x9d, 0xaf, 0x7b, 0x43, 0x99, 0x10,
469 0xc1, 0xab, 0xe3, 0x1b, 0x35, 0x80, 0x38, 0x96,
470 0xf9, 0x44, 0x4f, 0x28, 0xb4, 0xeb, 0x45
471 };
472
473 const unsigned char hash_result [] = {
474 0x17, 0x7f, 0x03, 0x42, 0x28, 0x1c, 0x31, 0xb9,
475 0x0b, 0x1c, 0x7b, 0x9d, 0xaf, 0x7b, 0x43, 0x99,
476 0x10, 0xc1, 0xab, 0xe3, 0x1b, 0x35, 0x80, 0x38,
477 0x96, 0xf9, 0x44, 0x4f, 0x28, 0xb4, 0xeb, 0x45
478 };
479
480 const std::string key = "58Lqn5WIP961x3zuLGo5Uw==";
481 std::vector<SBFullHashResult> full_hashes;
482 bool re_key = false;
483 SafeBrowsingProtocolParser parser;
484 EXPECT_TRUE(parser.ParseGetHash(reinterpret_cast<const char*>(get_hash),
485 sizeof(get_hash),
486 key,
487 &re_key,
488 &full_hashes));
489 EXPECT_FALSE(re_key);
[email protected]954bc8a52008-09-17 18:16:01490 EXPECT_EQ(full_hashes.size(), static_cast<size_t>(1));
initial.commit09911bf2008-07-26 23:55:29491 EXPECT_EQ(memcmp(hash_result, &full_hashes[0].hash, sizeof(SBFullHash)), 0);
492}
initial.commit09911bf2008-07-26 23:55:29493
[email protected]3b0f5f62009-01-08 01:22:30494TEST(SafeBrowsingProtocolParsingTest, TestGetHashWithUnknownList) {
495 std::string hash_response = "goog-phish-shavar:1:32\n"
496 "12345678901234567890123456789012"
497 "googpub-phish-shavar:19:32\n"
498 "09876543210987654321098765432109";
499 bool re_key = false;
500 std::string key = "";
501 std::vector<SBFullHashResult> full_hashes;
502 SafeBrowsingProtocolParser parser;
503 EXPECT_TRUE(parser.ParseGetHash(hash_response.data(),
504 hash_response.size(),
505 key,
506 &re_key,
507 &full_hashes));
508
509 EXPECT_EQ(full_hashes.size(), 1);
510 EXPECT_EQ(memcmp("12345678901234567890123456789012",
511 &full_hashes[0].hash, sizeof(SBFullHash)), 0);
512 EXPECT_EQ(full_hashes[0].list_name, "goog-phish-shavar");
513 EXPECT_EQ(full_hashes[0].add_chunk_id, 1);
514
515 hash_response += "goog-malware-shavar:7:32\n"
516 "abcdefghijklmnopqrstuvwxyz123457";
517 full_hashes.clear();
518 EXPECT_TRUE(parser.ParseGetHash(hash_response.data(),
519 hash_response.size(),
520 key,
521 &re_key,
522 &full_hashes));
523
524 EXPECT_EQ(full_hashes.size(), 2);
525 EXPECT_EQ(memcmp("12345678901234567890123456789012",
526 &full_hashes[0].hash, sizeof(SBFullHash)), 0);
527 EXPECT_EQ(full_hashes[0].list_name, "goog-phish-shavar");
528 EXPECT_EQ(full_hashes[0].add_chunk_id, 1);
529 EXPECT_EQ(memcmp("abcdefghijklmnopqrstuvwxyz123457",
530 &full_hashes[1].hash, sizeof(SBFullHash)), 0);
531 EXPECT_EQ(full_hashes[1].list_name, "goog-malware-shavar");
532 EXPECT_EQ(full_hashes[1].add_chunk_id, 7);
533}
534
initial.commit09911bf2008-07-26 23:55:29535TEST(SafeBrowsingProtocolParsingTest, TestFormatHash) {
536 SafeBrowsingProtocolParser parser;
537 std::vector<SBPrefix> prefixes;
538 std::string get_hash;
539
540 prefixes.push_back(0x34333231);
541 prefixes.push_back(0x64636261);
542 prefixes.push_back(0x73727170);
543
544 parser.FormatGetHash(prefixes, &get_hash);
545 EXPECT_EQ(get_hash, "4:12\n1234abcdpqrs");
546}
547
548TEST(SafeBrowsingProtocolParsingTest, TestGetKey) {
549 SafeBrowsingProtocolParser parser;
550 std::string key_response("clientkey:10:0123456789\n"
551 "wrappedkey:20:abcdefghijklmnopqrst\n");
552
553 std::string client_key, wrapped_key;
554 EXPECT_TRUE(parser.ParseNewKey(key_response.data(),
555 static_cast<int>(key_response.length()),
556 &client_key,
557 &wrapped_key));
558
559 EXPECT_EQ(client_key, "0123456789");
560 EXPECT_EQ(wrapped_key, "abcdefghijklmnopqrst");
561}
562
563TEST(SafeBrowsingProtocolParsingTest, TestReKey) {
564 SafeBrowsingProtocolParser parser;
565 std::string update("n:1800\ni:phishy\ne:pleaserekey\n");
566
567 bool re_key = false;
568 bool reset = false;
569 int next_update = -1;
570 std::vector<SBChunkDelete> deletes;
571 std::vector<ChunkUrl> urls;
572 EXPECT_TRUE(parser.ParseUpdate(update.data(),
573 static_cast<int>(update.size()), "",
574 &next_update, &re_key,
575 &reset, &deletes, &urls));
576 EXPECT_TRUE(re_key);
577}
578
579TEST(SafeBrowsingProtocolParsingTest, TestReset) {
580 SafeBrowsingProtocolParser parser;
581 std::string update("n:1800\ni:phishy\nr:pleasereset\n");
582
583 bool re_key = false;
584 bool reset = false;
585 int next_update = -1;
586 std::vector<SBChunkDelete> deletes;
587 std::vector<ChunkUrl> urls;
588 EXPECT_TRUE(parser.ParseUpdate(update.data(),
589 static_cast<int>(update.size()), "",
590 &next_update, &re_key,
591 &reset, &deletes, &urls));
592 EXPECT_TRUE(reset);
593}
594
[email protected]445d4cc2008-10-09 21:31:57595// The SafeBrowsing service will occasionally send zero length chunks so that
596// client requests will have longer contiguous chunk number ranges, and thus
597// reduce the request size.
598TEST(SafeBrowsingProtocolParsingTest, TestZeroSizeAddChunk) {
599 std::string add_chunk("a:1:4:0\n");
600 SafeBrowsingProtocolParser parser;
601 bool re_key = false;
602 std::deque<SBChunk> chunks;
603
604 bool result = parser.ParseChunk(add_chunk.data(),
605 static_cast<int>(add_chunk.length()),
606 "", "", &re_key, &chunks);
607 EXPECT_TRUE(result);
608 EXPECT_EQ(chunks.size(), static_cast<size_t>(1));
609 EXPECT_EQ(chunks[0].chunk_number, 1);
610 EXPECT_EQ(chunks[0].hosts.size(), static_cast<size_t>(0));
611
612 safe_browsing_util::FreeChunks(&chunks);
613
614 // Now test a zero size chunk in between normal chunks.
615 chunks.clear();
616 std::string add_chunks("a:1:4:18\n1234\001abcd5678\001wxyz"
617 "a:2:4:0\n"
618 "a:3:4:9\ncafe\001beef");
619 result = parser.ParseChunk(add_chunks.data(),
620 static_cast<int>(add_chunks.length()),
621 "", "", &re_key, &chunks);
622 EXPECT_TRUE(result);
623 EXPECT_EQ(chunks.size(), static_cast<size_t>(3));
624
625 // See that each chunk has the right content.
626 EXPECT_EQ(chunks[0].chunk_number, 1);
627 EXPECT_EQ(chunks[0].hosts.size(), static_cast<size_t>(2));
628 EXPECT_EQ(chunks[0].hosts[0].host, 0x34333231);
629 EXPECT_EQ(chunks[0].hosts[0].entry->PrefixAt(0), 0x64636261);
630 EXPECT_EQ(chunks[0].hosts[1].host, 0x38373635);
631 EXPECT_EQ(chunks[0].hosts[1].entry->PrefixAt(0), 0x7a797877);
632
633 EXPECT_EQ(chunks[1].chunk_number, 2);
634 EXPECT_EQ(chunks[1].hosts.size(), static_cast<size_t>(0));
635
636 EXPECT_EQ(chunks[2].chunk_number, 3);
637 EXPECT_EQ(chunks[2].hosts.size(), static_cast<size_t>(1));
638 EXPECT_EQ(chunks[2].hosts[0].host, 0x65666163);
639 EXPECT_EQ(chunks[2].hosts[0].entry->PrefixAt(0), 0x66656562);
640
641 safe_browsing_util::FreeChunks(&chunks);
642}
643
644// Test parsing a zero sized sub chunk.
645TEST(SafeBrowsingProtocolParsingTest, TestZeroSizeSubChunk) {
646 std::string sub_chunk("s:9:4:0\n");
647 SafeBrowsingProtocolParser parser;
648 bool re_key = false;
649 std::deque<SBChunk> chunks;
650
651 bool result = parser.ParseChunk(sub_chunk.data(),
652 static_cast<int>(sub_chunk.length()),
653 "", "", &re_key, &chunks);
654 EXPECT_TRUE(result);
655 EXPECT_EQ(chunks.size(), static_cast<size_t>(1));
656 EXPECT_EQ(chunks[0].chunk_number, 9);
657 EXPECT_EQ(chunks[0].hosts.size(), static_cast<size_t>(0));
658
659 safe_browsing_util::FreeChunks(&chunks);
660 chunks.clear();
661
662 // Test parsing a zero sized sub chunk mixed in with content carrying chunks.
663 std::string sub_chunks("s:1:4:9\nabcdxwxyz"
664 "s:2:4:0\n"
665 "s:3:4:26\nefgh\0011234pqrscafe\0015678lmno");
666 sub_chunks[12] = '\0';
667
668 result = parser.ParseChunk(sub_chunks.data(),
669 static_cast<int>(sub_chunks.length()),
670 "", "", &re_key, &chunks);
671 EXPECT_TRUE(result);
672
673 EXPECT_EQ(chunks[0].chunk_number, 1);
674 EXPECT_EQ(chunks[0].hosts.size(), static_cast<size_t>(1));
675 EXPECT_EQ(chunks[0].hosts[0].host, 0x64636261);
676 EXPECT_EQ(chunks[0].hosts[0].entry->prefix_count(), 0);
677
678 EXPECT_EQ(chunks[1].chunk_number, 2);
679 EXPECT_EQ(chunks[1].hosts.size(), static_cast<size_t>(0));
680
681 EXPECT_EQ(chunks[2].chunk_number, 3);
682 EXPECT_EQ(chunks[2].hosts.size(), static_cast<size_t>(2));
683 EXPECT_EQ(chunks[2].hosts[0].host, 0x68676665);
684 EXPECT_EQ(chunks[2].hosts[0].entry->prefix_count(), 1);
685 EXPECT_EQ(chunks[2].hosts[0].entry->PrefixAt(0), 0x73727170);
686 EXPECT_EQ(chunks[2].hosts[0].entry->ChunkIdAtPrefix(0), 0x31323334);
687 EXPECT_EQ(chunks[2].hosts[1].host, 0x65666163);
688 EXPECT_EQ(chunks[2].hosts[1].entry->prefix_count(), 1);
689 EXPECT_EQ(chunks[2].hosts[1].entry->PrefixAt(0), 0x6f6e6d6c);
690 EXPECT_EQ(chunks[2].hosts[1].entry->ChunkIdAtPrefix(0), 0x35363738);
691
692 safe_browsing_util::FreeChunks(&chunks);
693}
694
initial.commit09911bf2008-07-26 23:55:29695TEST(SafeBrowsingProtocolParsingTest, TestVerifyUpdateMac) {
initial.commit09911bf2008-07-26 23:55:29696 SafeBrowsingProtocolParser parser;
697
698 const std::string update =
699 "m:XIU0LiQhAPJq6dynXwHbygjS5tw=\n"
700 "n:1895\n"
701 "i:goog-phish-shavar\n"
702 "u:s.ytimg.com/safebrowsing/rd/goog-phish-shavar_s_6501-6505:6501-6505,pcY6iVeT9-CBQ3fdAF0rpnKjR1Y=\n"
703 "u:s.ytimg.com/safebrowsing/rd/goog-phish-shavar_s_6506-6510:6506-6510,SDBrYC3rX3KEPe72LOypnP6QYac=\n"
704 "u:s.ytimg.com/safebrowsing/rd/goog-phish-shavar_s_6511-6520:6511-6520,9UQo-e7OkcsXT2wFWTAhOuWOsUs=\n"
705 "u:s.ytimg.com/safebrowsing/rd/goog-phish-shavar_s_6521-6560:6521-6560,qVNw6JIpR1q6PIXST7J4LJ9n3Zg=\n"
706 "u:s.ytimg.com/safebrowsing/rd/goog-phish-shavar_s_6561-6720:6561-6720,7OiJvCbiwvpzPITW-hQohY5NHuc=\n"
707 "u:s.ytimg.com/safebrowsing/rd/goog-phish-shavar_s_6721-6880:6721-6880,oBS3svhoi9deIa0sWZ_gnD0ujj8=\n"
708 "u:s.ytimg.com/safebrowsing/rd/goog-phish-shavar_s_6881-7040:6881-7040,a0r8Xit4VvH39xgyQHZTPczKBIE=\n"
709 "u:s.ytimg.com/safebrowsing/rd/goog-phish-shavar_s_7041-7200:7041-7163,q538LChutGknBw55s6kcE2wTcvU=\n"
710 "u:s.ytimg.com/safebrowsing/rd/goog-phish-shavar_a_8001-8160:8001-8024,8026-8045,8048-8049,8051-8134,8136-8152,8155-8160,j6XXAEWnjYk9tVVLBSdQvIEq2Wg=\n"
711 "u:s.ytimg.com/safebrowsing/rd/goog-phish-shavar_a_8161-8320:8161-8215,8217-8222,8224-8320,YaNfiqdQOt-uLCLWVLj46AZpAjQ=\n"
712 "u:s.ytimg.com/safebrowsing/rd/goog-phish-shavar_a_8321-8480:8321-8391,8393-8399,8402,8404-8419,8421-8425,8427,8431-8433,8435-8439,8441-8443,8445-8446,8448-8480,ALj31GQMwGiIeU3bM2ZYKITfU-U=\n"
713 "u:s.ytimg.com/safebrowsing/rd/goog-phish-shavar_a_8481-8640:8481-8500,8502-8508,8510-8511,8513-8517,8519-8525,8527-8531,8533,8536-8539,8541-8576,8578-8638,8640,TlQYRmS_kZ5PBAUIUyNQDq0Jprs=\n"
714 "u:s.ytimg.com/safebrowsing/rd/goog-phish-shavar_a_8641-8800:8641-8689,8691-8731,8733-8786,x1Qf7hdNrO8b6yym03ZzNydDS1o=\n";
715
716 bool re_key = false;
717 bool reset = false;
718 int next_update = -1;
719 std::vector<SBChunkDelete> deletes;
720 std::vector<ChunkUrl> urls;
721 const std::string key("58Lqn5WIP961x3zuLGo5Uw==");
722 EXPECT_TRUE(parser.ParseUpdate(update.data(),
723 static_cast<int>(update.size()), key,
724 &next_update, &re_key,
725 &reset, &deletes, &urls));
726 EXPECT_FALSE(re_key);
727 EXPECT_EQ(next_update, 1895);
728}
729
730TEST(SafeBrowsingProtocolParsingTest, TestVerifyChunkMac) {
initial.commit09911bf2008-07-26 23:55:29731 SafeBrowsingProtocolParser parser;
732
733 const unsigned char chunk[] = {
734 0x73, 0x3a, 0x32, 0x30, 0x30, 0x32, 0x3a, 0x34,
735 0x3a, 0x32, 0x32, 0x0a, 0x2f, 0x4f, 0x89, 0x7a,
736 0x01, 0x00, 0x00, 0x0a, 0x59, 0xc8, 0x71, 0xdf,
737 0x9d, 0x29, 0x0c, 0xba, 0xd7, 0x00, 0x00, 0x00,
738 0x0a, 0x59
739 };
740
741 bool re_key = false;
742 std::deque<SBChunk> chunks;
743 const std::string key("v_aDSz6jI92WeHCOoZ07QA==");
744 const std::string mac("W9Xp2fUcQ9V66If6Cvsrstpa4Kk=");
745
746 EXPECT_TRUE(parser.ParseChunk(reinterpret_cast<const char*>(chunk),
747 sizeof(chunk), key, mac,
748 &re_key, &chunks));
749 EXPECT_FALSE(re_key);
750
751 safe_browsing_util::FreeChunks(&chunks);
license.botbf09a502008-08-24 00:55:55752}