summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorukai@chromium.org <ukai@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-01-19 10:30:53 +0000
committerukai@chromium.org <ukai@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-01-19 10:30:53 +0000
commit7bab769c20fc49cd1fbd55177b8ce26b471d7c22 (patch)
treef6ad33c152214f338e6694e7d557a017a00b6fee /net
parentd58e172826d246e93777ba10087f73b63f206724 (diff)
downloadchromium_src-7bab769c20fc49cd1fbd55177b8ce26b471d7c22.zip
chromium_src-7bab769c20fc49cd1fbd55177b8ce26b471d7c22.tar.gz
chromium_src-7bab769c20fc49cd1fbd55177b8ce26b471d7c22.tar.bz2
Fix secure websocket (wss) on Mac.
When SSLClientSocket of Mac reports certificate error (e.g. ERR_CERT_AUTHORITY_INVALID), it hasn't finish the SSL handshake and doesn't report the socket is connected. So, even if we tricks the result from SSLClientSocket::Connect by HandleCertificateError, it will be handled as ERR_CONNECTION_FAILED because socket_->IsConnected() is false. So, when SSLClientSocket::Connect reported certificate error and socket_->IsConnectedAndIdle() is false, get the certificate and retry establishing connection again with the certificate in allowed bad certificates, so we could ignore the certificate verify error. Without this fix, websocket live experiment on mac always fails for secure connection. BUG=32569 TEST=try open wss: connection and got open events. Review URL: http://codereview.chromium.org/543111 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@36519 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net')
-rw-r--r--net/socket_stream/socket_stream.cc37
1 files changed, 35 insertions, 2 deletions
diff --git a/net/socket_stream/socket_stream.cc b/net/socket_stream/socket_stream.cc
index 402b8ec..2a01f17 100644
--- a/net/socket_stream/socket_stream.cc
+++ b/net/socket_stream/socket_stream.cc
@@ -740,8 +740,41 @@ int SocketStream::DoSSLConnect() {
}
int SocketStream::DoSSLConnectComplete(int result) {
- if (IsCertificateError(result))
- result = HandleCertificateError(result);
+ if (IsCertificateError(result)) {
+ if (socket_->IsConnectedAndIdle()) {
+ result = HandleCertificateError(result);
+ } else {
+ // SSLClientSocket for Mac will report socket is not connected,
+ // if it returns cert verification error. It didn't perform
+ // SSLHandshake yet.
+ // So, we should restart establishing connection with the
+ // certificate in allowed bad certificates in |ssl_config_|.
+ // See also net/http/http_network_transaction.cc
+ // HandleCertificateError() and RestartIgnoringLastError().
+ SSLClientSocket* ssl_socket =
+ reinterpret_cast<SSLClientSocket*>(socket_.get());
+ SSLInfo ssl_info;
+ ssl_socket->GetSSLInfo(&ssl_info);
+ SSLConfig::CertAndStatus bad_cert;
+ bad_cert.cert = ssl_info.cert;
+ bad_cert.cert_status = ssl_info.cert_status;
+ if (ssl_config_.IsAllowedBadCert(ssl_info.cert)) {
+ // If we already have the certificate in the set of allowed bad
+ // certificates, we did try it and failed again, so we should not
+ // retry again: the connection should fail at last.
+ next_state_ = STATE_CLOSE;
+ return result;
+ }
+ // Add the bad certificate to the set of allowed certificates in the
+ // SSL info object.
+ ssl_config_.allowed_bad_certs.push_back(bad_cert);
+ // Restart connection ignoring the bad certificate.
+ socket_->Disconnect();
+ socket_.reset();
+ next_state_ = STATE_TCP_CONNECT;
+ return OK;
+ }
+ }
if (result == OK)
result = DidEstablishConnection();