| 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 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 502 // cache the DER (if not already cached via X509_set_ex_data). | 502 // cache the DER (if not already cached via X509_set_ex_data). |
| 503 DERCache der_cache_a, der_cache_b; | 503 DERCache der_cache_a, der_cache_b; |
| 504 | 504 |
| 505 return GetDERAndCacheIfNeeded(a, &der_cache_a) && | 505 return GetDERAndCacheIfNeeded(a, &der_cache_a) && |
| 506 GetDERAndCacheIfNeeded(b, &der_cache_b) && | 506 GetDERAndCacheIfNeeded(b, &der_cache_b) && |
| 507 der_cache_a.data_length == der_cache_b.data_length && | 507 der_cache_a.data_length == der_cache_b.data_length && |
| 508 memcmp(der_cache_a.data, der_cache_b.data, der_cache_a.data_length) == 0; | 508 memcmp(der_cache_a.data, der_cache_b.data, der_cache_a.data_length) == 0; |
| 509 } | 509 } |
| 510 | 510 |
| 511 } // namespace net | 511 } // namespace net |
| OLD | NEW |