Added new API to enable 0-RTT for 3rd party QUIC stacks.

Reviewed-by: Tim Hudson <tjh@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/26842)
This commit is contained in:
Cheng Zhang 2025-02-20 10:28:35 +08:00 committed by Tomas Mraz
parent 8d69f4005b
commit db2c54cc92
9 changed files with 74 additions and 8 deletions

View 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().

View 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.

View 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

View 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

View 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;
}

View 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);
}

View 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;
}

View 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;

View 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: