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

Side by Side Diff: net/base/x509_certificate.cc

Issue 4645001: Change the HTTP cache to cache the entire certificate chain for SSL sites (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/net/base
Patch Set: Rebase before commit Created 9 years, 8 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
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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/base/x509_certificate.h" 5 #include "net/base/x509_certificate.h"
6 6
7 #include <stdlib.h> 7 #include <stdlib.h>
8 8
9 #include <map> 9 #include <map>
10 #include <string> 10 #include <string>
11 #include <vector> 11 #include <vector>
12 12
13 #include "base/lazy_instance.h" 13 #include "base/lazy_instance.h"
14 #include "base/logging.h" 14 #include "base/logging.h"
15 #include "base/memory/singleton.h" 15 #include "base/memory/singleton.h"
16 #include "base/metrics/histogram.h" 16 #include "base/metrics/histogram.h"
17 #include "base/pickle.h"
17 #include "base/sha1.h" 18 #include "base/sha1.h"
18 #include "base/string_piece.h" 19 #include "base/string_piece.h"
19 #include "base/string_util.h" 20 #include "base/string_util.h"
20 #include "base/time.h" 21 #include "base/time.h"
21 #include "net/base/pem_tokenizer.h" 22 #include "net/base/pem_tokenizer.h"
22 23
23 namespace net { 24 namespace net {
24 25
25 namespace { 26 namespace {
26 27
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after
224 if (!cert_handle) 225 if (!cert_handle)
225 return NULL; 226 return NULL;
226 227
227 X509Certificate* cert = CreateFromHandle(cert_handle, 228 X509Certificate* cert = CreateFromHandle(cert_handle,
228 SOURCE_LONE_CERT_IMPORT, 229 SOURCE_LONE_CERT_IMPORT,
229 OSCertHandles()); 230 OSCertHandles());
230 FreeOSCertHandle(cert_handle); 231 FreeOSCertHandle(cert_handle);
231 return cert; 232 return cert;
232 } 233 }
233 234
235 // static
236 X509Certificate* X509Certificate::CreateFromPickle(const Pickle& pickle,
237 void** pickle_iter,
238 PickleType type) {
239 OSCertHandle cert_handle = ReadCertHandleFromPickle(pickle, pickle_iter);
240 OSCertHandles intermediates;
241
242 // Even if a certificate fails to parse, whether the server certificate in
243 // |cert_handle| or one of the optional intermediates, continue reading
244 // the data from |pickle| so that |pickle_iter| is kept in sync for any
245 // other reads the caller may perform after this method returns.
wtc 2011/04/20 23:07:58 If a certificate fails to parse, the subsequent da
Ryan Sleevi 2011/04/20 23:59:10 There are two reasons for why parsing may fail, an
246 if (type == PICKLETYPE_CERTIFICATE_CHAIN) {
247 size_t num_intermediates;
248 if (!pickle.ReadSize(pickle_iter, &num_intermediates)) {
249 FreeOSCertHandle(cert_handle);
250 return NULL;
251 }
252
253 bool ok = !!cert_handle;
wtc 2011/04/20 23:07:58 Nit: say bool ok = (cert_handle != NULL);
254 for (size_t i = 0; i < num_intermediates; ++i) {
255 OSCertHandle intermediate = ReadCertHandleFromPickle(pickle,
256 pickle_iter);
257 // If an intermediate fails to load, it and any certificates after it
258 // will not be added. However, any intermediates that were successfully
259 // parsed before the failure can be safely returned.
260 ok &= !!intermediate;
261 if (ok) {
262 intermediates.push_back(intermediate);
263 } else if (intermediate) {
264 FreeOSCertHandle(intermediate);
265 }
266 }
267 }
268
269 if (!cert_handle)
270 return NULL;
wtc 2011/04/20 23:07:58 We should also return NULL if |ok| is false.
Ryan Sleevi 2011/04/20 23:59:10 This contradicts the behaviour documented in line
271 X509Certificate* cert = CreateFromHandle(cert_handle, SOURCE_FROM_CACHE,
272 intermediates);
273 FreeOSCertHandle(cert_handle);
274 for (size_t i = 0; i < intermediates.size(); ++i)
275 FreeOSCertHandle(intermediates[i]);
276
277 return cert;
278 }
279
280 // static
234 CertificateList X509Certificate::CreateCertificateListFromBytes( 281 CertificateList X509Certificate::CreateCertificateListFromBytes(
235 const char* data, int length, int format) { 282 const char* data, int length, int format) {
236 OSCertHandles certificates; 283 OSCertHandles certificates;
237 284
238 // Check to see if it is in a PEM-encoded form. This check is performed 285 // Check to see if it is in a PEM-encoded form. This check is performed
239 // first, as both OS X and NSS will both try to convert if they detect 286 // first, as both OS X and NSS will both try to convert if they detect
240 // PEM encoding, except they don't do it consistently between the two. 287 // PEM encoding, except they don't do it consistently between the two.
241 base::StringPiece data_string(data, length); 288 base::StringPiece data_string(data, length);
242 std::vector<std::string> pem_headers; 289 std::vector<std::string> pem_headers;
243 290
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
301 it != certificates.end(); ++it) { 348 it != certificates.end(); ++it) {
302 X509Certificate* result = CreateFromHandle(*it, SOURCE_LONE_CERT_IMPORT, 349 X509Certificate* result = CreateFromHandle(*it, SOURCE_LONE_CERT_IMPORT,
303 OSCertHandles()); 350 OSCertHandles());
304 results.push_back(scoped_refptr<X509Certificate>(result)); 351 results.push_back(scoped_refptr<X509Certificate>(result));
305 FreeOSCertHandle(*it); 352 FreeOSCertHandle(*it);
306 } 353 }
307 354
308 return results; 355 return results;
309 } 356 }
310 357
358 void X509Certificate::Persist(Pickle* pickle) {
359 DCHECK(cert_handle_);
360 if (!WriteCertHandleToPickle(cert_handle_, pickle)) {
361 NOTREACHED();
362 return;
363 }
364
365 if (!pickle->WriteSize(intermediate_ca_certs_.size())) {
366 NOTREACHED();
367 return;
368 }
369
370 for (size_t i = 0; i < intermediate_ca_certs_.size(); ++i) {
371 if (!WriteCertHandleToPickle(intermediate_ca_certs_[i], pickle)) {
372 NOTREACHED();
373 return;
374 }
375 }
376 }
377
311 bool X509Certificate::HasExpired() const { 378 bool X509Certificate::HasExpired() const {
312 return base::Time::Now() > valid_expiry(); 379 return base::Time::Now() > valid_expiry();
313 } 380 }
314 381
315 bool X509Certificate::Equals(const X509Certificate* other) const { 382 bool X509Certificate::Equals(const X509Certificate* other) const {
316 return IsSameOSCert(cert_handle_, other->cert_handle_); 383 return IsSameOSCert(cert_handle_, other->cert_handle_);
317 } 384 }
318 385
319 bool X509Certificate::HasIntermediateCertificate(OSCertHandle cert) { 386 bool X509Certificate::HasIntermediateCertificate(OSCertHandle cert) {
320 #if defined(OS_MACOSX) || defined(OS_WIN) || defined(USE_OPENSSL)
321 for (size_t i = 0; i < intermediate_ca_certs_.size(); ++i) { 387 for (size_t i = 0; i < intermediate_ca_certs_.size(); ++i) {
322 if (IsSameOSCert(cert, intermediate_ca_certs_[i])) 388 if (IsSameOSCert(cert, intermediate_ca_certs_[i]))
323 return true; 389 return true;
324 } 390 }
325 return false; 391 return false;
326 #else
327 return true;
328 #endif
329 } 392 }
330 393
331 bool X509Certificate::HasIntermediateCertificates(const OSCertHandles& certs) { 394 bool X509Certificate::HasIntermediateCertificates(const OSCertHandles& certs) {
332 for (size_t i = 0; i < certs.size(); ++i) { 395 for (size_t i = 0; i < certs.size(); ++i) {
333 if (!HasIntermediateCertificate(certs[i])) 396 if (!HasIntermediateCertificate(certs[i]))
334 return false; 397 return false;
335 } 398 }
336 return true; 399 return true;
337 } 400 }
338 401
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after
541 bool X509Certificate::IsSHA1HashInSortedArray(const SHA1Fingerprint& hash, 604 bool X509Certificate::IsSHA1HashInSortedArray(const SHA1Fingerprint& hash,
542 const uint8* array, 605 const uint8* array,
543 size_t array_byte_len) { 606 size_t array_byte_len) {
544 DCHECK_EQ(0u, array_byte_len % base::SHA1_LENGTH); 607 DCHECK_EQ(0u, array_byte_len % base::SHA1_LENGTH);
545 const unsigned arraylen = array_byte_len / base::SHA1_LENGTH; 608 const unsigned arraylen = array_byte_len / base::SHA1_LENGTH;
546 return NULL != bsearch(hash.data, array, arraylen, base::SHA1_LENGTH, 609 return NULL != bsearch(hash.data, array, arraylen, base::SHA1_LENGTH,
547 CompareSHA1Hashes); 610 CompareSHA1Hashes);
548 } 611 }
549 612
550 } // namespace net 613 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698