From 82a2becab332c35b53c31d3f8a743fba66bef869 Mon Sep 17 00:00:00 2001 From: Hugo Landau Date: Mon, 16 Jan 2023 15:27:01 +0000 Subject: [PATCH] QUIC SSL: Prohibit early data functionailty Reviewed-by: Tomas Mraz Reviewed-by: Matt Caswell Reviewed-by: Paul Dale (Merged from https://github.com/openssl/openssl/pull/20061) --- doc/man3/SSL_read_early_data.pod | 2 ++ ssl/ssl_lib.c | 24 ++++++++++++++---------- test/quicapitest.c | 22 ++++++++++++++++++++++ 3 files changed, 38 insertions(+), 10 deletions(-) diff --git a/doc/man3/SSL_read_early_data.pod b/doc/man3/SSL_read_early_data.pod index 13c3bcf6a6..e9fce65223 100644 --- a/doc/man3/SSL_read_early_data.pod +++ b/doc/man3/SSL_read_early_data.pod @@ -241,6 +241,8 @@ protection feature will still be used even if a callback is present unless it has been explicitly disabled using the SSL_OP_NO_ANTI_REPLAY option. See L below. +These functions cannot currently be used with QUIC SSL objects. + =head1 NOTES The whole purpose of early data is to enable a client to start sending data to diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c index e4157f28fe..11f6cb2be9 100644 --- a/ssl/ssl_lib.c +++ b/ssl/ssl_lib.c @@ -759,8 +759,12 @@ SSL *ossl_ssl_connection_new_int(SSL_CTX *ctx, const SSL_METHOD *method) } s->mode = ctx->mode; s->max_cert_list = ctx->max_cert_list; - s->max_early_data = ctx->max_early_data; - s->recv_max_early_data = ctx->recv_max_early_data; + + if (!IS_QUIC_CTX(ctx)) { + s->max_early_data = ctx->max_early_data; + s->recv_max_early_data = ctx->recv_max_early_data; + } + s->num_tickets = ctx->num_tickets; s->pha_enabled = ctx->pha_enabled; @@ -805,7 +809,7 @@ SSL *ossl_ssl_connection_new_int(SSL_CTX *ctx, const SSL_METHOD *method) X509_VERIFY_PARAM_inherit(s->param, ctx->param); s->quiet_shutdown = ctx->quiet_shutdown; - if (!IS_QUIC_SSL(ssl)) + if (!IS_QUIC_CTX(ctx)) s->ext.max_fragment_len_mode = ctx->ext.max_fragment_len_mode; s->max_send_fragment = ctx->max_send_fragment; @@ -869,8 +873,10 @@ SSL *ossl_ssl_connection_new_int(SSL_CTX *ctx, const SSL_METHOD *method) s->key_update = SSL_KEY_UPDATE_NONE; - s->allow_early_data_cb = ctx->allow_early_data_cb; - s->allow_early_data_cb_data = ctx->allow_early_data_cb_data; + if (!IS_QUIC_CTX(ctx)) { + s->allow_early_data_cb = ctx->allow_early_data_cb; + s->allow_early_data_cb_data = ctx->allow_early_data_cb_data; + } if (!method->ssl_init(ssl)) goto sslerr; @@ -2341,7 +2347,6 @@ int SSL_read_early_data(SSL *s, void *buf, size_t num, size_t *readbytes) int ret; SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL_ONLY(s); - /* TODO(QUIC): This will need special handling for QUIC */ if (sc == NULL) return 0; @@ -2399,7 +2404,6 @@ int SSL_get_early_data_status(const SSL *s) { const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL_ONLY(s); - /* TODO(QUIC): This will need special handling for QUIC */ if (sc == NULL) return 0; @@ -6878,7 +6882,7 @@ int SSL_set_max_early_data(SSL *s, uint32_t max_early_data) { SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); - if (sc == NULL) + if (sc == NULL || IS_QUIC_SSL(s)) return 0; sc->max_early_data = max_early_data; @@ -6912,7 +6916,7 @@ int SSL_set_recv_max_early_data(SSL *s, uint32_t recv_max_early_data) { SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); - if (sc == NULL) + if (sc == NULL || IS_QUIC_SSL(s)) return 0; sc->recv_max_early_data = recv_max_early_data; @@ -7089,7 +7093,7 @@ void SSL_set_allow_early_data_cb(SSL *s, { SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); - if (sc == NULL) + if (sc == NULL || IS_QUIC_SSL(s)) return; sc->allow_early_data_cb = cb; diff --git a/test/quicapitest.c b/test/quicapitest.c index aa4badbcda..5255674384 100644 --- a/test/quicapitest.c +++ b/test/quicapitest.c @@ -422,6 +422,8 @@ static int test_quic_forbidden_options(void) int testresult = 0; SSL_CTX *ctx = NULL; SSL *ssl = NULL; + char buf[16]; + size_t len; if (!TEST_ptr(ctx = SSL_CTX_new_ex(libctx, NULL, OSSL_QUIC_client_method()))) goto err; @@ -432,6 +434,11 @@ static int test_quic_forbidden_options(void) if (!TEST_uint64_t_eq(SSL_CTX_get_options(ctx), UINT64_MAX)) goto err; + /* Set options on CTX which should not be inherited (tested below). */ + SSL_CTX_set_read_ahead(ctx, 1); + SSL_CTX_set_max_early_data(ctx, 1); + SSL_CTX_set_recv_max_early_data(ctx, 1); + if (!TEST_ptr(ssl = SSL_new(ctx))) goto err; @@ -452,6 +459,9 @@ static int test_quic_forbidden_options(void) goto err; /* Readahead */ + if (!TEST_false(SSL_get_read_ahead(ssl))) + goto err; + SSL_set_read_ahead(ssl, 1); if (!TEST_false(SSL_get_read_ahead(ssl))) goto err; @@ -467,6 +477,18 @@ static int test_quic_forbidden_options(void) || !TEST_false(SSL_set_tlsext_max_fragment_length(ssl, TLSEXT_max_fragment_length_512))) goto err; + /* Max early data */ + if (!TEST_false(SSL_get_recv_max_early_data(ssl)) + || !TEST_false(SSL_get_max_early_data(ssl)) + || !TEST_false(SSL_set_recv_max_early_data(ssl, 1)) + || !TEST_false(SSL_set_max_early_data(ssl, 1))) + goto err; + + /* Read/Write */ + if (!TEST_false(SSL_read_early_data(ssl, buf, sizeof(buf), &len)) + || !TEST_false(SSL_write_early_data(ssl, buf, sizeof(buf), &len))) + goto err; + testresult = 1; err: SSL_free(ssl); -- 2.34.1