| 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 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 52 case SEC_E_INVALID_HANDLE: | 52 case SEC_E_INVALID_HANDLE: |
| 53 return ERR_UNEXPECTED; | 53 return ERR_UNEXPECTED; |
| 54 case SEC_E_OK: | 54 case SEC_E_OK: |
| 55 return OK; | 55 return OK; |
| 56 default: | 56 default: |
| 57 LOG(WARNING) << "Unknown error " << err << " mapped to net::ERR_FAILED"; | 57 LOG(WARNING) << "Unknown error " << err << " mapped to net::ERR_FAILED"; |
| 58 return ERR_FAILED; | 58 return ERR_FAILED; |
| 59 } | 59 } |
| 60 } | 60 } |
| 61 | 61 |
| 62 // Returns true if the two CERT_CONTEXTs contain the same certificate. |
| 63 bool SameCert(PCCERT_CONTEXT a, PCCERT_CONTEXT b) { |
| 64 return a->cbCertEncoded == b->cbCertEncoded && |
| 65 memcmp(a->pbCertEncoded, b->pbCertEncoded, b->cbCertEncoded) == 0; |
| 66 } |
| 67 |
| 62 //----------------------------------------------------------------------------- | 68 //----------------------------------------------------------------------------- |
| 63 | 69 |
| 64 // A bitmask consisting of these bit flags encodes which versions of the SSL | 70 // A bitmask consisting of these bit flags encodes which versions of the SSL |
| 65 // protocol (SSL 2.0, SSL 3.0, and TLS 1.0) are enabled. | 71 // protocol (SSL 2.0, SSL 3.0, and TLS 1.0) are enabled. |
| 66 enum { | 72 enum { |
| 67 SSL2 = 1 << 0, | 73 SSL2 = 1 << 0, |
| 68 SSL3 = 1 << 1, | 74 SSL3 = 1 << 1, |
| 69 TLS1 = 1 << 2, | 75 TLS1 = 1 << 2, |
| 70 SSL_VERSION_MASKS = 1 << 3 // The number of SSL version bitmasks. | 76 SSL_VERSION_MASKS = 1 << 3 // The number of SSL version bitmasks. |
| 71 }; | 77 }; |
| (...skipping 634 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 706 | 712 |
| 707 DCHECK(server_cert_); | 713 DCHECK(server_cert_); |
| 708 return verifier_.Verify(server_cert_, hostname_, | 714 return verifier_.Verify(server_cert_, hostname_, |
| 709 ssl_config_.rev_checking_enabled, | 715 ssl_config_.rev_checking_enabled, |
| 710 &server_cert_verify_result_, &io_callback_); | 716 &server_cert_verify_result_, &io_callback_); |
| 711 } | 717 } |
| 712 | 718 |
| 713 int SSLClientSocketWin::DoVerifyCertComplete(int result) { | 719 int SSLClientSocketWin::DoVerifyCertComplete(int result) { |
| 714 LogConnectionTypeMetrics(); | 720 LogConnectionTypeMetrics(); |
| 715 if (renegotiating_) { | 721 if (renegotiating_) { |
| 716 // A rehandshake, started in the middle of a Read, has completed. | 722 DidCompleteRenegotiation(result); |
| 717 renegotiating_ = false; | |
| 718 // Pick up where we left off. Go back to reading data. | |
| 719 if (result == OK) | |
| 720 SetNextStateForRead(); | |
| 721 } else { | 723 } else { |
| 722 // The initial handshake, kicked off by a Connect, has completed. | 724 // The initial handshake, kicked off by a Connect, has completed. |
| 723 completed_handshake_ = true; | 725 completed_handshake_ = true; |
| 724 // Exit DoLoop and return the result to the caller of Connect. | 726 // Exit DoLoop and return the result to the caller of Connect. |
| 725 DCHECK(next_state_ == STATE_NONE); | 727 DCHECK(next_state_ == STATE_NONE); |
| 726 } | 728 } |
| 727 return result; | 729 return result; |
| 728 } | 730 } |
| 729 | 731 |
| 730 int SSLClientSocketWin::DoPayloadRead() { | 732 int SSLClientSocketWin::DoPayloadRead() { |
| (...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 957 return MapSecurityError(status); | 959 return MapSecurityError(status); |
| 958 } | 960 } |
| 959 DCHECK(!server_cert_ || renegotiating_); | 961 DCHECK(!server_cert_ || renegotiating_); |
| 960 PCCERT_CONTEXT server_cert_handle = NULL; | 962 PCCERT_CONTEXT server_cert_handle = NULL; |
| 961 status = QueryContextAttributes( | 963 status = QueryContextAttributes( |
| 962 &ctxt_, SECPKG_ATTR_REMOTE_CERT_CONTEXT, &server_cert_handle); | 964 &ctxt_, SECPKG_ATTR_REMOTE_CERT_CONTEXT, &server_cert_handle); |
| 963 if (status != SEC_E_OK) { | 965 if (status != SEC_E_OK) { |
| 964 DLOG(ERROR) << "QueryContextAttributes failed: " << status; | 966 DLOG(ERROR) << "QueryContextAttributes failed: " << status; |
| 965 return MapSecurityError(status); | 967 return MapSecurityError(status); |
| 966 } | 968 } |
| 967 server_cert_ = X509Certificate::CreateFromHandle( | 969 if (renegotiating_ && |
| 968 server_cert_handle, X509Certificate::SOURCE_FROM_NETWORK); | 970 SameCert(server_cert_->os_cert_handle(), server_cert_handle)) { |
| 971 // We already verified the server certificate. Either it is good or the |
| 972 // user has accepted the certificate error. |
| 973 CertFreeCertificateContext(server_cert_handle); |
| 974 DidCompleteRenegotiation(OK); |
| 975 } else { |
| 976 server_cert_ = X509Certificate::CreateFromHandle( |
| 977 server_cert_handle, X509Certificate::SOURCE_FROM_NETWORK); |
| 969 | 978 |
| 970 next_state_ = STATE_VERIFY_CERT; | 979 next_state_ = STATE_VERIFY_CERT; |
| 980 } |
| 971 return OK; | 981 return OK; |
| 972 } | 982 } |
| 973 | 983 |
| 984 // Called when a renegotiation is completed. |result| is the verification |
| 985 // result of the server certificate received during renegotiation. |
| 986 void SSLClientSocketWin::DidCompleteRenegotiation(int result) { |
| 987 // A rehandshake, started in the middle of a Read, has completed. |
| 988 renegotiating_ = false; |
| 989 // Pick up where we left off. Go back to reading data. |
| 990 if (result == OK) |
| 991 SetNextStateForRead(); |
| 992 } |
| 993 |
| 974 void SSLClientSocketWin::LogConnectionTypeMetrics() const { | 994 void SSLClientSocketWin::LogConnectionTypeMetrics() const { |
| 975 UpdateConnectionTypeHistograms(CONNECTION_SSL); | 995 UpdateConnectionTypeHistograms(CONNECTION_SSL); |
| 976 if (server_cert_verify_result_.has_md5) | 996 if (server_cert_verify_result_.has_md5) |
| 977 UpdateConnectionTypeHistograms(CONNECTION_SSL_MD5); | 997 UpdateConnectionTypeHistograms(CONNECTION_SSL_MD5); |
| 978 if (server_cert_verify_result_.has_md2) | 998 if (server_cert_verify_result_.has_md2) |
| 979 UpdateConnectionTypeHistograms(CONNECTION_SSL_MD2); | 999 UpdateConnectionTypeHistograms(CONNECTION_SSL_MD2); |
| 980 if (server_cert_verify_result_.has_md4) | 1000 if (server_cert_verify_result_.has_md4) |
| 981 UpdateConnectionTypeHistograms(CONNECTION_SSL_MD4); | 1001 UpdateConnectionTypeHistograms(CONNECTION_SSL_MD4); |
| 982 if (server_cert_verify_result_.has_md5_ca) | 1002 if (server_cert_verify_result_.has_md5_ca) |
| 983 UpdateConnectionTypeHistograms(CONNECTION_SSL_MD5_CA); | 1003 UpdateConnectionTypeHistograms(CONNECTION_SSL_MD5_CA); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 994 } | 1014 } |
| 995 } | 1015 } |
| 996 | 1016 |
| 997 void SSLClientSocketWin::FreeSendBuffer() { | 1017 void SSLClientSocketWin::FreeSendBuffer() { |
| 998 SECURITY_STATUS status = FreeContextBuffer(send_buffer_.pvBuffer); | 1018 SECURITY_STATUS status = FreeContextBuffer(send_buffer_.pvBuffer); |
| 999 DCHECK(status == SEC_E_OK); | 1019 DCHECK(status == SEC_E_OK); |
| 1000 memset(&send_buffer_, 0, sizeof(send_buffer_)); | 1020 memset(&send_buffer_, 0, sizeof(send_buffer_)); |
| 1001 } | 1021 } |
| 1002 | 1022 |
| 1003 } // namespace net | 1023 } // namespace net |
| OLD | NEW |