Convert more of the SSL write path to size_t and Spans. We still have our <= 0 return values because anything with BIOs tries to preserve BIO_write's error returns. (Maybe we can stop doing this? BIO_read's error return is a little subtle with EOF vs error, but BIO_write's is uninteresting.) But the rest of the logic is size_t-clean and hopefully a little clearer. We still have to support SSL_write's rather goofy calling convention, however. I haven't pushed Spans down into the low-level record construction logic yet. We should probably do that, but there are enough offsets tossed around there that they warrant their own CL. Bug: 507 Change-Id: Ia0c702d1a2d3713e71b0bbfa8d65649d3b20da9b Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/47544 Commit-Queue: Bob Beck <bbe@google.com> Reviewed-by: Bob Beck <bbe@google.com>
diff --git a/ssl/ssl_lib.cc b/ssl/ssl_lib.cc index 7035748..4d3ad44 100644 --- a/ssl/ssl_lib.cc +++ b/ssl/ssl_lib.cc
@@ -1058,6 +1058,7 @@ } int ret = 0; + size_t bytes_written = 0; bool needs_handshake = false; do { // If necessary, complete the handshake implicitly. @@ -1072,10 +1073,16 @@ } } - ret = ssl->method->write_app_data(ssl, &needs_handshake, - (const uint8_t *)buf, num); + if (num < 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_LENGTH); + return -1; + } + ret = ssl->method->write_app_data( + ssl, &needs_handshake, &bytes_written, + MakeConstSpan(static_cast<const uint8_t *>(buf), + static_cast<size_t>(num))); } while (needs_handshake); - return ret; + return ret <= 0 ? ret : static_cast<int>(bytes_written); } int SSL_key_update(SSL *ssl, int request_type) { @@ -1239,8 +1246,7 @@ // Discard any unfinished writes from the perspective of |SSL_write|'s // retry. The handshake will transparently flush out the pending record // (discarded by the server) to keep the framing correct. - ssl->s3->wpend_buf = nullptr; - ssl->s3->wpend_tot = 0; + ssl->s3->pending_write = {}; } enum ssl_early_data_reason_t SSL_get_early_data_reason(const SSL *ssl) {