libmicrohttpd2

HTTP server C library (MHD 2.x, alpha)
Log | Files | Refs | README | LICENSE

tls_gnu_funcs.h (18149B)


      1 /* SPDX-License-Identifier: LGPL-2.1-or-later OR (GPL-2.0-or-later WITH eCos-exception-2.0) */
      2 /*
      3   This file is part of GNU libmicrohttpd.
      4   Copyright (C) 2024-2025 Evgeny Grin (Karlson2k)
      5 
      6   GNU libmicrohttpd is free software; you can redistribute it and/or
      7   modify it under the terms of the GNU Lesser General Public
      8   License as published by the Free Software Foundation; either
      9   version 2.1 of the License, or (at your option) any later version.
     10 
     11   GNU libmicrohttpd is distributed in the hope that it will be useful,
     12   but WITHOUT ANY WARRANTY; without even the implied warranty of
     13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     14   Lesser General Public License for more details.
     15 
     16   Alternatively, you can redistribute GNU libmicrohttpd and/or
     17   modify it under the terms of the GNU General Public License as
     18   published by the Free Software Foundation; either version 2 of
     19   the License, or (at your option) any later version, together
     20   with the eCos exception, as follows:
     21 
     22     As a special exception, if other files instantiate templates or
     23     use macros or inline functions from this file, or you compile this
     24     file and link it with other works to produce a work based on this
     25     file, this file does not by itself cause the resulting work to be
     26     covered by the GNU General Public License. However the source code
     27     for this file must still be made available in accordance with
     28     section (3) of the GNU General Public License v2.
     29 
     30     This exception does not invalidate any other reasons why a work
     31     based on this file might be covered by the GNU General Public
     32     License.
     33 
     34   You should have received copies of the GNU Lesser General Public
     35   License and the GNU General Public License along with this library;
     36   if not, see <https://www.gnu.org/licenses/>.
     37 */
     38 
     39 /**
     40  * @file src/mhd2/tls_gnu_funcs.h
     41  * @brief  The declarations of GnuTLS wrapper functions
     42  * @author Karlson2k (Evgeny Grin)
     43  */
     44 
     45 #ifndef MHD_TLS_GNU_FUNCS_H
     46 #define MHD_TLS_GNU_FUNCS_H 1
     47 
     48 #include "mhd_sys_options.h"
     49 
     50 #ifndef MHD_SUPPORT_GNUTLS
     51 #  error This header can be used only if GnuTLS is enabled
     52 #endif
     53 
     54 #include "sys_bool_type.h"
     55 #include "sys_base_types.h"
     56 
     57 #include "mhd_status_code_int.h"
     58 
     59 #include "mhd_tls_enums.h"
     60 #include "mhd_tls_cred_ptr.h"
     61 
     62 #include "mhd_socket_error.h"
     63 
     64 /**
     65  * The structure with daemon-specific GnuTLS data
     66  */
     67 struct mhd_TlsGnuDaemonData;    /* Forward declaration */
     68 
     69 /**
     70  * The structure with credentials
     71  */
     72 struct mhd_TlsGnuCredData;      /* Forward declaration */
     73 
     74 /**
     75  * The structure with connection-specific GnuTLS data
     76  */
     77 struct mhd_TlsGnuConnData;      /* Forward declaration */
     78 
     79 union MHD_ConnInfoDynamicTlsSess; /* Forward declaration */
     80 
     81 struct mhd_StctTlsVersion;      /* Forward declaration */
     82 
     83 /* ** Global initialisation / de-initialisation ** */
     84 
     85 /**
     86  * Globally initialise GnuTLS backend
     87  */
     88 MHD_INTERNAL void
     89 mhd_tls_gnu_global_init (void);
     90 
     91 /* An alias for mhd_tls_gnu_global_init() */
     92 #define mhd_tls_gnu_global_init_once()    mhd_tls_gnu_global_init ()
     93 
     94 /* An alias for mhd_tls_gnu_global_init() */
     95 #define mhd_tls_gnu_global_re_init()      mhd_tls_gnu_global_init ()
     96 
     97 /**
     98  * Globally de-initialise GnuTLS backend
     99  */
    100 MHD_INTERNAL void
    101 mhd_tls_gnu_global_deinit (void);
    102 
    103 /**
    104  * Check whether GnuTLS backend was successfully initialised globally
    105  * @return 'true' if backend has been successfully initialised,
    106  *         'false' if backend cannot be used
    107  */
    108 MHD_INTERNAL bool
    109 mhd_tls_gnu_is_inited_fine (void)
    110 MHD_FN_PURE_;
    111 
    112 
    113 /* ** Daemon initialisation / de-initialisation ** */
    114 
    115 struct MHD_Daemon;      /* Forward declaration */
    116 struct DaemonOptions;   /* Forward declaration */
    117 
    118 /**
    119  * Check whether GnuTLS backend supports edge-triggered sockets polling
    120  * @param s the daemon settings
    121  * @return 'true' if the backend supports edge-triggered sockets polling,
    122  *         'false' if edge-triggered sockets polling cannot be used
    123  */
    124 #define mhd_tls_gnu_is_edge_trigg_supported(s) (! 0)
    125 
    126 #ifdef mhd_HAVE_TLS_ACME
    127 /**
    128  * Check whether GnuTLS backend supports ACME ALPN challenge protocol
    129  * @param s the daemon settings
    130  * @return 'true' if the backend supports ACME ALPN challenge protocol,
    131  *         'false' otherwise
    132  */
    133 #  ifdef mhd_HAVE_GNUTLS_ACME
    134 #    define mhd_tls_gnu_is_acme_alpn_supported(s)   ((void)(s), (!0))
    135 #  else  /* ! mhd_HAVE_GNUTLS_ACME */
    136 #    define mhd_tls_gnu_is_acme_alpn_supported(s)   ((void)(s), (!!0))
    137 #  endif /* mhd_HAVE_GNUTLS_ACME */
    138 #endif /* mhd_HAVE_TLS_ACME */
    139 
    140 
    141 /**
    142  * Allocate and initialise daemon TLS parameters
    143  * @param d the daemon handle
    144  * @param s the daemon settings
    145  * @param p_d_tls the pointer to variable to set the pointer to
    146  *                the daemon's TLS settings (allocated by this function)
    147  * @return #MHD_SC_OK on success (p_d_tls set to the allocated settings),
    148  *         error code otherwise
    149  */
    150 MHD_INTERNAL mhd_StatusCodeInt
    151 mhd_tls_gnu_daemon_init3 (struct MHD_Daemon *restrict d,
    152                           struct DaemonOptions *restrict s,
    153                           struct mhd_TlsGnuDaemonData **restrict p_d_tls)
    154 MHD_FN_MUST_CHECK_RESULT_ MHD_FN_PAR_NONNULL_ALL_ MHD_FN_PAR_OUT_ (3);
    155 
    156 
    157 /**
    158  * Allocate and initialise daemon TLS parameters
    159  * @param d the daemon handle
    160  * @param et if 'true' then sockets polling uses edge-triggering
    161  * @param s the daemon settings
    162  * @param p_d_tls the pointer to variable to set the pointer to
    163  *                the daemon's TLS settings (allocated by this function)
    164  * @return #MHD_SC_OK on success (p_d_tls set to the allocated settings),
    165  *         error code otherwise
    166  */
    167 #define mhd_tls_gnu_daemon_init(d, et, s, p_d_tls)        \
    168         mhd_tls_gnu_daemon_init3 ((d),(s),(p_d_tls))
    169 
    170 /**
    171  * De-initialise daemon TLS parameters (and free memory allocated for TLS
    172  * settings)
    173  * @param d_tls the pointer to the daemon's TLS settings
    174  */
    175 MHD_INTERNAL void
    176 mhd_tls_gnu_daemon_deinit (struct mhd_TlsGnuDaemonData *restrict d_tls)
    177 MHD_FN_PAR_NONNULL_ALL_ MHD_FN_PAR_INOUT_ (1);
    178 
    179 /**
    180  * Perform clean-up of TLS resources before thread closing.
    181  * Must be called before thread is closed, after any use of TLS functions
    182  * in the thread, but before de-initialisation of daemon's TLS data.
    183  * @param d_tls the pointer to  the daemon's TLS settings
    184  */
    185 #define mhd_tls_gnu_thread_cleanup(d_tls)       ((void) 0)
    186 
    187 /* ** Credentials creation / destruction ** */
    188 
    189 #ifdef mhd_HAVE_GNUTLS_ACME
    190 /**
    191  * Create TLS credentials from the provided certificate and key data
    192  *
    193  * Created credentials must be destroyed with #mhd_tls_gnu_cred_destroy_nodmn()
    194  * function before de-initialisation of the daemon's TLS settings.
    195  *
    196  * @param d_tls the pointer to the daemon's TLS settings
    197  * @param[out] pp_cred the backend-specific credentials pointer to initialise;
    198  *                     the GnuTLS member is set to the allocated credentials on
    199  *                     success and to NULL on failure
    200  * @param cert_len the length of the @p cert buffer, not including the
    201  *                 zero-termination byte,
    202  *                 must not be zero
    203  * @param cert the certificate data in PEM format, zero-terminated
    204  * @param key_len the length of the @p key buffer, not including the
    205  *                zero-termination byte,
    206  *                must not be zero
    207  * @param key the private key data in PEM format, zero-terminated
    208  * @param pass the password for the private key, zero-terminated,
    209  *             may be NULL if the private key is not password-protected
    210  * @return #mhd_TLS_CRED_CREATE_OK on success,
    211  *         other enum mhd_TlsCredCreateResult values on failure
    212  */
    213 MHD_INTERNAL enum mhd_TlsCredCreateResult
    214 mhd_tls_gnu_cred_create_nopl (struct mhd_TlsGnuDaemonData *restrict d_tls,
    215                               union mhd_TlsCredDataPtr *restrict pp_cred,
    216                               size_t cert_len,
    217                               const char *restrict cert,
    218                               size_t key_len,
    219                               const char *restrict key,
    220                               const char *restrict pass)
    221 MHD_FN_MUST_CHECK_RESULT_
    222 MHD_FN_PAR_NONNULL_ (1) MHD_FN_PAR_NONNULL_ (2)
    223 MHD_FN_PAR_NONNULL_ (4) MHD_FN_PAR_NONNULL_ (6)
    224 MHD_FN_PAR_OUT_ (2)
    225 MHD_FN_PAR_IN_SIZE_ (4, 3) MHD_FN_PAR_IN_SIZE_ (6, 5)
    226 MHD_FN_PAR_CSTR_ (4) MHD_FN_PAR_CSTR_ (6) MHD_FN_PAR_CSTR_ (7);
    227 
    228 /**
    229  * Create TLS credentials from the provided certificate and key data.
    230  *
    231  * Created credentials must be destroyed with #mhd_tls_gnu_cred_destroy_nodmn()
    232  * function before de-initialisation of the daemon's TLS settings.
    233  *
    234  * @param d_tls the pointer to the daemon's TLS settings
    235  * @param[out] pp_c the backend-specific credentials pointer to initialise;
    236  *                  the GnuTLS member is set to the allocated credentials on
    237  *                  success and to NULL on failure
    238  * @param cert_l the length of the @p cert buffer, not including the
    239  *               zero-termination byte,
    240  *               must not be zero
    241  * @param cert the certificate data in PEM format, zero-terminated
    242  * @param k_l the length of the @p key buffer, not including the
    243  *            zero-termination byte,
    244  *            must not be zero
    245  * @param k the private key data in PEM format, zero-terminated
    246  * @param ps_l the length of the @p pass buffer, not including the
    247  *             zero-termination byte,
    248  *             must be zero if the @p pass is NULL
    249  * @param ps the password for the private key, zero-terminated,
    250  *           may be NULL if the private key is not password-protected
    251  * @return #mhd_TLS_CRED_CREATE_OK on success,
    252  *         other enum mhd_TlsCredCreateResult values on failure
    253  */
    254 #  define mhd_tls_gnu_cred_create(d_tls, pp_c, cert_l, cert, k_l, k, ps_l, ps) \
    255         mhd_tls_gnu_cred_create_nopl((d_tls),(pp_c),(cert_l),(cert),\
    256                                      (k_l),(k),(((void)(ps_l)),(ps)))
    257 
    258 /**
    259  * Release TLS credentials and free the allocated memory when no references
    260  * remain.
    261  *
    262  * @param cred the backend-specific credentials pointer to release; the GnuTLS
    263  *             member must be non-NULL
    264  */
    265 MHD_INTERNAL void
    266 mhd_tls_gnu_cred_destroy_nodmn (union mhd_TlsCredDataPtr cred)
    267 MHD_FN_PAR_NONNULL_ALL_;
    268 
    269 #else  /* ! mhd_HAVE_GNUTLS_ACME */
    270 #  define mhd_tls_gnu_cred_create(d_tls, pp_c, cert_l, cert, k_l, k, ps_l, ps) \
    271         ((void)d_tls, (void)pp_c, (void)cert_l, (void)cert, \
    272          (void)k_l, (void)k, (void)ps_l, (void)ps, \
    273          mhd_TLS_CRED_CREATE_UNSUPPORTED)
    274 #  define mhd_tls_gnu_cred_destroy_nodmn(cred)  ((void)(cred))
    275 #endif /* ! mhd_HAVE_GNUTLS_ACME */
    276 
    277 /**
    278  * Release TLS credentials and free the allocated memory when no references
    279  * remain.
    280  *
    281  * @param d_tls the pointer to the daemon's TLS settings
    282  * @param cred the backend-specific credentials pointer to release; the GnuTLS
    283  *             member must be non-NULL
    284  */
    285 #define mhd_tls_gnu_cred_destroy(d_tls, cred) \
    286         do { (void)(d_tls); mhd_tls_gnu_cred_destroy_nodmn ((cred)); } while (0)
    287 
    288 /* ** Connection initialisation / de-initialisation ** */
    289 
    290 struct mhd_ConnSocket; /* Forward declaration */
    291 
    292 /**
    293  * Get size size of the connection's TLS settings
    294  */
    295 MHD_INTERNAL size_t
    296 mhd_tls_gnu_conn_get_tls_size_v (void);
    297 
    298 /**
    299  * Get size size of the connection's TLS settings
    300  * @param d_tls the pointer to the daemon's TLS settings
    301  */
    302 #define mhd_tls_gnu_conn_get_tls_size(d_tls) \
    303         mhd_tls_gnu_conn_get_tls_size_v ()
    304 
    305 /**
    306  * Initialise connection TLS settings
    307  * @param d_tls the daemon TLS settings
    308  * @param sk data about the socket for the connection
    309  * @param[out] c_tls the pointer to the allocated space for
    310  *                   the connection TLS settings
    311  * @return 'true' on success,
    312  *         'false' otherwise
    313  */
    314 MHD_INTERNAL bool
    315 mhd_tls_gnu_conn_init (const struct mhd_TlsGnuDaemonData *restrict d_tls,
    316                        const struct mhd_ConnSocket *sk,
    317                        struct mhd_TlsGnuConnData *restrict c_tls)
    318 MHD_FN_MUST_CHECK_RESULT_ MHD_FN_PAR_NONNULL_ALL_ MHD_FN_PAR_OUT_ (3);
    319 
    320 /**
    321  * De-initialise connection TLS settings.
    322  * The provided pointer is not freed/deallocated.
    323  * @param c_tls the initialised connection TLS settings
    324  */
    325 MHD_INTERNAL void
    326 mhd_tls_gnu_conn_deinit (struct mhd_TlsGnuConnData *restrict c_tls)
    327 MHD_FN_PAR_NONNULL_ALL_;
    328 
    329 
    330 /* ** TLS connection establishing ** */
    331 
    332 /**
    333  * Perform TLS handshake
    334  * @param c_tls the connection TLS handle
    335  * @return #mhd_TLS_PROCED_SUCCESS if completed successfully
    336  *         or other enum mhd_TlsProcedureResult values
    337  */
    338 MHD_INTERNAL enum mhd_TlsProcedureResult
    339 mhd_tls_gnu_conn_handshake (struct mhd_TlsGnuConnData *restrict c_tls)
    340 MHD_FN_MUST_CHECK_RESULT_ MHD_FN_PAR_NONNULL_ALL_;
    341 
    342 /**
    343  * Perform shutdown of TLS layer
    344  * @param c_tls the connection TLS handle
    345  * @return #mhd_TLS_PROCED_SUCCESS if completed successfully
    346  *         or other enum mhd_TlsProcedureResult values
    347  */
    348 MHD_INTERNAL enum mhd_TlsProcedureResult
    349 mhd_tls_gnu_conn_shutdown (struct mhd_TlsGnuConnData *restrict c_tls)
    350 MHD_FN_MUST_CHECK_RESULT_ MHD_FN_PAR_NONNULL_ALL_;
    351 
    352 
    353 /* ** Data sending and receiving over TLS connection ** */
    354 
    355 /**
    356  * Receive the data from the remote side over TLS connection
    357  *
    358  * @param c_tls the connection TLS handle
    359  * @param buf_size the size of the @a buf buffer
    360  * @param[out] buf the buffer to fill with the received data
    361  * @param[out] received the pointer to variable to get the size of the data
    362  *                      actually put to the @a buffer
    363  * @return mhd_SOCKET_ERR_NO_ERROR if receive succeed (the @a received gets
    364  *         the received size) or socket error
    365  */
    366 MHD_INTERNAL enum mhd_SocketError
    367 mhd_tls_gnu_conn_recv (struct mhd_TlsGnuConnData *restrict c_tls,
    368                        size_t buf_size,
    369                        char buf[MHD_FN_PAR_DYN_ARR_SIZE_ (buf_size)],
    370                        size_t *restrict received)
    371 MHD_FN_PAR_NONNULL_ALL_ MHD_FN_PAR_OUT_SIZE_ (3, 2) MHD_FN_PAR_OUT_ (4);
    372 
    373 /**
    374  * Check whether any incoming data is pending in the TLS buffers
    375  *
    376  * @param c_tls the connection TLS handle
    377  * @return 'true' if any incoming remote data is already pending (the TLS recv()
    378  *          call can be performed),
    379  *         'false' otherwise
    380  */
    381 MHD_INTERNAL bool
    382 mhd_tls_gnu_conn_has_data_in (struct mhd_TlsGnuConnData *restrict c_tls)
    383 MHD_FN_PAR_NONNULL_ALL_;
    384 
    385 /**
    386  * Send data to the remote side over TLS connection
    387  *
    388  * @param c_tls the connection TLS handle
    389  * @param buf_size the size of the @a buf (in bytes)
    390  * @param buf content of the buffer to send
    391  * @param[out] sent the pointer to get amount of actually sent bytes
    392  * @return mhd_SOCKET_ERR_NO_ERROR if send succeed (the @a sent gets
    393  *         the sent size) or socket error
    394  */
    395 MHD_INTERNAL enum mhd_SocketError
    396 mhd_tls_gnu_conn_send4 (struct mhd_TlsGnuConnData *restrict c_tls,
    397                         size_t buf_size,
    398                         const char buf[MHD_FN_PAR_DYN_ARR_SIZE_ (buf_size)],
    399                         size_t *restrict sent)
    400 MHD_FN_PAR_NONNULL_ALL_ MHD_FN_PAR_IN_SIZE_ (3, 2) MHD_FN_PAR_OUT_ (4);
    401 
    402 /**
    403  * Send data to the remote side over TLS connection
    404  *
    405  * @param c_tls the connection TLS handle
    406  * @param buf_size the size of the @a buf (in bytes)
    407  * @param buf content of the buffer to send
    408  * @param push_data set to 'false' if it is know that the data in the @a b
    409  *                  is incomplete (message or chunk),
    410  *                  set to 'true' if the data is complete or the final part
    411  * @param[out] sent the pointer to get amount of actually sent bytes
    412  * @return mhd_SOCKET_ERR_NO_ERROR if send succeed (the @a sent gets
    413  *         the sent size) or socket error
    414  */
    415 #define mhd_tls_gnu_conn_send(c_tls, buf_size, buf, push_data, sent) \
    416         mhd_tls_gnu_conn_send4 (c_tls,buf_size,buf,sent)
    417 
    418 /* ** TLS connection information ** */
    419 
    420 /**
    421  * Check whether the connection is using "custom transport" functions.
    422  * "Custom transport" means that data sending and receiving over system
    423  * sockets is performed by MHD callbacks.
    424  * When "custom transport" is used, backend TLS send/recv functions are:
    425  * * perform additional syscalls (socket options) for data pushing/buffering,
    426  * * change socket states like corked, NO_DELAY, both by syscalls and in
    427  *   MHD socket metadata,
    428  * * set disconnect error from the system reported socket error.
    429  *
    430  * @param c_tls the connection TLS handle
    431  * @return boolean 'true' if custom transport is used,
    432  *         boolean 'false' otherwise
    433  */
    434 #define mhd_tls_gnu_conn_has_cstm_tr(c_tls)    (! ! 0)
    435 
    436 /**
    437  * Get the TLS session used in connection
    438  * @param c_tls the connection TLS handle
    439  * @param tls_sess_out the pointer to variable to be set to the TLS session
    440  *                     handle
    441  */
    442 MHD_INTERNAL void
    443 mhd_tls_gnu_conn_get_tls_sess (
    444   struct mhd_TlsGnuConnData *restrict c_tls,
    445   union MHD_ConnInfoDynamicTlsSess *restrict tls_sess_out)
    446 MHD_FN_PAR_NONNULL_ALL_ MHD_FN_PAR_OUT_ (2);
    447 
    448 /**
    449  * Get the TLS version used in connection
    450  * @param c_tls the connection TLS handle
    451  * @param tls_ver_out the pointer to variable to be set to the TLS version
    452  * @return 'true' is TLS version information set successfully,
    453  *         'false' if TLS version information cannot be obtained or mapped
    454  */
    455 MHD_INTERNAL bool
    456 mhd_tls_gnu_conn_get_tls_ver (struct mhd_TlsGnuConnData *restrict c_tls,
    457                               struct mhd_StctTlsVersion *restrict tls_ver_out)
    458 MHD_FN_PAR_NONNULL_ALL_ MHD_FN_PAR_OUT_ (2);
    459 
    460 /**
    461  * Get a protocol selected by ALPN
    462  * @param c_tls the connection TLS handle
    463  * @return the selected protocol code
    464  */
    465 MHD_INTERNAL enum mhd_TlsAlpnProt
    466 mhd_tls_gnu_conn_get_alpn_prot (struct mhd_TlsGnuConnData *restrict c_tls)
    467 MHD_FN_PAR_NONNULL_ALL_;
    468 
    469 #ifdef mhd_HAVE_TLS_ACME
    470 /**
    471  * Check whether the connection is ACME ALPN challenge connection
    472  * @param c_tls the connection TLS handle
    473  * @return 'true' if the connection is ACME ALPN challenge connection,
    474  *         'false' otherwise
    475  */
    476 #  ifdef mhd_HAVE_GNUTLS_ACME
    477 MHD_INTERNAL bool
    478 mhd_tls_gnu_conn_is_acme (struct mhd_TlsGnuConnData *restrict c_tls)
    479 MHD_FN_PAR_NONNULL_ALL_;
    480 
    481 #  else  /* ! mhd_HAVE_GNUTLS_ACME */
    482 #    define mhd_tls_gnu_conn_is_acme(c_tls) (((void)(c_tls)), (!!0))
    483 #  endif /* ! mhd_HAVE_GNUTLS_ACME */
    484 #endif /* mhd_HAVE_TLS_ACME */
    485 
    486 
    487 #endif /* ! MHD_TLS_GNU_FUNCS_H */