]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
Added new API to enable 0-RTT for 3rd party QUIC stacks.
authorCheng Zhang <zhangcheng170@huawei.com>
Thu, 20 Feb 2025 02:28:35 +0000 (10:28 +0800)
committerTomas Mraz <tomas@openssl.org>
Fri, 21 Feb 2025 11:01:30 +0000 (12:01 +0100)
Reviewed-by: Tim Hudson <tjh@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/26842)

CHANGES.md
doc/man3/SSL_set_quic_tls_cbs.pod
include/internal/quic_tls.h
include/openssl/ssl.h.in
ssl/quic/quic_tls.c
ssl/quic/quic_tls_api.c
ssl/ssl_lib.c
test/sslapitest.c
util/libssl.num

index 3607dd06f9f960e86adc37a2d2a91e42f0b5d528..991a862504e507bc60d800affa09d6da50e50f2a 100644 (file)
@@ -30,6 +30,10 @@ OpenSSL 3.5
 
 ### Changes between 3.4 and 3.5 [xx XXX xxxx]
 
+* Added new API to enable 0-RTT for 3rd party QUIC stacks.
+
+  *Cheng Zhang*
+
 * Added support for a new callback registration SSL_CTX_set_new_pending_conn_cb,
   which allows for application notification of new connection SSL object
   creation, which occurs independently of calls to SSL_accept_connection().
index 87a4d3a214203d75c857494a896cf98b7bf5c534..c1967715434a2e9dbc75b816cf4ed4ae22a48cb7 100644 (file)
@@ -9,7 +9,8 @@ OSSL_FUNC_SSL_QUIC_TLS_yield_secret_fn,
 OSSL_FUNC_SSL_QUIC_TLS_got_transport_params_fn,
 OSSL_FUNC_SSL_QUIC_TLS_alert_fn,
 SSL_set_quic_tls_cbs,
-SSL_set_quic_tls_transport_params
+SSL_set_quic_tls_transport_params,
+SSL_set_quic_tls_early_data_enabled
 - Use the OpenSSL TLS implementation for a third party QUIC implementation
 
 =head1 SYNOPSIS
@@ -59,6 +60,7 @@ SSL_set_quic_tls_transport_params
  int SSL_set_quic_tls_transport_params(SSL *s,
                                        const unsigned char *params,
                                        size_t params_len);
+ int SSL_set_quic_tls_early_data_enabled(SSL *s, int enabled);
 
 =head1 DESCRIPTION
 
@@ -133,6 +135,9 @@ function must have been called by the time the transport parameters need to be
 sent. For a client this will be before the connection has been initiated. For a
 server this might typically occur during the got_transport_params_cb.
 
+The SSL_set_quic_tls_early_data_enabled() function is used to enable the 0-RTT
+feature for a third party QUIC implementation.
+
 =head1 RETURN VALUES
 
 These functions return 1 on success and 0 on failure.
index 5e53a45d521db82523c2b42acc2f30843929a7a1..c444a60fe32250594989e4e4679bd85fd9f2943a 100644 (file)
@@ -108,4 +108,5 @@ int ossl_quic_tls_get_error(QUIC_TLS *qtls,
 int ossl_quic_tls_is_cert_request(QUIC_TLS *qtls);
 int ossl_quic_tls_has_bad_max_early_data(QUIC_TLS *qtls);
 
+int ossl_quic_tls_set_early_data_enabled(QUIC_TLS *qtls, int enabled);
 #endif
index e25899f627b86d5805bed2aed3116aa420246fcb..511ceb64180efcc4fc9306ec686ed4a758322893 100644 (file)
@@ -2878,6 +2878,8 @@ int SSL_set_quic_tls_transport_params(SSL *s,
                                       const unsigned char *params,
                                       size_t params_len);
 
+int SSL_set_quic_tls_early_data_enabled(SSL *s, int enabled);
+
 # ifdef  __cplusplus
 }
 # endif
index 6d524d73ee85b7a93c72db4e5d413a45a556dabb..546d09d46b42079a4dbfa1219367d5718c007ed6 100644 (file)
@@ -912,3 +912,30 @@ int ossl_quic_tls_has_bad_max_early_data(QUIC_TLS *qtls)
      */
     return max_early_data != 0xffffffff && max_early_data != 0;
 }
+
+int ossl_quic_tls_set_early_data_enabled(QUIC_TLS *qtls, int enabled)
+{
+    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(qtls->args.s);
+
+    if (!SSL_IS_QUIC_HANDSHAKE(sc) || !SSL_in_before(qtls->args.s))
+        return 0;
+
+    if (!enabled) {
+        sc->max_early_data = 0;
+        sc->early_data_state = SSL_EARLY_DATA_NONE;
+        return 1;
+    }
+
+    if (sc->server) {
+        sc->max_early_data = 0xffffffff;
+        sc->early_data_state = SSL_EARLY_DATA_ACCEPTING;
+        return 1;
+    }
+
+    if ((sc->session == NULL || sc->session->ext.max_early_data != 0xffffffff)
+        && sc->psk_use_session_cb == NULL)
+        return 0;
+
+    sc->early_data_state = SSL_EARLY_DATA_CONNECTING;
+    return 1;
+}
index 4ba9f934c16f1688a4a4cbb4e637ebceeb2dbe31..3c202a3094d53520d9f1f1e19a5fd763e47d6cf7 100644 (file)
@@ -189,3 +189,20 @@ int SSL_set_quic_tls_transport_params(SSL *s,
 
     return ossl_quic_tls_set_transport_params(sc->qtls, params, params_len);
 }
