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 1259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1270 | 1270 |
1271 int SSLClientSocketOpenSSL::BufferSend(void) { | 1271 int SSLClientSocketOpenSSL::BufferSend(void) { |
1272 if (transport_send_busy_) | 1272 if (transport_send_busy_) |
1273 return ERR_IO_PENDING; | 1273 return ERR_IO_PENDING; |
1274 | 1274 |
1275 if (!send_buffer_.get()) { | 1275 if (!send_buffer_.get()) { |
1276 // Get a fresh send buffer out of the send BIO. | 1276 // Get a fresh send buffer out of the send BIO. |
1277 size_t max_read = BIO_ctrl_pending(transport_bio_); | 1277 size_t max_read = BIO_ctrl_pending(transport_bio_); |
1278 if (!max_read) | 1278 if (!max_read) |
1279 return 0; // Nothing pending in the OpenSSL write BIO. | 1279 return 0; // Nothing pending in the OpenSSL write BIO. |
1280 send_buffer_ = new DrainableIOBuffer(new IOBuffer(max_read), max_read); | 1280 |
1281 int read_bytes = BIO_read(transport_bio_, send_buffer_->data(), max_read); | 1281 char* bio_transport_buf; |
1282 DCHECK_GT(read_bytes, 0); | 1282 // Get the internal buffer and number of bytes available for non-copying |
1283 CHECK_EQ(static_cast<int>(max_read), read_bytes); | 1283 // read. |
1284 // BIO_ctrl_pending() is still called above. Calling BIO_nread0() when | |
1285 // there is no data triggers a call to BIO_nread() to read one byte. This | |
1286 // has side effect that the retry flag is set. | |
1287 int available_read_bytes = BIO_nread0(transport_bio_, &bio_transport_buf); | |
Ryan Sleevi
2014/04/29 18:57:02
Note the comments in bss_bio.c
WARNING: The non-c
haavardm
2014/04/29 20:52:56
Yes I saw that too and agree it's a bit risky, esp
| |
1288 // BIO_nread0() might report less than BIO_ctrl_pending() due to the buffer | |
1289 // offset and no ring buffer wrap-around for non-copying interface. | |
1290 CHECK_GE(static_cast<int>(max_read), available_read_bytes); | |
Ryan Sleevi
2014/04/29 18:57:02
Two things:
1) I'm a little nervous about this CHE
haavardm
2014/04/29 20:52:56
Normally, if the read/write index is in the middle
| |
1291 if (available_read_bytes <= 0) | |
1292 return 0; | |
1293 | |
1294 send_buffer_ = new DrainableIOBuffer(new WrappedIOBuffer(bio_transport_buf), | |
1295 available_read_bytes); | |
Ryan Sleevi
2014/04/29 18:57:02
BUG: So, the contract of IOBuffer is that, althoug
haavardm
2014/04/29 20:52:56
Ah, right. I knew about the contract for IOBuffer
| |
1284 } | 1296 } |
1285 | 1297 |
1286 int rv = transport_->socket()->Write( | 1298 int rv = transport_->socket()->Write( |
1287 send_buffer_.get(), | 1299 send_buffer_.get(), |
1288 send_buffer_->BytesRemaining(), | 1300 send_buffer_->BytesRemaining(), |
1289 base::Bind(&SSLClientSocketOpenSSL::BufferSendComplete, | 1301 base::Bind(&SSLClientSocketOpenSSL::BufferSendComplete, |
1290 base::Unretained(this))); | 1302 base::Unretained(this))); |
1291 if (rv == ERR_IO_PENDING) { | 1303 if (rv == ERR_IO_PENDING) { |
1292 transport_send_busy_ = true; | 1304 transport_send_busy_ = true; |
1293 } else { | 1305 } else { |
(...skipping 21 matching lines...) Expand all Loading... | |
1315 // One read for the SSL record header (~5 bytes) and one read for the SSL | 1327 // 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 | 1328 // record body. Rather than issuing these reads to the underlying socket |
1317 // (and constantly allocating new IOBuffers), a single Read() request to | 1329 // (and constantly allocating new IOBuffers), a single Read() request to |
1318 // fill |transport_bio_| is issued. As long as an SSL client socket cannot | 1330 // 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 | 1331 // be gracefully shutdown (via SSL close alerts) and re-used for non-SSL |
1320 // traffic, this over-subscribed Read()ing will not cause issues. | 1332 // traffic, this over-subscribed Read()ing will not cause issues. |
1321 size_t max_write = BIO_ctrl_get_write_guarantee(transport_bio_); | 1333 size_t max_write = BIO_ctrl_get_write_guarantee(transport_bio_); |
1322 if (!max_write) | 1334 if (!max_write) |
1323 return ERR_IO_PENDING; | 1335 return ERR_IO_PENDING; |
1324 | 1336 |
1325 recv_buffer_ = new IOBuffer(max_write); | 1337 char* bio_transport_buf; |
1338 // Get the internal buffer and number of bytes available for non-copying | |
1339 // write. | |
1340 int available_write_bytes = BIO_nwrite0(transport_bio_, &bio_transport_buf); | |
1341 // BIO_nwrite0() might report less than BIO_ctrl_get_write_guarantee() due to | |
1342 // the buffer offset and no ring buffer wrap-around for non-copying interface. | |
1343 DCHECK_GE(static_cast<int>(max_write), available_write_bytes); | |
1344 if (available_write_bytes <= 0) | |
1345 return ERR_IO_PENDING; | |
1346 | |
1347 recv_buffer_ = new WrappedIOBuffer(bio_transport_buf); | |
1326 int rv = transport_->socket()->Read( | 1348 int rv = transport_->socket()->Read( |
1327 recv_buffer_.get(), | 1349 recv_buffer_.get(), |
1328 max_write, | 1350 available_write_bytes, |
1329 base::Bind(&SSLClientSocketOpenSSL::BufferRecvComplete, | 1351 base::Bind(&SSLClientSocketOpenSSL::BufferRecvComplete, |
1330 base::Unretained(this))); | 1352 base::Unretained(this))); |
1331 if (rv == ERR_IO_PENDING) { | 1353 if (rv == ERR_IO_PENDING) { |
1332 transport_recv_busy_ = true; | 1354 transport_recv_busy_ = true; |
1333 } else { | 1355 } else { |
1334 rv = TransportReadComplete(rv); | 1356 rv = TransportReadComplete(rv); |
1335 } | 1357 } |
1336 return rv; | 1358 return rv; |
1337 } | 1359 } |
1338 | 1360 |
(...skipping 21 matching lines...) Expand all Loading... | |
1360 | 1382 |
1361 // Match the fix for http://crbug.com/249848 in NSS by erroring future reads | 1383 // Match the fix for http://crbug.com/249848 in NSS by erroring future reads |
1362 // from the socket after a write error. | 1384 // from the socket after a write error. |
1363 // | 1385 // |
1364 // TODO(davidben): Avoid having read and write ends interact this way. | 1386 // TODO(davidben): Avoid having read and write ends interact this way. |
1365 transport_write_error_ = result; | 1387 transport_write_error_ = result; |
1366 (void)BIO_shutdown_wr(transport_bio_); | 1388 (void)BIO_shutdown_wr(transport_bio_); |
1367 send_buffer_ = NULL; | 1389 send_buffer_ = NULL; |
1368 } else { | 1390 } else { |
1369 DCHECK(send_buffer_.get()); | 1391 DCHECK(send_buffer_.get()); |
1392 char* bio_transport_buf; | |
1393 // Advance the buffer index. | |
1394 int ret = BIO_nread(transport_bio_, &bio_transport_buf, result); | |
1395 CHECK_EQ(ret, result); | |
1396 CHECK_EQ(bio_transport_buf, send_buffer_->data()); | |
1370 send_buffer_->DidConsume(result); | 1397 send_buffer_->DidConsume(result); |
1371 DCHECK_GE(send_buffer_->BytesRemaining(), 0); | 1398 DCHECK_GE(send_buffer_->BytesRemaining(), 0); |
1372 if (send_buffer_->BytesRemaining() <= 0) | 1399 if (send_buffer_->BytesRemaining() <= 0) |
1373 send_buffer_ = NULL; | 1400 send_buffer_ = NULL; |
1374 } | 1401 } |
1375 } | 1402 } |
1376 | 1403 |
1377 int SSLClientSocketOpenSSL::TransportReadComplete(int result) { | 1404 int SSLClientSocketOpenSSL::TransportReadComplete(int result) { |
1378 DCHECK(ERR_IO_PENDING != result); | 1405 DCHECK(ERR_IO_PENDING != result); |
1379 if (result <= 0) { | 1406 if (result <= 0) { |
1380 DVLOG(1) << "TransportReadComplete result " << result; | 1407 DVLOG(1) << "TransportReadComplete result " << result; |
1381 // Received 0 (end of file) or an error. Either way, bubble it up to the | 1408 // 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 | 1409 // 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). | 1410 // relay up to the SSL socket client (i.e. via DoReadCallback). |
1384 if (result == 0) | 1411 if (result == 0) |
1385 transport_recv_eof_ = true; | 1412 transport_recv_eof_ = true; |
1386 (void)BIO_shutdown_wr(transport_bio_); | 1413 (void)BIO_shutdown_wr(transport_bio_); |
1387 } else if (transport_write_error_ < 0) { | 1414 } else if (transport_write_error_ < 0) { |
1388 // Mirror transport write errors as read failures; transport_bio_ has been | 1415 // Mirror transport write errors as read failures; transport_bio_ has been |
1389 // shut down by TransportWriteComplete, so the BIO_write will fail, failing | 1416 // shut down by TransportWriteComplete, so the BIO_write will fail, failing |
1390 // the CHECK. http://crbug.com/335557. | 1417 // the CHECK. http://crbug.com/335557. |
1391 result = transport_write_error_; | 1418 result = transport_write_error_; |
1392 } else { | 1419 } else { |
1393 DCHECK(recv_buffer_.get()); | 1420 char* bio_transport_buf; |
1394 int ret = BIO_write(transport_bio_, recv_buffer_->data(), result); | 1421 // Set the amount of data read into buffer. |
1422 int ret = BIO_nwrite(transport_bio_, &bio_transport_buf, result); | |
1423 CHECK_EQ(ret, result); | |
1424 CHECK_EQ(bio_transport_buf, recv_buffer_->data()); | |
1395 // A write into a memory BIO should always succeed. | 1425 // A write into a memory BIO should always succeed. |
1396 // Force values on the stack for http://crbug.com/335557 | 1426 // Force values on the stack for http://crbug.com/335557 |
1397 base::debug::Alias(&result); | 1427 base::debug::Alias(&result); |
1398 base::debug::Alias(&ret); | 1428 base::debug::Alias(&ret); |
1399 CHECK_EQ(result, ret); | 1429 CHECK_EQ(result, ret); |
1400 } | 1430 } |
1401 recv_buffer_ = NULL; | 1431 recv_buffer_ = NULL; |
1402 transport_recv_busy_ = false; | 1432 transport_recv_busy_ = false; |
1403 return result; | 1433 return result; |
1404 } | 1434 } |
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1565 DVLOG(2) << "next protocol: '" << npn_proto_ << "' status: " << npn_status_; | 1595 DVLOG(2) << "next protocol: '" << npn_proto_ << "' status: " << npn_status_; |
1566 return SSL_TLSEXT_ERR_OK; | 1596 return SSL_TLSEXT_ERR_OK; |
1567 } | 1597 } |
1568 | 1598 |
1569 scoped_refptr<X509Certificate> | 1599 scoped_refptr<X509Certificate> |
1570 SSLClientSocketOpenSSL::GetUnverifiedServerCertificateChain() const { | 1600 SSLClientSocketOpenSSL::GetUnverifiedServerCertificateChain() const { |
1571 return server_cert_; | 1601 return server_cert_; |
1572 } | 1602 } |
1573 | 1603 |
1574 } // namespace net | 1604 } // namespace net |
OLD | NEW |