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:
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;
+ }
+}