| OLD | NEW |
| 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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 #include "net/base/ssl_client_socket_nss.h" | 5 #include "net/base/ssl_client_socket_nss.h" |
| 6 | 6 |
| 7 #include <nspr.h> | 7 #include <nspr.h> |
| 8 #include <nss.h> | 8 #include <nss.h> |
| 9 #include <secerr.h> | 9 #include <secerr.h> |
| 10 // Work around https://bugzilla.mozilla.org/show_bug.cgi?id=455424 | 10 // Work around https://bugzilla.mozilla.org/show_bug.cgi?id=455424 |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 98 : | 98 : |
| 99 buffer_send_callback_(this, &SSLClientSocketNSS::BufferSendComplete), | 99 buffer_send_callback_(this, &SSLClientSocketNSS::BufferSendComplete), |
| 100 buffer_recv_callback_(this, &SSLClientSocketNSS::BufferRecvComplete), | 100 buffer_recv_callback_(this, &SSLClientSocketNSS::BufferRecvComplete), |
| 101 transport_send_busy_(false), | 101 transport_send_busy_(false), |
| 102 transport_recv_busy_(false), | 102 transport_recv_busy_(false), |
| 103 io_callback_(this, &SSLClientSocketNSS::OnIOComplete), | 103 io_callback_(this, &SSLClientSocketNSS::OnIOComplete), |
| 104 transport_(transport_socket), | 104 transport_(transport_socket), |
| 105 hostname_(hostname), | 105 hostname_(hostname), |
| 106 ssl_config_(ssl_config), | 106 ssl_config_(ssl_config), |
| 107 user_callback_(NULL), | 107 user_callback_(NULL), |
| 108 user_buf_(NULL), | |
| 109 user_buf_len_(0), | 108 user_buf_len_(0), |
| 110 server_cert_error_(0), | 109 server_cert_error_(0), |
| 111 completed_handshake_(false), | 110 completed_handshake_(false), |
| 112 next_state_(STATE_NONE), | 111 next_state_(STATE_NONE), |
| 113 nss_fd_(NULL), | 112 nss_fd_(NULL), |
| 114 nss_bufs_(NULL) { | 113 nss_bufs_(NULL) { |
| 115 EnterFunction(""); | 114 EnterFunction(""); |
| 116 } | 115 } |
| 117 | 116 |
| 118 SSLClientSocketNSS::~SSLClientSocketNSS() { | 117 SSLClientSocketNSS::~SSLClientSocketNSS() { |
| (...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 310 // alert message from the server, and return false in that case. Although | 309 // alert message from the server, and return false in that case. Although |
| 311 // the close_notify alert message means EOF in the SSL layer, it is just | 310 // the close_notify alert message means EOF in the SSL layer, it is just |
| 312 // bytes to the transport layer below, so transport_->IsConnectedAndIdle() | 311 // bytes to the transport layer below, so transport_->IsConnectedAndIdle() |
| 313 // returns the desired false when we receive close_notify. | 312 // returns the desired false when we receive close_notify. |
| 314 EnterFunction(""); | 313 EnterFunction(""); |
| 315 bool ret = completed_handshake_ && transport_->IsConnectedAndIdle(); | 314 bool ret = completed_handshake_ && transport_->IsConnectedAndIdle(); |
| 316 LeaveFunction(""); | 315 LeaveFunction(""); |
| 317 return ret; | 316 return ret; |
| 318 } | 317 } |
| 319 | 318 |
| 320 int SSLClientSocketNSS::Read(char* buf, int buf_len, | 319 int SSLClientSocketNSS::Read(IOBuffer* buf, int buf_len, |
| 321 CompletionCallback* callback) { | 320 CompletionCallback* callback) { |
| 322 EnterFunction(buf_len); | 321 EnterFunction(buf_len); |
| 323 DCHECK(completed_handshake_); | 322 DCHECK(completed_handshake_); |
| 324 DCHECK(next_state_ == STATE_NONE); | 323 DCHECK(next_state_ == STATE_NONE); |
| 325 DCHECK(!user_callback_); | 324 DCHECK(!user_callback_); |
| 326 DCHECK(!user_buf_); | 325 DCHECK(!user_buf_); |
| 327 | 326 |
| 328 user_buf_ = buf; | 327 user_buf_ = buf; |
| 329 user_buf_len_ = buf_len; | 328 user_buf_len_ = buf_len; |
| 330 | 329 |
| 331 GotoState(STATE_PAYLOAD_READ); | 330 GotoState(STATE_PAYLOAD_READ); |
| 332 int rv = DoLoop(OK); | 331 int rv = DoLoop(OK); |
| 333 if (rv == ERR_IO_PENDING) | 332 if (rv == ERR_IO_PENDING) |
| 334 user_callback_ = callback; | 333 user_callback_ = callback; |
| 335 LeaveFunction(rv); | 334 LeaveFunction(rv); |
| 336 return rv; | 335 return rv; |
| 337 } | 336 } |
| 338 | 337 |
| 339 int SSLClientSocketNSS::Write(const char* buf, int buf_len, | 338 int SSLClientSocketNSS::Write(IOBuffer* buf, int buf_len, |
| 340 CompletionCallback* callback) { | 339 CompletionCallback* callback) { |
| 341 EnterFunction(buf_len); | 340 EnterFunction(buf_len); |
| 342 DCHECK(completed_handshake_); | 341 DCHECK(completed_handshake_); |
| 343 DCHECK(next_state_ == STATE_NONE); | 342 DCHECK(next_state_ == STATE_NONE); |
| 344 DCHECK(!user_callback_); | 343 DCHECK(!user_callback_); |
| 345 DCHECK(!user_buf_); | 344 DCHECK(!user_buf_); |
| 346 | 345 |
| 347 user_buf_ = const_cast<char*>(buf); | 346 user_buf_ = buf; |
| 348 user_buf_len_ = buf_len; | 347 user_buf_len_ = buf_len; |
| 349 | 348 |
| 350 GotoState(STATE_PAYLOAD_WRITE); | 349 GotoState(STATE_PAYLOAD_WRITE); |
| 351 int rv = DoLoop(OK); | 350 int rv = DoLoop(OK); |
| 352 if (rv == ERR_IO_PENDING) | 351 if (rv == ERR_IO_PENDING) |
| 353 user_callback_ = callback; | 352 user_callback_ = callback; |
| 354 LeaveFunction(rv); | 353 LeaveFunction(rv); |
| 355 return rv; | 354 return rv; |
| 356 } | 355 } |
| 357 | 356 |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 398 } | 397 } |
| 399 | 398 |
| 400 void SSLClientSocketNSS::DoCallback(int rv) { | 399 void SSLClientSocketNSS::DoCallback(int rv) { |
| 401 EnterFunction(rv); | 400 EnterFunction(rv); |
| 402 DCHECK(rv != ERR_IO_PENDING); | 401 DCHECK(rv != ERR_IO_PENDING); |
| 403 DCHECK(user_callback_); | 402 DCHECK(user_callback_); |
| 404 | 403 |
| 405 // since Run may result in Read being called, clear user_callback_ up front. | 404 // since Run may result in Read being called, clear user_callback_ up front. |
| 406 CompletionCallback* c = user_callback_; | 405 CompletionCallback* c = user_callback_; |
| 407 user_callback_ = NULL; | 406 user_callback_ = NULL; |
| 407 user_buf_ = NULL; |
| 408 c->Run(rv); | 408 c->Run(rv); |
| 409 LeaveFunction(""); | 409 LeaveFunction(""); |
| 410 } | 410 } |
| 411 | 411 |
| 412 void SSLClientSocketNSS::OnIOComplete(int result) { | 412 void SSLClientSocketNSS::OnIOComplete(int result) { |
| 413 EnterFunction(result); | 413 EnterFunction(result); |
| 414 int rv = DoLoop(result); | 414 int rv = DoLoop(result); |
| 415 if (rv != ERR_IO_PENDING && user_callback_ != NULL) | 415 if (rv != ERR_IO_PENDING && user_callback_ != NULL) |
| 416 DoCallback(rv); | 416 DoCallback(rv); |
| 417 LeaveFunction(""); | 417 LeaveFunction(""); |
| 418 } | 418 } |
| 419 | 419 |
| 420 // Map a Chromium net error code to an NSS error code | 420 // Map a Chromium net error code to an NSS error code |
| 421 // See _MD_unix_map_default_error in the NSS source | 421 // See _MD_unix_map_default_error in the NSS source |
| 422 // tree for inspiration. | 422 // tree for inspiration. |
| 423 static PRErrorCode MapErrorToNSS(int result) { | 423 static PRErrorCode MapErrorToNSS(int result) { |
| 424 if (result >=0) | 424 if (result >=0) |
| 425 return result; | 425 return result; |
| 426 // TODO(port): add real table | 426 // TODO(port): add real table |
| 427 LOG(ERROR) << "MapErrorToNSS " << result; | 427 LOG(ERROR) << "MapErrorToNSS " << result; |
| 428 return PR_UNKNOWN_ERROR; | 428 return PR_UNKNOWN_ERROR; |
| 429 } | 429 } |
| 430 | 430 |
| 431 /* | 431 // Do network I/O between the given buffer and the given socket. |
| 432 * Do network I/O between the given buffer and the given socket. | 432 // Return 0 for EOF, |
| 433 * Return 0 for EOF, | 433 // > 0 for bytes transferred immediately, |
| 434 * > 0 for bytes transferred immediately, | 434 // < 0 for error (or the non-error ERR_IO_PENDING). |
| 435 * < 0 for error (or the non-error ERR_IO_PENDING). | |
| 436 */ | |
| 437 int SSLClientSocketNSS::BufferSend(void) { | 435 int SSLClientSocketNSS::BufferSend(void) { |
| 438 if (transport_send_busy_) return ERR_IO_PENDING; | 436 if (transport_send_busy_) return ERR_IO_PENDING; |
| 439 | 437 |
| 440 const char *buf; | 438 const char *buf; |
| 441 int nb = memio_GetWriteParams(nss_bufs_, &buf); | 439 int nb = memio_GetWriteParams(nss_bufs_, &buf); |
| 442 EnterFunction(nb); | 440 EnterFunction(nb); |
| 443 | 441 |
| 444 int rv; | 442 int rv; |
| 445 if (!nb) { | 443 if (!nb) { |
| 446 rv = OK; | 444 rv = OK; |
| 447 } else { | 445 } else { |
| 448 rv = transport_->Write(buf, nb, &buffer_send_callback_); | 446 scoped_refptr<IOBuffer> send_buffer = new IOBuffer(nb); |
| 447 memcpy(send_buffer->data(), buf, nb); |
| 448 rv = transport_->Write(send_buffer, nb, &buffer_send_callback_); |
| 449 if (rv == ERR_IO_PENDING) | 449 if (rv == ERR_IO_PENDING) |
| 450 transport_send_busy_ = true; | 450 transport_send_busy_ = true; |
| 451 else | 451 else |
| 452 memio_PutWriteResult(nss_bufs_, MapErrorToNSS(rv)); | 452 memio_PutWriteResult(nss_bufs_, MapErrorToNSS(rv)); |
| 453 } | 453 } |
| 454 | 454 |
| 455 LeaveFunction(rv); | 455 LeaveFunction(rv); |
| 456 return rv; | 456 return rv; |
| 457 } | 457 } |
| 458 | 458 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 469 if (transport_recv_busy_) return ERR_IO_PENDING; | 469 if (transport_recv_busy_) return ERR_IO_PENDING; |
| 470 | 470 |
| 471 char *buf; | 471 char *buf; |
| 472 int nb = memio_GetReadParams(nss_bufs_, &buf); | 472 int nb = memio_GetReadParams(nss_bufs_, &buf); |
| 473 EnterFunction(nb); | 473 EnterFunction(nb); |
| 474 int rv; | 474 int rv; |
| 475 if (!nb) { | 475 if (!nb) { |
| 476 // buffer too full to read into, so no I/O possible at moment | 476 // buffer too full to read into, so no I/O possible at moment |
| 477 rv = ERR_IO_PENDING; | 477 rv = ERR_IO_PENDING; |
| 478 } else { | 478 } else { |
| 479 rv = transport_->Read(buf, nb, &buffer_recv_callback_); | 479 recv_buffer_ = new IOBuffer(nb); |
| 480 if (rv == ERR_IO_PENDING) | 480 rv = transport_->Read(recv_buffer_, nb, &buffer_recv_callback_); |
| 481 if (rv == ERR_IO_PENDING) { |
| 481 transport_recv_busy_ = true; | 482 transport_recv_busy_ = true; |
| 482 else | 483 } else { |
| 484 if (rv > 0) |
| 485 memcpy(buf, recv_buffer_->data(), rv); |
| 483 memio_PutReadResult(nss_bufs_, MapErrorToNSS(rv)); | 486 memio_PutReadResult(nss_bufs_, MapErrorToNSS(rv)); |
| 487 recv_buffer_ = NULL; |
| 488 } |
| 484 } | 489 } |
| 485 LeaveFunction(rv); | 490 LeaveFunction(rv); |
| 486 return rv; | 491 return rv; |
| 487 } | 492 } |
| 488 | 493 |
| 489 void SSLClientSocketNSS::BufferRecvComplete(int result) { | 494 void SSLClientSocketNSS::BufferRecvComplete(int result) { |
| 490 EnterFunction(result); | 495 EnterFunction(result); |
| 496 if (result > 0) { |
| 497 char *buf; |
| 498 memio_GetReadParams(nss_bufs_, &buf); |
| 499 memcpy(buf, recv_buffer_->data(), result); |
| 500 } |
| 501 recv_buffer_ = NULL; |
| 491 memio_PutReadResult(nss_bufs_, result); | 502 memio_PutReadResult(nss_bufs_, result); |
| 492 transport_recv_busy_ = false; | 503 transport_recv_busy_ = false; |
| 493 OnIOComplete(result); | 504 OnIOComplete(result); |
| 494 LeaveFunction(""); | 505 LeaveFunction(""); |
| 495 } | 506 } |
| 496 | 507 |
| 497 int SSLClientSocketNSS::DoLoop(int last_io_result) { | 508 int SSLClientSocketNSS::DoLoop(int last_io_result) { |
| 498 EnterFunction(last_io_result); | 509 EnterFunction(last_io_result); |
| 499 bool network_moved; | 510 bool network_moved; |
| 500 int rv = last_io_result; | 511 int rv = last_io_result; |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 600 << ", net_error " << net_error; | 611 << ", net_error " << net_error; |
| 601 } | 612 } |
| 602 } | 613 } |
| 603 | 614 |
| 604 LeaveFunction(""); | 615 LeaveFunction(""); |
| 605 return net_error; | 616 return net_error; |
| 606 } | 617 } |
| 607 | 618 |
| 608 int SSLClientSocketNSS::DoPayloadRead() { | 619 int SSLClientSocketNSS::DoPayloadRead() { |
| 609 EnterFunction(user_buf_len_); | 620 EnterFunction(user_buf_len_); |
| 610 int rv = PR_Read(nss_fd_, user_buf_, user_buf_len_); | 621 int rv = PR_Read(nss_fd_, user_buf_->data(), user_buf_len_); |
| 611 if (rv >= 0) { | 622 if (rv >= 0) { |
| 612 LogData(user_buf_, rv); | 623 LogData(user_buf_->data(), rv); |
| 613 user_buf_ = NULL; | 624 user_buf_ = NULL; |
| 614 LeaveFunction(""); | 625 LeaveFunction(""); |
| 615 return rv; | 626 return rv; |
| 616 } | 627 } |
| 617 PRErrorCode prerr = PR_GetError(); | 628 PRErrorCode prerr = PR_GetError(); |
| 618 if (prerr == PR_WOULD_BLOCK_ERROR) { | 629 if (prerr == PR_WOULD_BLOCK_ERROR) { |
| 619 GotoState(STATE_PAYLOAD_READ); | 630 GotoState(STATE_PAYLOAD_READ); |
| 620 LeaveFunction(""); | 631 LeaveFunction(""); |
| 621 return ERR_IO_PENDING; | 632 return ERR_IO_PENDING; |
| 622 } | 633 } |
| 623 user_buf_ = NULL; | 634 user_buf_ = NULL; |
| 624 LeaveFunction(""); | 635 LeaveFunction(""); |
| 625 return NetErrorFromNSPRError(prerr); | 636 return NetErrorFromNSPRError(prerr); |
| 626 } | 637 } |
| 627 | 638 |
| 628 int SSLClientSocketNSS::DoPayloadWrite() { | 639 int SSLClientSocketNSS::DoPayloadWrite() { |
| 629 EnterFunction(user_buf_len_); | 640 EnterFunction(user_buf_len_); |
| 630 int rv = PR_Write(nss_fd_, user_buf_, user_buf_len_); | 641 int rv = PR_Write(nss_fd_, user_buf_->data(), user_buf_len_); |
| 631 if (rv >= 0) { | 642 if (rv >= 0) { |
| 632 LogData(user_buf_, rv); | 643 LogData(user_buf_->data(), rv); |
| 633 user_buf_ = NULL; | 644 user_buf_ = NULL; |
| 634 LeaveFunction(""); | 645 LeaveFunction(""); |
| 635 return rv; | 646 return rv; |
| 636 } | 647 } |
| 637 PRErrorCode prerr = PR_GetError(); | 648 PRErrorCode prerr = PR_GetError(); |
| 638 if (prerr == PR_WOULD_BLOCK_ERROR) { | 649 if (prerr == PR_WOULD_BLOCK_ERROR) { |
| 639 GotoState(STATE_PAYLOAD_WRITE); | 650 GotoState(STATE_PAYLOAD_WRITE); |
| 640 return ERR_IO_PENDING; | 651 return ERR_IO_PENDING; |
| 641 } | 652 } |
| 642 user_buf_ = NULL; | 653 user_buf_ = NULL; |
| 643 LeaveFunction(""); | 654 LeaveFunction(""); |
| 644 return NetErrorFromNSPRError(prerr); | 655 return NetErrorFromNSPRError(prerr); |
| 645 } | 656 } |
| 646 | 657 |
| 647 } // namespace net | 658 } // namespace net |
| OLD | NEW |