| 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 408 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 419 user_write_callback_(NULL), | 419 user_write_callback_(NULL), |
| 420 user_read_buf_len_(0), | 420 user_read_buf_len_(0), |
| 421 user_write_buf_len_(0), | 421 user_write_buf_len_(0), |
| 422 server_cert_nss_(NULL), | 422 server_cert_nss_(NULL), |
| 423 client_auth_cert_needed_(false), | 423 client_auth_cert_needed_(false), |
| 424 handshake_callback_called_(false), | 424 handshake_callback_called_(false), |
| 425 completed_handshake_(false), | 425 completed_handshake_(false), |
| 426 pseudo_connected_(false), | 426 pseudo_connected_(false), |
| 427 eset_mitm_detected_(false), | 427 eset_mitm_detected_(false), |
| 428 netnanny_mitm_detected_(false), | 428 netnanny_mitm_detected_(false), |
| 429 peername_initialized_(false), |
| 429 dnssec_provider_(NULL), | 430 dnssec_provider_(NULL), |
| 430 next_handshake_state_(STATE_NONE), | 431 next_handshake_state_(STATE_NONE), |
| 431 nss_fd_(NULL), | 432 nss_fd_(NULL), |
| 432 nss_bufs_(NULL), | 433 nss_bufs_(NULL), |
| 433 net_log_(transport_socket->socket()->NetLog()), | 434 net_log_(transport_socket->socket()->NetLog()), |
| 434 predicted_npn_status_(kNextProtoUnsupported), | 435 predicted_npn_status_(kNextProtoUnsupported), |
| 435 predicted_npn_proto_used_(false), | 436 predicted_npn_proto_used_(false), |
| 436 ssl_host_info_(ssl_host_info) { | 437 ssl_host_info_(ssl_host_info) { |
| 437 EnterFunction(""); | 438 EnterFunction(""); |
| 438 } | 439 } |
| (...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 731 net_log_.EndEvent(NetLog::TYPE_SSL_CONNECT, NULL); | 732 net_log_.EndEvent(NetLog::TYPE_SSL_CONNECT, NULL); |
| 732 return rv; | 733 return rv; |
| 733 } | 734 } |
| 734 | 735 |
| 735 rv = InitializeSSLOptions(); | 736 rv = InitializeSSLOptions(); |
| 736 if (rv != OK) { | 737 if (rv != OK) { |
| 737 net_log_.EndEvent(NetLog::TYPE_SSL_CONNECT, NULL); | 738 net_log_.EndEvent(NetLog::TYPE_SSL_CONNECT, NULL); |
| 738 return rv; | 739 return rv; |
| 739 } | 740 } |
| 740 | 741 |
| 742 // Attempt to initialize the peer name. In the case of TCP FastOpen, |
| 743 // we don't have the peer yet. |
| 744 if (!UsingTCPFastOpen()) { |
| 745 rv = InitializeSSLPeerName(); |
| 746 if (rv != OK) { |
| 747 net_log_.EndEvent(NetLog::TYPE_SSL_CONNECT, NULL); |
| 748 return rv; |
| 749 } |
| 750 } |
| 751 |
| 741 if (ssl_config_.snap_start_enabled && ssl_host_info_.get()) { | 752 if (ssl_config_.snap_start_enabled && ssl_host_info_.get()) { |
| 742 GotoState(STATE_SNAP_START_LOAD_INFO); | 753 GotoState(STATE_SNAP_START_LOAD_INFO); |
| 743 } else { | 754 } else { |
| 744 GotoState(STATE_HANDSHAKE); | 755 GotoState(STATE_HANDSHAKE); |
| 745 } | 756 } |
| 746 | 757 |
| 747 rv = DoHandshakeLoop(OK); | 758 rv = DoHandshakeLoop(OK); |
| 748 if (rv == ERR_IO_PENDING) { | 759 if (rv == ERR_IO_PENDING) { |
| 749 if (pseudo_connected_) { | 760 if (pseudo_connected_) { |
| 750 net_log_.EndEvent(NetLog::TYPE_SSL_CONNECT, NULL); | 761 net_log_.EndEvent(NetLog::TYPE_SSL_CONNECT, NULL); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 761 } | 772 } |
| 762 | 773 |
| 763 int SSLClientSocketNSS::InitializeSSLOptions() { | 774 int SSLClientSocketNSS::InitializeSSLOptions() { |
| 764 // Transport connected, now hook it up to nss | 775 // Transport connected, now hook it up to nss |
| 765 // TODO(port): specify rx and tx buffer sizes separately | 776 // TODO(port): specify rx and tx buffer sizes separately |
| 766 nss_fd_ = memio_CreateIOLayer(kRecvBufferSize); | 777 nss_fd_ = memio_CreateIOLayer(kRecvBufferSize); |
| 767 if (nss_fd_ == NULL) { | 778 if (nss_fd_ == NULL) { |
| 768 return ERR_OUT_OF_MEMORY; // TODO(port): map NSPR error code. | 779 return ERR_OUT_OF_MEMORY; // TODO(port): map NSPR error code. |
| 769 } | 780 } |
| 770 | 781 |
| 771 // Tell NSS who we're connected to | |
| 772 AddressList peer_address; | |
| 773 int err = transport_->socket()->GetPeerAddress(&peer_address); | |
| 774 if (err != OK) | |
| 775 return err; | |
| 776 | |
| 777 const struct addrinfo* ai = peer_address.head(); | |
| 778 | |
| 779 PRNetAddr peername; | |
| 780 memset(&peername, 0, sizeof(peername)); | |
| 781 DCHECK_LE(ai->ai_addrlen, sizeof(peername)); | |
| 782 size_t len = std::min(static_cast<size_t>(ai->ai_addrlen), sizeof(peername)); | |
| 783 memcpy(&peername, ai->ai_addr, len); | |
| 784 | |
| 785 // Adjust the address family field for BSD, whose sockaddr | |
| 786 // structure has a one-byte length and one-byte address family | |
| 787 // field at the beginning. PRNetAddr has a two-byte address | |
| 788 // family field at the beginning. | |
| 789 peername.raw.family = ai->ai_addr->sa_family; | |
| 790 | |
| 791 memio_SetPeerName(nss_fd_, &peername); | |
| 792 | |
| 793 // Grab pointer to buffers | 782 // Grab pointer to buffers |
| 794 nss_bufs_ = memio_GetSecret(nss_fd_); | 783 nss_bufs_ = memio_GetSecret(nss_fd_); |
| 795 | 784 |
| 796 /* Create SSL state machine */ | 785 /* Create SSL state machine */ |
| 797 /* Push SSL onto our fake I/O socket */ | 786 /* Push SSL onto our fake I/O socket */ |
| 798 nss_fd_ = SSL_ImportFD(NULL, nss_fd_); | 787 nss_fd_ = SSL_ImportFD(NULL, nss_fd_); |
| 799 if (nss_fd_ == NULL) { | 788 if (nss_fd_ == NULL) { |
| 800 LogFailedNSSFunction(net_log_, "SSL_ImportFD", ""); | 789 LogFailedNSSFunction(net_log_, "SSL_ImportFD", ""); |
| 801 return ERR_OUT_OF_MEMORY; // TODO(port): map NSPR/NSS error code. | 790 return ERR_OUT_OF_MEMORY; // TODO(port): map NSPR/NSS error code. |
| 802 } | 791 } |
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 937 | 926 |
| 938 rv = SSL_HandshakeCallback(nss_fd_, HandshakeCallback, this); | 927 rv = SSL_HandshakeCallback(nss_fd_, HandshakeCallback, this); |
| 939 if (rv != SECSuccess) { | 928 if (rv != SECSuccess) { |
| 940 LogFailedNSSFunction(net_log_, "SSL_HandshakeCallback", ""); | 929 LogFailedNSSFunction(net_log_, "SSL_HandshakeCallback", ""); |
| 941 return ERR_UNEXPECTED; | 930 return ERR_UNEXPECTED; |
| 942 } | 931 } |
| 943 | 932 |
| 944 // Tell SSL the hostname we're trying to connect to. | 933 // Tell SSL the hostname we're trying to connect to. |
| 945 SSL_SetURL(nss_fd_, hostname_.c_str()); | 934 SSL_SetURL(nss_fd_, hostname_.c_str()); |
| 946 | 935 |
| 936 // Tell SSL we're a client; needed if not letting NSPR do socket I/O |
| 937 SSL_ResetHandshake(nss_fd_, 0); |
| 938 |
| 939 return OK; |
| 940 } |
| 941 |
| 942 int SSLClientSocketNSS::InitializeSSLPeerName() { |
| 943 // Tell NSS who we're connected to |
| 944 AddressList peer_address; |
| 945 int err = transport_->socket()->GetPeerAddress(&peer_address); |
| 946 if (err != OK) |
| 947 return err; |
| 948 |
| 949 const struct addrinfo* ai = peer_address.head(); |
| 950 |
| 951 PRNetAddr peername; |
| 952 memset(&peername, 0, sizeof(peername)); |
| 953 DCHECK_LE(ai->ai_addrlen, sizeof(peername)); |
| 954 size_t len = std::min(static_cast<size_t>(ai->ai_addrlen), |
| 955 sizeof(peername)); |
| 956 memcpy(&peername, ai->ai_addr, len); |
| 957 |
| 958 // Adjust the address family field for BSD, whose sockaddr |
| 959 // structure has a one-byte length and one-byte address family |
| 960 // field at the beginning. PRNetAddr has a two-byte address |
| 961 // family field at the beginning. |
| 962 peername.raw.family = ai->ai_addr->sa_family; |
| 963 |
| 964 memio_SetPeerName(nss_fd_, &peername); |
| 965 |
| 947 // Set the peer ID for session reuse. This is necessary when we create an | 966 // Set the peer ID for session reuse. This is necessary when we create an |
| 948 // SSL tunnel through a proxy -- GetPeerName returns the proxy's address | 967 // SSL tunnel through a proxy -- GetPeerName returns the proxy's address |
| 949 // rather than the destination server's address in that case. | 968 // rather than the destination server's address in that case. |
| 950 // TODO(wtc): port in |peer_address| is not the server's port when a proxy is | 969 // TODO(wtc): port in |peer_address| is not the server's port when a proxy is |
| 951 // used. | 970 // used. |
| 952 std::string peer_id = base::StringPrintf("%s:%d", hostname_.c_str(), | 971 std::string peer_id = base::StringPrintf("%s:%d", hostname_.c_str(), |
| 953 peer_address.GetPort()); | 972 peer_address.GetPort()); |
| 954 rv = SSL_SetSockPeerID(nss_fd_, const_cast<char*>(peer_id.c_str())); | 973 SECStatus rv = SSL_SetSockPeerID(nss_fd_, const_cast<char*>(peer_id.c_str())); |
| 955 if (rv != SECSuccess) | 974 if (rv != SECSuccess) |
| 956 LogFailedNSSFunction(net_log_, "SSL_SetSockPeerID", peer_id.c_str()); | 975 LogFailedNSSFunction(net_log_, "SSL_SetSockPeerID", peer_id.c_str()); |
| 957 | 976 |
| 958 // Tell SSL we're a client; needed if not letting NSPR do socket I/O | 977 peername_initialized_ = true; |
| 959 SSL_ResetHandshake(nss_fd_, 0); | |
| 960 | |
| 961 return OK; | 978 return OK; |
| 962 } | 979 } |
| 963 | 980 |
| 964 void SSLClientSocketNSS::InvalidateSessionIfBadCertificate() { | 981 void SSLClientSocketNSS::InvalidateSessionIfBadCertificate() { |
| 965 if (UpdateServerCert() != NULL && | 982 if (UpdateServerCert() != NULL && |
| 966 ssl_config_.IsAllowedBadCert(server_cert_)) { | 983 ssl_config_.IsAllowedBadCert(server_cert_)) { |
| 967 SSL_InvalidateSession(nss_fd_); | 984 SSL_InvalidateSession(nss_fd_); |
| 968 } | 985 } |
| 969 } | 986 } |
| 970 | 987 |
| (...skipping 25 matching lines...) Expand all Loading... |
| 996 server_cert_ = NULL; | 1013 server_cert_ = NULL; |
| 997 if (server_cert_nss_) { | 1014 if (server_cert_nss_) { |
| 998 CERT_DestroyCertificate(server_cert_nss_); | 1015 CERT_DestroyCertificate(server_cert_nss_); |
| 999 server_cert_nss_ = NULL; | 1016 server_cert_nss_ = NULL; |
| 1000 } | 1017 } |
| 1001 server_cert_verify_result_.Reset(); | 1018 server_cert_verify_result_.Reset(); |
| 1002 completed_handshake_ = false; | 1019 completed_handshake_ = false; |
| 1003 pseudo_connected_ = false; | 1020 pseudo_connected_ = false; |
| 1004 eset_mitm_detected_ = false; | 1021 eset_mitm_detected_ = false; |
| 1005 netnanny_mitm_detected_= false; | 1022 netnanny_mitm_detected_= false; |
| 1023 peername_initialized_ = false; |
| 1006 nss_bufs_ = NULL; | 1024 nss_bufs_ = NULL; |
| 1007 client_certs_.clear(); | 1025 client_certs_.clear(); |
| 1008 client_auth_cert_needed_ = false; | 1026 client_auth_cert_needed_ = false; |
| 1009 | 1027 |
| 1010 LeaveFunction(""); | 1028 LeaveFunction(""); |
| 1011 } | 1029 } |
| 1012 | 1030 |
| 1013 bool SSLClientSocketNSS::IsConnected() const { | 1031 bool SSLClientSocketNSS::IsConnected() const { |
| 1014 // Ideally, we should also check if we have received the close_notify alert | 1032 // Ideally, we should also check if we have received the close_notify alert |
| 1015 // message from the server, and return false in that case. We're not doing | 1033 // message from the server, and return false in that case. We're not doing |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1061 } | 1079 } |
| 1062 | 1080 |
| 1063 bool SSLClientSocketNSS::WasEverUsed() const { | 1081 bool SSLClientSocketNSS::WasEverUsed() const { |
| 1064 if (transport_.get() && transport_->socket()) { | 1082 if (transport_.get() && transport_->socket()) { |
| 1065 return transport_->socket()->WasEverUsed(); | 1083 return transport_->socket()->WasEverUsed(); |
| 1066 } | 1084 } |
| 1067 NOTREACHED(); | 1085 NOTREACHED(); |
| 1068 return false; | 1086 return false; |
| 1069 } | 1087 } |
| 1070 | 1088 |
| 1089 bool SSLClientSocketNSS::UsingTCPFastOpen() const { |
| 1090 if (transport_.get() && transport_->socket()) { |
| 1091 return transport_->socket()->UsingTCPFastOpen(); |
| 1092 } |
| 1093 NOTREACHED(); |
| 1094 return false; |
| 1095 } |
| 1096 |
| 1071 int SSLClientSocketNSS::Read(IOBuffer* buf, int buf_len, | 1097 int SSLClientSocketNSS::Read(IOBuffer* buf, int buf_len, |
| 1072 CompletionCallback* callback) { | 1098 CompletionCallback* callback) { |
| 1073 EnterFunction(buf_len); | 1099 EnterFunction(buf_len); |
| 1074 DCHECK(!user_read_callback_); | 1100 DCHECK(!user_read_callback_); |
| 1075 DCHECK(!user_connect_callback_); | 1101 DCHECK(!user_connect_callback_); |
| 1076 DCHECK(!user_read_buf_); | 1102 DCHECK(!user_read_buf_); |
| 1077 DCHECK(nss_bufs_); | 1103 DCHECK(nss_bufs_); |
| 1078 | 1104 |
| 1079 user_read_buf_ = buf; | 1105 user_read_buf_ = buf; |
| 1080 user_read_buf_len_ = buf_len; | 1106 user_read_buf_len_ = buf_len; |
| (...skipping 480 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1561 memio_PutWriteResult(nss_bufs_, MapErrorToNSS(rv)); | 1587 memio_PutWriteResult(nss_bufs_, MapErrorToNSS(rv)); |
| 1562 } | 1588 } |
| 1563 } | 1589 } |
| 1564 | 1590 |
| 1565 LeaveFunction(rv); | 1591 LeaveFunction(rv); |
| 1566 return rv; | 1592 return rv; |
| 1567 } | 1593 } |
| 1568 | 1594 |
| 1569 void SSLClientSocketNSS::BufferSendComplete(int result) { | 1595 void SSLClientSocketNSS::BufferSendComplete(int result) { |
| 1570 EnterFunction(result); | 1596 EnterFunction(result); |
| 1597 |
| 1598 // In the case of TCP FastOpen, connect is now finished. |
| 1599 if (!peername_initialized_ && UsingTCPFastOpen()) |
| 1600 InitializeSSLPeerName(); |
| 1601 |
| 1571 memio_PutWriteResult(nss_bufs_, MapErrorToNSS(result)); | 1602 memio_PutWriteResult(nss_bufs_, MapErrorToNSS(result)); |
| 1572 transport_send_busy_ = false; | 1603 transport_send_busy_ = false; |
| 1573 OnSendComplete(result); | 1604 OnSendComplete(result); |
| 1574 LeaveFunction(""); | 1605 LeaveFunction(""); |
| 1575 } | 1606 } |
| 1576 | 1607 |
| 1577 | 1608 |
| 1578 int SSLClientSocketNSS::BufferRecv(void) { | 1609 int SSLClientSocketNSS::BufferRecv(void) { |
| 1579 if (transport_recv_busy_) return ERR_IO_PENDING; | 1610 if (transport_recv_busy_) return ERR_IO_PENDING; |
| 1580 | 1611 |
| (...skipping 868 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2449 return ERR_IO_PENDING; | 2480 return ERR_IO_PENDING; |
| 2450 } | 2481 } |
| 2451 LeaveFunction(""); | 2482 LeaveFunction(""); |
| 2452 rv = MapNSPRError(prerr); | 2483 rv = MapNSPRError(prerr); |
| 2453 net_log_.AddEvent(NetLog::TYPE_SSL_WRITE_ERROR, | 2484 net_log_.AddEvent(NetLog::TYPE_SSL_WRITE_ERROR, |
| 2454 new SSLErrorParams(rv, prerr)); | 2485 new SSLErrorParams(rv, prerr)); |
| 2455 return rv; | 2486 return rv; |
| 2456 } | 2487 } |
| 2457 | 2488 |
| 2458 } // namespace net | 2489 } // namespace net |
| OLD | NEW |