1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// Use of this source code is governed by a BSD-style license that can be
321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// found in the LICENSE file.
421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "net/socket/nss_ssl_util.h"
621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include <nss.h>
821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include <secerr.h>
921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include <ssl.h>
1021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include <sslerr.h>
1121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
1272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include <string>
1372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
1421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "base/lazy_instance.h"
1521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "base/logging.h"
16ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/singleton.h"
173f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include "base/threading/thread_restrictions.h"
1821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "base/values.h"
19ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "crypto/nss_util.h"
2021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "net/base/net_errors.h"
2121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "net/base/net_log.h"
2221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
2321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsennamespace net {
2421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
2521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenclass NSSSSLInitSingleton {
2621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen public:
2721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  NSSSSLInitSingleton() {
28ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    crypto::EnsureNSSInit();
2921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
3021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    NSS_SetDomesticPolicy();
3121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
3221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#if defined(USE_SYSTEM_SSL)
3321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    // Use late binding to avoid scary but benign warning
3421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    // "Symbol `SSL_ImplementedCiphers' has different size in shared object,
3521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    //  consider re-linking"
3621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    // TODO(wtc): Use the new SSL_GetImplementedCiphers and
3721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    // SSL_GetNumImplementedCiphers functions when we require NSS 3.12.6.
3821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    // See https://bugzilla.mozilla.org/show_bug.cgi?id=496993.
3921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    const PRUint16* pSSL_ImplementedCiphers = static_cast<const PRUint16*>(
4021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        dlsym(RTLD_DEFAULT, "SSL_ImplementedCiphers"));
4121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    if (pSSL_ImplementedCiphers == NULL) {
4221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      NOTREACHED() << "Can't get list of supported ciphers";
4321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      return;
4421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    }
4521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#else
4621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#define pSSL_ImplementedCiphers SSL_ImplementedCiphers
4721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#endif
4821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
4921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    // Explicitly enable exactly those ciphers with keys of at least 80 bits
5021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    for (int i = 0; i < SSL_NumImplementedCiphers; i++) {
5121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      SSLCipherSuiteInfo info;
5221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      if (SSL_GetCipherSuiteInfo(pSSL_ImplementedCiphers[i], &info,
5321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                                 sizeof(info)) == SECSuccess) {
5421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        SSL_CipherPrefSetDefault(pSSL_ImplementedCiphers[i],
5521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                                 (info.effectiveKeyBits >= 80));
5621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      }
5721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    }
5821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
5921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    // Enable SSL.
6021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    SSL_OptionSetDefault(SSL_SECURITY, PR_TRUE);
6121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
6221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    // All other SSL options are set per-session by SSLClientSocket and
6321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    // SSLServerSocket.
6421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  }
6521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
6621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  ~NSSSSLInitSingleton() {
6721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    // Have to clear the cache, or NSS_Shutdown fails with SEC_ERROR_BUSY.
6821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    SSL_ClearSessionCache();
6921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  }
7021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen};
7121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
7221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenstatic base::LazyInstance<NSSSSLInitSingleton> g_nss_ssl_init_singleton(
7321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    base::LINKER_INITIALIZED);
7421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
7521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// Initialize the NSS SSL library if it isn't already initialized.  This must
7621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// be called before any other NSS SSL functions.  This function is
7721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// thread-safe, and the NSS SSL library will only ever be initialized once.
7821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// The NSS SSL library will be properly shut down on program exit.
7921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid EnsureNSSSSLInit() {
8021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // Initializing SSL causes us to do blocking IO.
8121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // Temporarily allow it until we fix
8221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  //   http://code.google.com/p/chromium/issues/detail?id=59847
8321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  base::ThreadRestrictions::ScopedAllowIO allow_io;
8421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
8521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  g_nss_ssl_init_singleton.Get();
8621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
8721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
8821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// Map a Chromium net error code to an NSS error code.
8921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// See _MD_unix_map_default_error in the NSS source
9021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// tree for inspiration.
9121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenPRErrorCode MapErrorToNSS(int result) {
9221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  if (result >=0)
9321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    return result;
9421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
9521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  switch (result) {
9621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    case ERR_IO_PENDING:
9721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      return PR_WOULD_BLOCK_ERROR;
9821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    case ERR_ACCESS_DENIED:
9921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    case ERR_NETWORK_ACCESS_DENIED:
10021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      // For connect, this could be mapped to PR_ADDRESS_NOT_SUPPORTED_ERROR.
10121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      return PR_NO_ACCESS_RIGHTS_ERROR;
10221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    case ERR_NOT_IMPLEMENTED:
10321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      return PR_NOT_IMPLEMENTED_ERROR;
10421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    case ERR_INTERNET_DISCONNECTED:  // Equivalent to ENETDOWN.
10521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      return PR_NETWORK_UNREACHABLE_ERROR;  // Best approximation.
10621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    case ERR_CONNECTION_TIMED_OUT:
10721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    case ERR_TIMED_OUT:
10821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      return PR_IO_TIMEOUT_ERROR;
10921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    case ERR_CONNECTION_RESET:
11021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      return PR_CONNECT_RESET_ERROR;
11121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    case ERR_CONNECTION_ABORTED:
11221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      return PR_CONNECT_ABORTED_ERROR;
11321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    case ERR_CONNECTION_REFUSED:
11421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      return PR_CONNECT_REFUSED_ERROR;
11521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    case ERR_ADDRESS_UNREACHABLE:
11621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      return PR_HOST_UNREACHABLE_ERROR;  // Also PR_NETWORK_UNREACHABLE_ERROR.
11721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    case ERR_ADDRESS_INVALID:
11821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      return PR_ADDRESS_NOT_AVAILABLE_ERROR;
11921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    case ERR_NAME_NOT_RESOLVED:
12021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      return PR_DIRECTORY_LOOKUP_ERROR;
12121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    default:
12221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      LOG(WARNING) << "MapErrorToNSS " << result
12321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                   << " mapped to PR_UNKNOWN_ERROR";
12421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      return PR_UNKNOWN_ERROR;
12521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  }
12621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
12721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
12821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// The default error mapping function.
12921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// Maps an NSS error code to a network error code.
13021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenint MapNSSError(PRErrorCode err) {
13121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // TODO(port): fill this out as we learn what's important
13221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  switch (err) {
13321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    case PR_WOULD_BLOCK_ERROR:
13421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      return ERR_IO_PENDING;
13521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    case PR_ADDRESS_NOT_SUPPORTED_ERROR:  // For connect.
13621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    case PR_NO_ACCESS_RIGHTS_ERROR:
13721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      return ERR_ACCESS_DENIED;
13821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    case PR_IO_TIMEOUT_ERROR:
13921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      return ERR_TIMED_OUT;
14021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    case PR_CONNECT_RESET_ERROR:
14121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      return ERR_CONNECTION_RESET;
14221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    case PR_CONNECT_ABORTED_ERROR:
14321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      return ERR_CONNECTION_ABORTED;
14421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    case PR_CONNECT_REFUSED_ERROR:
14521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      return ERR_CONNECTION_REFUSED;
14621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    case PR_HOST_UNREACHABLE_ERROR:
14721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    case PR_NETWORK_UNREACHABLE_ERROR:
14821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      return ERR_ADDRESS_UNREACHABLE;
14921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    case PR_ADDRESS_NOT_AVAILABLE_ERROR:
15021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      return ERR_ADDRESS_INVALID;
15121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    case PR_INVALID_ARGUMENT_ERROR:
15221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      return ERR_INVALID_ARGUMENT;
15321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    case PR_END_OF_FILE_ERROR:
15421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      return ERR_CONNECTION_CLOSED;
15521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    case PR_NOT_IMPLEMENTED_ERROR:
15621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      return ERR_NOT_IMPLEMENTED;
15721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
15821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    case SEC_ERROR_INVALID_ARGS:
15921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      return ERR_INVALID_ARGUMENT;
16072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    case SEC_ERROR_NO_KEY:
16172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      return ERR_SSL_CLIENT_AUTH_CERT_NO_PRIVATE_KEY;
16272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    case SEC_ERROR_INVALID_KEY:
16372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    case SSL_ERROR_SIGN_HASHES_FAILURE:
16472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED;
16572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    // A handshake (initial or renegotiation) may fail because some signature
16672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    // (for example, the signature in the ServerKeyExchange message for an
16772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    // ephemeral Diffie-Hellman cipher suite) is invalid.
16872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    case SEC_ERROR_BAD_SIGNATURE:
16972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      return ERR_SSL_PROTOCOL_ERROR;
17021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
17121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    case SSL_ERROR_SSL_DISABLED:
17221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      return ERR_NO_SSL_VERSIONS_ENABLED;
17321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    case SSL_ERROR_NO_CYPHER_OVERLAP:
17421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    case SSL_ERROR_UNSUPPORTED_VERSION:
17521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      return ERR_SSL_VERSION_OR_CIPHER_MISMATCH;
17621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    case SSL_ERROR_HANDSHAKE_FAILURE_ALERT:
17721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    case SSL_ERROR_HANDSHAKE_UNEXPECTED_ALERT:
17821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    case SSL_ERROR_ILLEGAL_PARAMETER_ALERT:
17921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      return ERR_SSL_PROTOCOL_ERROR;
18021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    case SSL_ERROR_DECOMPRESSION_FAILURE_ALERT:
18121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      return ERR_SSL_DECOMPRESSION_FAILURE_ALERT;
18221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    case SSL_ERROR_BAD_MAC_ALERT:
18321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      return ERR_SSL_BAD_RECORD_MAC_ALERT;
18421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    case SSL_ERROR_UNSAFE_NEGOTIATION:
18521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      return ERR_SSL_UNSAFE_NEGOTIATION;
186dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    case SSL_ERROR_WEAK_SERVER_EPHEMERAL_DH_KEY:
18721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      return ERR_SSL_WEAK_SERVER_EPHEMERAL_DH_KEY;
18821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
18921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    default: {
19021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      if (IS_SSL_ERROR(err)) {
19172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        LOG(WARNING) << "Unknown SSL error " << err
19272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                     << " mapped to net::ERR_SSL_PROTOCOL_ERROR";
19321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        return ERR_SSL_PROTOCOL_ERROR;
19421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      }
19572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      LOG(WARNING) << "Unknown error " << err << " mapped to net::ERR_FAILED";
19621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      return ERR_FAILED;
19721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    }
19821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  }
19921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
20021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
20121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// Context-sensitive error mapping functions.
20221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenint MapNSSHandshakeError(PRErrorCode err) {
20321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  switch (err) {
20421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    // If the server closed on us, it is a protocol error.
20521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    // Some TLS-intolerant servers do this when we request TLS.
20621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    case PR_END_OF_FILE_ERROR:
20721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      return ERR_SSL_PROTOCOL_ERROR;
20821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    default:
20921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      return MapNSSError(err);
21021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  }
21121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
21221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
21321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// Extra parameters to attach to the NetLog when we receive an error in response
21421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// to a call to an NSS function.  Used instead of SSLErrorParams with
21521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// events of type TYPE_SSL_NSS_ERROR.  Automatically looks up last PR error.
21621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenclass SSLFailedNSSFunctionParams : public NetLog::EventParameters {
21721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen public:
21821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // |param| is ignored if it has a length of 0.
21921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  SSLFailedNSSFunctionParams(const std::string& function,
22021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                             const std::string& param)
22121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      : function_(function), param_(param), ssl_lib_error_(PR_GetError()) {
22221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  }
22321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
22421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  virtual Value* ToValue() const {
22521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    DictionaryValue* dict = new DictionaryValue();
22621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    dict->SetString("function", function_);
22721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    if (!param_.empty())
22821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      dict->SetString("param", param_);
22921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    dict->SetInteger("ssl_lib_error", ssl_lib_error_);
23021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    return dict;
23121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  }
23221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
23321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen private:
23421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  const std::string function_;
23521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  const std::string param_;
23621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  const PRErrorCode ssl_lib_error_;
23721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen};
23821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
23921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid LogFailedNSSFunction(const BoundNetLog& net_log,
24021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                          const char* function,
24121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                          const char* param) {
24221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  net_log.AddEvent(
24321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      NetLog::TYPE_SSL_NSS_ERROR,
24421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      make_scoped_refptr(new SSLFailedNSSFunctionParams(function, param)));
24521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
24621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
24721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}  // namespace net
248