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

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: 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
« net/cert/crl_set.h ('K') | « 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 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
231 return false; 242 return false;
232 243
233 double not_after; 244 double not_after;
234 if (!header_dict->GetDouble("NotAfter", &not_after)) { 245 if (!header_dict->GetDouble("NotAfter", &not_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
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
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
OLDNEW
« net/cert/crl_set.h ('K') | « net/cert/crl_set.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698