tls_multi_funcs.c (30963B)
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_multi_funcs.c 41 * @brief The implementation of MultiTLS wrapper functions 42 * @author Karlson2k (Evgeny Grin) 43 */ 44 45 #include "mhd_sys_options.h" 46 47 #include "sys_bool_type.h" 48 49 #include "mhd_assert.h" 50 #include "mhd_unreachable.h" 51 52 #include "compat_calloc.h" 53 #include "sys_malloc.h" 54 55 #include "mhd_arr_num_elems.h" 56 57 #include "tls_multi_tls_lib.h" 58 59 #include "tls_multi_daemon_data.h" 60 #include "tls_multi_conn_data.h" 61 #include "tls_multi_funcs.h" 62 63 /* Include all supported TLS backends headers */ 64 #if defined(MHD_SUPPORT_GNUTLS) 65 # include "tls_gnu_funcs.h" 66 #endif 67 #if defined(MHD_SUPPORT_OPENSSL) 68 # include "tls_open_funcs.h" 69 #endif 70 #if defined(MHD_SUPPORT_MBEDTLS) 71 # include "tls_mbed_funcs.h" 72 #endif 73 74 #include "daemon_options.h" 75 #include "daemon_logger.h" 76 77 #ifdef mhd_USE_TLS_DEBUG_MESSAGES 78 # include <stdio.h> /* For TLS debug printing */ 79 #endif 80 81 #include "mhd_public_api.h" 82 83 #ifdef mhd_USE_TLS_DEBUG_MESSAGES 84 # define mhd_M_DEBUG_PRINT(msg) \ 85 do { fprintf (stderr, "## MultiTLS: " msg "\n"); \ 86 fflush (stderr); } while (0) 87 # define mhd_M_DEBUG_PRINT1(msg, arg1) \ 88 do { fprintf (stderr, "## MultiTLS: " msg "\n", arg1); \ 89 fflush (stderr); } while (0) 90 #else 91 # define mhd_M_DEBUG_PRINT(msg) ((void) 0) 92 # define mhd_M_DEBUG_PRINT1(msg, arg1) ((void) 0) 93 #endif 94 95 96 /* ** Global initialisation / de-initialisation ** */ 97 98 MHD_INTERNAL void 99 mhd_tls_multi_global_init_once (void) 100 { 101 #if defined(MHD_SUPPORT_GNUTLS) 102 mhd_tls_gnu_global_init_once (); 103 #endif 104 #if defined(MHD_SUPPORT_OPENSSL) 105 mhd_tls_open_global_init_once (); 106 #endif 107 #if defined(MHD_SUPPORT_MBEDTLS) 108 mhd_tls_mbed_global_init_once (); 109 #endif 110 } 111 112 113 MHD_INTERNAL void 114 mhd_tls_multi_global_deinit (void) 115 { 116 /* Note: the order is reversed to match the initialisation */ 117 #if defined(MHD_SUPPORT_OPENSSL) 118 mhd_tls_open_global_deinit (); 119 #endif 120 #if defined(MHD_SUPPORT_GNUTLS) 121 mhd_tls_gnu_global_deinit (); 122 #endif 123 #if defined(MHD_SUPPORT_MBEDTLS) 124 mhd_tls_mbed_global_deinit (); 125 #endif 126 } 127 128 129 MHD_INTERNAL void 130 mhd_tls_multi_global_re_init (void) 131 { 132 #if defined(MHD_SUPPORT_GNUTLS) 133 mhd_tls_gnu_global_re_init (); 134 #endif 135 #if defined(MHD_SUPPORT_OPENSSL) 136 mhd_tls_open_global_re_init (); 137 #endif 138 #if defined(MHD_SUPPORT_MBEDTLS) 139 mhd_tls_mbed_global_re_init (); 140 #endif 141 } 142 143 144 /* ** Daemon initialisation / de-initialisation ** */ 145 146 MHD_INTERNAL MHD_FN_PURE_ bool 147 mhd_tls_multi_is_edge_trigg_supported (struct DaemonOptions *s) 148 { 149 switch (s->tls) 150 { 151 case MHD_TLS_BACKEND_NONE: 152 mhd_UNREACHABLE (); 153 return false; 154 case MHD_TLS_BACKEND_ANY: 155 #ifdef MHD_SUPPORT_GNUTLS 156 if (mhd_tls_gnu_is_edge_trigg_supported (s) 157 && mhd_tls_gnu_is_inited_fine ()) 158 # ifdef mhd_HAVE_TLS_ACME 159 if (mhd_tls_gnu_is_acme_alpn_supported (s) 160 || !s->acme_alpn_required) 161 # endif /* mhd_HAVE_TLS_ACME */ 162 return true; 163 #endif 164 #ifdef MHD_SUPPORT_OPENSSL 165 if (mhd_tls_open_is_edge_trigg_supported (s) 166 && mhd_tls_open_is_inited_fine ()) 167 # ifdef mhd_HAVE_TLS_ACME 168 if (mhd_tls_open_is_acme_alpn_supported (s) 169 || !s->acme_alpn_required) 170 # endif /* mhd_HAVE_TLS_ACME */ 171 return true; 172 #endif 173 #ifdef MHD_SUPPORT_MBEDTLS 174 if (mhd_tls_mbed_is_edge_trigg_supported (s) 175 && mhd_tls_mbed_is_inited_fine ()) 176 # ifdef mhd_HAVE_TLS_ACME 177 if (mhd_tls_mbed_is_acme_alpn_supported (s) 178 || !s->acme_alpn_required) 179 # endif /* mhd_HAVE_TLS_ACME */ 180 return true; 181 #endif 182 return false; 183 case MHD_TLS_BACKEND_GNUTLS: 184 #ifdef MHD_SUPPORT_GNUTLS 185 /* Ignore "backend inited" status here, 186 it will be checked on daemon TLS init */ 187 return mhd_tls_gnu_is_edge_trigg_supported (s); 188 #endif 189 break; 190 case MHD_TLS_BACKEND_OPENSSL: 191 #ifdef MHD_SUPPORT_OPENSSL 192 /* Ignore "backend inited" status here, 193 it will be checked on daemon TLS init */ 194 return mhd_tls_open_is_edge_trigg_supported (s); 195 #endif 196 break; 197 case MHD_TLS_BACKEND_MBEDTLS: 198 #ifdef MHD_SUPPORT_MBEDTLS 199 /* Ignore "backend inited" status here, 200 it will be checked on daemon TLS init */ 201 return mhd_tls_mbed_is_edge_trigg_supported (s); 202 #endif 203 break; 204 default: 205 mhd_UNREACHABLE (); 206 break; 207 } 208 return false; 209 } 210 211 212 #ifdef mhd_HAVE_TLS_ACME 213 MHD_INTERNAL MHD_FN_PURE_ bool 214 mhd_tls_multi_is_acme_alpn_supported (struct DaemonOptions *s) 215 { 216 switch (s->tls) 217 { 218 case MHD_TLS_BACKEND_NONE: 219 mhd_UNREACHABLE (); 220 return false; 221 case MHD_TLS_BACKEND_ANY: 222 # ifdef MHD_SUPPORT_GNUTLS 223 if (mhd_tls_gnu_is_acme_alpn_supported (s) 224 && mhd_tls_gnu_is_inited_fine ()) 225 return true; 226 # endif 227 # ifdef MHD_SUPPORT_OPENSSL 228 if (mhd_tls_open_is_acme_alpn_supported (s) 229 && mhd_tls_open_is_inited_fine ()) 230 return true; 231 # endif 232 # ifdef MHD_SUPPORT_MBEDTLS 233 if (mhd_tls_mbed_is_acme_alpn_supported (s) 234 && mhd_tls_mbed_is_inited_fine ()) 235 return true; 236 # endif 237 return false; 238 case MHD_TLS_BACKEND_GNUTLS: 239 # ifdef MHD_SUPPORT_GNUTLS 240 /* Ignore "backend inited" status here, 241 it will be checked on daemon TLS init */ 242 return mhd_tls_gnu_is_acme_alpn_supported (s); 243 # endif 244 break; 245 case MHD_TLS_BACKEND_OPENSSL: 246 # ifdef MHD_SUPPORT_OPENSSL 247 /* Ignore "backend inited" status here, 248 it will be checked on daemon TLS init */ 249 return mhd_tls_open_is_acme_alpn_supported (s); 250 # endif 251 break; 252 case MHD_TLS_BACKEND_MBEDTLS: 253 # ifdef MHD_SUPPORT_MBEDTLS 254 /* Ignore "backend inited" status here, 255 it will be checked on daemon TLS init */ 256 return mhd_tls_mbed_is_acme_alpn_supported (s); 257 # endif 258 break; 259 default: 260 mhd_UNREACHABLE (); 261 break; 262 } 263 return false; 264 } 265 266 267 #endif /* mhd_HAVE_TLS_ACME */ 268 269 /** 270 * Initialise selected TLS backend for the daemon 271 * @param route the selected TLS backend 272 * @param d the daemon handle 273 * @param s the daemon settings 274 * @param d_tls the daemon's TLS settings, backend-specific data is allocated 275 * and initialised 276 * @return #MHD_SC_OK on success (the backend-specific data is allocated), 277 * error code otherwise 278 */ 279 static MHD_FN_MUST_CHECK_RESULT_ MHD_FN_PAR_NONNULL_ALL_ 280 MHD_FN_PAR_OUT_ (5) mhd_StatusCodeInt 281 tls_daemon_init_try (enum mhd_TlsMultiRoute route, 282 struct MHD_Daemon *restrict d, 283 bool sk_edge_trigg, 284 struct DaemonOptions *restrict s, 285 struct mhd_TlsMultiDaemonData *restrict d_tls) 286 { 287 mhd_StatusCodeInt res; 288 289 #ifndef MHD_SUPPORT_OPENSSL 290 (void)sk_edge_trigg; /* Unused, mute compiler warning */ 291 #endif /* ! MHD_SUPPORT_OPENSSL */ 292 293 switch (route) 294 { 295 #ifdef MHD_SUPPORT_GNUTLS 296 case mhd_TLS_MULTI_ROUTE_GNU: 297 if (!mhd_tls_gnu_is_inited_fine ()) 298 return MHD_SC_TLS_BACKEND_UNAVAILABLE; 299 res = mhd_tls_gnu_daemon_init (d, 300 sk_edge_trigg, 301 s, 302 &(d_tls->data.gnutls)); 303 if (MHD_SC_OK == res) 304 { 305 mhd_M_DEBUG_PRINT ("GnuTLS backend initialised successfully " \ 306 "for the daemon"); 307 d_tls->choice = route; 308 return MHD_SC_OK; 309 } 310 mhd_M_DEBUG_PRINT1 ("Failed to initialise GnuTLS backend for " \ 311 "the daemon, error code: %u", (unsigned)res); 312 return res; 313 #endif 314 #ifdef MHD_SUPPORT_OPENSSL 315 case mhd_TLS_MULTI_ROUTE_OPEN: 316 if (!mhd_tls_open_is_inited_fine ()) 317 return MHD_SC_TLS_BACKEND_UNAVAILABLE; 318 res = mhd_tls_open_daemon_init (d, 319 sk_edge_trigg, 320 s, 321 &(d_tls->data.openssl)); 322 if (MHD_SC_OK == res) 323 { 324 mhd_M_DEBUG_PRINT ("OpenSSL backend initialised successfully " \ 325 "for the daemon"); 326 d_tls->choice = route; 327 return MHD_SC_OK; 328 } 329 mhd_M_DEBUG_PRINT1 ("Failed to initialise OpenSSL backend for " \ 330 "the daemon, error code: %u", (unsigned)res); 331 return res; 332 #endif 333 #ifdef MHD_SUPPORT_MBEDTLS 334 case mhd_TLS_MULTI_ROUTE_MBED: 335 if (!mhd_tls_mbed_is_inited_fine ()) 336 return MHD_SC_TLS_BACKEND_UNAVAILABLE; 337 res = mhd_tls_mbed_daemon_init (d, 338 sk_edge_trigg, 339 s, 340 &(d_tls->data.mbedtls)); 341 if (MHD_SC_OK == res) 342 { 343 mhd_M_DEBUG_PRINT ("MbedTLS backend initialised successfully " \ 344 "for the daemon"); 345 d_tls->choice = route; 346 return MHD_SC_OK; 347 } 348 mhd_M_DEBUG_PRINT1 ("Failed to initialise MbedTLS backend for " \ 349 "the daemon, error code: %u", (unsigned)res); 350 return res; 351 #endif 352 case mhd_TLS_MULTI_ROUTE_NONE: 353 default: 354 break; 355 } 356 mhd_assert (0 && "Impossible value"); 357 mhd_UNREACHABLE (); 358 return MHD_SC_INTERNAL_ERROR; 359 } 360 361 362 MHD_INTERNAL MHD_FN_MUST_CHECK_RESULT_ MHD_FN_PAR_NONNULL_ALL_ 363 MHD_FN_PAR_OUT_ (4) mhd_StatusCodeInt 364 mhd_tls_multi_daemon_init (struct MHD_Daemon *restrict d, 365 bool sk_edge_trigg, 366 struct DaemonOptions *restrict s, 367 struct mhd_TlsMultiDaemonData **restrict p_d_tls) 368 { 369 mhd_StatusCodeInt res; 370 struct mhd_TlsMultiDaemonData *restrict d_tls; 371 d_tls = (struct mhd_TlsMultiDaemonData *) 372 mhd_calloc (1, 373 sizeof (struct mhd_TlsMultiDaemonData)); 374 if (NULL == d_tls) 375 return MHD_SC_DAEMON_MEM_ALLOC_FAILURE; 376 377 d_tls->choice = mhd_TLS_MULTI_ROUTE_NONE; 378 #ifndef HAVE_NULL_PTR_ALL_ZEROS 379 # ifdef MHD_SUPPORT_GNUTLS 380 d_tls->data.gnutls = NULL; 381 # endif /* MHD_SUPPORT_GNUTLS */ 382 # ifdef MHD_SUPPORT_OPENSSL 383 d_tls->data.openssl = NULL; 384 # endif /* MHD_SUPPORT_OPENSSL */ 385 # ifdef MHD_SUPPORT_MBEDTLS 386 d_tls->data.mbedtls = NULL; 387 # endif /* MHD_SUPPORT_MBEDTLS */ 388 #endif /* ! HAVE_NULL_PTR_ALL_ZEROS */ 389 390 res = MHD_SC_INTERNAL_ERROR; /* Mute compiler warning, the value should not be used */ 391 switch (s->tls) 392 { 393 case MHD_TLS_BACKEND_ANY: 394 if (1) 395 { 396 size_t i; 397 enum mhd_TlsMultiRoute backends[] = { 398 #ifdef MHD_SUPPORT_GNUTLS 399 mhd_TLS_MULTI_ROUTE_GNU, 400 #endif 401 #ifdef MHD_SUPPORT_OPENSSL 402 mhd_TLS_MULTI_ROUTE_OPEN, 403 #endif 404 #ifdef MHD_SUPPORT_MBEDTLS 405 mhd_TLS_MULTI_ROUTE_MBED, 406 #endif 407 mhd_TLS_MULTI_ROUTE_NONE /* Not used */ 408 }; 409 /* Try backends one-by-one */ 410 for (i = 0; i < mhd_ARR_NUM_ELEMS (backends) - 1; ++i) 411 { 412 res = tls_daemon_init_try (backends[i], 413 d, 414 sk_edge_trigg, 415 s, 416 d_tls); 417 if (MHD_SC_OK == res) 418 break; 419 } 420 } 421 break; 422 #ifdef MHD_SUPPORT_GNUTLS 423 case MHD_TLS_BACKEND_GNUTLS: 424 mhd_assert (mhd_tls_gnu_is_inited_fine ()); /* Must be checked earlier */ 425 res = tls_daemon_init_try (mhd_TLS_MULTI_ROUTE_GNU, 426 d, 427 sk_edge_trigg, 428 s, 429 d_tls); 430 break; 431 #endif /* MHD_SUPPORT_GNUTLS */ 432 #ifdef MHD_SUPPORT_OPENSSL 433 case MHD_TLS_BACKEND_OPENSSL: 434 mhd_assert (mhd_tls_open_is_inited_fine ()); /* Must be checked earlier */ 435 res = tls_daemon_init_try (mhd_TLS_MULTI_ROUTE_OPEN, 436 d, 437 sk_edge_trigg, 438 s, 439 d_tls); 440 #endif /* MHD_SUPPORT_OPENSSL */ 441 break; 442 #ifdef MHD_SUPPORT_MBEDTLS 443 case MHD_TLS_BACKEND_MBEDTLS: 444 mhd_assert (mhd_tls_mbed_is_inited_fine ()); /* Must be checked earlier */ 445 res = tls_daemon_init_try (mhd_TLS_MULTI_ROUTE_MBED, 446 d, 447 sk_edge_trigg, 448 s, 449 d_tls); 450 #endif /* MHD_SUPPORT_MBEDTLS */ 451 break; 452 453 #ifndef MHD_SUPPORT_GNUTLS 454 case MHD_TLS_BACKEND_GNUTLS: 455 #endif /* ! MHD_SUPPORT_GNUTLS */ 456 #ifndef MHD_SUPPORT_OPENSSL 457 case MHD_TLS_BACKEND_OPENSSL: 458 #endif /* ! MHD_SUPPORT_OPENSSL */ 459 #ifndef MHD_SUPPORT_MBEDTLS 460 case MHD_TLS_BACKEND_MBEDTLS: 461 #endif /* ! MHD_SUPPORT_MBEDTLS */ 462 case MHD_TLS_BACKEND_NONE: 463 default: 464 mhd_UNREACHABLE (); 465 res = MHD_SC_TLS_BACKEND_UNSUPPORTED; 466 break; 467 } 468 mhd_assert (NULL != d_tls); 469 if (MHD_SC_OK == res) 470 { 471 *p_d_tls = d_tls; 472 return MHD_SC_OK; 473 } 474 free (d_tls); 475 return res; 476 } 477 478 479 MHD_INTERNAL MHD_FN_PAR_NONNULL_ALL_ 480 MHD_FN_PAR_INOUT_ (1) void 481 mhd_tls_multi_daemon_deinit (struct mhd_TlsMultiDaemonData *restrict d_tls) 482 { 483 switch (d_tls->choice) 484 { 485 #ifdef MHD_SUPPORT_GNUTLS 486 case mhd_TLS_MULTI_ROUTE_GNU: 487 mhd_tls_gnu_daemon_deinit (d_tls->data.gnutls); 488 break; 489 #endif 490 #ifdef MHD_SUPPORT_OPENSSL 491 case mhd_TLS_MULTI_ROUTE_OPEN: 492 mhd_tls_open_daemon_deinit (d_tls->data.openssl); 493 break; 494 #endif 495 #ifdef MHD_SUPPORT_MBEDTLS 496 case mhd_TLS_MULTI_ROUTE_MBED: 497 mhd_tls_mbed_daemon_deinit (d_tls->data.mbedtls); 498 break; 499 #endif 500 case mhd_TLS_MULTI_ROUTE_NONE: 501 default: 502 mhd_UNREACHABLE (); 503 break; 504 } 505 free (d_tls); 506 } 507 508 509 #ifdef mhd_HAVE_TLS_THREAD_CLEANUP 510 /** 511 * Perform clean-up of TLS resources before thread closing. 512 * Must be called before thread is closed, after any use of TLS functions 513 * in the thread, but before de-initialisation of daemon's TLS data. 514 * @param d_tls the pointer to the daemon's TLS settings 515 */ 516 MHD_INTERNAL MHD_FN_PAR_NONNULL_ALL_ 517 MHD_FN_PAR_INOUT_ (1) void 518 mhd_tls_multi_thread_cleanup (struct mhd_TlsMultiDaemonData *restrict d_tls) 519 { 520 switch (d_tls->choice) 521 { 522 # ifdef MHD_SUPPORT_GNUTLS 523 case mhd_TLS_MULTI_ROUTE_GNU: 524 mhd_tls_gnu_thread_cleanup (d_tls->data.gnutls); 525 break; 526 # endif 527 # ifdef MHD_SUPPORT_OPENSSL 528 case mhd_TLS_MULTI_ROUTE_OPEN: 529 mhd_tls_open_thread_cleanup (d_tls->data.openssl); 530 break; 531 # endif 532 # ifdef MHD_SUPPORT_MBEDTLS 533 case mhd_TLS_MULTI_ROUTE_MBED: 534 mhd_tls_mbed_thread_cleanup (d_tls->data.mbedtls); 535 break; 536 # endif 537 case mhd_TLS_MULTI_ROUTE_NONE: 538 default: 539 mhd_UNREACHABLE (); 540 break; 541 } 542 } 543 544 545 #endif /* mhd_HAVE_TLS_THREAD_CLEANUP */ 546 547 /* ** Credentials creation / destruction ** */ 548 549 #ifdef mhd_HAVE_TLS_ACME 550 551 MHD_INTERNAL MHD_FN_MUST_CHECK_RESULT_ 552 MHD_FN_PAR_NONNULL_ (1) MHD_FN_PAR_NONNULL_ (2) 553 MHD_FN_PAR_NONNULL_ (4) MHD_FN_PAR_NONNULL_ (6) 554 MHD_FN_PAR_OUT_ (2) 555 MHD_FN_PAR_IN_SIZE_ (4, 3) MHD_FN_PAR_IN_SIZE_ (6, 5) 556 MHD_FN_PAR_IN_SIZE_ (8, 7) 557 MHD_FN_PAR_CSTR_ (4) MHD_FN_PAR_CSTR_ (6) MHD_FN_PAR_CSTR_ (8) 558 enum mhd_TlsCredCreateResult 559 mhd_tls_multi_cred_create (struct mhd_TlsMultiDaemonData *restrict d_tls, 560 union mhd_TlsCredDataPtr *restrict pp_cred, 561 size_t cert_len, 562 const char *restrict cert, 563 size_t key_len, 564 const char *restrict key, 565 size_t pass_len, 566 const char *restrict pass) 567 { 568 switch (d_tls->choice) 569 { 570 # ifdef MHD_SUPPORT_GNUTLS 571 case mhd_TLS_MULTI_ROUTE_GNU: 572 return mhd_tls_gnu_cred_create (d_tls->data.gnutls, 573 pp_cred, 574 cert_len, 575 cert, 576 key_len, 577 key, 578 pass_len, 579 pass); 580 # endif 581 # ifdef MHD_SUPPORT_OPENSSL 582 case mhd_TLS_MULTI_ROUTE_OPEN: 583 return mhd_tls_open_cred_create (d_tls->data.openssl, 584 pp_cred, 585 cert_len, 586 cert, 587 key_len, 588 key, 589 pass_len, 590 pass); 591 # endif 592 # ifdef MHD_SUPPORT_MBEDTLS 593 case mhd_TLS_MULTI_ROUTE_MBED: 594 return mhd_tls_mbed_cred_create (d_tls->data.mbedtls, 595 pp_cred, 596 cert_len, 597 cert, 598 key_len, 599 key, 600 pass_len, 601 pass); 602 # endif 603 case mhd_TLS_MULTI_ROUTE_NONE: 604 default: 605 mhd_UNREACHABLE (); 606 } 607 608 return mhd_TLS_CRED_CREATE_UNSUPPORTED; 609 } 610 611 612 MHD_INTERNAL MHD_FN_PAR_NONNULL_ALL_ void 613 mhd_tls_multi_cred_destroy (struct mhd_TlsMultiDaemonData *restrict d_tls, 614 union mhd_TlsCredDataPtr cred) 615 { 616 switch (d_tls->choice) 617 { 618 # ifdef MHD_SUPPORT_GNUTLS 619 case mhd_TLS_MULTI_ROUTE_GNU: 620 mhd_tls_gnu_cred_destroy (d_tls->data.gnutls, 621 cred); 622 break; 623 # endif 624 # ifdef MHD_SUPPORT_OPENSSL 625 case mhd_TLS_MULTI_ROUTE_OPEN: 626 mhd_tls_open_cred_destroy (d_tls->data.openssl, 627 cred); 628 break; 629 # endif 630 # ifdef MHD_SUPPORT_MBEDTLS 631 case mhd_TLS_MULTI_ROUTE_MBED: 632 mhd_tls_mbed_cred_destroy (d_tls->data.mbedtls, 633 cred); 634 break; 635 # endif 636 case mhd_TLS_MULTI_ROUTE_NONE: 637 default: 638 mhd_UNREACHABLE (); 639 } 640 } 641 642 643 #endif /* mhd_HAVE_TLS_ACME */ 644 645 /* ** Connection initialisation / de-initialisation ** */ 646 647 MHD_INTERNAL size_t 648 mhd_tls_multi_conn_get_tls_size (struct mhd_TlsMultiDaemonData *restrict d_tls) 649 { 650 size_t data_size; 651 652 data_size = sizeof(struct mhd_TlsMultiConnData); 653 switch (d_tls->choice) 654 { 655 #ifdef MHD_SUPPORT_GNUTLS 656 case mhd_TLS_MULTI_ROUTE_GNU: 657 data_size += mhd_tls_gnu_conn_get_tls_size (d_tls->data.gnutls); 658 break; 659 #endif 660 #ifdef MHD_SUPPORT_OPENSSL 661 case mhd_TLS_MULTI_ROUTE_OPEN: 662 data_size += mhd_tls_open_conn_get_tls_size (d_tls->data.openssl); 663 break; 664 #endif 665 #ifdef MHD_SUPPORT_MBEDTLS 666 case mhd_TLS_MULTI_ROUTE_MBED: 667 data_size += mhd_tls_mbed_conn_get_tls_size (d_tls->data.mbedtls); 668 break; 669 #endif 670 case mhd_TLS_MULTI_ROUTE_NONE: 671 default: 672 mhd_UNREACHABLE (); 673 } 674 675 return data_size; 676 } 677 678 679 MHD_INTERNAL MHD_FN_MUST_CHECK_RESULT_ MHD_FN_PAR_NONNULL_ALL_ 680 MHD_FN_PAR_OUT_ (3) bool 681 mhd_tls_multi_conn_init (const struct mhd_TlsMultiDaemonData *restrict d_tls, 682 struct mhd_ConnSocket *sk, 683 struct mhd_TlsMultiConnData *restrict c_tls) 684 { 685 c_tls->choice = d_tls->choice; 686 switch (c_tls->choice) 687 { 688 #ifdef MHD_SUPPORT_GNUTLS 689 case mhd_TLS_MULTI_ROUTE_GNU: 690 /* Assume the same alignment requirements for both structures */ 691 c_tls->data.gnutls = (struct mhd_TlsGnuConnData *)(c_tls + 1); 692 return mhd_tls_gnu_conn_init (d_tls->data.gnutls, 693 sk, 694 c_tls->data.gnutls); 695 #endif 696 #ifdef MHD_SUPPORT_OPENSSL 697 case mhd_TLS_MULTI_ROUTE_OPEN: 698 /* Assume the same alignment requirements for both structures */ 699 c_tls->data.openssl = (struct mhd_TlsOpenConnData *)(c_tls + 1); 700 return mhd_tls_open_conn_init (d_tls->data.openssl, 701 sk, 702 c_tls->data.openssl); 703 #endif 704 #ifdef MHD_SUPPORT_MBEDTLS 705 case mhd_TLS_MULTI_ROUTE_MBED: 706 /* Assume the same alignment requirements for both structures */ 707 c_tls->data.mbedtls = (struct mhd_TlsMbedConnData *)(c_tls + 1); 708 return mhd_tls_mbed_conn_init (d_tls->data.mbedtls, 709 sk, 710 c_tls->data.mbedtls); 711 #endif 712 case mhd_TLS_MULTI_ROUTE_NONE: 713 default: 714 mhd_UNREACHABLE (); 715 break; 716 } 717 718 return false; 719 } 720 721 722 /** 723 * De-initialise connection TLS settings. 724 * The provided pointer is not freed/deallocated. 725 * @param c_tls the initialised connection TLS settings 726 */ 727 MHD_INTERNAL MHD_FN_PAR_NONNULL_ALL_ void 728 mhd_tls_multi_conn_deinit (struct mhd_TlsMultiConnData *restrict c_tls) 729 { 730 switch (c_tls->choice) 731 { 732 #ifdef MHD_SUPPORT_GNUTLS 733 case mhd_TLS_MULTI_ROUTE_GNU: 734 mhd_tls_gnu_conn_deinit (c_tls->data.gnutls); 735 break; 736 #endif 737 #ifdef MHD_SUPPORT_OPENSSL 738 case mhd_TLS_MULTI_ROUTE_OPEN: 739 mhd_tls_open_conn_deinit (c_tls->data.openssl); 740 break; 741 #endif 742 #ifdef MHD_SUPPORT_MBEDTLS 743 case mhd_TLS_MULTI_ROUTE_MBED: 744 mhd_tls_mbed_conn_deinit (c_tls->data.mbedtls); 745 break; 746 #endif 747 case mhd_TLS_MULTI_ROUTE_NONE: 748 default: 749 mhd_UNREACHABLE (); 750 } 751 } 752 753 754 /* ** TLS connection establishing ** */ 755 756 MHD_INTERNAL MHD_FN_MUST_CHECK_RESULT_ MHD_FN_PAR_NONNULL_ALL_ 757 enum mhd_TlsProcedureResult 758 mhd_tls_multi_conn_handshake (struct mhd_TlsMultiConnData *restrict c_tls) 759 { 760 switch (c_tls->choice) 761 { 762 #ifdef MHD_SUPPORT_GNUTLS 763 case mhd_TLS_MULTI_ROUTE_GNU: 764 return mhd_tls_gnu_conn_handshake (c_tls->data.gnutls); 765 #endif 766 #ifdef MHD_SUPPORT_OPENSSL 767 case mhd_TLS_MULTI_ROUTE_OPEN: 768 return mhd_tls_open_conn_handshake (c_tls->data.openssl); 769 #endif 770 #ifdef MHD_SUPPORT_MBEDTLS 771 case mhd_TLS_MULTI_ROUTE_MBED: 772 return mhd_tls_mbed_conn_handshake (c_tls->data.mbedtls); 773 #endif 774 case mhd_TLS_MULTI_ROUTE_NONE: 775 default: 776 mhd_UNREACHABLE (); 777 break; 778 } 779 return mhd_TLS_PROCED_FAILED; 780 } 781 782 783 MHD_INTERNAL MHD_FN_MUST_CHECK_RESULT_ MHD_FN_PAR_NONNULL_ALL_ 784 enum mhd_TlsProcedureResult 785 mhd_tls_multi_conn_shutdown (struct mhd_TlsMultiConnData *restrict c_tls) 786 { 787 switch (c_tls->choice) 788 { 789 #ifdef MHD_SUPPORT_GNUTLS 790 case mhd_TLS_MULTI_ROUTE_GNU: 791 return mhd_tls_gnu_conn_shutdown (c_tls->data.gnutls); 792 #endif 793 #ifdef MHD_SUPPORT_OPENSSL 794 case mhd_TLS_MULTI_ROUTE_OPEN: 795 return mhd_tls_open_conn_shutdown (c_tls->data.openssl); 796 #endif 797 #ifdef MHD_SUPPORT_MBEDTLS 798 case mhd_TLS_MULTI_ROUTE_MBED: 799 return mhd_tls_mbed_conn_shutdown (c_tls->data.mbedtls); 800 #endif 801 case mhd_TLS_MULTI_ROUTE_NONE: 802 default: 803 mhd_UNREACHABLE (); 804 break; 805 } 806 return mhd_TLS_PROCED_FAILED; 807 } 808 809 810 /* ** Data receiving and sending ** */ 811 812 MHD_INTERNAL MHD_FN_PAR_NONNULL_ALL_ 813 MHD_FN_PAR_OUT_SIZE_ (3, 2) 814 MHD_FN_PAR_OUT_ (4) enum mhd_SocketError 815 mhd_tls_multi_conn_recv (struct mhd_TlsMultiConnData *restrict c_tls, 816 size_t buf_size, 817 char buf[MHD_FN_PAR_DYN_ARR_SIZE_ (buf_size)], 818 size_t *restrict received) 819 { 820 switch (c_tls->choice) 821 { 822 #ifdef MHD_SUPPORT_GNUTLS 823 case mhd_TLS_MULTI_ROUTE_GNU: 824 return mhd_tls_gnu_conn_recv (c_tls->data.gnutls, 825 buf_size, 826 buf, 827 received); 828 #endif 829 #ifdef MHD_SUPPORT_OPENSSL 830 case mhd_TLS_MULTI_ROUTE_OPEN: 831 return mhd_tls_open_conn_recv (c_tls->data.openssl, 832 buf_size, 833 buf, 834 received); 835 #endif 836 #ifdef MHD_SUPPORT_MBEDTLS 837 case mhd_TLS_MULTI_ROUTE_MBED: 838 return mhd_tls_mbed_conn_recv (c_tls->data.mbedtls, 839 buf_size, 840 buf, 841 received); 842 #endif 843 case mhd_TLS_MULTI_ROUTE_NONE: 844 default: 845 mhd_UNREACHABLE (); 846 break; 847 } 848 return mhd_SOCKET_ERR_INTERNAL; 849 } 850 851 852 MHD_INTERNAL MHD_FN_PAR_NONNULL_ALL_ MHD_FN_PURE_ bool 853 mhd_tls_multi_conn_has_cstm_tr (struct mhd_TlsMultiConnData *restrict c_tls) 854 { 855 (void)c_tls; /* Could be unused if all underling functions are actually macros */ 856 switch (c_tls->choice) 857 { 858 #ifdef MHD_SUPPORT_GNUTLS 859 case mhd_TLS_MULTI_ROUTE_GNU: 860 return mhd_tls_gnu_conn_has_cstm_tr (c_tls->data.gnutls); 861 #endif 862 #ifdef MHD_SUPPORT_OPENSSL 863 case mhd_TLS_MULTI_ROUTE_OPEN: 864 return mhd_tls_open_conn_has_cstm_tr (c_tls->data.openssl); 865 #endif 866 #ifdef MHD_SUPPORT_MBEDTLS 867 case mhd_TLS_MULTI_ROUTE_MBED: 868 return mhd_tls_mbed_conn_has_cstm_tr (c_tls->data.mbedtls); 869 #endif 870 case mhd_TLS_MULTI_ROUTE_NONE: 871 default: 872 mhd_UNREACHABLE (); 873 break; 874 } 875 return false; 876 } 877 878 879 MHD_INTERNAL MHD_FN_PAR_NONNULL_ALL_ bool 880 mhd_tls_multi_conn_has_data_in (struct mhd_TlsMultiConnData *restrict c_tls) 881 { 882 switch (c_tls->choice) 883 { 884 #ifdef MHD_SUPPORT_GNUTLS 885 case mhd_TLS_MULTI_ROUTE_GNU: 886 return mhd_tls_gnu_conn_has_data_in (c_tls->data.gnutls); 887 #endif 888 #ifdef MHD_SUPPORT_OPENSSL 889 case mhd_TLS_MULTI_ROUTE_OPEN: 890 return mhd_tls_open_conn_has_data_in (c_tls->data.openssl); 891 #endif 892 #ifdef MHD_SUPPORT_MBEDTLS 893 case mhd_TLS_MULTI_ROUTE_MBED: 894 return mhd_tls_mbed_conn_has_data_in (c_tls->data.mbedtls); 895 #endif 896 case mhd_TLS_MULTI_ROUTE_NONE: 897 default: 898 mhd_UNREACHABLE (); 899 break; 900 } 901 return false; 902 } 903 904 905 MHD_INTERNAL MHD_FN_PAR_NONNULL_ALL_ 906 MHD_FN_PAR_IN_SIZE_ (3, 2) 907 MHD_FN_PAR_OUT_ (5) enum mhd_SocketError 908 mhd_tls_multi_conn_send (struct mhd_TlsMultiConnData *restrict c_tls, 909 size_t buf_size, 910 const char buf[MHD_FN_PAR_DYN_ARR_SIZE_ (buf_size)], 911 bool push_data, 912 size_t *restrict sent) 913 { 914 (void)push_data; /* Could be unused if not supported by all backends */ 915 switch (c_tls->choice) 916 { 917 #ifdef MHD_SUPPORT_GNUTLS 918 case mhd_TLS_MULTI_ROUTE_GNU: 919 return mhd_tls_gnu_conn_send (c_tls->data.gnutls, 920 buf_size, 921 buf, 922 push_data, 923 sent); 924 #endif 925 #ifdef MHD_SUPPORT_OPENSSL 926 case mhd_TLS_MULTI_ROUTE_OPEN: 927 return mhd_tls_open_conn_send (c_tls->data.openssl, 928 buf_size, 929 buf, 930 push_data, 931 sent); 932 #endif 933 #ifdef MHD_SUPPORT_MBEDTLS 934 case mhd_TLS_MULTI_ROUTE_MBED: 935 return mhd_tls_mbed_conn_send (c_tls->data.mbedtls, 936 buf_size, 937 buf, 938 push_data, 939 sent); 940 #endif 941 case mhd_TLS_MULTI_ROUTE_NONE: 942 default: 943 mhd_UNREACHABLE (); 944 break; 945 } 946 return mhd_SOCKET_ERR_INTERNAL; 947 } 948 949 950 /* ** TLS connection information ** */ 951 952 MHD_INTERNAL MHD_FN_PAR_NONNULL_ALL_ 953 MHD_FN_PAR_OUT_ (2) void 954 mhd_tls_multi_conn_get_tls_sess ( 955 struct mhd_TlsMultiConnData *restrict c_tls, 956 union MHD_ConnInfoDynamicTlsSess *restrict tls_sess_out) 957 { 958 switch (c_tls->choice) 959 { 960 #ifdef MHD_SUPPORT_GNUTLS 961 case mhd_TLS_MULTI_ROUTE_GNU: 962 mhd_tls_gnu_conn_get_tls_sess (c_tls->data.gnutls, 963 tls_sess_out); 964 break; 965 #endif 966 #ifdef MHD_SUPPORT_OPENSSL 967 case mhd_TLS_MULTI_ROUTE_OPEN: 968 mhd_tls_open_conn_get_tls_sess (c_tls->data.openssl, 969 tls_sess_out); 970 break; 971 #endif 972 #ifdef MHD_SUPPORT_MBEDTLS 973 case mhd_TLS_MULTI_ROUTE_MBED: 974 mhd_tls_mbed_conn_get_tls_sess (c_tls->data.mbedtls, 975 tls_sess_out); 976 break; 977 #endif 978 case mhd_TLS_MULTI_ROUTE_NONE: 979 default: 980 mhd_UNREACHABLE (); 981 break; 982 } 983 } 984 985 986 MHD_INTERNAL MHD_FN_PAR_NONNULL_ALL_ 987 MHD_FN_PAR_OUT_ (2) bool 988 mhd_tls_multi_conn_get_tls_ver (struct mhd_TlsMultiConnData *restrict c_tls, 989 struct mhd_StctTlsVersion *restrict tls_ver_out) 990 { 991 switch (c_tls->choice) 992 { 993 #ifdef MHD_SUPPORT_GNUTLS 994 case mhd_TLS_MULTI_ROUTE_GNU: 995 return mhd_tls_gnu_conn_get_tls_ver (c_tls->data.gnutls, 996 tls_ver_out); 997 #endif 998 #ifdef MHD_SUPPORT_OPENSSL 999 case mhd_TLS_MULTI_ROUTE_OPEN: 1000 return mhd_tls_open_conn_get_tls_ver (c_tls->data.openssl, 1001 tls_ver_out); 1002 #endif 1003 #ifdef MHD_SUPPORT_MBEDTLS 1004 case mhd_TLS_MULTI_ROUTE_MBED: 1005 return mhd_tls_mbed_conn_get_tls_ver (c_tls->data.mbedtls, 1006 tls_ver_out); 1007 #endif 1008 case mhd_TLS_MULTI_ROUTE_NONE: 1009 default: 1010 mhd_UNREACHABLE (); 1011 break; 1012 } 1013 return false; 1014 } 1015 1016 1017 MHD_INTERNAL MHD_FN_PAR_NONNULL_ALL_ enum mhd_TlsAlpnProt 1018 mhd_tls_multi_conn_get_alpn_prot (struct mhd_TlsMultiConnData *restrict c_tls) 1019 { 1020 switch (c_tls->choice) 1021 { 1022 #ifdef MHD_SUPPORT_GNUTLS 1023 case mhd_TLS_MULTI_ROUTE_GNU: 1024 return mhd_tls_gnu_conn_get_alpn_prot (c_tls->data.gnutls); 1025 #endif 1026 #ifdef MHD_SUPPORT_OPENSSL 1027 case mhd_TLS_MULTI_ROUTE_OPEN: 1028 return mhd_tls_open_conn_get_alpn_prot (c_tls->data.openssl); 1029 #endif 1030 #ifdef MHD_SUPPORT_MBEDTLS 1031 case mhd_TLS_MULTI_ROUTE_MBED: 1032 return mhd_tls_mbed_conn_get_alpn_prot (c_tls->data.mbedtls); 1033 #endif 1034 case mhd_TLS_MULTI_ROUTE_NONE: 1035 default: 1036 mhd_UNREACHABLE (); 1037 break; 1038 } 1039 return mhd_TLS_ALPN_PROT_NOT_SELECTED; 1040 } 1041 1042 1043 #ifdef mhd_HAVE_TLS_ACME 1044 MHD_INTERNAL MHD_FN_PAR_NONNULL_ALL_ bool 1045 mhd_tls_multi_conn_is_acme (struct mhd_TlsMultiConnData *restrict c_tls) 1046 { 1047 switch (c_tls->choice) 1048 { 1049 # ifdef MHD_SUPPORT_GNUTLS 1050 case mhd_TLS_MULTI_ROUTE_GNU: 1051 return mhd_tls_gnu_conn_is_acme (c_tls->data.gnutls); 1052 # endif 1053 # ifdef MHD_SUPPORT_OPENSSL 1054 case mhd_TLS_MULTI_ROUTE_OPEN: 1055 return mhd_tls_open_conn_is_acme (c_tls->data.openssl); 1056 # endif 1057 # ifdef MHD_SUPPORT_MBEDTLS 1058 case mhd_TLS_MULTI_ROUTE_MBED: 1059 return mhd_tls_mbed_conn_is_acme (c_tls->data.mbedtls); 1060 # endif 1061 case mhd_TLS_MULTI_ROUTE_NONE: 1062 default: 1063 mhd_UNREACHABLE (); 1064 break; 1065 } 1066 return false; 1067 } 1068 1069 1070 #endif /* mhd_HAVE_TLS_ACME */