Chromium Code Reviews| 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 out_serials->reserve(num_serials); | |
| 161 data->remove_prefix(sizeof(uint32)); | 163 data->remove_prefix(sizeof(uint32)); |
| 162 | 164 |
| 163 for (uint32 i = 0; i < num_serials; ++i) { | 165 for (uint32 i = 0; i < num_serials; ++i) { |
| 164 uint8 serial_length; | 166 uint8 serial_length; |
| 165 if (data->size() < sizeof(uint8)) | 167 if (data->size() < sizeof(uint8)) |
| 166 return false; | 168 return false; |
| 167 memcpy(&serial_length, data->data(), sizeof(uint8)); | 169 memcpy(&serial_length, data->data(), sizeof(uint8)); |
|
pasko
2014/05/26 18:41:11
maybe:
serial_length = ((uint8*)data->data())[0]
Philippe
2014/05/26 18:53:39
Done.
| |
| 168 data->remove_prefix(sizeof(uint8)); | 170 data->remove_prefix(sizeof(uint8)); |
| 169 | 171 |
| 170 if (data->size() < serial_length) | 172 if (data->size() < serial_length) |
| 171 return false; | 173 return false; |
| 172 std::string serial(data->data(), serial_length); | 174 |
| 173 data->remove_prefix(serial_length); | 175 data->remove_prefix(serial_length); |
| 174 out_serials->push_back(serial); | 176 out_serials->push_back(std::string()); |
| 177 out_serials->back().assign(data->data(), serial_length); | |
| 175 } | 178 } |
| 176 | 179 |
| 177 return true; | 180 return true; |
| 178 } | 181 } |
| 179 | 182 |
| 180 bool CRLSet::CopyBlockedSPKIsFromHeader(base::DictionaryValue* header_dict) { | 183 bool CRLSet::CopyBlockedSPKIsFromHeader(base::DictionaryValue* header_dict) { |
| 181 base::ListValue* blocked_spkis_list = NULL; | 184 base::ListValue* blocked_spkis_list = NULL; |
| 182 if (!header_dict->GetList("BlockedSPKIs", &blocked_spkis_list)) { | 185 if (!header_dict->GetList("BlockedSPKIs", &blocked_spkis_list)) { |
| 183 // BlockedSPKIs is optional, so it's fine if we don't find it. | 186 // BlockedSPKIs is optional, so it's fine if we don't find it. |
| 184 return true; | 187 return true; |
| 185 } | 188 } |
| 186 | 189 |
| 187 blocked_spkis_.clear(); | 190 blocked_spkis_.clear(); |
| 191 blocked_spkis_.reserve(blocked_spkis_list->GetSize()); | |
| 192 | |
| 193 std::string spki_sha256_base64; | |
| 188 | 194 |
| 189 for (size_t i = 0; i < blocked_spkis_list->GetSize(); ++i) { | 195 for (size_t i = 0; i < blocked_spkis_list->GetSize(); ++i) { |
| 190 std::string spki_sha256_base64, spki_sha256; | 196 spki_sha256_base64.clear(); |
| 197 | |
| 191 if (!blocked_spkis_list->GetString(i, &spki_sha256_base64)) | 198 if (!blocked_spkis_list->GetString(i, &spki_sha256_base64)) |
| 192 return false; | 199 return false; |
| 193 if (!base::Base64Decode(spki_sha256_base64, &spki_sha256)) | 200 |
| 201 blocked_spkis_.push_back(std::string()); | |
| 202 if (!base::Base64Decode(spki_sha256_base64, &blocked_spkis_.back())) { | |
| 203 blocked_spkis_.pop_back(); | |
| 194 return false; | 204 return false; |
| 195 blocked_spkis_.push_back(spki_sha256); | 205 } |
| 196 } | 206 } |
| 197 | 207 |
| 198 return true; | 208 return true; |
| 199 } | 209 } |
| 200 | 210 |
| 201 // static | 211 // static |
| 202 bool CRLSet::Parse(base::StringPiece data, scoped_refptr<CRLSet>* out_crl_set) { | 212 bool CRLSet::Parse(base::StringPiece data, scoped_refptr<CRLSet>* out_crl_set) { |
| 213 TRACE_EVENT0("CRLSet", "Parse"); | |
| 203 // Other parts of Chrome assume that we're little endian, so we don't lose | 214 // Other parts of Chrome assume that we're little endian, so we don't lose |
| 204 // anything by doing this. | 215 // anything by doing this. |
| 205 #if defined(__BYTE_ORDER) | 216 #if defined(__BYTE_ORDER) |
| 206 // Linux check | 217 // Linux check |
| 207 COMPILE_ASSERT(__BYTE_ORDER == __LITTLE_ENDIAN, assumes_little_endian); | 218 COMPILE_ASSERT(__BYTE_ORDER == __LITTLE_ENDIAN, assumes_little_endian); |
| 208 #elif defined(__BIG_ENDIAN__) | 219 #elif defined(__BIG_ENDIAN__) |
| 209 // Mac check | 220 // Mac check |
| 210 #error assumes little endian | 221 #error assumes little endian |
| 211 #endif | 222 #endif |
| 212 | 223 |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 231 return false; | 242 return false; |
| 232 | 243 |
| 233 double not_after; | 244 double not_after; |
| 234 if (!header_dict->GetDouble("NotAfter", ¬_after)) { | 245 if (!header_dict->GetDouble("NotAfter", ¬_after)) { |
| 235 // NotAfter is optional for now. | 246 // NotAfter is optional for now. |
| 236 not_after = 0; | 247 not_after = 0; |
| 237 } | 248 } |
| 238 if (not_after < 0) | 249 if (not_after < 0) |
| 239 return false; | 250 return false; |
| 240 | 251 |
| 241 scoped_refptr<CRLSet> crl_set(new CRLSet); | 252 scoped_refptr<CRLSet> crl_set(new CRLSet()); |
| 242 crl_set->sequence_ = static_cast<uint32>(sequence); | 253 crl_set->sequence_ = static_cast<uint32>(sequence); |
| 243 crl_set->not_after_ = static_cast<uint64>(not_after); | 254 crl_set->not_after_ = static_cast<uint64>(not_after); |
| 255 crl_set->crls_.reserve(50); // Value observed on google.com. | |
| 244 | 256 |
| 245 for (size_t crl_index = 0; !data.empty(); crl_index++) { | 257 for (size_t crl_index = 0; !data.empty(); crl_index++) { |
| 246 std::string parent_spki_sha256; | 258 // Speculatively push back a pair and pass it to ReadCRL() to avoid |
| 247 std::vector<std::string> serials; | 259 // unnecessary copies. |
| 248 if (!ReadCRL(&data, &parent_spki_sha256, &serials)) | 260 crl_set->crls_.push_back( |
| 261 std::make_pair(std::string(), std::vector<std::string>())); | |
| 262 std::pair<std::string, std::vector<std::string> >* const back_pair = | |
| 263 &crl_set->crls_.back(); | |
| 264 | |
| 265 if (!ReadCRL(&data, &back_pair->first, &back_pair->second)) { | |
| 266 // Undo the speculative push_back() performed above. | |
| 267 crl_set->crls_.pop_back(); | |
| 249 return false; | 268 return false; |
| 269 } | |
| 250 | 270 |
| 251 crl_set->crls_.push_back(std::make_pair(parent_spki_sha256, serials)); | 271 crl_set->crls_index_by_issuer_[back_pair->first] = crl_index; |
| 252 crl_set->crls_index_by_issuer_[parent_spki_sha256] = crl_index; | |
| 253 } | 272 } |
| 254 | 273 |
| 255 if (!crl_set->CopyBlockedSPKIsFromHeader(header_dict.get())) | 274 if (!crl_set->CopyBlockedSPKIsFromHeader(header_dict.get())) |
| 256 return false; | 275 return false; |
| 257 | 276 |
| 258 *out_crl_set = crl_set; | 277 *out_crl_set = crl_set; |
| 259 return true; | 278 return true; |
| 260 } | 279 } |
| 261 | 280 |
| 262 // kMaxUncompressedChangesLength is the largest changes array that we'll | 281 // 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) { | 560 if (!serial.empty() && (serial[0] & 0x80) != 0) { |
| 542 // This serial number is negative but the process which generates CRL sets | 561 // This serial number is negative but the process which generates CRL sets |
| 543 // will reject any certificates with negative serial numbers as invalid. | 562 // will reject any certificates with negative serial numbers as invalid. |
| 544 return UNKNOWN; | 563 return UNKNOWN; |
| 545 } | 564 } |
| 546 | 565 |
| 547 // Remove any leading zero bytes. | 566 // Remove any leading zero bytes. |
| 548 while (serial.size() > 1 && serial[0] == 0x00) | 567 while (serial.size() > 1 && serial[0] == 0x00) |
| 549 serial.remove_prefix(1); | 568 serial.remove_prefix(1); |
| 550 | 569 |
| 551 std::map<std::string, size_t>::const_iterator i = | 570 base::hash_map<std::string, size_t>::const_iterator i = |
| 552 crls_index_by_issuer_.find(issuer_spki_hash.as_string()); | 571 crls_index_by_issuer_.find(issuer_spki_hash.as_string()); |
| 553 if (i == crls_index_by_issuer_.end()) | 572 if (i == crls_index_by_issuer_.end()) |
| 554 return UNKNOWN; | 573 return UNKNOWN; |
| 555 const std::vector<std::string>& serials = crls_[i->second].second; | 574 const std::vector<std::string>& serials = crls_[i->second].second; |
| 556 | 575 |
| 557 for (std::vector<std::string>::const_iterator i = serials.begin(); | 576 for (std::vector<std::string>::const_iterator i = serials.begin(); |
| 558 i != serials.end(); ++i) { | 577 i != serials.end(); ++i) { |
| 559 if (base::StringPiece(*i) == serial) | 578 if (base::StringPiece(*i) == serial) |
| 560 return REVOKED; | 579 return REVOKED; |
| 561 } | 580 } |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 602 crl_set->crls_index_by_issuer_[spki] = 0; | 621 crl_set->crls_index_by_issuer_[spki] = 0; |
| 603 } | 622 } |
| 604 | 623 |
| 605 if (!serial_number.empty()) | 624 if (!serial_number.empty()) |
| 606 crl_set->crls_[0].second.push_back(serial_number); | 625 crl_set->crls_[0].second.push_back(serial_number); |
| 607 | 626 |
| 608 return crl_set; | 627 return crl_set; |
| 609 } | 628 } |
| 610 | 629 |
| 611 } // namespace net | 630 } // namespace net |
| OLD | NEW |