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 |