| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 <openssl/asn1.h> | 7 #include <openssl/asn1.h> |
| 8 #include <openssl/crypto.h> | 8 #include <openssl/crypto.h> |
| 9 #include <openssl/obj_mac.h> | 9 #include <openssl/obj_mac.h> |
| 10 #include <openssl/pem.h> | 10 #include <openssl/pem.h> |
| (...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 199 DERCache* der_cache = static_cast<DERCache*>(ptr); | 199 DERCache* der_cache = static_cast<DERCache*>(ptr); |
| 200 if (!der_cache) | 200 if (!der_cache) |
| 201 return; | 201 return; |
| 202 if (der_cache->data) | 202 if (der_cache->data) |
| 203 OPENSSL_free(der_cache->data); | 203 OPENSSL_free(der_cache->data); |
| 204 OPENSSL_free(der_cache); | 204 OPENSSL_free(der_cache); |
| 205 } | 205 } |
| 206 | 206 |
| 207 class X509InitSingleton { | 207 class X509InitSingleton { |
| 208 public: | 208 public: |
| 209 static X509InitSingleton* Get() { | 209 static X509InitSingleton* GetInstance() { |
| 210 // We allow the X509 store to leak, because it is used from a non-joinable | 210 // We allow the X509 store to leak, because it is used from a non-joinable |
| 211 // worker that is not stopped on shutdown, hence may still be using | 211 // worker that is not stopped on shutdown, hence may still be using |
| 212 // OpenSSL library after the AtExit runner has completed. | 212 // OpenSSL library after the AtExit runner has completed. |
| 213 return Singleton<X509InitSingleton, | 213 return Singleton<X509InitSingleton, |
| 214 LeakySingletonTraits<X509InitSingleton> >::get(); | 214 LeakySingletonTraits<X509InitSingleton> >::get(); |
| 215 } | 215 } |
| 216 int der_cache_ex_index() const { return der_cache_ex_index_; } | 216 int der_cache_ex_index() const { return der_cache_ex_index_; } |
| 217 X509_STORE* store() const { return store_.get(); } | 217 X509_STORE* store() const { return store_.get(); } |
| 218 | 218 |
| 219 private: | 219 private: |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 252 internal_cache->data_length = data_length; | 252 internal_cache->data_length = data_length; |
| 253 X509_set_ex_data(cert, x509_der_cache_index, internal_cache); | 253 X509_set_ex_data(cert, x509_der_cache_index, internal_cache); |
| 254 return internal_cache; | 254 return internal_cache; |
| 255 } | 255 } |
| 256 | 256 |
| 257 // Returns true if |der_cache| points to valid data, false otherwise. | 257 // Returns true if |der_cache| points to valid data, false otherwise. |
| 258 // (note: the DER-encoded data in |der_cache| is owned by |cert|, callers should | 258 // (note: the DER-encoded data in |der_cache| is owned by |cert|, callers should |
| 259 // not free it). | 259 // not free it). |
| 260 bool GetDERAndCacheIfNeeded(X509Certificate::OSCertHandle cert, | 260 bool GetDERAndCacheIfNeeded(X509Certificate::OSCertHandle cert, |
| 261 DERCache* der_cache) { | 261 DERCache* der_cache) { |
| 262 int x509_der_cache_index = X509InitSingleton::Get()->der_cache_ex_index(); | 262 int x509_der_cache_index = |
| 263 X509InitSingleton::GetInstance()->der_cache_ex_index(); |
| 263 | 264 |
| 264 // Re-encoding the DER data via i2d_X509 is an expensive operation, but it's | 265 // Re-encoding the DER data via i2d_X509 is an expensive operation, but it's |
| 265 // necessary for comparing two certificates. We re-encode at most once per | 266 // necessary for comparing two certificates. We re-encode at most once per |
| 266 // certificate and cache the data within the X509 cert using X509_set_ex_data. | 267 // certificate and cache the data within the X509 cert using X509_set_ex_data. |
| 267 DERCache* internal_cache = static_cast<DERCache*>( | 268 DERCache* internal_cache = static_cast<DERCache*>( |
| 268 X509_get_ex_data(cert, x509_der_cache_index)); | 269 X509_get_ex_data(cert, x509_der_cache_index)); |
| 269 if (!internal_cache) { | 270 if (!internal_cache) { |
| 270 unsigned char* data = NULL; | 271 unsigned char* data = NULL; |
| 271 int data_length = i2d_X509(cert, &data); | 272 int data_length = i2d_X509(cert, &data); |
| 272 if (data_length <= 0 || !data) | 273 if (data_length <= 0 || !data) |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 385 dns_names->clear(); | 386 dns_names->clear(); |
| 386 | 387 |
| 387 ParseSubjectAltNames(cert_handle_, dns_names); | 388 ParseSubjectAltNames(cert_handle_, dns_names); |
| 388 | 389 |
| 389 if (dns_names->empty()) | 390 if (dns_names->empty()) |
| 390 dns_names->push_back(subject_.common_name); | 391 dns_names->push_back(subject_.common_name); |
| 391 } | 392 } |
| 392 | 393 |
| 393 // static | 394 // static |
| 394 X509_STORE* X509Certificate::cert_store() { | 395 X509_STORE* X509Certificate::cert_store() { |
| 395 return X509InitSingleton::Get()->store(); | 396 return X509InitSingleton::GetInstance()->store(); |
| 396 } | 397 } |
| 397 | 398 |
| 398 int X509Certificate::Verify(const std::string& hostname, | 399 int X509Certificate::Verify(const std::string& hostname, |
| 399 int flags, | 400 int flags, |
| 400 CertVerifyResult* verify_result) const { | 401 CertVerifyResult* verify_result) const { |
| 401 verify_result->Reset(); | 402 verify_result->Reset(); |
| 402 | 403 |
| 403 // TODO(joth): We should fetch the subjectAltNames directly rather than via | 404 // TODO(joth): We should fetch the subjectAltNames directly rather than via |
| 404 // GetDNSNames, so we can apply special handling for IP addresses vs DNS | 405 // GetDNSNames, so we can apply special handling for IP addresses vs DNS |
| 405 // names, etc. See http://crbug.com/62973. | 406 // names, etc. See http://crbug.com/62973. |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 454 // cache the DER (if not already cached via X509_set_ex_data). | 455 // cache the DER (if not already cached via X509_set_ex_data). |
| 455 DERCache der_cache_a, der_cache_b; | 456 DERCache der_cache_a, der_cache_b; |
| 456 | 457 |
| 457 return GetDERAndCacheIfNeeded(a, &der_cache_a) && | 458 return GetDERAndCacheIfNeeded(a, &der_cache_a) && |
| 458 GetDERAndCacheIfNeeded(b, &der_cache_b) && | 459 GetDERAndCacheIfNeeded(b, &der_cache_b) && |
| 459 der_cache_a.data_length == der_cache_b.data_length && | 460 der_cache_a.data_length == der_cache_b.data_length && |
| 460 memcmp(der_cache_a.data, der_cache_b.data, der_cache_a.data_length) == 0; | 461 memcmp(der_cache_a.data, der_cache_b.data, der_cache_a.data_length) == 0; |
| 461 } | 462 } |
| 462 | 463 |
| 463 } // namespace net | 464 } // namespace net |
| OLD | NEW |