OLD | NEW |
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 <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/memory/singleton.h" | 16 #include "base/memory/singleton.h" |
17 #include "base/openssl_util.h" | |
18 #include "base/pickle.h" | 17 #include "base/pickle.h" |
19 #include "base/string_number_conversions.h" | 18 #include "base/string_number_conversions.h" |
| 19 #include "crypto/openssl_util.h" |
20 #include "net/base/cert_status_flags.h" | 20 #include "net/base/cert_status_flags.h" |
21 #include "net/base/cert_verify_result.h" | 21 #include "net/base/cert_verify_result.h" |
22 #include "net/base/net_errors.h" | 22 #include "net/base/net_errors.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 base::EnsureOpenSSLInit(); | 34 crypto::EnsureOpenSSLInit(); |
35 const unsigned char* der_data = reinterpret_cast<const unsigned char*>(data); | 35 const unsigned char* der_data = reinterpret_cast<const unsigned char*>(data); |
36 base::ScopedOpenSSL<PKCS7, PKCS7_free> pkcs7_cert( | 36 crypto::ScopedOpenSSL<PKCS7, PKCS7_free> pkcs7_cert( |
37 d2i_PKCS7(NULL, &der_data, length)); | 37 d2i_PKCS7(NULL, &der_data, length)); |
38 if (!pkcs7_cert.get()) | 38 if (!pkcs7_cert.get()) |
39 return; | 39 return; |
40 | 40 |
41 STACK_OF(X509)* certs = NULL; | 41 STACK_OF(X509)* certs = NULL; |
42 int nid = OBJ_obj2nid(pkcs7_cert.get()->type); | 42 int nid = OBJ_obj2nid(pkcs7_cert.get()->type); |
43 if (nid == NID_pkcs7_signed) { | 43 if (nid == NID_pkcs7_signed) { |
44 certs = pkcs7_cert.get()->d.sign->cert; | 44 certs = pkcs7_cert.get()->d.sign->cert; |
45 } else if (nid == NID_pkcs7_signedAndEnveloped) { | 45 } else if (nid == NID_pkcs7_signedAndEnveloped) { |
46 certs = pkcs7_cert.get()->d.signed_and_enveloped->cert; | 46 certs = pkcs7_cert.get()->d.signed_and_enveloped->cert; |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
92 &principal->country_name); | 92 &principal->country_name); |
93 } | 93 } |
94 | 94 |
95 void ParseSubjectAltNames(X509Certificate::OSCertHandle cert, | 95 void ParseSubjectAltNames(X509Certificate::OSCertHandle cert, |
96 std::vector<std::string>* dns_names) { | 96 std::vector<std::string>* dns_names) { |
97 int index = X509_get_ext_by_NID(cert, NID_subject_alt_name, -1); | 97 int index = X509_get_ext_by_NID(cert, NID_subject_alt_name, -1); |
98 X509_EXTENSION* alt_name_ext = X509_get_ext(cert, index); | 98 X509_EXTENSION* alt_name_ext = X509_get_ext(cert, index); |
99 if (!alt_name_ext) | 99 if (!alt_name_ext) |
100 return; | 100 return; |
101 | 101 |
102 base::ScopedOpenSSL<GENERAL_NAMES, GENERAL_NAMES_free> alt_names( | 102 crypto::ScopedOpenSSL<GENERAL_NAMES, GENERAL_NAMES_free> alt_names( |
103 reinterpret_cast<GENERAL_NAMES*>(X509V3_EXT_d2i(alt_name_ext))); | 103 reinterpret_cast<GENERAL_NAMES*>(X509V3_EXT_d2i(alt_name_ext))); |
104 if (!alt_names.get()) | 104 if (!alt_names.get()) |
105 return; | 105 return; |
106 | 106 |
107 for (int i = 0; i < sk_GENERAL_NAME_num(alt_names.get()); ++i) { | 107 for (int i = 0; i < sk_GENERAL_NAME_num(alt_names.get()); ++i) { |
108 const GENERAL_NAME* name = sk_GENERAL_NAME_value(alt_names.get(), i); | 108 const GENERAL_NAME* name = sk_GENERAL_NAME_value(alt_names.get(), i); |
109 if (name->type == GEN_DNS) { | 109 if (name->type == GEN_DNS) { |
110 unsigned char* dns_name = ASN1_STRING_data(name->d.dNSName); | 110 unsigned char* dns_name = ASN1_STRING_data(name->d.dNSName); |
111 if (!dns_name) | 111 if (!dns_name) |
112 continue; | 112 continue; |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
219 void ResetCertStore() { | 219 void ResetCertStore() { |
220 store_.reset(X509_STORE_new()); | 220 store_.reset(X509_STORE_new()); |
221 DCHECK(store_.get()); | 221 DCHECK(store_.get()); |
222 X509_STORE_set_default_paths(store_.get()); | 222 X509_STORE_set_default_paths(store_.get()); |
223 // TODO(joth): Enable CRL (see X509_STORE_set_flags(X509_V_FLAG_CRL_CHECK)). | 223 // TODO(joth): Enable CRL (see X509_STORE_set_flags(X509_V_FLAG_CRL_CHECK)). |
224 } | 224 } |
225 | 225 |
226 private: | 226 private: |
227 friend struct DefaultSingletonTraits<X509InitSingleton>; | 227 friend struct DefaultSingletonTraits<X509InitSingleton>; |
228 X509InitSingleton() { | 228 X509InitSingleton() { |
229 base::EnsureOpenSSLInit(); | 229 crypto::EnsureOpenSSLInit(); |
230 der_cache_ex_index_ = X509_get_ex_new_index(0, 0, 0, 0, DERCache_free); | 230 der_cache_ex_index_ = X509_get_ex_new_index(0, 0, 0, 0, DERCache_free); |
231 DCHECK_NE(der_cache_ex_index_, -1); | 231 DCHECK_NE(der_cache_ex_index_, -1); |
232 ResetCertStore(); | 232 ResetCertStore(); |
233 } | 233 } |
234 | 234 |
235 int der_cache_ex_index_; | 235 int der_cache_ex_index_; |
236 base::ScopedOpenSSL<X509_STORE, X509_STORE_free> store_; | 236 crypto::ScopedOpenSSL<X509_STORE, X509_STORE_free> store_; |
237 | 237 |
238 DISALLOW_COPY_AND_ASSIGN(X509InitSingleton); | 238 DISALLOW_COPY_AND_ASSIGN(X509InitSingleton); |
239 }; | 239 }; |
240 | 240 |
241 // Takes ownership of |data| (which must have been allocated by OpenSSL). | 241 // Takes ownership of |data| (which must have been allocated by OpenSSL). |
242 DERCache* SetDERCache(X509Certificate::OSCertHandle cert, | 242 DERCache* SetDERCache(X509Certificate::OSCertHandle cert, |
243 int x509_der_cache_index, | 243 int x509_der_cache_index, |
244 unsigned char* data, | 244 unsigned char* data, |
245 int data_length) { | 245 int data_length) { |
246 DERCache* internal_cache = static_cast<DERCache*>( | 246 DERCache* internal_cache = static_cast<DERCache*>( |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
301 | 301 |
302 // static | 302 // static |
303 void X509Certificate::FreeOSCertHandle(OSCertHandle cert_handle) { | 303 void X509Certificate::FreeOSCertHandle(OSCertHandle cert_handle) { |
304 // Decrement the ref-count for the cert and, if all references are gone, | 304 // Decrement the ref-count for the cert and, if all references are gone, |
305 // free the memory and any application-specific data associated with the | 305 // free the memory and any application-specific data associated with the |
306 // certificate. | 306 // certificate. |
307 X509_free(cert_handle); | 307 X509_free(cert_handle); |
308 } | 308 } |
309 | 309 |
310 void X509Certificate::Initialize() { | 310 void X509Certificate::Initialize() { |
311 base::EnsureOpenSSLInit(); | 311 crypto::EnsureOpenSSLInit(); |
312 fingerprint_ = CalculateFingerprint(cert_handle_); | 312 fingerprint_ = CalculateFingerprint(cert_handle_); |
313 | 313 |
314 ASN1_INTEGER* num = X509_get_serialNumber(cert_handle_); | 314 ASN1_INTEGER* num = X509_get_serialNumber(cert_handle_); |
315 if (num) { | 315 if (num) { |
316 serial_number_ = std::string( | 316 serial_number_ = std::string( |
317 reinterpret_cast<char*>(num->data), | 317 reinterpret_cast<char*>(num->data), |
318 num->length); | 318 num->length); |
319 // Remove leading zeros. | 319 // Remove leading zeros. |
320 while (serial_number_.size() > 1 && serial_number_[0] == 0) | 320 while (serial_number_.size() > 1 && serial_number_[0] == 0) |
321 serial_number_ = serial_number_.substr(1, serial_number_.size() - 1); | 321 serial_number_ = serial_number_.substr(1, serial_number_.size() - 1); |
(...skipping 17 matching lines...) Expand all Loading... |
339 CHECK(ret); | 339 CHECK(ret); |
340 CHECK_EQ(sha1_size, sizeof(sha1.data)); | 340 CHECK_EQ(sha1_size, sizeof(sha1.data)); |
341 return sha1; | 341 return sha1; |
342 } | 342 } |
343 | 343 |
344 // static | 344 // static |
345 X509Certificate::OSCertHandle X509Certificate::CreateOSCertHandleFromBytes( | 345 X509Certificate::OSCertHandle X509Certificate::CreateOSCertHandleFromBytes( |
346 const char* data, int length) { | 346 const char* data, int length) { |
347 if (length < 0) | 347 if (length < 0) |
348 return NULL; | 348 return NULL; |
349 base::EnsureOpenSSLInit(); | 349 crypto::EnsureOpenSSLInit(); |
350 const unsigned char* d2i_data = | 350 const unsigned char* d2i_data = |
351 reinterpret_cast<const unsigned char*>(data); | 351 reinterpret_cast<const unsigned char*>(data); |
352 // Don't cache this data via SetDERCache as this wire format may be not be | 352 // Don't cache this data via SetDERCache as this wire format may be not be |
353 // identical from the i2d_X509 roundtrip. | 353 // identical from the i2d_X509 roundtrip. |
354 X509* cert = d2i_X509(NULL, &d2i_data, length); | 354 X509* cert = d2i_X509(NULL, &d2i_data, length); |
355 return cert; | 355 return cert; |
356 } | 356 } |
357 | 357 |
358 // static | 358 // static |
359 X509Certificate::OSCertHandles X509Certificate::CreateOSCertHandlesFromBytes( | 359 X509Certificate::OSCertHandles X509Certificate::CreateOSCertHandlesFromBytes( |
(...skipping 28 matching lines...) Expand all Loading... |
388 const char* data; | 388 const char* data; |
389 int length; | 389 int length; |
390 if (!pickle.ReadData(pickle_iter, &data, &length)) | 390 if (!pickle.ReadData(pickle_iter, &data, &length)) |
391 return NULL; | 391 return NULL; |
392 | 392 |
393 return CreateFromBytes(data, length); | 393 return CreateFromBytes(data, length); |
394 } | 394 } |
395 | 395 |
396 // static | 396 // static |
397 X509Certificate* X509Certificate::CreateSelfSigned( | 397 X509Certificate* X509Certificate::CreateSelfSigned( |
398 base::RSAPrivateKey* key, | 398 crypto::RSAPrivateKey* key, |
399 const std::string& subject, | 399 const std::string& subject, |
400 uint32 serial_number, | 400 uint32 serial_number, |
401 base::TimeDelta valid_duration) { | 401 base::TimeDelta valid_duration) { |
402 // TODO(port): Implement. | 402 // TODO(port): Implement. |
403 return NULL; | 403 return NULL; |
404 } | 404 } |
405 | 405 |
406 void X509Certificate::Persist(Pickle* pickle) { | 406 void X509Certificate::Persist(Pickle* pickle) { |
407 DERCache der_cache; | 407 DERCache der_cache; |
408 if (!GetDERAndCacheIfNeeded(cert_handle_, &der_cache)) | 408 if (!GetDERAndCacheIfNeeded(cert_handle_, &der_cache)) |
(...skipping 28 matching lines...) Expand all Loading... |
437 } | 437 } |
438 | 438 |
439 // TODO(joth): We should fetch the subjectAltNames directly rather than via | 439 // TODO(joth): We should fetch the subjectAltNames directly rather than via |
440 // GetDNSNames, so we can apply special handling for IP addresses vs DNS | 440 // GetDNSNames, so we can apply special handling for IP addresses vs DNS |
441 // names, etc. See http://crbug.com/62973. | 441 // names, etc. See http://crbug.com/62973. |
442 std::vector<std::string> cert_names; | 442 std::vector<std::string> cert_names; |
443 GetDNSNames(&cert_names); | 443 GetDNSNames(&cert_names); |
444 if (!VerifyHostname(hostname, cert_names)) | 444 if (!VerifyHostname(hostname, cert_names)) |
445 verify_result->cert_status |= CERT_STATUS_COMMON_NAME_INVALID; | 445 verify_result->cert_status |= CERT_STATUS_COMMON_NAME_INVALID; |
446 | 446 |
447 base::ScopedOpenSSL<X509_STORE_CTX, X509_STORE_CTX_free> ctx( | 447 crypto::ScopedOpenSSL<X509_STORE_CTX, X509_STORE_CTX_free> ctx( |
448 X509_STORE_CTX_new()); | 448 X509_STORE_CTX_new()); |
449 | 449 |
450 base::ScopedOpenSSL<STACK_OF(X509), sk_X509_free_fn> intermediates( | 450 crypto::ScopedOpenSSL<STACK_OF(X509), sk_X509_free_fn> intermediates( |
451 sk_X509_new_null()); | 451 sk_X509_new_null()); |
452 if (!intermediates.get()) | 452 if (!intermediates.get()) |
453 return ERR_OUT_OF_MEMORY; | 453 return ERR_OUT_OF_MEMORY; |
454 | 454 |
455 for (OSCertHandles::const_iterator it = intermediate_ca_certs_.begin(); | 455 for (OSCertHandles::const_iterator it = intermediate_ca_certs_.begin(); |
456 it != intermediate_ca_certs_.end(); ++it) { | 456 it != intermediate_ca_certs_.end(); ++it) { |
457 if (!sk_X509_push(intermediates.get(), *it)) | 457 if (!sk_X509_push(intermediates.get(), *it)) |
458 return ERR_OUT_OF_MEMORY; | 458 return ERR_OUT_OF_MEMORY; |
459 } | 459 } |
460 int rv = X509_STORE_CTX_init(ctx.get(), cert_store(), | 460 int rv = X509_STORE_CTX_init(ctx.get(), cert_store(), |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
495 // cache the DER (if not already cached via X509_set_ex_data). | 495 // cache the DER (if not already cached via X509_set_ex_data). |
496 DERCache der_cache_a, der_cache_b; | 496 DERCache der_cache_a, der_cache_b; |
497 | 497 |
498 return GetDERAndCacheIfNeeded(a, &der_cache_a) && | 498 return GetDERAndCacheIfNeeded(a, &der_cache_a) && |
499 GetDERAndCacheIfNeeded(b, &der_cache_b) && | 499 GetDERAndCacheIfNeeded(b, &der_cache_b) && |
500 der_cache_a.data_length == der_cache_b.data_length && | 500 der_cache_a.data_length == der_cache_b.data_length && |
501 memcmp(der_cache_a.data, der_cache_b.data, der_cache_a.data_length) == 0; | 501 memcmp(der_cache_a.data, der_cache_b.data, der_cache_a.data_length) == 0; |
502 } | 502 } |
503 | 503 |
504 } // namespace net | 504 } // namespace net |
OLD | NEW |