| 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 |