]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
- Fix #1296: DNS over QUIC depends on a very outdated version of
authorW.C.A. Wijngaards <wouter@nlnetlabs.nl>
Thu, 19 Jun 2025 12:39:45 +0000 (14:39 +0200)
committerW.C.A. Wijngaards <wouter@nlnetlabs.nl>
Thu, 19 Jun 2025 12:39:45 +0000 (14:39 +0200)
  ngtcp2. Fixed so it works with ngtcp2 1.13.0 and OpenSSL 3.5.0.

config.h.in
configure
configure.ac
doc/Changelog
services/listen_dnsport.c
services/listen_dnsport.h
testcode/doqclient.c
testdata/doq_downstream.tdir/unbound_server.key
testdata/doq_downstream.tdir/unbound_server.pem

index f2dc8c8b92b33c0f4888b9a3cc987ddd5065d94c..b166f6f23e86a91e9d641fa35cac55b44f408034 100644 (file)
    `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
 
    */
 #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
 /* 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
 
index adbd18b9ef32e26a1999c63b69925c05afb64c9d..af58f5ef6f1d48c585aa67dc6f9d42bd44c5bb42 100755 (executable)
--- a/configure
+++ b/configure
@@ -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
index 051e7b392e332946caef1dd0704236c7e68ee7fd..ff50e1e27f4a7f9e2377a887680b838fea620f53 100644 (file)
@@ -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>
index 2c1dcf710a0f19f2074f636574492d8310e177c8..41fff539cc2817485b979157fd0dccc07069e036 100644 (file)
@@ -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.
index a3b4d494176c6f9aef245bf7029b27b38db2dd26..b77e9f13a0f996b1b322dfdbd42a5809f5d5097f 100644 (file)
 #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;
 }
index f6275f805fba68ab1658e9c64086c1d6c89a3aa2..963595a1ccc5b5b24066a55394a9c59174997386 100644 (file)
@@ -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;
index e6f63a761f357e0b55bc8da27e620efe6e33093c..238a9380306dc0f4702fc523a5ca36cf61d64558 100644 (file)
 #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)
index 4256c421dd0dfcf5d0a819e6318b6bef252c6b72..370a7bbb2f220db951edc1ee71104a844bca7f1f 100644 (file)
@@ -1,15 +1,39 @@
 -----BEGIN RSA PRIVATE KEY-----
-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
+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
 -----END RSA PRIVATE KEY-----
index aeda3ff11882ca5e15cb163278c0eb6f1e59a66b..986807310f2bfd548a38fd888f7557459452467b 100644 (file)
@@ -1,11 +1,22 @@
 -----BEGIN CERTIFICATE-----
-MIIBmzCCAQQCCQDsNJ1UmphEFzANBgkqhkiG9w0BAQUFADASMRAwDgYDVQQDEwd1
-bmJvdW5kMB4XDTA4MDkxMTA5MDk0MFoXDTI4MDUyOTA5MDk0MFowEjEQMA4GA1UE
-AxMHdW5ib3VuZDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAtxeybL9rtNaS
-y/axZ47DFPyGghVCM/+tuA3GhPOGeIIzJeZFgN2sUHKrpdcJcEq2ysK6J8vnfYR/
-/jF9LWcL5fMNzpoZjgImkPkhwrCLjo1cEI19LESwetT8+fjwIlb5z2vSSGAeUKyu
-g1RLMSB4/DDnOSSjka5xErBQ4esnjHkCAwEAATANBgkqhkiG9w0BAQUFAAOBgQAZ
-9N0lnLENs4JMvPS+mn8C5m9bkkFITd32IiLjf0zgYpIUbFXH6XaEr9GNZBUG8feG
-l/6WRXnbnVSblI5odQ4XxGZ9inYY6qtW30uv76HvoKp+QZ1c3460ddR8NauhcCHH
-Z7S+QbLXi+r2JAhpPozZCjBHlRD0ixzA1mKQTJhJZg==
+MIIDqzCCAhMCFBHWXeQ6ZIa9QcQbXLFfC6tj+KA+MA0GCSqGSIb3DQEBCwUAMBIx
+EDAOBgNVBAMMB3VuYm91bmQwHhcNMjAwNzA4MTMzMjI5WhcNNDAwMzI1MTMzMjI5
+WjASMRAwDgYDVQQDDAd1bmJvdW5kMIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIB
+igKCAYEAvjSVSN2QMXudpzukdLCqgg/IOhCX8KYkD0FFFfWcQjgKq5wI0x41iG32
+a6wbGanre4IX7VxaSPu9kkHfnGgynCk5nwDRedE/FLFhAU78PoT0+NqqGRS7XVQ2
+4vLmIz9Hqc2Ozx1um1BXBTmIT0UfN2e22I0LWQ6a3seZlEDRj45gnk7Zuh9MDgot
+aBdm+v1JAbupSf6Zis4VEH3JNdvVGE3O1DHEIeuuz/3BDhpf6WBDH+8KWaBe1ca4
+TZHr9ThL2gEMEfAQl0wXDwRWRoi3NjNMH+mw0L1rjwThI5GXqNIee7o5FzUReSXZ
+uTdFMyGe3Owcx+XoYnwi6cplSNoGsDBu4B9bKKglR9YleJVw4L4Xi8xPq6O9UPj4
++nypHk/DOoC7DIM3ufN0yxPBsFo5TVowxfhdjZXJbbftd2TZv7AH8+XLA5UoZgRz
+XgzECelXSCTBFlMTnT48LfA9pMLydyjAz2UdPHs5Iv+TK5nnI+aJoeaP7kFZSngx
+dy1+A/bNAgMBAAEwDQYJKoZIhvcNAQELBQADggGBABunf93MKaCUHiZgnoOTinsW
+84/EgInrgtKzAyH+BhnKkJOhhR0kkIAx5d9BpDlaSiRTACFon9moWCgDIIsK/Ar7
+JE0Kln9cV//wiiNoFU0O4mnzyGUIMvlaEX6QHMJJQYvL05+w/3AAcf5XmMJtR5ca
+fJ8FqvGC34b2WxX9lTQoyT52sRt+1KnQikiMEnEyAdKktMG+MwKsFDdOwDXyZhZg
+XZhRrfX3/NVJolqB6EahjWIGXDeKuSSKZVtCyib6LskyeMzN5lcRfvubKDdlqFVF
+qlD7rHBsKhQUWK/IO64mGf7y/de+CgHtED5vDvr/p2uj/9sABATfbrOQR3W/Of25
+sLBj4OEfrJ7lX8hQgFaxkMI3x6VFT3W8dTCp7xnQgb6bgROWB5fNEZ9jk/gjSRmD
+yIU+r0UbKe5kBk/CmZVFXL2TyJ92V5NYEQh8V4DGy19qZ6u/XKYyNJL4ocs35GGe
+CA8SBuyrmdhx38h1RHErR2Skzadi1S7MwGf1y431fQ==
 -----END CERTIFICATE-----