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 |