Index: net/socket/ssl_client_socket_nss.cc |
diff --git a/net/socket/ssl_client_socket_nss.cc b/net/socket/ssl_client_socket_nss.cc |
index 05cad2790676edd851302f128561887f42dba1f5..341af9e11a946177f1f87c637a20bf091e7fc823 100644 |
--- a/net/socket/ssl_client_socket_nss.cc |
+++ b/net/socket/ssl_client_socket_nss.cc |
@@ -63,7 +63,6 @@ |
#include "base/compiler_specific.h" |
#include "base/metrics/histogram.h" |
-#include "base/lazy_instance.h" |
#include "base/logging.h" |
#include "base/nss_util.h" |
#include "base/string_number_conversions.h" |
@@ -88,6 +87,7 @@ |
#include "net/ocsp/nss_ocsp.h" |
#include "net/socket/client_socket_handle.h" |
#include "net/socket/dns_cert_provenance_checker.h" |
+#include "net/socket/nss_ssl_util.h" |
#include "net/socket/ssl_error_params.h" |
#include "net/socket/ssl_host_info.h" |
@@ -139,183 +139,6 @@ namespace net { |
namespace { |
-class NSSSSLInitSingleton { |
- public: |
- NSSSSLInitSingleton() { |
- base::EnsureNSSInit(); |
- |
- NSS_SetDomesticPolicy(); |
- |
-#if defined(USE_SYSTEM_SSL) |
- // Use late binding to avoid scary but benign warning |
- // "Symbol `SSL_ImplementedCiphers' has different size in shared object, |
- // consider re-linking" |
- // TODO(wtc): Use the new SSL_GetImplementedCiphers and |
- // SSL_GetNumImplementedCiphers functions when we require NSS 3.12.6. |
- // See https://bugzilla.mozilla.org/show_bug.cgi?id=496993. |
- const PRUint16* pSSL_ImplementedCiphers = static_cast<const PRUint16*>( |
- dlsym(RTLD_DEFAULT, "SSL_ImplementedCiphers")); |
- if (pSSL_ImplementedCiphers == NULL) { |
- NOTREACHED() << "Can't get list of supported ciphers"; |
- return; |
- } |
-#else |
-#define pSSL_ImplementedCiphers SSL_ImplementedCiphers |
-#endif |
- |
- // Explicitly enable exactly those ciphers with keys of at least 80 bits |
- for (int i = 0; i < SSL_NumImplementedCiphers; i++) { |
- SSLCipherSuiteInfo info; |
- if (SSL_GetCipherSuiteInfo(pSSL_ImplementedCiphers[i], &info, |
- sizeof(info)) == SECSuccess) { |
- SSL_CipherPrefSetDefault(pSSL_ImplementedCiphers[i], |
- (info.effectiveKeyBits >= 80)); |
- } |
- } |
- |
- // Enable SSL. |
- SSL_OptionSetDefault(SSL_SECURITY, PR_TRUE); |
- |
- // All other SSL options are set per-session by SSLClientSocket. |
- } |
- |
- ~NSSSSLInitSingleton() { |
- // Have to clear the cache, or NSS_Shutdown fails with SEC_ERROR_BUSY. |
- SSL_ClearSessionCache(); |
- } |
-}; |
- |
-static base::LazyInstance<NSSSSLInitSingleton> g_nss_ssl_init_singleton( |
- base::LINKER_INITIALIZED); |
- |
-// Initialize the NSS SSL library if it isn't already initialized. This must |
-// be called before any other NSS SSL functions. This function is |
-// thread-safe, and the NSS SSL library will only ever be initialized once. |
-// The NSS SSL library will be properly shut down on program exit. |
-void EnsureNSSSSLInit() { |
- // Initializing SSL causes us to do blocking IO. |
- // Temporarily allow it until we fix |
- // http://code.google.com/p/chromium/issues/detail?id=59847 |
- base::ThreadRestrictions::ScopedAllowIO allow_io; |
- |
- g_nss_ssl_init_singleton.Get(); |
-} |
- |
-// The default error mapping function. |
-// Maps an NSPR error code to a network error code. |
-int MapNSPRError(PRErrorCode err) { |
- // TODO(port): fill this out as we learn what's important |
- switch (err) { |
- case PR_WOULD_BLOCK_ERROR: |
- return ERR_IO_PENDING; |
- case PR_ADDRESS_NOT_SUPPORTED_ERROR: // For connect. |
- case PR_NO_ACCESS_RIGHTS_ERROR: |
- return ERR_ACCESS_DENIED; |
- case PR_IO_TIMEOUT_ERROR: |
- return ERR_TIMED_OUT; |
- case PR_CONNECT_RESET_ERROR: |
- return ERR_CONNECTION_RESET; |
- case PR_CONNECT_ABORTED_ERROR: |
- return ERR_CONNECTION_ABORTED; |
- case PR_CONNECT_REFUSED_ERROR: |
- return ERR_CONNECTION_REFUSED; |
- case PR_HOST_UNREACHABLE_ERROR: |
- case PR_NETWORK_UNREACHABLE_ERROR: |
- return ERR_ADDRESS_UNREACHABLE; |
- case PR_ADDRESS_NOT_AVAILABLE_ERROR: |
- return ERR_ADDRESS_INVALID; |
- case PR_INVALID_ARGUMENT_ERROR: |
- return ERR_INVALID_ARGUMENT; |
- case PR_END_OF_FILE_ERROR: |
- return ERR_CONNECTION_CLOSED; |
- case PR_NOT_IMPLEMENTED_ERROR: |
- return ERR_NOT_IMPLEMENTED; |
- |
- case SEC_ERROR_INVALID_ARGS: |
- return ERR_INVALID_ARGUMENT; |
- |
- case SSL_ERROR_SSL_DISABLED: |
- return ERR_NO_SSL_VERSIONS_ENABLED; |
- case SSL_ERROR_NO_CYPHER_OVERLAP: |
- case SSL_ERROR_UNSUPPORTED_VERSION: |
- return ERR_SSL_VERSION_OR_CIPHER_MISMATCH; |
- case SSL_ERROR_HANDSHAKE_FAILURE_ALERT: |
- case SSL_ERROR_HANDSHAKE_UNEXPECTED_ALERT: |
- case SSL_ERROR_ILLEGAL_PARAMETER_ALERT: |
- return ERR_SSL_PROTOCOL_ERROR; |
- case SSL_ERROR_DECOMPRESSION_FAILURE_ALERT: |
- return ERR_SSL_DECOMPRESSION_FAILURE_ALERT; |
- case SSL_ERROR_BAD_MAC_ALERT: |
- return ERR_SSL_BAD_RECORD_MAC_ALERT; |
- case SSL_ERROR_UNSAFE_NEGOTIATION: |
- return ERR_SSL_UNSAFE_NEGOTIATION; |
- case SSL_ERROR_WEAK_SERVER_KEY: |
- return ERR_SSL_WEAK_SERVER_EPHEMERAL_DH_KEY; |
- |
- default: { |
- if (IS_SSL_ERROR(err)) { |
- LOG(WARNING) << "Unknown SSL error " << err << |
- " mapped to net::ERR_SSL_PROTOCOL_ERROR"; |
- return ERR_SSL_PROTOCOL_ERROR; |
- } |
- LOG(WARNING) << "Unknown error " << err << |
- " mapped to net::ERR_FAILED"; |
- return ERR_FAILED; |
- } |
- } |
-} |
- |
-// Context-sensitive error mapping functions. |
- |
-int MapHandshakeError(PRErrorCode err) { |
- switch (err) { |
- // If the server closed on us, it is a protocol error. |
- // Some TLS-intolerant servers do this when we request TLS. |
- case PR_END_OF_FILE_ERROR: |
- // The handshake may fail because some signature (for example, the |
- // signature in the ServerKeyExchange message for an ephemeral |
- // Diffie-Hellman cipher suite) is invalid. |
- case SEC_ERROR_BAD_SIGNATURE: |
- return ERR_SSL_PROTOCOL_ERROR; |
- default: |
- return MapNSPRError(err); |
- } |
-} |
- |
-// Extra parameters to attach to the NetLog when we receive an error in response |
-// to a call to an NSS function. Used instead of SSLErrorParams with |
-// events of type TYPE_SSL_NSS_ERROR. Automatically looks up last PR error. |
-class SSLFailedNSSFunctionParams : public NetLog::EventParameters { |
- public: |
- // |param| is ignored if it has a length of 0. |
- SSLFailedNSSFunctionParams(const std::string& function, |
- const std::string& param) |
- : function_(function), param_(param), ssl_lib_error_(PR_GetError()) { |
- } |
- |
- virtual Value* ToValue() const { |
- DictionaryValue* dict = new DictionaryValue(); |
- dict->SetString("function", function_); |
- if (!param_.empty()) |
- dict->SetString("param", param_); |
- dict->SetInteger("ssl_lib_error", ssl_lib_error_); |
- return dict; |
- } |
- |
- private: |
- const std::string function_; |
- const std::string param_; |
- const PRErrorCode ssl_lib_error_; |
-}; |
- |
-void LogFailedNSSFunction(const BoundNetLog& net_log, |
- const char* function, |
- const char* param) { |
- net_log.AddEvent( |
- NetLog::TYPE_SSL_NSS_ERROR, |
- make_scoped_refptr(new SSLFailedNSSFunctionParams(function, param))); |
-} |
- |
#if defined(OS_WIN) |
// This callback is intended to be used with CertFindChainInStore. In addition |
@@ -734,6 +557,13 @@ int SSLClientSocketNSS::InitializeSSLOptions() { |
#error "You need to install NSS-3.12 or later to build chromium" |
#endif |
+ rv = SSL_OptionSet(nss_fd_, SSL_NO_CACHE, |
+ ssl_config_.session_cache_disabled); |
+ if (rv != SECSuccess) { |
+ LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_NO_CACHE"); |
+ return ERR_UNEXPECTED; |
+ } |
+ |
#ifdef SSL_ENABLE_DEFLATE |
// Some web servers have been found to break if TLS is used *or* if DEFLATE |
// is advertised. Thus, if TLS is disabled (probably because we are doing |
@@ -1361,46 +1191,6 @@ void SSLClientSocketNSS::OnRecvComplete(int result) { |
LeaveFunction(""); |
} |
-// Map a Chromium net error code to an NSS error code. |
-// See _MD_unix_map_default_error in the NSS source |
-// tree for inspiration. |
-static PRErrorCode MapErrorToNSS(int result) { |
- if (result >=0) |
- return result; |
- |
- switch (result) { |
- case ERR_IO_PENDING: |
- return PR_WOULD_BLOCK_ERROR; |
- case ERR_ACCESS_DENIED: |
- case ERR_NETWORK_ACCESS_DENIED: |
- // For connect, this could be mapped to PR_ADDRESS_NOT_SUPPORTED_ERROR. |
- return PR_NO_ACCESS_RIGHTS_ERROR; |
- case ERR_NOT_IMPLEMENTED: |
- return PR_NOT_IMPLEMENTED_ERROR; |
- case ERR_INTERNET_DISCONNECTED: // Equivalent to ENETDOWN. |
- return PR_NETWORK_UNREACHABLE_ERROR; // Best approximation. |
- case ERR_CONNECTION_TIMED_OUT: |
- case ERR_TIMED_OUT: |
- return PR_IO_TIMEOUT_ERROR; |
- case ERR_CONNECTION_RESET: |
- return PR_CONNECT_RESET_ERROR; |
- case ERR_CONNECTION_ABORTED: |
- return PR_CONNECT_ABORTED_ERROR; |
- case ERR_CONNECTION_REFUSED: |
- return PR_CONNECT_REFUSED_ERROR; |
- case ERR_ADDRESS_UNREACHABLE: |
- return PR_HOST_UNREACHABLE_ERROR; // Also PR_NETWORK_UNREACHABLE_ERROR. |
- case ERR_ADDRESS_INVALID: |
- return PR_ADDRESS_NOT_AVAILABLE_ERROR; |
- case ERR_NAME_NOT_RESOLVED: |
- return PR_DIRECTORY_LOOKUP_ERROR; |
- default: |
- LOG(WARNING) << "MapErrorToNSS " << result |
- << " mapped to PR_UNKNOWN_ERROR"; |
- return PR_UNKNOWN_ERROR; |
- } |
-} |
- |
// Do network I/O between the given buffer and the given socket. |
// Return true if some I/O performed, false otherwise (error or ERR_IO_PENDING) |
bool SSLClientSocketNSS::DoTransportIO() { |
@@ -2577,7 +2367,7 @@ int SSLClientSocketNSS::DoPayloadRead() { |
return ERR_IO_PENDING; |
} |
LeaveFunction(""); |
- rv = MapNSPRError(prerr); |
+ rv = MapNSSError(prerr); |
net_log_.AddEvent(NetLog::TYPE_SSL_READ_ERROR, |
make_scoped_refptr(new SSLErrorParams(rv, prerr))); |
return rv; |
@@ -2598,7 +2388,7 @@ int SSLClientSocketNSS::DoPayloadWrite() { |
return ERR_IO_PENDING; |
} |
LeaveFunction(""); |
- rv = MapNSPRError(prerr); |
+ rv = MapNSSError(prerr); |
net_log_.AddEvent(NetLog::TYPE_SSL_WRITE_ERROR, |
make_scoped_refptr(new SSLErrorParams(rv, prerr))); |
return rv; |