OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 SSLClientSocketNSS::DoVerifyCertComplete() derived | 5 // This file includes code SSLClientSocketNSS::DoVerifyCertComplete() derived |
6 // from AuthCertificateCallback() in | 6 // from AuthCertificateCallback() in |
7 // mozilla/security/manager/ssl/src/nsNSSCallbacks.cpp. | 7 // mozilla/security/manager/ssl/src/nsNSSCallbacks.cpp. |
8 | 8 |
9 /* ***** BEGIN LICENSE BLOCK ***** | 9 /* ***** BEGIN LICENSE BLOCK ***** |
10 * Version: MPL 1.1/GPL 2.0/LGPL 2.1 | 10 * Version: MPL 1.1/GPL 2.0/LGPL 2.1 |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
66 #include "base/string_util.h" | 66 #include "base/string_util.h" |
67 #include "net/base/address_list.h" | 67 #include "net/base/address_list.h" |
68 #include "net/base/cert_verifier.h" | 68 #include "net/base/cert_verifier.h" |
69 #include "net/base/io_buffer.h" | 69 #include "net/base/io_buffer.h" |
70 #include "net/base/net_log.h" | 70 #include "net/base/net_log.h" |
71 #include "net/base/net_errors.h" | 71 #include "net/base/net_errors.h" |
72 #include "net/base/ssl_cert_request_info.h" | 72 #include "net/base/ssl_cert_request_info.h" |
73 #include "net/base/ssl_info.h" | 73 #include "net/base/ssl_info.h" |
74 #include "net/base/sys_addrinfo.h" | 74 #include "net/base/sys_addrinfo.h" |
75 #include "net/ocsp/nss_ocsp.h" | 75 #include "net/ocsp/nss_ocsp.h" |
| 76 #include "net/socket/client_socket_handle.h" |
76 | 77 |
77 static const int kRecvBufferSize = 4096; | 78 static const int kRecvBufferSize = 4096; |
78 | 79 |
79 namespace net { | 80 namespace net { |
80 | 81 |
81 // State machines are easier to debug if you log state transitions. | 82 // State machines are easier to debug if you log state transitions. |
82 // Enable these if you want to see what's going on. | 83 // Enable these if you want to see what's going on. |
83 #if 1 | 84 #if 1 |
84 #define EnterFunction(x) | 85 #define EnterFunction(x) |
85 #define LeaveFunction(x) | 86 #define LeaveFunction(x) |
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
270 | 271 |
271 #endif | 272 #endif |
272 | 273 |
273 } // namespace | 274 } // namespace |
274 | 275 |
275 #if defined(OS_WIN) | 276 #if defined(OS_WIN) |
276 // static | 277 // static |
277 HCERTSTORE SSLClientSocketNSS::cert_store_ = NULL; | 278 HCERTSTORE SSLClientSocketNSS::cert_store_ = NULL; |
278 #endif | 279 #endif |
279 | 280 |
280 SSLClientSocketNSS::SSLClientSocketNSS(ClientSocket* transport_socket, | 281 SSLClientSocketNSS::SSLClientSocketNSS(ClientSocketHandle* transport_socket, |
281 const std::string& hostname, | 282 const std::string& hostname, |
282 const SSLConfig& ssl_config) | 283 const SSLConfig& ssl_config) |
283 : ALLOW_THIS_IN_INITIALIZER_LIST(buffer_send_callback_( | 284 : ALLOW_THIS_IN_INITIALIZER_LIST(buffer_send_callback_( |
284 this, &SSLClientSocketNSS::BufferSendComplete)), | 285 this, &SSLClientSocketNSS::BufferSendComplete)), |
285 ALLOW_THIS_IN_INITIALIZER_LIST(buffer_recv_callback_( | 286 ALLOW_THIS_IN_INITIALIZER_LIST(buffer_recv_callback_( |
286 this, &SSLClientSocketNSS::BufferRecvComplete)), | 287 this, &SSLClientSocketNSS::BufferRecvComplete)), |
287 transport_send_busy_(false), | 288 transport_send_busy_(false), |
288 transport_recv_busy_(false), | 289 transport_recv_busy_(false), |
289 ALLOW_THIS_IN_INITIALIZER_LIST(handshake_io_callback_( | 290 ALLOW_THIS_IN_INITIALIZER_LIST(handshake_io_callback_( |
290 this, &SSLClientSocketNSS::OnHandshakeIOComplete)), | 291 this, &SSLClientSocketNSS::OnHandshakeIOComplete)), |
291 transport_(transport_socket), | 292 transport_(transport_socket), |
292 hostname_(hostname), | 293 hostname_(hostname), |
293 ssl_config_(ssl_config), | 294 ssl_config_(ssl_config), |
294 user_connect_callback_(NULL), | 295 user_connect_callback_(NULL), |
295 user_read_callback_(NULL), | 296 user_read_callback_(NULL), |
296 user_write_callback_(NULL), | 297 user_write_callback_(NULL), |
297 user_read_buf_len_(0), | 298 user_read_buf_len_(0), |
298 user_write_buf_len_(0), | 299 user_write_buf_len_(0), |
299 server_cert_nss_(NULL), | 300 server_cert_nss_(NULL), |
300 client_auth_cert_needed_(false), | 301 client_auth_cert_needed_(false), |
301 handshake_callback_called_(false), | 302 handshake_callback_called_(false), |
302 completed_handshake_(false), | 303 completed_handshake_(false), |
303 next_handshake_state_(STATE_NONE), | 304 next_handshake_state_(STATE_NONE), |
304 nss_fd_(NULL), | 305 nss_fd_(NULL), |
305 nss_bufs_(NULL), | 306 nss_bufs_(NULL), |
306 net_log_(transport_socket->NetLog()) { | 307 net_log_(transport_socket->socket()->NetLog()) { |
307 EnterFunction(""); | 308 EnterFunction(""); |
308 } | 309 } |
309 | 310 |
310 SSLClientSocketNSS::~SSLClientSocketNSS() { | 311 SSLClientSocketNSS::~SSLClientSocketNSS() { |
311 EnterFunction(""); | 312 EnterFunction(""); |
312 Disconnect(); | 313 Disconnect(); |
313 LeaveFunction(""); | 314 LeaveFunction(""); |
314 } | 315 } |
315 | 316 |
316 int SSLClientSocketNSS::Init() { | 317 int SSLClientSocketNSS::Init() { |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
370 int SSLClientSocketNSS::InitializeSSLOptions() { | 371 int SSLClientSocketNSS::InitializeSSLOptions() { |
371 // Transport connected, now hook it up to nss | 372 // Transport connected, now hook it up to nss |
372 // TODO(port): specify rx and tx buffer sizes separately | 373 // TODO(port): specify rx and tx buffer sizes separately |
373 nss_fd_ = memio_CreateIOLayer(kRecvBufferSize); | 374 nss_fd_ = memio_CreateIOLayer(kRecvBufferSize); |
374 if (nss_fd_ == NULL) { | 375 if (nss_fd_ == NULL) { |
375 return ERR_OUT_OF_MEMORY; // TODO(port): map NSPR error code. | 376 return ERR_OUT_OF_MEMORY; // TODO(port): map NSPR error code. |
376 } | 377 } |
377 | 378 |
378 // Tell NSS who we're connected to | 379 // Tell NSS who we're connected to |
379 AddressList peer_address; | 380 AddressList peer_address; |
380 int err = transport_->GetPeerAddress(&peer_address); | 381 int err = transport_->socket()->GetPeerAddress(&peer_address); |
381 if (err != OK) | 382 if (err != OK) |
382 return err; | 383 return err; |
383 | 384 |
384 const struct addrinfo* ai = peer_address.head(); | 385 const struct addrinfo* ai = peer_address.head(); |
385 | 386 |
386 PRNetAddr peername; | 387 PRNetAddr peername; |
387 memset(&peername, 0, sizeof(peername)); | 388 memset(&peername, 0, sizeof(peername)); |
388 DCHECK_LE(ai->ai_addrlen, sizeof(peername)); | 389 DCHECK_LE(ai->ai_addrlen, sizeof(peername)); |
389 size_t len = std::min(static_cast<size_t>(ai->ai_addrlen), sizeof(peername)); | 390 size_t len = std::min(static_cast<size_t>(ai->ai_addrlen), sizeof(peername)); |
390 memcpy(&peername, ai->ai_addr, len); | 391 memcpy(&peername, ai->ai_addr, len); |
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
541 // TODO(wtc): Send SSL close_notify alert. | 542 // TODO(wtc): Send SSL close_notify alert. |
542 if (nss_fd_ != NULL) { | 543 if (nss_fd_ != NULL) { |
543 InvalidateSessionIfBadCertificate(); | 544 InvalidateSessionIfBadCertificate(); |
544 PR_Close(nss_fd_); | 545 PR_Close(nss_fd_); |
545 nss_fd_ = NULL; | 546 nss_fd_ = NULL; |
546 } | 547 } |
547 | 548 |
548 // Shut down anything that may call us back (through buffer_send_callback_, | 549 // Shut down anything that may call us back (through buffer_send_callback_, |
549 // buffer_recv_callback, or handshake_io_callback_). | 550 // buffer_recv_callback, or handshake_io_callback_). |
550 verifier_.reset(); | 551 verifier_.reset(); |
551 transport_->Disconnect(); | 552 transport_->socket()->Disconnect(); |
552 | 553 |
553 // Reset object state | 554 // Reset object state |
554 transport_send_busy_ = false; | 555 transport_send_busy_ = false; |
555 transport_recv_busy_ = false; | 556 transport_recv_busy_ = false; |
556 user_connect_callback_ = NULL; | 557 user_connect_callback_ = NULL; |
557 user_read_callback_ = NULL; | 558 user_read_callback_ = NULL; |
558 user_write_callback_ = NULL; | 559 user_write_callback_ = NULL; |
559 user_read_buf_ = NULL; | 560 user_read_buf_ = NULL; |
560 user_read_buf_len_ = 0; | 561 user_read_buf_len_ = 0; |
561 user_write_buf_ = NULL; | 562 user_write_buf_ = NULL; |
(...skipping 13 matching lines...) Expand all Loading... |
575 } | 576 } |
576 | 577 |
577 bool SSLClientSocketNSS::IsConnected() const { | 578 bool SSLClientSocketNSS::IsConnected() const { |
578 // Ideally, we should also check if we have received the close_notify alert | 579 // Ideally, we should also check if we have received the close_notify alert |
579 // message from the server, and return false in that case. We're not doing | 580 // message from the server, and return false in that case. We're not doing |
580 // that, so this function may return a false positive. Since the upper | 581 // that, so this function may return a false positive. Since the upper |
581 // layer (HttpNetworkTransaction) needs to handle a persistent connection | 582 // layer (HttpNetworkTransaction) needs to handle a persistent connection |
582 // closed by the server when we send a request anyway, a false positive in | 583 // closed by the server when we send a request anyway, a false positive in |
583 // exchange for simpler code is a good trade-off. | 584 // exchange for simpler code is a good trade-off. |
584 EnterFunction(""); | 585 EnterFunction(""); |
585 bool ret = completed_handshake_ && transport_->IsConnected(); | 586 bool ret = completed_handshake_ && transport_->socket()->IsConnected(); |
586 LeaveFunction(""); | 587 LeaveFunction(""); |
587 return ret; | 588 return ret; |
588 } | 589 } |
589 | 590 |
590 bool SSLClientSocketNSS::IsConnectedAndIdle() const { | 591 bool SSLClientSocketNSS::IsConnectedAndIdle() const { |
591 // Unlike IsConnected, this method doesn't return a false positive. | 592 // Unlike IsConnected, this method doesn't return a false positive. |
592 // | 593 // |
593 // Strictly speaking, we should check if we have received the close_notify | 594 // Strictly speaking, we should check if we have received the close_notify |
594 // alert message from the server, and return false in that case. Although | 595 // alert message from the server, and return false in that case. Although |
595 // the close_notify alert message means EOF in the SSL layer, it is just | 596 // the close_notify alert message means EOF in the SSL layer, it is just |
596 // bytes to the transport layer below, so transport_->IsConnectedAndIdle() | 597 // bytes to the transport layer below, so |
597 // returns the desired false when we receive close_notify. | 598 // transport_->socket()->IsConnectedAndIdle() returns the desired false |
| 599 // when we receive close_notify. |
598 EnterFunction(""); | 600 EnterFunction(""); |
599 bool ret = completed_handshake_ && transport_->IsConnectedAndIdle(); | 601 bool ret = completed_handshake_ && transport_->socket()->IsConnectedAndIdle(); |
600 LeaveFunction(""); | 602 LeaveFunction(""); |
601 return ret; | 603 return ret; |
602 } | 604 } |
603 | 605 |
604 int SSLClientSocketNSS::GetPeerAddress(AddressList* address) const { | 606 int SSLClientSocketNSS::GetPeerAddress(AddressList* address) const { |
605 return transport_->GetPeerAddress(address); | 607 return transport_->socket()->GetPeerAddress(address); |
606 } | 608 } |
607 | 609 |
608 int SSLClientSocketNSS::Read(IOBuffer* buf, int buf_len, | 610 int SSLClientSocketNSS::Read(IOBuffer* buf, int buf_len, |
609 CompletionCallback* callback) { | 611 CompletionCallback* callback) { |
610 EnterFunction(buf_len); | 612 EnterFunction(buf_len); |
611 DCHECK(completed_handshake_); | 613 DCHECK(completed_handshake_); |
612 DCHECK(next_handshake_state_ == STATE_NONE); | 614 DCHECK(next_handshake_state_ == STATE_NONE); |
613 DCHECK(!user_read_callback_); | 615 DCHECK(!user_read_callback_); |
614 DCHECK(!user_connect_callback_); | 616 DCHECK(!user_connect_callback_); |
615 DCHECK(!user_read_buf_); | 617 DCHECK(!user_read_buf_); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
649 user_write_callback_ = callback; | 651 user_write_callback_ = callback; |
650 } else { | 652 } else { |
651 user_write_buf_ = NULL; | 653 user_write_buf_ = NULL; |
652 user_write_buf_len_ = 0; | 654 user_write_buf_len_ = 0; |
653 } | 655 } |
654 LeaveFunction(rv); | 656 LeaveFunction(rv); |
655 return rv; | 657 return rv; |
656 } | 658 } |
657 | 659 |
658 bool SSLClientSocketNSS::SetReceiveBufferSize(int32 size) { | 660 bool SSLClientSocketNSS::SetReceiveBufferSize(int32 size) { |
659 return transport_->SetReceiveBufferSize(size); | 661 return transport_->socket()->SetReceiveBufferSize(size); |
660 } | 662 } |
661 | 663 |
662 bool SSLClientSocketNSS::SetSendBufferSize(int32 size) { | 664 bool SSLClientSocketNSS::SetSendBufferSize(int32 size) { |
663 return transport_->SetSendBufferSize(size); | 665 return transport_->socket()->SetSendBufferSize(size); |
664 } | 666 } |
665 | 667 |
666 #if defined(OS_WIN) | 668 #if defined(OS_WIN) |
667 // static | 669 // static |
668 X509Certificate::OSCertHandle SSLClientSocketNSS::CreateOSCert( | 670 X509Certificate::OSCertHandle SSLClientSocketNSS::CreateOSCert( |
669 const SECItem& der_cert) { | 671 const SECItem& der_cert) { |
670 // TODO(wtc): close cert_store_ at shutdown. | 672 // TODO(wtc): close cert_store_ at shutdown. |
671 if (!cert_store_) | 673 if (!cert_store_) |
672 cert_store_ = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, NULL, 0, NULL); | 674 cert_store_ = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, NULL, 0, NULL); |
673 | 675 |
(...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1010 // nss_bufs_ is a circular buffer. It may have two contiguous parts | 1012 // nss_bufs_ is a circular buffer. It may have two contiguous parts |
1011 // (before and after the wrap). So this for loop needs two iterations. | 1013 // (before and after the wrap). So this for loop needs two iterations. |
1012 for (int i = 0; i < 2; ++i) { | 1014 for (int i = 0; i < 2; ++i) { |
1013 const char* buf; | 1015 const char* buf; |
1014 int nb = memio_GetWriteParams(nss_bufs_, &buf); | 1016 int nb = memio_GetWriteParams(nss_bufs_, &buf); |
1015 if (!nb) | 1017 if (!nb) |
1016 break; | 1018 break; |
1017 | 1019 |
1018 scoped_refptr<IOBuffer> send_buffer = new IOBuffer(nb); | 1020 scoped_refptr<IOBuffer> send_buffer = new IOBuffer(nb); |
1019 memcpy(send_buffer->data(), buf, nb); | 1021 memcpy(send_buffer->data(), buf, nb); |
1020 int rv = transport_->Write(send_buffer, nb, &buffer_send_callback_); | 1022 int rv = transport_->socket()->Write(send_buffer, nb, |
| 1023 &buffer_send_callback_); |
1021 if (rv == ERR_IO_PENDING) { | 1024 if (rv == ERR_IO_PENDING) { |
1022 transport_send_busy_ = true; | 1025 transport_send_busy_ = true; |
1023 break; | 1026 break; |
1024 } else { | 1027 } else { |
1025 memio_PutWriteResult(nss_bufs_, MapErrorToNSS(rv)); | 1028 memio_PutWriteResult(nss_bufs_, MapErrorToNSS(rv)); |
1026 if (rv < 0) { | 1029 if (rv < 0) { |
1027 // Return the error even if the previous Write succeeded. | 1030 // Return the error even if the previous Write succeeded. |
1028 nsent = rv; | 1031 nsent = rv; |
1029 break; | 1032 break; |
1030 } | 1033 } |
(...skipping 19 matching lines...) Expand all Loading... |
1050 | 1053 |
1051 char *buf; | 1054 char *buf; |
1052 int nb = memio_GetReadParams(nss_bufs_, &buf); | 1055 int nb = memio_GetReadParams(nss_bufs_, &buf); |
1053 EnterFunction(nb); | 1056 EnterFunction(nb); |
1054 int rv; | 1057 int rv; |
1055 if (!nb) { | 1058 if (!nb) { |
1056 // buffer too full to read into, so no I/O possible at moment | 1059 // buffer too full to read into, so no I/O possible at moment |
1057 rv = ERR_IO_PENDING; | 1060 rv = ERR_IO_PENDING; |
1058 } else { | 1061 } else { |
1059 recv_buffer_ = new IOBuffer(nb); | 1062 recv_buffer_ = new IOBuffer(nb); |
1060 rv = transport_->Read(recv_buffer_, nb, &buffer_recv_callback_); | 1063 rv = transport_->socket()->Read(recv_buffer_, nb, &buffer_recv_callback_); |
1061 if (rv == ERR_IO_PENDING) { | 1064 if (rv == ERR_IO_PENDING) { |
1062 transport_recv_busy_ = true; | 1065 transport_recv_busy_ = true; |
1063 } else { | 1066 } else { |
1064 if (rv > 0) | 1067 if (rv > 0) |
1065 memcpy(buf, recv_buffer_->data(), rv); | 1068 memcpy(buf, recv_buffer_->data(), rv); |
1066 memio_PutReadResult(nss_bufs_, MapErrorToNSS(rv)); | 1069 memio_PutReadResult(nss_bufs_, MapErrorToNSS(rv)); |
1067 recv_buffer_ = NULL; | 1070 recv_buffer_ = NULL; |
1068 } | 1071 } |
1069 } | 1072 } |
1070 LeaveFunction(rv); | 1073 LeaveFunction(rv); |
(...skipping 481 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1552 PRErrorCode prerr = PR_GetError(); | 1555 PRErrorCode prerr = PR_GetError(); |
1553 if (prerr == PR_WOULD_BLOCK_ERROR) { | 1556 if (prerr == PR_WOULD_BLOCK_ERROR) { |
1554 LeaveFunction(""); | 1557 LeaveFunction(""); |
1555 return ERR_IO_PENDING; | 1558 return ERR_IO_PENDING; |
1556 } | 1559 } |
1557 LeaveFunction(""); | 1560 LeaveFunction(""); |
1558 return MapNSPRError(prerr); | 1561 return MapNSPRError(prerr); |
1559 } | 1562 } |
1560 | 1563 |
1561 } // namespace net | 1564 } // namespace net |
OLD | NEW |