diff --git a/configure.ac b/configure.ac index bce7f240..f2b88101 100644 --- a/configure.ac +++ b/configure.ac @@ -3383,6 +3383,7 @@ AS_CASE( ]) MSG_HTTPS="yes (using libgnutls)" AC_DEFINE([[HTTPS_SUPPORT]],[[1]],[Define to 1 if libmicrohttpd is compiled with HTTPS support.]) + AC_DEFINE([[HTTPS_WITH_GNUTLS]],[[1]],[Define to 1 if libmicrohttpd is compiled with GnuTLS support.]) ], [openssl],[ AS_IF([[test "x$have_openssl" != "xyes"]],[ @@ -3390,6 +3391,7 @@ AS_CASE( ]) MSG_HTTPS="yes (using openssl)" AC_DEFINE([[HTTPS_SUPPORT]],[[1]],[Define to 1 if libmicrohttpd is compiled with HTTPS support.]) + AC_DEFINE([[HTTPS_WITH_OPENSSL]],[[1]],[Define to 1 if libmicrohttpd is compiled with OpenSSL support.]) ], [mbedtls],[ AS_IF([[test "x$have_mbedtls" != "xyes"]],[ @@ -3397,6 +3399,7 @@ AS_CASE( ]) MSG_HTTPS="yes (using mbedtls)" AC_DEFINE([[HTTPS_SUPPORT]],[[1]],[Define to 1 if libmicrohttpd is compiled with HTTPS support.]) + AC_DEFINE([[HTTPS_WITH_MBEDTLS]],[[1]],[Define to 1 if libmicrohttpd is compiled with mbedTLS support.]) AC_MSG_ERROR([[mbedtls support not yet implemented]]) ], [all],[ @@ -3419,8 +3422,10 @@ AS_CASE( [AC_MSG_ERROR([Unsupported argument for --enable-https])] ) -AM_CONDITIONAL([ENABLE_TLS_PLUGINS], [[test "x$enable_tls_plugins" = "x1"]]) -AC_DEFINE([[ENABLE_TLS_PLUGINS]],[[$enable_tls_plugins]],[Define to 1 if we should use TLS plugins.]) +AM_CONDITIONAL([ENABLE_TLS_PLUGINS], + [[test "x$enable_tls_plugins" = "x1"]]) +AS_IF([[test "x$enable_tls_plugins" = "x1"]], + [AC_DEFINE([[ENABLE_TLS_PLUGINS]],[[1]],[Define to 1 if we should use TLS plugins.])]) AC_MSG_CHECKING(whether to support HTTPS) diff --git a/src/microhttpd/connection.c b/src/microhttpd/connection.c index c2b589ad..b736a025 100644 --- a/src/microhttpd/connection.c +++ b/src/microhttpd/connection.c @@ -5415,6 +5415,9 @@ MHD_get_connection_info (struct MHD_Connection *connection, gnutls_protocol_t res; res = gnutls_protocol_get_version (connection->tls.gnutls.tls_session); connection->connection_info_dummy.protocol = (int) res; + + // NEW: + // connection->connection_info_dummy.protocol = (int) MHD_tls_get_protocol_version (connection); } return &connection->connection_info_dummy; case MHD_CONNECTION_INFO_GNUTLS_SESSION: diff --git a/src/microhttpd/connection_https_openssl.c b/src/microhttpd/connection_https_openssl.c index fd2e3d8c..8b6b894d 100644 --- a/src/microhttpd/connection_https_openssl.c +++ b/src/microhttpd/connection_https_openssl.c @@ -33,6 +33,36 @@ #include "openssl/ssl.h" #include "openssl/err.h" + +#if ENABLE_TLS_PLUGINS +#define PRIVATE_SYMBOL static +#else +#define PRIVATE_SYMBOL /* public */ +#endif + + +PRIVATE_SYMBOL +enum MHD_TlsProtocolVersion +MHD_TLS_openssl_get_version (struct MHD_Connection *connection) +{ + // ... +} + + +struct TLS_Plugin * +MHD_TLS_openssl_init (void *ctx) +{ +#define OPENSSL_API(rval,fname,fargs) \ + fname = MHD_TLS_openssl_ ## fname + + static struct TLS_Plugin plugin = { + TLS_API (OPENSSL_API) + }; +#undef OPENSSL_API + return &plugin; +} + + FILE *err_file; /** @@ -92,7 +122,7 @@ set_context (SSL_CTX *ctx, const char *path) * @return 1 if an error occured, 0 otherwise */ int -create_secure_connection (SSL_CTX *ctx, const char *hostnname, const char *port, +create_secure_connection (SSL_CTX *ctx, const char *hostname, const char *port, struct MHD_Connection *connection) { BIO *bio = BIO_new_ssl_connect (ctx); @@ -103,7 +133,7 @@ create_secure_connection (SSL_CTX *ctx, const char *hostnname, const char *port, // Prevent some failure when not receiving non-application data SSL_set_mode (ssl, SSL_MODE_AUTO_RETRY); - BIO_set_conn_hostname (bio, hostnname); + BIO_set_conn_hostname (bio, hostname); // Set the BIO in a non blocking mode BIO_set_nbio (bio, 1); if ((1 == SSL_is_init_finished (ssl)) || diff --git a/src/microhttpd/connection_https_openssl.h b/src/microhttpd/connection_https_openssl.h index ddfcb8a5..1dc5e552 100644 --- a/src/microhttpd/connection_https_openssl.h +++ b/src/microhttpd/connection_https_openssl.h @@ -18,15 +18,31 @@ */ /** - * @file connection_https.h + * @file connection_https_openssl.h * @brief Methods for managing connections * @author Edouard LEFIZELIER */ - -#ifndef CONNECTION_HTTPS_EXT_OPENSSL_H -#define CONNECTION_HTTPS_EXT_OPENSSL_H +#ifndef CONNECTION_HTTPS_OPENSSL_H +#define CONNECTION_HTTPS_OPENSSL_H #include "internal.h" +#include "tls_plugin.h" + +#if ENABLE_TLS_PLUGINS + +struct TLS_Plugin * +MHD_TLS_openssl_init (void *ctx); + +#else + +#define OPENSSL_API(rval,fname,...) \ + rval MHD_TLS_openssl_ ## fname (__VA_ARGS__) +TLS_API (OPENSSL_API) +#undef OPENSSL_API + +#endif + + /* Not sure about those includes */ #include "openssl/bio.h" #include "openssl/ssl.h" diff --git a/src/microhttpd/daemon.c b/src/microhttpd/daemon.c index f27fa246..86b34016 100644 --- a/src/microhttpd/daemon.c +++ b/src/microhttpd/daemon.c @@ -1521,6 +1521,8 @@ process_urh (struct MHD_UpgradeResponseHandle *urh) if (data_size > SSIZE_MAX) data_size = SSIZE_MAX; + // res = MHD_TLS_record_send (connection, urh->out_buffer, data_size); + res = gnutls_record_send (connection->tls.gnutls.tls_session, urh->out_buffer, data_size); diff --git a/src/microhttpd/internal.h b/src/microhttpd/internal.h index 77bec185..f61af6d4 100644 --- a/src/microhttpd/internal.h +++ b/src/microhttpd/internal.h @@ -33,6 +33,7 @@ #include "platform.h" #include "microhttpd.h" #include "mhd_assert.h" +#include "tls_plugin.h" #ifdef HTTPS_SUPPORT #include @@ -1940,6 +1941,7 @@ struct MHD_Daemon #ifdef UPGRADE_SUPPORT #ifdef HTTPS_SUPPORT + /** * File descriptor associated with the #run_epoll_for_upgrade() loop. * Only available if #MHD_USE_HTTPS_EPOLL_UPGRADE is set. @@ -2277,6 +2279,13 @@ struct MHD_Daemon union TLS_DaemonState tls_daemonsState; +#if ENABLE_TLS_PLUGINS + /** + * TLS plugin to use. + */ + struct TLS_Plugin *tls_plugin; +#endif + #endif /* HTTPS_SUPPORT */ #ifdef DAUTH_SUPPORT diff --git a/src/microhttpd/tls_plugin.h b/src/microhttpd/tls_plugin.h new file mode 100644 index 00000000..570e6aa9 --- /dev/null +++ b/src/microhttpd/tls_plugin.h @@ -0,0 +1,90 @@ +/* + This file is part of libmicrohttpd + Copyright (C) 2023 Christian Grothoff + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +*/ +/** + * @file tls_plugin.h + * @brief TLS API that enables pluggable TLS use + * @author Christian Grothoff + */ +#ifndef TLS_PLUGIN_H +#define TLS_PLUGIN_H + + +#define TLS_API(M) \ + M (enum MHD_TlsProtocolVersion, get_version, struct MHD_Connection *); \ + M (void, set_callbacks, struct MHD_Connection *); \ + M (bool, connection_shutdown, struct MHD_Connection *); \ + M (ssize_t, record_send, struct MHD_Connection *connection, \ + const void *buf, size_t data_size); \ + M (int, init_certificate, struct MHD_Daemon *); + + +#define TLS_CALLBACKS(rval,fname,...) \ + rval (*fname)(__VA_ARGS__) + +struct TLS_Plugin +{ + TLS_API (TLS_CALLBACKS) +}; + + +#if ENABLE_TLS_PLUGINS + + +/* If we are using a pluggable TLS library, use the plugin! */ + +#define TLS_PLUGIN_API(rval,fname,...) \ + #define MHD_TLS_ ## fname daemon->tls_plugin->fname +TLS_API (TLS_PLUGIN_API) +#undef TLS_PLUGIN_API + +#else +#if HTTPS_WITH_GNUTLS + +/* If we are using GNUtls exclusively, define + MHD_TLS_-API functions to directly use GNUtls variant */ +#define TLS_GNUTLS_API(rval,fname,...) \ + #define MHD_TLS_ ## fname MHD_TLS_gnutls_ ## fname +TLS_API (TLS_GNUTLS_API) +#undef TLS_GNUTLS_API + +#elif HTTPS_WITH_OPENSSL + +/* If we are using OpenSSL exclusively, define + MHD_TLS_-API functions to directly use OpenSSL variant */ +#define TLS_OPENSSL_API(rval,fname,...) \ + #define MHD_TLS_ ## fname MHD_TLS_openssl_ ## fname +TLS_API (TLS_OPENSSL_API) +#undef TLS_OPENSSL_API + +#elif HTTPS_WITH_MBEDTLS + +/* If we are using Mbedtls exclusively, define + MHD_TLS_-API functions to directly use Mbedtls variant */ +#define TLS_MBEDTLS_API(rval,fname,...) \ + #define MHD_TLS_ ## fname MHD_TLS_mbedtls_ ## fname +TLS_API (TLS_MBEDTLS_API) +#undef TLS_MBEDTLS_API + +#else +#error WTF +#endif +#endif + +#endif