OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "base/base64.h" | 5 #include "base/base64.h" |
| 6 #include "base/debug/trace_event.h" |
6 #include "base/format_macros.h" | 7 #include "base/format_macros.h" |
7 #include "base/json/json_reader.h" | 8 #include "base/json/json_reader.h" |
8 #include "base/logging.h" | 9 #include "base/logging.h" |
9 #include "base/stl_util.h" | 10 #include "base/stl_util.h" |
10 #include "base/strings/string_util.h" | 11 #include "base/strings/string_util.h" |
11 #include "base/strings/stringprintf.h" | 12 #include "base/strings/stringprintf.h" |
12 #include "base/time/time.h" | 13 #include "base/time/time.h" |
13 #include "base/values.h" | 14 #include "base/values.h" |
14 #include "crypto/sha2.h" | 15 #include "crypto/sha2.h" |
15 #include "net/cert/crl_set.h" | 16 #include "net/cert/crl_set.h" |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
144 } | 145 } |
145 | 146 |
146 // kCurrentFileVersion is the version of the CRLSet file format that we | 147 // kCurrentFileVersion is the version of the CRLSet file format that we |
147 // currently implement. | 148 // currently implement. |
148 static const int kCurrentFileVersion = 0; | 149 static const int kCurrentFileVersion = 0; |
149 | 150 |
150 static bool ReadCRL(base::StringPiece* data, std::string* out_parent_spki_hash, | 151 static bool ReadCRL(base::StringPiece* data, std::string* out_parent_spki_hash, |
151 std::vector<std::string>* out_serials) { | 152 std::vector<std::string>* out_serials) { |
152 if (data->size() < crypto::kSHA256Length) | 153 if (data->size() < crypto::kSHA256Length) |
153 return false; | 154 return false; |
154 *out_parent_spki_hash = std::string(data->data(), crypto::kSHA256Length); | 155 out_parent_spki_hash->assign(data->data(), crypto::kSHA256Length); |
155 data->remove_prefix(crypto::kSHA256Length); | 156 data->remove_prefix(crypto::kSHA256Length); |
156 | 157 |
157 if (data->size() < sizeof(uint32)) | 158 if (data->size() < sizeof(uint32)) |
158 return false; | 159 return false; |
159 uint32 num_serials; | 160 uint32 num_serials; |
160 memcpy(&num_serials, data->data(), sizeof(uint32)); // assumes little endian | 161 memcpy(&num_serials, data->data(), sizeof(uint32)); // assumes little endian |
| 162 if (num_serials > 32 * 1024 * 1024) // Sanity check. |
| 163 return false; |
| 164 |
| 165 out_serials->reserve(num_serials); |
161 data->remove_prefix(sizeof(uint32)); | 166 data->remove_prefix(sizeof(uint32)); |
162 | 167 |
163 for (uint32 i = 0; i < num_serials; ++i) { | 168 for (uint32 i = 0; i < num_serials; ++i) { |
164 uint8 serial_length; | |
165 if (data->size() < sizeof(uint8)) | 169 if (data->size() < sizeof(uint8)) |
166 return false; | 170 return false; |
167 memcpy(&serial_length, data->data(), sizeof(uint8)); | 171 |
| 172 uint8 serial_length = data->data()[0]; |
168 data->remove_prefix(sizeof(uint8)); | 173 data->remove_prefix(sizeof(uint8)); |
169 | 174 |
170 if (data->size() < serial_length) | 175 if (data->size() < serial_length) |
171 return false; | 176 return false; |
172 std::string serial(data->data(), serial_length); | 177 |
| 178 out_serials->push_back(std::string()); |
| 179 out_serials->back().assign(data->data(), serial_length); |
173 data->remove_prefix(serial_length); | 180 data->remove_prefix(serial_length); |
174 out_serials->push_back(serial); | |
175 } | 181 } |
176 | 182 |
177 return true; | 183 return true; |
178 } | 184 } |
179 | 185 |
180 bool CRLSet::CopyBlockedSPKIsFromHeader(base::DictionaryValue* header_dict) { | 186 bool CRLSet::CopyBlockedSPKIsFromHeader(base::DictionaryValue* header_dict) { |
181 base::ListValue* blocked_spkis_list = NULL; | 187 base::ListValue* blocked_spkis_list = NULL; |
182 if (!header_dict->GetList("BlockedSPKIs", &blocked_spkis_list)) { | 188 if (!header_dict->GetList("BlockedSPKIs", &blocked_spkis_list)) { |
183 // BlockedSPKIs is optional, so it's fine if we don't find it. | 189 // BlockedSPKIs is optional, so it's fine if we don't find it. |
184 return true; | 190 return true; |
185 } | 191 } |
186 | 192 |
187 blocked_spkis_.clear(); | 193 blocked_spkis_.clear(); |
| 194 blocked_spkis_.reserve(blocked_spkis_list->GetSize()); |
| 195 |
| 196 std::string spki_sha256_base64; |
188 | 197 |
189 for (size_t i = 0; i < blocked_spkis_list->GetSize(); ++i) { | 198 for (size_t i = 0; i < blocked_spkis_list->GetSize(); ++i) { |
190 std::string spki_sha256_base64, spki_sha256; | 199 spki_sha256_base64.clear(); |
| 200 |
191 if (!blocked_spkis_list->GetString(i, &spki_sha256_base64)) | 201 if (!blocked_spkis_list->GetString(i, &spki_sha256_base64)) |
192 return false; | 202 return false; |
193 if (!base::Base64Decode(spki_sha256_base64, &spki_sha256)) | 203 |
| 204 blocked_spkis_.push_back(std::string()); |
| 205 if (!base::Base64Decode(spki_sha256_base64, &blocked_spkis_.back())) { |
| 206 blocked_spkis_.pop_back(); |
194 return false; | 207 return false; |
195 blocked_spkis_.push_back(spki_sha256); | 208 } |
196 } | 209 } |
197 | 210 |
198 return true; | 211 return true; |
199 } | 212 } |
200 | 213 |
201 // static | 214 // static |
202 bool CRLSet::Parse(base::StringPiece data, scoped_refptr<CRLSet>* out_crl_set) { | 215 bool CRLSet::Parse(base::StringPiece data, scoped_refptr<CRLSet>* out_crl_set) { |
| 216 TRACE_EVENT0("CRLSet", "Parse"); |
203 // Other parts of Chrome assume that we're little endian, so we don't lose | 217 // Other parts of Chrome assume that we're little endian, so we don't lose |
204 // anything by doing this. | 218 // anything by doing this. |
205 #if defined(__BYTE_ORDER) | 219 #if defined(__BYTE_ORDER) |
206 // Linux check | 220 // Linux check |
207 COMPILE_ASSERT(__BYTE_ORDER == __LITTLE_ENDIAN, assumes_little_endian); | 221 COMPILE_ASSERT(__BYTE_ORDER == __LITTLE_ENDIAN, assumes_little_endian); |
208 #elif defined(__BIG_ENDIAN__) | 222 #elif defined(__BIG_ENDIAN__) |
209 // Mac check | 223 // Mac check |
210 #error assumes little endian | 224 #error assumes little endian |
211 #endif | 225 #endif |
212 | 226 |
(...skipping 18 matching lines...) Expand all Loading... |
231 return false; | 245 return false; |
232 | 246 |
233 double not_after; | 247 double not_after; |
234 if (!header_dict->GetDouble("NotAfter", ¬_after)) { | 248 if (!header_dict->GetDouble("NotAfter", ¬_after)) { |
235 // NotAfter is optional for now. | 249 // NotAfter is optional for now. |
236 not_after = 0; | 250 not_after = 0; |
237 } | 251 } |
238 if (not_after < 0) | 252 if (not_after < 0) |
239 return false; | 253 return false; |
240 | 254 |
241 scoped_refptr<CRLSet> crl_set(new CRLSet); | 255 scoped_refptr<CRLSet> crl_set(new CRLSet()); |
242 crl_set->sequence_ = static_cast<uint32>(sequence); | 256 crl_set->sequence_ = static_cast<uint32>(sequence); |
243 crl_set->not_after_ = static_cast<uint64>(not_after); | 257 crl_set->not_after_ = static_cast<uint64>(not_after); |
| 258 crl_set->crls_.reserve(64); // Value observed experimentally. |
244 | 259 |
245 for (size_t crl_index = 0; !data.empty(); crl_index++) { | 260 for (size_t crl_index = 0; !data.empty(); crl_index++) { |
246 std::string parent_spki_sha256; | 261 // Speculatively push back a pair and pass it to ReadCRL() to avoid |
247 std::vector<std::string> serials; | 262 // unnecessary copies. |
248 if (!ReadCRL(&data, &parent_spki_sha256, &serials)) | 263 crl_set->crls_.push_back( |
| 264 std::make_pair(std::string(), std::vector<std::string>())); |
| 265 std::pair<std::string, std::vector<std::string> >* const back_pair = |
| 266 &crl_set->crls_.back(); |
| 267 |
| 268 if (!ReadCRL(&data, &back_pair->first, &back_pair->second)) { |
| 269 // Undo the speculative push_back() performed above. |
| 270 crl_set->crls_.pop_back(); |
249 return false; | 271 return false; |
| 272 } |
250 | 273 |
251 crl_set->crls_.push_back(std::make_pair(parent_spki_sha256, serials)); | 274 crl_set->crls_index_by_issuer_[back_pair->first] = crl_index; |
252 crl_set->crls_index_by_issuer_[parent_spki_sha256] = crl_index; | |
253 } | 275 } |
254 | 276 |
255 if (!crl_set->CopyBlockedSPKIsFromHeader(header_dict.get())) | 277 if (!crl_set->CopyBlockedSPKIsFromHeader(header_dict.get())) |
256 return false; | 278 return false; |
257 | 279 |
258 *out_crl_set = crl_set; | 280 *out_crl_set = crl_set; |
259 return true; | 281 return true; |
260 } | 282 } |
261 | 283 |
262 // kMaxUncompressedChangesLength is the largest changes array that we'll | 284 // kMaxUncompressedChangesLength is the largest changes array that we'll |
(...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
541 if (!serial.empty() && (serial[0] & 0x80) != 0) { | 563 if (!serial.empty() && (serial[0] & 0x80) != 0) { |
542 // This serial number is negative but the process which generates CRL sets | 564 // This serial number is negative but the process which generates CRL sets |
543 // will reject any certificates with negative serial numbers as invalid. | 565 // will reject any certificates with negative serial numbers as invalid. |
544 return UNKNOWN; | 566 return UNKNOWN; |
545 } | 567 } |
546 | 568 |
547 // Remove any leading zero bytes. | 569 // Remove any leading zero bytes. |
548 while (serial.size() > 1 && serial[0] == 0x00) | 570 while (serial.size() > 1 && serial[0] == 0x00) |
549 serial.remove_prefix(1); | 571 serial.remove_prefix(1); |
550 | 572 |
551 std::map<std::string, size_t>::const_iterator i = | 573 base::hash_map<std::string, size_t>::const_iterator i = |
552 crls_index_by_issuer_.find(issuer_spki_hash.as_string()); | 574 crls_index_by_issuer_.find(issuer_spki_hash.as_string()); |
553 if (i == crls_index_by_issuer_.end()) | 575 if (i == crls_index_by_issuer_.end()) |
554 return UNKNOWN; | 576 return UNKNOWN; |
555 const std::vector<std::string>& serials = crls_[i->second].second; | 577 const std::vector<std::string>& serials = crls_[i->second].second; |
556 | 578 |
557 for (std::vector<std::string>::const_iterator i = serials.begin(); | 579 for (std::vector<std::string>::const_iterator i = serials.begin(); |
558 i != serials.end(); ++i) { | 580 i != serials.end(); ++i) { |
559 if (base::StringPiece(*i) == serial) | 581 if (base::StringPiece(*i) == serial) |
560 return REVOKED; | 582 return REVOKED; |
561 } | 583 } |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
602 crl_set->crls_index_by_issuer_[spki] = 0; | 624 crl_set->crls_index_by_issuer_[spki] = 0; |
603 } | 625 } |
604 | 626 |
605 if (!serial_number.empty()) | 627 if (!serial_number.empty()) |
606 crl_set->crls_[0].second.push_back(serial_number); | 628 crl_set->crls_[0].second.push_back(serial_number); |
607 | 629 |
608 return crl_set; | 630 return crl_set; |
609 } | 631 } |
610 | 632 |
611 } // namespace net | 633 } // namespace net |
OLD | NEW |