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 16 matching lines...) Expand all Loading... | |
| 27 #include "net/socket/ssl_session_cache_openssl.h" | 27 #include "net/socket/ssl_session_cache_openssl.h" |
| 28 #include "net/ssl/openssl_client_key_store.h" | 28 #include "net/ssl/openssl_client_key_store.h" |
| 29 #include "net/ssl/ssl_cert_request_info.h" | 29 #include "net/ssl/ssl_cert_request_info.h" |
| 30 #include "net/ssl/ssl_connection_status_flags.h" | 30 #include "net/ssl/ssl_connection_status_flags.h" |
| 31 #include "net/ssl/ssl_info.h" | 31 #include "net/ssl/ssl_info.h" |
| 32 | 32 |
| 33 namespace net { | 33 namespace net { |
| 34 | 34 |
| 35 namespace { | 35 namespace { |
| 36 | 36 |
| 37 // This IOBuffer version is to be used with OpenSSL's non-copying interface, | |
| 38 // to guarantee that the BIO object remains alive as long as the socket keeps | |
| 39 // a reference to it's internal data buffer. | |
| 40 // | |
| 41 // |bio_buffer| must be retrieved from |bio| using the non-copying interface | |
| 42 // BIO_nread0() or BIO_nwrite0(). The reference count of |bio| is increased to | |
| 43 // make sure |bio| is not free'd if it is referenced from elsewhere. | |
| 44 class WrappedBIOAndIOBuffer : public IOBuffer { | |
| 45 public: | |
| 46 | |
| 47 explicit WrappedBIOAndIOBuffer(const char* bio_buffer, BIO* bio) | |
|
Ryan Sleevi
2014/04/30 21:33:32
nit: delete newline on 46
| |
| 48 : IOBuffer(const_cast<char*>(bio_buffer)), bio_(bio) { | |
| 49 CHECK(bio); | |
| 50 | |
| 51 CRYPTO_add(&bio_->references, 1, CRYPTO_LOCK_BIO); | |
| 52 } | |
| 53 | |
| 54 protected: | |
| 55 virtual ~WrappedBIOAndIOBuffer() { | |
| 56 data_ = NULL; | |
| 57 // Will count down the reference count, and free if the count reaches zero. | |
| 58 BIO_free_all(bio_); | |
| 59 } | |
| 60 | |
| 61 BIO* bio_; | |
| 62 }; | |
| 63 | |
| 37 // Enable this to see logging for state machine state transitions. | 64 // Enable this to see logging for state machine state transitions. |
| 38 #if 0 | 65 #if 0 |
| 39 #define GotoState(s) do { DVLOG(2) << (void *)this << " " << __FUNCTION__ << \ | 66 #define GotoState(s) do { DVLOG(2) << (void *)this << " " << __FUNCTION__ << \ |
| 40 " jump to state " << s; \ | 67 " jump to state " << s; \ |
| 41 next_handshake_state_ = s; } while (0) | 68 next_handshake_state_ = s; } while (0) |
| 42 #else | 69 #else |
| 43 #define GotoState(s) next_handshake_state_ = s | 70 #define GotoState(s) next_handshake_state_ = s |
| 44 #endif | 71 #endif |
| 45 | 72 |
| 46 // This constant can be any non-negative/non-zero value (eg: it does not | 73 // This constant can be any non-negative/non-zero value (eg: it does not |
| (...skipping 1222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1269 } | 1296 } |
| 1270 | 1297 |
| 1271 int SSLClientSocketOpenSSL::BufferSend(void) { | 1298 int SSLClientSocketOpenSSL::BufferSend(void) { |
| 1272 if (transport_send_busy_) | 1299 if (transport_send_busy_) |
| 1273 return ERR_IO_PENDING; | 1300 return ERR_IO_PENDING; |
| 1274 | 1301 |
| 1275 if (!send_buffer_.get()) { | 1302 if (!send_buffer_.get()) { |
| 1276 // Get a fresh send buffer out of the send BIO. | 1303 // Get a fresh send buffer out of the send BIO. |
| 1277 size_t max_read = BIO_ctrl_pending(transport_bio_); | 1304 size_t max_read = BIO_ctrl_pending(transport_bio_); |
| 1278 if (!max_read) | 1305 if (!max_read) |
| 1279 return 0; // Nothing pending in the OpenSSL write BIO. | 1306 return 0; // Nothing pending in the OpenSSL write BIO. |
|
Ryan Sleevi
2014/04/30 21:33:32
Is this still necessary, given that BIO_nread0 wit
haavardm
2014/05/01 16:55:19
The problem with letting 0 fall through is that ca
Ryan Sleevi
2014/05/08 22:59:28
Yeah, I suppose the alternative would be to reset
| |
| 1280 send_buffer_ = new DrainableIOBuffer(new IOBuffer(max_read), max_read); | 1307 |
| 1281 int read_bytes = BIO_read(transport_bio_, send_buffer_->data(), max_read); | 1308 char* bio_transport_buf; |
| 1282 DCHECK_GT(read_bytes, 0); | 1309 // Get the internal buffer and number of bytes available for non-copying |
| 1283 CHECK_EQ(static_cast<int>(max_read), read_bytes); | 1310 // read. |
| 1311 // BIO_ctrl_pending() is still called above. Calling BIO_nread0() when | |
| 1312 // there is no data triggers a call to BIO_nread() to read one byte. This | |
| 1313 // has side effect that the retry flag is set. | |
| 1314 int available_read_bytes = BIO_nread0(transport_bio_, &bio_transport_buf); | |
| 1315 // BIO_nread0() might report less than BIO_ctrl_pending() due to the buffer | |
| 1316 // offset and no ring buffer wrap-around for non-copying interface. | |
| 1317 CHECK_GE(static_cast<int>(max_read), available_read_bytes); | |
| 1318 if (available_read_bytes <= 0) | |
| 1319 return 0; | |
| 1320 | |
| 1321 send_buffer_ = new DrainableIOBuffer( | |
|
Ryan Sleevi
2014/04/30 21:33:32
Huh. I'm not really sure why we use a DrainableIOB
haavardm
2014/05/01 16:55:19
I believe the drainable buffer is needed to handle
Ryan Sleevi
2014/05/08 22:59:28
Yeah, but why create a DrainableIOBuffer (and have
haavardm
2014/05/09 07:23:41
Yes, I had a look into NSS yesterday and saw how y
| |
| 1322 new WrappedBIOAndIOBuffer(bio_transport_buf, transport_bio_), | |
| 1323 available_read_bytes); | |
| 1284 } | 1324 } |
| 1285 | 1325 |
| 1286 int rv = transport_->socket()->Write( | 1326 int rv = transport_->socket()->Write( |
| 1287 send_buffer_.get(), | 1327 send_buffer_.get(), |
| 1288 send_buffer_->BytesRemaining(), | 1328 send_buffer_->BytesRemaining(), |
| 1289 base::Bind(&SSLClientSocketOpenSSL::BufferSendComplete, | 1329 base::Bind(&SSLClientSocketOpenSSL::BufferSendComplete, |
| 1290 base::Unretained(this))); | 1330 base::Unretained(this))); |
| 1291 if (rv == ERR_IO_PENDING) { | 1331 if (rv == ERR_IO_PENDING) { |
| 1292 transport_send_busy_ = true; | 1332 transport_send_busy_ = true; |
| 1293 } else { | 1333 } else { |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 1315 // One read for the SSL record header (~5 bytes) and one read for the SSL | 1355 // One read for the SSL record header (~5 bytes) and one read for the SSL |
| 1316 // record body. Rather than issuing these reads to the underlying socket | 1356 // record body. Rather than issuing these reads to the underlying socket |
| 1317 // (and constantly allocating new IOBuffers), a single Read() request to | 1357 // (and constantly allocating new IOBuffers), a single Read() request to |
| 1318 // fill |transport_bio_| is issued. As long as an SSL client socket cannot | 1358 // fill |transport_bio_| is issued. As long as an SSL client socket cannot |
| 1319 // be gracefully shutdown (via SSL close alerts) and re-used for non-SSL | 1359 // be gracefully shutdown (via SSL close alerts) and re-used for non-SSL |
| 1320 // traffic, this over-subscribed Read()ing will not cause issues. | 1360 // traffic, this over-subscribed Read()ing will not cause issues. |
| 1321 size_t max_write = BIO_ctrl_get_write_guarantee(transport_bio_); | 1361 size_t max_write = BIO_ctrl_get_write_guarantee(transport_bio_); |
| 1322 if (!max_write) | 1362 if (!max_write) |
| 1323 return ERR_IO_PENDING; | 1363 return ERR_IO_PENDING; |
| 1324 | 1364 |
| 1325 recv_buffer_ = new IOBuffer(max_write); | 1365 char* bio_transport_buf; |
| 1366 // Get the internal buffer and number of bytes available for non-copying | |
| 1367 // write. | |
| 1368 int available_write_bytes = BIO_nwrite0(transport_bio_, &bio_transport_buf); | |
| 1369 // BIO_nwrite0() might report less than BIO_ctrl_get_write_guarantee() due to | |
| 1370 // the buffer offset and no ring buffer wrap-around for non-copying interface. | |
| 1371 DCHECK_GE(static_cast<int>(max_write), available_write_bytes); | |
| 1372 if (available_write_bytes <= 0) | |
| 1373 return ERR_IO_PENDING; | |
| 1374 | |
| 1375 recv_buffer_ = new WrappedBIOAndIOBuffer(bio_transport_buf, transport_bio_); | |
| 1326 int rv = transport_->socket()->Read( | 1376 int rv = transport_->socket()->Read( |
| 1327 recv_buffer_.get(), | 1377 recv_buffer_.get(), |
| 1328 max_write, | 1378 available_write_bytes, |
| 1329 base::Bind(&SSLClientSocketOpenSSL::BufferRecvComplete, | 1379 base::Bind(&SSLClientSocketOpenSSL::BufferRecvComplete, |
| 1330 base::Unretained(this))); | 1380 base::Unretained(this))); |
| 1331 if (rv == ERR_IO_PENDING) { | 1381 if (rv == ERR_IO_PENDING) { |
| 1332 transport_recv_busy_ = true; | 1382 transport_recv_busy_ = true; |
| 1333 } else { | 1383 } else { |
| 1334 rv = TransportReadComplete(rv); | 1384 rv = TransportReadComplete(rv); |
| 1335 } | 1385 } |
| 1336 return rv; | 1386 return rv; |
| 1337 } | 1387 } |
| 1338 | 1388 |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 1360 | 1410 |
| 1361 // Match the fix for http://crbug.com/249848 in NSS by erroring future reads | 1411 // Match the fix for http://crbug.com/249848 in NSS by erroring future reads |
| 1362 // from the socket after a write error. | 1412 // from the socket after a write error. |
| 1363 // | 1413 // |
| 1364 // TODO(davidben): Avoid having read and write ends interact this way. | 1414 // TODO(davidben): Avoid having read and write ends interact this way. |
| 1365 transport_write_error_ = result; | 1415 transport_write_error_ = result; |
| 1366 (void)BIO_shutdown_wr(transport_bio_); | 1416 (void)BIO_shutdown_wr(transport_bio_); |
| 1367 send_buffer_ = NULL; | 1417 send_buffer_ = NULL; |
| 1368 } else { | 1418 } else { |
| 1369 DCHECK(send_buffer_.get()); | 1419 DCHECK(send_buffer_.get()); |
| 1420 char* bio_transport_buf; | |
| 1421 // Advance the buffer index. | |
| 1422 int ret = BIO_nread(transport_bio_, &bio_transport_buf, result); | |
| 1423 CHECK_EQ(ret, result); | |
| 1424 CHECK_EQ(bio_transport_buf, send_buffer_->data()); | |
| 1370 send_buffer_->DidConsume(result); | 1425 send_buffer_->DidConsume(result); |
| 1371 DCHECK_GE(send_buffer_->BytesRemaining(), 0); | 1426 DCHECK_GE(send_buffer_->BytesRemaining(), 0); |
| 1372 if (send_buffer_->BytesRemaining() <= 0) | 1427 if (send_buffer_->BytesRemaining() <= 0) |
| 1373 send_buffer_ = NULL; | 1428 send_buffer_ = NULL; |
| 1374 } | 1429 } |
| 1375 } | 1430 } |
| 1376 | 1431 |
| 1377 int SSLClientSocketOpenSSL::TransportReadComplete(int result) { | 1432 int SSLClientSocketOpenSSL::TransportReadComplete(int result) { |
| 1378 DCHECK(ERR_IO_PENDING != result); | 1433 DCHECK(ERR_IO_PENDING != result); |
| 1379 if (result <= 0) { | 1434 if (result <= 0) { |
| 1380 DVLOG(1) << "TransportReadComplete result " << result; | 1435 DVLOG(1) << "TransportReadComplete result " << result; |
| 1381 // Received 0 (end of file) or an error. Either way, bubble it up to the | 1436 // Received 0 (end of file) or an error. Either way, bubble it up to the |
| 1382 // SSL layer via the BIO. TODO(joth): consider stashing the error code, to | 1437 // SSL layer via the BIO. TODO(joth): consider stashing the error code, to |
| 1383 // relay up to the SSL socket client (i.e. via DoReadCallback). | 1438 // relay up to the SSL socket client (i.e. via DoReadCallback). |
| 1384 if (result == 0) | 1439 if (result == 0) |
| 1385 transport_recv_eof_ = true; | 1440 transport_recv_eof_ = true; |
| 1386 (void)BIO_shutdown_wr(transport_bio_); | 1441 (void)BIO_shutdown_wr(transport_bio_); |
| 1387 } else if (transport_write_error_ < 0) { | 1442 } else if (transport_write_error_ < 0) { |
| 1388 // Mirror transport write errors as read failures; transport_bio_ has been | 1443 // Mirror transport write errors as read failures; transport_bio_ has been |
| 1389 // shut down by TransportWriteComplete, so the BIO_write will fail, failing | 1444 // shut down by TransportWriteComplete, so the BIO_write will fail, failing |
| 1390 // the CHECK. http://crbug.com/335557. | 1445 // the CHECK. http://crbug.com/335557. |
| 1391 result = transport_write_error_; | 1446 result = transport_write_error_; |
| 1392 } else { | 1447 } else { |
| 1393 DCHECK(recv_buffer_.get()); | 1448 char* bio_transport_buf; |
| 1394 int ret = BIO_write(transport_bio_, recv_buffer_->data(), result); | 1449 // Set the amount of data read into buffer. |
| 1450 int ret = BIO_nwrite(transport_bio_, &bio_transport_buf, result); | |
| 1451 CHECK_EQ(ret, result); | |
| 1452 CHECK_EQ(bio_transport_buf, recv_buffer_->data()); | |
| 1395 // A write into a memory BIO should always succeed. | 1453 // A write into a memory BIO should always succeed. |
| 1396 // Force values on the stack for http://crbug.com/335557 | 1454 // Force values on the stack for http://crbug.com/335557 |
| 1397 base::debug::Alias(&result); | 1455 base::debug::Alias(&result); |
| 1398 base::debug::Alias(&ret); | 1456 base::debug::Alias(&ret); |
| 1399 CHECK_EQ(result, ret); | 1457 CHECK_EQ(result, ret); |
| 1400 } | 1458 } |
| 1401 recv_buffer_ = NULL; | 1459 recv_buffer_ = NULL; |
| 1402 transport_recv_busy_ = false; | 1460 transport_recv_busy_ = false; |
| 1403 return result; | 1461 return result; |
| 1404 } | 1462 } |
| (...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1565 DVLOG(2) << "next protocol: '" << npn_proto_ << "' status: " << npn_status_; | 1623 DVLOG(2) << "next protocol: '" << npn_proto_ << "' status: " << npn_status_; |
| 1566 return SSL_TLSEXT_ERR_OK; | 1624 return SSL_TLSEXT_ERR_OK; |
| 1567 } | 1625 } |
| 1568 | 1626 |
| 1569 scoped_refptr<X509Certificate> | 1627 scoped_refptr<X509Certificate> |
| 1570 SSLClientSocketOpenSSL::GetUnverifiedServerCertificateChain() const { | 1628 SSLClientSocketOpenSSL::GetUnverifiedServerCertificateChain() const { |
| 1571 return server_cert_; | 1629 return server_cert_; |
| 1572 } | 1630 } |
| 1573 | 1631 |
| 1574 } // namespace net | 1632 } // namespace net |
| OLD | NEW |