| 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_win.h" | 5 #include "net/base/ssl_client_socket_win.h" |
| 6 | 6 |
| 7 #include <schnlsp.h> | 7 #include <schnlsp.h> |
| 8 | 8 |
| 9 #include "base/lock.h" | 9 #include "base/lock.h" |
| 10 #include "base/singleton.h" | 10 #include "base/singleton.h" |
| (...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 208 const SSLConfig& ssl_config) | 208 const SSLConfig& ssl_config) |
| 209 #pragma warning(suppress: 4355) | 209 #pragma warning(suppress: 4355) |
| 210 : io_callback_(this, &SSLClientSocketWin::OnIOComplete), | 210 : io_callback_(this, &SSLClientSocketWin::OnIOComplete), |
| 211 transport_(transport_socket), | 211 transport_(transport_socket), |
| 212 hostname_(hostname), | 212 hostname_(hostname), |
| 213 ssl_config_(ssl_config), | 213 ssl_config_(ssl_config), |
| 214 user_callback_(NULL), | 214 user_callback_(NULL), |
| 215 user_buf_(NULL), | 215 user_buf_(NULL), |
| 216 user_buf_len_(0), | 216 user_buf_len_(0), |
| 217 next_state_(STATE_NONE), | 217 next_state_(STATE_NONE), |
| 218 server_cert_(NULL), | |
| 219 creds_(NULL), | 218 creds_(NULL), |
| 220 payload_send_buffer_len_(0), | 219 payload_send_buffer_len_(0), |
| 221 bytes_sent_(0), | 220 bytes_sent_(0), |
| 222 decrypted_ptr_(NULL), | 221 decrypted_ptr_(NULL), |
| 223 bytes_decrypted_(0), | 222 bytes_decrypted_(0), |
| 224 received_ptr_(NULL), | 223 received_ptr_(NULL), |
| 225 bytes_received_(0), | 224 bytes_received_(0), |
| 226 completed_handshake_(false), | 225 completed_handshake_(false), |
| 227 complete_handshake_on_write_complete_(false), | 226 complete_handshake_on_write_complete_(false), |
| 228 ignore_ok_result_(false), | 227 ignore_ok_result_(false), |
| 229 no_client_cert_(false) { | 228 no_client_cert_(false) { |
| 230 memset(&stream_sizes_, 0, sizeof(stream_sizes_)); | 229 memset(&stream_sizes_, 0, sizeof(stream_sizes_)); |
| 231 memset(&send_buffer_, 0, sizeof(send_buffer_)); | 230 memset(&send_buffer_, 0, sizeof(send_buffer_)); |
| 232 memset(&ctxt_, 0, sizeof(ctxt_)); | 231 memset(&ctxt_, 0, sizeof(ctxt_)); |
| 233 } | 232 } |
| 234 | 233 |
| 235 SSLClientSocketWin::~SSLClientSocketWin() { | 234 SSLClientSocketWin::~SSLClientSocketWin() { |
| 236 Disconnect(); | 235 Disconnect(); |
| 237 } | 236 } |
| 238 | 237 |
| 239 void SSLClientSocketWin::GetSSLInfo(SSLInfo* ssl_info) { | 238 void SSLClientSocketWin::GetSSLInfo(SSLInfo* ssl_info) { |
| 240 SECURITY_STATUS status = SEC_E_OK; | 239 if (!server_cert_) |
| 241 if (server_cert_ == NULL) { | 240 return; |
| 242 status = QueryContextAttributes(&ctxt_, | 241 |
| 243 SECPKG_ATTR_REMOTE_CERT_CONTEXT, | 242 ssl_info->cert = server_cert_; |
| 244 &server_cert_); | 243 ssl_info->cert_status = server_cert_verify_result_.cert_status; |
| 245 } | |
| 246 if (status == SEC_E_OK) { | |
| 247 DCHECK(server_cert_); | |
| 248 PCCERT_CONTEXT dup_cert = CertDuplicateCertificateContext(server_cert_); | |
| 249 ssl_info->cert = X509Certificate::CreateFromHandle( | |
| 250 dup_cert, X509Certificate::SOURCE_FROM_NETWORK); | |
| 251 } | |
| 252 SecPkgContext_ConnectionInfo connection_info; | 244 SecPkgContext_ConnectionInfo connection_info; |
| 253 status = QueryContextAttributes(&ctxt_, | 245 SECURITY_STATUS status = QueryContextAttributes( |
| 254 SECPKG_ATTR_CONNECTION_INFO, | 246 &ctxt_, SECPKG_ATTR_CONNECTION_INFO, &connection_info); |
| 255 &connection_info); | |
| 256 if (status == SEC_E_OK) { | 247 if (status == SEC_E_OK) { |
| 257 // TODO(wtc): compute the overall security strength, taking into account | 248 // TODO(wtc): compute the overall security strength, taking into account |
| 258 // dwExchStrength and dwHashStrength. dwExchStrength needs to be | 249 // dwExchStrength and dwHashStrength. dwExchStrength needs to be |
| 259 // normalized. | 250 // normalized. |
| 260 ssl_info->security_bits = connection_info.dwCipherStrength; | 251 ssl_info->security_bits = connection_info.dwCipherStrength; |
| 261 } | 252 } |
| 262 ssl_info->cert_status = server_cert_verify_result_.cert_status; | |
| 263 } | 253 } |
| 264 | 254 |
| 265 int SSLClientSocketWin::Connect(CompletionCallback* callback) { | 255 int SSLClientSocketWin::Connect(CompletionCallback* callback) { |
| 266 DCHECK(transport_.get()); | 256 DCHECK(transport_.get()); |
| 267 DCHECK(next_state_ == STATE_NONE); | 257 DCHECK(next_state_ == STATE_NONE); |
| 268 DCHECK(!user_callback_); | 258 DCHECK(!user_callback_); |
| 269 | 259 |
| 270 int ssl_version_mask = 0; | 260 int ssl_version_mask = 0; |
| 271 if (ssl_config_.ssl2_enabled) | 261 if (ssl_config_.ssl2_enabled) |
| 272 ssl_version_mask |= SSL2; | 262 ssl_version_mask |= SSL2; |
| (...skipping 26 matching lines...) Expand all Loading... |
| 299 transport_->Disconnect(); | 289 transport_->Disconnect(); |
| 300 | 290 |
| 301 if (send_buffer_.pvBuffer) { | 291 if (send_buffer_.pvBuffer) { |
| 302 FreeContextBuffer(send_buffer_.pvBuffer); | 292 FreeContextBuffer(send_buffer_.pvBuffer); |
| 303 memset(&send_buffer_, 0, sizeof(send_buffer_)); | 293 memset(&send_buffer_, 0, sizeof(send_buffer_)); |
| 304 } | 294 } |
| 305 if (ctxt_.dwLower || ctxt_.dwUpper) { | 295 if (ctxt_.dwLower || ctxt_.dwUpper) { |
| 306 DeleteSecurityContext(&ctxt_); | 296 DeleteSecurityContext(&ctxt_); |
| 307 memset(&ctxt_, 0, sizeof(ctxt_)); | 297 memset(&ctxt_, 0, sizeof(ctxt_)); |
| 308 } | 298 } |
| 309 if (server_cert_) { | 299 if (server_cert_) |
| 310 CertFreeCertificateContext(server_cert_); | |
| 311 server_cert_ = NULL; | 300 server_cert_ = NULL; |
| 312 } | |
| 313 | 301 |
| 314 // TODO(wtc): reset more members? | 302 // TODO(wtc): reset more members? |
| 315 bytes_decrypted_ = 0; | 303 bytes_decrypted_ = 0; |
| 316 bytes_received_ = 0; | 304 bytes_received_ = 0; |
| 317 } | 305 } |
| 318 | 306 |
| 319 bool SSLClientSocketWin::IsConnected() const { | 307 bool SSLClientSocketWin::IsConnected() const { |
| 320 // Ideally, we should also check if we have received the close_notify alert | 308 // Ideally, we should also check if we have received the close_notify alert |
| 321 // message from the server, and return false in that case. We're not doing | 309 // message from the server, and return false in that case. We're not doing |
| 322 // that, so this function may return a false positive. Since the upper | 310 // that, so this function may return a false positive. Since the upper |
| (...skipping 367 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 690 } | 678 } |
| 691 | 679 |
| 692 return OK; | 680 return OK; |
| 693 } | 681 } |
| 694 | 682 |
| 695 // Set server_cert_status_ and return OK or a network error. | 683 // Set server_cert_status_ and return OK or a network error. |
| 696 int SSLClientSocketWin::DoVerifyCert() { | 684 int SSLClientSocketWin::DoVerifyCert() { |
| 697 next_state_ = STATE_VERIFY_CERT_COMPLETE; | 685 next_state_ = STATE_VERIFY_CERT_COMPLETE; |
| 698 | 686 |
| 699 DCHECK(server_cert_); | 687 DCHECK(server_cert_); |
| 700 | 688 return verifier_.Verify(server_cert_, hostname_, |
| 701 PCCERT_CONTEXT dup_cert = CertDuplicateCertificateContext(server_cert_); | 689 ssl_config_.rev_checking_enabled, |
| 702 scoped_refptr<X509Certificate> cert = | |
| 703 X509Certificate::CreateFromHandle(dup_cert, | |
| 704 X509Certificate::SOURCE_FROM_NETWORK); | |
| 705 return verifier_.Verify(cert, hostname_, ssl_config_.rev_checking_enabled, | |
| 706 &server_cert_verify_result_, &io_callback_); | 690 &server_cert_verify_result_, &io_callback_); |
| 707 } | 691 } |
| 708 | 692 |
| 709 int SSLClientSocketWin::DoVerifyCertComplete(int result) { | 693 int SSLClientSocketWin::DoVerifyCertComplete(int result) { |
| 710 LogConnectionTypeMetrics(); | 694 LogConnectionTypeMetrics(); |
| 711 return result; | 695 return result; |
| 712 } | 696 } |
| 713 | 697 |
| 714 int SSLClientSocketWin::DoPayloadRead() { | 698 int SSLClientSocketWin::DoPayloadRead() { |
| 715 next_state_ = STATE_PAYLOAD_READ_COMPLETE; | 699 next_state_ = STATE_PAYLOAD_READ_COMPLETE; |
| (...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 917 } | 901 } |
| 918 | 902 |
| 919 int SSLClientSocketWin::DidCompleteHandshake() { | 903 int SSLClientSocketWin::DidCompleteHandshake() { |
| 920 SECURITY_STATUS status = QueryContextAttributes( | 904 SECURITY_STATUS status = QueryContextAttributes( |
| 921 &ctxt_, SECPKG_ATTR_STREAM_SIZES, &stream_sizes_); | 905 &ctxt_, SECPKG_ATTR_STREAM_SIZES, &stream_sizes_); |
| 922 if (status != SEC_E_OK) { | 906 if (status != SEC_E_OK) { |
| 923 DLOG(ERROR) << "QueryContextAttributes failed: " << status; | 907 DLOG(ERROR) << "QueryContextAttributes failed: " << status; |
| 924 return MapSecurityError(status); | 908 return MapSecurityError(status); |
| 925 } | 909 } |
| 926 DCHECK(!server_cert_); | 910 DCHECK(!server_cert_); |
| 911 PCCERT_CONTEXT server_cert_handle = NULL; |
| 927 status = QueryContextAttributes( | 912 status = QueryContextAttributes( |
| 928 &ctxt_, SECPKG_ATTR_REMOTE_CERT_CONTEXT, &server_cert_); | 913 &ctxt_, SECPKG_ATTR_REMOTE_CERT_CONTEXT, &server_cert_handle); |
| 929 if (status != SEC_E_OK) { | 914 if (status != SEC_E_OK) { |
| 930 DLOG(ERROR) << "QueryContextAttributes failed: " << status; | 915 DLOG(ERROR) << "QueryContextAttributes failed: " << status; |
| 931 return MapSecurityError(status); | 916 return MapSecurityError(status); |
| 932 } | 917 } |
| 918 server_cert_ = X509Certificate::CreateFromHandle( |
| 919 server_cert_handle, X509Certificate::SOURCE_FROM_NETWORK); |
| 933 | 920 |
| 934 completed_handshake_ = true; | 921 completed_handshake_ = true; |
| 935 next_state_ = STATE_VERIFY_CERT; | 922 next_state_ = STATE_VERIFY_CERT; |
| 936 return OK; | 923 return OK; |
| 937 } | 924 } |
| 938 | 925 |
| 939 void SSLClientSocketWin::LogConnectionTypeMetrics() const { | 926 void SSLClientSocketWin::LogConnectionTypeMetrics() const { |
| 940 UpdateConnectionTypeHistograms(CONNECTION_SSL); | 927 UpdateConnectionTypeHistograms(CONNECTION_SSL); |
| 941 if (server_cert_verify_result_.has_md5) | 928 if (server_cert_verify_result_.has_md5) |
| 942 UpdateConnectionTypeHistograms(CONNECTION_SSL_MD5); | 929 UpdateConnectionTypeHistograms(CONNECTION_SSL_MD5); |
| 943 if (server_cert_verify_result_.has_md2) | 930 if (server_cert_verify_result_.has_md2) |
| 944 UpdateConnectionTypeHistograms(CONNECTION_SSL_MD2); | 931 UpdateConnectionTypeHistograms(CONNECTION_SSL_MD2); |
| 945 if (server_cert_verify_result_.has_md4) | 932 if (server_cert_verify_result_.has_md4) |
| 946 UpdateConnectionTypeHistograms(CONNECTION_SSL_MD4); | 933 UpdateConnectionTypeHistograms(CONNECTION_SSL_MD4); |
| 947 if (server_cert_verify_result_.has_md5_ca) | 934 if (server_cert_verify_result_.has_md5_ca) |
| 948 UpdateConnectionTypeHistograms(CONNECTION_SSL_MD5_CA); | 935 UpdateConnectionTypeHistograms(CONNECTION_SSL_MD5_CA); |
| 949 if (server_cert_verify_result_.has_md2_ca) | 936 if (server_cert_verify_result_.has_md2_ca) |
| 950 UpdateConnectionTypeHistograms(CONNECTION_SSL_MD2_CA); | 937 UpdateConnectionTypeHistograms(CONNECTION_SSL_MD2_CA); |
| 951 } | 938 } |
| 952 | 939 |
| 953 } // namespace net | 940 } // namespace net |
| 954 | 941 |
| OLD | NEW |