• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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@netscape.com>
31  *   Javier Delgadillo <javi@netscape.com>
32  *   Kai Engert <kengert@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:
NSSSSLInitSingleton()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 
~NSSSSLInitSingleton()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.
EnsureNSSSSLInit()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.
MapNSPRError(PRErrorCode err)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 
MapHandshakeError(PRErrorCode err)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 
SSLClientSocketNSS(ClientSocket * transport_socket,const std::string & hostname,const SSLConfig & ssl_config)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 
~SSLClientSocketNSS()249 SSLClientSocketNSS::~SSLClientSocketNSS() {
250   EnterFunction("");
251   Disconnect();
252   LeaveFunction("");
253 }
254 
Init()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 
Connect(CompletionCallback * callback,LoadLog * load_log)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 
InitializeSSLOptions()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 
InvalidateSessionIfBadCertificate()445 void SSLClientSocketNSS::InvalidateSessionIfBadCertificate() {
446   if (UpdateServerCert() != NULL &&
447       ssl_config_.IsAllowedBadCert(server_cert_)) {
448     SSL_InvalidateSession(nss_fd_);
449   }
450 }
451 
Disconnect()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 
IsConnected() const491 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 
IsConnectedAndIdle() const504 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 
GetPeerName(struct sockaddr * name,socklen_t * namelen)518 int SSLClientSocketNSS::GetPeerName(struct sockaddr* name, socklen_t* namelen) {
519   return transport_->GetPeerName(name, namelen);
520 }
521 
Read(IOBuffer * buf,int buf_len,CompletionCallback * callback)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 
Write(IOBuffer * buf,int buf_len,CompletionCallback * callback)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 
SetReceiveBufferSize(int32 size)572 bool SSLClientSocketNSS::SetReceiveBufferSize(int32 size) {
573   return transport_->SetReceiveBufferSize(size);
574 }
575 
SetSendBufferSize(int32 size)576 bool SSLClientSocketNSS::SetSendBufferSize(int32 size) {
577   return transport_->SetSendBufferSize(size);
578 }
579 
UpdateServerCert()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 
GetSSLInfo(SSLInfo * ssl_info)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 
GetSSLCertRequestInfo(SSLCertRequestInfo * cert_request_info)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
GetNextProto(std::string * proto)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 
DoReadCallback(int rv)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 
DoWriteCallback(int rv)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 //
DoConnectCallback(int rv)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 
OnHandshakeIOComplete(int result)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 
OnSendComplete(int result)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 
OnRecvComplete(int result)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.
MapErrorToNSS(int result)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)
DoTransportIO()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).
BufferSend(void)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 
BufferSendComplete(int result)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 
BufferRecv(void)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 
BufferRecvComplete(int result)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 
DoHandshakeLoop(int last_io_result)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 
DoReadLoop(int result)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 
DoWriteLoop(int result)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.
OwnAuthCertHandler(void * arg,PRFileDesc * socket,PRBool checksig,PRBool is_server)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.
ClientAuthHandler(void * arg,PRFileDesc * socket,CERTDistNames * ca_names,CERTCertificate ** result_certificate,SECKEYPrivateKey ** result_private_key)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.
HandshakeCallback(PRFileDesc * socket,void * arg)1138 void SSLClientSocketNSS::HandshakeCallback(PRFileDesc* socket,
1139                                            void* arg) {
1140   SSLClientSocketNSS* that = reinterpret_cast<SSLClientSocketNSS*>(arg);
1141 
1142   that->UpdateServerCert();
1143 }
1144 
DoHandshake()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 
DoVerifyCert(int result)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.
DoVerifyCertComplete(int result)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 
DoPayloadRead()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 
DoPayloadWrite()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