Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(149)

Side by Side Diff: net/socket/ssl_client_socket_nss.cc

Issue 255074: Make SSLClientSocketNSS full-duplex (Closed)
Patch Set: fix wtc comment Created 11 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « net/socket/ssl_client_socket_nss.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2006-2009 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // This file includes code GetDefaultCertNickname(), derived from 5 // This file includes code GetDefaultCertNickname(), derived from
6 // nsNSSCertificate::defaultServerNickName() 6 // nsNSSCertificate::defaultServerNickName()
7 // in mozilla/security/manager/ssl/src/nsNSSCertificate.cpp 7 // in mozilla/security/manager/ssl/src/nsNSSCertificate.cpp
8 // and SSLClientSocketNSS::DoVerifyCertComplete() derived from 8 // and SSLClientSocketNSS::DoVerifyCertComplete() derived from
9 // AuthCertificateCallback() in 9 // AuthCertificateCallback() in
10 // mozilla/security/manager/ssl/src/nsNSSCallbacks.cpp. 10 // mozilla/security/manager/ssl/src/nsNSSCallbacks.cpp.
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
74 74
75 static const int kRecvBufferSize = 4096; 75 static const int kRecvBufferSize = 4096;
76 76
77 namespace net { 77 namespace net {
78 78
79 // State machines are easier to debug if you log state transitions. 79 // State machines are easier to debug if you log state transitions.
80 // Enable these if you want to see what's going on. 80 // Enable these if you want to see what's going on.
81 #if 1 81 #if 1
82 #define EnterFunction(x) 82 #define EnterFunction(x)
83 #define LeaveFunction(x) 83 #define LeaveFunction(x)
84 #define GotoState(s) next_state_ = s 84 #define GotoState(s) next_handshake_state_ = s
85 #define LogData(s, len) 85 #define LogData(s, len)
86 #else 86 #else
87 #define EnterFunction(x) LOG(INFO) << (void *)this << " " << __FUNCTION__ << \ 87 #define EnterFunction(x) LOG(INFO) << (void *)this << " " << __FUNCTION__ << \
88 " enter " << x << "; next_state " << next_state_ 88 " enter " << x << \
89 "; next_handshake_state " << next_handshake_state_
89 #define LeaveFunction(x) LOG(INFO) << (void *)this << " " << __FUNCTION__ << \ 90 #define LeaveFunction(x) LOG(INFO) << (void *)this << " " << __FUNCTION__ << \
90 " leave " << x << "; next_state " << next_state_ 91 " leave " << x << \
92 "; next_handshake_state " << next_handshake_state_
91 #define GotoState(s) do { LOG(INFO) << (void *)this << " " << __FUNCTION__ << \ 93 #define GotoState(s) do { LOG(INFO) << (void *)this << " " << __FUNCTION__ << \
92 " jump to state " << s; next_state_ = s; } while (0) 94 " jump to state " << s; \
95 next_handshake_state_ = s; } while (0)
93 #define LogData(s, len) LOG(INFO) << (void *)this << " " << __FUNCTION__ << \ 96 #define LogData(s, len) LOG(INFO) << (void *)this << " " << __FUNCTION__ << \
94 " data [" << std::string(s, len) << "]"; 97 " data [" << std::string(s, len) << "]";
95 98
96 #endif 99 #endif
97 100
98 namespace { 101 namespace {
99 102
100 // Gets default certificate nickname from cert. 103 // Gets default certificate nickname from cert.
101 // Derived from nsNSSCertificate::defaultServerNickname 104 // Derived from nsNSSCertificate::defaultServerNickname
102 // in mozilla/security/manager/ssl/src/nsNSSCertificate.cpp. 105 // in mozilla/security/manager/ssl/src/nsNSSCertificate.cpp.
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
186 bool SSLClientSocketNSS::nss_options_initialized_ = false; 189 bool SSLClientSocketNSS::nss_options_initialized_ = false;
187 190
188 SSLClientSocketNSS::SSLClientSocketNSS(ClientSocket* transport_socket, 191 SSLClientSocketNSS::SSLClientSocketNSS(ClientSocket* transport_socket,
189 const std::string& hostname, 192 const std::string& hostname,
190 const SSLConfig& ssl_config) 193 const SSLConfig& ssl_config)
191 : 194 :
192 buffer_send_callback_(this, &SSLClientSocketNSS::BufferSendComplete), 195 buffer_send_callback_(this, &SSLClientSocketNSS::BufferSendComplete),
193 buffer_recv_callback_(this, &SSLClientSocketNSS::BufferRecvComplete), 196 buffer_recv_callback_(this, &SSLClientSocketNSS::BufferRecvComplete),
194 transport_send_busy_(false), 197 transport_send_busy_(false),
195 transport_recv_busy_(false), 198 transport_recv_busy_(false),
196 io_callback_(this, &SSLClientSocketNSS::OnIOComplete), 199 handshake_io_callback_(this, &SSLClientSocketNSS::OnHandshakeIOComplete),
197 transport_(transport_socket), 200 transport_(transport_socket),
198 hostname_(hostname), 201 hostname_(hostname),
199 ssl_config_(ssl_config), 202 ssl_config_(ssl_config),
200 user_connect_callback_(NULL), 203 user_connect_callback_(NULL),
201 user_callback_(NULL), 204 user_read_callback_(NULL),
202 user_buf_len_(0), 205 user_write_callback_(NULL),
206 user_read_buf_len_(0),
207 user_write_buf_len_(0),
203 completed_handshake_(false), 208 completed_handshake_(false),
204 next_state_(STATE_NONE), 209 next_handshake_state_(STATE_NONE),
205 nss_fd_(NULL), 210 nss_fd_(NULL),
206 nss_bufs_(NULL) { 211 nss_bufs_(NULL) {
207 EnterFunction(""); 212 EnterFunction("");
208 } 213 }
209 214
210 SSLClientSocketNSS::~SSLClientSocketNSS() { 215 SSLClientSocketNSS::~SSLClientSocketNSS() {
211 EnterFunction(""); 216 EnterFunction("");
212 Disconnect(); 217 Disconnect();
213 LeaveFunction(""); 218 LeaveFunction("");
214 } 219 }
215 220
216 int SSLClientSocketNSS::Init() { 221 int SSLClientSocketNSS::Init() {
217 EnterFunction(""); 222 EnterFunction("");
218 // Initialize NSS in a threadsafe way. 223 // Initialize NSS in a threadsafe way.
219 base::EnsureNSSInit(); 224 base::EnsureNSSInit();
220 // We must call EnsureOCSPInit() here, on the IO thread, to get the IO loop 225 // We must call EnsureOCSPInit() here, on the IO thread, to get the IO loop
221 // by MessageLoopForIO::current(). 226 // by MessageLoopForIO::current().
222 // X509Certificate::Verify() runs on a worker thread of CertVerifier. 227 // X509Certificate::Verify() runs on a worker thread of CertVerifier.
223 EnsureOCSPInit(); 228 EnsureOCSPInit();
224 229
225 LeaveFunction(""); 230 LeaveFunction("");
226 return OK; 231 return OK;
227 } 232 }
228 233
229 int SSLClientSocketNSS::Connect(CompletionCallback* callback) { 234 int SSLClientSocketNSS::Connect(CompletionCallback* callback) {
230 EnterFunction(""); 235 EnterFunction("");
231 DCHECK(transport_.get()); 236 DCHECK(transport_.get());
232 DCHECK(next_state_ == STATE_NONE); 237 DCHECK(next_handshake_state_ == STATE_NONE);
233 DCHECK(!user_callback_); 238 DCHECK(!user_read_callback_);
239 DCHECK(!user_write_callback_);
234 DCHECK(!user_connect_callback_); 240 DCHECK(!user_connect_callback_);
235 DCHECK(!user_buf_); 241 DCHECK(!user_read_buf_);
242 DCHECK(!user_write_buf_);
236 243
237 if (Init() != OK) { 244 if (Init() != OK) {
238 NOTREACHED() << "Couldn't initialize nss"; 245 NOTREACHED() << "Couldn't initialize nss";
239 } 246 }
240 247
241 // Transport connected, now hook it up to nss 248 // Transport connected, now hook it up to nss
242 // TODO(port): specify rx and tx buffer sizes separately 249 // TODO(port): specify rx and tx buffer sizes separately
243 nss_fd_ = memio_CreateIOLayer(kRecvBufferSize); 250 nss_fd_ = memio_CreateIOLayer(kRecvBufferSize);
244 if (nss_fd_ == NULL) { 251 if (nss_fd_ == NULL) {
245 return 9999; // TODO(port): real error 252 return 9999; // TODO(port): real error
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
314 rv = SSL_HandshakeCallback(nss_fd_, HandshakeCallback, this); 321 rv = SSL_HandshakeCallback(nss_fd_, HandshakeCallback, this);
315 if (rv != SECSuccess) 322 if (rv != SECSuccess)
316 return ERR_UNEXPECTED; 323 return ERR_UNEXPECTED;
317 324
318 // Tell SSL the hostname we're trying to connect to. 325 // Tell SSL the hostname we're trying to connect to.
319 SSL_SetURL(nss_fd_, hostname_.c_str()); 326 SSL_SetURL(nss_fd_, hostname_.c_str());
320 327
321 // Tell SSL we're a client; needed if not letting NSPR do socket I/O 328 // Tell SSL we're a client; needed if not letting NSPR do socket I/O
322 SSL_ResetHandshake(nss_fd_, 0); 329 SSL_ResetHandshake(nss_fd_, 0);
323 330
324 GotoState(STATE_HANDSHAKE_READ); 331 GotoState(STATE_HANDSHAKE);
325 rv = DoLoop(OK); 332 rv = DoHandshakeLoop(OK);
326 if (rv == ERR_IO_PENDING) 333 if (rv == ERR_IO_PENDING)
327 user_connect_callback_ = callback; 334 user_connect_callback_ = callback;
328 335
329 LeaveFunction(""); 336 LeaveFunction("");
330 return rv > OK ? OK : rv; 337 return rv > OK ? OK : rv;
331 } 338 }
332 339
333 void SSLClientSocketNSS::InvalidateSessionIfBadCertificate() { 340 void SSLClientSocketNSS::InvalidateSessionIfBadCertificate() {
334 if (UpdateServerCert() != NULL && 341 if (UpdateServerCert() != NULL &&
335 ssl_config_.IsAllowedBadCert(server_cert_)) { 342 ssl_config_.IsAllowedBadCert(server_cert_)) {
336 SSL_InvalidateSession(nss_fd_); 343 SSL_InvalidateSession(nss_fd_);
337 } 344 }
338 } 345 }
339 346
340 void SSLClientSocketNSS::Disconnect() { 347 void SSLClientSocketNSS::Disconnect() {
341 EnterFunction(""); 348 EnterFunction("");
342 349
343 // TODO(wtc): Send SSL close_notify alert. 350 // TODO(wtc): Send SSL close_notify alert.
344 if (nss_fd_ != NULL) { 351 if (nss_fd_ != NULL) {
345 InvalidateSessionIfBadCertificate(); 352 InvalidateSessionIfBadCertificate();
346 PR_Close(nss_fd_); 353 PR_Close(nss_fd_);
347 nss_fd_ = NULL; 354 nss_fd_ = NULL;
348 } 355 }
349 356
350 // Shut down anything that may call us back (through buffer_send_callback_, 357 // Shut down anything that may call us back (through buffer_send_callback_,
351 // buffer_recv_callback, or io_callback_). 358 // buffer_recv_callback, or handshake_io_callback_).
352 verifier_.reset(); 359 verifier_.reset();
353 transport_->Disconnect(); 360 transport_->Disconnect();
354 361
355 // Reset object state 362 // Reset object state
356 transport_send_busy_ = false; 363 transport_send_busy_ = false;
357 transport_recv_busy_ = false; 364 transport_recv_busy_ = false;
358 user_connect_callback_ = NULL; 365 user_connect_callback_ = NULL;
359 user_callback_ = NULL; 366 user_read_callback_ = NULL;
360 user_buf_ = NULL; 367 user_write_callback_ = NULL;
361 user_buf_len_ = 0; 368 user_read_buf_ = NULL;
369 user_read_buf_len_ = 0;
370 user_write_buf_ = NULL;
371 user_write_buf_len_ = 0;
362 server_cert_ = NULL; 372 server_cert_ = NULL;
363 server_cert_verify_result_.Reset(); 373 server_cert_verify_result_.Reset();
364 completed_handshake_ = false; 374 completed_handshake_ = false;
365 nss_bufs_ = NULL; 375 nss_bufs_ = NULL;
366 376
367 LeaveFunction(""); 377 LeaveFunction("");
368 } 378 }
369 379
370 bool SSLClientSocketNSS::IsConnected() const { 380 bool SSLClientSocketNSS::IsConnected() const {
371 // Ideally, we should also check if we have received the close_notify alert 381 // Ideally, we should also check if we have received the close_notify alert
(...skipping 19 matching lines...) Expand all
391 EnterFunction(""); 401 EnterFunction("");
392 bool ret = completed_handshake_ && transport_->IsConnectedAndIdle(); 402 bool ret = completed_handshake_ && transport_->IsConnectedAndIdle();
393 LeaveFunction(""); 403 LeaveFunction("");
394 return ret; 404 return ret;
395 } 405 }
396 406
397 int SSLClientSocketNSS::Read(IOBuffer* buf, int buf_len, 407 int SSLClientSocketNSS::Read(IOBuffer* buf, int buf_len,
398 CompletionCallback* callback) { 408 CompletionCallback* callback) {
399 EnterFunction(buf_len); 409 EnterFunction(buf_len);
400 DCHECK(completed_handshake_); 410 DCHECK(completed_handshake_);
401 DCHECK(next_state_ == STATE_NONE); 411 DCHECK(next_handshake_state_ == STATE_NONE);
402 DCHECK(!user_callback_); 412 DCHECK(!user_read_callback_);
403 DCHECK(!user_connect_callback_); 413 DCHECK(!user_connect_callback_);
404 DCHECK(!user_buf_); 414 DCHECK(!user_read_buf_);
415 DCHECK(nss_bufs_);
405 416
406 user_buf_ = buf; 417 user_read_buf_ = buf;
407 user_buf_len_ = buf_len; 418 user_read_buf_len_ = buf_len;
408 419
409 GotoState(STATE_PAYLOAD_READ); 420 int rv = DoReadLoop(OK);
410 int rv = DoLoop(OK); 421
411 if (rv == ERR_IO_PENDING) 422 if (rv == ERR_IO_PENDING)
wtc 2009/10/14 01:54:15 Please add braces {} to "if" when "else" has brace
412 user_callback_ = callback; 423 user_read_callback_ = callback;
424 else {
425 user_read_buf_ = NULL;
426 user_read_buf_len_ = 0;
427 }
413 LeaveFunction(rv); 428 LeaveFunction(rv);
414 return rv; 429 return rv;
415 } 430 }
416 431
417 int SSLClientSocketNSS::Write(IOBuffer* buf, int buf_len, 432 int SSLClientSocketNSS::Write(IOBuffer* buf, int buf_len,
418 CompletionCallback* callback) { 433 CompletionCallback* callback) {
419 EnterFunction(buf_len); 434 EnterFunction(buf_len);
420 DCHECK(completed_handshake_); 435 DCHECK(completed_handshake_);
421 DCHECK(next_state_ == STATE_NONE); 436 DCHECK(next_handshake_state_ == STATE_NONE);
422 DCHECK(!user_callback_); 437 DCHECK(!user_write_callback_);
423 DCHECK(!user_connect_callback_); 438 DCHECK(!user_connect_callback_);
424 DCHECK(!user_buf_); 439 DCHECK(!user_write_buf_);
440 DCHECK(nss_bufs_);
425 441
426 user_buf_ = buf; 442 user_write_buf_ = buf;
427 user_buf_len_ = buf_len; 443 user_write_buf_len_ = buf_len;
428 444
429 GotoState(STATE_PAYLOAD_WRITE); 445 int rv = DoWriteLoop(OK);
430 int rv = DoLoop(OK); 446
431 if (rv == ERR_IO_PENDING) 447 if (rv == ERR_IO_PENDING)
432 user_callback_ = callback; 448 user_write_callback_ = callback;
wtc 2009/10/14 01:54:15 Same here: both "if" and "else" should have braces
449 else {
450 user_write_buf_ = NULL;
451 user_write_buf_len_ = 0;
452 }
433 LeaveFunction(rv); 453 LeaveFunction(rv);
434 return rv; 454 return rv;
435 } 455 }
436 456
437 bool SSLClientSocketNSS::SetReceiveBufferSize(int32 size) { 457 bool SSLClientSocketNSS::SetReceiveBufferSize(int32 size) {
438 return transport_->SetReceiveBufferSize(size); 458 return transport_->SetReceiveBufferSize(size);
439 } 459 }
440 460
441 bool SSLClientSocketNSS::SetSendBufferSize(int32 size) { 461 bool SSLClientSocketNSS::SetSendBufferSize(int32 size) {
442 return transport_->SetSendBufferSize(size); 462 return transport_->SetSendBufferSize(size);
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
484 DCHECK(server_cert_ != NULL); 504 DCHECK(server_cert_ != NULL);
485 ssl_info->cert = server_cert_; 505 ssl_info->cert = server_cert_;
486 LeaveFunction(""); 506 LeaveFunction("");
487 } 507 }
488 508
489 void SSLClientSocketNSS::GetSSLCertRequestInfo( 509 void SSLClientSocketNSS::GetSSLCertRequestInfo(
490 SSLCertRequestInfo* cert_request_info) { 510 SSLCertRequestInfo* cert_request_info) {
491 // TODO(wtc): implement this. 511 // TODO(wtc): implement this.
492 } 512 }
493 513
494 void SSLClientSocketNSS::DoCallback(int rv) { 514 void SSLClientSocketNSS::DoReadCallback(int rv) {
495 EnterFunction(rv); 515 EnterFunction(rv);
496 DCHECK(rv != ERR_IO_PENDING); 516 DCHECK(rv != ERR_IO_PENDING);
497 DCHECK(user_callback_); 517 DCHECK(user_read_callback_);
498 518
499 // Since Run may result in Read being called, clear |user_callback_| up front. 519 // Since Run may result in Read being called, clear |user_read_callback_|
500 CompletionCallback* c = user_callback_; 520 // up front.
501 user_callback_ = NULL; 521 CompletionCallback* c = user_read_callback_;
502 user_buf_ = NULL; 522 user_read_callback_ = NULL;
523 user_read_buf_ = NULL;
524 user_read_buf_len_ = 0;
503 c->Run(rv); 525 c->Run(rv);
504 LeaveFunction(""); 526 LeaveFunction("");
505 } 527 }
528
529 void SSLClientSocketNSS::DoWriteCallback(int rv) {
530 EnterFunction(rv);
531 DCHECK(rv != ERR_IO_PENDING);
532 DCHECK(user_write_callback_);
533
534 // Since Run may result in Write being called, clear |user_write_callback_|
535 // up front.
536 CompletionCallback* c = user_write_callback_;
537 user_write_callback_ = NULL;
538 user_write_buf_ = NULL;
539 user_write_buf_len_ = 0;
540 c->Run(rv);
541 LeaveFunction("");
542 }
506 543
507 // As part of Connect(), the SSLClientSocketNSS object performs an SSL 544 // As part of Connect(), the SSLClientSocketNSS object performs an SSL
508 // handshake. This requires network IO, which in turn calls 545 // handshake. This requires network IO, which in turn calls
509 // BufferRecvComplete() with a non-zero byte count. This byte count eventually 546 // BufferRecvComplete() with a non-zero byte count. This byte count eventually
510 // winds its way through the state machine and ends up being passed to the 547 // winds its way through the state machine and ends up being passed to the
511 // callback. For Read() and Write(), that's what we want. But for Connect(), 548 // callback. For Read() and Write(), that's what we want. But for Connect(),
512 // the caller expects OK (i.e. 0) for success. 549 // the caller expects OK (i.e. 0) for success.
513 // 550 //
514 void SSLClientSocketNSS::DoConnectCallback(int rv) { 551 void SSLClientSocketNSS::DoConnectCallback(int rv) {
515 EnterFunction(rv); 552 EnterFunction(rv);
516 DCHECK_NE(rv, ERR_IO_PENDING); 553 DCHECK_NE(rv, ERR_IO_PENDING);
517 DCHECK(user_connect_callback_); 554 DCHECK(user_connect_callback_);
518 555
519 // Since Run may result in Read being called, clear |user_connect_callback_|
520 // up front.
521 CompletionCallback* c = user_connect_callback_; 556 CompletionCallback* c = user_connect_callback_;
522 user_connect_callback_ = NULL; 557 user_connect_callback_ = NULL;
523 c->Run(rv > OK ? OK : rv); 558 c->Run(rv > OK ? OK : rv);
524 LeaveFunction(""); 559 LeaveFunction("");
525 } 560 }
526 561
527 void SSLClientSocketNSS::OnIOComplete(int result) { 562 void SSLClientSocketNSS::OnHandshakeIOComplete(int result) {
528 EnterFunction(result); 563 EnterFunction(result);
529 int rv = DoLoop(result); 564 int rv = DoHandshakeLoop(result);
530 if (rv != ERR_IO_PENDING) { 565 if (rv != ERR_IO_PENDING)
531 if (user_callback_) { 566 DoConnectCallback(rv);
532 DoCallback(rv);
533 } else if (user_connect_callback_) {
534 DoConnectCallback(rv);
535 }
536 }
537 LeaveFunction(""); 567 LeaveFunction("");
538 } 568 }
539 569
570 void SSLClientSocketNSS::OnSendComplete(int result) {
571 EnterFunction(result);
572 if (next_handshake_state_ != STATE_NONE) {
573 // In handshake phase.
574 OnHandshakeIOComplete(result);
575 LeaveFunction("");
576 return;
577 }
578
579 // OnSendComplete may need to call DoPayloadRead while the renegotiation
580 // handshake is in progress.
581 int rv_read = ERR_IO_PENDING;
582 int rv_write = ERR_IO_PENDING;
583 bool network_moved;
584 do {
585 if (user_read_buf_)
586 rv_read = DoPayloadRead();
587 if (user_write_buf_)
588 rv_write = DoPayloadWrite();
589 network_moved = DoTransportIO();
590 } while (rv_read == ERR_IO_PENDING &&
591 rv_write == ERR_IO_PENDING &&
592 network_moved);
593
594 if (user_read_buf_ && rv_read != ERR_IO_PENDING)
595 DoReadCallback(rv_read);
596 if (user_write_buf_ && rv_write != ERR_IO_PENDING)
597 DoWriteCallback(rv_write);
598
599 LeaveFunction("");
600 }
601
602 void SSLClientSocketNSS::OnRecvComplete(int result) {
603 EnterFunction(result);
604 if (next_handshake_state_ != STATE_NONE) {
605 // In handshake phase.
606 OnHandshakeIOComplete(result);
607 LeaveFunction("");
608 return;
609 }
610
611 // Network layer received some data, check if client requested to read
612 // decrypted data.
613 if (!user_read_buf_) {
614 LeaveFunction("");
615 return;
616 }
617
618 int rv = DoReadLoop(result);
619 if (rv != ERR_IO_PENDING)
620 DoReadCallback(rv);
621 LeaveFunction("");
622 }
623
540 // Map a Chromium net error code to an NSS error code 624 // Map a Chromium net error code to an NSS error code
541 // See _MD_unix_map_default_error in the NSS source 625 // See _MD_unix_map_default_error in the NSS source
542 // tree for inspiration. 626 // tree for inspiration.
543 static PRErrorCode MapErrorToNSS(int result) { 627 static PRErrorCode MapErrorToNSS(int result) {
544 if (result >=0) 628 if (result >=0)
545 return result; 629 return result;
546 // TODO(port): add real table 630 // TODO(port): add real table
547 LOG(ERROR) << "MapErrorToNSS " << result; 631 LOG(ERROR) << "MapErrorToNSS " << result;
548 return PR_UNKNOWN_ERROR; 632 return PR_UNKNOWN_ERROR;
549 } 633 }
550 634
551 // Do network I/O between the given buffer and the given socket. 635 // Do network I/O between the given buffer and the given socket.
636 // Return true if some I/O performed, false otherwise (error or ERR_IO_PENDING)
637 bool SSLClientSocketNSS::DoTransportIO() {
638 EnterFunction("");
639 bool network_moved = false;
640 if (nss_bufs_ != NULL) {
641 int nsent = BufferSend();
642 int nreceived = BufferRecv();
643 network_moved = (nsent > 0 || nreceived >= 0);
644 }
645 LeaveFunction(network_moved);
646 return network_moved;
647 }
648
552 // Return 0 for EOF, 649 // Return 0 for EOF,
553 // > 0 for bytes transferred immediately, 650 // > 0 for bytes transferred immediately,
554 // < 0 for error (or the non-error ERR_IO_PENDING). 651 // < 0 for error (or the non-error ERR_IO_PENDING).
555 int SSLClientSocketNSS::BufferSend(void) { 652 int SSLClientSocketNSS::BufferSend(void) {
556 if (transport_send_busy_) return ERR_IO_PENDING; 653 if (transport_send_busy_) return ERR_IO_PENDING;
557 654
558 const char *buf; 655 const char *buf;
559 int nb = memio_GetWriteParams(nss_bufs_, &buf); 656 int nb = memio_GetWriteParams(nss_bufs_, &buf);
560 EnterFunction(nb); 657 EnterFunction(nb);
561 658
(...skipping 11 matching lines...) Expand all
573 } 670 }
574 671
575 LeaveFunction(rv); 672 LeaveFunction(rv);
576 return rv; 673 return rv;
577 } 674 }
578 675
579 void SSLClientSocketNSS::BufferSendComplete(int result) { 676 void SSLClientSocketNSS::BufferSendComplete(int result) {
580 EnterFunction(result); 677 EnterFunction(result);
581 memio_PutWriteResult(nss_bufs_, result); 678 memio_PutWriteResult(nss_bufs_, result);
582 transport_send_busy_ = false; 679 transport_send_busy_ = false;
583 OnIOComplete(result); 680 OnSendComplete(result);
584 LeaveFunction(""); 681 LeaveFunction("");
585 } 682 }
586 683
587 684
588 int SSLClientSocketNSS::BufferRecv(void) { 685 int SSLClientSocketNSS::BufferRecv(void) {
589 if (transport_recv_busy_) return ERR_IO_PENDING; 686 if (transport_recv_busy_) return ERR_IO_PENDING;
590 687
591 char *buf; 688 char *buf;
592 int nb = memio_GetReadParams(nss_bufs_, &buf); 689 int nb = memio_GetReadParams(nss_bufs_, &buf);
593 EnterFunction(nb); 690 EnterFunction(nb);
(...skipping 20 matching lines...) Expand all
614 void SSLClientSocketNSS::BufferRecvComplete(int result) { 711 void SSLClientSocketNSS::BufferRecvComplete(int result) {
615 EnterFunction(result); 712 EnterFunction(result);
616 if (result > 0) { 713 if (result > 0) {
617 char *buf; 714 char *buf;
618 memio_GetReadParams(nss_bufs_, &buf); 715 memio_GetReadParams(nss_bufs_, &buf);
619 memcpy(buf, recv_buffer_->data(), result); 716 memcpy(buf, recv_buffer_->data(), result);
620 } 717 }
621 recv_buffer_ = NULL; 718 recv_buffer_ = NULL;
622 memio_PutReadResult(nss_bufs_, result); 719 memio_PutReadResult(nss_bufs_, result);
623 transport_recv_busy_ = false; 720 transport_recv_busy_ = false;
624 OnIOComplete(result); 721 OnRecvComplete(result);
625 LeaveFunction(""); 722 LeaveFunction("");
626 } 723 }
627 724
628 int SSLClientSocketNSS::DoLoop(int last_io_result) { 725 int SSLClientSocketNSS::DoHandshakeLoop(int last_io_result) {
629 EnterFunction(last_io_result); 726 EnterFunction(last_io_result);
630 bool network_moved; 727 bool network_moved;
631 int rv = last_io_result; 728 int rv = last_io_result;
632 do { 729 do {
633 network_moved = false;
634 // Default to STATE_NONE for next state. 730 // Default to STATE_NONE for next state.
635 // (This is a quirk carried over from the windows 731 // (This is a quirk carried over from the windows
636 // implementation. It makes reading the logs a bit harder.) 732 // implementation. It makes reading the logs a bit harder.)
637 // State handlers can and often do call GotoState just 733 // State handlers can and often do call GotoState just
638 // to stay in the current state. 734 // to stay in the current state.
639 State state = next_state_; 735 State state = next_handshake_state_;
640 GotoState(STATE_NONE); 736 GotoState(STATE_NONE);
641 switch (state) { 737 switch (state) {
642 case STATE_NONE: 738 case STATE_NONE:
643 // we're just pumping data between the buffer and the network 739 // we're just pumping data between the buffer and the network
644 break; 740 break;
645 case STATE_HANDSHAKE_READ: 741 case STATE_HANDSHAKE:
646 rv = DoHandshakeRead(); 742 rv = DoHandshake();
647 break; 743 break;
648 case STATE_VERIFY_CERT: 744 case STATE_VERIFY_CERT:
649 DCHECK(rv == OK); 745 DCHECK(rv == OK);
650 rv = DoVerifyCert(rv); 746 rv = DoVerifyCert(rv);
651 break; 747 break;
652 case STATE_VERIFY_CERT_COMPLETE: 748 case STATE_VERIFY_CERT_COMPLETE:
653 rv = DoVerifyCertComplete(rv); 749 rv = DoVerifyCertComplete(rv);
654 break; 750 break;
655 case STATE_PAYLOAD_READ:
656 rv = DoPayloadRead();
657 break;
658 case STATE_PAYLOAD_WRITE:
659 rv = DoPayloadWrite();
660 break;
661 default: 751 default:
662 rv = ERR_UNEXPECTED; 752 rv = ERR_UNEXPECTED;
663 NOTREACHED() << "unexpected state"; 753 NOTREACHED() << "unexpected state";
664 break; 754 break;
665 } 755 }
666 756
667 // Do the actual network I/O 757 // Do the actual network I/O
668 if (nss_bufs_ != NULL) { 758 network_moved = DoTransportIO();
669 int nsent = BufferSend();
670 int nreceived = BufferRecv();
671 network_moved = (nsent > 0 || nreceived >= 0);
672 }
673 } while ((rv != ERR_IO_PENDING || network_moved) && 759 } while ((rv != ERR_IO_PENDING || network_moved) &&
674 next_state_ != STATE_NONE); 760 next_handshake_state_ != STATE_NONE);
675 LeaveFunction(""); 761 LeaveFunction("");
676 return rv; 762 return rv;
677 } 763 }
764
765 int SSLClientSocketNSS::DoReadLoop(int result) {
766 EnterFunction("");
767 DCHECK(completed_handshake_);
768 DCHECK(next_handshake_state_ == STATE_NONE);
769
770 if (result < 0)
771 return result;
772
773 if (!nss_bufs_)
774 return ERR_UNEXPECTED;
775
776 bool network_moved;
777 int rv;
778 do {
779 rv = DoPayloadRead();
780 network_moved = DoTransportIO();
781 } while (rv == ERR_IO_PENDING && network_moved);
782
783 LeaveFunction("");
784 return rv;
785 }
786
787 int SSLClientSocketNSS::DoWriteLoop(int result) {
788 EnterFunction("");
789 DCHECK(completed_handshake_);
790 DCHECK(next_handshake_state_ == STATE_NONE);
791
792 if (result < 0)
793 return result;
794
795 if (!nss_bufs_)
796 return ERR_UNEXPECTED;
797
798 bool network_moved;
799 int rv;
800 do {
801 rv = DoPayloadWrite();
802 network_moved = DoTransportIO();
803 } while (rv == ERR_IO_PENDING && network_moved);
804
805 LeaveFunction("");
806 return rv;
807 }
678 808
679 // static 809 // static
680 // NSS calls this if an incoming certificate needs to be verified. 810 // NSS calls this if an incoming certificate needs to be verified.
681 // Do nothing but return SECSuccess. 811 // Do nothing but return SECSuccess.
682 // This is called only in full handshake mode. 812 // This is called only in full handshake mode.
683 // Peer certificate is retrieved in HandshakeCallback() later, which is called 813 // Peer certificate is retrieved in HandshakeCallback() later, which is called
684 // in full handshake mode or in resumption handshake mode. 814 // in full handshake mode or in resumption handshake mode.
685 SECStatus SSLClientSocketNSS::OwnAuthCertHandler(void* arg, 815 SECStatus SSLClientSocketNSS::OwnAuthCertHandler(void* arg,
686 PRFileDesc* socket, 816 PRFileDesc* socket,
687 PRBool checksig, 817 PRBool checksig,
688 PRBool is_server) { 818 PRBool is_server) {
689 // Tell NSS to not verify the certificate. 819 // Tell NSS to not verify the certificate.
690 return SECSuccess; 820 return SECSuccess;
691 } 821 }
692 822
693 // static 823 // static
694 // NSS calls this when handshake is completed. 824 // NSS calls this when handshake is completed.
695 // After the SSL handshake is finished, use CertVerifier to verify 825 // After the SSL handshake is finished, use CertVerifier to verify
696 // the saved server certificate. 826 // the saved server certificate.
697 void SSLClientSocketNSS::HandshakeCallback(PRFileDesc* socket, 827 void SSLClientSocketNSS::HandshakeCallback(PRFileDesc* socket,
698 void* arg) { 828 void* arg) {
699 SSLClientSocketNSS* that = reinterpret_cast<SSLClientSocketNSS*>(arg); 829 SSLClientSocketNSS* that = reinterpret_cast<SSLClientSocketNSS*>(arg);
700 830
701 that->UpdateServerCert(); 831 that->UpdateServerCert();
702 } 832 }
703 833
704 int SSLClientSocketNSS::DoHandshakeRead() { 834 int SSLClientSocketNSS::DoHandshake() {
705 EnterFunction(""); 835 EnterFunction("");
706 int net_error = net::OK; 836 int net_error = net::OK;
707 int rv = SSL_ForceHandshake(nss_fd_); 837 int rv = SSL_ForceHandshake(nss_fd_);
708 838
709 if (rv == SECSuccess) { 839 if (rv == SECSuccess) {
710 // SSL handshake is completed. Let's verify the certificate. 840 // SSL handshake is completed. Let's verify the certificate.
711 GotoState(STATE_VERIFY_CERT); 841 GotoState(STATE_VERIFY_CERT);
712 // Done! 842 // Done!
713 } else { 843 } else {
714 PRErrorCode prerr = PR_GetError(); 844 PRErrorCode prerr = PR_GetError();
715 845
716 // If the server closed on us, it is a protocol error. 846 // If the server closed on us, it is a protocol error.
717 // Some TLS-intolerant servers do this when we request TLS. 847 // Some TLS-intolerant servers do this when we request TLS.
718 if (prerr == PR_END_OF_FILE_ERROR) { 848 if (prerr == PR_END_OF_FILE_ERROR) {
719 net_error = ERR_SSL_PROTOCOL_ERROR; 849 net_error = ERR_SSL_PROTOCOL_ERROR;
720 } else { 850 } else {
721 net_error = NetErrorFromNSPRError(prerr); 851 net_error = NetErrorFromNSPRError(prerr);
722 } 852 }
723 853
724 // If not done, stay in this state 854 // If not done, stay in this state
725 if (net_error == ERR_IO_PENDING) { 855 if (net_error == ERR_IO_PENDING) {
726 GotoState(STATE_HANDSHAKE_READ); 856 GotoState(STATE_HANDSHAKE);
727 } else { 857 } else {
728 LOG(ERROR) << "handshake failed; NSS error code " << prerr 858 LOG(ERROR) << "handshake failed; NSS error code " << prerr
729 << ", net_error " << net_error; 859 << ", net_error " << net_error;
730 } 860 }
731 } 861 }
732 862
733 LeaveFunction(""); 863 LeaveFunction("");
734 return net_error; 864 return net_error;
735 } 865 }
736 866
737 int SSLClientSocketNSS::DoVerifyCert(int result) { 867 int SSLClientSocketNSS::DoVerifyCert(int result) {
738 DCHECK(server_cert_); 868 DCHECK(server_cert_);
739 GotoState(STATE_VERIFY_CERT_COMPLETE); 869 GotoState(STATE_VERIFY_CERT_COMPLETE);
740 int flags = 0; 870 int flags = 0;
741 if (ssl_config_.rev_checking_enabled) 871 if (ssl_config_.rev_checking_enabled)
742 flags |= X509Certificate::VERIFY_REV_CHECKING_ENABLED; 872 flags |= X509Certificate::VERIFY_REV_CHECKING_ENABLED;
743 if (ssl_config_.verify_ev_cert) 873 if (ssl_config_.verify_ev_cert)
744 flags |= X509Certificate::VERIFY_EV_CERT; 874 flags |= X509Certificate::VERIFY_EV_CERT;
745 verifier_.reset(new CertVerifier); 875 verifier_.reset(new CertVerifier);
746 return verifier_->Verify(server_cert_, hostname_, flags, 876 return verifier_->Verify(server_cert_, hostname_, flags,
747 &server_cert_verify_result_, &io_callback_); 877 &server_cert_verify_result_,
878 &handshake_io_callback_);
748 } 879 }
749 880
750 // Derived from AuthCertificateCallback() in 881 // Derived from AuthCertificateCallback() in
751 // mozilla/source/security/manager/ssl/src/nsNSSCallbacks.cpp. 882 // mozilla/source/security/manager/ssl/src/nsNSSCallbacks.cpp.
752 int SSLClientSocketNSS::DoVerifyCertComplete(int result) { 883 int SSLClientSocketNSS::DoVerifyCertComplete(int result) {
753 DCHECK(verifier_.get()); 884 DCHECK(verifier_.get());
754 verifier_.reset(); 885 verifier_.reset();
755 886
756 if (result == OK) { 887 if (result == OK) {
757 // Remember the intermediate CA certs if the server sends them to us. 888 // Remember the intermediate CA certs if the server sends them to us.
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
798 if (IsCertificateError(result) && 929 if (IsCertificateError(result) &&
799 ssl_config_.IsAllowedBadCert(server_cert_)) { 930 ssl_config_.IsAllowedBadCert(server_cert_)) {
800 LOG(INFO) << "accepting bad SSL certificate, as user told us to"; 931 LOG(INFO) << "accepting bad SSL certificate, as user told us to";
801 result = OK; 932 result = OK;
802 } 933 }
803 934
804 completed_handshake_ = true; 935 completed_handshake_ = true;
805 // TODO(ukai): we may not need this call because it is now harmless to have an 936 // TODO(ukai): we may not need this call because it is now harmless to have an
806 // session with a bad cert. 937 // session with a bad cert.
807 InvalidateSessionIfBadCertificate(); 938 InvalidateSessionIfBadCertificate();
808 // Exit DoLoop and return the result to the caller to Connect. 939 // Exit DoHandshakeLoop and return the result to the caller to Connect.
809 DCHECK(next_state_ == STATE_NONE); 940 DCHECK(next_handshake_state_ == STATE_NONE);
810 return result; 941 return result;
811 } 942 }
812 943
813 int SSLClientSocketNSS::DoPayloadRead() { 944 int SSLClientSocketNSS::DoPayloadRead() {
814 EnterFunction(user_buf_len_); 945 EnterFunction(user_read_buf_len_);
815 int rv = PR_Read(nss_fd_, user_buf_->data(), user_buf_len_); 946 DCHECK(user_read_buf_);
947 DCHECK(user_read_buf_len_ > 0);
948 int rv = PR_Read(nss_fd_, user_read_buf_->data(), user_read_buf_len_);
816 if (rv >= 0) { 949 if (rv >= 0) {
817 LogData(user_buf_->data(), rv); 950 LogData(user_read_buf_->data(), rv);
818 user_buf_ = NULL;
819 LeaveFunction(""); 951 LeaveFunction("");
820 return rv; 952 return rv;
821 } 953 }
822 PRErrorCode prerr = PR_GetError(); 954 PRErrorCode prerr = PR_GetError();
823 if (prerr == PR_WOULD_BLOCK_ERROR) { 955 if (prerr == PR_WOULD_BLOCK_ERROR) {
824 GotoState(STATE_PAYLOAD_READ);
825 LeaveFunction(""); 956 LeaveFunction("");
826 return ERR_IO_PENDING; 957 return ERR_IO_PENDING;
827 } 958 }
828 user_buf_ = NULL;
829 LeaveFunction(""); 959 LeaveFunction("");
830 return NetErrorFromNSPRError(prerr); 960 return NetErrorFromNSPRError(prerr);
831 } 961 }
832 962
833 int SSLClientSocketNSS::DoPayloadWrite() { 963 int SSLClientSocketNSS::DoPayloadWrite() {
834 EnterFunction(user_buf_len_); 964 EnterFunction(user_write_buf_len_);
835 int rv = PR_Write(nss_fd_, user_buf_->data(), user_buf_len_); 965 DCHECK(user_write_buf_);
966 int rv = PR_Write(nss_fd_, user_write_buf_->data(), user_write_buf_len_);
836 if (rv >= 0) { 967 if (rv >= 0) {
837 LogData(user_buf_->data(), rv); 968 LogData(user_write_buf_->data(), rv);
838 user_buf_ = NULL;
839 LeaveFunction(""); 969 LeaveFunction("");
840 return rv; 970 return rv;
841 } 971 }
842 PRErrorCode prerr = PR_GetError(); 972 PRErrorCode prerr = PR_GetError();
843 if (prerr == PR_WOULD_BLOCK_ERROR) { 973 if (prerr == PR_WOULD_BLOCK_ERROR) {
844 GotoState(STATE_PAYLOAD_WRITE);
845 return ERR_IO_PENDING; 974 return ERR_IO_PENDING;
846 } 975 }
847 user_buf_ = NULL;
848 LeaveFunction(""); 976 LeaveFunction("");
849 return NetErrorFromNSPRError(prerr); 977 return NetErrorFromNSPRError(prerr);
850 } 978 }
851 979
852 } // namespace net 980 } // namespace net
OLDNEW
« no previous file with comments | « net/socket/ssl_client_socket_nss.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698