Chromium Code Reviews| Index: net/socket_stream/socket_stream.cc |
| diff --git a/net/socket_stream/socket_stream.cc b/net/socket_stream/socket_stream.cc |
| index 8ea686a53e66b44ed95e38c90f18743a631cf966..7f1af5915d6d8d68d9febc2b9cb9138616a613c1 100644 |
| --- a/net/socket_stream/socket_stream.cc |
| +++ b/net/socket_stream/socket_stream.cc |
| @@ -21,9 +21,12 @@ |
| #include "net/base/io_buffer.h" |
| #include "net/base/net_errors.h" |
| #include "net/base/net_util.h" |
| +#include "net/base/ssl_cert_request_info.h" |
| #include "net/http/http_auth_handler_factory.h" |
| +#include "net/http/http_network_session.h" |
| #include "net/http/http_request_info.h" |
| #include "net/http/http_response_headers.h" |
| +#include "net/http/http_transaction_factory.h" |
| #include "net/http/http_util.h" |
| #include "net/socket/client_socket_factory.h" |
| #include "net/socket/socks5_client_socket.h" |
| @@ -923,6 +926,8 @@ int SocketStream::DoSecureProxyConnectComplete(int result) { |
| result = DidEstablishSSL(result); |
| if (next_state_ != STATE_NONE) |
| return result; |
| + if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) |
| + return HandleCertificateRequest(result); |
| if (result == OK) |
| next_state_ = STATE_WRITE_TUNNEL_HEADERS; |
| else |
| @@ -1088,6 +1093,53 @@ int SocketStream::HandleAuthChallenge(const HttpResponseHeaders* headers) { |
| return ERR_TUNNEL_CONNECTION_FAILED; |
| } |
| +int SocketStream::HandleCertificateRequest(int result) { |
| + // TODO(toyoshim): We must support SSL client authentication for not only |
| + // secure proxy but also secure server. |
| + |
| + if (ssl_config_.send_client_cert) |
|
ukai
2011/10/17 01:48:56
we might need to have 2 SSLConfig?
server_ssl_con
Takashi Toyoshima
2011/10/17 02:50:05
When we support client authentication for secure s
ukai
2011/10/17 04:18:08
even without client authentication, can we use the
Takashi Toyoshima
2011/10/17 04:42:30
Oops!
Sorry, now I see what was wrong
I fix it.
|
| + // We already have performed SSL client authentication once and failed. |
| + return result; |
| + |
| + DCHECK(socket_.get()); |
| + scoped_refptr<SSLCertRequestInfo> cert_request_info = new SSLCertRequestInfo; |
| + SSLClientSocket* ssl_socket = |
| + reinterpret_cast<SSLClientSocket*>(socket_.get()); |
|
ukai
2011/10/17 01:48:56
static_cast ?
Takashi Toyoshima
2011/10/17 02:50:05
Right.
I fixed it and a same wrong cast in DidEsta
|
| + ssl_socket->GetSSLCertRequestInfo(cert_request_info); |
| + |
| + HttpTransactionFactory* factory = context_->http_transaction_factory(); |
| + if (!factory) |
| + return result; |
| + scoped_refptr<HttpNetworkSession> session = factory->GetSession(); |
| + if (!session.get()) |
| + return result; |
| + |
| + scoped_refptr<X509Certificate> client_cert; |
| + bool found_cached_cert = session->ssl_client_auth_cache()->Lookup( |
| + cert_request_info->host_and_port, &client_cert); |
| + if (!found_cached_cert) |
| + return result; |
| + if (!client_cert) |
| + return result; |
| + |
| + const std::vector<scoped_refptr<X509Certificate> >& client_certs = |
| + cert_request_info->client_certs; |
| + bool cert_still_valid = false; |
| + for (size_t i = 0; i < client_certs.size(); ++i) { |
| + if (client_cert->Equals(client_certs[i])) { |
| + cert_still_valid = true; |
| + break; |
| + } |
| + } |
| + if (!cert_still_valid) |
| + return result; |
| + |
| + ssl_config_.send_client_cert = true; |
| + ssl_config_.client_cert = client_cert; |
| + next_state_ = STATE_TCP_CONNECT; |
| + return OK; |
| +} |
| + |
| void SocketStream::DoAuthRequired() { |
| if (delegate_ && auth_info_.get()) |
| delegate_->OnAuthRequired(this, auth_info_.get()); |