summaryrefslogtreecommitdiffstats
path: root/net/socket/ssl_client_socket_nss.cc
diff options
context:
space:
mode:
Diffstat (limited to 'net/socket/ssl_client_socket_nss.cc')
-rw-r--r--net/socket/ssl_client_socket_nss.cc232
1 files changed, 11 insertions, 221 deletions
diff --git a/net/socket/ssl_client_socket_nss.cc b/net/socket/ssl_client_socket_nss.cc
index 3f56b59..49e065f 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
@@ -736,6 +559,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_resume_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
@@ -1363,46 +1193,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() {
@@ -2191,7 +1981,7 @@ int SSLClientSocketNSS::DoHandshake() {
}
} else {
PRErrorCode prerr = PR_GetError();
- net_error = MapHandshakeError(prerr);
+ net_error = MapNSSHandshakeError(prerr);
// If not done, stay in this state
if (net_error == ERR_IO_PENDING) {
@@ -2580,7 +2370,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;
@@ -2601,7 +2391,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;