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 |