+
+int SSL_set_quic_tls_early_data_enabled(SSL *s, int enabled)
+{
+    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);
+
+    if (!SSL_is_tls(s)) {
+        ERR_raise(ERR_LIB_SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+        return 0;
+    }
+
+    if (sc->qtls == NULL) {
+        ERR_raise(ERR_LIB_SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+        return 0;
+    }
+
+    return ossl_quic_tls_set_early_data_enabled(sc->qtls, enabled);
+}
index f1c679083fb48e9f2b70c26b6b827b55bfc07380..5d01b1d3941700b5490fe0cedece1587afbd65a0 100644 (file)
@@ -4946,6 +4946,13 @@ int SSL_do_handshake(SSL *s)
             ret = sc->handshake_func(s);
         }
     }
+
+    if (ret == 1 && SSL_IS_QUIC_HANDSHAKE(sc) && !SSL_is_init_finished(s)) {
+        sc->rwstate = SSL_READING;
+        BIO_clear_retry_flags(SSL_get_rbio(s));
+        BIO_set_retry_read(SSL_get_rbio(s));
+        ret = 0;
+    }
     return ret;
 }
 
index e5b999a29b9607110e629218f000eaeef51921df..1d4fbab5817adaa701a6476662b2b27499d73812 100644 (file)
@@ -12800,7 +12800,7 @@ static void assert_no_end_of_early_data(int write_p, int version, int content_ty
         end_of_early_data = 1;
 }
 
-static int test_no_end_of_early_data(void)
+static int test_quic_tls_early_data(void)
 {
     SSL_CTX *sctx = NULL, *cctx = NULL;
     SSL *serverssl = NULL, *clientssl = NULL;
@@ -12869,15 +12869,17 @@ static int test_no_end_of_early_data(void)
                                                             sizeof(sparams))))
         goto end;
 
-    SSL_CONNECTION_FROM_SSL(clientssl)->early_data_state = SSL_EARLY_DATA_CONNECTING;
-    SSL_CONNECTION_FROM_SSL(serverssl)->early_data_state = SSL_EARLY_DATA_ACCEPTING;
+    SSL_set_quic_tls_early_data_enabled(serverssl, 1);
+    SSL_set_quic_tls_early_data_enabled(clientssl, 1);
 
     SSL_set_msg_callback(serverssl, assert_no_end_of_early_data);
     SSL_set_msg_callback(clientssl, assert_no_end_of_early_data);
 
-    if (!TEST_int_eq(SSL_connect(clientssl), 1)
-            || !TEST_int_eq(SSL_accept(serverssl), 1)
-            || !TEST_int_eq(SSL_get_early_data_status(serverssl), SSL_EARLY_DATA_ACCEPTED))
+    if (!TEST_int_eq(SSL_connect(clientssl), 0)
+            || !TEST_int_eq(SSL_accept(serverssl), 0)
+            || !TEST_int_eq(SSL_get_early_data_status(serverssl), SSL_EARLY_DATA_ACCEPTED)
+            || !TEST_int_eq(SSL_get_error(clientssl, 0), SSL_ERROR_WANT_READ)
+            || !TEST_int_eq(SSL_get_error(serverssl, 0), SSL_ERROR_WANT_READ))
         goto end;
 
     /* Check the encryption levels are what we expect them to be */
@@ -13262,7 +13264,7 @@ int setup_tests(void)
     ADD_ALL_TESTS(test_alpn, 4);
 #if !defined(OSSL_NO_USABLE_TLS1_3)
     ADD_TEST(test_quic_tls);
-    ADD_TEST(test_no_end_of_early_data);
+    ADD_TEST(test_quic_tls_early_data);
 #endif
     return 1;
 
index 69186525755ff808d7939cb108422c63d2f56a91..797df2b2f3146421eaefc54fcd8ed95e85136fac 100644 (file)
@@ -589,6 +589,7 @@ SSL_set_block_padding_ex                589 3_4_0   EXIST::FUNCTION:
 SSL_get1_builtin_sigalgs                590    3_4_0   EXIST::FUNCTION:
 SSL_set_quic_tls_cbs                    ?      3_5_0   EXIST::FUNCTION:
 SSL_set_quic_tls_transport_params       ?      3_5_0   EXIST::FUNCTION:
+SSL_set_quic_tls_early_data_enabled     ?      3_5_0   EXIST::FUNCTION:
 OSSL_QUIC_server_method                 ?      3_5_0   EXIST::FUNCTION:QUIC
 SSL_is_listener                         ?      3_5_0   EXIST::FUNCTION:
 SSL_get0_listener                       ?      3_5_0   EXIST::FUNCTION: