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 |