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