summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
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();