Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(123)

Side by Side Diff: net/cert/crl_set.cc

Issue 302643003: Remove unnecessary copies in CRLSet parsing. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix unit test Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « net/cert/crl_set.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
231 return false; 245 return false;
232 246
233 double not_after; 247 double not_after;
234 if (!header_dict->GetDouble("NotAfter", &not_after)) { 248 if (!header_dict->GetDouble("NotAfter", &not_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
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
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
OLDNEW
« no previous file with comments | « net/cert/crl_set.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698