Push read_shutdown logic down a layer. We'll probably want to either move or add additional checks later, but meanwhile this gets more code on the BIO-free side of the divide. Change-Id: I3e2b570cdf1d70a262d952c20fd2d76ff4f70dd0 Reviewed-on: https://boringssl-review.googlesource.com/21365 Commit-Queue: Steven Valdez <svaldez@google.com> CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org> Reviewed-by: Steven Valdez <svaldez@google.com>
diff --git a/ssl/d1_pkt.cc b/ssl/d1_pkt.cc index c2cbd7e..5b1cce5 100644 --- a/ssl/d1_pkt.cc +++ b/ssl/d1_pkt.cc
@@ -129,64 +129,55 @@ namespace bssl { int dtls1_get_record(SSL *ssl) { -again: - switch (ssl->s3->read_shutdown) { - case ssl_shutdown_none: - break; - case ssl_shutdown_fatal_alert: - OPENSSL_PUT_ERROR(SSL, SSL_R_PROTOCOL_IS_SHUTDOWN); - return -1; - case ssl_shutdown_close_notify: - return 0; - } - - Span<uint8_t> body; - uint8_t type, alert; - size_t consumed; - enum ssl_open_record_t open_ret = dtls_open_record( - ssl, &type, &body, &consumed, &alert, ssl_read_buffer(ssl)); - if (open_ret != ssl_open_record_partial) { - ssl_read_buffer_consume(ssl, consumed); - } - switch (open_ret) { - case ssl_open_record_partial: { - assert(ssl_read_buffer(ssl).empty()); - int read_ret = ssl_read_buffer_extend_to(ssl, 0 /* unused */); - if (read_ret <= 0) { - return read_ret; - } - goto again; + for (;;) { + Span<uint8_t> body; + uint8_t type, alert; + size_t consumed; + enum ssl_open_record_t open_ret = dtls_open_record( + ssl, &type, &body, &consumed, &alert, ssl_read_buffer(ssl)); + if (open_ret != ssl_open_record_partial) { + ssl_read_buffer_consume(ssl, consumed); } + switch (open_ret) { + case ssl_open_record_partial: { + assert(ssl_read_buffer(ssl).empty()); + int read_ret = ssl_read_buffer_extend_to(ssl, 0 /* unused */); + if (read_ret <= 0) { + return read_ret; + } + continue; + } - case ssl_open_record_success: { - if (body.size() > 0xffff) { - OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW); + case ssl_open_record_success: { + if (body.size() > 0xffff) { + OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW); + return -1; + } + + SSL3_RECORD *rr = &ssl->s3->rrec; + rr->type = type; + rr->length = static_cast<uint16_t>(body.size()); + rr->data = body.data(); + return 1; + } + + case ssl_open_record_discard: + continue; + + case ssl_open_record_close_notify: + return 0; + + case ssl_open_record_error: + if (alert != 0) { + ssl_send_alert(ssl, SSL3_AL_FATAL, alert); + } return -1; - } - - SSL3_RECORD *rr = &ssl->s3->rrec; - rr->type = type; - rr->length = static_cast<uint16_t>(body.size()); - rr->data = body.data(); - return 1; } - case ssl_open_record_discard: - goto again; - - case ssl_open_record_close_notify: - return 0; - - case ssl_open_record_error: - if (alert != 0) { - ssl_send_alert(ssl, SSL3_AL_FATAL, alert); - } - return -1; + assert(0); + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return -1; } - - assert(0); - OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); - return -1; } int dtls1_read_app_data(SSL *ssl, bool *out_got_handshake, uint8_t *buf,
diff --git a/ssl/dtls_record.cc b/ssl/dtls_record.cc index c06a62d..2bf1d42 100644 --- a/ssl/dtls_record.cc +++ b/ssl/dtls_record.cc
@@ -179,6 +179,17 @@ size_t *out_consumed, uint8_t *out_alert, Span<uint8_t> in) { *out_consumed = 0; + switch (ssl->s3->read_shutdown) { + case ssl_shutdown_none: + break; + case ssl_shutdown_fatal_alert: + OPENSSL_PUT_ERROR(SSL, SSL_R_PROTOCOL_IS_SHUTDOWN); + *out_alert = 0; + return ssl_open_record_error; + case ssl_shutdown_close_notify: + return ssl_open_record_close_notify; + } + if (in.empty()) { return ssl_open_record_partial; }
diff --git a/ssl/s3_pkt.cc b/ssl/s3_pkt.cc index b182826..71e1a08 100644 --- a/ssl/s3_pkt.cc +++ b/ssl/s3_pkt.cc
@@ -127,63 +127,54 @@ static int do_ssl3_write(SSL *ssl, int type, const uint8_t *buf, unsigned len); int ssl3_get_record(SSL *ssl) { -again: - switch (ssl->s3->read_shutdown) { - case ssl_shutdown_none: - break; - case ssl_shutdown_fatal_alert: - OPENSSL_PUT_ERROR(SSL, SSL_R_PROTOCOL_IS_SHUTDOWN); - return -1; - case ssl_shutdown_close_notify: - return 0; - } - - Span<uint8_t> body; - uint8_t type, alert = SSL_AD_DECODE_ERROR; - size_t consumed; - enum ssl_open_record_t open_ret = tls_open_record( - ssl, &type, &body, &consumed, &alert, ssl_read_buffer(ssl)); - if (open_ret != ssl_open_record_partial) { - ssl_read_buffer_consume(ssl, consumed); - } - switch (open_ret) { - case ssl_open_record_partial: { - int read_ret = ssl_read_buffer_extend_to(ssl, consumed); - if (read_ret <= 0) { - return read_ret; - } - goto again; + for (;;) { + Span<uint8_t> body; + uint8_t type, alert = SSL_AD_DECODE_ERROR; + size_t consumed; + enum ssl_open_record_t open_ret = tls_open_record( + ssl, &type, &body, &consumed, &alert, ssl_read_buffer(ssl)); + if (open_ret != ssl_open_record_partial) { + ssl_read_buffer_consume(ssl, consumed); } + switch (open_ret) { + case ssl_open_record_partial: { + int read_ret = ssl_read_buffer_extend_to(ssl, consumed); + if (read_ret <= 0) { + return read_ret; + } + continue; + } - case ssl_open_record_success: { - if (body.size() > 0xffff) { - OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW); + case ssl_open_record_success: { + if (body.size() > 0xffff) { + OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW); + return -1; + } + + SSL3_RECORD *rr = &ssl->s3->rrec; + rr->type = type; + rr->length = static_cast<uint16_t>(body.size()); + rr->data = body.data(); + return 1; + } + + case ssl_open_record_discard: + continue; + + case ssl_open_record_close_notify: + return 0; + + case ssl_open_record_error: + if (alert != 0) { + ssl_send_alert(ssl, SSL3_AL_FATAL, alert); + } return -1; - } - - SSL3_RECORD *rr = &ssl->s3->rrec; - rr->type = type; - rr->length = static_cast<uint16_t>(body.size()); - rr->data = body.data(); - return 1; } - case ssl_open_record_discard: - goto again; - - case ssl_open_record_close_notify: - return 0; - - case ssl_open_record_error: - if (alert != 0) { - ssl_send_alert(ssl, SSL3_AL_FATAL, alert); - } - return -1; + assert(0); + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return -1; } - - assert(0); - OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); - return -1; } int ssl3_write_app_data(SSL *ssl, bool *out_needs_handshake, const uint8_t *buf,
diff --git a/ssl/tls_record.cc b/ssl/tls_record.cc index ba38bc9..44a04d9 100644 --- a/ssl/tls_record.cc +++ b/ssl/tls_record.cc
@@ -191,6 +191,16 @@ Span<uint8_t> *out, size_t *out_consumed, uint8_t *out_alert, Span<uint8_t> in) { *out_consumed = 0; + switch (ssl->s3->read_shutdown) { + case ssl_shutdown_none: + break; + case ssl_shutdown_fatal_alert: + OPENSSL_PUT_ERROR(SSL, SSL_R_PROTOCOL_IS_SHUTDOWN); + *out_alert = 0; + return ssl_open_record_error; + case ssl_shutdown_close_notify: + return ssl_open_record_close_notify; + } CBS cbs = CBS(in);