| Index: net/base/ssl_client_socket_win.cc
|
| ===================================================================
|
| --- net/base/ssl_client_socket_win.cc (revision 17904)
|
| +++ net/base/ssl_client_socket_win.cc (working copy)
|
| @@ -60,6 +60,12 @@
|
| }
|
| }
|
|
|
| +// Returns true if the two CERT_CONTEXTs contain the same certificate.
|
| +bool SameCert(PCCERT_CONTEXT a, PCCERT_CONTEXT b) {
|
| + return a->cbCertEncoded == b->cbCertEncoded &&
|
| + memcmp(a->pbCertEncoded, b->pbCertEncoded, b->cbCertEncoded) == 0;
|
| +}
|
| +
|
| //-----------------------------------------------------------------------------
|
|
|
| // A bitmask consisting of these bit flags encodes which versions of the SSL
|
| @@ -727,11 +733,7 @@
|
|
|
| LogConnectionTypeMetrics();
|
| if (renegotiating_) {
|
| - // A rehandshake, started in the middle of a Read, has completed.
|
| - renegotiating_ = false;
|
| - // Pick up where we left off. Go back to reading data.
|
| - if (result == OK)
|
| - SetNextStateForRead();
|
| + DidCompleteRenegotiation(result);
|
| } else {
|
| // The initial handshake, kicked off by a Connect, has completed.
|
| completed_handshake_ = true;
|
| @@ -998,13 +1000,31 @@
|
| DLOG(ERROR) << "QueryContextAttributes failed: " << status;
|
| return MapSecurityError(status);
|
| }
|
| - server_cert_ = X509Certificate::CreateFromHandle(
|
| - server_cert_handle, X509Certificate::SOURCE_FROM_NETWORK);
|
| + if (renegotiating_ &&
|
| + SameCert(server_cert_->os_cert_handle(), server_cert_handle)) {
|
| + // We already verified the server certificate. Either it is good or the
|
| + // user has accepted the certificate error.
|
| + CertFreeCertificateContext(server_cert_handle);
|
| + DidCompleteRenegotiation(OK);
|
| + } else {
|
| + server_cert_ = X509Certificate::CreateFromHandle(
|
| + server_cert_handle, X509Certificate::SOURCE_FROM_NETWORK);
|
|
|
| - next_state_ = STATE_VERIFY_CERT;
|
| + next_state_ = STATE_VERIFY_CERT;
|
| + }
|
| return OK;
|
| }
|
|
|
| +// Called when a renegotiation is completed. |result| is the verification
|
| +// result of the server certificate received during renegotiation.
|
| +void SSLClientSocketWin::DidCompleteRenegotiation(int result) {
|
| + // A rehandshake, started in the middle of a Read, has completed.
|
| + renegotiating_ = false;
|
| + // Pick up where we left off. Go back to reading data.
|
| + if (result == OK)
|
| + SetNextStateForRead();
|
| +}
|
| +
|
| void SSLClientSocketWin::LogConnectionTypeMetrics() const {
|
| UpdateConnectionTypeHistograms(CONNECTION_SSL);
|
| if (server_cert_verify_result_.has_md5)
|
|
|