| 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 // OpenSSL binding for SSLClientSocket. The class layout and general principle | 5 // OpenSSL binding for SSLClientSocket. The class layout and general principle |
| 6 // of operation is derived from SSLClientSocketNSS. | 6 // of operation is derived from SSLClientSocketNSS. |
| 7 | 7 |
| 8 #include "net/socket/ssl_client_socket_openssl.h" | 8 #include "net/socket/ssl_client_socket_openssl.h" |
| 9 | 9 |
| 10 #include <openssl/err.h> | 10 #include <openssl/err.h> |
| (...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 336 SSLClientSocketOpenSSL::SSLClientSocketOpenSSL( | 336 SSLClientSocketOpenSSL::SSLClientSocketOpenSSL( |
| 337 scoped_ptr<ClientSocketHandle> transport_socket, | 337 scoped_ptr<ClientSocketHandle> transport_socket, |
| 338 const HostPortPair& host_and_port, | 338 const HostPortPair& host_and_port, |
| 339 const SSLConfig& ssl_config, | 339 const SSLConfig& ssl_config, |
| 340 const SSLClientSocketContext& context) | 340 const SSLClientSocketContext& context) |
| 341 : transport_send_busy_(false), | 341 : transport_send_busy_(false), |
| 342 transport_recv_busy_(false), | 342 transport_recv_busy_(false), |
| 343 transport_recv_eof_(false), | 343 transport_recv_eof_(false), |
| 344 weak_factory_(this), | 344 weak_factory_(this), |
| 345 pending_read_error_(kNoPendingReadResult), | 345 pending_read_error_(kNoPendingReadResult), |
| 346 transport_write_error_(OK), |
| 346 completed_handshake_(false), | 347 completed_handshake_(false), |
| 347 client_auth_cert_needed_(false), | 348 client_auth_cert_needed_(false), |
| 348 cert_verifier_(context.cert_verifier), | 349 cert_verifier_(context.cert_verifier), |
| 349 server_bound_cert_service_(context.server_bound_cert_service), | 350 server_bound_cert_service_(context.server_bound_cert_service), |
| 350 ssl_(NULL), | 351 ssl_(NULL), |
| 351 transport_bio_(NULL), | 352 transport_bio_(NULL), |
| 352 transport_(transport_socket.Pass()), | 353 transport_(transport_socket.Pass()), |
| 353 host_and_port_(host_and_port), | 354 host_and_port_(host_and_port), |
| 354 ssl_config_(ssl_config), | 355 ssl_config_(ssl_config), |
| 355 ssl_session_cache_shard_(context.ssl_session_cache_shard), | 356 ssl_session_cache_shard_(context.ssl_session_cache_shard), |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 459 recv_buffer_ = NULL; | 460 recv_buffer_ = NULL; |
| 460 | 461 |
| 461 user_connect_callback_.Reset(); | 462 user_connect_callback_.Reset(); |
| 462 user_read_callback_.Reset(); | 463 user_read_callback_.Reset(); |
| 463 user_write_callback_.Reset(); | 464 user_write_callback_.Reset(); |
| 464 user_read_buf_ = NULL; | 465 user_read_buf_ = NULL; |
| 465 user_read_buf_len_ = 0; | 466 user_read_buf_len_ = 0; |
| 466 user_write_buf_ = NULL; | 467 user_write_buf_ = NULL; |
| 467 user_write_buf_len_ = 0; | 468 user_write_buf_len_ = 0; |
| 468 | 469 |
| 470 pending_read_error_ = kNoPendingReadResult; |
| 471 transport_write_error_ = OK; |
| 472 |
| 469 server_cert_verify_result_.Reset(); | 473 server_cert_verify_result_.Reset(); |
| 470 completed_handshake_ = false; | 474 completed_handshake_ = false; |
| 471 | 475 |
| 472 cert_authorities_.clear(); | 476 cert_authorities_.clear(); |
| 473 client_auth_cert_needed_ = false; | 477 client_auth_cert_needed_ = false; |
| 474 } | 478 } |
| 475 | 479 |
| 476 bool SSLClientSocketOpenSSL::IsConnected() const { | 480 bool SSLClientSocketOpenSSL::IsConnected() const { |
| 477 // If the handshake has not yet completed. | 481 // If the handshake has not yet completed. |
| 478 if (!completed_handshake_) | 482 if (!completed_handshake_) |
| (...skipping 718 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1197 | 1201 |
| 1198 recv_buffer_ = new IOBuffer(max_write); | 1202 recv_buffer_ = new IOBuffer(max_write); |
| 1199 int rv = transport_->socket()->Read( | 1203 int rv = transport_->socket()->Read( |
| 1200 recv_buffer_.get(), | 1204 recv_buffer_.get(), |
| 1201 max_write, | 1205 max_write, |
| 1202 base::Bind(&SSLClientSocketOpenSSL::BufferRecvComplete, | 1206 base::Bind(&SSLClientSocketOpenSSL::BufferRecvComplete, |
| 1203 base::Unretained(this))); | 1207 base::Unretained(this))); |
| 1204 if (rv == ERR_IO_PENDING) { | 1208 if (rv == ERR_IO_PENDING) { |
| 1205 transport_recv_busy_ = true; | 1209 transport_recv_busy_ = true; |
| 1206 } else { | 1210 } else { |
| 1207 TransportReadComplete(rv); | 1211 rv = TransportReadComplete(rv); |
| 1208 } | 1212 } |
| 1209 return rv; | 1213 return rv; |
| 1210 } | 1214 } |
| 1211 | 1215 |
| 1212 void SSLClientSocketOpenSSL::BufferSendComplete(int result) { | 1216 void SSLClientSocketOpenSSL::BufferSendComplete(int result) { |
| 1213 transport_send_busy_ = false; | 1217 transport_send_busy_ = false; |
| 1214 TransportWriteComplete(result); | 1218 TransportWriteComplete(result); |
| 1215 OnSendComplete(result); | 1219 OnSendComplete(result); |
| 1216 } | 1220 } |
| 1217 | 1221 |
| 1218 void SSLClientSocketOpenSSL::BufferRecvComplete(int result) { | 1222 void SSLClientSocketOpenSSL::BufferRecvComplete(int result) { |
| 1219 TransportReadComplete(result); | 1223 result = TransportReadComplete(result); |
| 1220 OnRecvComplete(result); | 1224 OnRecvComplete(result); |
| 1221 } | 1225 } |
| 1222 | 1226 |
| 1223 void SSLClientSocketOpenSSL::TransportWriteComplete(int result) { | 1227 void SSLClientSocketOpenSSL::TransportWriteComplete(int result) { |
| 1224 DCHECK(ERR_IO_PENDING != result); | 1228 DCHECK(ERR_IO_PENDING != result); |
| 1225 if (result < 0) { | 1229 if (result < 0) { |
| 1226 // Got a socket write error; close the BIO to indicate this upward. | 1230 // Got a socket write error; close the BIO to indicate this upward. |
| 1231 // |
| 1232 // TODO(davidben): The value of |result| gets lost. Feed the error back into |
| 1233 // the BIO so it gets (re-)detected in OnSendComplete. Perhaps with |
| 1234 // BIO_set_callback. |
| 1227 DVLOG(1) << "TransportWriteComplete error " << result; | 1235 DVLOG(1) << "TransportWriteComplete error " << result; |
| 1236 (void)BIO_shutdown_wr(SSL_get_wbio(ssl_)); |
| 1237 |
| 1238 // Match the fix for http://crbug.com/249848 in NSS by erroring future reads |
| 1239 // from the socket after a write error. |
| 1240 // |
| 1241 // TODO(davidben): Avoid having read and write ends interact this way. |
| 1242 transport_write_error_ = result; |
| 1228 (void)BIO_shutdown_wr(transport_bio_); | 1243 (void)BIO_shutdown_wr(transport_bio_); |
| 1229 BIO_set_mem_eof_return(transport_bio_, 0); | |
| 1230 send_buffer_ = NULL; | 1244 send_buffer_ = NULL; |
| 1231 } else { | 1245 } else { |
| 1232 DCHECK(send_buffer_.get()); | 1246 DCHECK(send_buffer_.get()); |
| 1233 send_buffer_->DidConsume(result); | 1247 send_buffer_->DidConsume(result); |
| 1234 DCHECK_GE(send_buffer_->BytesRemaining(), 0); | 1248 DCHECK_GE(send_buffer_->BytesRemaining(), 0); |
| 1235 if (send_buffer_->BytesRemaining() <= 0) | 1249 if (send_buffer_->BytesRemaining() <= 0) |
| 1236 send_buffer_ = NULL; | 1250 send_buffer_ = NULL; |
| 1237 } | 1251 } |
| 1238 } | 1252 } |
| 1239 | 1253 |
| 1240 void SSLClientSocketOpenSSL::TransportReadComplete(int result) { | 1254 int SSLClientSocketOpenSSL::TransportReadComplete(int result) { |
| 1241 DCHECK(ERR_IO_PENDING != result); | 1255 DCHECK(ERR_IO_PENDING != result); |
| 1242 if (result <= 0) { | 1256 if (result <= 0) { |
| 1243 DVLOG(1) << "TransportReadComplete result " << result; | 1257 DVLOG(1) << "TransportReadComplete result " << result; |
| 1244 // Received 0 (end of file) or an error. Either way, bubble it up to the | 1258 // Received 0 (end of file) or an error. Either way, bubble it up to the |
| 1245 // SSL layer via the BIO. TODO(joth): consider stashing the error code, to | 1259 // SSL layer via the BIO. TODO(joth): consider stashing the error code, to |
| 1246 // relay up to the SSL socket client (i.e. via DoReadCallback). | 1260 // relay up to the SSL socket client (i.e. via DoReadCallback). |
| 1247 if (result == 0) | 1261 if (result == 0) |
| 1248 transport_recv_eof_ = true; | 1262 transport_recv_eof_ = true; |
| 1249 BIO_set_mem_eof_return(transport_bio_, 0); | |
| 1250 (void)BIO_shutdown_wr(transport_bio_); | 1263 (void)BIO_shutdown_wr(transport_bio_); |
| 1264 } else if (transport_write_error_ < 0) { |
| 1265 // Mirror transport write errors as read failures; transport_bio_ has been |
| 1266 // shut down by TransportWriteComplete, so the BIO_write will fail, failing |
| 1267 // the CHECK. http://crbug.com/335557. |
| 1268 result = transport_write_error_; |
| 1251 } else { | 1269 } else { |
| 1252 DCHECK(recv_buffer_.get()); | 1270 DCHECK(recv_buffer_.get()); |
| 1253 int ret = BIO_write(transport_bio_, recv_buffer_->data(), result); | 1271 int ret = BIO_write(transport_bio_, recv_buffer_->data(), result); |
| 1254 // A write into a memory BIO should always succeed. | 1272 // A write into a memory BIO should always succeed. |
| 1255 // Force values on the stack for http://crbug.com/335557 | 1273 // Force values on the stack for http://crbug.com/335557 |
| 1256 base::debug::Alias(&result); | 1274 base::debug::Alias(&result); |
| 1257 base::debug::Alias(&ret); | 1275 base::debug::Alias(&ret); |
| 1258 CHECK_EQ(result, ret); | 1276 CHECK_EQ(result, ret); |
| 1259 } | 1277 } |
| 1260 recv_buffer_ = NULL; | 1278 recv_buffer_ = NULL; |
| 1261 transport_recv_busy_ = false; | 1279 transport_recv_busy_ = false; |
| 1280 return result; |
| 1262 } | 1281 } |
| 1263 | 1282 |
| 1264 int SSLClientSocketOpenSSL::ClientCertRequestCallback(SSL* ssl, | 1283 int SSLClientSocketOpenSSL::ClientCertRequestCallback(SSL* ssl, |
| 1265 X509** x509, | 1284 X509** x509, |
| 1266 EVP_PKEY** pkey) { | 1285 EVP_PKEY** pkey) { |
| 1267 DVLOG(3) << "OpenSSL ClientCertRequestCallback called"; | 1286 DVLOG(3) << "OpenSSL ClientCertRequestCallback called"; |
| 1268 DCHECK(ssl == ssl_); | 1287 DCHECK(ssl == ssl_); |
| 1269 DCHECK(*x509 == NULL); | 1288 DCHECK(*x509 == NULL); |
| 1270 DCHECK(*pkey == NULL); | 1289 DCHECK(*pkey == NULL); |
| 1271 | 1290 |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1394 } | 1413 } |
| 1395 | 1414 |
| 1396 npn_proto_.assign(reinterpret_cast<const char*>(*out), *outlen); | 1415 npn_proto_.assign(reinterpret_cast<const char*>(*out), *outlen); |
| 1397 server_protos_.assign(reinterpret_cast<const char*>(in), inlen); | 1416 server_protos_.assign(reinterpret_cast<const char*>(in), inlen); |
| 1398 DVLOG(2) << "next protocol: '" << npn_proto_ << "' status: " << npn_status_; | 1417 DVLOG(2) << "next protocol: '" << npn_proto_ << "' status: " << npn_status_; |
| 1399 #endif | 1418 #endif |
| 1400 return SSL_TLSEXT_ERR_OK; | 1419 return SSL_TLSEXT_ERR_OK; |
| 1401 } | 1420 } |
| 1402 | 1421 |
| 1403 } // namespace net | 1422 } // namespace net |
| OLD | NEW |