diff options
Diffstat (limited to 'chrome/browser/safe_browsing/protocol_parser_unittest.cc')
-rw-r--r-- | chrome/browser/safe_browsing/protocol_parser_unittest.cc | 654 |
1 files changed, 654 insertions, 0 deletions
diff --git a/chrome/browser/safe_browsing/protocol_parser_unittest.cc b/chrome/browser/safe_browsing/protocol_parser_unittest.cc new file mode 100644 index 0000000..2366543 --- /dev/null +++ b/chrome/browser/safe_browsing/protocol_parser_unittest.cc @@ -0,0 +1,654 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Program to test the SafeBrowsing protocol parsing v2.1. + +#include <hash_map> + +#include "base/logging.h" +#include "base/string_util.h" +#include "base/win_util.h" +#include "chrome/browser/safe_browsing/protocol_parser.h" +#include "testing/gtest/include/gtest/gtest.h" + + +// Test parsing one add chunk. +TEST(SafeBrowsingProtocolParsingTest, TestAddChunk) { + std::string add_chunk("a:1:4:35\naaaax1111\0032222333344447777\00288889999"); + add_chunk[13] = '\0'; + + // Run the parse. + SafeBrowsingProtocolParser parser; + bool re_key = false; + std::deque<SBChunk> chunks; + bool result = parser.ParseChunk(add_chunk.data(), + static_cast<int>(add_chunk.length()), + "", "", &re_key, &chunks); + EXPECT_TRUE(result); + EXPECT_FALSE(re_key); + EXPECT_EQ(chunks.size(), 1); + EXPECT_EQ(chunks[0].chunk_number, 1); + EXPECT_EQ(chunks[0].hosts.size(), 3); + + EXPECT_EQ(chunks[0].hosts[0].host, 0x61616161); + SBEntry* entry = chunks[0].hosts[0].entry; + EXPECT_EQ(entry->type(), SBEntry::ADD_PREFIX); + EXPECT_EQ(entry->prefix_count(), 0); + + EXPECT_EQ(chunks[0].hosts[1].host, 0x31313131); + entry = chunks[0].hosts[1].entry; + EXPECT_EQ(entry->type(), SBEntry::ADD_PREFIX); + EXPECT_EQ(entry->prefix_count(), 3); + EXPECT_EQ(entry->PrefixAt(0), 0x32323232); + EXPECT_EQ(entry->PrefixAt(1), 0x33333333); + EXPECT_EQ(entry->PrefixAt(2), 0x34343434); + + EXPECT_EQ(chunks[0].hosts[2].host, 0x37373737); + entry = chunks[0].hosts[2].entry; + EXPECT_EQ(entry->type(), SBEntry::ADD_PREFIX); + EXPECT_EQ(entry->prefix_count(), 2); + EXPECT_EQ(entry->PrefixAt(0), 0x38383838); + EXPECT_EQ(entry->PrefixAt(1), 0x39393939); + + safe_browsing_util::FreeChunks(&chunks); +} + +// Test parsing one add chunk with full hashes. +TEST(SafeBrowsingProtocolParsingTest, TestAddFullChunk) { + std::string add_chunk("a:1:32:69\naaaa"); + add_chunk.push_back(2); + + SBFullHash full_hash1, full_hash2; + for (int i = 0; i < 32; ++i) { + full_hash1.full_hash[i] = i % 2 ? 1 : 2; + full_hash2.full_hash[i] = i % 2 ? 3 : 4; + } + + add_chunk.append(full_hash1.full_hash, 32); + add_chunk.append(full_hash2.full_hash, 32); + + // Run the parse. + SafeBrowsingProtocolParser parser; + bool re_key = false; + std::deque<SBChunk> chunks; + bool result = parser.ParseChunk(add_chunk.data(), + static_cast<int>(add_chunk.length()), + "", "", &re_key, &chunks); + EXPECT_TRUE(result); + EXPECT_FALSE(re_key); + EXPECT_EQ(chunks.size(), 1); + EXPECT_EQ(chunks[0].chunk_number, 1); + EXPECT_EQ(chunks[0].hosts.size(), 1); + + EXPECT_EQ(chunks[0].hosts[0].host, 0x61616161); + SBEntry* entry = chunks[0].hosts[0].entry; + EXPECT_EQ(entry->type(), SBEntry::ADD_FULL_HASH); + EXPECT_EQ(entry->prefix_count(), 2); + EXPECT_TRUE(entry->FullHashAt(0) == full_hash1); + EXPECT_TRUE(entry->FullHashAt(1) == full_hash2); + + safe_browsing_util::FreeChunks(&chunks); +} + +// Test parsing multiple add chunks. We'll use the same chunk as above, and add +// one more after it. +TEST(SafeBrowsingProtocolParsingTest, TestAddChunks) { + std::string add_chunk("a:1:4:35\naaaax1111\0032222333344447777\00288889999" + "a:2:4:13\n5555\002ppppgggg"); + add_chunk[13] = '\0'; + + // Run the parse. + SafeBrowsingProtocolParser parser; + bool re_key = false; + std::deque<SBChunk> chunks; + bool result = parser.ParseChunk(add_chunk.data(), + static_cast<int>(add_chunk.length()), + "", "", &re_key, &chunks); + EXPECT_TRUE(result); + EXPECT_FALSE(re_key); + EXPECT_EQ(chunks.size(), 2); + EXPECT_EQ(chunks[0].chunk_number, 1); + EXPECT_EQ(chunks[0].hosts.size(), 3); + + EXPECT_EQ(chunks[0].hosts[0].host, 0x61616161); + SBEntry* entry = chunks[0].hosts[0].entry; + EXPECT_EQ(entry->type(), SBEntry::ADD_PREFIX); + EXPECT_EQ(entry->prefix_count(), 0); + + EXPECT_EQ(chunks[0].hosts[1].host, 0x31313131); + entry = chunks[0].hosts[1].entry; + EXPECT_EQ(entry->type(), SBEntry::ADD_PREFIX); + EXPECT_EQ(entry->prefix_count(), 3); + EXPECT_EQ(entry->PrefixAt(0), 0x32323232); + EXPECT_EQ(entry->PrefixAt(1), 0x33333333); + EXPECT_EQ(entry->PrefixAt(2), 0x34343434); + + EXPECT_EQ(chunks[0].hosts[2].host, 0x37373737); + entry = chunks[0].hosts[2].entry; + EXPECT_EQ(entry->type(), SBEntry::ADD_PREFIX); + EXPECT_EQ(entry->prefix_count(), 2); + EXPECT_EQ(entry->PrefixAt(0), 0x38383838); + EXPECT_EQ(entry->PrefixAt(1), 0x39393939); + + + EXPECT_EQ(chunks[1].chunk_number, 2); + EXPECT_EQ(chunks[1].hosts.size(), 1); + + EXPECT_EQ(chunks[1].hosts[0].host, 0x35353535); + entry = chunks[1].hosts[0].entry; + EXPECT_EQ(entry->type(), SBEntry::ADD_PREFIX); + EXPECT_EQ(entry->prefix_count(), 2); + EXPECT_EQ(entry->PrefixAt(0), 0x70707070); + EXPECT_EQ(entry->PrefixAt(1), 0x67676767); + + safe_browsing_util::FreeChunks(&chunks); +} + +// Test parsing one add chunk where a hostkey spans several entries. +TEST(SafeBrowsingProtocolParsingTest, TestAddBigChunk) { + std::string add_chunk("a:1:4:1050\naaaaX"); + add_chunk[add_chunk.size() - 1] |= 0xFF; + for (int i = 0; i < 255; ++i) + add_chunk.append(StringPrintf("%04d", i)); + + add_chunk.append("aaaa"); + add_chunk.push_back(5); + for (int i = 0; i < 5; ++i) + add_chunk.append(StringPrintf("001%d", i)); + + SafeBrowsingProtocolParser parser; + bool re_key = false; + std::deque<SBChunk> chunks; + bool result = parser.ParseChunk(add_chunk.data(), + static_cast<int>(add_chunk.length()), + "", "", &re_key, &chunks); + EXPECT_TRUE(result); + EXPECT_FALSE(re_key); + EXPECT_EQ(chunks.size(), 1); + EXPECT_EQ(chunks[0].chunk_number, 1); + + EXPECT_EQ(chunks[0].hosts.size(), 1); + + const SBChunkHost& host = chunks[0].hosts[0]; + EXPECT_EQ(host.host, 0x61616161); + EXPECT_EQ(host.entry->prefix_count(), 260); + + safe_browsing_util::FreeChunks(&chunks); +} + +// Test parsing one sub chunk. +TEST(SafeBrowsingProtocolParsingTest, TestSubChunk) { + std::string sub_chunk("s:9:4:59\naaaaxkkkk1111\003" + "zzzz2222zzzz3333zzzz4444" + "7777\002yyyy8888yyyy9999"); + sub_chunk[13] = '\0'; + + // Run the parse. + SafeBrowsingProtocolParser parser; + bool re_key = false; + std::deque<SBChunk> chunks; + bool result = parser.ParseChunk(sub_chunk.data(), + static_cast<int>(sub_chunk.length()), + "", "", &re_key, &chunks); + EXPECT_TRUE(result); + EXPECT_FALSE(re_key); + EXPECT_EQ(chunks.size(), 1); + EXPECT_EQ(chunks[0].chunk_number, 9); + EXPECT_EQ(chunks[0].hosts.size(), 3); + + EXPECT_EQ(chunks[0].hosts[0].host, 0x61616161); + SBEntry* entry = chunks[0].hosts[0].entry; + EXPECT_EQ(entry->type(), SBEntry::SUB_PREFIX); + EXPECT_EQ(entry->chunk_id(), 0x6b6b6b6b); + EXPECT_EQ(entry->prefix_count(), 0); + + EXPECT_EQ(chunks[0].hosts[1].host, 0x31313131); + entry = chunks[0].hosts[1].entry; + EXPECT_EQ(entry->type(), SBEntry::SUB_PREFIX); + EXPECT_EQ(entry->prefix_count(), 3); + EXPECT_EQ(entry->ChunkIdAtPrefix(0), 0x7a7a7a7a); + EXPECT_EQ(entry->PrefixAt(0), 0x32323232); + EXPECT_EQ(entry->ChunkIdAtPrefix(1), 0x7a7a7a7a); + EXPECT_EQ(entry->PrefixAt(1), 0x33333333); + EXPECT_EQ(entry->ChunkIdAtPrefix(2), 0x7a7a7a7a); + EXPECT_EQ(entry->PrefixAt(2), 0x34343434); + + EXPECT_EQ(chunks[0].hosts[2].host, 0x37373737); + entry = chunks[0].hosts[2].entry; + EXPECT_EQ(entry->type(), SBEntry::SUB_PREFIX); + EXPECT_EQ(entry->prefix_count(), 2); + EXPECT_EQ(entry->ChunkIdAtPrefix(0), 0x79797979); + EXPECT_EQ(entry->PrefixAt(0), 0x38383838); + EXPECT_EQ(entry->ChunkIdAtPrefix(1), 0x79797979); + EXPECT_EQ(entry->PrefixAt(1), 0x39393939); + + safe_browsing_util::FreeChunks(&chunks); +} + +// Test parsing one sub chunk with full hashes. +TEST(SafeBrowsingProtocolParsingTest, TestSubFullChunk) { + std::string sub_chunk("s:1:32:77\naaaa"); + sub_chunk.push_back(2); + + SBFullHash full_hash1, full_hash2; + for (int i = 0; i < 32; ++i) { + full_hash1.full_hash[i] = i % 2 ? 1 : 2; + full_hash2.full_hash[i] = i % 2 ? 3 : 4; + } + + sub_chunk.append("yyyy"); + sub_chunk.append(full_hash1.full_hash, 32); + sub_chunk.append("zzzz"); + sub_chunk.append(full_hash2.full_hash, 32); + + // Run the parse. + SafeBrowsingProtocolParser parser; + bool re_key = false; + std::deque<SBChunk> chunks; + bool result = parser.ParseChunk(sub_chunk.data(), + static_cast<int>(sub_chunk.length()), + "", "", &re_key, &chunks); + EXPECT_TRUE(result); + EXPECT_FALSE(re_key); + EXPECT_EQ(chunks.size(), 1); + EXPECT_EQ(chunks[0].chunk_number, 1); + EXPECT_EQ(chunks[0].hosts.size(), 1); + + EXPECT_EQ(chunks[0].hosts[0].host, 0x61616161); + SBEntry* entry = chunks[0].hosts[0].entry; + EXPECT_EQ(entry->type(), SBEntry::SUB_FULL_HASH); + EXPECT_EQ(entry->prefix_count(), 2); + EXPECT_EQ(entry->ChunkIdAtPrefix(0), 0x79797979); + EXPECT_TRUE(entry->FullHashAt(0) == full_hash1); + EXPECT_EQ(entry->ChunkIdAtPrefix(1), 0x7a7a7a7a); + EXPECT_TRUE(entry->FullHashAt(1) == full_hash2); + + safe_browsing_util::FreeChunks(&chunks); +} + +// Test parsing the SafeBrowsing update response. +TEST(SafeBrowsingProtocolParsingTest, TestChunkDelete) { + std::string add_del("n:1700\ni:phishy\nad:1-7,43-597,44444,99999\n" + "i:malware\nsd:21-27,42,171717\n"); + + SafeBrowsingProtocolParser parser; + int next_query_sec = 0; + bool re_key = false; + bool reset = false; + std::vector<SBChunkDelete> deletes; + std::vector<ChunkUrl> urls; + EXPECT_TRUE(parser.ParseUpdate(add_del.data(), + static_cast<int>(add_del.length()), "", + &next_query_sec, &re_key, + &reset, &deletes, &urls)); + + EXPECT_TRUE(urls.empty()); + EXPECT_FALSE(re_key); + EXPECT_FALSE(reset); + EXPECT_EQ(next_query_sec, 1700); + EXPECT_EQ(deletes.size(), 2); + + EXPECT_EQ(deletes[0].chunk_del.size(), 4); + EXPECT_TRUE(deletes[0].chunk_del[0] == ChunkRange(1, 7)); + EXPECT_TRUE(deletes[0].chunk_del[1] == ChunkRange(43, 597)); + EXPECT_TRUE(deletes[0].chunk_del[2] == ChunkRange(44444)); + EXPECT_TRUE(deletes[0].chunk_del[3] == ChunkRange(99999)); + + EXPECT_EQ(deletes[1].chunk_del.size(), 3); + EXPECT_TRUE(deletes[1].chunk_del[0] == ChunkRange(21, 27)); + EXPECT_TRUE(deletes[1].chunk_del[1] == ChunkRange(42)); + EXPECT_TRUE(deletes[1].chunk_del[2] == ChunkRange(171717)); + + // An update response with missing list name. + + next_query_sec = 0; + deletes.clear(); + urls.clear(); + add_del = "n:1700\nad:1-7,43-597,44444,99999\ni:malware\nsd:4,21-27171717\n"; + EXPECT_FALSE(parser.ParseUpdate(add_del.data(), + static_cast<int>(add_del.length()), "", + &next_query_sec, &re_key, + &reset, &deletes, &urls)); +} + +// Test parsing the SafeBrowsing update response. +TEST(SafeBrowsingProtocolParsingTest, TestRedirects) { + std::string redirects("i:goog-malware-shavar\n" + "u:cache.googlevideo.com/safebrowsing/rd/goog-malware-shavar_s_1\n" + "u:cache.googlevideo.com/safebrowsing/rd/goog-malware-shavar_s_2\n" + "u:cache.googlevideo.com/safebrowsing/rd/goog-malware-shavar_s_3\n" + "u:s.ytimg.com/safebrowsing/rd/goog-phish-shavar_a_8641-8800:8641-8689," + "8691-8731,8733-8786\n"); + + SafeBrowsingProtocolParser parser; + int next_query_sec = 0; + bool re_key = false; + bool reset = false; + std::vector<SBChunkDelete> deletes; + std::vector<ChunkUrl> urls; + EXPECT_TRUE(parser.ParseUpdate(redirects.data(), + static_cast<int>(redirects.length()), "", + &next_query_sec, &re_key, + &reset, &deletes, &urls)); + + EXPECT_FALSE(re_key); + EXPECT_FALSE(reset); + EXPECT_EQ(urls.size(), 4); + EXPECT_EQ(urls[0].url, + "cache.googlevideo.com/safebrowsing/rd/goog-malware-shavar_s_1"); + EXPECT_EQ(urls[1].url, + "cache.googlevideo.com/safebrowsing/rd/goog-malware-shavar_s_2"); + EXPECT_EQ(urls[2].url, + "cache.googlevideo.com/safebrowsing/rd/goog-malware-shavar_s_3"); + EXPECT_EQ(urls[3].url, + "s.ytimg.com/safebrowsing/rd/goog-phish-shavar_a_8641-8800:8641-8689," + "8691-8731,8733-8786"); + EXPECT_EQ(next_query_sec, 0); + EXPECT_TRUE(deletes.empty()); +} + +TEST(SafeBrowsingProtocolParsingTest, TestRedirectsWithMac) { + std::string redirects("i:goog-phish-shavar\n" + "u:s.ytimg.com/safebrowsing/rd/goog-phish-shavar_s_6501-6505:6501-6505," + "pcY6iVeT9-CBQ3fdAF0rpnKjR1Y=\n" + "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"); + + SafeBrowsingProtocolParser parser; + int next_query_sec = 0; + bool re_key = false; + bool reset = false; + const std::string key("58Lqn5WIP961x3zuLGo5Uw=="); + std::vector<SBChunkDelete> deletes; + std::vector<ChunkUrl> urls; + EXPECT_TRUE(parser.ParseUpdate(redirects.data(), + static_cast<int>(redirects.length()), key, + &next_query_sec, &re_key, + &reset, &deletes, &urls)); + + EXPECT_FALSE(re_key); + EXPECT_FALSE(reset); + EXPECT_EQ(urls.size(), 2); + EXPECT_EQ(urls[0].url, + "s.ytimg.com/safebrowsing/rd/goog-phish-shavar_s_6501-6505:6501-6505"); + EXPECT_EQ(urls[0].mac, "pcY6iVeT9-CBQ3fdAF0rpnKjR1Y="); + EXPECT_EQ(urls[1].url, + "s.ytimg.com/safebrowsing/rd/goog-phish-shavar_a_8001-8160:8001-8024," + "8026-8045,8048-8049,8051-8134,8136-8152,8155-8160"); + EXPECT_EQ(urls[1].mac, "j6XXAEWnjYk9tVVLBSdQvIEq2Wg="); +} + +// Test parsing various SafeBrowsing protocol headers. +TEST(SafeBrowsingProtocolParsingTest, TestNextQueryTime) { + std::string headers("n:1800\ni:goog-white-shavar\n"); + SafeBrowsingProtocolParser parser; + int next_query_sec = 0; + bool re_key = false; + bool reset = false; + std::vector<SBChunkDelete> deletes; + std::vector<ChunkUrl> urls; + EXPECT_TRUE(parser.ParseUpdate(headers.data(), + static_cast<int>(headers.length()), "", + &next_query_sec, &re_key, + &reset, &deletes, &urls)); + + EXPECT_EQ(next_query_sec, 1800); + EXPECT_FALSE(re_key); + EXPECT_FALSE(reset); + EXPECT_TRUE(deletes.empty()); + EXPECT_TRUE(urls.empty()); +} + +// Test parsing data from a GetHashRequest +TEST(SafeBrowsingProtocolParsingTest, TestGetHash) { + std::string get_hash("goog-phish-shavar:19:96\n" + "00112233445566778899aabbccddeeff" + "00001111222233334444555566667777" + "ffffeeeeddddccccbbbbaaaa99998888"); + std::vector<SBFullHashResult> full_hashes; + bool re_key = false; + SafeBrowsingProtocolParser parser; + parser.ParseGetHash(get_hash.data(), + static_cast<int>(get_hash.length()), "", + &re_key, + &full_hashes); + + EXPECT_FALSE(re_key); + EXPECT_EQ(full_hashes.size(), 3); + EXPECT_EQ(memcmp(&full_hashes[0].hash, + "00112233445566778899aabbccddeeff", + sizeof(SBFullHash)), 0); + EXPECT_EQ(full_hashes[0].list_name, "goog-phish-shavar"); + EXPECT_EQ(memcmp(&full_hashes[1].hash, + "00001111222233334444555566667777", + sizeof(SBFullHash)), 0); + EXPECT_EQ(full_hashes[1].list_name, "goog-phish-shavar"); + EXPECT_EQ(memcmp(&full_hashes[2].hash, + "ffffeeeeddddccccbbbbaaaa99998888", + sizeof(SBFullHash)), 0); + EXPECT_EQ(full_hashes[2].list_name, "goog-phish-shavar"); + + // Test multiple lists in the GetHash results. + std::string get_hash2("goog-phish-shavar:19:32\n" + "00112233445566778899aabbccddeeff" + "goog-malware-shavar:19:64\n" + "cafebeefcafebeefdeaddeaddeaddead" + "zzzzyyyyxxxxwwwwvvvvuuuuttttssss"); + parser.ParseGetHash(get_hash2.data(), + static_cast<int>(get_hash2.length()), "", + &re_key, + &full_hashes); + + EXPECT_FALSE(re_key); + EXPECT_EQ(full_hashes.size(), 3); + EXPECT_EQ(memcmp(&full_hashes[0].hash, + "00112233445566778899aabbccddeeff", + sizeof(SBFullHash)), 0); + EXPECT_EQ(full_hashes[0].list_name, "goog-phish-shavar"); + EXPECT_EQ(memcmp(&full_hashes[1].hash, + "cafebeefcafebeefdeaddeaddeaddead", + sizeof(SBFullHash)), 0); + EXPECT_EQ(full_hashes[1].list_name, "goog-malware-shavar"); + EXPECT_EQ(memcmp(&full_hashes[2].hash, + "zzzzyyyyxxxxwwwwvvvvuuuuttttssss", + sizeof(SBFullHash)), 0); + EXPECT_EQ(full_hashes[2].list_name, "goog-malware-shavar"); +} + +TEST(SafeBrowsingProtocolParsingTest, TestGetHashWithMac) { + // TODO(paulg): Bug: http://b/1084719, skip this test on Windows 2000 until + // this bug is fixed. + if (win_util::GetWinVersion() <= win_util::WINVERSION_2000) + return; + + const unsigned char get_hash[] = { + 0x32, 0x56, 0x74, 0x6f, 0x6b, 0x36, 0x64, 0x41, + 0x51, 0x72, 0x65, 0x51, 0x62, 0x38, 0x51, 0x68, + 0x59, 0x45, 0x57, 0x51, 0x57, 0x4d, 0x52, 0x65, + 0x42, 0x63, 0x41, 0x3d, 0x0a, 0x67, 0x6f, 0x6f, + 0x67, 0x2d, 0x70, 0x68, 0x69, 0x73, 0x68, 0x2d, + 0x73, 0x68, 0x61, 0x76, 0x61, 0x72, 0x3a, 0x36, + 0x31, 0x36, 0x39, 0x3a, 0x33, 0x32, 0x0a, 0x17, + 0x7f, 0x03, 0x42, 0x28, 0x1c, 0x31, 0xb9, 0x0b, + 0x1c, 0x7b, 0x9d, 0xaf, 0x7b, 0x43, 0x99, 0x10, + 0xc1, 0xab, 0xe3, 0x1b, 0x35, 0x80, 0x38, 0x96, + 0xf9, 0x44, 0x4f, 0x28, 0xb4, 0xeb, 0x45 + }; + + const unsigned char hash_result [] = { + 0x17, 0x7f, 0x03, 0x42, 0x28, 0x1c, 0x31, 0xb9, + 0x0b, 0x1c, 0x7b, 0x9d, 0xaf, 0x7b, 0x43, 0x99, + 0x10, 0xc1, 0xab, 0xe3, 0x1b, 0x35, 0x80, 0x38, + 0x96, 0xf9, 0x44, 0x4f, 0x28, 0xb4, 0xeb, 0x45 + }; + + const std::string key = "58Lqn5WIP961x3zuLGo5Uw=="; + std::vector<SBFullHashResult> full_hashes; + bool re_key = false; + SafeBrowsingProtocolParser parser; + EXPECT_TRUE(parser.ParseGetHash(reinterpret_cast<const char*>(get_hash), + sizeof(get_hash), + key, + &re_key, + &full_hashes)); + EXPECT_FALSE(re_key); + EXPECT_EQ(full_hashes.size(), 1); + EXPECT_EQ(memcmp(hash_result, &full_hashes[0].hash, sizeof(SBFullHash)), 0); +} + + +TEST(SafeBrowsingProtocolParsingTest, TestFormatHash) { + SafeBrowsingProtocolParser parser; + std::vector<SBPrefix> prefixes; + std::string get_hash; + + prefixes.push_back(0x34333231); + prefixes.push_back(0x64636261); + prefixes.push_back(0x73727170); + + parser.FormatGetHash(prefixes, &get_hash); + EXPECT_EQ(get_hash, "4:12\n1234abcdpqrs"); +} + +TEST(SafeBrowsingProtocolParsingTest, TestGetKey) { + SafeBrowsingProtocolParser parser; + std::string key_response("clientkey:10:0123456789\n" + "wrappedkey:20:abcdefghijklmnopqrst\n"); + + std::string client_key, wrapped_key; + EXPECT_TRUE(parser.ParseNewKey(key_response.data(), + static_cast<int>(key_response.length()), + &client_key, + &wrapped_key)); + + EXPECT_EQ(client_key, "0123456789"); + EXPECT_EQ(wrapped_key, "abcdefghijklmnopqrst"); +} + +TEST(SafeBrowsingProtocolParsingTest, TestReKey) { + SafeBrowsingProtocolParser parser; + std::string update("n:1800\ni:phishy\ne:pleaserekey\n"); + + bool re_key = false; + bool reset = false; + int next_update = -1; + std::vector<SBChunkDelete> deletes; + std::vector<ChunkUrl> urls; + EXPECT_TRUE(parser.ParseUpdate(update.data(), + static_cast<int>(update.size()), "", + &next_update, &re_key, + &reset, &deletes, &urls)); + EXPECT_TRUE(re_key); +} + +TEST(SafeBrowsingProtocolParsingTest, TestReset) { + SafeBrowsingProtocolParser parser; + std::string update("n:1800\ni:phishy\nr:pleasereset\n"); + + bool re_key = false; + bool reset = false; + int next_update = -1; + std::vector<SBChunkDelete> deletes; + std::vector<ChunkUrl> urls; + EXPECT_TRUE(parser.ParseUpdate(update.data(), + static_cast<int>(update.size()), "", + &next_update, &re_key, + &reset, &deletes, &urls)); + EXPECT_TRUE(reset); +} + +TEST(SafeBrowsingProtocolParsingTest, TestVerifyUpdateMac) { + // TODO(paulg): Bug: http://b/1084719, skip this test on Windows 2000 until + // this bug is fixed. + if (win_util::GetWinVersion() <= win_util::WINVERSION_2000) + return; + + SafeBrowsingProtocolParser parser; + + const std::string update = + "m:XIU0LiQhAPJq6dynXwHbygjS5tw=\n" + "n:1895\n" + "i:goog-phish-shavar\n" + "u:s.ytimg.com/safebrowsing/rd/goog-phish-shavar_s_6501-6505:6501-6505,pcY6iVeT9-CBQ3fdAF0rpnKjR1Y=\n" + "u:s.ytimg.com/safebrowsing/rd/goog-phish-shavar_s_6506-6510:6506-6510,SDBrYC3rX3KEPe72LOypnP6QYac=\n" + "u:s.ytimg.com/safebrowsing/rd/goog-phish-shavar_s_6511-6520:6511-6520,9UQo-e7OkcsXT2wFWTAhOuWOsUs=\n" + "u:s.ytimg.com/safebrowsing/rd/goog-phish-shavar_s_6521-6560:6521-6560,qVNw6JIpR1q6PIXST7J4LJ9n3Zg=\n" + "u:s.ytimg.com/safebrowsing/rd/goog-phish-shavar_s_6561-6720:6561-6720,7OiJvCbiwvpzPITW-hQohY5NHuc=\n" + "u:s.ytimg.com/safebrowsing/rd/goog-phish-shavar_s_6721-6880:6721-6880,oBS3svhoi9deIa0sWZ_gnD0ujj8=\n" + "u:s.ytimg.com/safebrowsing/rd/goog-phish-shavar_s_6881-7040:6881-7040,a0r8Xit4VvH39xgyQHZTPczKBIE=\n" + "u:s.ytimg.com/safebrowsing/rd/goog-phish-shavar_s_7041-7200:7041-7163,q538LChutGknBw55s6kcE2wTcvU=\n" + "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" + "u:s.ytimg.com/safebrowsing/rd/goog-phish-shavar_a_8161-8320:8161-8215,8217-8222,8224-8320,YaNfiqdQOt-uLCLWVLj46AZpAjQ=\n" + "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" + "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" + "u:s.ytimg.com/safebrowsing/rd/goog-phish-shavar_a_8641-8800:8641-8689,8691-8731,8733-8786,x1Qf7hdNrO8b6yym03ZzNydDS1o=\n"; + + bool re_key = false; + bool reset = false; + int next_update = -1; + std::vector<SBChunkDelete> deletes; + std::vector<ChunkUrl> urls; + const std::string key("58Lqn5WIP961x3zuLGo5Uw=="); + EXPECT_TRUE(parser.ParseUpdate(update.data(), + static_cast<int>(update.size()), key, + &next_update, &re_key, + &reset, &deletes, &urls)); + EXPECT_FALSE(re_key); + EXPECT_EQ(next_update, 1895); +} + +TEST(SafeBrowsingProtocolParsingTest, TestVerifyChunkMac) { + // TODO(paulg): Bug: http://b/1084719, skip this test on Windows 2000 until + // this bug is fixed. + if (win_util::GetWinVersion() <= win_util::WINVERSION_2000) + return; + + SafeBrowsingProtocolParser parser; + + const unsigned char chunk[] = { + 0x73, 0x3a, 0x32, 0x30, 0x30, 0x32, 0x3a, 0x34, + 0x3a, 0x32, 0x32, 0x0a, 0x2f, 0x4f, 0x89, 0x7a, + 0x01, 0x00, 0x00, 0x0a, 0x59, 0xc8, 0x71, 0xdf, + 0x9d, 0x29, 0x0c, 0xba, 0xd7, 0x00, 0x00, 0x00, + 0x0a, 0x59 + }; + + bool re_key = false; + std::deque<SBChunk> chunks; + const std::string key("v_aDSz6jI92WeHCOoZ07QA=="); + const std::string mac("W9Xp2fUcQ9V66If6Cvsrstpa4Kk="); + + EXPECT_TRUE(parser.ParseChunk(reinterpret_cast<const char*>(chunk), + sizeof(chunk), key, mac, + &re_key, &chunks)); + EXPECT_FALSE(re_key); + + safe_browsing_util::FreeChunks(&chunks); +}
\ No newline at end of file |