| OLD | NEW |
| 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 "net/cert/x509_certificate.h" | 5 #include "net/cert/x509_certificate.h" |
| 6 | 6 |
| 7 #include <limits.h> | 7 #include <limits.h> |
| 8 #include <stdlib.h> | 8 #include <stdlib.h> |
| 9 | 9 |
| 10 #include <algorithm> | 10 #include <algorithm> |
| 11 #include <map> | 11 #include <map> |
| 12 #include <string> | 12 #include <string> |
| 13 #include <vector> | 13 #include <vector> |
| 14 | 14 |
| 15 #include "base/trace_event/trace_event.h" |
| 15 #include "base/base64.h" | 16 #include "base/base64.h" |
| 16 #include "base/lazy_instance.h" | 17 #include "base/lazy_instance.h" |
| 17 #include "base/logging.h" | 18 #include "base/logging.h" |
| 18 #include "base/macros.h" | 19 #include "base/macros.h" |
| 19 #include "base/memory/scoped_ptr.h" | 20 #include "base/memory/scoped_ptr.h" |
| 20 #include "base/memory/singleton.h" | 21 #include "base/memory/singleton.h" |
| 21 #include "base/metrics/histogram_macros.h" | 22 #include "base/metrics/histogram_macros.h" |
| 22 #include "base/pickle.h" | 23 #include "base/pickle.h" |
| 23 #include "base/profiler/scoped_tracker.h" | 24 #include "base/profiler/scoped_tracker.h" |
| 24 #include "base/sha1.h" | 25 #include "base/sha1.h" |
| (...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 258 scoped_refptr<X509Certificate> X509Certificate::CreateFromHandle( | 259 scoped_refptr<X509Certificate> X509Certificate::CreateFromHandle( |
| 259 OSCertHandle cert_handle, | 260 OSCertHandle cert_handle, |
| 260 const OSCertHandles& intermediates) { | 261 const OSCertHandles& intermediates) { |
| 261 DCHECK(cert_handle); | 262 DCHECK(cert_handle); |
| 262 return new X509Certificate(cert_handle, intermediates); | 263 return new X509Certificate(cert_handle, intermediates); |
| 263 } | 264 } |
| 264 | 265 |
| 265 // static | 266 // static |
| 266 scoped_refptr<X509Certificate> X509Certificate::CreateFromDERCertChain( | 267 scoped_refptr<X509Certificate> X509Certificate::CreateFromDERCertChain( |
| 267 const std::vector<base::StringPiece>& der_certs) { | 268 const std::vector<base::StringPiece>& der_certs) { |
| 269 TRACE_EVENT0("toplevel", "X509Certificate::CreateFromDERCertChain"); |
| 270 |
| 268 // TODO(cbentzel): Remove ScopedTracker below once crbug.com/424386 is fixed. | 271 // TODO(cbentzel): Remove ScopedTracker below once crbug.com/424386 is fixed. |
| 269 tracked_objects::ScopedTracker tracking_profile( | 272 tracked_objects::ScopedTracker tracking_profile( |
| 270 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 273 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
| 271 "424386 X509Certificate::CreateFromDERCertChain")); | 274 "424386 X509Certificate::CreateFromDERCertChain")); |
| 272 | 275 |
| 273 if (der_certs.empty()) | 276 if (der_certs.empty()) |
| 274 return NULL; | 277 return NULL; |
| 275 | 278 |
| 279 TRACE_EVENT0("toplevel", "X509Certificate::CreateFromDERCertChain::A"); |
| 280 |
| 276 X509Certificate::OSCertHandles intermediate_ca_certs; | 281 X509Certificate::OSCertHandles intermediate_ca_certs; |
| 277 for (size_t i = 1; i < der_certs.size(); i++) { | 282 for (size_t i = 1; i < der_certs.size(); i++) { |
| 278 OSCertHandle handle = CreateOSCertHandleFromBytes( | 283 OSCertHandle handle = CreateOSCertHandleFromBytes( |
| 279 const_cast<char*>(der_certs[i].data()), der_certs[i].size()); | 284 const_cast<char*>(der_certs[i].data()), der_certs[i].size()); |
| 280 if (!handle) | 285 if (!handle) |
| 281 break; | 286 break; |
| 282 intermediate_ca_certs.push_back(handle); | 287 intermediate_ca_certs.push_back(handle); |
| 283 } | 288 } |
| 284 | 289 |
| 290 TRACE_EVENT0("toplevel", "X509Certificate::CreateFromDERCertChain::B"); |
| 285 OSCertHandle handle = NULL; | 291 OSCertHandle handle = NULL; |
| 286 // Return NULL if we failed to parse any of the certs. | 292 // Return NULL if we failed to parse any of the certs. |
| 287 if (der_certs.size() - 1 == intermediate_ca_certs.size()) { | 293 if (der_certs.size() - 1 == intermediate_ca_certs.size()) { |
| 288 handle = CreateOSCertHandleFromBytes( | 294 handle = CreateOSCertHandleFromBytes( |
| 289 const_cast<char*>(der_certs[0].data()), der_certs[0].size()); | 295 const_cast<char*>(der_certs[0].data()), der_certs[0].size()); |
| 290 } | 296 } |
| 297 TRACE_EVENT0("toplevel", "X509Certificate::CreateFromDERCertChain::C"); |
| 291 | 298 |
| 292 scoped_refptr<X509Certificate> cert = nullptr; | 299 scoped_refptr<X509Certificate> cert = nullptr; |
| 293 if (handle) { | 300 if (handle) { |
| 301 TRACE_EVENT0("toplevel", "X509Certificate::CreateFromDERCertChain::C.1"); |
| 294 cert = CreateFromHandle(handle, intermediate_ca_certs); | 302 cert = CreateFromHandle(handle, intermediate_ca_certs); |
| 303 TRACE_EVENT0("toplevel", "X509Certificate::CreateFromDERCertChain::C.2"); |
| 295 FreeOSCertHandle(handle); | 304 FreeOSCertHandle(handle); |
| 296 } | 305 } |
| 306 TRACE_EVENT0("toplevel", "X509Certificate::CreateFromDERCertChain::D"); |
| 297 | 307 |
| 298 for (size_t i = 0; i < intermediate_ca_certs.size(); i++) | 308 for (size_t i = 0; i < intermediate_ca_certs.size(); i++) |
| 299 FreeOSCertHandle(intermediate_ca_certs[i]); | 309 FreeOSCertHandle(intermediate_ca_certs[i]); |
| 300 | 310 |
| 301 return cert; | 311 return cert; |
| 302 } | 312 } |
| 303 | 313 |
| 304 // static | 314 // static |
| 305 scoped_refptr<X509Certificate> X509Certificate::CreateFromBytes( | 315 scoped_refptr<X509Certificate> X509Certificate::CreateFromBytes( |
| 306 const char* data, | 316 const char* data, |
| 307 size_t length) { | 317 size_t length) { |
| 308 OSCertHandle cert_handle = CreateOSCertHandleFromBytes(data, length); | 318 OSCertHandle cert_handle = CreateOSCertHandleFromBytes(data, length); |
| 309 if (!cert_handle) | 319 if (!cert_handle) |
| 310 return NULL; | 320 return NULL; |
| 311 | 321 |
| 312 scoped_refptr<X509Certificate> cert = | 322 scoped_refptr<X509Certificate> cert = |
| 313 CreateFromHandle(cert_handle, OSCertHandles()); | 323 CreateFromHandle(cert_handle, OSCertHandles()); |
| 314 FreeOSCertHandle(cert_handle); | 324 FreeOSCertHandle(cert_handle); |
| 315 return cert; | 325 return cert; |
| 316 } | 326 } |
| 317 | 327 |
| 318 // static | 328 // static |
| 319 scoped_refptr<X509Certificate> X509Certificate::CreateFromPickle( | 329 scoped_refptr<X509Certificate> X509Certificate::CreateFromPickle( |
| 320 base::PickleIterator* pickle_iter, | 330 base::PickleIterator* pickle_iter, |
| 321 PickleType type) { | 331 PickleType type) { |
| 332 TRACE_EVENT0("toplevel", "X509Certificate::CreateFromPickle"); |
| 333 |
| 322 if (type == PICKLETYPE_CERTIFICATE_CHAIN_V3) { | 334 if (type == PICKLETYPE_CERTIFICATE_CHAIN_V3) { |
| 323 int chain_length = 0; | 335 int chain_length = 0; |
| 324 if (!pickle_iter->ReadLength(&chain_length)) | 336 if (!pickle_iter->ReadLength(&chain_length)) |
| 325 return NULL; | 337 return NULL; |
| 326 | 338 |
| 327 std::vector<base::StringPiece> cert_chain; | 339 std::vector<base::StringPiece> cert_chain; |
| 328 const char* data = NULL; | 340 const char* data = NULL; |
| 329 int data_length = 0; | 341 int data_length = 0; |
| 330 for (int i = 0; i < chain_length; ++i) { | 342 for (int i = 0; i < chain_length; ++i) { |
| 343 TRACE_EVENT0("toplevel", "X509Certificate::CreateFromPickle::A"); |
| 331 if (!pickle_iter->ReadData(&data, &data_length)) | 344 if (!pickle_iter->ReadData(&data, &data_length)) |
| 332 return NULL; | 345 return NULL; |
| 346 TRACE_EVENT0("toplevel", "X509Certificate::CreateFromPickle::B"); |
| 333 cert_chain.push_back(base::StringPiece(data, data_length)); | 347 cert_chain.push_back(base::StringPiece(data, data_length)); |
| 334 } | 348 } |
| 335 return CreateFromDERCertChain(cert_chain); | 349 return CreateFromDERCertChain(cert_chain); |
| 336 } | 350 } |
| 337 | 351 |
| 338 // Legacy / Migration code. This should eventually be removed once | 352 // Legacy / Migration code. This should eventually be removed once |
| 339 // sufficient time has passed that all pickles serialized prior to | 353 // sufficient time has passed that all pickles serialized prior to |
| 340 // PICKLETYPE_CERTIFICATE_CHAIN_V3 have been removed. | 354 // PICKLETYPE_CERTIFICATE_CHAIN_V3 have been removed. |
| 341 OSCertHandle cert_handle = ReadOSCertHandleFromPickle(pickle_iter); | 355 OSCertHandle cert_handle = ReadOSCertHandleFromPickle(pickle_iter); |
| 342 if (!cert_handle) | 356 if (!cert_handle) |
| (...skipping 29 matching lines...) Expand all Loading... |
| 372 // the pickle, we should report success. Note that it is technically | 386 // the pickle, we should report success. Note that it is technically |
| 373 // possible for us to skip over zeroes that should have occurred after | 387 // possible for us to skip over zeroes that should have occurred after |
| 374 // an empty certificate list; to avoid this going forward, only do this | 388 // an empty certificate list; to avoid this going forward, only do this |
| 375 // backward-compatibility stuff for PICKLETYPE_CERTIFICATE_CHAIN_V1 | 389 // backward-compatibility stuff for PICKLETYPE_CERTIFICATE_CHAIN_V1 |
| 376 // which comes from the pickle version number in http_response_info.cc. | 390 // which comes from the pickle version number in http_response_info.cc. |
| 377 if (num_intermediates) { | 391 if (num_intermediates) { |
| 378 FreeOSCertHandle(cert_handle); | 392 FreeOSCertHandle(cert_handle); |
| 379 return NULL; | 393 return NULL; |
| 380 } | 394 } |
| 381 } | 395 } |
| 396 |
| 382 if (zero_check) | 397 if (zero_check) |
| 383 *pickle_iter = saved_iter; | 398 *pickle_iter = saved_iter; |
| 384 #endif // defined(OS_POSIX) && !defined(OS_MACOSX) && defined(__x86_64__) | 399 #endif // defined(OS_POSIX) && !defined(OS_MACOSX) && defined(__x86_64__) |
| 385 | 400 |
| 386 for (uint32_t i = 0; i < num_intermediates; ++i) { | 401 for (uint32_t i = 0; i < num_intermediates; ++i) { |
| 387 OSCertHandle intermediate = ReadOSCertHandleFromPickle(pickle_iter); | 402 OSCertHandle intermediate = ReadOSCertHandleFromPickle(pickle_iter); |
| 388 if (!intermediate) | 403 if (!intermediate) |
| 389 break; | 404 break; |
| 390 intermediates.push_back(intermediate); | 405 intermediates.push_back(intermediate); |
| 391 } | 406 } |
| (...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 736 OSCertHandles chain; | 751 OSCertHandles chain; |
| 737 chain.push_back(leaf); | 752 chain.push_back(leaf); |
| 738 chain.insert(chain.end(), intermediates.begin(), intermediates.end()); | 753 chain.insert(chain.end(), intermediates.begin(), intermediates.end()); |
| 739 | 754 |
| 740 return CalculateCAFingerprint256(chain); | 755 return CalculateCAFingerprint256(chain); |
| 741 } | 756 } |
| 742 | 757 |
| 743 X509Certificate::X509Certificate(OSCertHandle cert_handle, | 758 X509Certificate::X509Certificate(OSCertHandle cert_handle, |
| 744 const OSCertHandles& intermediates) | 759 const OSCertHandles& intermediates) |
| 745 : cert_handle_(DupOSCertHandle(cert_handle)) { | 760 : cert_handle_(DupOSCertHandle(cert_handle)) { |
| 761 TRACE_EVENT0("toplevel", "X509Certificate::X509Certificate::A"); |
| 746 InsertOrUpdateCache(&cert_handle_); | 762 InsertOrUpdateCache(&cert_handle_); |
| 763 TRACE_EVENT0("toplevel", "X509Certificate::X509Certificate::B"); |
| 747 for (size_t i = 0; i < intermediates.size(); ++i) { | 764 for (size_t i = 0; i < intermediates.size(); ++i) { |
| 748 // Duplicate the incoming certificate, as the caller retains ownership | 765 // Duplicate the incoming certificate, as the caller retains ownership |
| 749 // of |intermediates|. | 766 // of |intermediates|. |
| 750 OSCertHandle intermediate = DupOSCertHandle(intermediates[i]); | 767 OSCertHandle intermediate = DupOSCertHandle(intermediates[i]); |
| 751 // Update the cache, which will assume ownership of the duplicated | 768 // Update the cache, which will assume ownership of the duplicated |
| 752 // handle and return a suitable equivalent, potentially from the cache. | 769 // handle and return a suitable equivalent, potentially from the cache. |
| 753 InsertOrUpdateCache(&intermediate); | 770 InsertOrUpdateCache(&intermediate); |
| 754 intermediate_ca_certs_.push_back(intermediate); | 771 intermediate_ca_certs_.push_back(intermediate); |
| 755 } | 772 } |
| 773 TRACE_EVENT0("toplevel", "X509Certificate::X509Certificate::C"); |
| 756 // Platform-specific initialization. | 774 // Platform-specific initialization. |
| 757 Initialize(); | 775 Initialize(); |
| 758 } | 776 } |
| 759 | 777 |
| 760 X509Certificate::~X509Certificate() { | 778 X509Certificate::~X509Certificate() { |
| 761 if (cert_handle_) { | 779 if (cert_handle_) { |
| 762 RemoveFromCache(cert_handle_); | 780 RemoveFromCache(cert_handle_); |
| 763 FreeOSCertHandle(cert_handle_); | 781 FreeOSCertHandle(cert_handle_); |
| 764 } | 782 } |
| 765 for (size_t i = 0; i < intermediate_ca_certs_.size(); ++i) { | 783 for (size_t i = 0; i < intermediate_ca_certs_.size(); ++i) { |
| 766 RemoveFromCache(intermediate_ca_certs_[i]); | 784 RemoveFromCache(intermediate_ca_certs_[i]); |
| 767 FreeOSCertHandle(intermediate_ca_certs_[i]); | 785 FreeOSCertHandle(intermediate_ca_certs_[i]); |
| 768 } | 786 } |
| 769 } | 787 } |
| 770 | 788 |
| 771 } // namespace net | 789 } // namespace net |
| OLD | NEW |