OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 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/safe_browsing_util.h" | 5 #include "components/safe_browsing_db/util.h" |
6 | 6 |
7 #include "base/logging.h" | |
8 #include "base/strings/string_util.h" | 7 #include "base/strings/string_util.h" |
9 #include "base/strings/stringprintf.h" | |
10 #include "chrome/browser/safe_browsing/chunk.pb.h" | |
11 #include "components/google/core/browser/google_util.h" | |
12 #include "crypto/sha2.h" | 8 #include "crypto/sha2.h" |
13 #include "net/base/escape.h" | 9 #include "net/base/escape.h" |
14 #include "url/gurl.h" | 10 #include "url/gurl.h" |
15 #include "url/url_util.h" | 11 #include "url/url_util.h" |
16 | 12 |
17 // SBCachedFullHashResult ------------------------------------------------------ | |
18 | |
19 SBCachedFullHashResult::SBCachedFullHashResult() {} | |
20 | |
21 SBCachedFullHashResult::SBCachedFullHashResult( | |
22 const base::Time& in_expire_after) | |
23 : expire_after(in_expire_after) {} | |
24 | |
25 SBCachedFullHashResult::~SBCachedFullHashResult() {} | |
26 | |
27 // SBChunkData ----------------------------------------------------------------- | |
28 | |
29 // TODO(shess): Right now this contains a scoped_ptr<ChunkData> so that the | |
30 // proto buffer isn't copied all over the place, then these are contained in a | |
31 // ScopedVector for purposes of passing things around between tasks. This seems | |
32 // convoluted. Maybe it would make sense to have an overall container class | |
33 // returning references to a nested per-chunk class? | |
34 | |
35 SBChunkData::SBChunkData() { | |
36 } | |
37 | |
38 SBChunkData::SBChunkData(safe_browsing::ChunkData* raw_data) | |
39 : chunk_data_(raw_data) { | |
40 DCHECK(chunk_data_.get()); | |
41 } | |
42 | |
43 SBChunkData::~SBChunkData() { | |
44 } | |
45 | |
46 bool SBChunkData::ParseFrom(const unsigned char* data, size_t length) { | |
47 scoped_ptr<safe_browsing::ChunkData> chunk(new safe_browsing::ChunkData()); | |
48 if (!chunk->ParseFromArray(data, length)) | |
49 return false; | |
50 | |
51 if (chunk->chunk_type() != safe_browsing::ChunkData::ADD && | |
52 chunk->chunk_type() != safe_browsing::ChunkData::SUB) { | |
53 return false; | |
54 } | |
55 | |
56 size_t hash_size = 0; | |
57 if (chunk->prefix_type() == safe_browsing::ChunkData::PREFIX_4B) { | |
58 hash_size = sizeof(SBPrefix); | |
59 } else if (chunk->prefix_type() == safe_browsing::ChunkData::FULL_32B) { | |
60 hash_size = sizeof(SBFullHash); | |
61 } else { | |
62 return false; | |
63 } | |
64 | |
65 const size_t hash_count = chunk->hashes().size() / hash_size; | |
66 if (hash_count * hash_size != chunk->hashes().size()) | |
67 return false; | |
68 | |
69 if (chunk->chunk_type() == safe_browsing::ChunkData::SUB && | |
70 static_cast<size_t>(chunk->add_numbers_size()) != hash_count) { | |
71 return false; | |
72 } | |
73 | |
74 chunk_data_.swap(chunk); | |
75 return true; | |
76 } | |
77 | |
78 int SBChunkData::ChunkNumber() const { | |
79 return chunk_data_->chunk_number(); | |
80 } | |
81 | |
82 bool SBChunkData::IsAdd() const { | |
83 return chunk_data_->chunk_type() == safe_browsing::ChunkData::ADD; | |
84 } | |
85 | |
86 bool SBChunkData::IsSub() const { | |
87 return chunk_data_->chunk_type() == safe_browsing::ChunkData::SUB; | |
88 } | |
89 | |
90 int SBChunkData::AddChunkNumberAt(size_t i) const { | |
91 DCHECK(IsSub()); | |
92 DCHECK((IsPrefix() && i < PrefixCount()) || | |
93 (IsFullHash() && i < FullHashCount())); | |
94 return chunk_data_->add_numbers(i); | |
95 } | |
96 | |
97 bool SBChunkData::IsPrefix() const { | |
98 return chunk_data_->prefix_type() == safe_browsing::ChunkData::PREFIX_4B; | |
99 } | |
100 | |
101 size_t SBChunkData::PrefixCount() const { | |
102 DCHECK(IsPrefix()); | |
103 return chunk_data_->hashes().size() / sizeof(SBPrefix); | |
104 } | |
105 | |
106 SBPrefix SBChunkData::PrefixAt(size_t i) const { | |
107 DCHECK(IsPrefix()); | |
108 DCHECK_LT(i, PrefixCount()); | |
109 | |
110 SBPrefix prefix; | |
111 memcpy(&prefix, chunk_data_->hashes().data() + i * sizeof(SBPrefix), | |
112 sizeof(SBPrefix)); | |
113 return prefix; | |
114 } | |
115 | |
116 bool SBChunkData::IsFullHash() const { | |
117 return chunk_data_->prefix_type() == safe_browsing::ChunkData::FULL_32B; | |
118 } | |
119 | |
120 size_t SBChunkData::FullHashCount() const { | |
121 DCHECK(IsFullHash()); | |
122 return chunk_data_->hashes().size() / sizeof(SBFullHash); | |
123 } | |
124 | |
125 SBFullHash SBChunkData::FullHashAt(size_t i) const { | |
126 DCHECK(IsFullHash()); | |
127 DCHECK_LT(i, FullHashCount()); | |
128 | |
129 SBFullHash full_hash; | |
130 memcpy(&full_hash, chunk_data_->hashes().data() + i * sizeof(SBFullHash), | |
131 sizeof(SBFullHash)); | |
132 return full_hash; | |
133 } | |
134 | |
135 // SBListChunkRanges ----------------------------------------------------------- | |
136 | |
137 SBListChunkRanges::SBListChunkRanges(const std::string& n) | |
138 : name(n) { | |
139 } | |
140 | |
141 // SBChunkDelete --------------------------------------------------------------- | |
142 | |
143 SBChunkDelete::SBChunkDelete() : is_sub_del(false) {} | |
144 | |
145 SBChunkDelete::~SBChunkDelete() {} | |
146 | |
147 // Utility functions ----------------------------------------------------------- | 13 // Utility functions ----------------------------------------------------------- |
148 | 14 |
149 namespace { | 15 namespace { |
150 bool IsKnownList(const std::string& name) { | 16 bool IsKnownList(const std::string& name) { |
151 for (size_t i = 0; i < arraysize(safe_browsing_util::kAllLists); ++i) { | 17 for (size_t i = 0; i < arraysize(safe_browsing::kAllLists); ++i) { |
152 if (!strcmp(safe_browsing_util::kAllLists[i], name.c_str())) { | 18 if (!strcmp(safe_browsing::kAllLists[i], name.c_str())) { |
153 return true; | 19 return true; |
154 } | 20 } |
155 } | 21 } |
156 return false; | 22 return false; |
157 } | 23 } |
158 } // namespace | 24 } // namespace |
159 | 25 |
160 namespace safe_browsing_util { | 26 |
| 27 // SBCachedFullHashResult ------------------------------------------------------ |
| 28 |
| 29 SBCachedFullHashResult::SBCachedFullHashResult() {} |
| 30 |
| 31 SBCachedFullHashResult::SBCachedFullHashResult( |
| 32 const base::Time& in_expire_after) |
| 33 : expire_after(in_expire_after) {} |
| 34 |
| 35 SBCachedFullHashResult::~SBCachedFullHashResult() {} |
| 36 |
| 37 |
| 38 namespace safe_browsing { |
161 | 39 |
162 // Listnames that browser can process. | 40 // Listnames that browser can process. |
163 const char kMalwareList[] = "goog-malware-shavar"; | 41 const char kMalwareList[] = "goog-malware-shavar"; |
164 const char kPhishingList[] = "goog-phish-shavar"; | 42 const char kPhishingList[] = "goog-phish-shavar"; |
165 const char kBinUrlList[] = "goog-badbinurl-shavar"; | 43 const char kBinUrlList[] = "goog-badbinurl-shavar"; |
166 const char kCsdWhiteList[] = "goog-csdwhite-sha256"; | 44 const char kCsdWhiteList[] = "goog-csdwhite-sha256"; |
167 const char kDownloadWhiteList[] = "goog-downloadwhite-digest256"; | 45 const char kDownloadWhiteList[] = "goog-downloadwhite-digest256"; |
168 const char kExtensionBlacklist[] = "goog-badcrxids-digestvar"; | 46 const char kExtensionBlacklist[] = "goog-badcrxids-digestvar"; |
169 const char kIPBlacklist[] = "goog-badip-digest256"; | 47 const char kIPBlacklist[] = "goog-badip-digest256"; |
170 const char kUnwantedUrlList[] = "goog-unwanted-shavar"; | 48 const char kUnwantedUrlList[] = "goog-unwanted-shavar"; |
171 const char kInclusionWhitelist[] = "goog-csdinclusionwhite-sha256"; | 49 const char kInclusionWhitelist[] = "goog-csdinclusionwhite-sha256"; |
172 | 50 |
173 const char* kAllLists[9] = { | 51 const char* kAllLists[9] = { |
174 kMalwareList, | 52 kMalwareList, |
175 kPhishingList, | 53 kPhishingList, |
176 kBinUrlList, | 54 kBinUrlList, |
177 kCsdWhiteList, | 55 kCsdWhiteList, |
178 kDownloadWhiteList, | 56 kDownloadWhiteList, |
179 kExtensionBlacklist, | 57 kExtensionBlacklist, |
180 kIPBlacklist, | 58 kIPBlacklist, |
181 kUnwantedUrlList, | 59 kUnwantedUrlList, |
182 kInclusionWhitelist, | 60 kInclusionWhitelist, |
183 }; | 61 }; |
184 | 62 |
185 ListType GetListId(const base::StringPiece& name) { | 63 ListType GetListId(const base::StringPiece& name) { |
186 ListType id; | 64 ListType id; |
187 if (name == safe_browsing_util::kMalwareList) { | 65 if (name == kMalwareList) { |
188 id = MALWARE; | 66 id = MALWARE; |
189 } else if (name == safe_browsing_util::kPhishingList) { | 67 } else if (name == kPhishingList) { |
190 id = PHISH; | 68 id = PHISH; |
191 } else if (name == safe_browsing_util::kBinUrlList) { | 69 } else if (name == kBinUrlList) { |
192 id = BINURL; | 70 id = BINURL; |
193 } else if (name == safe_browsing_util::kCsdWhiteList) { | 71 } else if (name == kCsdWhiteList) { |
194 id = CSDWHITELIST; | 72 id = CSDWHITELIST; |
195 } else if (name == safe_browsing_util::kDownloadWhiteList) { | 73 } else if (name == kDownloadWhiteList) { |
196 id = DOWNLOADWHITELIST; | 74 id = DOWNLOADWHITELIST; |
197 } else if (name == safe_browsing_util::kExtensionBlacklist) { | 75 } else if (name == kExtensionBlacklist) { |
198 id = EXTENSIONBLACKLIST; | 76 id = EXTENSIONBLACKLIST; |
199 } else if (name == safe_browsing_util::kIPBlacklist) { | 77 } else if (name == kIPBlacklist) { |
200 id = IPBLACKLIST; | 78 id = IPBLACKLIST; |
201 } else if (name == safe_browsing_util::kUnwantedUrlList) { | 79 } else if (name == kUnwantedUrlList) { |
202 id = UNWANTEDURL; | 80 id = UNWANTEDURL; |
203 } else if (name == safe_browsing_util::kInclusionWhitelist) { | 81 } else if (name == kInclusionWhitelist) { |
204 id = INCLUSIONWHITELIST; | 82 id = INCLUSIONWHITELIST; |
205 } else { | 83 } else { |
206 id = INVALID; | 84 id = INVALID; |
207 } | 85 } |
208 return id; | 86 return id; |
209 } | 87 } |
210 | 88 |
211 bool GetListName(ListType list_id, std::string* list) { | 89 bool GetListName(ListType list_id, std::string* list) { |
212 switch (list_id) { | 90 switch (list_id) { |
213 case MALWARE: | 91 case MALWARE: |
214 *list = safe_browsing_util::kMalwareList; | 92 *list = kMalwareList; |
215 break; | 93 break; |
216 case PHISH: | 94 case PHISH: |
217 *list = safe_browsing_util::kPhishingList; | 95 *list = kPhishingList; |
218 break; | 96 break; |
219 case BINURL: | 97 case BINURL: |
220 *list = safe_browsing_util::kBinUrlList; | 98 *list = kBinUrlList; |
221 break; | 99 break; |
222 case CSDWHITELIST: | 100 case CSDWHITELIST: |
223 *list = safe_browsing_util::kCsdWhiteList; | 101 *list = kCsdWhiteList; |
224 break; | 102 break; |
225 case DOWNLOADWHITELIST: | 103 case DOWNLOADWHITELIST: |
226 *list = safe_browsing_util::kDownloadWhiteList; | 104 *list = kDownloadWhiteList; |
227 break; | 105 break; |
228 case EXTENSIONBLACKLIST: | 106 case EXTENSIONBLACKLIST: |
229 *list = safe_browsing_util::kExtensionBlacklist; | 107 *list = kExtensionBlacklist; |
230 break; | 108 break; |
231 case IPBLACKLIST: | 109 case IPBLACKLIST: |
232 *list = safe_browsing_util::kIPBlacklist; | 110 *list = kIPBlacklist; |
233 break; | 111 break; |
234 case UNWANTEDURL: | 112 case UNWANTEDURL: |
235 *list = safe_browsing_util::kUnwantedUrlList; | 113 *list = kUnwantedUrlList; |
236 break; | 114 break; |
237 case INCLUSIONWHITELIST: | 115 case INCLUSIONWHITELIST: |
238 *list = safe_browsing_util::kInclusionWhitelist; | 116 *list = kInclusionWhitelist; |
239 break; | 117 break; |
240 default: | 118 default: |
241 return false; | 119 return false; |
242 } | 120 } |
243 DCHECK(IsKnownList(*list)); | 121 DCHECK(IsKnownList(*list)); |
244 return true; | 122 return true; |
245 } | 123 } |
246 | 124 |
| 125 |
| 126 SBFullHash SBFullHashForString(const base::StringPiece& str) { |
| 127 SBFullHash h; |
| 128 crypto::SHA256HashString(str, &h.full_hash, sizeof(h.full_hash)); |
| 129 return h; |
| 130 } |
| 131 |
| 132 SBFullHash StringToSBFullHash(const std::string& hash_in) { |
| 133 DCHECK_EQ(crypto::kSHA256Length, hash_in.size()); |
| 134 SBFullHash hash_out; |
| 135 memcpy(hash_out.full_hash, hash_in.data(), crypto::kSHA256Length); |
| 136 return hash_out; |
| 137 } |
| 138 |
| 139 std::string SBFullHashToString(const SBFullHash& hash) { |
| 140 DCHECK_EQ(crypto::kSHA256Length, sizeof(hash.full_hash)); |
| 141 return std::string(hash.full_hash, sizeof(hash.full_hash)); |
| 142 } |
| 143 |
| 144 |
247 std::string Unescape(const std::string& url) { | 145 std::string Unescape(const std::string& url) { |
248 std::string unescaped_str(url); | 146 std::string unescaped_str(url); |
249 std::string old_unescaped_str; | 147 std::string old_unescaped_str; |
250 const int kMaxLoopIterations = 1024; | 148 const int kMaxLoopIterations = 1024; |
251 int loop_var = 0; | 149 int loop_var = 0; |
252 do { | 150 do { |
253 old_unescaped_str = unescaped_str; | 151 old_unescaped_str = unescaped_str; |
254 unescaped_str = net::UnescapeURLComponent( | 152 unescaped_str = net::UnescapeURLComponent( |
255 old_unescaped_str, net::UnescapeRule::SPOOFING_AND_CONTROL_CHARS | | 153 old_unescaped_str, net::UnescapeRule::SPOOFING_AND_CONTROL_CHARS | |
256 net::UnescapeRule::SPACES | | 154 net::UnescapeRule::SPACES | |
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
463 std::vector<std::string> hosts, paths; | 361 std::vector<std::string> hosts, paths; |
464 GenerateHostsToCheck(url, &hosts); | 362 GenerateHostsToCheck(url, &hosts); |
465 GeneratePathsToCheck(url, &paths); | 363 GeneratePathsToCheck(url, &paths); |
466 for (size_t h = 0; h < hosts.size(); ++h) { | 364 for (size_t h = 0; h < hosts.size(); ++h) { |
467 for (size_t p = 0; p < paths.size(); ++p) { | 365 for (size_t p = 0; p < paths.size(); ++p) { |
468 urls->push_back(hosts[h] + paths[p]); | 366 urls->push_back(hosts[h] + paths[p]); |
469 } | 367 } |
470 } | 368 } |
471 } | 369 } |
472 | 370 |
473 SBFullHash StringToSBFullHash(const std::string& hash_in) { | 371 } // namespace safe_browsing |
474 DCHECK_EQ(crypto::kSHA256Length, hash_in.size()); | |
475 SBFullHash hash_out; | |
476 memcpy(hash_out.full_hash, hash_in.data(), crypto::kSHA256Length); | |
477 return hash_out; | |
478 } | |
479 | |
480 std::string SBFullHashToString(const SBFullHash& hash) { | |
481 DCHECK_EQ(crypto::kSHA256Length, sizeof(hash.full_hash)); | |
482 return std::string(hash.full_hash, sizeof(hash.full_hash)); | |
483 } | |
484 | |
485 } // namespace safe_browsing_util | |
OLD | NEW |