tls_multi_funcs.c (31001B)
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_NONNULL_IF_NONZERO_ (8, 7) 555 MHD_FN_PAR_OUT_ (2) 556 MHD_FN_PAR_IN_SIZE_ (4, 3) MHD_FN_PAR_IN_SIZE_ (6, 5) 557 MHD_FN_PAR_IN_SIZE_ (8, 7) 558 MHD_FN_PAR_CSTR_ (4) MHD_FN_PAR_CSTR_ (6) MHD_FN_PAR_CSTR_ (8) 559 enum mhd_TlsCredCreateResult 560 mhd_tls_multi_cred_create (struct mhd_TlsMultiDaemonData *restrict d_tls, 561 union mhd_TlsCredDataPtr *restrict pp_cred, 562 size_t cert_len, 563 const char *restrict cert, 564 size_t key_len, 565 const char *restrict key, 566 size_t pass_len, 567 const char *restrict pass) 568 { 569 switch (d_tls->choice) 570 { 571 # ifdef MHD_SUPPORT_GNUTLS 572 case mhd_TLS_MULTI_ROUTE_GNU: 573 return mhd_tls_gnu_cred_create (d_tls->data.gnutls, 574 pp_cred, 575 cert_len, 576 cert, 577 key_len, 578 key, 579 pass_len, 580 pass); 581 # endif 582 # ifdef MHD_SUPPORT_OPENSSL 583 case mhd_TLS_MULTI_ROUTE_OPEN: 584 return mhd_tls_open_cred_create (d_tls->data.openssl, 585 pp_cred, 586 cert_len, 587 cert, 588 key_len, 589 key, 590 pass_len, 591 pass); 592 # endif 593 # ifdef MHD_SUPPORT_MBEDTLS 594 case mhd_TLS_MULTI_ROUTE_MBED: 595 return mhd_tls_mbed_cred_create (d_tls->data.mbedtls, 596 pp_cred, 597 cert_len, 598 cert, 599 key_len, 600 key, 601 pass_len, 602 pass); 603 # endif 604 case mhd_TLS_MULTI_ROUTE_NONE: 605 default: 606 mhd_UNREACHABLE (); 607 } 608 609 return mhd_TLS_CRED_CREATE_UNSUPPORTED; 610 } 611 612 613 MHD_INTERNAL MHD_FN_PAR_NONNULL_ALL_ void 614 mhd_tls_multi_cred_destroy (struct mhd_TlsMultiDaemonData *restrict d_tls, 615 union mhd_TlsCredDataPtr cred) 616 { 617 switch (d_tls->choice) 618 { 619 # ifdef MHD_SUPPORT_GNUTLS 620 case mhd_TLS_MULTI_ROUTE_GNU: 621 mhd_tls_gnu_cred_destroy (d_tls->data.gnutls, 622 cred); 623 break; 624 # endif 625 # ifdef MHD_SUPPORT_OPENSSL 626 case mhd_TLS_MULTI_ROUTE_OPEN: 627 mhd_tls_open_cred_destroy (d_tls->data.openssl, 628 cred); 629 break; 630 # endif 631 # ifdef MHD_SUPPORT_MBEDTLS 632 case mhd_TLS_MULTI_ROUTE_MBED: 633 mhd_tls_mbed_cred_destroy (d_tls->data.mbedtls, 634 cred); 635 break; 636 # endif 637 case mhd_TLS_MULTI_ROUTE_NONE: 638 default: 639 mhd_UNREACHABLE (); 640 } 641 } 642 643 644 #endif /* mhd_HAVE_TLS_ACME */ 645 646 /* ** Connection initialisation / de-initialisation ** */ 647 648 MHD_INTERNAL size_t 649 mhd_tls_multi_conn_get_tls_size (struct mhd_TlsMultiDaemonData *restrict d_tls) 650 { 651 size_t data_size; 652 653 data_size = sizeof(struct mhd_TlsMultiConnData); 654 switch (d_tls->choice) 655 { 656 #ifdef MHD_SUPPORT_GNUTLS 657 case mhd_TLS_MULTI_ROUTE_GNU: 658 data_size += mhd_tls_gnu_conn_get_tls_size (d_tls->data.gnutls); 659 break; 660 #endif 661 #ifdef MHD_SUPPORT_OPENSSL 662 case mhd_TLS_MULTI_ROUTE_OPEN: 663 data_size += mhd_tls_open_conn_get_tls_size (d_tls->data.openssl); 664 break; 665 #endif 666 #ifdef MHD_SUPPORT_MBEDTLS 667 case mhd_TLS_MULTI_ROUTE_MBED: 668 data_size += mhd_tls_mbed_conn_get_tls_size (d_tls->data.mbedtls); 669 break; 670 #endif 671 case mhd_TLS_MULTI_ROUTE_NONE: 672 default: 673 mhd_UNREACHABLE (); 674 } 675 676 return data_size; 677 } 678 679 680 MHD_INTERNAL MHD_FN_MUST_CHECK_RESULT_ MHD_FN_PAR_NONNULL_ALL_ 681 MHD_FN_PAR_OUT_ (3) bool 682 mhd_tls_multi_conn_init (const struct mhd_TlsMultiDaemonData *restrict d_tls, 683 struct mhd_ConnSocket *sk, 684 struct mhd_TlsMultiConnData *restrict c_tls) 685 { 686 c_tls->choice = d_tls->choice; 687 switch (c_tls->choice) 688 { 689 #ifdef MHD_SUPPORT_GNUTLS 690 case mhd_TLS_MULTI_ROUTE_GNU: 691 /* Assume the same alignment requirements for both structures */ 692 c_tls->data.gnutls = (struct mhd_TlsGnuConnData *)(c_tls + 1); 693 return mhd_tls_gnu_conn_init (d_tls->data.gnutls, 694 sk, 695 c_tls->data.gnutls); 696 #endif 697 #ifdef MHD_SUPPORT_OPENSSL 698 case mhd_TLS_MULTI_ROUTE_OPEN: 699 /* Assume the same alignment requirements for both structures */ 700 c_tls->data.openssl = (struct mhd_TlsOpenConnData *)(c_tls + 1); 701 return mhd_tls_open_conn_init (d_tls->data.openssl, 702 sk, 703 c_tls->data.openssl); 704 #endif 705 #ifdef MHD_SUPPORT_MBEDTLS 706 case mhd_TLS_MULTI_ROUTE_MBED: 707 /* Assume the same alignment requirements for both structures */ 708 c_tls->data.mbedtls = (struct mhd_TlsMbedConnData *)(c_tls + 1); 709 return mhd_tls_mbed_conn_init (d_tls->data.mbedtls, 710 sk, 711 c_tls->data.mbedtls); 712 #endif 713 case mhd_TLS_MULTI_ROUTE_NONE: 714 default: 715 mhd_UNREACHABLE (); 716 break; 717 } 718 719 return false; 720 } 721 722 723 /** 724 * De-initialise connection TLS settings. 725 * The provided pointer is not freed/deallocated. 726 * @param c_tls the initialised connection TLS settings 727 */ 728 MHD_INTERNAL MHD_FN_PAR_NONNULL_ALL_ void 729 mhd_tls_multi_conn_deinit (struct mhd_TlsMultiConnData *restrict c_tls) 730 { 731 switch (c_tls->choice) 732 { 733 #ifdef MHD_SUPPORT_GNUTLS 734 case mhd_TLS_MULTI_ROUTE_GNU: 735 mhd_tls_gnu_conn_deinit (c_tls->data.gnutls); 736 break; 737 #endif 738 #ifdef MHD_SUPPORT_OPENSSL 739 case mhd_TLS_MULTI_ROUTE_OPEN: 740 mhd_tls_open_conn_deinit (c_tls->data.openssl); 741 break; 742 #endif 743 #ifdef MHD_SUPPORT_MBEDTLS 744 case mhd_TLS_MULTI_ROUTE_MBED: 745 mhd_tls_mbed_conn_deinit (c_tls->data.mbedtls); 746 break; 747 #endif 748 case mhd_TLS_MULTI_ROUTE_NONE: 749 default: 750 mhd_UNREACHABLE (); 751 } 752 } 753 754 755 /* ** TLS connection establishing ** */ 756 757 MHD_INTERNAL MHD_FN_MUST_CHECK_RESULT_ MHD_FN_PAR_NONNULL_ALL_ 758 enum mhd_TlsProcedureResult 759 mhd_tls_multi_conn_handshake (struct mhd_TlsMultiConnData *restrict c_tls) 760 { 761 switch (c_tls->choice) 762 { 763 #ifdef MHD_SUPPORT_GNUTLS 764 case mhd_TLS_MULTI_ROUTE_GNU: 765 return mhd_tls_gnu_conn_handshake (c_tls->data.gnutls); 766 #endif 767 #ifdef MHD_SUPPORT_OPENSSL 768 case mhd_TLS_MULTI_ROUTE_OPEN: 769 return mhd_tls_open_conn_handshake (c_tls->data.openssl); 770 #endif 771 #ifdef MHD_SUPPORT_MBEDTLS 772 case mhd_TLS_MULTI_ROUTE_MBED: 773 return mhd_tls_mbed_conn_handshake (c_tls->data.mbedtls); 774 #endif 775 case mhd_TLS_MULTI_ROUTE_NONE: 776 default: 777 mhd_UNREACHABLE (); 778 break; 779 } 780 return mhd_TLS_PROCED_FAILED; 781 } 782 783 784 MHD_INTERNAL MHD_FN_MUST_CHECK_RESULT_ MHD_FN_PAR_NONNULL_ALL_ 785 enum mhd_TlsProcedureResult 786 mhd_tls_multi_conn_shutdown (struct mhd_TlsMultiConnData *restrict c_tls) 787 { 788 switch (c_tls->choice) 789 { 790 #ifdef MHD_SUPPORT_GNUTLS 791 case mhd_TLS_MULTI_ROUTE_GNU: 792 return mhd_tls_gnu_conn_shutdown (c_tls->data.gnutls); 793 #endif 794 #ifdef MHD_SUPPORT_OPENSSL 795 case mhd_TLS_MULTI_ROUTE_OPEN: 796 return mhd_tls_open_conn_shutdown (c_tls->data.openssl); 797 #endif 798 #ifdef MHD_SUPPORT_MBEDTLS 799 case mhd_TLS_MULTI_ROUTE_MBED: 800 return mhd_tls_mbed_conn_shutdown (c_tls->data.mbedtls); 801 #endif 802 case mhd_TLS_MULTI_ROUTE_NONE: 803 default: 804 mhd_UNREACHABLE (); 805 break; 806 } 807 return mhd_TLS_PROCED_FAILED; 808 } 809 810 811 /* ** Data receiving and sending ** */ 812 813 MHD_INTERNAL MHD_FN_PAR_NONNULL_ALL_ 814 MHD_FN_PAR_OUT_SIZE_ (3, 2) 815 MHD_FN_PAR_OUT_ (4) enum mhd_SocketError 816 mhd_tls_multi_conn_recv (struct mhd_TlsMultiConnData *restrict c_tls, 817 size_t buf_size, 818 char buf[MHD_FN_PAR_DYN_ARR_SIZE_ (buf_size)], 819 size_t *restrict received) 820 { 821 switch (c_tls->choice) 822 { 823 #ifdef MHD_SUPPORT_GNUTLS 824 case mhd_TLS_MULTI_ROUTE_GNU: 825 return mhd_tls_gnu_conn_recv (c_tls->data.gnutls, 826 buf_size, 827 buf, 828 received); 829 #endif 830 #ifdef MHD_SUPPORT_OPENSSL 831 case mhd_TLS_MULTI_ROUTE_OPEN: 832 return mhd_tls_open_conn_recv (c_tls->data.openssl, 833 buf_size, 834 buf, 835 received); 836 #endif 837 #ifdef MHD_SUPPORT_MBEDTLS 838 case mhd_TLS_MULTI_ROUTE_MBED: 839 return mhd_tls_mbed_conn_recv (c_tls->data.mbedtls, 840 buf_size, 841 buf, 842 received); 843 #endif 844 case mhd_TLS_MULTI_ROUTE_NONE: 845 default: 846 mhd_UNREACHABLE (); 847 break; 848 } 849 return mhd_SOCKET_ERR_INTERNAL; 850 } 851 852 853 MHD_INTERNAL MHD_FN_PAR_NONNULL_ALL_ MHD_FN_PURE_ bool 854 mhd_tls_multi_conn_has_cstm_tr (struct mhd_TlsMultiConnData *restrict c_tls) 855 { 856 (void)c_tls; /* Could be unused if all underling functions are actually macros */ 857 switch (c_tls->choice) 858 { 859 #ifdef MHD_SUPPORT_GNUTLS 860 case mhd_TLS_MULTI_ROUTE_GNU: 861 return mhd_tls_gnu_conn_has_cstm_tr (c_tls->data.gnutls); 862 #endif 863 #ifdef MHD_SUPPORT_OPENSSL 864 case mhd_TLS_MULTI_ROUTE_OPEN: 865 return mhd_tls_open_conn_has_cstm_tr (c_tls->data.openssl); 866 #endif 867 #ifdef MHD_SUPPORT_MBEDTLS 868 case mhd_TLS_MULTI_ROUTE_MBED: 869 return mhd_tls_mbed_conn_has_cstm_tr (c_tls->data.mbedtls); 870 #endif 871 case mhd_TLS_MULTI_ROUTE_NONE: 872 default: 873 mhd_UNREACHABLE (); 874 break; 875 } 876 return false; 877 } 878 879 880 MHD_INTERNAL MHD_FN_PAR_NONNULL_ALL_ bool 881 mhd_tls_multi_conn_has_data_in (struct mhd_TlsMultiConnData *restrict c_tls) 882 { 883 switch (c_tls->choice) 884 { 885 #ifdef MHD_SUPPORT_GNUTLS 886 case mhd_TLS_MULTI_ROUTE_GNU: 887 return mhd_tls_gnu_conn_has_data_in (c_tls->data.gnutls); 888 #endif 889 #ifdef MHD_SUPPORT_OPENSSL 890 case mhd_TLS_MULTI_ROUTE_OPEN: 891 return mhd_tls_open_conn_has_data_in (c_tls->data.openssl); 892 #endif 893 #ifdef MHD_SUPPORT_MBEDTLS 894 case mhd_TLS_MULTI_ROUTE_MBED: 895 return mhd_tls_mbed_conn_has_data_in (c_tls->data.mbedtls); 896 #endif 897 case mhd_TLS_MULTI_ROUTE_NONE: 898 default: 899 mhd_UNREACHABLE (); 900 break; 901 } 902 return false; 903 } 904 905 906 MHD_INTERNAL MHD_FN_PAR_NONNULL_ALL_ 907 MHD_FN_PAR_IN_SIZE_ (3, 2) 908 MHD_FN_PAR_OUT_ (5) enum mhd_SocketError 909 mhd_tls_multi_conn_send (struct mhd_TlsMultiConnData *restrict c_tls, 910 size_t buf_size, 911 const char buf[MHD_FN_PAR_DYN_ARR_SIZE_ (buf_size)], 912 bool push_data, 913 size_t *restrict sent) 914 { 915 (void)push_data; /* Could be unused if not supported by all backends */ 916 switch (c_tls->choice) 917 { 918 #ifdef MHD_SUPPORT_GNUTLS 919 case mhd_TLS_MULTI_ROUTE_GNU: 920 return mhd_tls_gnu_conn_send (c_tls->data.gnutls, 921 buf_size, 922 buf, 923 push_data, 924 sent); 925 #endif 926 #ifdef MHD_SUPPORT_OPENSSL 927 case mhd_TLS_MULTI_ROUTE_OPEN: 928 return mhd_tls_open_conn_send (c_tls->data.openssl, 929 buf_size, 930 buf, 931 push_data, 932 sent); 933 #endif 934 #ifdef MHD_SUPPORT_MBEDTLS 935 case mhd_TLS_MULTI_ROUTE_MBED: 936 return mhd_tls_mbed_conn_send (c_tls->data.mbedtls, 937 buf_size, 938 buf, 939 push_data, 940 sent); 941 #endif 942 case mhd_TLS_MULTI_ROUTE_NONE: 943 default: 944 mhd_UNREACHABLE (); 945 break; 946 } 947 return mhd_SOCKET_ERR_INTERNAL; 948 } 949 950 951 /* ** TLS connection information ** */ 952 953 MHD_INTERNAL MHD_FN_PAR_NONNULL_ALL_ 954 MHD_FN_PAR_OUT_ (2) void 955 mhd_tls_multi_conn_get_tls_sess ( 956 struct mhd_TlsMultiConnData *restrict c_tls, 957 union MHD_ConnInfoDynamicTlsSess *restrict tls_sess_out) 958 { 959 switch (c_tls->choice) 960 { 961 #ifdef MHD_SUPPORT_GNUTLS 962 case mhd_TLS_MULTI_ROUTE_GNU: 963 mhd_tls_gnu_conn_get_tls_sess (c_tls->data.gnutls, 964 tls_sess_out); 965 break; 966 #endif 967 #ifdef MHD_SUPPORT_OPENSSL 968 case mhd_TLS_MULTI_ROUTE_OPEN: 969 mhd_tls_open_conn_get_tls_sess (c_tls->data.openssl, 970 tls_sess_out); 971 break; 972 #endif 973 #ifdef MHD_SUPPORT_MBEDTLS 974 case mhd_TLS_MULTI_ROUTE_MBED: 975 mhd_tls_mbed_conn_get_tls_sess (c_tls->data.mbedtls, 976 tls_sess_out); 977 break; 978 #endif 979 case mhd_TLS_MULTI_ROUTE_NONE: 980 default: 981 mhd_UNREACHABLE (); 982 break; 983 } 984 } 985 986 987 MHD_INTERNAL MHD_FN_PAR_NONNULL_ALL_ 988 MHD_FN_PAR_OUT_ (2) bool 989 mhd_tls_multi_conn_get_tls_ver (struct mhd_TlsMultiConnData *restrict c_tls, 990 struct mhd_StctTlsVersion *restrict tls_ver_out) 991 { 992 switch (c_tls->choice) 993 { 994 #ifdef MHD_SUPPORT_GNUTLS 995 case mhd_TLS_MULTI_ROUTE_GNU: 996 return mhd_tls_gnu_conn_get_tls_ver (c_tls->data.gnutls, 997 tls_ver_out); 998 #endif 999 #ifdef MHD_SUPPORT_OPENSSL 1000 case mhd_TLS_MULTI_ROUTE_OPEN: 1001 return mhd_tls_open_conn_get_tls_ver (c_tls->data.openssl, 1002 tls_ver_out); 1003 #endif 1004 #ifdef MHD_SUPPORT_MBEDTLS 1005 case mhd_TLS_MULTI_ROUTE_MBED: 1006 return mhd_tls_mbed_conn_get_tls_ver (c_tls->data.mbedtls, 1007 tls_ver_out); 1008 #endif 1009 case mhd_TLS_MULTI_ROUTE_NONE: 1010 default: 1011 mhd_UNREACHABLE (); 1012 break; 1013 } 1014 return false; 1015 } 1016 1017 1018 MHD_INTERNAL MHD_FN_PAR_NONNULL_ALL_ enum mhd_TlsAlpnProt 1019 mhd_tls_multi_conn_get_alpn_prot (struct mhd_TlsMultiConnData *restrict c_tls) 1020 { 1021 switch (c_tls->choice) 1022 { 1023 #ifdef MHD_SUPPORT_GNUTLS 1024 case mhd_TLS_MULTI_ROUTE_GNU: 1025 return mhd_tls_gnu_conn_get_alpn_prot (c_tls->data.gnutls); 1026 #endif 1027 #ifdef MHD_SUPPORT_OPENSSL 1028 case mhd_TLS_MULTI_ROUTE_OPEN: 1029 return mhd_tls_open_conn_get_alpn_prot (c_tls->data.openssl); 1030 #endif 1031 #ifdef MHD_SUPPORT_MBEDTLS 1032 case mhd_TLS_MULTI_ROUTE_MBED: 1033 return mhd_tls_mbed_conn_get_alpn_prot (c_tls->data.mbedtls); 1034 #endif 1035 case mhd_TLS_MULTI_ROUTE_NONE: 1036 default: 1037 mhd_UNREACHABLE (); 1038 break; 1039 } 1040 return mhd_TLS_ALPN_PROT_NOT_SELECTED; 1041 } 1042 1043 1044 #ifdef mhd_HAVE_TLS_ACME 1045 MHD_INTERNAL MHD_FN_PAR_NONNULL_ALL_ bool 1046 mhd_tls_multi_conn_is_acme (struct mhd_TlsMultiConnData *restrict c_tls) 1047 { 1048 switch (c_tls->choice) 1049 { 1050 # ifdef MHD_SUPPORT_GNUTLS 1051 case mhd_TLS_MULTI_ROUTE_GNU: 1052 return mhd_tls_gnu_conn_is_acme (c_tls->data.gnutls); 1053 # endif 1054 # ifdef MHD_SUPPORT_OPENSSL 1055 case mhd_TLS_MULTI_ROUTE_OPEN: 1056 return mhd_tls_open_conn_is_acme (c_tls->data.openssl); 1057 # endif 1058 # ifdef MHD_SUPPORT_MBEDTLS 1059 case mhd_TLS_MULTI_ROUTE_MBED: 1060 return mhd_tls_mbed_conn_is_acme (c_tls->data.mbedtls); 1061 # endif 1062 case mhd_TLS_MULTI_ROUTE_NONE: 1063 default: 1064 mhd_UNREACHABLE (); 1065 break; 1066 } 1067 return false; 1068 } 1069 1070 1071 #endif /* mhd_HAVE_TLS_ACME */