Chromium Code Reviews| 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 // This file includes code SSLClientSocketNSS::DoVerifyCertComplete() derived | 5 // This file includes code SSLClientSocketNSS::DoVerifyCertComplete() derived |
| 6 // from AuthCertificateCallback() in | 6 // from AuthCertificateCallback() in |
| 7 // mozilla/security/manager/ssl/src/nsNSSCallbacks.cpp. | 7 // mozilla/security/manager/ssl/src/nsNSSCallbacks.cpp. |
| 8 | 8 |
| 9 /* ***** BEGIN LICENSE BLOCK ***** | 9 /* ***** BEGIN LICENSE BLOCK ***** |
| 10 * Version: MPL 1.1/GPL 2.0/LGPL 2.1 | 10 * Version: MPL 1.1/GPL 2.0/LGPL 2.1 |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 53 #include <nspr.h> | 53 #include <nspr.h> |
| 54 #include <nss.h> | 54 #include <nss.h> |
| 55 #include <ocsp.h> | 55 #include <ocsp.h> |
| 56 #include <pk11pub.h> | 56 #include <pk11pub.h> |
| 57 #include <secerr.h> | 57 #include <secerr.h> |
| 58 #include <sechash.h> | 58 #include <sechash.h> |
| 59 #include <ssl.h> | 59 #include <ssl.h> |
| 60 #include <sslerr.h> | 60 #include <sslerr.h> |
| 61 #include <sslproto.h> | 61 #include <sslproto.h> |
| 62 | 62 |
| 63 #if defined(OS_LINUX) | |
| 64 #include <dlfcn.h> | |
| 65 #endif | |
| 66 | |
| 63 #include <limits> | 67 #include <limits> |
| 64 | 68 |
| 65 #include "base/compiler_specific.h" | 69 #include "base/compiler_specific.h" |
| 70 #include "base/logging.h" | |
| 66 #include "base/metrics/histogram.h" | 71 #include "base/metrics/histogram.h" |
| 67 #include "base/logging.h" | |
| 68 #include "base/nss_util.h" | 72 #include "base/nss_util.h" |
| 73 #include "base/singleton.h" | |
| 69 #include "base/string_number_conversions.h" | 74 #include "base/string_number_conversions.h" |
| 70 #include "base/string_util.h" | 75 #include "base/string_util.h" |
| 71 #include "base/stringprintf.h" | 76 #include "base/stringprintf.h" |
| 72 #include "base/threading/thread_restrictions.h" | 77 #include "base/threading/thread_restrictions.h" |
| 73 #include "base/values.h" | 78 #include "base/values.h" |
| 74 #include "net/base/address_list.h" | 79 #include "net/base/address_list.h" |
| 75 #include "net/base/cert_status_flags.h" | 80 #include "net/base/cert_status_flags.h" |
| 76 #include "net/base/cert_verifier.h" | 81 #include "net/base/cert_verifier.h" |
| 77 #include "net/base/connection_type_histograms.h" | 82 #include "net/base/connection_type_histograms.h" |
| 78 #include "net/base/dns_util.h" | 83 #include "net/base/dns_util.h" |
| 79 #include "net/base/dnsrr_resolver.h" | 84 #include "net/base/dnsrr_resolver.h" |
| 80 #include "net/base/dnssec_chain_verifier.h" | 85 #include "net/base/dnssec_chain_verifier.h" |
| 81 #include "net/base/io_buffer.h" | 86 #include "net/base/io_buffer.h" |
| 82 #include "net/base/net_errors.h" | 87 #include "net/base/net_errors.h" |
| 83 #include "net/base/net_log.h" | 88 #include "net/base/net_log.h" |
| 84 #include "net/base/ssl_cert_request_info.h" | 89 #include "net/base/ssl_cert_request_info.h" |
| 85 #include "net/base/ssl_connection_status_flags.h" | 90 #include "net/base/ssl_connection_status_flags.h" |
| 86 #include "net/base/ssl_info.h" | 91 #include "net/base/ssl_info.h" |
| 87 #include "net/base/sys_addrinfo.h" | 92 #include "net/base/sys_addrinfo.h" |
| 88 #include "net/ocsp/nss_ocsp.h" | 93 #include "net/ocsp/nss_ocsp.h" |
| 89 #include "net/socket/client_socket_handle.h" | 94 #include "net/socket/client_socket_handle.h" |
| 90 #include "net/socket/dns_cert_provenance_checker.h" | 95 #include "net/socket/dns_cert_provenance_checker.h" |
| 91 #include "net/socket/nss_ssl_util.h" | 96 #include "net/socket/nss_ssl_util.h" |
| 92 #include "net/socket/ssl_error_params.h" | 97 #include "net/socket/ssl_error_params.h" |
| 93 #include "net/socket/ssl_host_info.h" | 98 #include "net/socket/ssl_host_info.h" |
| 94 | 99 |
| 95 #if defined(USE_SYSTEM_SSL) | 100 #if defined(USE_SYSTEM_SSL) |
|
wtc
2011/01/18 20:43:48
Hmm... let's combine the #include <dlfcn.h> you ad
| |
| 96 #include <dlfcn.h> | 101 #include <dlfcn.h> |
| 97 #endif | 102 #endif |
| 98 #if defined(OS_WIN) | 103 #if defined(OS_WIN) |
| 99 #include <windows.h> | 104 #include <windows.h> |
| 100 #include <wincrypt.h> | 105 #include <wincrypt.h> |
| 101 #elif defined(OS_MACOSX) | 106 #elif defined(OS_MACOSX) |
| 102 #include <Security/SecBase.h> | 107 #include <Security/SecBase.h> |
| 103 #include <Security/SecCertificate.h> | 108 #include <Security/SecCertificate.h> |
| 104 #include <Security/SecIdentity.h> | 109 #include <Security/SecIdentity.h> |
| 105 #endif | 110 #endif |
| 106 | 111 |
| 107 static const int kRecvBufferSize = 4096; | 112 static const int kRecvBufferSize = 4096; |
| 108 | 113 |
| 109 // kCorkTimeoutMs is the number of milliseconds for which we'll wait for a | 114 // kCorkTimeoutMs is the number of milliseconds for which we'll wait for a |
| 110 // Write to an SSL socket which we're False Starting. Since corking stops the | 115 // Write to an SSL socket which we're False Starting. Since corking stops the |
| 111 // Finished message from being sent, the server sees an incomplete handshake | 116 // Finished message from being sent, the server sees an incomplete handshake |
| 112 // and some will time out such sockets quite aggressively. | 117 // and some will time out such sockets quite aggressively. |
| 113 static const int kCorkTimeoutMs = 200; | 118 static const int kCorkTimeoutMs = 200; |
| 114 | 119 |
| 115 #if defined(OS_LINUX) | 120 #if defined(OS_LINUX) |
| 116 // On Linux, we dynamically link against the system version of libnss3.so. In | 121 // On Linux, we dynamically link against the system version of libnss3.so. In |
| 117 // order to continue working on systems without up-to-date versions of NSS we | 122 // order to continue working on systems without up-to-date versions of NSS we |
| 118 // declare CERT_CacheOCSPResponseFromSideChannel to be a weak symbol. If, at | 123 // lookup CERT_CacheOCSPResponseFromSideChannel with dlsym. |
| 119 // run time, we find that the symbol didn't resolve then we can avoid calling | 124 typedef SECStatus |
| 120 // the function. | 125 (*CacheOCSPResponseFromSideChannelFunction)( |
| 121 extern SECStatus | |
| 122 CERT_CacheOCSPResponseFromSideChannel( | |
| 123 CERTCertDBHandle *handle, CERTCertificate *cert, PRTime time, | 126 CERTCertDBHandle *handle, CERTCertificate *cert, PRTime time, |
| 124 SECItem *encodedResponse, void *pwArg) __attribute__((weak)); | 127 SECItem *encodedResponse, void *pwArg); |
| 125 | 128 |
| 126 static bool HaveCacheOCSPResponseFromSideChannelFunction() { | 129 // RuntimeLibNSSFunctionPointers is a singleton which caches the results of any |
| 127 return CERT_CacheOCSPResponseFromSideChannel != NULL; | 130 // runtime symbol resolution that we need. |
| 131 class RuntimeLibNSSFunctionPointers { | |
| 132 public: | |
| 133 CacheOCSPResponseFromSideChannelFunction | |
| 134 GetCacheOCSPResponseFromSideChannelFunction() { | |
| 135 return cache_ocsp_response_from_side_channel_; | |
| 136 } | |
| 137 | |
| 138 static RuntimeLibNSSFunctionPointers* GetInstance() { | |
| 139 return Singleton<RuntimeLibNSSFunctionPointers>::get(); | |
| 140 } | |
| 141 | |
| 142 private: | |
| 143 friend struct DefaultSingletonTraits<RuntimeLibNSSFunctionPointers>; | |
| 144 | |
| 145 RuntimeLibNSSFunctionPointers() { | |
| 146 cache_ocsp_response_from_side_channel_ = | |
| 147 (CacheOCSPResponseFromSideChannelFunction) | |
| 148 dlsym(RTLD_DEFAULT, "CERT_CacheOCSPResponseFromSideChannel"); | |
| 149 } | |
| 150 | |
| 151 CacheOCSPResponseFromSideChannelFunction | |
| 152 cache_ocsp_response_from_side_channel_; | |
| 153 }; | |
| 154 | |
| 155 static CacheOCSPResponseFromSideChannelFunction | |
| 156 GetCacheOCSPResponseFromSideChannelFunction() { | |
| 157 return RuntimeLibNSSFunctionPointers::GetInstance() | |
| 158 ->GetCacheOCSPResponseFromSideChannelFunction(); | |
| 128 } | 159 } |
| 129 #else | 160 #else |
| 130 // On other platforms we use the system's certificate validation functions. | 161 // On other platforms we use the system's certificate validation functions. |
| 131 // Thus we need, in the future, to plumb the OCSP response into those system | 162 // Thus we need, in the future, to plumb the OCSP response into those system |
| 132 // functions. Until then, we act as if we didn't support OCSP stapling. | 163 // functions. Until then, we act as if we didn't support OCSP stapling. |
| 133 static bool HaveCacheOCSPResponseFromSideChannelFunction() { | 164 static CacheOCSPResponseFromSideChannelFunction |
| 134 return false; | 165 GetCacheOCSPResponseFromSideChannelFunction() { |
| 166 return NULL; | |
| 135 } | 167 } |
| 136 #endif | 168 #endif |
| 137 | 169 |
| 138 namespace net { | 170 namespace net { |
| 139 | 171 |
| 140 // State machines are easier to debug if you log state transitions. | 172 // State machines are easier to debug if you log state transitions. |
| 141 // Enable these if you want to see what's going on. | 173 // Enable these if you want to see what's going on. |
| 142 #if 1 | 174 #if 1 |
| 143 #define EnterFunction(x) | 175 #define EnterFunction(x) |
| 144 #define LeaveFunction(x) | 176 #define LeaveFunction(x) |
| (...skipping 507 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 652 rv = SSL_SetNextProtoNego( | 684 rv = SSL_SetNextProtoNego( |
| 653 nss_fd_, | 685 nss_fd_, |
| 654 reinterpret_cast<const unsigned char *>(ssl_config_.next_protos.data()), | 686 reinterpret_cast<const unsigned char *>(ssl_config_.next_protos.data()), |
| 655 ssl_config_.next_protos.size()); | 687 ssl_config_.next_protos.size()); |
| 656 if (rv != SECSuccess) | 688 if (rv != SECSuccess) |
| 657 LogFailedNSSFunction(net_log_, "SSL_SetNextProtoNego", ""); | 689 LogFailedNSSFunction(net_log_, "SSL_SetNextProtoNego", ""); |
| 658 } | 690 } |
| 659 #endif | 691 #endif |
| 660 | 692 |
| 661 #ifdef SSL_ENABLE_OCSP_STAPLING | 693 #ifdef SSL_ENABLE_OCSP_STAPLING |
| 662 if (HaveCacheOCSPResponseFromSideChannelFunction() && | 694 if (GetCacheOCSPResponseFromSideChannelFunction() && |
| 663 !ssl_config_.snap_start_enabled) { | 695 !ssl_config_.snap_start_enabled) { |
| 664 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_OCSP_STAPLING, PR_TRUE); | 696 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_OCSP_STAPLING, PR_TRUE); |
| 665 if (rv != SECSuccess) | 697 if (rv != SECSuccess) |
| 666 LogFailedNSSFunction(net_log_, "SSL_OptionSet (OCSP stapling)", ""); | 698 LogFailedNSSFunction(net_log_, "SSL_OptionSet (OCSP stapling)", ""); |
| 667 } | 699 } |
| 668 #endif | 700 #endif |
| 669 | 701 |
| 670 rv = SSL_OptionSet(nss_fd_, SSL_HANDSHAKE_AS_CLIENT, PR_TRUE); | 702 rv = SSL_OptionSet(nss_fd_, SSL_HANDSHAKE_AS_CLIENT, PR_TRUE); |
| 671 if (rv != SECSuccess) { | 703 if (rv != SECSuccess) { |
| 672 LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_HANDSHAKE_AS_CLIENT"); | 704 LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_HANDSHAKE_AS_CLIENT"); |
| (...skipping 1310 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1983 memcmp(certs[i]->derCert.data, state.certs[i].data(), | 2015 memcmp(certs[i]->derCert.data, state.certs[i].data(), |
| 1984 certs[i]->derCert.len) != 0) { | 2016 certs[i]->derCert.len) != 0) { |
| 1985 predicted_cert_chain_correct_ = false; | 2017 predicted_cert_chain_correct_ = false; |
| 1986 break; | 2018 break; |
| 1987 } | 2019 } |
| 1988 } | 2020 } |
| 1989 } | 2021 } |
| 1990 } | 2022 } |
| 1991 | 2023 |
| 1992 #if defined(SSL_ENABLE_OCSP_STAPLING) | 2024 #if defined(SSL_ENABLE_OCSP_STAPLING) |
| 2025 const CacheOCSPResponseFromSideChannelFunction cache_ocsp_response = | |
| 2026 GetCacheOCSPResponseFromSideChannelFunction(); | |
| 1993 // TODO: we need to be able to plumb an OCSP response into the system | 2027 // TODO: we need to be able to plumb an OCSP response into the system |
| 1994 // libraries. When we do, HaveCacheOCSPResponseFromSideChannelFunction | 2028 // libraries. When we do, GetOCSPResponseFromSideChannelFunction |
| 1995 // needs to be updated for those platforms. | 2029 // needs to be updated for those platforms. |
| 1996 if (!predicted_cert_chain_correct_ && | 2030 if (!predicted_cert_chain_correct_ && cache_ocsp_response) { |
|
wtc
2011/01/18 20:43:48
I assume predicted_cert_chain_correct_ is likely t
| |
| 1997 HaveCacheOCSPResponseFromSideChannelFunction()) { | |
| 1998 unsigned int len = 0; | 2031 unsigned int len = 0; |
| 1999 SSL_GetStapledOCSPResponse(nss_fd_, NULL, &len); | 2032 SSL_GetStapledOCSPResponse(nss_fd_, NULL, &len); |
| 2000 if (len) { | 2033 if (len) { |
| 2001 const unsigned int orig_len = len; | 2034 const unsigned int orig_len = len; |
| 2002 scoped_array<uint8> ocsp_response(new uint8[orig_len]); | 2035 scoped_array<uint8> ocsp_response(new uint8[orig_len]); |
| 2003 SSL_GetStapledOCSPResponse(nss_fd_, ocsp_response.get(), &len); | 2036 SSL_GetStapledOCSPResponse(nss_fd_, ocsp_response.get(), &len); |
| 2004 DCHECK_EQ(orig_len, len); | 2037 DCHECK_EQ(orig_len, len); |
| 2005 | 2038 |
| 2006 SECItem ocsp_response_item; | 2039 SECItem ocsp_response_item; |
| 2007 ocsp_response_item.type = siBuffer; | 2040 ocsp_response_item.type = siBuffer; |
| 2008 ocsp_response_item.data = ocsp_response.get(); | 2041 ocsp_response_item.data = ocsp_response.get(); |
| 2009 ocsp_response_item.len = len; | 2042 ocsp_response_item.len = len; |
| 2010 | 2043 |
| 2011 CERT_CacheOCSPResponseFromSideChannel( | 2044 cache_ocsp_response( |
| 2012 CERT_GetDefaultCertDB(), server_cert_nss_, PR_Now(), | 2045 CERT_GetDefaultCertDB(), server_cert_nss_, PR_Now(), |
| 2013 &ocsp_response_item, NULL); | 2046 &ocsp_response_item, NULL); |
| 2014 } | 2047 } |
| 2015 } | 2048 } |
| 2016 #endif | 2049 #endif |
| 2017 | 2050 |
| 2018 SaveSnapStartInfo(); | 2051 SaveSnapStartInfo(); |
| 2019 // SSL handshake is completed. It's possible that we mispredicted the | 2052 // SSL handshake is completed. It's possible that we mispredicted the |
| 2020 // NPN agreed protocol. In this case, we've just sent a request in the | 2053 // NPN agreed protocol. In this case, we've just sent a request in the |
| 2021 // wrong protocol! The higher levels of this network stack aren't | 2054 // wrong protocol! The higher levels of this network stack aren't |
| (...skipping 463 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2485 case SSL_CONNECTION_VERSION_TLS1_1: | 2518 case SSL_CONNECTION_VERSION_TLS1_1: |
| 2486 UpdateConnectionTypeHistograms(CONNECTION_SSL_TLS1_1); | 2519 UpdateConnectionTypeHistograms(CONNECTION_SSL_TLS1_1); |
| 2487 break; | 2520 break; |
| 2488 case SSL_CONNECTION_VERSION_TLS1_2: | 2521 case SSL_CONNECTION_VERSION_TLS1_2: |
| 2489 UpdateConnectionTypeHistograms(CONNECTION_SSL_TLS1_2); | 2522 UpdateConnectionTypeHistograms(CONNECTION_SSL_TLS1_2); |
| 2490 break; | 2523 break; |
| 2491 }; | 2524 }; |
| 2492 } | 2525 } |
| 2493 | 2526 |
| 2494 } // namespace net | 2527 } // namespace net |
| OLD | NEW |