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

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

Issue 202058: WebSocket implementation in Chromium. (Closed)
Patch Set: update 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') | webkit/api/public/WebKitClient.h » ('j') | 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)
412 user_callback_ = callback; 423 user_read_callback_ = callback;
413 LeaveFunction(rv); 424 LeaveFunction(rv);
414 return rv; 425 return rv;
415 } 426 }
416 427
417 int SSLClientSocketNSS::Write(IOBuffer* buf, int buf_len, 428 int SSLClientSocketNSS::Write(IOBuffer* buf, int buf_len,
418 CompletionCallback* callback) { 429 CompletionCallback* callback) {
419 EnterFunction(buf_len); 430 EnterFunction(buf_len);
420 DCHECK(completed_handshake_); 431 DCHECK(completed_handshake_);
421 DCHECK(next_state_ == STATE_NONE); 432 DCHECK(next_handshake_state_ == STATE_NONE);
422 DCHECK(!user_callback_); 433 DCHECK(!user_write_callback_);
423 DCHECK(!user_connect_callback_); 434 DCHECK(!user_connect_callback_);
424 DCHECK(!user_buf_); 435 DCHECK(!user_write_buf_);
436 DCHECK(nss_bufs_);
425 437
426 user_buf_ = buf; 438 user_write_buf_ = buf;
427 user_buf_len_ = buf_len; 439 user_write_buf_len_ = buf_len;
428 440
429 GotoState(STATE_PAYLOAD_WRITE); 441 int rv = DoWriteLoop(OK);
430 int rv = DoLoop(OK); 442
431 if (rv == ERR_IO_PENDING) 443 if (rv == ERR_IO_PENDING)
432 user_callback_ = callback; 444 user_write_callback_ = callback;
433 LeaveFunction(rv); 445 LeaveFunction(rv);
434 return rv; 446 return rv;
435 } 447 }
436 448
437 bool SSLClientSocketNSS::SetReceiveBufferSize(int32 size) { 449 bool SSLClientSocketNSS::SetReceiveBufferSize(int32 size) {
438 return transport_->SetReceiveBufferSize(size); 450 return transport_->SetReceiveBufferSize(size);
439 } 451 }
440 452
441 bool SSLClientSocketNSS::SetSendBufferSize(int32 size) { 453 bool SSLClientSocketNSS::SetSendBufferSize(int32 size) {
442 return transport_->SetSendBufferSize(size); 454 return transport_->SetSendBufferSize(size);
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
484 DCHECK(server_cert_ != NULL); 496 DCHECK(server_cert_ != NULL);
485 ssl_info->cert = server_cert_; 497 ssl_info->cert = server_cert_;
486 LeaveFunction(""); 498 LeaveFunction("");
487 } 499 }
488 500
489 void SSLClientSocketNSS::GetSSLCertRequestInfo( 501 void SSLClientSocketNSS::GetSSLCertRequestInfo(
490 SSLCertRequestInfo* cert_request_info) { 502 SSLCertRequestInfo* cert_request_info) {
491 // TODO(wtc): implement this. 503 // TODO(wtc): implement this.
492 } 504 }
493 505
494 void SSLClientSocketNSS::DoCallback(int rv) { 506 void SSLClientSocketNSS::DoReadCallback(int rv) {
495 EnterFunction(rv); 507 EnterFunction(rv);
496 DCHECK(rv != ERR_IO_PENDING); 508 DCHECK(rv != ERR_IO_PENDING);
497 DCHECK(user_callback_); 509 DCHECK(user_read_callback_);
498 510
499 // Since Run may result in Read being called, clear |user_callback_| up front. 511 // Since Run may result in Read being called, clear |user_read_callback_|
500 CompletionCallback* c = user_callback_; 512 // up front.
501 user_callback_ = NULL; 513 CompletionCallback* c = user_read_callback_;
502 user_buf_ = NULL; 514 user_read_callback_ = NULL;
503 c->Run(rv); 515 c->Run(rv);
504 LeaveFunction(""); 516 LeaveFunction("");
505 } 517 }
518
519 void SSLClientSocketNSS::DoWriteCallback(int rv) {
520 EnterFunction(rv);
521 DCHECK(rv != ERR_IO_PENDING);
522 DCHECK(user_write_callback_);
523
524 // Since Run may result in Write being called, clear |user_write_callback_|
525 // up front.
526 CompletionCallback* c = user_write_callback_;
527 user_write_callback_ = NULL;
528 c->Run(rv);
529 LeaveFunction("");
530 }
506 531
507 // As part of Connect(), the SSLClientSocketNSS object performs an SSL 532 // As part of Connect(), the SSLClientSocketNSS object performs an SSL
508 // handshake. This requires network IO, which in turn calls 533 // handshake. This requires network IO, which in turn calls
509 // BufferRecvComplete() with a non-zero byte count. This byte count eventually 534 // 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 535 // 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(), 536 // callback. For Read() and Write(), that's what we want. But for Connect(),
512 // the caller expects OK (i.e. 0) for success. 537 // the caller expects OK (i.e. 0) for success.
513 // 538 //
514 void SSLClientSocketNSS::DoConnectCallback(int rv) { 539 void SSLClientSocketNSS::DoConnectCallback(int rv) {
515 EnterFunction(rv); 540 EnterFunction(rv);
516 DCHECK_NE(rv, ERR_IO_PENDING); 541 DCHECK_NE(rv, ERR_IO_PENDING);
517 DCHECK(user_connect_callback_); 542 DCHECK(user_connect_callback_);
518 543
519 // Since Run may result in Read being called, clear |user_connect_callback_|
520 // up front.
521 CompletionCallback* c = user_connect_callback_; 544 CompletionCallback* c = user_connect_callback_;
522 user_connect_callback_ = NULL; 545 user_connect_callback_ = NULL;
523 c->Run(rv > OK ? OK : rv); 546 c->Run(rv > OK ? OK : rv);
524 LeaveFunction(""); 547 LeaveFunction("");
525 } 548 }
526 549
527 void SSLClientSocketNSS::OnIOComplete(int result) { 550 void SSLClientSocketNSS::OnHandshakeIOComplete(int result) {
528 EnterFunction(result); 551 EnterFunction(result);
529 int rv = DoLoop(result); 552 int rv = DoHandshakeLoop(result);
530 if (rv != ERR_IO_PENDING) { 553 DCHECK(user_connect_callback_);
531 if (user_callback_) { 554 if (rv != ERR_IO_PENDING)
532 DoCallback(rv); 555 DoConnectCallback(rv);
533 } else if (user_connect_callback_) {
534 DoConnectCallback(rv);
535 }
536 }
537 LeaveFunction(""); 556 LeaveFunction("");
538 } 557 }
539 558
559 void SSLClientSocketNSS::OnSendComplete(int result) {
560 EnterFunction(result);
561 if (next_handshake_state_ != STATE_NONE) {
562 // In handshake phase.
563 OnHandshakeIOComplete(result);
564 LeaveFunction("");
565 return;
566 }
567
568 // Network layer sent some data, check if client requested to write
569 // more data.
570 if (!user_write_buf_) {
571 LeaveFunction("");
572 return;
573 }
574
575 int rv = DoWriteLoop(result);
576 if (rv != ERR_IO_PENDING)
577 DoWriteCallback(rv);
578 LeaveFunction("");
579 }
580
581 void SSLClientSocketNSS::OnRecvComplete(int result) {
582 EnterFunction(result);
583 if (next_handshake_state_ != STATE_NONE) {
584 // In handshake phase.
585 OnHandshakeIOComplete(result);
586 LeaveFunction("");
587 return;
588 }
589
590 // Network layer received some data, check if client requested to read
591 // decrypted data.
592 if (!user_read_buf_) {
593 LeaveFunction("");
594 return;
595 }
596
597 int rv = DoReadLoop(result);
598 if (rv != ERR_IO_PENDING)
599 DoReadCallback(rv);
600 LeaveFunction("");
601 }
602
540 // Map a Chromium net error code to an NSS error code 603 // Map a Chromium net error code to an NSS error code
541 // See _MD_unix_map_default_error in the NSS source 604 // See _MD_unix_map_default_error in the NSS source
542 // tree for inspiration. 605 // tree for inspiration.
543 static PRErrorCode MapErrorToNSS(int result) { 606 static PRErrorCode MapErrorToNSS(int result) {
544 if (result >=0) 607 if (result >=0)
545 return result; 608 return result;
546 // TODO(port): add real table 609 // TODO(port): add real table
547 LOG(ERROR) << "MapErrorToNSS " << result; 610 LOG(ERROR) << "MapErrorToNSS " << result;
548 return PR_UNKNOWN_ERROR; 611 return PR_UNKNOWN_ERROR;
549 } 612 }
550 613
551 // Do network I/O between the given buffer and the given socket. 614 // Do network I/O between the given buffer and the given socket.
615 // Return true if some I/O performed, false otherwise (error or ERR_IO_PENDING)
616 bool SSLClientSocketNSS::DoTransportIO() {
617 bool network_moved = false;
618 if (nss_bufs_ != NULL) {
619 int nsent = BufferSend();
620 int nreceived = BufferRecv();
621 network_moved = (nsent > 0 || nreceived >= 0);
622 }
623 return network_moved;
624 }
625
552 // Return 0 for EOF, 626 // Return 0 for EOF,
553 // > 0 for bytes transferred immediately, 627 // > 0 for bytes transferred immediately,
554 // < 0 for error (or the non-error ERR_IO_PENDING). 628 // < 0 for error (or the non-error ERR_IO_PENDING).
555 int SSLClientSocketNSS::BufferSend(void) { 629 int SSLClientSocketNSS::BufferSend(void) {
556 if (transport_send_busy_) return ERR_IO_PENDING; 630 if (transport_send_busy_) return ERR_IO_PENDING;
557 631
558 const char *buf; 632 const char *buf;
559 int nb = memio_GetWriteParams(nss_bufs_, &buf); 633 int nb = memio_GetWriteParams(nss_bufs_, &buf);
560 EnterFunction(nb); 634 EnterFunction(nb);
561 635
(...skipping 11 matching lines...) Expand all
573 } 647 }
574 648
575 LeaveFunction(rv); 649 LeaveFunction(rv);
576 return rv; 650 return rv;
577 } 651 }
578 652
579 void SSLClientSocketNSS::BufferSendComplete(int result) { 653 void SSLClientSocketNSS::BufferSendComplete(int result) {
580 EnterFunction(result); 654 EnterFunction(result);
581 memio_PutWriteResult(nss_bufs_, result); 655 memio_PutWriteResult(nss_bufs_, result);
582 transport_send_busy_ = false; 656 transport_send_busy_ = false;
583 OnIOComplete(result); 657 OnSendComplete(result);
584 LeaveFunction(""); 658 LeaveFunction("");
585 } 659 }
586 660
587 661
588 int SSLClientSocketNSS::BufferRecv(void) { 662 int SSLClientSocketNSS::BufferRecv(void) {
589 if (transport_recv_busy_) return ERR_IO_PENDING; 663 if (transport_recv_busy_) return ERR_IO_PENDING;
590 664
591 char *buf; 665 char *buf;
592 int nb = memio_GetReadParams(nss_bufs_, &buf); 666 int nb = memio_GetReadParams(nss_bufs_, &buf);
593 EnterFunction(nb); 667 EnterFunction(nb);
(...skipping 20 matching lines...) Expand all
614 void SSLClientSocketNSS::BufferRecvComplete(int result) { 688 void SSLClientSocketNSS::BufferRecvComplete(int result) {
615 EnterFunction(result); 689 EnterFunction(result);
616 if (result > 0) { 690 if (result > 0) {
617 char *buf; 691 char *buf;
618 memio_GetReadParams(nss_bufs_, &buf); 692 memio_GetReadParams(nss_bufs_, &buf);
619 memcpy(buf, recv_buffer_->data(), result); 693 memcpy(buf, recv_buffer_->data(), result);
620 } 694 }
621 recv_buffer_ = NULL; 695 recv_buffer_ = NULL;
622 memio_PutReadResult(nss_bufs_, result); 696 memio_PutReadResult(nss_bufs_, result);
623 transport_recv_busy_ = false; 697 transport_recv_busy_ = false;
624 OnIOComplete(result); 698 OnRecvComplete(result);
625 LeaveFunction(""); 699 LeaveFunction("");
626 } 700 }
627 701
628 int SSLClientSocketNSS::DoLoop(int last_io_result) { 702 int SSLClientSocketNSS::DoHandshakeLoop(int last_io_result) {
629 EnterFunction(last_io_result); 703 EnterFunction(last_io_result);
630 bool network_moved; 704 bool network_moved;
631 int rv = last_io_result; 705 int rv = last_io_result;
632 do { 706 do {
633 network_moved = false; 707 network_moved = false;
634 // Default to STATE_NONE for next state. 708 // Default to STATE_NONE for next state.
635 // (This is a quirk carried over from the windows 709 // (This is a quirk carried over from the windows
636 // implementation. It makes reading the logs a bit harder.) 710 // implementation. It makes reading the logs a bit harder.)
637 // State handlers can and often do call GotoState just 711 // State handlers can and often do call GotoState just
638 // to stay in the current state. 712 // to stay in the current state.
639 State state = next_state_; 713 State state = next_handshake_state_;
640 GotoState(STATE_NONE); 714 GotoState(STATE_NONE);
641 switch (state) { 715 switch (state) {
642 case STATE_NONE: 716 case STATE_NONE:
643 // we're just pumping data between the buffer and the network 717 // we're just pumping data between the buffer and the network
644 break; 718 break;
645 case STATE_HANDSHAKE_READ: 719 case STATE_HANDSHAKE:
646 rv = DoHandshakeRead(); 720 rv = DoHandshake();
647 break; 721 break;
648 case STATE_VERIFY_CERT: 722 case STATE_VERIFY_CERT:
649 DCHECK(rv == OK); 723 DCHECK(rv == OK);
650 rv = DoVerifyCert(rv); 724 rv = DoVerifyCert(rv);
651 break; 725 break;
652 case STATE_VERIFY_CERT_COMPLETE: 726 case STATE_VERIFY_CERT_COMPLETE:
653 rv = DoVerifyCertComplete(rv); 727 rv = DoVerifyCertComplete(rv);
654 break; 728 break;
655 case STATE_PAYLOAD_READ:
656 rv = DoPayloadRead();
657 break;
658 case STATE_PAYLOAD_WRITE:
659 rv = DoPayloadWrite();
660 break;
661 default: 729 default:
662 rv = ERR_UNEXPECTED; 730 rv = ERR_UNEXPECTED;
663 NOTREACHED() << "unexpected state"; 731 NOTREACHED() << "unexpected state";
664 break; 732 break;
665 } 733 }
666 734
667 // Do the actual network I/O 735 // Do the actual network I/O
668 if (nss_bufs_ != NULL) { 736 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) && 737 } while ((rv != ERR_IO_PENDING || network_moved) &&
674 next_state_ != STATE_NONE); 738 next_handshake_state_ != STATE_NONE);
675 LeaveFunction(""); 739 LeaveFunction("");
676 return rv; 740 return rv;
677 } 741 }
742
743 int SSLClientSocketNSS::DoReadLoop(int result) {
744 EnterFunction("");
745 DCHECK(completed_handshake_);
746 DCHECK(next_handshake_state_ == STATE_NONE);
747
748 if (result < 0)
749 return result;
750
751 if (!nss_bufs_)
752 return ERR_UNEXPECTED;
753
754 while (DoTransportIO()) continue;
755 bool network_moved;
756 int rv;
757 do {
758 network_moved = false;
759 rv = DoPayloadRead();
760 if (rv != ERR_IO_PENDING)
761 break;
762 network_moved = DoTransportIO();
763 } while (network_moved);
764
765 LeaveFunction("");
766 return rv;
767 }
768
769 int SSLClientSocketNSS::DoWriteLoop(int result) {
770 EnterFunction("");
771 DCHECK(completed_handshake_);
772 DCHECK(next_handshake_state_ == STATE_NONE);
773
774 if (result < 0)
775 return result;
776
777 if (!nss_bufs_)
778 return ERR_UNEXPECTED;
779
780 bool network_moved;
781 int rv;
782 do {
783 network_moved = false;
784 rv = DoPayloadWrite();
785 if (rv != ERR_IO_PENDING)
786 break;
787 network_moved = DoTransportIO();
788 } while (network_moved);
789 while (DoTransportIO()) continue;
790
791 LeaveFunction("");
792 return rv;
793 }
678 794
679 // static 795 // static
680 // NSS calls this if an incoming certificate needs to be verified. 796 // NSS calls this if an incoming certificate needs to be verified.
681 // Do nothing but return SECSuccess. 797 // Do nothing but return SECSuccess.
682 // This is called only in full handshake mode. 798 // This is called only in full handshake mode.
683 // Peer certificate is retrieved in HandshakeCallback() later, which is called 799 // Peer certificate is retrieved in HandshakeCallback() later, which is called
684 // in full handshake mode or in resumption handshake mode. 800 // in full handshake mode or in resumption handshake mode.
685 SECStatus SSLClientSocketNSS::OwnAuthCertHandler(void* arg, 801 SECStatus SSLClientSocketNSS::OwnAuthCertHandler(void* arg,
686 PRFileDesc* socket, 802 PRFileDesc* socket,
687 PRBool checksig, 803 PRBool checksig,
688 PRBool is_server) { 804 PRBool is_server) {
689 // Tell NSS to not verify the certificate. 805 // Tell NSS to not verify the certificate.
690 return SECSuccess; 806 return SECSuccess;
691 } 807 }
692 808
693 // static 809 // static
694 // NSS calls this when handshake is completed. 810 // NSS calls this when handshake is completed.
695 // After the SSL handshake is finished, use CertVerifier to verify 811 // After the SSL handshake is finished, use CertVerifier to verify
696 // the saved server certificate. 812 // the saved server certificate.
697 void SSLClientSocketNSS::HandshakeCallback(PRFileDesc* socket, 813 void SSLClientSocketNSS::HandshakeCallback(PRFileDesc* socket,
698 void* arg) { 814 void* arg) {
699 SSLClientSocketNSS* that = reinterpret_cast<SSLClientSocketNSS*>(arg); 815 SSLClientSocketNSS* that = reinterpret_cast<SSLClientSocketNSS*>(arg);
700 816
701 that->UpdateServerCert(); 817 that->UpdateServerCert();
702 } 818 }
703 819
704 int SSLClientSocketNSS::DoHandshakeRead() { 820 int SSLClientSocketNSS::DoHandshake() {
705 EnterFunction(""); 821 EnterFunction("");
706 int net_error = net::OK; 822 int net_error = net::OK;
707 int rv = SSL_ForceHandshake(nss_fd_); 823 int rv = SSL_ForceHandshake(nss_fd_);
708 824
709 if (rv == SECSuccess) { 825 if (rv == SECSuccess) {
710 // SSL handshake is completed. Let's verify the certificate. 826 // SSL handshake is completed. Let's verify the certificate.
711 GotoState(STATE_VERIFY_CERT); 827 GotoState(STATE_VERIFY_CERT);
712 // Done! 828 // Done!
713 } else { 829 } else {
714 PRErrorCode prerr = PR_GetError(); 830 PRErrorCode prerr = PR_GetError();
715 831
716 // If the server closed on us, it is a protocol error. 832 // If the server closed on us, it is a protocol error.
717 // Some TLS-intolerant servers do this when we request TLS. 833 // Some TLS-intolerant servers do this when we request TLS.
718 if (prerr == PR_END_OF_FILE_ERROR) { 834 if (prerr == PR_END_OF_FILE_ERROR) {
719 net_error = ERR_SSL_PROTOCOL_ERROR; 835 net_error = ERR_SSL_PROTOCOL_ERROR;
720 } else { 836 } else {
721 net_error = NetErrorFromNSPRError(prerr); 837 net_error = NetErrorFromNSPRError(prerr);
722 } 838 }
723 839
724 // If not done, stay in this state 840 // If not done, stay in this state
725 if (net_error == ERR_IO_PENDING) { 841 if (net_error == ERR_IO_PENDING) {
726 GotoState(STATE_HANDSHAKE_READ); 842 GotoState(STATE_HANDSHAKE);
727 } else { 843 } else {
728 LOG(ERROR) << "handshake failed; NSS error code " << prerr 844 LOG(ERROR) << "handshake failed; NSS error code " << prerr
729 << ", net_error " << net_error; 845 << ", net_error " << net_error;
730 } 846 }
731 } 847 }
732 848
733 LeaveFunction(""); 849 LeaveFunction("");
734 return net_error; 850 return net_error;
735 } 851 }
736 852
737 int SSLClientSocketNSS::DoVerifyCert(int result) { 853 int SSLClientSocketNSS::DoVerifyCert(int result) {
738 DCHECK(server_cert_); 854 DCHECK(server_cert_);
739 GotoState(STATE_VERIFY_CERT_COMPLETE); 855 GotoState(STATE_VERIFY_CERT_COMPLETE);
740 int flags = 0; 856 int flags = 0;
741 if (ssl_config_.rev_checking_enabled) 857 if (ssl_config_.rev_checking_enabled)
742 flags |= X509Certificate::VERIFY_REV_CHECKING_ENABLED; 858 flags |= X509Certificate::VERIFY_REV_CHECKING_ENABLED;
743 if (ssl_config_.verify_ev_cert) 859 if (ssl_config_.verify_ev_cert)
744 flags |= X509Certificate::VERIFY_EV_CERT; 860 flags |= X509Certificate::VERIFY_EV_CERT;
745 verifier_.reset(new CertVerifier); 861 verifier_.reset(new CertVerifier);
746 return verifier_->Verify(server_cert_, hostname_, flags, 862 return verifier_->Verify(server_cert_, hostname_, flags,
747 &server_cert_verify_result_, &io_callback_); 863 &server_cert_verify_result_,
864 &handshake_io_callback_);
748 } 865 }
749 866
750 // Derived from AuthCertificateCallback() in 867 // Derived from AuthCertificateCallback() in
751 // mozilla/source/security/manager/ssl/src/nsNSSCallbacks.cpp. 868 // mozilla/source/security/manager/ssl/src/nsNSSCallbacks.cpp.
752 int SSLClientSocketNSS::DoVerifyCertComplete(int result) { 869 int SSLClientSocketNSS::DoVerifyCertComplete(int result) {
753 DCHECK(verifier_.get()); 870 DCHECK(verifier_.get());
754 verifier_.reset(); 871 verifier_.reset();
755 872
756 if (result == OK) { 873 if (result == OK) {
757 // Remember the intermediate CA certs if the server sends them to us. 874 // 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) && 915 if (IsCertificateError(result) &&
799 ssl_config_.IsAllowedBadCert(server_cert_)) { 916 ssl_config_.IsAllowedBadCert(server_cert_)) {
800 LOG(INFO) << "accepting bad SSL certificate, as user told us to"; 917 LOG(INFO) << "accepting bad SSL certificate, as user told us to";
801 result = OK; 918 result = OK;
802 } 919 }
803 920
804 completed_handshake_ = true; 921 completed_handshake_ = true;
805 // TODO(ukai): we may not need this call because it is now harmless to have an 922 // TODO(ukai): we may not need this call because it is now harmless to have an
806 // session with a bad cert. 923 // session with a bad cert.
807 InvalidateSessionIfBadCertificate(); 924 InvalidateSessionIfBadCertificate();
808 // Exit DoLoop and return the result to the caller to Connect. 925 // Exit DoHandshakeLoop and return the result to the caller to Connect.
809 DCHECK(next_state_ == STATE_NONE); 926 DCHECK(next_handshake_state_ == STATE_NONE);
810 return result; 927 return result;
811 } 928 }
812 929
813 int SSLClientSocketNSS::DoPayloadRead() { 930 int SSLClientSocketNSS::DoPayloadRead() {
814 EnterFunction(user_buf_len_); 931 EnterFunction(user_read_buf_len_);
815 int rv = PR_Read(nss_fd_, user_buf_->data(), user_buf_len_); 932 DCHECK(user_read_buf_);
933 DCHECK(user_read_buf_len_ > 0);
934 int rv = PR_Read(nss_fd_, user_read_buf_->data(), user_read_buf_len_);
816 if (rv >= 0) { 935 if (rv >= 0) {
817 LogData(user_buf_->data(), rv); 936 LogData(user_read_buf_->data(), rv);
818 user_buf_ = NULL; 937 user_read_buf_ = NULL;
938 user_read_buf_len_ = 0;
819 LeaveFunction(""); 939 LeaveFunction("");
820 return rv; 940 return rv;
821 } 941 }
822 PRErrorCode prerr = PR_GetError(); 942 PRErrorCode prerr = PR_GetError();
823 if (prerr == PR_WOULD_BLOCK_ERROR) { 943 if (prerr == PR_WOULD_BLOCK_ERROR) {
824 GotoState(STATE_PAYLOAD_READ);
825 LeaveFunction(""); 944 LeaveFunction("");
826 return ERR_IO_PENDING; 945 return ERR_IO_PENDING;
827 } 946 }
828 user_buf_ = NULL; 947 user_read_buf_ = NULL;
948 user_read_buf_len_ = 0;
829 LeaveFunction(""); 949 LeaveFunction("");
830 return NetErrorFromNSPRError(prerr); 950 return NetErrorFromNSPRError(prerr);
831 } 951 }
832 952
833 int SSLClientSocketNSS::DoPayloadWrite() { 953 int SSLClientSocketNSS::DoPayloadWrite() {
834 EnterFunction(user_buf_len_); 954 EnterFunction(user_write_buf_len_);
835 int rv = PR_Write(nss_fd_, user_buf_->data(), user_buf_len_); 955 if (!user_write_buf_)
956 return OK;
957 int rv = PR_Write(nss_fd_, user_write_buf_->data(), user_write_buf_len_);
836 if (rv >= 0) { 958 if (rv >= 0) {
837 LogData(user_buf_->data(), rv); 959 LogData(user_write_buf_->data(), rv);
838 user_buf_ = NULL; 960 user_write_buf_ = NULL;
961 user_write_buf_len_ = 0;
839 LeaveFunction(""); 962 LeaveFunction("");
840 return rv; 963 return rv;
841 } 964 }
842 PRErrorCode prerr = PR_GetError(); 965 PRErrorCode prerr = PR_GetError();
843 if (prerr == PR_WOULD_BLOCK_ERROR) { 966 if (prerr == PR_WOULD_BLOCK_ERROR) {
844 GotoState(STATE_PAYLOAD_WRITE);
845 return ERR_IO_PENDING; 967 return ERR_IO_PENDING;
846 } 968 }
847 user_buf_ = NULL; 969 user_write_buf_ = NULL;
970 user_write_buf_len_ = 0;
848 LeaveFunction(""); 971 LeaveFunction("");
849 return NetErrorFromNSPRError(prerr); 972 return NetErrorFromNSPRError(prerr);
850 } 973 }
851 974
852 } // namespace net 975 } // namespace net
OLDNEW
« no previous file with comments | « net/socket/ssl_client_socket_nss.h ('k') | webkit/api/public/WebKitClient.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698