From 01b85e43d7252de312297dc2d5b7877a977cc17e Mon Sep 17 00:00:00 2001 From: Benjamin Kaduk Date: Tue, 1 Sep 2020 15:10:41 -0700 Subject: QUIC: enforce consistent encryption level for handshake messages The QUIC-TLS spec requires that TLS handshake messages do not cross encryption level boundaries, but we were not previously enforcing this. (cherry picked from commit 5b76e4fb7bdc2165edcbd335599b79306d8402aa) --- ssl/ssl_local.h | 1 + ssl/ssl_quic.c | 12 +++++++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/ssl/ssl_local.h b/ssl/ssl_local.h index b2db990f76..213c87f77c 100644 --- a/ssl/ssl_local.h +++ b/ssl/ssl_local.h @@ -1406,6 +1406,7 @@ struct ssl_st { #ifndef OPENSSL_NO_QUIC OSSL_ENCRYPTION_LEVEL quic_read_level; OSSL_ENCRYPTION_LEVEL quic_write_level; + OSSL_ENCRYPTION_LEVEL quic_latest_level_received; BUF_MEM *quic_buf; /* buffer incoming handshake messages */ QUIC_DATA *quic_input_data_head; QUIC_DATA *quic_input_data_tail; diff --git a/ssl/ssl_quic.c b/ssl/ssl_quic.c index bc3c220067..b79a40a8b6 100644 --- a/ssl/ssl_quic.c +++ b/ssl/ssl_quic.c @@ -100,7 +100,8 @@ int SSL_provide_quic_data(SSL *ssl, OSSL_ENCRYPTION_LEVEL level, /* Level can be different than the current read, but not less */ if (level < ssl->quic_read_level - || (ssl->quic_input_data_tail != NULL && level < ssl->quic_input_data_tail->level)) { + || (ssl->quic_input_data_tail != NULL && level < ssl->quic_input_data_tail->level) + || level < ssl->quic_latest_level_received) { SSLerr(SSL_F_SSL_PROVIDE_QUIC_DATA, SSL_R_WRONG_ENCRYPTION_LEVEL_RECEIVED); return 0; } @@ -122,6 +123,15 @@ int SSL_provide_quic_data(SSL *ssl, OSSL_ENCRYPTION_LEVEL level, buf = NULL; } + /* A TLS message must not cross an encryption level boundary */ + if (ssl->quic_buf->length != ssl->quic_next_record_start + && level != ssl->quic_latest_level_received) { + SSLerr(SSL_F_SSL_PROVIDE_QUIC_DATA, + SSL_R_WRONG_ENCRYPTION_LEVEL_RECEIVED); + return 0; + } + ssl->quic_latest_level_received = level; + offset = ssl->quic_buf->length; if (!BUF_MEM_grow(ssl->quic_buf, offset + len)) { SSLerr(SSL_F_SSL_PROVIDE_QUIC_DATA, ERR_R_INTERNAL_ERROR); -- 2.35.3