QUIC SSL: Prohibit early data functionailty
authorHugo Landau <hlandau@openssl.org>
Mon, 16 Jan 2023 15:27:01 +0000 (15:27 +0000)
committerPauli <pauli@openssl.org>
Tue, 4 Jul 2023 23:02:26 +0000 (09:02 +1000)
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Paul Dale <pauli@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/20061)

doc/man3/SSL_read_early_data.pod
ssl/ssl_lib.c
test/quicapitest.c

index 13c3bcf6a65de1ace6ee556248f492cf338ef20e..e9fce6522335b0793454f89cc8a21ba99f794e01 100644 (file)
@@ -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</REPLAY PROTECTION> 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
index e4157f28fedf2e7f9e94eee65265b0aaed609a9e..11f6cb2be95df20f4e3a70d5cfa0446bc4038f6a 100644 (file)
@@ -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;
index aa4badbcdaf2db59a24a21b87ab9164641cf37bd..5255674384639f5ba799365e142caa3d4bbaa27b 100644 (file)
@@ -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);