| 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 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 53 case SEC_E_INVALID_HANDLE: | 53 case SEC_E_INVALID_HANDLE: |
| 54 return ERR_UNEXPECTED; | 54 return ERR_UNEXPECTED; |
| 55 case SEC_E_OK: | 55 case SEC_E_OK: |
| 56 return OK; | 56 return OK; |
| 57 default: | 57 default: |
| 58 LOG(WARNING) << "Unknown error " << err << " mapped to net::ERR_FAILED"; | 58 LOG(WARNING) << "Unknown error " << err << " mapped to net::ERR_FAILED"; |
| 59 return ERR_FAILED; | 59 return ERR_FAILED; |
| 60 } | 60 } |
| 61 } | 61 } |
| 62 | 62 |
| 63 // Returns true if the two CERT_CONTEXTs contain the same certificate. |
| 64 bool SameCert(PCCERT_CONTEXT a, PCCERT_CONTEXT b) { |
| 65 return a->cbCertEncoded == b->cbCertEncoded && |
| 66 memcmp(a->pbCertEncoded, b->pbCertEncoded, b->cbCertEncoded) == 0; |
| 67 } |
| 68 |
| 63 //----------------------------------------------------------------------------- | 69 //----------------------------------------------------------------------------- |
| 64 | 70 |
| 65 // A bitmask consisting of these bit flags encodes which versions of the SSL | 71 // A bitmask consisting of these bit flags encodes which versions of the SSL |
| 66 // protocol (SSL 2.0, SSL 3.0, and TLS 1.0) are enabled. | 72 // protocol (SSL 2.0, SSL 3.0, and TLS 1.0) are enabled. |
| 67 enum { | 73 enum { |
| 68 SSL2 = 1 << 0, | 74 SSL2 = 1 << 0, |
| 69 SSL3 = 1 << 1, | 75 SSL3 = 1 << 1, |
| 70 TLS1 = 1 << 2, | 76 TLS1 = 1 << 2, |
| 71 SSL_VERSION_MASKS = 1 << 3 // The number of SSL version bitmasks. | 77 SSL_VERSION_MASKS = 1 << 3 // The number of SSL version bitmasks. |
| 72 }; | 78 }; |
| (...skipping 647 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 720 // Eventually, we should cache the cert verification results so that we don't | 726 // Eventually, we should cache the cert verification results so that we don't |
| 721 // need to call verifier_.Verify repeatedly. But for now we need to do this. | 727 // need to call verifier_.Verify repeatedly. But for now we need to do this. |
| 722 // Alternatively, we might be able to store the cert's status along with | 728 // Alternatively, we might be able to store the cert's status along with |
| 723 // the cert in the allowed_bad_certs_ set. | 729 // the cert in the allowed_bad_certs_ set. |
| 724 if (IsCertificateError(result) && | 730 if (IsCertificateError(result) && |
| 725 ssl_config_.allowed_bad_certs_.count(server_cert_)) | 731 ssl_config_.allowed_bad_certs_.count(server_cert_)) |
| 726 result = OK; | 732 result = OK; |
| 727 | 733 |
| 728 LogConnectionTypeMetrics(); | 734 LogConnectionTypeMetrics(); |
| 729 if (renegotiating_) { | 735 if (renegotiating_) { |
| 730 // A rehandshake, started in the middle of a Read, has completed. | 736 DidCompleteRenegotiation(result); |
| 731 renegotiating_ = false; | |
| 732 // Pick up where we left off. Go back to reading data. | |
| 733 if (result == OK) | |
| 734 SetNextStateForRead(); | |
| 735 } else { | 737 } else { |
| 736 // The initial handshake, kicked off by a Connect, has completed. | 738 // The initial handshake, kicked off by a Connect, has completed. |
| 737 completed_handshake_ = true; | 739 completed_handshake_ = true; |
| 738 // Exit DoLoop and return the result to the caller of Connect. | 740 // Exit DoLoop and return the result to the caller of Connect. |
| 739 DCHECK(next_state_ == STATE_NONE); | 741 DCHECK(next_state_ == STATE_NONE); |
| 740 } | 742 } |
| 741 return result; | 743 return result; |
| 742 } | 744 } |
| 743 | 745 |
| 744 int SSLClientSocketWin::DoPayloadRead() { | 746 int SSLClientSocketWin::DoPayloadRead() { |
| (...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 991 return MapSecurityError(status); | 993 return MapSecurityError(status); |
| 992 } | 994 } |
| 993 DCHECK(!server_cert_ || renegotiating_); | 995 DCHECK(!server_cert_ || renegotiating_); |
| 994 PCCERT_CONTEXT server_cert_handle = NULL; | 996 PCCERT_CONTEXT server_cert_handle = NULL; |
| 995 status = QueryContextAttributes( | 997 status = QueryContextAttributes( |
| 996 &ctxt_, SECPKG_ATTR_REMOTE_CERT_CONTEXT, &server_cert_handle); | 998 &ctxt_, SECPKG_ATTR_REMOTE_CERT_CONTEXT, &server_cert_handle); |
| 997 if (status != SEC_E_OK) { | 999 if (status != SEC_E_OK) { |
| 998 DLOG(ERROR) << "QueryContextAttributes failed: " << status; | 1000 DLOG(ERROR) << "QueryContextAttributes failed: " << status; |
| 999 return MapSecurityError(status); | 1001 return MapSecurityError(status); |
| 1000 } | 1002 } |
| 1001 server_cert_ = X509Certificate::CreateFromHandle( | 1003 if (renegotiating_ && |
| 1002 server_cert_handle, X509Certificate::SOURCE_FROM_NETWORK); | 1004 SameCert(server_cert_->os_cert_handle(), server_cert_handle)) { |
| 1005 // We already verified the server certificate. Either it is good or the |
| 1006 // user has accepted the certificate error. |
| 1007 CertFreeCertificateContext(server_cert_handle); |
| 1008 DidCompleteRenegotiation(OK); |
| 1009 } else { |
| 1010 server_cert_ = X509Certificate::CreateFromHandle( |
| 1011 server_cert_handle, X509Certificate::SOURCE_FROM_NETWORK); |
| 1003 | 1012 |
| 1004 next_state_ = STATE_VERIFY_CERT; | 1013 next_state_ = STATE_VERIFY_CERT; |
| 1014 } |
| 1005 return OK; | 1015 return OK; |
| 1006 } | 1016 } |
| 1007 | 1017 |
| 1018 // Called when a renegotiation is completed. |result| is the verification |
| 1019 // result of the server certificate received during renegotiation. |
| 1020 void SSLClientSocketWin::DidCompleteRenegotiation(int result) { |
| 1021 // A rehandshake, started in the middle of a Read, has completed. |
| 1022 renegotiating_ = false; |
| 1023 // Pick up where we left off. Go back to reading data. |
| 1024 if (result == OK) |
| 1025 SetNextStateForRead(); |
| 1026 } |
| 1027 |
| 1008 void SSLClientSocketWin::LogConnectionTypeMetrics() const { | 1028 void SSLClientSocketWin::LogConnectionTypeMetrics() const { |
| 1009 UpdateConnectionTypeHistograms(CONNECTION_SSL); | 1029 UpdateConnectionTypeHistograms(CONNECTION_SSL); |
| 1010 if (server_cert_verify_result_.has_md5) | 1030 if (server_cert_verify_result_.has_md5) |
| 1011 UpdateConnectionTypeHistograms(CONNECTION_SSL_MD5); | 1031 UpdateConnectionTypeHistograms(CONNECTION_SSL_MD5); |
| 1012 if (server_cert_verify_result_.has_md2) | 1032 if (server_cert_verify_result_.has_md2) |
| 1013 UpdateConnectionTypeHistograms(CONNECTION_SSL_MD2); | 1033 UpdateConnectionTypeHistograms(CONNECTION_SSL_MD2); |
| 1014 if (server_cert_verify_result_.has_md4) | 1034 if (server_cert_verify_result_.has_md4) |
| 1015 UpdateConnectionTypeHistograms(CONNECTION_SSL_MD4); | 1035 UpdateConnectionTypeHistograms(CONNECTION_SSL_MD4); |
| 1016 if (server_cert_verify_result_.has_md5_ca) | 1036 if (server_cert_verify_result_.has_md5_ca) |
| 1017 UpdateConnectionTypeHistograms(CONNECTION_SSL_MD5_CA); | 1037 UpdateConnectionTypeHistograms(CONNECTION_SSL_MD5_CA); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1028 } | 1048 } |
| 1029 } | 1049 } |
| 1030 | 1050 |
| 1031 void SSLClientSocketWin::FreeSendBuffer() { | 1051 void SSLClientSocketWin::FreeSendBuffer() { |
| 1032 SECURITY_STATUS status = FreeContextBuffer(send_buffer_.pvBuffer); | 1052 SECURITY_STATUS status = FreeContextBuffer(send_buffer_.pvBuffer); |
| 1033 DCHECK(status == SEC_E_OK); | 1053 DCHECK(status == SEC_E_OK); |
| 1034 memset(&send_buffer_, 0, sizeof(send_buffer_)); | 1054 memset(&send_buffer_, 0, sizeof(send_buffer_)); |
| 1035 } | 1055 } |
| 1036 | 1056 |
| 1037 } // namespace net | 1057 } // namespace net |
| OLD | NEW |