libmicrohttpd2

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

commit f6cd1b743c4a2aed9c236eb2b3f27cc7c5e41626
parent 7ce0a3f8a6eead1f1d835f745d23bc4c2ab21bb7
Author: Christian Grothoff <christian@grothoff.org>
Date:   Sun, 23 Nov 2025 11:53:49 +0100

support mbedtls/openssl for sha256

Diffstat:
Msrc/mhd2/Makefile.am | 28+++++++++++++++++++++-------
Rsrc/mhd2/md5_ext.c -> src/mhd2/md5_ext_gnutls.c | 0
Dsrc/mhd2/sha256_ext.c | 122-------------------------------------------------------------------------------
Msrc/mhd2/sha256_ext.h | 7++++---
Asrc/mhd2/sha256_ext_gnutls.c | 135+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/mhd2/sha256_ext_mbedtls.c | 146+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/mhd2/sha256_ext_openssl.c | 154+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
7 files changed, 460 insertions(+), 132 deletions(-)

diff --git a/src/mhd2/Makefile.am b/src/mhd2/Makefile.am @@ -157,7 +157,7 @@ auth_basic_OPTSOURCES = \ if MHD_MD5_EXTR md5_OPTSOURCES = \ - md5_ext.c md5_ext.h \ + md5_ext_gnutls.c md5_ext.h \ mhd_md5.h else md5_OPTSOURCES = \ @@ -166,13 +166,27 @@ md5_OPTSOURCES = \ endif if MHD_SHA256_EXTR -sha256_OPTSOURCES = \ - sha256_ext.c sha256_ext.h \ - mhd_sha256.h + sha256_OPTSOURCES = \ + sha256_ext.h \ + mhd_sha256.h + + if MHD_SUPPORT_OPENSSL + sha256_OPTSOURCES += \ + sha256_ext_openssl.c + else + if MHD_SUPPORT_GNUTLS + sha256_OPTSOURCES += \ + sha256_ext_gnutls.c + else + sha256_OPTSOURCES += \ + sha256_ext_mbedtls.c + endif + endif + else -sha256_OPTSOURCES = \ - sha256_int.c sha256_int.h \ - mhd_sha256.h + sha256_OPTSOURCES = \ + sha256_int.c sha256_int.h \ + mhd_sha256.h endif sha512_256_OPTSOURCES = \ diff --git a/src/mhd2/md5_ext.c b/src/mhd2/md5_ext_gnutls.c diff --git a/src/mhd2/sha256_ext.c b/src/mhd2/sha256_ext.c @@ -1,122 +0,0 @@ -/* SPDX-License-Identifier: LGPL-2.1-or-later OR (GPL-2.0-or-later WITH eCos-exception-2.0) */ -/* - This file is part of GNU libmicrohttpd. - Copyright (C) 2022-2023 Evgeny Grin (Karlson2k) - - GNU libmicrohttpd is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - GNU libmicrohttpd is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - Alternatively, you can redistribute GNU libmicrohttpd and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of - the License, or (at your option) any later version, together - with the eCos exception, as follows: - - As a special exception, if other files instantiate templates or - use macros or inline functions from this file, or you compile this - file and link it with other works to produce a work based on this - file, this file does not by itself cause the resulting work to be - covered by the GNU General Public License. However the source code - for this file must still be made available in accordance with - section (3) of the GNU General Public License v2. - - This exception does not invalidate any other reasons why a work - based on this file might be covered by the GNU General Public - License. - - You should have received copies of the GNU Lesser General Public - License and the GNU General Public License along with this library; - if not, see <https://www.gnu.org/licenses/>. -*/ - -/** - * @file microhttpd/sha256_ext.h - * @brief Wrapper for SHA-256 calculation performed by TLS library - * @author Karlson2k (Evgeny Grin) - */ - -#include <gnutls/crypto.h> -#include "sha256_ext.h" -#include "mhd_assert.h" - - -/** - * Initialise structure for SHA-256 calculation, allocate resources. - * - * This function must not be called more than one time for @a ctx. - * - * @param ctx the calculation context - */ -void -mhd_SHA256_init_one_time (struct mhd_Sha256CtxExt *ctx) -{ - ctx->handle = NULL; - ctx->ext_error = gnutls_hash_init (&ctx->handle, GNUTLS_DIG_SHA256); - if ((0 != ctx->ext_error) && (NULL != ctx->handle)) - { - /* GnuTLS may return initialisation error and set the handle at the - same time. Such handle cannot be used for calculations. - Note: GnuTLS may also return an error and NOT set the handle. */ - gnutls_free (ctx->handle); - ctx->handle = NULL; - } - - /* If handle is NULL, the error must be set */ - mhd_assert ((NULL != ctx->handle) || (0 != ctx->ext_error)); - /* If error is set, the handle must be NULL */ - mhd_assert ((0 == ctx->ext_error) || (NULL == ctx->handle)); -} - - -/** - * Process portion of bytes. - * - * @param ctx the calculation context - * @param data bytes to add to hash - * @param length number of bytes in @a data - */ -void -mhd_SHA256_update (struct mhd_Sha256CtxExt *ctx, - size_t size, - const uint8_t *data) -{ - mhd_assert (0 != size); - - if (0 == ctx->ext_error) - ctx->ext_error = gnutls_hash (ctx->handle, data, size); -} - - -/** - * Finalise SHA-256 calculation, return digest, reset hash calculation. - * - * @param ctx the calculation context - * @param[out] digest set to the hash, must be #mhd_SHA256_DIGEST_SIZE bytes - */ -void -mhd_SHA256_finish_reset (struct mhd_Sha256CtxExt *ctx, - uint8_t digest[mhd_SHA256_DIGEST_SIZE]) -{ - if (0 == ctx->ext_error) - gnutls_hash_output (ctx->handle, digest); -} - - -/** - * Free allocated resources. - * - * @param ctx the calculation context - */ -void -mhd_SHA256_deinit (struct mhd_Sha256CtxExt *ctx) -{ - if (NULL != ctx->handle) - gnutls_hash_deinit (ctx->handle, NULL); -} diff --git a/src/mhd2/sha256_ext.h b/src/mhd2/sha256_ext.h @@ -55,8 +55,9 @@ */ #define mhd_SHA256_DIGEST_SIZE (32) -/* Actual declaration is in GnuTLS lib header */ -struct hash_hd_st; +#ifndef MHD_SHA256_Context +#define MHD_SHA256_Context void +#endif /** * Indicates that struct mhd_Sha256CtxExt has 'ext_error' @@ -68,7 +69,7 @@ struct hash_hd_st; */ struct mhd_Sha256CtxExt { - struct hash_hd_st *handle; /**< Hash calculation handle */ + MHD_SHA256_Context *handle; /**< Hash calculation handle */ int ext_error; /**< Non-zero if external error occurs during init or hashing */ }; diff --git a/src/mhd2/sha256_ext_gnutls.c b/src/mhd2/sha256_ext_gnutls.c @@ -0,0 +1,135 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later OR (GPL-2.0-or-later WITH eCos-exception-2.0) */ +/* + This file is part of GNU libmicrohttpd. + Copyright (C) 2022-2023 Evgeny Grin (Karlson2k) + + GNU libmicrohttpd is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + GNU libmicrohttpd is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + Alternatively, you can redistribute GNU libmicrohttpd and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version, together + with the eCos exception, as follows: + + As a special exception, if other files instantiate templates or + use macros or inline functions from this file, or you compile this + file and link it with other works to produce a work based on this + file, this file does not by itself cause the resulting work to be + covered by the GNU General Public License. However the source code + for this file must still be made available in accordance with + section (3) of the GNU General Public License v2. + + This exception does not invalidate any other reasons why a work + based on this file might be covered by the GNU General Public + License. + + You should have received copies of the GNU Lesser General Public + License and the GNU General Public License along with this library; + if not, see <https://www.gnu.org/licenses/>. +*/ + +/** + * @file microhttpd/sha256_ext_gnutls.c + * @brief Wrapper for SHA-256 calculation performed by GnuTLS library + * @author Karlson2k (Evgeny Grin) + */ +#include <gnutls/crypto.h> +#define MHD_SHA256_Context struct hash_hd_st +#include "sha256_ext.h" +#include "mhd_assert.h" + + +/** + * Initialise structure for SHA-256 calculation, allocate resources. + * + * This function must not be called more than one time for @a ctx. + * + * @param ctx the calculation context + */ +void +mhd_SHA256_init_one_time (struct mhd_Sha256CtxExt *ctx) +{ + ctx->handle = NULL; + ctx->ext_error = gnutls_hash_init (&ctx->handle, + GNUTLS_DIG_SHA256); + if ( (0 != ctx->ext_error) && + (NULL != ctx->handle) ) + { + /* GnuTLS may return initialisation error and set the handle at the + same time. Such handle cannot be used for calculations. + Note: GnuTLS may also return an error and NOT set the handle. */ + gnutls_free (ctx->handle); + ctx->handle = NULL; + } + + /* If handle is NULL, the error must be set */ + mhd_assert ((NULL != ctx->handle) || (0 != ctx->ext_error)); + /* If error is set, the handle must be NULL */ + mhd_assert ((0 == ctx->ext_error) || (NULL == ctx->handle)); +} + + +/** + * Process portion of bytes. + * + * @param ctx the calculation context + * @param data bytes to add to hash + * @param length number of bytes in @a data + */ +void +mhd_SHA256_update (struct mhd_Sha256CtxExt *ctx, + size_t size, + const uint8_t *data) +{ + // FIXME-EG: I think that size == 0 should be allowed here. -CG + mhd_assert (0 != size); + + if (0 == ctx->ext_error) + ctx->ext_error = gnutls_hash (ctx->handle, + data, + size); +} + + +/** + * Finalise SHA-256 calculation, return digest, reset hash calculation. + * + * @param ctx the calculation context + * @param[out] digest set to the hash, must be #mhd_SHA256_DIGEST_SIZE bytes + */ +void +mhd_SHA256_finish_reset (struct mhd_Sha256CtxExt *ctx, + uint8_t digest[mhd_SHA256_DIGEST_SIZE]) +{ + // FIXME-EG: do we need the 'reset' part of the logic? + // Not all implementations include reset, may result in extra + // work, see OpenSSL & mbedTLS! -CG + if (0 == ctx->ext_error) + gnutls_hash_output (ctx->handle, + digest); +} + + +/** + * Free allocated resources. + * + * @param ctx the calculation context + */ +void +mhd_SHA256_deinit (struct mhd_Sha256CtxExt *ctx) +{ + if (NULL != ctx->handle) + { + gnutls_hash_deinit (ctx->handle, + NULL); + ctx->handle = NULL; + } +} diff --git a/src/mhd2/sha256_ext_mbedtls.c b/src/mhd2/sha256_ext_mbedtls.c @@ -0,0 +1,146 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later OR (GPL-2.0-or-later WITH eCos-exception-2.0) */ +/* + This file is part of GNU libmicrohttpd. + Copyright (C) 2025 Christian Grothoff + + GNU libmicrohttpd is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + GNU libmicrohttpd is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + Alternatively, you can redistribute GNU libmicrohttpd and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version, together + with the eCos exception, as follows: + + As a special exception, if other files instantiate templates or + use macros or inline functions from this file, or you compile this + file and link it with other works to produce a work based on this + file, this file does not by itself cause the resulting work to be + covered by the GNU General Public License. However the source code + for this file must still be made available in accordance with + section (3) of the GNU General Public License v2. + + This exception does not invalidate any other reasons why a work + based on this file might be covered by the GNU General Public + License. + + You should have received copies of the GNU Lesser General Public + License and the GNU General Public License along with this library; + if not, see <https://www.gnu.org/licenses/>. +*/ + +/** + * @file microhttpd/sha256_ext_mbedtls.c + * @brief Wrapper for SHA-256 calculation performed by TLS library + * @author Christian Grothoff + */ + +#include <mbedtls/sha256.h> +#define MHD_SHA256_Context mbedtls_sha256_context +#include "sha256_ext.h" +#include "mhd_assert.h" + + +/** + * Initialise structure for SHA-256 calculation, allocate resources. + * + * This function must not be called more than one time for @a ctx. + * + * @param ctx the calculation context + */ +void +mhd_SHA256_init_one_time (struct mhd_Sha256CtxExt *ctx) +{ + ctx->ext_error = 0; + ctx->handle = (mbedtls_sha256_context *) malloc ( + sizeof (mbedtls_sha256_context)); + if (NULL == ctx->handle) + { + ctx->ext_error = 1; /* Allocation failure */ + return; + } + + mbedtls_sha256_init (ctx->handle); + ctx->ext_error = mbedtls_sha256_starts_ret (ctx->handle, + 0); /* 0 = SHA-256 */ + if (0 != ctx->ext_error) + { + mhd_SHA256_deinit (ctx); + } + + /* If handle is NULL, the error must be set */ + mhd_assert ((NULL != ctx->handle) || (0 != ctx->ext_error)); + /* If error is set, the handle must be NULL */ + mhd_assert ((0 == ctx->ext_error) || (NULL == ctx->handle)); +} + + +/** + * Process portion of bytes. + * + * @param ctx the calculation context + * @param data bytes to add to hash + * @param length number of bytes in @a data + */ +void +mhd_SHA256_update (struct mhd_Sha256CtxExt *ctx, + size_t size, + const uint8_t *data) +{ + // FIXME-EG: I think that size == 0 should be allowed here. -CG + mhd_assert (0 != size); + + if (0 == ctx->ext_error) + ctx->ext_error = mbedtls_sha256_update_ret (ctx->handle, + data, + size); +} + + +/** + * Finalise SHA-256 calculation, return digest, reset hash calculation. + * + * @param ctx the calculation context + * @param[out] digest set to the hash, must be #mhd_SHA256_DIGEST_SIZE bytes + */ +void +mhd_SHA256_finish_reset (struct mhd_Sha256CtxExt *ctx, + uint8_t digest[mhd_SHA256_DIGEST_SIZE]) +{ + if (0 == ctx->ext_error) + { + ctx->ext_error = mbedtls_sha256_finish_ret (ctx->handle, + digest); + + if (0 == ctx->ext_error) + { + /* Reset for potential reuse */ + ctx->ext_error = mbedtls_sha256_starts_ret (ctx->handle, + 0 /* ! is224 */); + } + } +} + + +/** + * Free allocated resources. + * + * @param ctx the calculation context + */ +void +mhd_SHA256_deinit (struct mhd_Sha256CtxExt *ctx) +{ + if (NULL != ctx->handle) + { + mbedtls_sha256_free (ctx->handle); + free (ctx->handle); + ctx->handle = NULL; + } +} diff --git a/src/mhd2/sha256_ext_openssl.c b/src/mhd2/sha256_ext_openssl.c @@ -0,0 +1,154 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later OR (GPL-2.0-or-later WITH eCos-exception-2.0) */ +/* + This file is part of GNU libmicrohttpd. + Copyright (C) 2025 Christian Grothoff + + GNU libmicrohttpd is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + GNU libmicrohttpd is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + Alternatively, you can redistribute GNU libmicrohttpd and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version, together + with the eCos exception, as follows: + + As a special exception, if other files instantiate templates or + use macros or inline functions from this file, or you compile this + file and link it with other works to produce a work based on this + file, this file does not by itself cause the resulting work to be + covered by the GNU General Public License. However the source code + for this file must still be made available in accordance with + section (3) of the GNU General Public License v2. + + This exception does not invalidate any other reasons why a work + based on this file might be covered by the GNU General Public + License. + + You should have received copies of the GNU Lesser General Public + License and the GNU General Public License along with this library; + if not, see <https://www.gnu.org/licenses/>. +*/ + +/** + * @file microhttpd/sha256_ext_openssl.c + * @brief Wrapper for SHA-256 calculation performed by OpenSSL library + * @author Christian Grothoff + */ + +#include <openssl/evp.h> +#define MHD_SHA256_Context EVP_MD_CTX +#include "sha256_ext.h" +#include "mhd_assert.h" + + +/** + * Initialise structure for SHA-256 calculation, allocate resources. + * + * This function must not be called more than one time for @a ctx. + * + * @param ctx the calculation context + */ +void +mhd_SHA256_init_one_time (struct mhd_Sha256CtxExt *ctx) +{ + ctx->ext_error = 0; + ctx->handle = EVP_MD_CTX_new (); + if (NULL == ctx->handle) + { + ctx->ext_error = 1; /* Allocation failure */ + return; + } + if (1 != EVP_DigestInit_ex (ctx->handle, + EVP_sha256 (), + NULL)) + { + ctx->ext_error = 1; /* Initialization failure */ + mhd_SHA256_deinit (ctx); + } + + /* If handle is NULL, the error must be set */ + mhd_assert ((NULL != ctx->handle) || (0 != ctx->ext_error)); + /* If error is set, the handle must be NULL */ + mhd_assert ((0 == ctx->ext_error) || (NULL == ctx->handle)); +} + + +/** + * Process portion of bytes. + * + * @param ctx the calculation context + * @param data bytes to add to hash + * @param length number of bytes in @a data + */ +void +mhd_SHA256_update (struct mhd_Sha256CtxExt *ctx, + size_t size, + const uint8_t *data) +{ + // FIXME-EG: I think that size == 0 should be allowed here. -CG + mhd_assert (0 != size); + + if (0 == ctx->ext_error) + { + if (1 != EVP_DigestUpdate (ctx->handle, + data, + size)) + ctx->ext_error = 1; + } +} + + +/** + * Finalise SHA-256 calculation, return digest, reset hash calculation. + * + * @param ctx the calculation context + * @param[out] digest set to the hash, must be #mhd_SHA256_DIGEST_SIZE bytes + */ +void +mhd_SHA256_finish_reset (struct mhd_Sha256CtxExt *ctx, + uint8_t digest[mhd_SHA256_DIGEST_SIZE]) +{ + unsigned int len; + + if (0 == ctx->ext_error) + { + if (1 != EVP_DigestFinal_ex (ctx->handle, + digest, + &len)) + { + ctx->ext_error = 1; + } + else + { + mhd_assert (mhd_SHA256_DIGEST_SIZE == len); + /* Reset for potential reuse */ + if (1 != EVP_DigestInit_ex (ctx->handle, + EVP_sha256 (), + NULL)) + ctx->ext_error = 1; + } + } +} + + +/** + * Free allocated resources. + * + * @param ctx the calculation context + */ +void +mhd_SHA256_deinit (struct mhd_Sha256CtxExt *ctx) +{ + if (NULL != ctx->handle) + { + EVP_MD_CTX_free (ctx->handle); + ctx->handle = NULL; + } +}