mirror of
https://github.com/NLnetLabs/unbound.git
synced 2025-12-18 23:06:06 -05:00
- Fix #1296: DNS over QUIC depends on a very outdated version of
ngtcp2. Fixed so it works with ngtcp2 1.13.0 and OpenSSL 3.5.0.
This commit is contained in:
parent
9201c75013
commit
a1d68cdc96
9 changed files with 278 additions and 51 deletions
|
|
@ -477,6 +477,9 @@
|
|||
`ngtcp2_crypto_quictls_from_ossl_encryption_level' function. */
|
||||
#undef HAVE_NGTCP2_CRYPTO_QUICTLS_FROM_OSSL_ENCRYPTION_LEVEL
|
||||
|
||||
/* Define to 1 if you have the `ngtcp2_crypto_quictls_init' function. */
|
||||
#undef HAVE_NGTCP2_CRYPTO_QUICTLS_INIT
|
||||
|
||||
/* Define to 1 if the system has the type `ngtcp2_encryption_level'. */
|
||||
#undef HAVE_NGTCP2_ENCRYPTION_LEVEL
|
||||
|
||||
|
|
@ -484,6 +487,9 @@
|
|||
*/
|
||||
#undef HAVE_NGTCP2_NGTCP2_CRYPTO_OPENSSL_H
|
||||
|
||||
/* Define to 1 if you have the <ngtcp2/ngtcp2_crypto_ossl.h> header file. */
|
||||
#undef HAVE_NGTCP2_NGTCP2_CRYPTO_OSSL_H
|
||||
|
||||
/* Define to 1 if you have the <ngtcp2/ngtcp2_crypto_quictls.h> header file.
|
||||
*/
|
||||
#undef HAVE_NGTCP2_NGTCP2_CRYPTO_QUICTLS_H
|
||||
|
|
@ -1023,6 +1029,9 @@
|
|||
/* Define this to enable client TCP Fast Open. */
|
||||
#undef USE_MSG_FASTOPEN
|
||||
|
||||
/* Define this to use ngtcp2_crypto_ossl. */
|
||||
#undef USE_NGTCP2_CRYPTO_OSSL
|
||||
|
||||
/* Define this to enable client TCP Fast Open. */
|
||||
#undef USE_OSX_MSG_FASTOPEN
|
||||
|
||||
|
|
|
|||
70
configure
vendored
70
configure
vendored
|
|
@ -22285,6 +22285,13 @@ if test "x$ac_cv_header_ngtcp2_ngtcp2_h" = xyes
|
|||
then :
|
||||
printf "%s\n" "#define HAVE_NGTCP2_NGTCP2_H 1" >>confdefs.h
|
||||
|
||||
fi
|
||||
ac_fn_c_check_header_compile "$LINENO" "ngtcp2/ngtcp2_crypto_ossl.h" "ac_cv_header_ngtcp2_ngtcp2_crypto_ossl_h" "$ac_includes_default
|
||||
"
|
||||
if test "x$ac_cv_header_ngtcp2_ngtcp2_crypto_ossl_h" = xyes
|
||||
then :
|
||||
printf "%s\n" "#define HAVE_NGTCP2_NGTCP2_CRYPTO_OSSL_H 1" >>confdefs.h
|
||||
|
||||
fi
|
||||
ac_fn_c_check_header_compile "$LINENO" "ngtcp2/ngtcp2_crypto_openssl.h" "ac_cv_header_ngtcp2_ngtcp2_crypto_openssl_h" "$ac_includes_default
|
||||
"
|
||||
|
|
@ -22325,7 +22332,52 @@ else $as_nop
|
|||
fi
|
||||
printf "%s\n" "#define HAVE_DECL_NGTCP2_CRYPTO_ENCRYPT_CB $ac_have_decl" >>confdefs.h
|
||||
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ngtcp2_crypto_encrypt_cb in -lngtcp2_crypto_openssl" >&5
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ngtcp2_crypto_encrypt_cb in -lngtcp2_crypto_ossl" >&5
|
||||
printf %s "checking for ngtcp2_crypto_encrypt_cb in -lngtcp2_crypto_ossl... " >&6; }
|
||||
if test ${ac_cv_lib_ngtcp2_crypto_ossl_ngtcp2_crypto_encrypt_cb+y}
|
||||
then :
|
||||
printf %s "(cached) " >&6
|
||||
else $as_nop
|
||||
ac_check_lib_save_LIBS=$LIBS
|
||||
LIBS="-lngtcp2_crypto_ossl $LIBS"
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
|
||||
/* Override any GCC internal prototype to avoid an error.
|
||||
Use char because int might match the return type of a GCC
|
||||
builtin and then its argument prototype would still apply. */
|
||||
char ngtcp2_crypto_encrypt_cb ();
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
return ngtcp2_crypto_encrypt_cb ();
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"
|
||||
then :
|
||||
ac_cv_lib_ngtcp2_crypto_ossl_ngtcp2_crypto_encrypt_cb=yes
|
||||
else $as_nop
|
||||
ac_cv_lib_ngtcp2_crypto_ossl_ngtcp2_crypto_encrypt_cb=no
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext conftest.beam \
|
||||
conftest$ac_exeext conftest.$ac_ext
|
||||
LIBS=$ac_check_lib_save_LIBS
|
||||
fi
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ngtcp2_crypto_ossl_ngtcp2_crypto_encrypt_cb" >&5
|
||||
printf "%s\n" "$ac_cv_lib_ngtcp2_crypto_ossl_ngtcp2_crypto_encrypt_cb" >&6; }
|
||||
if test "x$ac_cv_lib_ngtcp2_crypto_ossl_ngtcp2_crypto_encrypt_cb" = xyes
|
||||
then :
|
||||
|
||||
LIBS="$LIBS -lngtcp2_crypto_ossl"
|
||||
|
||||
printf "%s\n" "#define USE_NGTCP2_CRYPTO_OSSL 1" >>confdefs.h
|
||||
|
||||
|
||||
else $as_nop
|
||||
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ngtcp2_crypto_encrypt_cb in -lngtcp2_crypto_openssl" >&5
|
||||
printf %s "checking for ngtcp2_crypto_encrypt_cb in -lngtcp2_crypto_openssl... " >&6; }
|
||||
if test ${ac_cv_lib_ngtcp2_crypto_openssl_ngtcp2_crypto_encrypt_cb+y}
|
||||
then :
|
||||
|
|
@ -22363,9 +22415,9 @@ printf "%s\n" "$ac_cv_lib_ngtcp2_crypto_openssl_ngtcp2_crypto_encrypt_cb" >&6; }
|
|||
if test "x$ac_cv_lib_ngtcp2_crypto_openssl_ngtcp2_crypto_encrypt_cb" = xyes
|
||||
then :
|
||||
LIBS="$LIBS -lngtcp2_crypto_openssl"
|
||||
fi
|
||||
else $as_nop
|
||||
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ngtcp2_crypto_encrypt_cb in -lngtcp2_crypto_quictls" >&5
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ngtcp2_crypto_encrypt_cb in -lngtcp2_crypto_quictls" >&5
|
||||
printf %s "checking for ngtcp2_crypto_encrypt_cb in -lngtcp2_crypto_quictls... " >&6; }
|
||||
if test ${ac_cv_lib_ngtcp2_crypto_quictls_ngtcp2_crypto_encrypt_cb+y}
|
||||
then :
|
||||
|
|
@ -22403,6 +22455,12 @@ printf "%s\n" "$ac_cv_lib_ngtcp2_crypto_quictls_ngtcp2_crypto_encrypt_cb" >&6; }
|
|||
if test "x$ac_cv_lib_ngtcp2_crypto_quictls_ngtcp2_crypto_encrypt_cb" = xyes
|
||||
then :
|
||||
LIBS="$LIBS -lngtcp2_crypto_quictls"
|
||||
fi
|
||||
|
||||
|
||||
fi
|
||||
|
||||
|
||||
fi
|
||||
|
||||
ac_fn_c_check_func "$LINENO" "ngtcp2_crypto_encrypt_cb" "ac_cv_func_ngtcp2_crypto_encrypt_cb"
|
||||
|
|
@ -22452,6 +22510,12 @@ if test "x$ac_cv_func_ngtcp2_crypto_quictls_configure_client_context" = xyes
|
|||
then :
|
||||
printf "%s\n" "#define HAVE_NGTCP2_CRYPTO_QUICTLS_CONFIGURE_CLIENT_CONTEXT 1" >>confdefs.h
|
||||
|
||||
fi
|
||||
ac_fn_c_check_func "$LINENO" "ngtcp2_crypto_quictls_init" "ac_cv_func_ngtcp2_crypto_quictls_init"
|
||||
if test "x$ac_cv_func_ngtcp2_crypto_quictls_init" = xyes
|
||||
then :
|
||||
printf "%s\n" "#define HAVE_NGTCP2_CRYPTO_QUICTLS_INIT 1" >>confdefs.h
|
||||
|
||||
fi
|
||||
ac_fn_c_check_func "$LINENO" "ngtcp2_conn_get_num_scid" "ac_cv_func_ngtcp2_conn_get_num_scid"
|
||||
if test "x$ac_cv_func_ngtcp2_conn_get_num_scid" = xyes
|
||||
|
|
|
|||
14
configure.ac
14
configure.ac
|
|
@ -1610,16 +1610,22 @@ if test x_$withval = x_yes -o x_$withval != x_no; then
|
|||
if test x_$found_libngtcp2 != x_yes; then
|
||||
AC_MSG_ERROR([Could not find libngtcp2, ngtcp2.h])
|
||||
fi
|
||||
AC_CHECK_HEADERS([ngtcp2/ngtcp2.h ngtcp2/ngtcp2_crypto_openssl.h ngtcp2/ngtcp2_crypto_quictls.h],,, [AC_INCLUDES_DEFAULT])
|
||||
AC_CHECK_HEADERS([ngtcp2/ngtcp2.h ngtcp2/ngtcp2_crypto_ossl.h ngtcp2/ngtcp2_crypto_openssl.h ngtcp2/ngtcp2_crypto_quictls.h],,, [AC_INCLUDES_DEFAULT])
|
||||
AC_CHECK_DECLS([ngtcp2_conn_server_new], [], [], [AC_INCLUDES_DEFAULT
|
||||
#include <ngtcp2/ngtcp2.h>
|
||||
])
|
||||
AC_CHECK_DECLS([ngtcp2_crypto_encrypt_cb], [], [], [AC_INCLUDES_DEFAULT
|
||||
#include <ngtcp2/ngtcp2_crypto.h>
|
||||
])
|
||||
AC_CHECK_LIB([ngtcp2_crypto_openssl], [ngtcp2_crypto_encrypt_cb], [ LIBS="$LIBS -lngtcp2_crypto_openssl" ])
|
||||
AC_CHECK_LIB([ngtcp2_crypto_quictls], [ngtcp2_crypto_encrypt_cb], [ LIBS="$LIBS -lngtcp2_crypto_quictls" ])
|
||||
AC_CHECK_FUNCS([ngtcp2_crypto_encrypt_cb ngtcp2_ccerr_default ngtcp2_conn_in_closing_period ngtcp2_conn_in_draining_period ngtcp2_conn_get_max_local_streams_uni ngtcp2_crypto_quictls_from_ossl_encryption_level ngtcp2_crypto_quictls_configure_server_context ngtcp2_crypto_quictls_configure_client_context ngtcp2_conn_get_num_scid ngtcp2_conn_tls_early_data_rejected ngtcp2_conn_encode_0rtt_transport_params])
|
||||
AC_CHECK_LIB([ngtcp2_crypto_ossl], [ngtcp2_crypto_encrypt_cb], [
|
||||
LIBS="$LIBS -lngtcp2_crypto_ossl"
|
||||
AC_DEFINE(USE_NGTCP2_CRYPTO_OSSL, 1, [Define this to use ngtcp2_crypto_ossl.])
|
||||
], [
|
||||
AC_CHECK_LIB([ngtcp2_crypto_openssl], [ngtcp2_crypto_encrypt_cb], [ LIBS="$LIBS -lngtcp2_crypto_openssl" ], [
|
||||
AC_CHECK_LIB([ngtcp2_crypto_quictls], [ngtcp2_crypto_encrypt_cb], [ LIBS="$LIBS -lngtcp2_crypto_quictls" ])
|
||||
])
|
||||
])
|
||||
AC_CHECK_FUNCS([ngtcp2_crypto_encrypt_cb ngtcp2_ccerr_default ngtcp2_conn_in_closing_period ngtcp2_conn_in_draining_period ngtcp2_conn_get_max_local_streams_uni ngtcp2_crypto_quictls_from_ossl_encryption_level ngtcp2_crypto_quictls_configure_server_context ngtcp2_crypto_quictls_configure_client_context ngtcp2_crypto_quictls_init ngtcp2_conn_get_num_scid ngtcp2_conn_tls_early_data_rejected ngtcp2_conn_encode_0rtt_transport_params])
|
||||
AC_CHECK_FUNCS([SSL_is_quic], [], [AC_MSG_ERROR([No QUIC support detected in OpenSSL. Need OpenSSL version with QUIC support to enable DNS over QUIC with libngtcp2.])])
|
||||
AC_CHECK_TYPES([struct ngtcp2_version_cid, ngtcp2_encryption_level],,,[AC_INCLUDES_DEFAULT
|
||||
#include <ngtcp2/ngtcp2.h>
|
||||
|
|
|
|||
|
|
@ -1,3 +1,7 @@
|
|||
19 June 2025: Wouter
|
||||
- Fix #1296: DNS over QUIC depends on a very outdated version of
|
||||
ngtcp2. Fixed so it works with ngtcp2 1.13.0 and OpenSSL 3.5.0.
|
||||
|
||||
17 June 2025: Yorgos
|
||||
- Fix for consistent use of local zone CNAME alias for configured auth
|
||||
zones. Now it also applies to downstream configured auth zones.
|
||||
|
|
|
|||
|
|
@ -90,10 +90,13 @@
|
|||
#ifdef HAVE_NGTCP2
|
||||
#include <ngtcp2/ngtcp2.h>
|
||||
#include <ngtcp2/ngtcp2_crypto.h>
|
||||
#ifdef HAVE_NGTCP2_NGTCP2_CRYPTO_QUICTLS_H
|
||||
#ifdef HAVE_NGTCP2_NGTCP2_CRYPTO_OSSL_H
|
||||
#include <ngtcp2/ngtcp2_crypto_ossl.h>
|
||||
#elif defined(HAVE_NGTCP2_NGTCP2_CRYPTO_QUICTLS_H)
|
||||
#include <ngtcp2/ngtcp2_crypto_quictls.h>
|
||||
#else
|
||||
#elif defined(HAVE_NGTCP2_NGTCP2_CRYPTO_OPENSSL_H)
|
||||
#include <ngtcp2/ngtcp2_crypto_openssl.h>
|
||||
#define MAKE_QUIC_METHOD 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
|
@ -3258,6 +3261,21 @@ doq_table_create(struct config_file* cfg, struct ub_randstate* rnd)
|
|||
struct doq_table* table = calloc(1, sizeof(*table));
|
||||
if(!table)
|
||||
return NULL;
|
||||
#ifdef USE_NGTCP2_CRYPTO_OSSL
|
||||
/* Initialize the ossl crypto, it is harmless to call twice,
|
||||
* and this is before use of doq connections. */
|
||||
if(ngtcp2_crypto_ossl_init() != 0) {
|
||||
log_err("ngtcp2_crypto_oss_init failed");
|
||||
free(table);
|
||||
return NULL;
|
||||
}
|
||||
#elif defined(HAVE_NGTCP2_CRYPTO_QUICTLS_INIT)
|
||||
if(ngtcp2_crypto_quictls_init() != 0) {
|
||||
log_err("ngtcp2_crypto_quictls_init failed");
|
||||
free(table);
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
table->idle_timeout = ((uint64_t)cfg->tcp_idle_timeout)*
|
||||
NGTCP2_MILLISECONDS;
|
||||
table->sv_scidlen = 16;
|
||||
|
|
@ -3597,12 +3615,18 @@ doq_conn_delete(struct doq_conn* conn, struct doq_table* table)
|
|||
lock_rw_wrlock(&conn->table->conid_lock);
|
||||
doq_conn_clear_conids(conn);
|
||||
lock_rw_unlock(&conn->table->conid_lock);
|
||||
ngtcp2_conn_del(conn->conn);
|
||||
/* Remove the app data from ngtcp2 before SSL_free of conn->ssl,
|
||||
* because the ngtcp2 conn is deleted. */
|
||||
SSL_set_app_data(conn->ssl, NULL);
|
||||
if(conn->stream_tree.count != 0) {
|
||||
traverse_postorder(&conn->stream_tree, stream_tree_del, table);
|
||||
}
|
||||
free(conn->key.dcid);
|
||||
SSL_free(conn->ssl);
|
||||
#ifdef USE_NGTCP2_CRYPTO_OSSL
|
||||
ngtcp2_crypto_ossl_ctx_del(conn->ossl_ctx);
|
||||
#endif
|
||||
ngtcp2_conn_del(conn->conn);
|
||||
free(conn->close_pkt);
|
||||
free(conn);
|
||||
}
|
||||
|
|
@ -4460,7 +4484,7 @@ doq_log_printf_cb(void* ATTR_UNUSED(user_data), const char* fmt, ...)
|
|||
va_end(ap);
|
||||
}
|
||||
|
||||
#ifndef HAVE_NGTCP2_CRYPTO_QUICTLS_CONFIGURE_SERVER_CONTEXT
|
||||
#ifdef MAKE_QUIC_METHOD
|
||||
/** the doq application tx key callback, false on failure */
|
||||
static int
|
||||
doq_application_tx_key_cb(struct doq_conn* conn)
|
||||
|
|
@ -4494,7 +4518,9 @@ doq_set_encryption_secrets(SSL *ssl, OSSL_ENCRYPTION_LEVEL ossl_level,
|
|||
ngtcp2_crypto_level
|
||||
#endif
|
||||
level =
|
||||
#ifdef HAVE_NGTCP2_CRYPTO_QUICTLS_FROM_OSSL_ENCRYPTION_LEVEL
|
||||
#ifdef USE_NGTCP2_CRYPTO_OSSL
|
||||
ngtcp2_crypto_ossl_from_ossl_encryption_level(ossl_level);
|
||||
#elif defined(HAVE_NGTCP2_CRYPTO_QUICTLS_FROM_OSSL_ENCRYPTION_LEVEL)
|
||||
ngtcp2_crypto_quictls_from_ossl_encryption_level(ossl_level);
|
||||
#else
|
||||
ngtcp2_crypto_openssl_from_ossl_encryption_level(ossl_level);
|
||||
|
|
@ -4540,7 +4566,9 @@ doq_add_handshake_data(SSL *ssl, OSSL_ENCRYPTION_LEVEL ossl_level,
|
|||
ngtcp2_crypto_level
|
||||
#endif
|
||||
level =
|
||||
#ifdef HAVE_NGTCP2_CRYPTO_QUICTLS_FROM_OSSL_ENCRYPTION_LEVEL
|
||||
#ifdef USE_NGTCP2_CRYPTO_OSSL
|
||||
ngtcp2_crypto_ossl_from_ossl_encryption_level(ossl_level);
|
||||
#elif defined(HAVE_NGTCP2_CRYPTO_QUICTLS_FROM_OSSL_ENCRYPTION_LEVEL)
|
||||
ngtcp2_crypto_quictls_from_ossl_encryption_level(ossl_level);
|
||||
#else
|
||||
ngtcp2_crypto_openssl_from_ossl_encryption_level(ossl_level);
|
||||
|
|
@ -4575,7 +4603,7 @@ doq_send_alert(SSL *ssl, enum ssl_encryption_level_t ATTR_UNUSED(level),
|
|||
doq_conn->tls_alert = alert;
|
||||
return 1;
|
||||
}
|
||||
#endif /* HAVE_NGTCP2_CRYPTO_QUICTLS_CONFIGURE_SERVER_CONTEXT */
|
||||
#endif /* MAKE_QUIC_METHOD */
|
||||
|
||||
/** ALPN select callback for the doq SSL context */
|
||||
static int
|
||||
|
|
@ -4597,7 +4625,7 @@ void* quic_sslctx_create(char* key, char* pem, char* verifypem)
|
|||
{
|
||||
#ifdef HAVE_NGTCP2
|
||||
char* sid_ctx = "unbound server";
|
||||
#ifndef HAVE_NGTCP2_CRYPTO_QUICTLS_CONFIGURE_SERVER_CONTEXT
|
||||
#ifdef MAKE_QUIC_METHOD
|
||||
SSL_QUIC_METHOD* quic_method;
|
||||
#endif
|
||||
SSL_CTX* ctx = SSL_CTX_new(TLS_server_method());
|
||||
|
|
@ -4670,7 +4698,7 @@ void* quic_sslctx_create(char* key, char* pem, char* verifypem)
|
|||
SSL_CTX_free(ctx);
|
||||
return NULL;
|
||||
}
|
||||
#else /* HAVE_NGTCP2_CRYPTO_QUICTLS_CONFIGURE_SERVER_CONTEXT */
|
||||
#elif defined(MAKE_QUIC_METHOD)
|
||||
/* The quic_method needs to remain valid during the SSL_CTX
|
||||
* lifetime, so we allocate it. It is freed with the
|
||||
* doq_server_socket. */
|
||||
|
|
@ -4705,12 +4733,29 @@ static ngtcp2_conn* doq_conn_ref_get_conn(ngtcp2_crypto_conn_ref* conn_ref)
|
|||
static SSL*
|
||||
doq_ssl_server_setup(SSL_CTX* ctx, struct doq_conn* conn)
|
||||
{
|
||||
#ifdef USE_NGTCP2_CRYPTO_OSSL
|
||||
int ret;
|
||||
#endif
|
||||
SSL* ssl = SSL_new(ctx);
|
||||
if(!ssl) {
|
||||
log_crypto_err("doq: SSL_new failed");
|
||||
return NULL;
|
||||
}
|
||||
#ifdef HAVE_NGTCP2_CRYPTO_QUICTLS_CONFIGURE_SERVER_CONTEXT
|
||||
#ifdef USE_NGTCP2_CRYPTO_OSSL
|
||||
if((ret=ngtcp2_crypto_ossl_ctx_new(&conn->ossl_ctx, NULL)) != 0) {
|
||||
log_err("doq: ngtcp2_crypto_ossl_ctx_new failed: %s",
|
||||
ngtcp2_strerror(ret));
|
||||
SSL_free(ssl);
|
||||
return NULL;
|
||||
}
|
||||
ngtcp2_crypto_ossl_ctx_set_ssl(conn->ossl_ctx, ssl);
|
||||
if(ngtcp2_crypto_ossl_configure_server_session(ssl) != 0) {
|
||||
log_err("doq: ngtcp2_crypto_ossl_configure_server_session failed");
|
||||
SSL_free(ssl);
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
#if defined(USE_NGTCP2_CRYPTO_OSSL) || defined(HAVE_NGTCP2_CRYPTO_QUICTLS_CONFIGURE_SERVER_CONTEXT)
|
||||
conn->conn_ref.get_conn = &doq_conn_ref_get_conn;
|
||||
conn->conn_ref.user_data = conn;
|
||||
SSL_set_app_data(ssl, &conn->conn_ref);
|
||||
|
|
@ -4718,7 +4763,11 @@ doq_ssl_server_setup(SSL_CTX* ctx, struct doq_conn* conn)
|
|||
SSL_set_app_data(ssl, conn);
|
||||
#endif
|
||||
SSL_set_accept_state(ssl);
|
||||
#ifdef USE_NGTCP2_CRYPTO_OSSL
|
||||
SSL_set_quic_tls_early_data_enabled(ssl, 1);
|
||||
#else
|
||||
SSL_set_quic_early_data_enabled(ssl, 1);
|
||||
#endif
|
||||
return ssl;
|
||||
}
|
||||
|
||||
|
|
@ -4839,7 +4888,11 @@ doq_conn_setup(struct doq_conn* conn, uint8_t* scid, size_t scidlen,
|
|||
log_err("doq_ssl_server_setup failed");
|
||||
return 0;
|
||||
}
|
||||
#ifdef USE_NGTCP2_CRYPTO_OSSL
|
||||
ngtcp2_conn_set_tls_native_handle(conn->conn, conn->ossl_ctx);
|
||||
#else
|
||||
ngtcp2_conn_set_tls_native_handle(conn->conn, conn->ssl);
|
||||
#endif
|
||||
doq_conn_write_enable(conn);
|
||||
return 1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -52,6 +52,9 @@
|
|||
#ifdef HAVE_NGTCP2
|
||||
#include <ngtcp2/ngtcp2.h>
|
||||
#include <ngtcp2/ngtcp2_crypto.h>
|
||||
#ifdef USE_NGTCP2_CRYPTO_OSSL
|
||||
struct ngtcp2_crypto_ossl_ctx;
|
||||
#endif
|
||||
#endif
|
||||
struct listen_list;
|
||||
struct config_file;
|
||||
|
|
@ -606,9 +609,13 @@ struct doq_conn {
|
|||
uint8_t tls_alert;
|
||||
/** the ssl context, SSL* */
|
||||
void* ssl;
|
||||
#ifdef HAVE_NGTCP2_CRYPTO_QUICTLS_CONFIGURE_SERVER_CONTEXT
|
||||
#if defined(USE_NGTCP2_CRYPTO_OSSL) || defined(HAVE_NGTCP2_CRYPTO_QUICTLS_CONFIGURE_SERVER_CONTEXT)
|
||||
/** the connection reference for ngtcp2_conn and userdata in ssl */
|
||||
struct ngtcp2_crypto_conn_ref conn_ref;
|
||||
#endif
|
||||
#ifdef USE_NGTCP2_CRYPTO_OSSL
|
||||
/** the per-connection state for ngtcp2_crypto_ossl */
|
||||
struct ngtcp2_crypto_ossl_ctx* ossl_ctx;
|
||||
#endif
|
||||
/** closure packet, if any */
|
||||
uint8_t* close_pkt;
|
||||
|
|
|
|||
|
|
@ -48,10 +48,13 @@
|
|||
#ifdef HAVE_NGTCP2
|
||||
#include <ngtcp2/ngtcp2.h>
|
||||
#include <ngtcp2/ngtcp2_crypto.h>
|
||||
#ifdef HAVE_NGTCP2_NGTCP2_CRYPTO_QUICTLS_H
|
||||
#ifdef HAVE_NGTCP2_NGTCP2_CRYPTO_OSSL_H
|
||||
#include <ngtcp2/ngtcp2_crypto_ossl.h>
|
||||
#elif defined(HAVE_NGTCP2_NGTCP2_CRYPTO_QUICTLS_H)
|
||||
#include <ngtcp2/ngtcp2_crypto_quictls.h>
|
||||
#else
|
||||
#elif defined(HAVE_NGTCP2_NGTCP2_CRYPTO_OPENSSL_H)
|
||||
#include <ngtcp2/ngtcp2_crypto_openssl.h>
|
||||
#define MAKE_QUIC_METHOD 1
|
||||
#endif
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/rand.h>
|
||||
|
|
@ -107,9 +110,13 @@ struct doq_client_data {
|
|||
SSL_CTX* ctx;
|
||||
/** SSL object */
|
||||
SSL* ssl;
|
||||
#ifdef HAVE_NGTCP2_CRYPTO_QUICTLS_CONFIGURE_CLIENT_CONTEXT
|
||||
#if defined(USE_NGTCP2_CRYPTO_OSSL) || defined(HAVE_NGTCP2_CRYPTO_QUICTLS_CONFIGURE_CLIENT_CONTEXT)
|
||||
/** the connection reference for ngtcp2_conn and userdata in ssl */
|
||||
struct ngtcp2_crypto_conn_ref conn_ref;
|
||||
#endif
|
||||
#ifdef USE_NGTCP2_CRYPTO_OSSL
|
||||
/** the per-connection state for ngtcp2_crypto_ossl */
|
||||
struct ngtcp2_crypto_ossl_ctx* ossl_ctx;
|
||||
#endif
|
||||
/** the quic version to use */
|
||||
uint32_t quic_version;
|
||||
|
|
@ -197,11 +204,12 @@ struct doq_client_stream {
|
|||
int query_is_done;
|
||||
};
|
||||
|
||||
#ifndef HAVE_NGTCP2_CRYPTO_QUICTLS_CONFIGURE_CLIENT_CONTEXT
|
||||
#ifdef MAKE_QUIC_METHOD
|
||||
/** the quic method struct, must remain valid during the QUIC connection. */
|
||||
static SSL_QUIC_METHOD quic_method;
|
||||
#endif
|
||||
|
||||
#if defined(USE_NGTCP2_CRYPTO_OSSL) || defined(HAVE_NGTCP2_CRYPTO_QUICTLS_CONFIGURE_CLIENT_CONTEXT)
|
||||
/** Get the connection ngtcp2_conn from the ssl app data
|
||||
* ngtcp2_crypto_conn_ref */
|
||||
static ngtcp2_conn* conn_ref_get_conn(ngtcp2_crypto_conn_ref* conn_ref)
|
||||
|
|
@ -210,11 +218,12 @@ static ngtcp2_conn* conn_ref_get_conn(ngtcp2_crypto_conn_ref* conn_ref)
|
|||
conn_ref->user_data;
|
||||
return data->conn;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
set_app_data(SSL* ssl, struct doq_client_data* data)
|
||||
{
|
||||
#ifdef HAVE_NGTCP2_CRYPTO_QUICTLS_CONFIGURE_CLIENT_CONTEXT
|
||||
#if defined(USE_NGTCP2_CRYPTO_OSSL) || defined(HAVE_NGTCP2_CRYPTO_QUICTLS_CONFIGURE_CLIENT_CONTEXT)
|
||||
data->conn_ref.get_conn = &conn_ref_get_conn;
|
||||
data->conn_ref.user_data = data;
|
||||
SSL_set_app_data(ssl, &data->conn_ref);
|
||||
|
|
@ -227,7 +236,7 @@ static struct doq_client_data*
|
|||
get_app_data(SSL* ssl)
|
||||
{
|
||||
struct doq_client_data* data;
|
||||
#ifdef HAVE_NGTCP2_CRYPTO_QUICTLS_CONFIGURE_CLIENT_CONTEXT
|
||||
#if defined(USE_NGTCP2_CRYPTO_OSSL) || defined(HAVE_NGTCP2_CRYPTO_QUICTLS_CONFIGURE_CLIENT_CONTEXT)
|
||||
data = (struct doq_client_data*)((struct ngtcp2_crypto_conn_ref*)
|
||||
SSL_get_app_data(ssl))->user_data;
|
||||
#else
|
||||
|
|
@ -893,7 +902,7 @@ handshake_completed(ngtcp2_conn* ATTR_UNUSED(conn), void* user_data)
|
|||
verbose(1, "early data was accepted by the server");
|
||||
}
|
||||
}
|
||||
#ifdef HAVE_NGTCP2_CRYPTO_QUICTLS_CONFIGURE_CLIENT_CONTEXT
|
||||
#if defined(USE_NGTCP2_CRYPTO_OSSL) || defined(HAVE_NGTCP2_CRYPTO_QUICTLS_CONFIGURE_CLIENT_CONTEXT)
|
||||
if(data->transport_file) {
|
||||
early_data_write_transport(data);
|
||||
}
|
||||
|
|
@ -1207,7 +1216,7 @@ early_data_write_transport(struct doq_client_data* data)
|
|||
#endif
|
||||
}
|
||||
|
||||
#ifndef HAVE_NGTCP2_CRYPTO_QUICTLS_CONFIGURE_CLIENT_CONTEXT
|
||||
#ifdef MAKE_QUIC_METHOD
|
||||
/** applicatation rx key callback, this is where the rx key is set,
|
||||
* and streams can be opened, like http3 unidirectional streams, like
|
||||
* the http3 control and http3 qpack encode and decoder streams. */
|
||||
|
|
@ -1317,7 +1326,7 @@ send_alert(SSL *ssl, enum ssl_encryption_level_t ATTR_UNUSED(level),
|
|||
data->tls_alert = alert;
|
||||
return 1;
|
||||
}
|
||||
#endif /* HAVE_NGTCP2_CRYPTO_QUICTLS_CONFIGURE_CLIENT_CONTEXT */
|
||||
#endif /* MAKE_QUIC_METHOD */
|
||||
|
||||
/** new session callback. We can write it to file for resumption later. */
|
||||
static int
|
||||
|
|
@ -1357,7 +1366,7 @@ ctx_client_setup(void)
|
|||
log_err("ngtcp2_crypto_quictls_configure_client_context failed");
|
||||
exit(1);
|
||||
}
|
||||
#else
|
||||
#elif defined(MAKE_QUIC_METHOD)
|
||||
memset(&quic_method, 0, sizeof(quic_method));
|
||||
quic_method.set_encryption_secrets = &set_encryption_secrets;
|
||||
quic_method.add_handshake_data = &add_handshake_data;
|
||||
|
|
@ -1373,22 +1382,39 @@ ctx_client_setup(void)
|
|||
static SSL*
|
||||
ssl_client_setup(struct doq_client_data* data)
|
||||
{
|
||||
#ifdef USE_NGTCP2_CRYPTO_OSSL
|
||||
int ret;
|
||||
#endif
|
||||
SSL* ssl = SSL_new(data->ctx);
|
||||
if(!ssl) {
|
||||
log_crypto_err("Could not SSL_new");
|
||||
exit(1);
|
||||
}
|
||||
#ifdef USE_NGTCP2_CRYPTO_OSSL
|
||||
if((ret=ngtcp2_crypto_ossl_ctx_new(&data->ossl_ctx, NULL)) != 0) {
|
||||
log_err("ngtcp2_crypto_ossl_ctx_new failed: %s",
|
||||
ngtcp2_strerror(ret));
|
||||
exit(1);
|
||||
}
|
||||
ngtcp2_crypto_ossl_ctx_set_ssl(data->ossl_ctx, ssl);
|
||||
if(ngtcp2_crypto_ossl_configure_client_session(ssl) != 0) {
|
||||
log_err("ngtcp2_crypto_ossl_configure_client_session failed");
|
||||
exit(1);
|
||||
}
|
||||
#endif
|
||||
set_app_data(ssl, data);
|
||||
SSL_set_connect_state(ssl);
|
||||
if(!SSL_set_fd(ssl, data->fd)) {
|
||||
log_crypto_err("Could not SSL_set_fd");
|
||||
exit(1);
|
||||
}
|
||||
#ifndef USE_NGTCP2_CRYPTO_OSSL
|
||||
if((data->quic_version & 0xff000000) == 0xff000000) {
|
||||
SSL_set_quic_use_legacy_codepoint(ssl, 1);
|
||||
} else {
|
||||
SSL_set_quic_use_legacy_codepoint(ssl, 0);
|
||||
}
|
||||
#endif
|
||||
SSL_set_alpn_protos(ssl, (const unsigned char *)"\x03""doq", 4);
|
||||
/* send the SNI host name */
|
||||
SSL_set_tlsext_host_name(ssl, "localhost");
|
||||
|
|
@ -2072,7 +2098,11 @@ early_data_setup_session(struct doq_client_data* data)
|
|||
SSL_SESSION_free(session);
|
||||
return 0;
|
||||
}
|
||||
#ifdef USE_NGTCP2_CRYPTO_OSSL
|
||||
SSL_set_quic_tls_early_data_enabled(data->ssl, 1);
|
||||
#else
|
||||
SSL_set_quic_early_data_enabled(data->ssl, 1);
|
||||
#endif
|
||||
SSL_SESSION_free(session);
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -2221,6 +2251,15 @@ create_doq_client_data(const char* svr, int port, struct ub_event_base* base,
|
|||
data = calloc(1, sizeof(*data));
|
||||
if(!data) fatal_exit("calloc failed: out of memory");
|
||||
data->base = base;
|
||||
#ifdef USE_NGTCP2_CRYPTO_OSSL
|
||||
/* Initialize the ossl crypto, it is harmless to call twice,
|
||||
* and this is before use of doq connections. */
|
||||
if(ngtcp2_crypto_ossl_init() != 0)
|
||||
fatal_exit("ngtcp2_crypto_oss_init failed");
|
||||
#elif defined(HAVE_NGTCP2_CRYPTO_QUICTLS_INIT)
|
||||
if(ngtcp2_crypto_quictls_init() != 0)
|
||||
fatal_exit("ngtcp2_crypto_quictls_init failed");
|
||||
#endif
|
||||
data->rnd = ub_initstate(NULL);
|
||||
if(!data->rnd) fatal_exit("ub_initstate failed: out of memory");
|
||||
data->svr = svr;
|
||||
|
|
@ -2255,7 +2294,11 @@ create_doq_client_data(const char* svr, int port, struct ub_event_base* base,
|
|||
SSL_CTX_sess_set_new_cb(data->ctx, new_session_cb);
|
||||
}
|
||||
data->ssl = ssl_client_setup(data);
|
||||
#ifdef USE_NGTCP2_CRYPTO_OSSL
|
||||
ngtcp2_conn_set_tls_native_handle(data->conn, data->ossl_ctx);
|
||||
#else
|
||||
ngtcp2_conn_set_tls_native_handle(data->conn, data->ssl);
|
||||
#endif
|
||||
if(data->early_data_enabled)
|
||||
early_data_setup(data);
|
||||
|
||||
|
|
@ -2301,8 +2344,14 @@ delete_doq_client_data(struct doq_client_data* data)
|
|||
}
|
||||
}
|
||||
#endif
|
||||
ngtcp2_conn_del(data->conn);
|
||||
/* Remove the app data from ngtcp2 before SSL_free of conn->ssl,
|
||||
* because the ngtcp2 conn is deleted. */
|
||||
SSL_set_app_data(data->ssl, NULL);
|
||||
SSL_free(data->ssl);
|
||||
#ifdef USE_NGTCP2_CRYPTO_OSSL
|
||||
ngtcp2_crypto_ossl_ctx_del(data->ossl_ctx);
|
||||
#endif
|
||||
ngtcp2_conn_del(data->conn);
|
||||
sldns_buffer_free(data->pkt_buf);
|
||||
sldns_buffer_free(data->blocked_pkt);
|
||||
if(data->fd != -1)
|
||||
|
|
|
|||
50
testdata/doq_downstream.tdir/unbound_server.key
vendored
50
testdata/doq_downstream.tdir/unbound_server.key
vendored
|
|
@ -1,15 +1,39 @@
|
|||
-----BEGIN RSA PRIVATE KEY-----
|
||||
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
|
||||
-----END RSA PRIVATE KEY-----
|
||||
|
|
|
|||
29
testdata/doq_downstream.tdir/unbound_server.pem
vendored
29
testdata/doq_downstream.tdir/unbound_server.pem
vendored
|
|
@ -1,11 +1,22 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
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
|
||||
-----END CERTIFICATE-----
|
||||
|
|
|
|||
Loading…
Reference in a new issue