Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "net/cert/crl_set_storage.h" | 5 #include "net/cert/crl_set_storage.h" |
| 6 | 6 |
| 7 #include "base/base64.h" | 7 #include "base/base64.h" |
| 8 #include "base/format_macros.h" | 8 #include "base/format_macros.h" |
| 9 #include "base/json/json_reader.h" | 9 #include "base/json/json_reader.h" |
| 10 #include "base/numerics/safe_conversions.h" | 10 #include "base/numerics/safe_conversions.h" |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 105 // in turn with a zlib compressed array of options: either the CRL is the same, | 105 // in turn with a zlib compressed array of options: either the CRL is the same, |
| 106 // a new CRL is inserted, the CRL is deleted or the CRL is updated. In the case | 106 // a new CRL is inserted, the CRL is deleted or the CRL is updated. In the case |
| 107 // of an update, the serials in the CRL are considered in the same fashion | 107 // of an update, the serials in the CRL are considered in the same fashion |
| 108 // except there is no delta update of a serial number: they are either | 108 // except there is no delta update of a serial number: they are either |
| 109 // inserted, deleted or left the same. | 109 // inserted, deleted or left the same. |
| 110 | 110 |
| 111 // ReadHeader reads the header (including length prefix) from |data| and | 111 // ReadHeader reads the header (including length prefix) from |data| and |
| 112 // updates |data| to remove the header on return. Caller takes ownership of the | 112 // updates |data| to remove the header on return. Caller takes ownership of the |
| 113 // returned pointer. | 113 // returned pointer. |
| 114 static base::DictionaryValue* ReadHeader(base::StringPiece* data) { | 114 static base::DictionaryValue* ReadHeader(base::StringPiece* data) { |
| 115 if (data->size() < 2) | 115 uint16_t header_len; |
| 116 if (data->size() < sizeof(header_len)) | |
| 116 return NULL; | 117 return NULL; |
| 117 uint16_t header_len; | 118 // Assumes little-endian. |
| 118 memcpy(&header_len, data->data(), 2); // Assumes little-endian. | 119 memcpy(&header_len, data->data(), sizeof(header_len)); |
| 119 data->remove_prefix(2); | 120 data->remove_prefix(sizeof(header_len)); |
| 120 | 121 |
| 121 if (data->size() < header_len) | 122 if (data->size() < header_len) |
| 122 return NULL; | 123 return NULL; |
| 123 | 124 |
| 124 const base::StringPiece header_bytes(data->data(), header_len); | 125 const base::StringPiece header_bytes(data->data(), header_len); |
| 125 data->remove_prefix(header_len); | 126 data->remove_prefix(header_len); |
| 126 | 127 |
| 127 scoped_ptr<base::Value> header(base::JSONReader::DeprecatedRead( | 128 scoped_ptr<base::Value> header(base::JSONReader::DeprecatedRead( |
| 128 header_bytes, base::JSON_ALLOW_TRAILING_COMMAS)); | 129 header_bytes, base::JSON_ALLOW_TRAILING_COMMAS)); |
| 129 if (header.get() == NULL) | 130 if (header.get() == NULL) |
| 130 return NULL; | 131 return NULL; |
| 131 | 132 |
| 132 if (!header->IsType(base::Value::TYPE_DICTIONARY)) | 133 if (!header->IsType(base::Value::TYPE_DICTIONARY)) |
| 133 return NULL; | 134 return NULL; |
| 134 return reinterpret_cast<base::DictionaryValue*>(header.release()); | 135 return reinterpret_cast<base::DictionaryValue*>(header.release()); |
| 135 } | 136 } |
| 136 | 137 |
| 137 // kCurrentFileVersion is the version of the CRLSet file format that we | 138 // kCurrentFileVersion is the version of the CRLSet file format that we |
| 138 // currently implement. | 139 // currently implement. |
| 139 static const int kCurrentFileVersion = 0; | 140 static const int kCurrentFileVersion = 0; |
| 140 | 141 |
| 141 static bool ReadCRL(base::StringPiece* data, std::string* out_parent_spki_hash, | 142 static bool ReadCRL(base::StringPiece* data, std::string* out_parent_spki_hash, |
| 142 std::vector<std::string>* out_serials) { | 143 std::vector<std::string>* out_serials) { |
| 143 if (data->size() < crypto::kSHA256Length) | 144 if (data->size() < crypto::kSHA256Length) |
| 144 return false; | 145 return false; |
| 145 out_parent_spki_hash->assign(data->data(), crypto::kSHA256Length); | 146 out_parent_spki_hash->assign(data->data(), crypto::kSHA256Length); |
| 146 data->remove_prefix(crypto::kSHA256Length); | 147 data->remove_prefix(crypto::kSHA256Length); |
| 147 | 148 |
| 148 if (data->size() < sizeof(uint32_t)) | 149 uint32_t num_serials; |
| 150 if (data->size() < sizeof(num_serials)) | |
| 149 return false; | 151 return false; |
| 150 uint32_t num_serials; | |
| 151 // Assumes little endian. | 152 // Assumes little endian. |
| 152 memcpy(&num_serials, data->data(), sizeof(uint32_t)); | 153 memcpy(&num_serials, data->data(), sizeof(num_serials)); |
| 154 data->remove_prefix(sizeof(num_serials)); | |
|
eroman
2015/06/04 22:25:31
this is a behavioral change from before.
that said
wtc
2015/06/05 17:39:33
Confirmed. I think the new code is better (it imme
| |
| 155 | |
| 153 if (num_serials > 32 * 1024 * 1024) // Sanity check. | 156 if (num_serials > 32 * 1024 * 1024) // Sanity check. |
|
eroman
2015/06/04 22:25:31
I am curious if you know where this number comes f
wtc
2015/06/05 17:39:33
I don't know where this number comes from. It is a
| |
| 154 return false; | 157 return false; |
| 155 | 158 |
| 156 out_serials->reserve(num_serials); | 159 out_serials->reserve(num_serials); |
| 157 data->remove_prefix(sizeof(uint32_t)); | |
| 158 | 160 |
| 159 for (uint32_t i = 0; i < num_serials; ++i) { | 161 for (uint32_t i = 0; i < num_serials; ++i) { |
| 160 if (data->size() < sizeof(uint8_t)) | 162 if (data->size() < sizeof(uint8_t)) |
| 161 return false; | 163 return false; |
| 162 | 164 |
| 163 uint8_t serial_length = data->data()[0]; | 165 uint8_t serial_length = data->data()[0]; |
| 164 data->remove_prefix(sizeof(uint8_t)); | 166 data->remove_prefix(sizeof(uint8_t)); |
| 165 | 167 |
| 166 if (data->size() < serial_length) | 168 if (data->size() < serial_length) |
| 167 return false; | 169 return false; |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 207 } | 209 } |
| 208 | 210 |
| 209 // kMaxUncompressedChangesLength is the largest changes array that we'll | 211 // kMaxUncompressedChangesLength is the largest changes array that we'll |
| 210 // accept. This bounds the number of CRLs in the CRLSet as well as the number | 212 // accept. This bounds the number of CRLs in the CRLSet as well as the number |
| 211 // of serial numbers in a given CRL. | 213 // of serial numbers in a given CRL. |
| 212 static const unsigned kMaxUncompressedChangesLength = 1024 * 1024; | 214 static const unsigned kMaxUncompressedChangesLength = 1024 * 1024; |
| 213 | 215 |
| 214 static bool ReadChanges(base::StringPiece* data, | 216 static bool ReadChanges(base::StringPiece* data, |
| 215 std::vector<uint8_t>* out_changes) { | 217 std::vector<uint8_t>* out_changes) { |
| 216 uint32_t uncompressed_size, compressed_size; | 218 uint32_t uncompressed_size, compressed_size; |
| 217 if (data->size() < 2 * sizeof(uint32_t)) | 219 if (data->size() < sizeof(uncompressed_size) + sizeof(compressed_size)) |
| 218 return false; | 220 return false; |
| 219 // Assumes little endian. | 221 // Assumes little endian. |
| 220 memcpy(&uncompressed_size, data->data(), sizeof(uint32_t)); | 222 memcpy(&uncompressed_size, data->data(), sizeof(uncompressed_size)); |
| 221 data->remove_prefix(4); | 223 data->remove_prefix(sizeof(uncompressed_size)); |
| 222 memcpy(&compressed_size, data->data(), sizeof(uint32_t)); | 224 memcpy(&compressed_size, data->data(), sizeof(compressed_size)); |
| 223 data->remove_prefix(4); | 225 data->remove_prefix(sizeof(compressed_size)); |
| 224 | 226 |
| 225 if (uncompressed_size > kMaxUncompressedChangesLength) | 227 if (uncompressed_size > kMaxUncompressedChangesLength) |
| 226 return false; | 228 return false; |
| 227 if (data->size() < compressed_size) | 229 if (data->size() < compressed_size) |
| 228 return false; | 230 return false; |
| 229 | 231 |
| 230 out_changes->clear(); | 232 out_changes->clear(); |
| 231 if (uncompressed_size == 0) | 233 if (uncompressed_size == 0) |
| 232 return true; | 234 return true; |
| 233 | 235 |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 254 | 256 |
| 255 size_t i = 0; | 257 size_t i = 0; |
| 256 for (std::vector<uint8_t>::const_iterator k = changes.begin(); | 258 for (std::vector<uint8_t>::const_iterator k = changes.begin(); |
| 257 k != changes.end(); ++k) { | 259 k != changes.end(); ++k) { |
| 258 if (*k == SYMBOL_SAME) { | 260 if (*k == SYMBOL_SAME) { |
| 259 if (i >= old_serials.size()) | 261 if (i >= old_serials.size()) |
| 260 return false; | 262 return false; |
| 261 out_serials->push_back(old_serials[i]); | 263 out_serials->push_back(old_serials[i]); |
| 262 i++; | 264 i++; |
| 263 } else if (*k == SYMBOL_INSERT) { | 265 } else if (*k == SYMBOL_INSERT) { |
| 264 uint8_t serial_length; | |
| 265 if (data->size() < sizeof(uint8_t)) | 266 if (data->size() < sizeof(uint8_t)) |
|
eroman
2015/06/04 22:25:31
Consider changing this line too.
wtc
2015/06/05 17:39:33
When reading just one byte, I would just use 1. Th
| |
| 266 return false; | 267 return false; |
| 267 memcpy(&serial_length, data->data(), sizeof(uint8_t)); | 268 uint8_t serial_length = data->data()[0]; |
| 268 data->remove_prefix(sizeof(uint8_t)); | 269 data->remove_prefix(sizeof(uint8_t)); |
|
wtc
2015/06/04 00:57:29
See similar code on lines 162-166.
| |
| 269 | 270 |
| 270 if (data->size() < serial_length) | 271 if (data->size() < serial_length) |
| 271 return false; | 272 return false; |
| 272 const std::string serial(data->data(), serial_length); | 273 const std::string serial(data->data(), serial_length); |
| 273 data->remove_prefix(serial_length); | 274 data->remove_prefix(serial_length); |
| 274 | 275 |
| 275 out_serials->push_back(serial); | 276 out_serials->push_back(serial); |
| 276 } else if (*k == SYMBOL_DELETE) { | 277 } else if (*k == SYMBOL_DELETE) { |
| 277 if (i >= old_serials.size()) | 278 if (i >= old_serials.size()) |
| 278 return false; | 279 return false; |
| (...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 542 memcpy(out + off, j->data(), j->size()); | 543 memcpy(out + off, j->data(), j->size()); |
| 543 off += j->size(); | 544 off += j->size(); |
| 544 } | 545 } |
| 545 } | 546 } |
| 546 | 547 |
| 547 CHECK_EQ(off, len); | 548 CHECK_EQ(off, len); |
| 548 return ret; | 549 return ret; |
| 549 } | 550 } |
| 550 | 551 |
| 551 } // namespace net | 552 } // namespace net |
| OLD | NEW |