Chromium Code Reviews| 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 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 450 // Shut down anything that may call us back. | 451 // Shut down anything that may call us back. |
| 451 verifier_.reset(); | 452 verifier_.reset(); |
| 452 transport_->socket()->Disconnect(); | 453 transport_->socket()->Disconnect(); |
| 453 | 454 |
| 454 // Null all callbacks, delete all buffers. | 455 // Null all callbacks, delete all buffers. |
| 455 transport_send_busy_ = false; | 456 transport_send_busy_ = false; |
| 456 send_buffer_ = NULL; | 457 send_buffer_ = NULL; |
| 457 transport_recv_busy_ = false; | 458 transport_recv_busy_ = false; |
| 458 transport_recv_eof_ = false; | 459 transport_recv_eof_ = false; |
| 459 recv_buffer_ = NULL; | 460 recv_buffer_ = NULL; |
| 460 | 461 |
|
Ryan Sleevi
2014/02/04 20:45:02
Don't you need to update transport_write_error_ he
davidben
2014/02/04 23:00:11
Done. Also reset pending_read_error_.
| |
| 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 |
| 469 server_cert_verify_result_.Reset(); | 470 server_cert_verify_result_.Reset(); |
| 470 completed_handshake_ = false; | 471 completed_handshake_ = false; |
| (...skipping 726 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1197 | 1198 |
| 1198 recv_buffer_ = new IOBuffer(max_write); | 1199 recv_buffer_ = new IOBuffer(max_write); |
| 1199 int rv = transport_->socket()->Read( | 1200 int rv = transport_->socket()->Read( |
| 1200 recv_buffer_.get(), | 1201 recv_buffer_.get(), |
| 1201 max_write, | 1202 max_write, |
| 1202 base::Bind(&SSLClientSocketOpenSSL::BufferRecvComplete, | 1203 base::Bind(&SSLClientSocketOpenSSL::BufferRecvComplete, |
| 1203 base::Unretained(this))); | 1204 base::Unretained(this))); |
| 1204 if (rv == ERR_IO_PENDING) { | 1205 if (rv == ERR_IO_PENDING) { |
| 1205 transport_recv_busy_ = true; | 1206 transport_recv_busy_ = true; |
| 1206 } else { | 1207 } else { |
| 1207 TransportReadComplete(rv); | 1208 rv = TransportReadComplete(rv); |
| 1208 } | 1209 } |
| 1209 return rv; | 1210 return rv; |
| 1210 } | 1211 } |
| 1211 | 1212 |
| 1212 void SSLClientSocketOpenSSL::BufferSendComplete(int result) { | 1213 void SSLClientSocketOpenSSL::BufferSendComplete(int result) { |
| 1213 transport_send_busy_ = false; | 1214 transport_send_busy_ = false; |
| 1214 TransportWriteComplete(result); | 1215 TransportWriteComplete(result); |
| 1215 OnSendComplete(result); | 1216 OnSendComplete(result); |
| 1216 } | 1217 } |
| 1217 | 1218 |
| 1218 void SSLClientSocketOpenSSL::BufferRecvComplete(int result) { | 1219 void SSLClientSocketOpenSSL::BufferRecvComplete(int result) { |
| 1219 TransportReadComplete(result); | 1220 result = TransportReadComplete(result); |
| 1220 OnRecvComplete(result); | 1221 OnRecvComplete(result); |
| 1221 } | 1222 } |
| 1222 | 1223 |
| 1223 void SSLClientSocketOpenSSL::TransportWriteComplete(int result) { | 1224 void SSLClientSocketOpenSSL::TransportWriteComplete(int result) { |
| 1224 DCHECK(ERR_IO_PENDING != result); | 1225 DCHECK(ERR_IO_PENDING != result); |
| 1225 if (result < 0) { | 1226 if (result < 0) { |
| 1226 // Got a socket write error; close the BIO to indicate this upward. | 1227 // Got a socket write error; close the BIO to indicate this upward. |
| 1228 // | |
| 1229 // TODO(davidben): The value of |result| gets lost. Feed the error back into | |
| 1230 // the BIO so it gets (re-)detected in OnSendComplete. Perhaps with | |
| 1231 // BIO_set_callback. | |
| 1227 DVLOG(1) << "TransportWriteComplete error " << result; | 1232 DVLOG(1) << "TransportWriteComplete error " << result; |
| 1233 (void)BIO_shutdown_wr(SSL_get_wbio(ssl_)); | |
|
davidben
2014/02/04 19:27:57
Could get away with even avoiding this line for mi
davidben
2014/02/04 19:27:57
It looks like sometimes OpenSSL wraps the wbio in
Ryan Sleevi
2014/02/04 20:45:02
Future work: Should we be using BIO_set_close() in
davidben
2014/02/04 23:00:11
Hrm. That seems to set the shutdown flag on the BI
| |
| 1234 | |
| 1235 // Match the fix for http://crbug.com/249848 in NSS by erroring future reads | |
| 1236 // from the socket after a write error. | |
| 1237 // | |
| 1238 // TODO(davidben): Avoid having read and write ends interact this way. | |
| 1239 transport_write_error_ = result; | |
| 1228 (void)BIO_shutdown_wr(transport_bio_); | 1240 (void)BIO_shutdown_wr(transport_bio_); |
| 1229 BIO_set_mem_eof_return(transport_bio_, 0); | |
|
davidben
2014/02/04 19:27:57
Looks like these calls don't do anything in BIO pa
| |
| 1230 send_buffer_ = NULL; | 1241 send_buffer_ = NULL; |
|
davidben
2014/02/04 19:27:57
This line is sort of funny. The next time we get a
Ryan Sleevi
2014/02/04 20:45:02
I'm not sure I follow why it's funny. We just had
davidben
2014/02/04 23:00:11
Keeping send_buffer_ around avoids the succeeds wi
| |
| 1231 } else { | 1242 } else { |
| 1232 DCHECK(send_buffer_.get()); | 1243 DCHECK(send_buffer_.get()); |
| 1233 send_buffer_->DidConsume(result); | 1244 send_buffer_->DidConsume(result); |
| 1234 DCHECK_GE(send_buffer_->BytesRemaining(), 0); | 1245 DCHECK_GE(send_buffer_->BytesRemaining(), 0); |
| 1235 if (send_buffer_->BytesRemaining() <= 0) | 1246 if (send_buffer_->BytesRemaining() <= 0) |
| 1236 send_buffer_ = NULL; | 1247 send_buffer_ = NULL; |
| 1237 } | 1248 } |
| 1238 } | 1249 } |
| 1239 | 1250 |
| 1240 void SSLClientSocketOpenSSL::TransportReadComplete(int result) { | 1251 int SSLClientSocketOpenSSL::TransportReadComplete(int result) { |
| 1241 DCHECK(ERR_IO_PENDING != result); | 1252 DCHECK(ERR_IO_PENDING != result); |
| 1242 if (result <= 0) { | 1253 if (result <= 0) { |
| 1243 DVLOG(1) << "TransportReadComplete result " << result; | 1254 DVLOG(1) << "TransportReadComplete result " << result; |
| 1244 // Received 0 (end of file) or an error. Either way, bubble it up to the | 1255 // 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 | 1256 // 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). | 1257 // relay up to the SSL socket client (i.e. via DoReadCallback). |
| 1247 if (result == 0) | 1258 if (result == 0) |
| 1248 transport_recv_eof_ = true; | 1259 transport_recv_eof_ = true; |
| 1249 BIO_set_mem_eof_return(transport_bio_, 0); | |
| 1250 (void)BIO_shutdown_wr(transport_bio_); | 1260 (void)BIO_shutdown_wr(transport_bio_); |
| 1261 } else if (transport_write_error_ < 0) { | |
| 1262 // Mirror transport write errors as read failures; transport_bio_ has been | |
| 1263 // shut down by TransportWriteComplete, so the BIO_write will fail. | |
| 1264 result = transport_write_error_; | |
|
Ryan Sleevi
2014/02/04 20:45:02
Let's add bug numbers. This is perhaps the most co
davidben
2014/02/04 23:00:11
Agreed. I kept it this way just to minimize behavi
| |
| 1251 } else { | 1265 } else { |
| 1252 DCHECK(recv_buffer_.get()); | 1266 DCHECK(recv_buffer_.get()); |
| 1253 int ret = BIO_write(transport_bio_, recv_buffer_->data(), result); | 1267 int ret = BIO_write(transport_bio_, recv_buffer_->data(), result); |
| 1254 // A write into a memory BIO should always succeed. | 1268 // A write into a memory BIO should always succeed. |
| 1255 // Force values on the stack for http://crbug.com/335557 | 1269 // Force values on the stack for http://crbug.com/335557 |
| 1256 base::debug::Alias(&result); | 1270 base::debug::Alias(&result); |
| 1257 base::debug::Alias(&ret); | 1271 base::debug::Alias(&ret); |
| 1258 CHECK_EQ(result, ret); | 1272 CHECK_EQ(result, ret); |
| 1259 } | 1273 } |
| 1260 recv_buffer_ = NULL; | 1274 recv_buffer_ = NULL; |
| 1261 transport_recv_busy_ = false; | 1275 transport_recv_busy_ = false; |
| 1276 return result; | |
| 1262 } | 1277 } |
| 1263 | 1278 |
| 1264 int SSLClientSocketOpenSSL::ClientCertRequestCallback(SSL* ssl, | 1279 int SSLClientSocketOpenSSL::ClientCertRequestCallback(SSL* ssl, |
| 1265 X509** x509, | 1280 X509** x509, |
| 1266 EVP_PKEY** pkey) { | 1281 EVP_PKEY** pkey) { |
| 1267 DVLOG(3) << "OpenSSL ClientCertRequestCallback called"; | 1282 DVLOG(3) << "OpenSSL ClientCertRequestCallback called"; |
| 1268 DCHECK(ssl == ssl_); | 1283 DCHECK(ssl == ssl_); |
| 1269 DCHECK(*x509 == NULL); | 1284 DCHECK(*x509 == NULL); |
| 1270 DCHECK(*pkey == NULL); | 1285 DCHECK(*pkey == NULL); |
| 1271 | 1286 |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1396 } | 1411 } |
| 1397 | 1412 |
| 1398 npn_proto_.assign(reinterpret_cast<const char*>(*out), *outlen); | 1413 npn_proto_.assign(reinterpret_cast<const char*>(*out), *outlen); |
| 1399 server_protos_.assign(reinterpret_cast<const char*>(in), inlen); | 1414 server_protos_.assign(reinterpret_cast<const char*>(in), inlen); |
| 1400 DVLOG(2) << "next protocol: '" << npn_proto_ << "' status: " << npn_status_; | 1415 DVLOG(2) << "next protocol: '" << npn_proto_ << "' status: " << npn_status_; |
| 1401 #endif | 1416 #endif |
| 1402 return SSL_TLSEXT_ERR_OK; | 1417 return SSL_TLSEXT_ERR_OK; |
| 1403 } | 1418 } |
| 1404 | 1419 |
| 1405 } // namespace net | 1420 } // namespace net |
| OLD | NEW |