tls_multi_funcs.c (24806B)
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 return true; 159 #endif 160 #ifdef MHD_SUPPORT_OPENSSL 161 if (mhd_tls_open_is_edge_trigg_supported (s) 162 && mhd_tls_open_is_inited_fine ()) 163 return true; 164 #endif 165 #ifdef MHD_SUPPORT_MBEDTLS 166 if (mhd_tls_mbed_is_edge_trigg_supported (s) 167 && mhd_tls_mbed_is_inited_fine ()) 168 return true; 169 #endif 170 return false; 171 case MHD_TLS_BACKEND_GNUTLS: 172 #ifdef MHD_SUPPORT_GNUTLS 173 /* Ignore "backend inited" status here, 174 it will be checked on daemon TLS init */ 175 return mhd_tls_gnu_is_edge_trigg_supported (s); 176 #endif 177 break; 178 case MHD_TLS_BACKEND_OPENSSL: 179 #ifdef MHD_SUPPORT_OPENSSL 180 /* Ignore "backend inited" status here, 181 it will be checked on daemon TLS init */ 182 return mhd_tls_open_is_edge_trigg_supported (s); 183 #endif 184 break; 185 case MHD_TLS_BACKEND_MBEDTLS: 186 #ifdef MHD_SUPPORT_MBEDTLS 187 /* Ignore "backend inited" status here, 188 it will be checked on daemon TLS init */ 189 return mhd_tls_mbed_is_edge_trigg_supported (s); 190 #endif 191 break; 192 default: 193 mhd_UNREACHABLE (); 194 break; 195 } 196 return false; 197 } 198 199 200 /** 201 * Initialise selected TLS backend for the daemon 202 * @param route the selected TLS backend 203 * @param d the daemon handle 204 * @param s the daemon settings 205 * @param d_tls the daemon's TLS settings, backend-specific data is allocated 206 * and initialised 207 * @return #MHD_SC_OK on success (the backend-specific data is allocated), 208 * error code otherwise 209 */ 210 static MHD_FN_MUST_CHECK_RESULT_ MHD_FN_PAR_NONNULL_ALL_ 211 MHD_FN_PAR_OUT_ (5) mhd_StatusCodeInt 212 tls_daemon_init_try (enum mhd_TlsMultiRoute route, 213 struct MHD_Daemon *restrict d, 214 bool sk_edge_trigg, 215 struct DaemonOptions *restrict s, 216 struct mhd_TlsMultiDaemonData *restrict d_tls) 217 { 218 mhd_StatusCodeInt res; 219 220 #ifndef MHD_SUPPORT_OPENSSL 221 (void) sk_edge_trigg; /* Unused, mute compiler warning */ 222 #endif /* ! MHD_SUPPORT_OPENSSL */ 223 224 switch (route) 225 { 226 #ifdef MHD_SUPPORT_GNUTLS 227 case mhd_TLS_MULTI_ROUTE_GNU: 228 if (! mhd_tls_gnu_is_inited_fine ()) 229 return MHD_SC_TLS_BACKEND_UNAVAILABLE; 230 res = mhd_tls_gnu_daemon_init (d, 231 sk_edge_trigg, 232 s, 233 &(d_tls->data.gnutls)); 234 if (MHD_SC_OK == res) 235 { 236 mhd_M_DEBUG_PRINT ("GnuTLS backend initialised successfully " \ 237 "for the daemon"); 238 d_tls->choice = route; 239 return MHD_SC_OK; 240 } 241 mhd_M_DEBUG_PRINT1 ("Failed to initialise GnuTLS backend for " \ 242 "the daemon, error code: %u", (unsigned) res); 243 return res; 244 #endif 245 #ifdef MHD_SUPPORT_OPENSSL 246 case mhd_TLS_MULTI_ROUTE_OPEN: 247 if (! mhd_tls_open_is_inited_fine ()) 248 return MHD_SC_TLS_BACKEND_UNAVAILABLE; 249 res = mhd_tls_open_daemon_init (d, 250 sk_edge_trigg, 251 s, 252 &(d_tls->data.openssl)); 253 if (MHD_SC_OK == res) 254 { 255 mhd_M_DEBUG_PRINT ("OpenSSL backend initialised successfully " \ 256 "for the daemon"); 257 d_tls->choice = route; 258 return MHD_SC_OK; 259 } 260 mhd_M_DEBUG_PRINT1 ("Failed to initialise OpenSSL backend for " \ 261 "the daemon, error code: %u", (unsigned) res); 262 return res; 263 #endif 264 #ifdef MHD_SUPPORT_MBEDTLS 265 case mhd_TLS_MULTI_ROUTE_MBED: 266 if (! mhd_tls_mbed_is_inited_fine ()) 267 return MHD_SC_TLS_BACKEND_UNAVAILABLE; 268 res = mhd_tls_mbed_daemon_init (d, 269 sk_edge_trigg, 270 s, 271 &(d_tls->data.mbedtls)); 272 if (MHD_SC_OK == res) 273 { 274 mhd_M_DEBUG_PRINT ("MbedTLS backend initialised successfully " \ 275 "for the daemon"); 276 d_tls->choice = route; 277 return MHD_SC_OK; 278 } 279 mhd_M_DEBUG_PRINT1 ("Failed to initialise MbedTLS backend for " \ 280 "the daemon, error code: %u", (unsigned) res); 281 return res; 282 #endif 283 case mhd_TLS_MULTI_ROUTE_NONE: 284 default: 285 break; 286 } 287 mhd_assert (0 && "Impossible value"); 288 mhd_UNREACHABLE (); 289 return MHD_SC_INTERNAL_ERROR; 290 } 291 292 293 MHD_INTERNAL MHD_FN_MUST_CHECK_RESULT_ MHD_FN_PAR_NONNULL_ALL_ 294 MHD_FN_PAR_OUT_ (4) mhd_StatusCodeInt 295 mhd_tls_multi_daemon_init (struct MHD_Daemon *restrict d, 296 bool sk_edge_trigg, 297 struct DaemonOptions *restrict s, 298 struct mhd_TlsMultiDaemonData **restrict p_d_tls) 299 { 300 mhd_StatusCodeInt res; 301 struct mhd_TlsMultiDaemonData *restrict d_tls; 302 d_tls = (struct mhd_TlsMultiDaemonData *) 303 mhd_calloc (1, 304 sizeof (struct mhd_TlsMultiDaemonData)); 305 if (NULL == d_tls) 306 return MHD_SC_DAEMON_MEM_ALLOC_FAILURE; 307 308 res = MHD_SC_INTERNAL_ERROR; /* Mute compiler warning, the value should not be used */ 309 switch (s->tls) 310 { 311 case MHD_TLS_BACKEND_ANY: 312 if (1) 313 { 314 size_t i; 315 enum mhd_TlsMultiRoute backends[] = { 316 #ifdef MHD_SUPPORT_GNUTLS 317 mhd_TLS_MULTI_ROUTE_GNU, 318 #endif 319 #ifdef MHD_SUPPORT_OPENSSL 320 mhd_TLS_MULTI_ROUTE_OPEN, 321 #endif 322 #ifdef MHD_SUPPORT_MBEDTLS 323 mhd_TLS_MULTI_ROUTE_MBED, 324 #endif 325 mhd_TLS_MULTI_ROUTE_NONE /* Not used */ 326 }; 327 /* Try backends one-by-one */ 328 for (i = 0; i < mhd_ARR_NUM_ELEMS (backends) - 1; ++i) 329 { 330 res = tls_daemon_init_try (backends[i], 331 d, 332 sk_edge_trigg, 333 s, 334 d_tls); 335 if (MHD_SC_OK == res) 336 break; 337 } 338 } 339 break; 340 #ifdef MHD_SUPPORT_GNUTLS 341 case MHD_TLS_BACKEND_GNUTLS: 342 mhd_assert (mhd_tls_gnu_is_inited_fine ()); /* Must be checked earlier */ 343 res = tls_daemon_init_try (mhd_TLS_MULTI_ROUTE_GNU, 344 d, 345 sk_edge_trigg, 346 s, 347 d_tls); 348 break; 349 #endif /* MHD_SUPPORT_GNUTLS */ 350 #ifdef MHD_SUPPORT_OPENSSL 351 case MHD_TLS_BACKEND_OPENSSL: 352 mhd_assert (mhd_tls_open_is_inited_fine ()); /* Must be checked earlier */ 353 res = tls_daemon_init_try (mhd_TLS_MULTI_ROUTE_OPEN, 354 d, 355 sk_edge_trigg, 356 s, 357 d_tls); 358 #endif /* MHD_SUPPORT_OPENSSL */ 359 break; 360 #ifdef MHD_SUPPORT_MBEDTLS 361 case MHD_TLS_BACKEND_MBEDTLS: 362 mhd_assert (mhd_tls_mbed_is_inited_fine ()); /* Must be checked earlier */ 363 res = tls_daemon_init_try (mhd_TLS_MULTI_ROUTE_MBED, 364 d, 365 sk_edge_trigg, 366 s, 367 d_tls); 368 #endif /* MHD_SUPPORT_MBEDTLS */ 369 break; 370 371 #ifndef MHD_SUPPORT_GNUTLS 372 case MHD_TLS_BACKEND_GNUTLS: 373 #endif /* ! MHD_SUPPORT_GNUTLS */ 374 #ifndef MHD_SUPPORT_OPENSSL 375 case MHD_TLS_BACKEND_OPENSSL: 376 #endif /* ! MHD_SUPPORT_OPENSSL */ 377 #ifndef MHD_SUPPORT_MBEDTLS 378 case MHD_TLS_BACKEND_MBEDTLS: 379 #endif /* ! MHD_SUPPORT_MBEDTLS */ 380 case MHD_TLS_BACKEND_NONE: 381 default: 382 mhd_UNREACHABLE (); 383 res = MHD_SC_TLS_BACKEND_UNSUPPORTED; 384 break; 385 } 386 mhd_assert (NULL != d_tls); 387 if (MHD_SC_OK == res) 388 { 389 *p_d_tls = d_tls; 390 return MHD_SC_OK; 391 } 392 free (d_tls); 393 return res; 394 } 395 396 397 MHD_INTERNAL MHD_FN_PAR_NONNULL_ALL_ 398 MHD_FN_PAR_INOUT_ (1) void 399 mhd_tls_multi_daemon_deinit (struct mhd_TlsMultiDaemonData *restrict d_tls) 400 { 401 switch (d_tls->choice) 402 { 403 #ifdef MHD_SUPPORT_GNUTLS 404 case mhd_TLS_MULTI_ROUTE_GNU: 405 mhd_tls_gnu_daemon_deinit (d_tls->data.gnutls); 406 break; 407 #endif 408 #ifdef MHD_SUPPORT_OPENSSL 409 case mhd_TLS_MULTI_ROUTE_OPEN: 410 mhd_tls_open_daemon_deinit (d_tls->data.openssl); 411 break; 412 #endif 413 #ifdef MHD_SUPPORT_MBEDTLS 414 case mhd_TLS_MULTI_ROUTE_MBED: 415 mhd_tls_mbed_daemon_deinit (d_tls->data.mbedtls); 416 break; 417 #endif 418 case mhd_TLS_MULTI_ROUTE_NONE: 419 default: 420 mhd_UNREACHABLE (); 421 break; 422 } 423 free (d_tls); 424 } 425 426 427 #ifdef mhd_HAVE_TLS_THREAD_CLEANUP 428 /** 429 * Perform clean-up of TLS resources before thread closing. 430 * Must be called before thread is closed, after any use of TLS functions 431 * in the thread, but before de-initialisation of daemon's TLS data. 432 * @param d_tls the pointer to the daemon's TLS settings 433 */ 434 MHD_INTERNAL MHD_FN_PAR_NONNULL_ALL_ 435 MHD_FN_PAR_INOUT_ (1) void 436 mhd_tls_multi_thread_cleanup (struct mhd_TlsMultiDaemonData *restrict d_tls) 437 { 438 switch (d_tls->choice) 439 { 440 #ifdef MHD_SUPPORT_GNUTLS 441 case mhd_TLS_MULTI_ROUTE_GNU: 442 mhd_tls_gnu_thread_cleanup (d_tls->data.gnutls); 443 break; 444 #endif 445 #ifdef MHD_SUPPORT_OPENSSL 446 case mhd_TLS_MULTI_ROUTE_OPEN: 447 mhd_tls_open_thread_cleanup (d_tls->data.openssl); 448 break; 449 #endif 450 #ifdef MHD_SUPPORT_MBEDTLS 451 case mhd_TLS_MULTI_ROUTE_MBED: 452 mhd_tls_mbed_thread_cleanup (d_tls->data.mbedtls); 453 break; 454 #endif 455 case mhd_TLS_MULTI_ROUTE_NONE: 456 default: 457 mhd_UNREACHABLE (); 458 break; 459 } 460 } 461 462 463 #endif /* mhd_HAVE_TLS_THREAD_CLEANUP */ 464 465 /* ** Connection initialisation / de-initialisation ** */ 466 467 MHD_INTERNAL size_t 468 mhd_tls_multi_conn_get_tls_size (struct mhd_TlsMultiDaemonData *restrict d_tls) 469 { 470 size_t data_size; 471 472 data_size = sizeof(struct mhd_TlsMultiConnData); 473 switch (d_tls->choice) 474 { 475 #ifdef MHD_SUPPORT_GNUTLS 476 case mhd_TLS_MULTI_ROUTE_GNU: 477 data_size += mhd_tls_gnu_conn_get_tls_size (d_tls->data.gnutls); 478 break; 479 #endif 480 #ifdef MHD_SUPPORT_OPENSSL 481 case mhd_TLS_MULTI_ROUTE_OPEN: 482 data_size += mhd_tls_open_conn_get_tls_size (d_tls->data.openssl); 483 break; 484 #endif 485 #ifdef MHD_SUPPORT_MBEDTLS 486 case mhd_TLS_MULTI_ROUTE_MBED: 487 data_size += mhd_tls_mbed_conn_get_tls_size (d_tls->data.mbedtls); 488 break; 489 #endif 490 case mhd_TLS_MULTI_ROUTE_NONE: 491 default: 492 mhd_UNREACHABLE (); 493 } 494 495 return data_size; 496 } 497 498 499 MHD_INTERNAL MHD_FN_MUST_CHECK_RESULT_ MHD_FN_PAR_NONNULL_ALL_ 500 MHD_FN_PAR_OUT_ (3) bool 501 mhd_tls_multi_conn_init (const struct mhd_TlsMultiDaemonData *restrict d_tls, 502 struct mhd_ConnSocket *sk, 503 struct mhd_TlsMultiConnData *restrict c_tls) 504 { 505 c_tls->choice = d_tls->choice; 506 switch (c_tls->choice) 507 { 508 #ifdef MHD_SUPPORT_GNUTLS 509 case mhd_TLS_MULTI_ROUTE_GNU: 510 /* Assume the same alignment requirements for both structures */ 511 c_tls->data.gnutls = (struct mhd_TlsGnuConnData *) (c_tls + 1); 512 return mhd_tls_gnu_conn_init (d_tls->data.gnutls, 513 sk, 514 c_tls->data.gnutls); 515 #endif 516 #ifdef MHD_SUPPORT_OPENSSL 517 case mhd_TLS_MULTI_ROUTE_OPEN: 518 /* Assume the same alignment requirements for both structures */ 519 c_tls->data.openssl = (struct mhd_TlsOpenConnData *) (c_tls + 1); 520 return mhd_tls_open_conn_init (d_tls->data.openssl, 521 sk, 522 c_tls->data.openssl); 523 #endif 524 #ifdef MHD_SUPPORT_MBEDTLS 525 case mhd_TLS_MULTI_ROUTE_MBED: 526 /* Assume the same alignment requirements for both structures */ 527 c_tls->data.mbedtls = (struct mhd_TlsMbedConnData *) (c_tls + 1); 528 return mhd_tls_mbed_conn_init (d_tls->data.mbedtls, 529 sk, 530 c_tls->data.mbedtls); 531 #endif 532 case mhd_TLS_MULTI_ROUTE_NONE: 533 default: 534 mhd_UNREACHABLE (); 535 break; 536 } 537 538 return false; 539 } 540 541 542 /** 543 * De-initialise connection TLS settings. 544 * The provided pointer is not freed/deallocated. 545 * @param c_tls the initialised connection TLS settings 546 */ 547 MHD_INTERNAL MHD_FN_PAR_NONNULL_ALL_ void 548 mhd_tls_multi_conn_deinit (struct mhd_TlsMultiConnData *restrict c_tls) 549 { 550 switch (c_tls->choice) 551 { 552 #ifdef MHD_SUPPORT_GNUTLS 553 case mhd_TLS_MULTI_ROUTE_GNU: 554 mhd_tls_gnu_conn_deinit (c_tls->data.gnutls); 555 break; 556 #endif 557 #ifdef MHD_SUPPORT_OPENSSL 558 case mhd_TLS_MULTI_ROUTE_OPEN: 559 mhd_tls_open_conn_deinit (c_tls->data.openssl); 560 break; 561 #endif 562 #ifdef MHD_SUPPORT_MBEDTLS 563 case mhd_TLS_MULTI_ROUTE_MBED: 564 mhd_tls_mbed_conn_deinit (c_tls->data.mbedtls); 565 break; 566 #endif 567 case mhd_TLS_MULTI_ROUTE_NONE: 568 default: 569 mhd_UNREACHABLE (); 570 } 571 } 572 573 574 /* ** TLS connection establishing ** */ 575 576 MHD_INTERNAL MHD_FN_MUST_CHECK_RESULT_ MHD_FN_PAR_NONNULL_ALL_ 577 enum mhd_TlsProcedureResult 578 mhd_tls_multi_conn_handshake (struct mhd_TlsMultiConnData *restrict c_tls) 579 { 580 switch (c_tls->choice) 581 { 582 #ifdef MHD_SUPPORT_GNUTLS 583 case mhd_TLS_MULTI_ROUTE_GNU: 584 return mhd_tls_gnu_conn_handshake (c_tls->data.gnutls); 585 #endif 586 #ifdef MHD_SUPPORT_OPENSSL 587 case mhd_TLS_MULTI_ROUTE_OPEN: 588 return mhd_tls_open_conn_handshake (c_tls->data.openssl); 589 #endif 590 #ifdef MHD_SUPPORT_MBEDTLS 591 case mhd_TLS_MULTI_ROUTE_MBED: 592 return mhd_tls_mbed_conn_handshake (c_tls->data.mbedtls); 593 #endif 594 case mhd_TLS_MULTI_ROUTE_NONE: 595 default: 596 mhd_UNREACHABLE (); 597 break; 598 } 599 return mhd_TLS_PROCED_FAILED; 600 } 601 602 603 MHD_INTERNAL MHD_FN_MUST_CHECK_RESULT_ MHD_FN_PAR_NONNULL_ALL_ 604 enum mhd_TlsProcedureResult 605 mhd_tls_multi_conn_shutdown (struct mhd_TlsMultiConnData *restrict c_tls) 606 { 607 switch (c_tls->choice) 608 { 609 #ifdef MHD_SUPPORT_GNUTLS 610 case mhd_TLS_MULTI_ROUTE_GNU: 611 return mhd_tls_gnu_conn_shutdown (c_tls->data.gnutls); 612 #endif 613 #ifdef MHD_SUPPORT_OPENSSL 614 case mhd_TLS_MULTI_ROUTE_OPEN: 615 return mhd_tls_open_conn_shutdown (c_tls->data.openssl); 616 #endif 617 #ifdef MHD_SUPPORT_MBEDTLS 618 case mhd_TLS_MULTI_ROUTE_MBED: 619 return mhd_tls_mbed_conn_shutdown (c_tls->data.mbedtls); 620 #endif 621 case mhd_TLS_MULTI_ROUTE_NONE: 622 default: 623 mhd_UNREACHABLE (); 624 break; 625 } 626 return mhd_TLS_PROCED_FAILED; 627 } 628 629 630 /* ** Data receiving and sending ** */ 631 632 MHD_INTERNAL MHD_FN_PAR_NONNULL_ALL_ 633 MHD_FN_PAR_OUT_SIZE_ (3,2) 634 MHD_FN_PAR_OUT_ (4) enum mhd_SocketError 635 mhd_tls_multi_conn_recv (struct mhd_TlsMultiConnData *restrict c_tls, 636 size_t buf_size, 637 char buf[MHD_FN_PAR_DYN_ARR_SIZE_ (buf_size)], 638 size_t *restrict received) 639 { 640 switch (c_tls->choice) 641 { 642 #ifdef MHD_SUPPORT_GNUTLS 643 case mhd_TLS_MULTI_ROUTE_GNU: 644 return mhd_tls_gnu_conn_recv (c_tls->data.gnutls, 645 buf_size, 646 buf, 647 received); 648 #endif 649 #ifdef MHD_SUPPORT_OPENSSL 650 case mhd_TLS_MULTI_ROUTE_OPEN: 651 return mhd_tls_open_conn_recv (c_tls->data.openssl, 652 buf_size, 653 buf, 654 received); 655 #endif 656 #ifdef MHD_SUPPORT_MBEDTLS 657 case mhd_TLS_MULTI_ROUTE_MBED: 658 return mhd_tls_mbed_conn_recv (c_tls->data.mbedtls, 659 buf_size, 660 buf, 661 received); 662 #endif 663 case mhd_TLS_MULTI_ROUTE_NONE: 664 default: 665 mhd_UNREACHABLE (); 666 break; 667 } 668 return mhd_SOCKET_ERR_INTERNAL; 669 } 670 671 672 MHD_INTERNAL MHD_FN_PAR_NONNULL_ALL_ MHD_FN_PURE_ bool 673 mhd_tls_multi_conn_has_cstm_tr (struct mhd_TlsMultiConnData *restrict c_tls) 674 { 675 (void) c_tls; /* Could be unused if all underling functions are actually macros */ 676 switch (c_tls->choice) 677 { 678 #ifdef MHD_SUPPORT_GNUTLS 679 case mhd_TLS_MULTI_ROUTE_GNU: 680 return mhd_tls_gnu_conn_has_cstm_tr (c_tls->data.gnutls); 681 #endif 682 #ifdef MHD_SUPPORT_OPENSSL 683 case mhd_TLS_MULTI_ROUTE_OPEN: 684 return mhd_tls_open_conn_has_cstm_tr (c_tls->data.openssl); 685 #endif 686 #ifdef MHD_SUPPORT_MBEDTLS 687 case mhd_TLS_MULTI_ROUTE_MBED: 688 return mhd_tls_mbed_conn_has_cstm_tr (c_tls->data.mbedtls); 689 #endif 690 case mhd_TLS_MULTI_ROUTE_NONE: 691 default: 692 mhd_UNREACHABLE (); 693 break; 694 } 695 return false; 696 } 697 698 699 MHD_INTERNAL MHD_FN_PAR_NONNULL_ALL_ bool 700 mhd_tls_multi_conn_has_data_in (struct mhd_TlsMultiConnData *restrict c_tls) 701 { 702 switch (c_tls->choice) 703 { 704 #ifdef MHD_SUPPORT_GNUTLS 705 case mhd_TLS_MULTI_ROUTE_GNU: 706 return mhd_tls_gnu_conn_has_data_in (c_tls->data.gnutls); 707 #endif 708 #ifdef MHD_SUPPORT_OPENSSL 709 case mhd_TLS_MULTI_ROUTE_OPEN: 710 return mhd_tls_open_conn_has_data_in (c_tls->data.openssl); 711 #endif 712 #ifdef MHD_SUPPORT_MBEDTLS 713 case mhd_TLS_MULTI_ROUTE_MBED: 714 return mhd_tls_mbed_conn_has_data_in (c_tls->data.mbedtls); 715 #endif 716 case mhd_TLS_MULTI_ROUTE_NONE: 717 default: 718 mhd_UNREACHABLE (); 719 break; 720 } 721 return false; 722 } 723 724 725 MHD_INTERNAL MHD_FN_PAR_NONNULL_ALL_ 726 MHD_FN_PAR_IN_SIZE_ (3,2) 727 MHD_FN_PAR_OUT_ (5) enum mhd_SocketError 728 mhd_tls_multi_conn_send (struct mhd_TlsMultiConnData *restrict c_tls, 729 size_t buf_size, 730 const char buf[MHD_FN_PAR_DYN_ARR_SIZE_ (buf_size)], 731 bool push_data, 732 size_t *restrict sent) 733 { 734 (void) push_data; /* Could be unused if not supported by all backends */ 735 switch (c_tls->choice) 736 { 737 #ifdef MHD_SUPPORT_GNUTLS 738 case mhd_TLS_MULTI_ROUTE_GNU: 739 return mhd_tls_gnu_conn_send (c_tls->data.gnutls, 740 buf_size, 741 buf, 742 push_data, 743 sent); 744 #endif 745 #ifdef MHD_SUPPORT_OPENSSL 746 case mhd_TLS_MULTI_ROUTE_OPEN: 747 return mhd_tls_open_conn_send (c_tls->data.openssl, 748 buf_size, 749 buf, 750 push_data, 751 sent); 752 #endif 753 #ifdef MHD_SUPPORT_MBEDTLS 754 case mhd_TLS_MULTI_ROUTE_MBED: 755 return mhd_tls_mbed_conn_send (c_tls->data.mbedtls, 756 buf_size, 757 buf, 758 push_data, 759 sent); 760 #endif 761 case mhd_TLS_MULTI_ROUTE_NONE: 762 default: 763 mhd_UNREACHABLE (); 764 break; 765 } 766 return mhd_SOCKET_ERR_INTERNAL; 767 } 768 769 770 /* ** TLS connection information ** */ 771 772 MHD_INTERNAL MHD_FN_PAR_NONNULL_ALL_ 773 MHD_FN_PAR_OUT_ (2) void 774 mhd_tls_multi_conn_get_tls_sess ( 775 struct mhd_TlsMultiConnData *restrict c_tls, 776 union MHD_ConnInfoDynamicTlsSess *restrict tls_sess_out) 777 { 778 switch (c_tls->choice) 779 { 780 #ifdef MHD_SUPPORT_GNUTLS 781 case mhd_TLS_MULTI_ROUTE_GNU: 782 mhd_tls_gnu_conn_get_tls_sess (c_tls->data.gnutls, 783 tls_sess_out); 784 break; 785 #endif 786 #ifdef MHD_SUPPORT_OPENSSL 787 case mhd_TLS_MULTI_ROUTE_OPEN: 788 mhd_tls_open_conn_get_tls_sess (c_tls->data.openssl, 789 tls_sess_out); 790 break; 791 #endif 792 #ifdef MHD_SUPPORT_MBEDTLS 793 case mhd_TLS_MULTI_ROUTE_MBED: 794 mhd_tls_mbed_conn_get_tls_sess (c_tls->data.mbedtls, 795 tls_sess_out); 796 break; 797 #endif 798 case mhd_TLS_MULTI_ROUTE_NONE: 799 default: 800 mhd_UNREACHABLE (); 801 break; 802 } 803 } 804 805 806 MHD_INTERNAL MHD_FN_PAR_NONNULL_ALL_ 807 MHD_FN_PAR_OUT_ (2) bool 808 mhd_tls_multi_conn_get_tls_ver (struct mhd_TlsMultiConnData *restrict c_tls, 809 struct mhd_StctTlsVersion *restrict tls_ver_out) 810 { 811 switch (c_tls->choice) 812 { 813 #ifdef MHD_SUPPORT_GNUTLS 814 case mhd_TLS_MULTI_ROUTE_GNU: 815 return mhd_tls_gnu_conn_get_tls_ver (c_tls->data.gnutls, 816 tls_ver_out); 817 #endif 818 #ifdef MHD_SUPPORT_OPENSSL 819 case mhd_TLS_MULTI_ROUTE_OPEN: 820 return mhd_tls_open_conn_get_tls_ver (c_tls->data.openssl, 821 tls_ver_out); 822 #endif 823 #ifdef MHD_SUPPORT_MBEDTLS 824 case mhd_TLS_MULTI_ROUTE_MBED: 825 return mhd_tls_mbed_conn_get_tls_ver (c_tls->data.mbedtls, 826 tls_ver_out); 827 #endif 828 case mhd_TLS_MULTI_ROUTE_NONE: 829 default: 830 mhd_UNREACHABLE (); 831 break; 832 } 833 return false; 834 } 835 836 837 MHD_INTERNAL MHD_FN_PAR_NONNULL_ALL_ enum mhd_TlsAlpnProt 838 mhd_tls_multi_conn_get_alpn_prot (struct mhd_TlsMultiConnData *restrict c_tls) 839 { 840 switch (c_tls->choice) 841 { 842 #ifdef MHD_SUPPORT_GNUTLS 843 case mhd_TLS_MULTI_ROUTE_GNU: 844 return mhd_tls_gnu_conn_get_alpn_prot (c_tls->data.gnutls); 845 #endif 846 #ifdef MHD_SUPPORT_OPENSSL 847 case mhd_TLS_MULTI_ROUTE_OPEN: 848 return mhd_tls_open_conn_get_alpn_prot (c_tls->data.openssl); 849 #endif 850 #ifdef MHD_SUPPORT_MBEDTLS 851 case mhd_TLS_MULTI_ROUTE_MBED: 852 return mhd_tls_mbed_conn_get_alpn_prot (c_tls->data.mbedtls); 853 #endif 854 case mhd_TLS_MULTI_ROUTE_NONE: 855 default: 856 mhd_UNREACHABLE (); 857 break; 858 } 859 return mhd_TLS_ALPN_PROT_NOT_SELECTED; 860 }