Home | History | Annotate | Download | only in socket
      1 // Copyright (c) 2006-2009 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 // This file includes code SSLClientSocketNSS::DoVerifyCertComplete() derived
      6 // from AuthCertificateCallback() in
      7 // mozilla/security/manager/ssl/src/nsNSSCallbacks.cpp.
      8 
      9 /* ***** BEGIN LICENSE BLOCK *****
     10  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
     11  *
     12  * The contents of this file are subject to the Mozilla Public License Version
     13  * 1.1 (the "License"); you may not use this file except in compliance with
     14  * the License. You may obtain a copy of the License at
     15  * http://www.mozilla.org/MPL/
     16  *
     17  * Software distributed under the License is distributed on an "AS IS" basis,
     18  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
     19  * for the specific language governing rights and limitations under the
     20  * License.
     21  *
     22  * The Original Code is the Netscape security libraries.
     23  *
     24  * The Initial Developer of the Original Code is
     25  * Netscape Communications Corporation.
     26  * Portions created by the Initial Developer are Copyright (C) 2000
     27  * the Initial Developer. All Rights Reserved.
     28  *
     29  * Contributor(s):
     30  *   Ian McGreer <mcgreer (at) netscape.com>
     31  *   Javier Delgadillo <javi (at) netscape.com>
     32  *   Kai Engert <kengert (at) redhat.com>
     33  *
     34  * Alternatively, the contents of this file may be used under the terms of
     35  * either the GNU General Public License Version 2 or later (the "GPL"), or
     36  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
     37  * in which case the provisions of the GPL or the LGPL are applicable instead
     38  * of those above. If you wish to allow use of your version of this file only
     39  * under the terms of either the GPL or the LGPL, and not to allow others to
     40  * use your version of this file under the terms of the MPL, indicate your
     41  * decision by deleting the provisions above and replace them with the notice
     42  * and other provisions required by the GPL or the LGPL. If you do not delete
     43  * the provisions above, a recipient may use your version of this file under
     44  * the terms of any one of the MPL, the GPL or the LGPL.
     45  *
     46  * ***** END LICENSE BLOCK ***** */
     47 
     48 #include "net/socket/ssl_client_socket_nss.h"
     49 
     50 #if defined(USE_SYSTEM_SSL)
     51 #include <dlfcn.h>
     52 #endif
     53 #include <certdb.h>
     54 #include <keyhi.h>
     55 #include <nspr.h>
     56 #include <nss.h>
     57 #include <secerr.h>
     58 #include <ssl.h>
     59 #include <sslerr.h>
     60 #include <pk11pub.h>
     61 
     62 #include "base/compiler_specific.h"
     63 #include "base/logging.h"
     64 #include "base/nss_util.h"
     65 #include "base/singleton.h"
     66 #include "base/string_util.h"
     67 #include "net/base/cert_verifier.h"
     68 #include "net/base/io_buffer.h"
     69 #include "net/base/load_log.h"
     70 #include "net/base/net_errors.h"
     71 #include "net/base/ssl_cert_request_info.h"
     72 #include "net/base/ssl_info.h"
     73 #include "net/ocsp/nss_ocsp.h"
     74 
     75 static const int kRecvBufferSize = 4096;
     76 
     77 namespace net {
     78 
     79 // State machines are easier to debug if you log state transitions.
     80 // Enable these if you want to see what's going on.
     81 #if 1
     82 #define EnterFunction(x)
     83 #define LeaveFunction(x)
     84 #define GotoState(s) next_handshake_state_ = s
     85 #define LogData(s, len)
     86 #else
     87 #define EnterFunction(x)  LOG(INFO) << (void *)this << " " << __FUNCTION__ << \
     88                            " enter " << x << \
     89                            "; next_handshake_state " << next_handshake_state_
     90 #define LeaveFunction(x)  LOG(INFO) << (void *)this << " " << __FUNCTION__ << \
     91                            " leave " << x << \
     92                            "; next_handshake_state " << next_handshake_state_
     93 #define GotoState(s) do { LOG(INFO) << (void *)this << " " << __FUNCTION__ << \
     94                            " jump to state " << s; \
     95                            next_handshake_state_ = s; } while (0)
     96 #define LogData(s, len)   LOG(INFO) << (void *)this << " " << __FUNCTION__ << \
     97                            " data [" << std::string(s, len) << "]";
     98 
     99 #endif
    100 
    101 namespace {
    102 
    103 class NSSSSLInitSingleton {
    104  public:
    105   NSSSSLInitSingleton() {
    106     base::EnsureNSSInit();
    107 
    108     NSS_SetDomesticPolicy();
    109 
    110 #if defined(USE_SYSTEM_SSL)
    111     // Use late binding to avoid scary but benign warning
    112     // "Symbol `SSL_ImplementedCiphers' has different size in shared object,
    113     //  consider re-linking"
    114     const PRUint16* pSSL_ImplementedCiphers = static_cast<const PRUint16*>(
    115         dlsym(RTLD_DEFAULT, "SSL_ImplementedCiphers"));
    116     if (pSSL_ImplementedCiphers == NULL) {
    117       NOTREACHED() << "Can't get list of supported ciphers";
    118       return;
    119     }
    120 #else
    121 #define pSSL_ImplementedCiphers SSL_ImplementedCiphers
    122 #endif
    123 
    124     // Explicitly enable exactly those ciphers with keys of at least 80 bits
    125     for (int i = 0; i < SSL_NumImplementedCiphers; i++) {
    126       SSLCipherSuiteInfo info;
    127       if (SSL_GetCipherSuiteInfo(pSSL_ImplementedCiphers[i], &info,
    128                                  sizeof(info)) == SECSuccess) {
    129         SSL_CipherPrefSetDefault(pSSL_ImplementedCiphers[i],
    130                                  (info.effectiveKeyBits >= 80));
    131       }
    132     }
    133 
    134     // Enable SSL.
    135     SSL_OptionSetDefault(SSL_SECURITY, PR_TRUE);
    136 
    137     // All other SSL options are set per-session by SSLClientSocket.
    138   }
    139 
    140   ~NSSSSLInitSingleton() {
    141     // Have to clear the cache, or NSS_Shutdown fails with SEC_ERROR_BUSY.
    142     SSL_ClearSessionCache();
    143   }
    144 };
    145 
    146 // Initialize the NSS SSL library if it isn't already initialized.  This must
    147 // be called before any other NSS SSL functions.  This function is
    148 // thread-safe, and the NSS SSL library will only ever be initialized once.
    149 // The NSS SSL library will be properly shut down on program exit.
    150 void EnsureNSSSSLInit() {
    151   Singleton<NSSSSLInitSingleton>::get();
    152 }
    153 
    154 // The default error mapping function.
    155 // Maps an NSPR error code to a network error code.
    156 int MapNSPRError(PRErrorCode err) {
    157   // TODO(port): fill this out as we learn what's important
    158   switch (err) {
    159     case PR_WOULD_BLOCK_ERROR:
    160       return ERR_IO_PENDING;
    161     case PR_ADDRESS_NOT_SUPPORTED_ERROR:  // For connect.
    162     case PR_NO_ACCESS_RIGHTS_ERROR:
    163       return ERR_ACCESS_DENIED;
    164     case PR_IO_TIMEOUT_ERROR:
    165       return ERR_TIMED_OUT;
    166     case PR_CONNECT_RESET_ERROR:
    167       return ERR_CONNECTION_RESET;
    168     case PR_CONNECT_ABORTED_ERROR:
    169       return ERR_CONNECTION_ABORTED;
    170     case PR_CONNECT_REFUSED_ERROR:
    171       return ERR_CONNECTION_REFUSED;
    172     case PR_HOST_UNREACHABLE_ERROR:
    173     case PR_NETWORK_UNREACHABLE_ERROR:
    174       return ERR_ADDRESS_UNREACHABLE;
    175     case PR_ADDRESS_NOT_AVAILABLE_ERROR:
    176       return ERR_ADDRESS_INVALID;
    177 
    178     case SSL_ERROR_NO_CYPHER_OVERLAP:
    179     case SSL_ERROR_UNSUPPORTED_VERSION:
    180       return ERR_SSL_VERSION_OR_CIPHER_MISMATCH;
    181     case SSL_ERROR_HANDSHAKE_FAILURE_ALERT:
    182       return ERR_SSL_PROTOCOL_ERROR;
    183 
    184     default: {
    185       if (IS_SSL_ERROR(err)) {
    186         LOG(WARNING) << "Unknown SSL error " << err <<
    187             " mapped to net::ERR_SSL_PROTOCOL_ERROR";
    188         return ERR_SSL_PROTOCOL_ERROR;
    189       }
    190       LOG(WARNING) << "Unknown error " << err <<
    191           " mapped to net::ERR_FAILED";
    192       return ERR_FAILED;
    193     }
    194   }
    195 }
    196 
    197 // Context-sensitive error mapping functions.
    198 
    199 int MapHandshakeError(PRErrorCode err) {
    200   switch (err) {
    201     // If the server closed on us, it is a protocol error.
    202     // Some TLS-intolerant servers do this when we request TLS.
    203     case PR_END_OF_FILE_ERROR:
    204     // The handshake may fail because some signature (for example, the
    205     // signature in the ServerKeyExchange message for an ephemeral
    206     // Diffie-Hellman cipher suite) is invalid.
    207     case SEC_ERROR_BAD_SIGNATURE:
    208       return ERR_SSL_PROTOCOL_ERROR;
    209     default:
    210       return MapNSPRError(err);
    211   }
    212 }
    213 
    214 }  // namespace
    215 
    216 #if defined(OS_WIN)
    217 // static
    218 HCERTSTORE SSLClientSocketNSS::cert_store_ = NULL;
    219 #endif
    220 
    221 SSLClientSocketNSS::SSLClientSocketNSS(ClientSocket* transport_socket,
    222                                        const std::string& hostname,
    223                                        const SSLConfig& ssl_config)
    224     : ALLOW_THIS_IN_INITIALIZER_LIST(buffer_send_callback_(
    225           this, &SSLClientSocketNSS::BufferSendComplete)),
    226       ALLOW_THIS_IN_INITIALIZER_LIST(buffer_recv_callback_(
    227           this, &SSLClientSocketNSS::BufferRecvComplete)),
    228       transport_send_busy_(false),
    229       transport_recv_busy_(false),
    230       ALLOW_THIS_IN_INITIALIZER_LIST(handshake_io_callback_(
    231           this, &SSLClientSocketNSS::OnHandshakeIOComplete)),
    232       transport_(transport_socket),
    233       hostname_(hostname),
    234       ssl_config_(ssl_config),
    235       user_connect_callback_(NULL),
    236       user_read_callback_(NULL),
    237       user_write_callback_(NULL),
    238       user_read_buf_len_(0),
    239       user_write_buf_len_(0),
    240       server_cert_nss_(NULL),
    241       client_auth_cert_needed_(false),
    242       completed_handshake_(false),
    243       next_handshake_state_(STATE_NONE),
    244       nss_fd_(NULL),
    245       nss_bufs_(NULL) {
    246   EnterFunction("");
    247 }
    248 
    249 SSLClientSocketNSS::~SSLClientSocketNSS() {
    250   EnterFunction("");
    251   Disconnect();
    252   LeaveFunction("");
    253 }
    254 
    255 int SSLClientSocketNSS::Init() {
    256   EnterFunction("");
    257   // Initialize the NSS SSL library in a threadsafe way.  This also
    258   // initializes the NSS base library.
    259   EnsureNSSSSLInit();
    260 #if !defined(OS_WIN)
    261   // We must call EnsureOCSPInit() here, on the IO thread, to get the IO loop
    262   // by MessageLoopForIO::current().
    263   // X509Certificate::Verify() runs on a worker thread of CertVerifier.
    264   EnsureOCSPInit();
    265 #endif
    266 
    267   LeaveFunction("");
    268   return OK;
    269 }
    270 
    271 int SSLClientSocketNSS::Connect(CompletionCallback* callback,
    272                                 LoadLog* load_log) {
    273   EnterFunction("");
    274   DCHECK(transport_.get());
    275   DCHECK(next_handshake_state_ == STATE_NONE);
    276   DCHECK(!user_read_callback_);
    277   DCHECK(!user_write_callback_);
    278   DCHECK(!user_connect_callback_);
    279   DCHECK(!user_read_buf_);
    280   DCHECK(!user_write_buf_);
    281 
    282   LoadLog::BeginEvent(load_log, LoadLog::TYPE_SSL_CONNECT);
    283 
    284   if (Init() != OK) {
    285     NOTREACHED() << "Couldn't initialize nss";
    286   }
    287 
    288   int rv = InitializeSSLOptions();
    289   if (rv != OK) {
    290     LoadLog::EndEvent(load_log, LoadLog::TYPE_SSL_CONNECT);
    291     return rv;
    292   }
    293 
    294   GotoState(STATE_HANDSHAKE);
    295   rv = DoHandshakeLoop(OK);
    296   if (rv == ERR_IO_PENDING) {
    297     user_connect_callback_ = callback;
    298     load_log_ = load_log;
    299   } else {
    300     LoadLog::EndEvent(load_log, LoadLog::TYPE_SSL_CONNECT);
    301   }
    302 
    303   LeaveFunction("");
    304   return rv > OK ? OK : rv;
    305 }
    306 
    307 int SSLClientSocketNSS::InitializeSSLOptions() {
    308   // Transport connected, now hook it up to nss
    309   // TODO(port): specify rx and tx buffer sizes separately
    310   nss_fd_ = memio_CreateIOLayer(kRecvBufferSize);
    311   if (nss_fd_ == NULL) {
    312     return ERR_OUT_OF_MEMORY;  // TODO(port): map NSPR error code.
    313   }
    314 
    315   // Tell NSS who we're connected to
    316   PRNetAddr peername;
    317   socklen_t len = sizeof(PRNetAddr);
    318   int err = transport_->GetPeerName((struct sockaddr *)&peername, &len);
    319   if (err) {
    320     DLOG(ERROR) << "GetPeerName failed";
    321     // TODO(wtc): Change GetPeerName to return a network error code.
    322     return ERR_UNEXPECTED;
    323   }
    324   memio_SetPeerName(nss_fd_, &peername);
    325 
    326   // Grab pointer to buffers
    327   nss_bufs_ = memio_GetSecret(nss_fd_);
    328 
    329   /* Create SSL state machine */
    330   /* Push SSL onto our fake I/O socket */
    331   nss_fd_ = SSL_ImportFD(NULL, nss_fd_);
    332   if (nss_fd_ == NULL) {
    333       return ERR_OUT_OF_MEMORY;  // TODO(port): map NSPR/NSS error code.
    334   }
    335   // TODO(port): set more ssl options!  Check errors!
    336 
    337   int rv;
    338 
    339   rv = SSL_OptionSet(nss_fd_, SSL_SECURITY, PR_TRUE);
    340   if (rv != SECSuccess)
    341      return ERR_UNEXPECTED;
    342 
    343   rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_SSL2, ssl_config_.ssl2_enabled);
    344   if (rv != SECSuccess)
    345      return ERR_UNEXPECTED;
    346 
    347   // SNI is enabled automatically if TLS is enabled -- as long as
    348   // SSL_V2_COMPATIBLE_HELLO isn't.
    349   // So don't do V2 compatible hellos unless we're really using SSL2,
    350   // to avoid errors like
    351   // "common name `mail.google.com' != requested host name `gmail.com'"
    352   rv = SSL_OptionSet(nss_fd_, SSL_V2_COMPATIBLE_HELLO,
    353                      ssl_config_.ssl2_enabled);
    354   if (rv != SECSuccess)
    355      return ERR_UNEXPECTED;
    356 
    357   rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_SSL3, ssl_config_.ssl3_enabled);
    358   if (rv != SECSuccess)
    359      return ERR_UNEXPECTED;
    360 
    361   rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_TLS, ssl_config_.tls1_enabled);
    362   if (rv != SECSuccess)
    363      return ERR_UNEXPECTED;
    364 
    365 #ifdef SSL_ENABLE_SESSION_TICKETS
    366   // Support RFC 5077
    367   rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_SESSION_TICKETS, PR_TRUE);
    368   if (rv != SECSuccess)
    369      LOG(INFO) << "SSL_ENABLE_SESSION_TICKETS failed.  Old system nss?";
    370 #else
    371   #error "You need to install NSS-3.12 or later to build chromium"
    372 #endif
    373 
    374 #ifdef SSL_ENABLE_DEFLATE
    375   // Some web servers have been found to break if TLS is used *or* if DEFLATE
    376   // is advertised. Thus, if TLS is disabled (probably because we are doing
    377   // SSLv3 fallback), we disable DEFLATE also.
    378   // See http://crbug.com/31628
    379   rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_DEFLATE, ssl_config_.tls1_enabled);
    380   if (rv != SECSuccess)
    381      LOG(INFO) << "SSL_ENABLE_DEFLATE failed.  Old system nss?";
    382 #endif
    383 
    384 #ifdef SSL_ENABLE_RENEGOTIATION
    385   // We allow servers to request renegotiation. Since we're a client,
    386   // prohibiting this is rather a waste of time. Only servers are in a position
    387   // to prevent renegotiation attacks.
    388   // http://extendedsubset.com/?p=8
    389   //
    390   // This should be changed when NSS 3.12.6 comes out with support for the
    391   // renegotiation info extension.
    392   // http://code.google.com/p/chromium/issues/detail?id=31647
    393   rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_RENEGOTIATION,
    394                      SSL_RENEGOTIATE_UNRESTRICTED);
    395   if (rv != SECSuccess)
    396      LOG(INFO) << "SSL_ENABLE_RENEGOTIATION failed.";
    397 #endif
    398 
    399 #ifdef SSL_NEXT_PROTO_NEGOTIATED
    400   if (!ssl_config_.next_protos.empty()) {
    401     rv = SSL_SetNextProtoNego(
    402        nss_fd_,
    403        reinterpret_cast<const unsigned char *>(ssl_config_.next_protos.data()),
    404        ssl_config_.next_protos.size());
    405     if (rv != SECSuccess)
    406        LOG(INFO) << "SSL_SetNextProtoNego failed.";
    407   }
    408 #endif
    409 
    410   rv = SSL_OptionSet(nss_fd_, SSL_HANDSHAKE_AS_CLIENT, PR_TRUE);
    411   if (rv != SECSuccess)
    412      return ERR_UNEXPECTED;
    413 
    414   rv = SSL_AuthCertificateHook(nss_fd_, OwnAuthCertHandler, this);
    415   if (rv != SECSuccess)
    416      return ERR_UNEXPECTED;
    417 
    418   rv = SSL_GetClientAuthDataHook(nss_fd_, ClientAuthHandler, this);
    419   if (rv != SECSuccess)
    420      return ERR_UNEXPECTED;
    421 
    422   rv = SSL_HandshakeCallback(nss_fd_, HandshakeCallback, this);
    423   if (rv != SECSuccess)
    424     return ERR_UNEXPECTED;
    425 
    426   // Tell SSL the hostname we're trying to connect to.
    427   SSL_SetURL(nss_fd_, hostname_.c_str());
    428 
    429   // Set the peer ID for session reuse.  This is necessary when we create an
    430   // SSL tunnel through a proxy -- GetPeerName returns the proxy's address
    431   // rather than the destination server's address in that case.
    432   // TODO(wtc): port in peername is not the server's port when a proxy is used.
    433   std::string peer_id = StringPrintf("%s:%d", hostname_.c_str(),
    434                                      PR_ntohs(PR_NetAddrInetPort(&peername)));
    435   rv = SSL_SetSockPeerID(nss_fd_, const_cast<char*>(peer_id.c_str()));
    436   if (rv != SECSuccess)
    437     LOG(INFO) << "SSL_SetSockPeerID failed: peer_id=" << peer_id;
    438 
    439   // Tell SSL we're a client; needed if not letting NSPR do socket I/O
    440   SSL_ResetHandshake(nss_fd_, 0);
    441 
    442   return OK;
    443 }
    444 
    445 void SSLClientSocketNSS::InvalidateSessionIfBadCertificate() {
    446   if (UpdateServerCert() != NULL &&
    447       ssl_config_.IsAllowedBadCert(server_cert_)) {
    448     SSL_InvalidateSession(nss_fd_);
    449   }
    450 }
    451 
    452 void SSLClientSocketNSS::Disconnect() {
    453   EnterFunction("");
    454 
    455   // TODO(wtc): Send SSL close_notify alert.
    456   if (nss_fd_ != NULL) {
    457     InvalidateSessionIfBadCertificate();
    458     PR_Close(nss_fd_);
    459     nss_fd_ = NULL;
    460   }
    461 
    462   // Shut down anything that may call us back (through buffer_send_callback_,
    463   // buffer_recv_callback, or handshake_io_callback_).
    464   verifier_.reset();
    465   transport_->Disconnect();
    466 
    467   // Reset object state
    468   transport_send_busy_   = false;
    469   transport_recv_busy_   = false;
    470   user_connect_callback_ = NULL;
    471   user_read_callback_    = NULL;
    472   user_write_callback_   = NULL;
    473   user_read_buf_         = NULL;
    474   user_read_buf_len_     = 0;
    475   user_write_buf_        = NULL;
    476   user_write_buf_len_    = 0;
    477   server_cert_           = NULL;
    478   if (server_cert_nss_) {
    479     CERT_DestroyCertificate(server_cert_nss_);
    480     server_cert_nss_     = NULL;
    481   }
    482   server_cert_verify_result_.Reset();
    483   completed_handshake_   = false;
    484   nss_bufs_              = NULL;
    485   client_certs_.clear();
    486   client_auth_cert_needed_ = false;
    487 
    488   LeaveFunction("");
    489 }
    490 
    491 bool SSLClientSocketNSS::IsConnected() const {
    492   // Ideally, we should also check if we have received the close_notify alert
    493   // message from the server, and return false in that case.  We're not doing
    494   // that, so this function may return a false positive.  Since the upper
    495   // layer (HttpNetworkTransaction) needs to handle a persistent connection
    496   // closed by the server when we send a request anyway, a false positive in
    497   // exchange for simpler code is a good trade-off.
    498   EnterFunction("");
    499   bool ret = completed_handshake_ && transport_->IsConnected();
    500   LeaveFunction("");
    501   return ret;
    502 }
    503 
    504 bool SSLClientSocketNSS::IsConnectedAndIdle() const {
    505   // Unlike IsConnected, this method doesn't return a false positive.
    506   //
    507   // Strictly speaking, we should check if we have received the close_notify
    508   // alert message from the server, and return false in that case.  Although
    509   // the close_notify alert message means EOF in the SSL layer, it is just
    510   // bytes to the transport layer below, so transport_->IsConnectedAndIdle()
    511   // returns the desired false when we receive close_notify.
    512   EnterFunction("");
    513   bool ret = completed_handshake_ && transport_->IsConnectedAndIdle();
    514   LeaveFunction("");
    515   return ret;
    516 }
    517 
    518 int SSLClientSocketNSS::GetPeerName(struct sockaddr* name, socklen_t* namelen) {
    519   return transport_->GetPeerName(name, namelen);
    520 }
    521 
    522 int SSLClientSocketNSS::Read(IOBuffer* buf, int buf_len,
    523                              CompletionCallback* callback) {
    524   EnterFunction(buf_len);
    525   DCHECK(completed_handshake_);
    526   DCHECK(next_handshake_state_ == STATE_NONE);
    527   DCHECK(!user_read_callback_);
    528   DCHECK(!user_connect_callback_);
    529   DCHECK(!user_read_buf_);
    530   DCHECK(nss_bufs_);
    531 
    532   user_read_buf_ = buf;
    533   user_read_buf_len_ = buf_len;
    534 
    535   int rv = DoReadLoop(OK);
    536 
    537   if (rv == ERR_IO_PENDING)
    538     user_read_callback_ = callback;
    539   else {
    540     user_read_buf_ = NULL;
    541     user_read_buf_len_ = 0;
    542   }
    543   LeaveFunction(rv);
    544   return rv;
    545 }
    546 
    547 int SSLClientSocketNSS::Write(IOBuffer* buf, int buf_len,
    548                               CompletionCallback* callback) {
    549   EnterFunction(buf_len);
    550   DCHECK(completed_handshake_);
    551   DCHECK(next_handshake_state_ == STATE_NONE);
    552   DCHECK(!user_write_callback_);
    553   DCHECK(!user_connect_callback_);
    554   DCHECK(!user_write_buf_);
    555   DCHECK(nss_bufs_);
    556 
    557   user_write_buf_ = buf;
    558   user_write_buf_len_ = buf_len;
    559 
    560   int rv = DoWriteLoop(OK);
    561 
    562   if (rv == ERR_IO_PENDING)
    563     user_write_callback_ = callback;
    564   else {
    565     user_write_buf_ = NULL;
    566     user_write_buf_len_ = 0;
    567   }
    568   LeaveFunction(rv);
    569   return rv;
    570 }
    571 
    572 bool SSLClientSocketNSS::SetReceiveBufferSize(int32 size) {
    573   return transport_->SetReceiveBufferSize(size);
    574 }
    575 
    576 bool SSLClientSocketNSS::SetSendBufferSize(int32 size) {
    577   return transport_->SetSendBufferSize(size);
    578 }
    579 
    580 X509Certificate *SSLClientSocketNSS::UpdateServerCert() {
    581   // We set the server_cert_ from OwnAuthCertHandler(), but this handler
    582   // does not necessarily get called if we are continuing a cached SSL
    583   // session.
    584   if (server_cert_ == NULL) {
    585     server_cert_nss_ = SSL_PeerCertificate(nss_fd_);
    586     if (server_cert_nss_) {
    587 #if defined(OS_WIN)
    588       // TODO(wtc): close cert_store_ at shutdown.
    589       if (!cert_store_)
    590         cert_store_ = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, NULL, 0, NULL);
    591 
    592       PCCERT_CONTEXT cert_context = NULL;
    593       BOOL ok = CertAddEncodedCertificateToStore(
    594           cert_store_,
    595           X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
    596           server_cert_nss_->derCert.data,
    597           server_cert_nss_->derCert.len,
    598           CERT_STORE_ADD_USE_EXISTING,
    599           &cert_context);
    600       DCHECK(ok);
    601       server_cert_ = X509Certificate::CreateFromHandle(
    602           cert_context, X509Certificate::SOURCE_FROM_NETWORK);
    603 
    604       // Add each of the intermediate certificates in the server's chain to
    605       // the server's X509Certificate object. This makes them available to
    606       // X509Certificate::Verify() for chain building.
    607       // TODO(wtc): Since X509Certificate::CreateFromHandle may return a
    608       // cached X509Certificate object, we may be adding intermediate CA
    609       // certificates to it repeatedly!
    610       CERTCertList* cert_list = CERT_GetCertChainFromCert(
    611           server_cert_nss_, PR_Now(), certUsageSSLCA);
    612       if (cert_list) {
    613         for (CERTCertListNode* node = CERT_LIST_HEAD(cert_list);
    614              !CERT_LIST_END(node, cert_list);
    615              node = CERT_LIST_NEXT(node)) {
    616           cert_context = NULL;
    617           ok = CertAddEncodedCertificateToStore(
    618               cert_store_,
    619               X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
    620               node->cert->derCert.data,
    621               node->cert->derCert.len,
    622               CERT_STORE_ADD_USE_EXISTING,
    623               &cert_context);
    624           DCHECK(ok);
    625           if (node->cert != server_cert_nss_)
    626             server_cert_->AddIntermediateCertificate(cert_context);
    627         }
    628         CERT_DestroyCertList(cert_list);
    629       }
    630 #else
    631       server_cert_ = X509Certificate::CreateFromHandle(
    632           CERT_DupCertificate(server_cert_nss_),
    633           X509Certificate::SOURCE_FROM_NETWORK);
    634 #endif
    635     }
    636   }
    637   return server_cert_;
    638 }
    639 
    640 void SSLClientSocketNSS::GetSSLInfo(SSLInfo* ssl_info) {
    641   EnterFunction("");
    642   ssl_info->Reset();
    643   if (!server_cert_)
    644     return;
    645 
    646   SSLChannelInfo channel_info;
    647   SECStatus ok = SSL_GetChannelInfo(nss_fd_,
    648                                     &channel_info, sizeof(channel_info));
    649   if (ok == SECSuccess &&
    650       channel_info.length == sizeof(channel_info) &&
    651       channel_info.cipherSuite) {
    652     SSLCipherSuiteInfo cipher_info;
    653     ok = SSL_GetCipherSuiteInfo(channel_info.cipherSuite,
    654                                 &cipher_info, sizeof(cipher_info));
    655     if (ok == SECSuccess) {
    656       ssl_info->security_bits = cipher_info.effectiveKeyBits;
    657     } else {
    658       ssl_info->security_bits = -1;
    659       LOG(DFATAL) << "SSL_GetCipherSuiteInfo returned " << PR_GetError()
    660                   << " for cipherSuite " << channel_info.cipherSuite;
    661     }
    662     UpdateServerCert();
    663   }
    664   ssl_info->cert_status = server_cert_verify_result_.cert_status;
    665   DCHECK(server_cert_ != NULL);
    666   ssl_info->cert = server_cert_;
    667 
    668   LeaveFunction("");
    669 }
    670 
    671 void SSLClientSocketNSS::GetSSLCertRequestInfo(
    672     SSLCertRequestInfo* cert_request_info) {
    673   EnterFunction("");
    674   cert_request_info->host_and_port = hostname_;
    675   cert_request_info->client_certs = client_certs_;
    676   LeaveFunction(cert_request_info->client_certs.size());
    677 }
    678 
    679 SSLClientSocket::NextProtoStatus
    680 SSLClientSocketNSS::GetNextProto(std::string* proto) {
    681 #if defined(SSL_NEXT_PROTO_NEGOTIATED)
    682   unsigned char buf[255];
    683   int state;
    684   unsigned len;
    685   SECStatus rv = SSL_GetNextProto(nss_fd_, &state, buf, &len, sizeof(buf));
    686   if (rv != SECSuccess) {
    687     NOTREACHED() << "Error return from SSL_GetNextProto: " << rv;
    688     proto->clear();
    689     return kNextProtoUnsupported;
    690   }
    691   // We don't check for truncation because sizeof(buf) is large enough to hold
    692   // the maximum protocol size.
    693   switch (state) {
    694     case SSL_NEXT_PROTO_NO_SUPPORT:
    695       proto->clear();
    696       return kNextProtoUnsupported;
    697     case SSL_NEXT_PROTO_NEGOTIATED:
    698       *proto = std::string(reinterpret_cast<char*>(buf), len);
    699       return kNextProtoNegotiated;
    700     case SSL_NEXT_PROTO_NO_OVERLAP:
    701       *proto = std::string(reinterpret_cast<char*>(buf), len);
    702       return kNextProtoNoOverlap;
    703     default:
    704       NOTREACHED() << "Unknown status from SSL_GetNextProto: " << state;
    705       proto->clear();
    706       return kNextProtoUnsupported;
    707   }
    708 #else
    709   // No NPN support in the libssl that we are building with.
    710   proto->clear();
    711   return kNextProtoUnsupported;
    712 #endif
    713 }
    714 
    715 void SSLClientSocketNSS::DoReadCallback(int rv) {
    716   EnterFunction(rv);
    717   DCHECK(rv != ERR_IO_PENDING);
    718   DCHECK(user_read_callback_);
    719 
    720   // Since Run may result in Read being called, clear |user_read_callback_|
    721   // up front.
    722   CompletionCallback* c = user_read_callback_;
    723   user_read_callback_ = NULL;
    724   user_read_buf_ = NULL;
    725   user_read_buf_len_ = 0;
    726   c->Run(rv);
    727   LeaveFunction("");
    728 }
    729 
    730 void SSLClientSocketNSS::DoWriteCallback(int rv) {
    731   EnterFunction(rv);
    732   DCHECK(rv != ERR_IO_PENDING);
    733   DCHECK(user_write_callback_);
    734 
    735   // Since Run may result in Write being called, clear |user_write_callback_|
    736   // up front.
    737   CompletionCallback* c = user_write_callback_;
    738   user_write_callback_ = NULL;
    739   user_write_buf_ = NULL;
    740   user_write_buf_len_ = 0;
    741   c->Run(rv);
    742   LeaveFunction("");
    743 }
    744 
    745 // As part of Connect(), the SSLClientSocketNSS object performs an SSL
    746 // handshake. This requires network IO, which in turn calls
    747 // BufferRecvComplete() with a non-zero byte count. This byte count eventually
    748 // winds its way through the state machine and ends up being passed to the
    749 // callback. For Read() and Write(), that's what we want. But for Connect(),
    750 // the caller expects OK (i.e. 0) for success.
    751 //
    752 void SSLClientSocketNSS::DoConnectCallback(int rv) {
    753   EnterFunction(rv);
    754   DCHECK_NE(rv, ERR_IO_PENDING);
    755   DCHECK(user_connect_callback_);
    756 
    757   CompletionCallback* c = user_connect_callback_;
    758   user_connect_callback_ = NULL;
    759   c->Run(rv > OK ? OK : rv);
    760   LeaveFunction("");
    761 }
    762 
    763 void SSLClientSocketNSS::OnHandshakeIOComplete(int result) {
    764   EnterFunction(result);
    765   int rv = DoHandshakeLoop(result);
    766   if (rv != ERR_IO_PENDING) {
    767     LoadLog::EndEvent(load_log_, net::LoadLog::TYPE_SSL_CONNECT);
    768     load_log_ = NULL;
    769     DoConnectCallback(rv);
    770   }
    771   LeaveFunction("");
    772 }
    773 
    774 void SSLClientSocketNSS::OnSendComplete(int result) {
    775   EnterFunction(result);
    776   if (next_handshake_state_ != STATE_NONE) {
    777     // In handshake phase.
    778     OnHandshakeIOComplete(result);
    779     LeaveFunction("");
    780     return;
    781   }
    782 
    783   // OnSendComplete may need to call DoPayloadRead while the renegotiation
    784   // handshake is in progress.
    785   int rv_read = ERR_IO_PENDING;
    786   int rv_write = ERR_IO_PENDING;
    787   bool network_moved;
    788   do {
    789       if (user_read_buf_)
    790           rv_read = DoPayloadRead();
    791       if (user_write_buf_)
    792           rv_write = DoPayloadWrite();
    793       network_moved = DoTransportIO();
    794   } while (rv_read == ERR_IO_PENDING &&
    795            rv_write == ERR_IO_PENDING &&
    796            network_moved);
    797 
    798   if (user_read_buf_ && rv_read != ERR_IO_PENDING)
    799       DoReadCallback(rv_read);
    800   if (user_write_buf_ && rv_write != ERR_IO_PENDING)
    801       DoWriteCallback(rv_write);
    802 
    803   LeaveFunction("");
    804 }
    805 
    806 void SSLClientSocketNSS::OnRecvComplete(int result) {
    807   EnterFunction(result);
    808   if (next_handshake_state_ != STATE_NONE) {
    809     // In handshake phase.
    810     OnHandshakeIOComplete(result);
    811     LeaveFunction("");
    812     return;
    813   }
    814 
    815   // Network layer received some data, check if client requested to read
    816   // decrypted data.
    817   if (!user_read_buf_) {
    818     LeaveFunction("");
    819     return;
    820   }
    821 
    822   int rv = DoReadLoop(result);
    823   if (rv != ERR_IO_PENDING)
    824     DoReadCallback(rv);
    825   LeaveFunction("");
    826 }
    827 
    828 // Map a Chromium net error code to an NSS error code.
    829 // See _MD_unix_map_default_error in the NSS source
    830 // tree for inspiration.
    831 static PRErrorCode MapErrorToNSS(int result) {
    832   if (result >=0)
    833     return result;
    834 
    835   switch (result) {
    836     case ERR_IO_PENDING:
    837       return PR_WOULD_BLOCK_ERROR;
    838     case ERR_ACCESS_DENIED:
    839       // For connect, this could be mapped to PR_ADDRESS_NOT_SUPPORTED_ERROR.
    840       return PR_NO_ACCESS_RIGHTS_ERROR;
    841     case ERR_INTERNET_DISCONNECTED:  // Equivalent to ENETDOWN.
    842       return PR_NETWORK_UNREACHABLE_ERROR;  // Best approximation.
    843     case ERR_CONNECTION_TIMED_OUT:
    844     case ERR_TIMED_OUT:
    845       return PR_IO_TIMEOUT_ERROR;
    846     case ERR_CONNECTION_RESET:
    847       return PR_CONNECT_RESET_ERROR;
    848     case ERR_CONNECTION_ABORTED:
    849       return PR_CONNECT_ABORTED_ERROR;
    850     case ERR_CONNECTION_REFUSED:
    851       return PR_CONNECT_REFUSED_ERROR;
    852     case ERR_ADDRESS_UNREACHABLE:
    853       return PR_HOST_UNREACHABLE_ERROR;  // Also PR_NETWORK_UNREACHABLE_ERROR.
    854     case ERR_ADDRESS_INVALID:
    855       return PR_ADDRESS_NOT_AVAILABLE_ERROR;
    856     default:
    857       LOG(WARNING) << "MapErrorToNSS " << result
    858                    << " mapped to PR_UNKNOWN_ERROR";
    859       return PR_UNKNOWN_ERROR;
    860   }
    861 }
    862 
    863 // Do network I/O between the given buffer and the given socket.
    864 // Return true if some I/O performed, false otherwise (error or ERR_IO_PENDING)
    865 bool SSLClientSocketNSS::DoTransportIO() {
    866   EnterFunction("");
    867   bool network_moved = false;
    868   if (nss_bufs_ != NULL) {
    869     int nsent = BufferSend();
    870     int nreceived = BufferRecv();
    871     network_moved = (nsent > 0 || nreceived >= 0);
    872   }
    873   LeaveFunction(network_moved);
    874   return network_moved;
    875 }
    876 
    877 // Return 0 for EOF,
    878 // > 0 for bytes transferred immediately,
    879 // < 0 for error (or the non-error ERR_IO_PENDING).
    880 int SSLClientSocketNSS::BufferSend(void) {
    881   if (transport_send_busy_) return ERR_IO_PENDING;
    882 
    883   int nsent = 0;
    884   EnterFunction("");
    885   // nss_bufs_ is a circular buffer.  It may have two contiguous parts
    886   // (before and after the wrap).  So this for loop needs two iterations.
    887   for (int i = 0; i < 2; ++i) {
    888     const char* buf;
    889     int nb = memio_GetWriteParams(nss_bufs_, &buf);
    890     if (!nb)
    891       break;
    892 
    893     scoped_refptr<IOBuffer> send_buffer = new IOBuffer(nb);
    894     memcpy(send_buffer->data(), buf, nb);
    895     int rv = transport_->Write(send_buffer, nb, &buffer_send_callback_);
    896     if (rv == ERR_IO_PENDING) {
    897       transport_send_busy_ = true;
    898       break;
    899     } else {
    900       memio_PutWriteResult(nss_bufs_, MapErrorToNSS(rv));
    901       if (rv < 0) {
    902         // Return the error even if the previous Write succeeded.
    903         nsent = rv;
    904         break;
    905       }
    906       nsent += rv;
    907     }
    908   }
    909 
    910   LeaveFunction(nsent);
    911   return nsent;
    912 }
    913 
    914 void SSLClientSocketNSS::BufferSendComplete(int result) {
    915   EnterFunction(result);
    916   memio_PutWriteResult(nss_bufs_, MapErrorToNSS(result));
    917   transport_send_busy_ = false;
    918   OnSendComplete(result);
    919   LeaveFunction("");
    920 }
    921 
    922 
    923 int SSLClientSocketNSS::BufferRecv(void) {
    924   if (transport_recv_busy_) return ERR_IO_PENDING;
    925 
    926   char *buf;
    927   int nb = memio_GetReadParams(nss_bufs_, &buf);
    928   EnterFunction(nb);
    929   int rv;
    930   if (!nb) {
    931     // buffer too full to read into, so no I/O possible at moment
    932     rv = ERR_IO_PENDING;
    933   } else {
    934     recv_buffer_ = new IOBuffer(nb);
    935     rv = transport_->Read(recv_buffer_, nb, &buffer_recv_callback_);
    936     if (rv == ERR_IO_PENDING) {
    937       transport_recv_busy_ = true;
    938     } else {
    939       if (rv > 0)
    940         memcpy(buf, recv_buffer_->data(), rv);
    941       memio_PutReadResult(nss_bufs_, MapErrorToNSS(rv));
    942       recv_buffer_ = NULL;
    943     }
    944   }
    945   LeaveFunction(rv);
    946   return rv;
    947 }
    948 
    949 void SSLClientSocketNSS::BufferRecvComplete(int result) {
    950   EnterFunction(result);
    951   if (result > 0) {
    952     char *buf;
    953     memio_GetReadParams(nss_bufs_, &buf);
    954     memcpy(buf, recv_buffer_->data(), result);
    955   }
    956   recv_buffer_ = NULL;
    957   memio_PutReadResult(nss_bufs_, MapErrorToNSS(result));
    958   transport_recv_busy_ = false;
    959   OnRecvComplete(result);
    960   LeaveFunction("");
    961 }
    962 
    963 int SSLClientSocketNSS::DoHandshakeLoop(int last_io_result) {
    964   EnterFunction(last_io_result);
    965   bool network_moved;
    966   int rv = last_io_result;
    967   do {
    968     // Default to STATE_NONE for next state.
    969     // (This is a quirk carried over from the windows
    970     // implementation.  It makes reading the logs a bit harder.)
    971     // State handlers can and often do call GotoState just
    972     // to stay in the current state.
    973     State state = next_handshake_state_;
    974     GotoState(STATE_NONE);
    975     switch (state) {
    976       case STATE_NONE:
    977         // we're just pumping data between the buffer and the network
    978         break;
    979       case STATE_HANDSHAKE:
    980         rv = DoHandshake();
    981         break;
    982       case STATE_VERIFY_CERT:
    983         DCHECK(rv == OK);
    984         rv = DoVerifyCert(rv);
    985         break;
    986       case STATE_VERIFY_CERT_COMPLETE:
    987         rv = DoVerifyCertComplete(rv);
    988         break;
    989       default:
    990         rv = ERR_UNEXPECTED;
    991         NOTREACHED() << "unexpected state";
    992         break;
    993     }
    994 
    995     // Do the actual network I/O
    996     network_moved = DoTransportIO();
    997   } while ((rv != ERR_IO_PENDING || network_moved) &&
    998             next_handshake_state_ != STATE_NONE);
    999   LeaveFunction("");
   1000   return rv;
   1001 }
   1002 
   1003 int SSLClientSocketNSS::DoReadLoop(int result) {
   1004   EnterFunction("");
   1005   DCHECK(completed_handshake_);
   1006   DCHECK(next_handshake_state_ == STATE_NONE);
   1007 
   1008   if (result < 0)
   1009     return result;
   1010 
   1011   if (!nss_bufs_)
   1012     return ERR_UNEXPECTED;
   1013 
   1014   bool network_moved;
   1015   int rv;
   1016   do {
   1017     rv = DoPayloadRead();
   1018     network_moved = DoTransportIO();
   1019   } while (rv == ERR_IO_PENDING && network_moved);
   1020 
   1021   LeaveFunction("");
   1022   return rv;
   1023 }
   1024 
   1025 int SSLClientSocketNSS::DoWriteLoop(int result) {
   1026   EnterFunction("");
   1027   DCHECK(completed_handshake_);
   1028   DCHECK(next_handshake_state_ == STATE_NONE);
   1029 
   1030   if (result < 0)
   1031     return result;
   1032 
   1033   if (!nss_bufs_)
   1034     return ERR_UNEXPECTED;
   1035 
   1036   bool network_moved;
   1037   int rv;
   1038   do {
   1039     rv = DoPayloadWrite();
   1040     network_moved = DoTransportIO();
   1041   } while (rv == ERR_IO_PENDING && network_moved);
   1042 
   1043   LeaveFunction("");
   1044   return rv;
   1045 }
   1046 
   1047 // static
   1048 // NSS calls this if an incoming certificate needs to be verified.
   1049 // Do nothing but return SECSuccess.
   1050 // This is called only in full handshake mode.
   1051 // Peer certificate is retrieved in HandshakeCallback() later, which is called
   1052 // in full handshake mode or in resumption handshake mode.
   1053 SECStatus SSLClientSocketNSS::OwnAuthCertHandler(void* arg,
   1054                                                  PRFileDesc* socket,
   1055                                                  PRBool checksig,
   1056                                                  PRBool is_server) {
   1057   // Tell NSS to not verify the certificate.
   1058   return SECSuccess;
   1059 }
   1060 
   1061 // static
   1062 // NSS calls this if a client certificate is needed.
   1063 // Based on Mozilla's NSS_GetClientAuthData.
   1064 SECStatus SSLClientSocketNSS::ClientAuthHandler(
   1065     void* arg,
   1066     PRFileDesc* socket,
   1067     CERTDistNames* ca_names,
   1068     CERTCertificate** result_certificate,
   1069     SECKEYPrivateKey** result_private_key) {
   1070 #if defined(OS_WIN)
   1071   // Not implemented.  Send no client certificate.
   1072   PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
   1073   return SECFailure;
   1074 #else
   1075   SSLClientSocketNSS* that = reinterpret_cast<SSLClientSocketNSS*>(arg);
   1076 
   1077   that->client_auth_cert_needed_ = !that->ssl_config_.send_client_cert;
   1078 
   1079   CERTCertificate* cert = NULL;
   1080   SECKEYPrivateKey* privkey = NULL;
   1081   void* wincx  = SSL_RevealPinArg(socket);
   1082 
   1083   // Second pass: a client certificate should have been selected.
   1084   if (that->ssl_config_.send_client_cert) {
   1085     if (that->ssl_config_.client_cert) {
   1086       cert = CERT_DupCertificate(
   1087           that->ssl_config_.client_cert->os_cert_handle());
   1088       privkey = PK11_FindKeyByAnyCert(cert, wincx);
   1089       if (privkey) {
   1090         // TODO(jsorianopastor): We should wait for server certificate
   1091         // verification before sending our credentials.  See
   1092         // http://crbug.com/13934.
   1093         *result_certificate = cert;
   1094         *result_private_key = privkey;
   1095         return SECSuccess;
   1096       }
   1097       LOG(WARNING) << "Client cert found without private key";
   1098     }
   1099     // Send no client certificate.
   1100     return SECFailure;
   1101   }
   1102 
   1103   CERTCertNicknames* names = CERT_GetCertNicknames(
   1104       CERT_GetDefaultCertDB(), SEC_CERT_NICKNAMES_USER, wincx);
   1105   if (names) {
   1106     for (int i = 0; i < names->numnicknames; ++i) {
   1107       cert = CERT_FindUserCertByUsage(
   1108           CERT_GetDefaultCertDB(), names->nicknames[i],
   1109           certUsageSSLClient, PR_FALSE, wincx);
   1110       if (!cert)
   1111         continue;
   1112       // Only check unexpired certs.
   1113       if (CERT_CheckCertValidTimes(cert, PR_Now(), PR_TRUE) ==
   1114           secCertTimeValid &&
   1115           NSS_CmpCertChainWCANames(cert, ca_names) == SECSuccess) {
   1116         privkey = PK11_FindKeyByAnyCert(cert, wincx);
   1117         if (privkey) {
   1118           X509Certificate* x509_cert = X509Certificate::CreateFromHandle(
   1119               cert, X509Certificate::SOURCE_LONE_CERT_IMPORT);
   1120           that->client_certs_.push_back(x509_cert);
   1121           SECKEY_DestroyPrivateKey(privkey);
   1122           continue;
   1123         }
   1124       }
   1125       CERT_DestroyCertificate(cert);
   1126     }
   1127     CERT_FreeNicknames(names);
   1128   }
   1129 
   1130   return SECFailure;
   1131 #endif
   1132 }
   1133 
   1134 // static
   1135 // NSS calls this when handshake is completed.
   1136 // After the SSL handshake is finished, use CertVerifier to verify
   1137 // the saved server certificate.
   1138 void SSLClientSocketNSS::HandshakeCallback(PRFileDesc* socket,
   1139                                            void* arg) {
   1140   SSLClientSocketNSS* that = reinterpret_cast<SSLClientSocketNSS*>(arg);
   1141 
   1142   that->UpdateServerCert();
   1143 }
   1144 
   1145 int SSLClientSocketNSS::DoHandshake() {
   1146   EnterFunction("");
   1147   int net_error = net::OK;
   1148   SECStatus rv = SSL_ForceHandshake(nss_fd_);
   1149 
   1150   if (client_auth_cert_needed_) {
   1151     net_error = ERR_SSL_CLIENT_AUTH_CERT_NEEDED;
   1152     // If the handshake already succeeded (because the server requests but
   1153     // doesn't require a client cert), we need to invalidate the SSL session
   1154     // so that we won't try to resume the non-client-authenticated session in
   1155     // the next handshake.  This will cause the server to ask for a client
   1156     // cert again.
   1157     if (rv == SECSuccess && SSL_InvalidateSession(nss_fd_) != SECSuccess) {
   1158       LOG(WARNING) << "Couldn't invalidate SSL session: " << PR_GetError();
   1159     }
   1160   } else if (rv == SECSuccess) {
   1161     // SSL handshake is completed.  Let's verify the certificate.
   1162     GotoState(STATE_VERIFY_CERT);
   1163     // Done!
   1164   } else {
   1165     PRErrorCode prerr = PR_GetError();
   1166     net_error = MapHandshakeError(prerr);
   1167 
   1168     // If not done, stay in this state
   1169     if (net_error == ERR_IO_PENDING) {
   1170       GotoState(STATE_HANDSHAKE);
   1171     } else {
   1172       LOG(ERROR) << "handshake failed; NSS error code " << prerr
   1173                  << ", net_error " << net_error;
   1174     }
   1175   }
   1176 
   1177   LeaveFunction("");
   1178   return net_error;
   1179 }
   1180 
   1181 int SSLClientSocketNSS::DoVerifyCert(int result) {
   1182   DCHECK(server_cert_);
   1183   GotoState(STATE_VERIFY_CERT_COMPLETE);
   1184   int flags = 0;
   1185   if (ssl_config_.rev_checking_enabled)
   1186     flags |= X509Certificate::VERIFY_REV_CHECKING_ENABLED;
   1187   if (ssl_config_.verify_ev_cert)
   1188     flags |= X509Certificate::VERIFY_EV_CERT;
   1189   verifier_.reset(new CertVerifier);
   1190   return verifier_->Verify(server_cert_, hostname_, flags,
   1191                            &server_cert_verify_result_,
   1192                            &handshake_io_callback_);
   1193 }
   1194 
   1195 // Derived from AuthCertificateCallback() in
   1196 // mozilla/source/security/manager/ssl/src/nsNSSCallbacks.cpp.
   1197 int SSLClientSocketNSS::DoVerifyCertComplete(int result) {
   1198   DCHECK(verifier_.get());
   1199   verifier_.reset();
   1200 
   1201   if (result == OK) {
   1202     // Remember the intermediate CA certs if the server sends them to us.
   1203     //
   1204     // We used to remember the intermediate CA certs in the NSS database
   1205     // persistently.  However, NSS opens a connection to the SQLite database
   1206     // during NSS initialization and doesn't close the connection until NSS
   1207     // shuts down.  If the file system where the database resides is gone,
   1208     // the database connection goes bad.  What's worse, the connection won't
   1209     // recover when the file system comes back.  Until this NSS or SQLite bug
   1210     // is fixed, we need to  avoid using the NSS database for non-essential
   1211     // purposes.  See https://bugzilla.mozilla.org/show_bug.cgi?id=508081 and
   1212     // http://crbug.com/15630 for more info.
   1213     CERTCertList* cert_list = CERT_GetCertChainFromCert(
   1214         server_cert_nss_, PR_Now(), certUsageSSLCA);
   1215     if (cert_list) {
   1216       for (CERTCertListNode* node = CERT_LIST_HEAD(cert_list);
   1217            !CERT_LIST_END(node, cert_list);
   1218            node = CERT_LIST_NEXT(node)) {
   1219         if (node->cert->slot || node->cert->isRoot || node->cert->isperm ||
   1220             node->cert == server_cert_nss_) {
   1221           // Some certs we don't want to remember are:
   1222           // - found on a token.
   1223           // - the root cert.
   1224           // - already stored in perm db.
   1225           // - the server cert itself.
   1226           continue;
   1227         }
   1228 
   1229         // We have found a CA cert that we want to remember.
   1230         // TODO(wtc): Remember the intermediate CA certs in a std::set
   1231         // temporarily (http://crbug.com/15630).
   1232       }
   1233       CERT_DestroyCertList(cert_list);
   1234     }
   1235   }
   1236 
   1237   // If we have been explicitly told to accept this certificate, override the
   1238   // result of verifier_.Verify.
   1239   // Eventually, we should cache the cert verification results so that we don't
   1240   // need to call verifier_.Verify repeatedly.  But for now we need to do this.
   1241   // Alternatively, we could use the cert's status that we stored along with
   1242   // the cert in the allowed_bad_certs vector.
   1243   if (IsCertificateError(result) &&
   1244       ssl_config_.IsAllowedBadCert(server_cert_)) {
   1245     LOG(INFO) << "accepting bad SSL certificate, as user told us to";
   1246     result = OK;
   1247   }
   1248 
   1249   completed_handshake_ = true;
   1250   // TODO(ukai): we may not need this call because it is now harmless to have an
   1251   // session with a bad cert.
   1252   InvalidateSessionIfBadCertificate();
   1253   // Exit DoHandshakeLoop and return the result to the caller to Connect.
   1254   DCHECK(next_handshake_state_ == STATE_NONE);
   1255   return result;
   1256 }
   1257 
   1258 int SSLClientSocketNSS::DoPayloadRead() {
   1259   EnterFunction(user_read_buf_len_);
   1260   DCHECK(user_read_buf_);
   1261   DCHECK(user_read_buf_len_ > 0);
   1262   int rv = PR_Read(nss_fd_, user_read_buf_->data(), user_read_buf_len_);
   1263   if (client_auth_cert_needed_) {
   1264     // We don't need to invalidate the non-client-authenticated SSL session
   1265     // because the server will renegotiate anyway.
   1266     LeaveFunction("");
   1267     return ERR_SSL_CLIENT_AUTH_CERT_NEEDED;
   1268   }
   1269   if (rv >= 0) {
   1270     LogData(user_read_buf_->data(), rv);
   1271     LeaveFunction("");
   1272     return rv;
   1273   }
   1274   PRErrorCode prerr = PR_GetError();
   1275   if (prerr == PR_WOULD_BLOCK_ERROR) {
   1276     LeaveFunction("");
   1277     return ERR_IO_PENDING;
   1278   }
   1279   LeaveFunction("");
   1280   return MapNSPRError(prerr);
   1281 }
   1282 
   1283 int SSLClientSocketNSS::DoPayloadWrite() {
   1284   EnterFunction(user_write_buf_len_);
   1285   DCHECK(user_write_buf_);
   1286   int rv = PR_Write(nss_fd_, user_write_buf_->data(), user_write_buf_len_);
   1287   if (rv >= 0) {
   1288     LogData(user_write_buf_->data(), rv);
   1289     LeaveFunction("");
   1290     return rv;
   1291   }
   1292   PRErrorCode prerr = PR_GetError();
   1293   if (prerr == PR_WOULD_BLOCK_ERROR) {
   1294     return ERR_IO_PENDING;
   1295   }
   1296   LeaveFunction("");
   1297   return MapNSPRError(prerr);
   1298 }
   1299 
   1300 }  // namespace net
   1301