| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "content/browser/renderer_host/pepper_tcp_socket.h" | 5 #include "content/browser/renderer_host/pepper_tcp_socket.h" |
| 6 | 6 |
| 7 #include <string.h> | 7 #include <string.h> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/bind_helpers.h" | 10 #include "base/bind_helpers.h" |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 96 !NetAddressPrivateImpl::NetAddressToAddressList(net_addr, | 96 !NetAddressPrivateImpl::NetAddressToAddressList(net_addr, |
| 97 &address_list_)) { | 97 &address_list_)) { |
| 98 SendConnectACKError(); | 98 SendConnectACKError(); |
| 99 return; | 99 return; |
| 100 } | 100 } |
| 101 | 101 |
| 102 connection_state_ = CONNECT_IN_PROGRESS; | 102 connection_state_ = CONNECT_IN_PROGRESS; |
| 103 StartConnect(address_list_); | 103 StartConnect(address_list_); |
| 104 } | 104 } |
| 105 | 105 |
| 106 void PepperTCPSocket::SSLHandshake(const std::string& server_name, | 106 void PepperTCPSocket::SSLHandshake( |
| 107 uint16_t server_port) { | 107 const std::string& server_name, |
| 108 uint16_t server_port, |
| 109 const std::vector<std::vector<char> >& trusted_certs, |
| 110 const std::vector<std::vector<char> >& untrusted_certs) { |
| 108 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 111 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 109 | 112 |
| 110 // Allow to do SSL handshake only if currently the socket has been connected | 113 // Allow to do SSL handshake only if currently the socket has been connected |
| 111 // and there isn't pending read or write. | 114 // and there isn't pending read or write. |
| 112 // IsConnected() includes the state that SSL handshake has been finished and | 115 // IsConnected() includes the state that SSL handshake has been finished and |
| 113 // therefore isn't suitable here. | 116 // therefore isn't suitable here. |
| 114 if (connection_state_ != CONNECTED || read_buffer_.get() || | 117 if (connection_state_ != CONNECTED || read_buffer_.get() || |
| 115 write_buffer_.get()) { | 118 write_buffer_.get()) { |
| 116 SendSSLHandshakeACK(false); | 119 SendSSLHandshakeACK(false); |
| 117 return; | 120 return; |
| 118 } | 121 } |
| 119 | 122 |
| 120 connection_state_ = SSL_HANDSHAKE_IN_PROGRESS; | 123 connection_state_ = SSL_HANDSHAKE_IN_PROGRESS; |
| 124 std::vector<scoped_refptr<net::X509Certificate> > parsed_trusted_certs; |
| 125 std::vector<scoped_refptr<net::X509Certificate> > parsed_untrusted_certs; |
| 126 bool success = ParseCertificates(trusted_certs, &parsed_trusted_certs) && |
| 127 ParseCertificates(untrusted_certs, &parsed_untrusted_certs); |
| 128 if (!success) { |
| 129 LOG(WARNING) << "Failed to parse socket-specific certificates."; |
| 130 OnSSLHandshakeCompleted(net::ERR_CERT_CONTAINS_ERRORS); |
| 131 return; |
| 132 } |
| 133 // TODO(raymes,rsleevi): Use trusted/untrusted certificates when connecting. |
| 134 |
| 121 net::ClientSocketHandle* handle = new net::ClientSocketHandle(); | 135 net::ClientSocketHandle* handle = new net::ClientSocketHandle(); |
| 122 handle->set_socket(socket_.release()); | 136 handle->set_socket(socket_.release()); |
| 123 net::ClientSocketFactory* factory = | 137 net::ClientSocketFactory* factory = |
| 124 net::ClientSocketFactory::GetDefaultFactory(); | 138 net::ClientSocketFactory::GetDefaultFactory(); |
| 125 net::HostPortPair host_port_pair(server_name, server_port); | 139 net::HostPortPair host_port_pair(server_name, server_port); |
| 126 net::SSLClientSocketContext ssl_context; | 140 net::SSLClientSocketContext ssl_context; |
| 127 ssl_context.cert_verifier = manager_->GetCertVerifier(); | 141 ssl_context.cert_verifier = manager_->GetCertVerifier(); |
| 128 socket_.reset(factory->CreateSSLClientSocket( | 142 socket_.reset(factory->CreateSSLClientSocket( |
| 129 handle, host_port_pair, manager_->ssl_config(), NULL, ssl_context)); | 143 handle, host_port_pair, manager_->ssl_config(), NULL, ssl_context)); |
| 130 if (!socket_.get()) { | 144 if (!socket_.get()) { |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 228 manager_->Send(new PpapiMsg_PPBTCPSocket_ReadACK( | 242 manager_->Send(new PpapiMsg_PPBTCPSocket_ReadACK( |
| 229 routing_id_, plugin_dispatcher_id_, socket_id_, false, std::string())); | 243 routing_id_, plugin_dispatcher_id_, socket_id_, false, std::string())); |
| 230 } | 244 } |
| 231 | 245 |
| 232 void PepperTCPSocket::SendWriteACKError() { | 246 void PepperTCPSocket::SendWriteACKError() { |
| 233 manager_->Send(new PpapiMsg_PPBTCPSocket_WriteACK( | 247 manager_->Send(new PpapiMsg_PPBTCPSocket_WriteACK( |
| 234 routing_id_, plugin_dispatcher_id_, socket_id_, false, 0)); | 248 routing_id_, plugin_dispatcher_id_, socket_id_, false, 0)); |
| 235 } | 249 } |
| 236 | 250 |
| 237 void PepperTCPSocket::SendSSLHandshakeACK(bool succeeded) { | 251 void PepperTCPSocket::SendSSLHandshakeACK(bool succeeded) { |
| 252 ppapi::PPB_X509Certificate_Fields certificate_fields; |
| 253 if (succeeded) { |
| 254 CHECK(socket_.get()); |
| 255 // Our socket is guaranteed to be an SSL socket if we get here. |
| 256 net::SSLClientSocket* ssl_socket = |
| 257 static_cast<net::SSLClientSocket*>(socket_.get()); |
| 258 net::SSLInfo ssl_info; |
| 259 ssl_socket->GetSSLInfo(&ssl_info); |
| 260 bool success = GetCertificateFields(*ssl_info.cert, |
| 261 &certificate_fields); |
| 262 CHECK(success); |
| 263 } |
| 238 manager_->Send(new PpapiMsg_PPBTCPSocket_SSLHandshakeACK( | 264 manager_->Send(new PpapiMsg_PPBTCPSocket_SSLHandshakeACK( |
| 239 routing_id_, plugin_dispatcher_id_, socket_id_, succeeded)); | 265 routing_id_, |
| 266 plugin_dispatcher_id_, |
| 267 socket_id_, |
| 268 succeeded, |
| 269 certificate_fields)); |
| 240 } | 270 } |
| 241 | 271 |
| 242 void PepperTCPSocket::OnResolveCompleted(int result) { | 272 void PepperTCPSocket::OnResolveCompleted(int result) { |
| 243 DCHECK(connection_state_ == CONNECT_IN_PROGRESS); | 273 DCHECK(connection_state_ == CONNECT_IN_PROGRESS); |
| 244 | 274 |
| 245 if (result != net::OK) { | 275 if (result != net::OK) { |
| 246 SendConnectACKError(); | 276 SendConnectACKError(); |
| 247 connection_state_ = BEFORE_CONNECT; | 277 connection_state_ = BEFORE_CONNECT; |
| 248 return; | 278 return; |
| 249 } | 279 } |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 315 routing_id_, plugin_dispatcher_id_, socket_id_, true, result)); | 345 routing_id_, plugin_dispatcher_id_, socket_id_, true, result)); |
| 316 } else { | 346 } else { |
| 317 SendWriteACKError(); | 347 SendWriteACKError(); |
| 318 } | 348 } |
| 319 write_buffer_ = NULL; | 349 write_buffer_ = NULL; |
| 320 } | 350 } |
| 321 | 351 |
| 322 bool PepperTCPSocket::IsConnected() const { | 352 bool PepperTCPSocket::IsConnected() const { |
| 323 return connection_state_ == CONNECTED || connection_state_ == SSL_CONNECTED; | 353 return connection_state_ == CONNECTED || connection_state_ == SSL_CONNECTED; |
| 324 } | 354 } |
| 355 |
| 356 bool PepperTCPSocket::ParseCertificates( |
| 357 const std::vector<std::vector<char> >& certs, |
| 358 std::vector<scoped_refptr<net::X509Certificate> >* result) { |
| 359 for (size_t i = 0; i < certs.size(); ++i) { |
| 360 if (certs[i].size() == 0) { |
| 361 return false; |
| 362 } |
| 363 scoped_refptr<net::X509Certificate> cert = |
| 364 net::X509Certificate::CreateFromBytes(&certs[i][0], |
| 365 certs[i].size()); |
| 366 result->push_back(cert); |
| 367 } |
| 368 return true; |
| 369 } |
| OLD | NEW |