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

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

Issue 4963002: Refactor EnsureOpenSSLInit and openssl_util into base (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebased Created 10 years, 1 month 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) 2006-2008 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-2008 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>
11 #include <openssl/pkcs7.h> 11 #include <openssl/pkcs7.h>
12 #include <openssl/sha.h> 12 #include <openssl/sha.h>
13 #include <openssl/ssl.h> 13 #include <openssl/ssl.h>
14 #include <openssl/x509v3.h> 14 #include <openssl/x509v3.h>
15 15
16 #include "base/openssl_util.h"
16 #include "base/pickle.h" 17 #include "base/pickle.h"
17 #include "base/singleton.h" 18 #include "base/singleton.h"
18 #include "base/string_number_conversions.h" 19 #include "base/string_number_conversions.h"
19 #include "net/base/cert_status_flags.h" 20 #include "net/base/cert_status_flags.h"
20 #include "net/base/cert_verify_result.h" 21 #include "net/base/cert_verify_result.h"
21 #include "net/base/net_errors.h" 22 #include "net/base/net_errors.h"
22 #include "net/base/openssl_util.h"
23 #include "net/base/x509_openssl_util.h" 23 #include "net/base/x509_openssl_util.h"
24 24
25 namespace net { 25 namespace net {
26 26
27 namespace nxou = net::x509_openssl_util; 27 namespace nxou = net::x509_openssl_util;
28 28
29 namespace { 29 namespace {
30 30
31 void CreateOSCertHandlesFromPKCS7Bytes( 31 void CreateOSCertHandlesFromPKCS7Bytes(
32 const char* data, int length, 32 const char* data, int length,
33 X509Certificate::OSCertHandles* handles) { 33 X509Certificate::OSCertHandles* handles) {
34 const unsigned char* der_data = reinterpret_cast<const unsigned char*>(data); 34 const unsigned char* der_data = reinterpret_cast<const unsigned char*>(data);
35 ScopedSSL<PKCS7, PKCS7_free> pkcs7_cert( 35 base::ScopedSSL<PKCS7, PKCS7_free> pkcs7_cert(
36 d2i_PKCS7(NULL, &der_data, length)); 36 d2i_PKCS7(NULL, &der_data, length));
37 if (!pkcs7_cert.get()) 37 if (!pkcs7_cert.get())
38 return; 38 return;
39 39
40 STACK_OF(X509)* certs = NULL; 40 STACK_OF(X509)* certs = NULL;
41 int nid = OBJ_obj2nid(pkcs7_cert.get()->type); 41 int nid = OBJ_obj2nid(pkcs7_cert.get()->type);
42 if (nid == NID_pkcs7_signed) { 42 if (nid == NID_pkcs7_signed) {
43 certs = pkcs7_cert.get()->d.sign->cert; 43 certs = pkcs7_cert.get()->d.sign->cert;
44 } else if (nid == NID_pkcs7_signedAndEnveloped) { 44 } else if (nid == NID_pkcs7_signedAndEnveloped) {
45 certs = pkcs7_cert.get()->d.signed_and_enveloped->cert; 45 certs = pkcs7_cert.get()->d.signed_and_enveloped->cert;
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
91 &principal->country_name); 91 &principal->country_name);
92 } 92 }
93 93
94 void ParseSubjectAltNames(X509Certificate::OSCertHandle cert, 94 void ParseSubjectAltNames(X509Certificate::OSCertHandle cert,
95 std::vector<std::string>* dns_names) { 95 std::vector<std::string>* dns_names) {
96 int index = X509_get_ext_by_NID(cert, NID_subject_alt_name, -1); 96 int index = X509_get_ext_by_NID(cert, NID_subject_alt_name, -1);
97 X509_EXTENSION* alt_name_ext = X509_get_ext(cert, index); 97 X509_EXTENSION* alt_name_ext = X509_get_ext(cert, index);
98 if (!alt_name_ext) 98 if (!alt_name_ext)
99 return; 99 return;
100 100
101 ScopedSSL<GENERAL_NAMES, GENERAL_NAMES_free> alt_names( 101 base::ScopedSSL<GENERAL_NAMES, GENERAL_NAMES_free> alt_names(
102 reinterpret_cast<GENERAL_NAMES*>(X509V3_EXT_d2i(alt_name_ext))); 102 reinterpret_cast<GENERAL_NAMES*>(X509V3_EXT_d2i(alt_name_ext)));
103 if (!alt_names.get()) 103 if (!alt_names.get())
104 return; 104 return;
105 105
106 for (int i = 0; i < sk_GENERAL_NAME_num(alt_names.get()); ++i) { 106 for (int i = 0; i < sk_GENERAL_NAME_num(alt_names.get()); ++i) {
107 const GENERAL_NAME* name = sk_GENERAL_NAME_value(alt_names.get(), i); 107 const GENERAL_NAME* name = sk_GENERAL_NAME_value(alt_names.get(), i);
108 if (name->type == GEN_DNS) { 108 if (name->type == GEN_DNS) {
109 unsigned char* dns_name = ASN1_STRING_data(name->d.dNSName); 109 unsigned char* dns_name = ASN1_STRING_data(name->d.dNSName);
110 if (!dns_name) 110 if (!dns_name)
111 continue; 111 continue;
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
199 if (!der_cache) 199 if (!der_cache)
200 return; 200 return;
201 if (der_cache->data) 201 if (der_cache->data)
202 OPENSSL_free(der_cache->data); 202 OPENSSL_free(der_cache->data);
203 OPENSSL_free(der_cache); 203 OPENSSL_free(der_cache);
204 } 204 }
205 205
206 class X509InitSingleton { 206 class X509InitSingleton {
207 public: 207 public:
208 int der_cache_ex_index() const { return der_cache_ex_index_; } 208 int der_cache_ex_index() const { return der_cache_ex_index_; }
209 X509_STORE* store() const { return store_.get(); }
209 210
210 private: 211 private:
211 friend struct DefaultSingletonTraits<X509InitSingleton>; 212 friend struct DefaultSingletonTraits<X509InitSingleton>;
212 X509InitSingleton() { 213 X509InitSingleton()
213 der_cache_ex_index_ = X509_get_ex_new_index(0, 0, 0, 0, DERCache_free); 214 : der_cache_ex_index_(X509_get_ex_new_index(0, 0, 0, 0, DERCache_free)),
215 store_(X509_STORE_new()) {
214 DCHECK_NE(der_cache_ex_index_, -1); 216 DCHECK_NE(der_cache_ex_index_, -1);
217 X509_STORE_set_default_paths(store_.get());
218 // TODO(joth): Enable CRL (see X509_STORE_set_flags(X509_V_FLAG_CRL_CHECK)).
215 } 219 }
216 ~X509InitSingleton() {}
217 220
218 int der_cache_ex_index_; 221 int der_cache_ex_index_;
222 base::ScopedSSL<X509_STORE, X509_STORE_free> store_;
219 223
220 DISALLOW_COPY_AND_ASSIGN(X509InitSingleton); 224 DISALLOW_COPY_AND_ASSIGN(X509InitSingleton);
221 }; 225 };
222 226
223 // Takes ownership of |data| (which must have been allocated by OpenSSL). 227 // Takes ownership of |data| (which must have been allocated by OpenSSL).
224 DERCache* SetDERCache(X509Certificate::OSCertHandle cert, 228 DERCache* SetDERCache(X509Certificate::OSCertHandle cert,
225 int x509_der_cache_index, 229 int x509_der_cache_index,
226 unsigned char* data, 230 unsigned char* data,
227 int data_length) { 231 int data_length) {
228 DERCache* internal_cache = static_cast<DERCache*>( 232 DERCache* internal_cache = static_cast<DERCache*>(
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
283 287
284 // static 288 // static
285 void X509Certificate::FreeOSCertHandle(OSCertHandle cert_handle) { 289 void X509Certificate::FreeOSCertHandle(OSCertHandle cert_handle) {
286 // Decrement the ref-count for the cert and, if all references are gone, 290 // Decrement the ref-count for the cert and, if all references are gone,
287 // free the memory and any application-specific data associated with the 291 // free the memory and any application-specific data associated with the
288 // certificate. 292 // certificate.
289 X509_free(cert_handle); 293 X509_free(cert_handle);
290 } 294 }
291 295
292 void X509Certificate::Initialize() { 296 void X509Certificate::Initialize() {
297 base::EnsureOpenSSLInit();
293 fingerprint_ = CalculateFingerprint(cert_handle_); 298 fingerprint_ = CalculateFingerprint(cert_handle_);
294 ParsePrincipal(cert_handle_, X509_get_subject_name(cert_handle_), &subject_); 299 ParsePrincipal(cert_handle_, X509_get_subject_name(cert_handle_), &subject_);
295 ParsePrincipal(cert_handle_, X509_get_issuer_name(cert_handle_), &issuer_); 300 ParsePrincipal(cert_handle_, X509_get_issuer_name(cert_handle_), &issuer_);
296 nxou::ParseDate(X509_get_notBefore(cert_handle_), &valid_start_); 301 nxou::ParseDate(X509_get_notBefore(cert_handle_), &valid_start_);
297 nxou::ParseDate(X509_get_notAfter(cert_handle_), &valid_expiry_); 302 nxou::ParseDate(X509_get_notAfter(cert_handle_), &valid_expiry_);
298 } 303 }
299 304
300 SHA1Fingerprint X509Certificate::CalculateFingerprint(OSCertHandle cert) { 305 SHA1Fingerprint X509Certificate::CalculateFingerprint(OSCertHandle cert) {
301 SHA1Fingerprint sha1; 306 SHA1Fingerprint sha1;
302 unsigned int sha1_size = static_cast<unsigned int>(sizeof(sha1.data)); 307 unsigned int sha1_size = static_cast<unsigned int>(sizeof(sha1.data));
303 int ret = X509_digest(cert, EVP_sha1(), sha1.data, &sha1_size); 308 int ret = X509_digest(cert, EVP_sha1(), sha1.data, &sha1_size);
304 CHECK(ret); 309 CHECK(ret);
305 CHECK_EQ(sha1_size, sizeof(sha1.data)); 310 CHECK_EQ(sha1_size, sizeof(sha1.data));
306 return sha1; 311 return sha1;
307 } 312 }
308 313
309 // static 314 // static
310 X509Certificate::OSCertHandle X509Certificate::CreateOSCertHandleFromBytes( 315 X509Certificate::OSCertHandle X509Certificate::CreateOSCertHandleFromBytes(
311 const char* data, int length) { 316 const char* data, int length) {
312 if (length < 0) 317 if (length < 0)
313 return NULL; 318 return NULL;
319 base::EnsureOpenSSLInit();
314 const unsigned char* d2i_data = 320 const unsigned char* d2i_data =
315 reinterpret_cast<const unsigned char*>(data); 321 reinterpret_cast<const unsigned char*>(data);
316 // Don't cache this data via SetDERCache as this wire format may be not be 322 // Don't cache this data via SetDERCache as this wire format may be not be
317 // identical from the i2d_X509 roundtrip. 323 // identical from the i2d_X509 roundtrip.
318 X509* cert = d2i_X509(NULL, &d2i_data, length); 324 X509* cert = d2i_X509(NULL, &d2i_data, length);
319 return cert; 325 return cert;
320 } 326 }
321 327
322 // static 328 // static
323 X509Certificate::OSCertHandles X509Certificate::CreateOSCertHandlesFromBytes( 329 X509Certificate::OSCertHandles X509Certificate::CreateOSCertHandlesFromBytes(
324 const char* data, int length, Format format) { 330 const char* data, int length, Format format) {
325 OSCertHandles results; 331 OSCertHandles results;
326 if (length < 0) 332 if (length < 0)
327 return results; 333 return results;
328 334
335 base::EnsureOpenSSLInit();
bulach 2010/11/16 14:23:50 you may want to remove it from here and put inside
joth 2010/11/16 15:57:41 Done.
329 switch (format) { 336 switch (format) {
330 case FORMAT_SINGLE_CERTIFICATE: { 337 case FORMAT_SINGLE_CERTIFICATE: {
331 OSCertHandle handle = CreateOSCertHandleFromBytes(data, length); 338 OSCertHandle handle = CreateOSCertHandleFromBytes(data, length);
332 if (handle) 339 if (handle)
333 results.push_back(handle); 340 results.push_back(handle);
334 break; 341 break;
335 } 342 }
336 case FORMAT_PKCS7: { 343 case FORMAT_PKCS7: {
337 CreateOSCertHandlesFromPKCS7Bytes(data, length, &results); 344 CreateOSCertHandlesFromPKCS7Bytes(data, length, &results);
338 break; 345 break;
339 } 346 }
340 default: { 347 default: {
341 NOTREACHED() << "Certificate format " << format << " unimplemented"; 348 NOTREACHED() << "Certificate format " << format << " unimplemented";
342 break; 349 break;
343 } 350 }
344 } 351 }
345 352
346 return results; 353 return results;
347 } 354 }
348 355
356 // static
349 X509Certificate* X509Certificate::CreateFromPickle(const Pickle& pickle, 357 X509Certificate* X509Certificate::CreateFromPickle(const Pickle& pickle,
350 void** pickle_iter) { 358 void** pickle_iter) {
351 const char* data; 359 const char* data;
352 int length; 360 int length;
353 if (!pickle.ReadData(pickle_iter, &data, &length)) 361 if (!pickle.ReadData(pickle_iter, &data, &length))
354 return NULL; 362 return NULL;
355 363
356 return CreateFromBytes(data, length); 364 return CreateFromBytes(data, length);
357 } 365 }
358 366
359 void X509Certificate::Persist(Pickle* pickle) { 367 void X509Certificate::Persist(Pickle* pickle) {
360 DERCache der_cache; 368 DERCache der_cache;
361 if (!GetDERAndCacheIfNeeded(cert_handle_, &der_cache)) 369 if (!GetDERAndCacheIfNeeded(cert_handle_, &der_cache))
362 return; 370 return;
363 371
364 pickle->WriteData(reinterpret_cast<const char*>(der_cache.data), 372 pickle->WriteData(reinterpret_cast<const char*>(der_cache.data),
365 der_cache.data_length); 373 der_cache.data_length);
366 } 374 }
367 375
368 void X509Certificate::GetDNSNames(std::vector<std::string>* dns_names) const { 376 void X509Certificate::GetDNSNames(std::vector<std::string>* dns_names) const {
369 dns_names->clear(); 377 dns_names->clear();
370 378
371 ParseSubjectAltNames(cert_handle_, dns_names); 379 ParseSubjectAltNames(cert_handle_, dns_names);
372 380
373 if (dns_names->empty()) 381 if (dns_names->empty())
374 dns_names->push_back(subject_.common_name); 382 dns_names->push_back(subject_.common_name);
375 } 383 }
376 384
385 // static
386 X509_STORE* X509Certificate::cert_store() {
387 base::EnsureOpenSSLInit();
388 return Singleton<X509InitSingleton>::get()->store();
389 }
390
377 int X509Certificate::Verify(const std::string& hostname, 391 int X509Certificate::Verify(const std::string& hostname,
378 int flags, 392 int flags,
379 CertVerifyResult* verify_result) const { 393 CertVerifyResult* verify_result) const {
380 verify_result->Reset(); 394 verify_result->Reset();
381 395
382 ScopedSSL<X509_STORE_CTX, X509_STORE_CTX_free> ctx(X509_STORE_CTX_new()); 396 base::ScopedSSL<X509_STORE_CTX, X509_STORE_CTX_free> ctx(
397 X509_STORE_CTX_new());
383 398
384 ScopedSSL<STACK_OF(X509), sk_X509_free_fn> intermediates(sk_X509_new_null()); 399 base::ScopedSSL<STACK_OF(X509), sk_X509_free_fn> intermediates(
400 sk_X509_new_null());
385 if (!intermediates.get()) 401 if (!intermediates.get())
386 return ERR_OUT_OF_MEMORY; 402 return ERR_OUT_OF_MEMORY;
387 403
388 for (OSCertHandles::const_iterator it = intermediate_ca_certs_.begin(); 404 for (OSCertHandles::const_iterator it = intermediate_ca_certs_.begin();
389 it != intermediate_ca_certs_.end(); ++it) { 405 it != intermediate_ca_certs_.end(); ++it) {
390 if (!sk_X509_push(intermediates.get(), *it)) 406 if (!sk_X509_push(intermediates.get(), *it))
391 return ERR_OUT_OF_MEMORY; 407 return ERR_OUT_OF_MEMORY;
392 } 408 }
393 int rv = X509_STORE_CTX_init(ctx.get(), 409 int rv = X509_STORE_CTX_init(ctx.get(), cert_store(),
394 GetOpenSSLInitSingleton()->x509_store(),
395 cert_handle_, intermediates.get()); 410 cert_handle_, intermediates.get());
396 CHECK_EQ(1, rv); 411 CHECK_EQ(1, rv);
397 412
398 if (X509_verify_cert(ctx.get()) == 1) { 413 if (X509_verify_cert(ctx.get()) == 1) {
399 return OK; 414 return OK;
400 } 415 }
401 416
402 int x509_error = X509_STORE_CTX_get_error(ctx.get()); 417 int x509_error = X509_STORE_CTX_get_error(ctx.get());
403 int cert_status = MapCertErrorToCertStatus(x509_error); 418 int cert_status = MapCertErrorToCertStatus(x509_error);
404 LOG(ERROR) << "X509 Verification error " 419 LOG(ERROR) << "X509 Verification error "
(...skipping 17 matching lines...) Expand all
422 // cache the DER (if not already cached via X509_set_ex_data). 437 // cache the DER (if not already cached via X509_set_ex_data).
423 DERCache der_cache_a, der_cache_b; 438 DERCache der_cache_a, der_cache_b;
424 439
425 return GetDERAndCacheIfNeeded(a, &der_cache_a) && 440 return GetDERAndCacheIfNeeded(a, &der_cache_a) &&
426 GetDERAndCacheIfNeeded(b, &der_cache_b) && 441 GetDERAndCacheIfNeeded(b, &der_cache_b) &&
427 der_cache_a.data_length == der_cache_b.data_length && 442 der_cache_a.data_length == der_cache_b.data_length &&
428 memcmp(der_cache_a.data, der_cache_b.data, der_cache_a.data_length) == 0; 443 memcmp(der_cache_a.data, der_cache_b.data, der_cache_a.data_length) == 0;
429 } 444 }
430 445
431 } // namespace net 446 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698