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 |