mirror of
https://git.gnunet.org/libmicrohttpd.git
synced 2026-09-25 04:09:31 +03:00
Implemented support for hash calculation by GnuTLS lib functions
This commit is contained in:
+229
-31
@@ -3048,8 +3048,8 @@ AC_MSG_RESULT([[$enable_bauth]])
|
||||
AC_MSG_CHECKING([[whether to support HTTP Digest authentication]])
|
||||
AC_ARG_ENABLE([dauth],
|
||||
[AS_HELP_STRING([--disable-dauth], [disable HTTP Digest Authentication support])],
|
||||
[enable_dauth=${enableval}],
|
||||
[enable_dauth=yes])
|
||||
[enable_dauth="${enableval}"],
|
||||
[enable_dauth="yes"])
|
||||
AS_IF([[test "x$enable_dauth" != "xno"]],
|
||||
[ enable_dauth=yes
|
||||
AC_DEFINE([DAUTH_SUPPORT],[1],[Define to 1 if libmicrohttpd is compiled with Digest Auth support.]) ])
|
||||
@@ -3084,57 +3084,249 @@ AC_MSG_RESULT([[$enable_cookie]])
|
||||
|
||||
# optional: MD5 support for Digest Auth. Enabled by default.
|
||||
AC_ARG_ENABLE([[md5]],
|
||||
[AS_HELP_STRING([[--disable-md5]],[disable MD5 hashing support for Digest Authentication])
|
||||
[AS_HELP_STRING([[--enable-md5=TYPE]],[enable TYPE of MD5 hashing code (yes, no, builtin, tlslib) [yes if dauth enabled]])
|
||||
],
|
||||
[
|
||||
AS_VAR_IF([[enable_md5]],[["yes"]],
|
||||
AS_VAR_IF([enable_md5],["internal"],[enable_md5='builtin'])
|
||||
AS_VAR_IF([enable_md5],["built-in"],[enable_md5='builtin'])
|
||||
AS_VAR_IF([enable_dauth],["yes"],[],
|
||||
[
|
||||
AS_VAR_IF([enable_dauth],["yes"],[],
|
||||
AS_VAR_IF([enable_md5],["no"],[],
|
||||
[
|
||||
AC_MSG_WARN([The parameter --enable-md5 is ignored as Digest Authentication is disabled])
|
||||
AC_MSG_WARN([The parameter --enable-md5=${enable_md5} is ignored as Digest Authentication is disabled])
|
||||
enable_md5='no'
|
||||
]
|
||||
)
|
||||
],[[enable_md5='no']]
|
||||
]
|
||||
)
|
||||
], [[enable_md5="${enable_dauth}"]]
|
||||
)
|
||||
AC_MSG_CHECKING([[whether to support MD5]])
|
||||
AS_VAR_IF([[enable_md5]],[["yes"]],
|
||||
AS_CASE([${enable_md5}],[yes|tlslib],
|
||||
[
|
||||
AC_DEFINE([[MHD_MD5_SUPPORT]],[[1]],
|
||||
[Define to 1 if libmicrohttpd is compiled with MD5 hashing support.])
|
||||
AS_IF([test "x${enable_compact_code}" != "xno" || test "x$enable_md5" = "xtlslib"],
|
||||
[
|
||||
AS_IF([test "x$enable_https" = "xyes"],
|
||||
[
|
||||
AC_CACHE_CHECK([whether GnuTLS supports MD5 hashing],[mhd_cv_gnutls_md5],
|
||||
[
|
||||
CFLAGS="${CFLAGS_ac} ${GNUTLS_CFLAGS} ${user_CFLAGS}"
|
||||
CPPFLAGS="${CPPFLAGS_ac} ${MHD_TLS_LIB_CPPFLAGS} ${user_CPPFLAGS}"
|
||||
CFLAGS="${CFLAGS_ac} ${MHD_TLS_LIB_CFLAGS} ${user_CFLAGS}"
|
||||
LDFLAGS="${LDFLAGS_ac} ${MHD_TLS_LIB_LDFLAGS} ${user_LDFLAGS}"
|
||||
save_LIBS="$LIBS"
|
||||
LIBS="${MHD_TLS_LIBDEPS} ${LIBS}"
|
||||
AC_LINK_IFELSE(
|
||||
[
|
||||
AC_LANG_PROGRAM(
|
||||
[[
|
||||
#include <gnutls/crypto.h>
|
||||
]],
|
||||
[[
|
||||
gnutls_hash_hd_t hash_handle;
|
||||
unsigned char digest[16];
|
||||
int exit_code;
|
||||
|
||||
if (0 == gnutls_hash_init(&hash_handle, GNUTLS_DIG_MD5))
|
||||
{
|
||||
if (0 == gnutls_hash(hash_handle, "", 1))
|
||||
{
|
||||
gnutls_hash_output(hash_handle, digest);
|
||||
if (0x93 == digest[0])
|
||||
exit_code = 0;
|
||||
else
|
||||
exit_code = 7;
|
||||
}
|
||||
else
|
||||
exit_code = 5;
|
||||
gnutls_hash_deinit(hash_handle, (void *)0);
|
||||
}
|
||||
else
|
||||
exit_code = 2;
|
||||
if (exit_code)
|
||||
return exit_code;
|
||||
]]
|
||||
)
|
||||
],
|
||||
[mhd_cv_gnutls_md5='yes'],[mhd_cv_gnutls_md5='no']
|
||||
)
|
||||
LIBS="${save_LIBS}"
|
||||
CFLAGS="${CFLAGS_ac} ${user_CFLAGS}"
|
||||
CPPFLAGS="${CPPFLAGS_ac} ${user_CPPFLAGS}"
|
||||
CFLAGS="${CFLAGS_ac} ${user_CFLAGS}"
|
||||
LDFLAGS="${LDFLAGS_ac} ${user_LDFLAGS}"
|
||||
]
|
||||
)
|
||||
AS_VAR_IF([mhd_cv_gnutls_md5],["no"],
|
||||
[
|
||||
AS_VAR_IF([enable_md5],["tlslib"],
|
||||
[AC_MSG_FAILURE([TLS library MD5 implementation is not available])]
|
||||
)
|
||||
enable_md5="builtin"
|
||||
],
|
||||
[enable_md5="tlslib"]
|
||||
)
|
||||
],
|
||||
[
|
||||
AS_VAR_IF([enable_md5],["tlslib"],
|
||||
[AC_MSG_ERROR([HTTPS is not enabled, TLS library MD5 implementation cannot be used])]
|
||||
)
|
||||
enable_md5="builtin"
|
||||
]
|
||||
)
|
||||
],
|
||||
[
|
||||
enable_md5="builtin"
|
||||
]
|
||||
)
|
||||
]
|
||||
)
|
||||
AM_CONDITIONAL([ENABLE_MD5], [[test "x${enable_md5}" = "xyes"]])
|
||||
AC_MSG_RESULT([[${enable_md5}]])
|
||||
AC_MSG_CHECKING([[whether to support MD5]])
|
||||
AS_UNSET([enable_md5_MSG])
|
||||
AS_CASE([${enable_md5}],
|
||||
[builtin],[enable_md5_MSG='yes, built-in'],
|
||||
[tlslib],[enable_md5_MSG='yes, external (TLS library)'],
|
||||
[no],[enable_md5_MSG='no'],
|
||||
[yes],[AC_MSG_ERROR([configure internal error: unexpected variable value])],
|
||||
[AC_MSG_ERROR([Unrecognized parameter --enable-md5=${enable_md5}])]
|
||||
)
|
||||
AS_IF([test "x${enable_md5}" = "xbuiltin" || test "x${enable_md5}" = "xtlslib" ],
|
||||
[
|
||||
AC_DEFINE([[MHD_MD5_SUPPORT]],[[1]],
|
||||
[Define to 1 if libmicrohttpd is compiled with MD5 hashing support.])
|
||||
]
|
||||
)
|
||||
AS_IF([test "x${enable_md5}" = "xtlslib" ],
|
||||
[
|
||||
AC_DEFINE([[MHD_MD5_TLSLIB]],[[1]],
|
||||
[Define to 1 if libmicrohttpd is compiled with MD5 hashing by TLS library.])
|
||||
]
|
||||
)
|
||||
AM_CONDITIONAL([ENABLE_MD5], [[test "x${enable_md5}" = "xbuiltin" || test "x${enable_md5}" = "xtlslib" ]])
|
||||
AM_CONDITIONAL([ENABLE_MD5_EXT], [[test "x${enable_md5}" = "xtlslib" ]])
|
||||
AC_MSG_RESULT([[${enable_md5_MSG}]])
|
||||
|
||||
# optional: SHA-256 support for Digest Auth. Enabled by default.
|
||||
AC_ARG_ENABLE([[sha256]],
|
||||
[AS_HELP_STRING([[--disable-sha256]],[disable SHA-256 hashing support for Digest Authentication])
|
||||
[AS_HELP_STRING([[--enable-sha256=TYPE]],[enable TYPE of SHA-256 hashing code (yes, no, builtin, tlslib) [yes if dauth enabled]])
|
||||
],
|
||||
[
|
||||
AS_VAR_IF([[enable_sha256]],[["yes"]],
|
||||
AS_VAR_IF([enable_sha256],["internal"],[enable_sha256='builtin'])
|
||||
AS_VAR_IF([enable_sha256],["built-in"],[enable_sha256='builtin'])
|
||||
AS_VAR_IF([enable_dauth],["yes"],[],
|
||||
[
|
||||
AS_VAR_IF([enable_dauth],["yes"],[],
|
||||
AS_VAR_IF([enable_sha256],["no"],[],
|
||||
[
|
||||
AC_MSG_WARN([The parameter --enable-sha256 is ignored as Digest Authentication is disabled])
|
||||
AC_MSG_WARN([The parameter --enable-sha256=${enable_sha256} is ignored as Digest Authentication is disabled])
|
||||
enable_sha256='no'
|
||||
]
|
||||
)
|
||||
],[[enable_sha256='no']]
|
||||
]
|
||||
)
|
||||
], [[enable_sha256="${enable_dauth}"]]
|
||||
)
|
||||
AC_MSG_CHECKING([[whether to support SHA-256]])
|
||||
AS_VAR_IF([[enable_sha256]],[["yes"]],
|
||||
AS_CASE([${enable_sha256}],[yes|tlslib],
|
||||
[
|
||||
AC_DEFINE([[MHD_SHA256_SUPPORT]],[[1]],
|
||||
[Define to 1 if libmicrohttpd is compiled with SHA-256 hashing support.])
|
||||
AS_IF([test "x${enable_compact_code}" != "xno" || test "x$enable_sha256" = "xtlslib"],
|
||||
[
|
||||
AS_IF([test "x$enable_https" = "xyes"],
|
||||
[
|
||||
AC_CACHE_CHECK([whether GnuTLS supports sha256 hashing],[mhd_cv_gnutls_sha256],
|
||||
[
|
||||
CFLAGS="${CFLAGS_ac} ${GNUTLS_CFLAGS} ${user_CFLAGS}"
|
||||
CPPFLAGS="${CPPFLAGS_ac} ${MHD_TLS_LIB_CPPFLAGS} ${user_CPPFLAGS}"
|
||||
CFLAGS="${CFLAGS_ac} ${MHD_TLS_LIB_CFLAGS} ${user_CFLAGS}"
|
||||
LDFLAGS="${LDFLAGS_ac} ${MHD_TLS_LIB_LDFLAGS} ${user_LDFLAGS}"
|
||||
save_LIBS="$LIBS"
|
||||
LIBS="${MHD_TLS_LIBDEPS} ${LIBS}"
|
||||
AC_LINK_IFELSE(
|
||||
[
|
||||
AC_LANG_PROGRAM(
|
||||
[[
|
||||
#include <gnutls/crypto.h>
|
||||
]],
|
||||
[[
|
||||
gnutls_hash_hd_t hash_handle;
|
||||
unsigned char digest[32];
|
||||
int exit_code;
|
||||
|
||||
if (0 == gnutls_hash_init(&hash_handle, GNUTLS_DIG_SHA256))
|
||||
{
|
||||
if (0 == gnutls_hash(hash_handle, "", 1))
|
||||
{
|
||||
gnutls_hash_output(hash_handle, digest);
|
||||
if (0x6e == digest[0])
|
||||
exit_code = 0;
|
||||
else
|
||||
exit_code = 7;
|
||||
}
|
||||
else
|
||||
exit_code = 5;
|
||||
gnutls_hash_deinit(hash_handle, (void *)0);
|
||||
}
|
||||
else
|
||||
exit_code = 2;
|
||||
if (exit_code)
|
||||
return exit_code;
|
||||
]]
|
||||
)
|
||||
],
|
||||
[mhd_cv_gnutls_sha256='yes'],[mhd_cv_gnutls_sha256='no']
|
||||
)
|
||||
LIBS="${save_LIBS}"
|
||||
CFLAGS="${CFLAGS_ac} ${user_CFLAGS}"
|
||||
CPPFLAGS="${CPPFLAGS_ac} ${user_CPPFLAGS}"
|
||||
CFLAGS="${CFLAGS_ac} ${user_CFLAGS}"
|
||||
LDFLAGS="${LDFLAGS_ac} ${user_LDFLAGS}"
|
||||
]
|
||||
)
|
||||
AS_VAR_IF([mhd_cv_gnutls_sha256],["no"],
|
||||
[
|
||||
AS_VAR_IF([enable_sha256],["tlslib"],
|
||||
[AC_MSG_FAILURE([TLS library SHA-256 implementation is not available])]
|
||||
)
|
||||
enable_sha256="builtin"
|
||||
],
|
||||
[enable_sha256="tlslib"]
|
||||
)
|
||||
],
|
||||
[
|
||||
AS_VAR_IF([enable_sha256],["tlslib"],
|
||||
[AC_MSG_ERROR([HTTPS is not enabled, TLS library SHA-256 implementation cannot be used])]
|
||||
)
|
||||
enable_sha256="builtin"
|
||||
]
|
||||
)
|
||||
],
|
||||
[
|
||||
enable_sha256="builtin"
|
||||
]
|
||||
)
|
||||
]
|
||||
)
|
||||
AM_CONDITIONAL([ENABLE_SHA256], [[test "x${enable_sha256}" = "xyes"]])
|
||||
AC_MSG_RESULT([[${enable_sha256}]])
|
||||
AC_MSG_CHECKING([[whether to support SHA-256]])
|
||||
AS_UNSET([enable_sha256_MSG])
|
||||
AS_CASE([${enable_sha256}],
|
||||
[builtin],[enable_sha256_MSG='yes, built-in'],
|
||||
[tlslib],[enable_sha256_MSG='yes, external (TLS library)'],
|
||||
[no],[enable_sha256_MSG='no'],
|
||||
[yes],[AC_MSG_ERROR([configure internal error: unexpected variable value])],
|
||||
[AC_MSG_ERROR([Unrecognized parameter --enable-sha256=${enable_sha256}])]
|
||||
)
|
||||
AS_IF([test "x${enable_sha256}" = "xbuiltin" || test "x${enable_sha256}" = "xtlslib" ],
|
||||
[
|
||||
AC_DEFINE([[MHD_SHA256_SUPPORT]],[[1]],
|
||||
[Define to 1 if libmicrohttpd is compiled with SHA-256 hashing support.])
|
||||
]
|
||||
)
|
||||
AS_IF([test "x${enable_sha256}" = "xtlslib" ],
|
||||
[
|
||||
AC_DEFINE([[MHD_SHA256_TLSLIB]],[[1]],
|
||||
[Define to 1 if libmicrohttpd is compiled with SHA-256 hashing by TLS library.])
|
||||
]
|
||||
)
|
||||
AM_CONDITIONAL([ENABLE_SHA256], [[test "x${enable_sha256}" = "xbuiltin" || test "x${enable_sha256}" = "xtlslib" ]])
|
||||
AM_CONDITIONAL([ENABLE_SHA256_EXT], [[test "x${enable_sha256}" = "xtlslib" ]])
|
||||
AC_MSG_RESULT([[${enable_sha256_MSG}]])
|
||||
|
||||
# optional: SHA-512/256 support for Digest Auth. Enabled by default.
|
||||
AC_ARG_ENABLE([[sha512-256]],
|
||||
@@ -3154,6 +3346,12 @@ AC_ARG_ENABLE([[sha512-256]],
|
||||
], [[enable_sha512_256="${enable_dauth}"]]
|
||||
)
|
||||
AC_MSG_CHECKING([[whether to support SHA-512/256]])
|
||||
AS_UNSET([enable_sha512_256_MSG])
|
||||
AS_CASE([${enable_sha512_256}],
|
||||
[yes],[enable_sha512_256_MSG='yes, built-in'],
|
||||
[no],[enable_sha512_256_MSG='no'],
|
||||
[AC_MSG_ERROR([Unrecognized parameter --enable-sha512-256=${enable_sha512_256}])]
|
||||
)
|
||||
AS_VAR_IF([[enable_sha512_256]],[["yes"]],
|
||||
[
|
||||
AC_DEFINE([[MHD_SHA512_256_SUPPORT]],[[1]],
|
||||
@@ -3161,11 +3359,11 @@ AS_VAR_IF([[enable_sha512_256]],[["yes"]],
|
||||
]
|
||||
)
|
||||
AM_CONDITIONAL([ENABLE_SHA512_256], [[test "x${enable_sha512_256}" = "xyes"]])
|
||||
AC_MSG_RESULT([[${enable_sha512_256}]])
|
||||
AC_MSG_RESULT([[${enable_sha512_256_MSG}]])
|
||||
|
||||
AS_IF([test "x$enable_dauth" != "xno"],
|
||||
[
|
||||
AS_IF([test "x${enable_md5}" != "xyes" && test "x${enable_sha256}" != "xyes" && test "x${enable_sha512_256}" != "xyes"],
|
||||
AS_IF([test "x${enable_md5}" = "xno" && test "x${enable_sha256}" = "xno" && test "x${enable_sha512_256}" != "xyes"],
|
||||
[AC_MSG_ERROR([At least one hashing algorithm must be enabled if Digest Auth is enabled])]
|
||||
)
|
||||
]
|
||||
@@ -4052,9 +4250,9 @@ AC_MSG_NOTICE([GNU libmicrohttpd ${PACKAGE_VERSION} Configuration Summary:
|
||||
Messages: ${enable_messages}
|
||||
Basic auth.: ${enable_bauth}
|
||||
Digest auth.: ${enable_dauth}
|
||||
MD5: ${enable_md5}
|
||||
SHA-256: ${enable_sha256}
|
||||
SHA-512/256: ${enable_sha512_256}
|
||||
MD5: ${enable_md5_MSG}
|
||||
SHA-256: ${enable_sha256_MSG}
|
||||
SHA-512/256: ${enable_sha512_256_MSG}
|
||||
HTTP "Upgrade": ${enable_httpupgrade}
|
||||
Cookie parsing: ${enable_cookie}
|
||||
Postproc: ${enable_postprocessor}
|
||||
@@ -4075,8 +4273,8 @@ AS_IF([test "x$enable_https" = "xyes"],
|
||||
|
||||
AS_IF([test "x$enable_bauth" != "xyes" || \
|
||||
test "x$enable_dauth" != "xyes" || \
|
||||
test "x${enable_md5}" != "xyes" || \
|
||||
test "x${enable_sha256}" != "xyes" || \
|
||||
test "x${enable_md5}" = "xno" || \
|
||||
test "x${enable_sha256}" = "xno" || \
|
||||
test "x${enable_sha512_256}" != "xyes" || \
|
||||
test "x$enable_httpupgrade" != "xyes" || \
|
||||
test "x$enable_cookie" != "xyes" || \
|
||||
|
||||
@@ -96,7 +96,7 @@ extern "C"
|
||||
* they are parsed as decimal numbers.
|
||||
* Example: 0x01093001 = 1.9.30-1.
|
||||
*/
|
||||
#define MHD_VERSION 0x00097539
|
||||
#define MHD_VERSION 0x00097540
|
||||
|
||||
/* If generic headers don't work on your platform, include headers
|
||||
which define 'va_list', 'size_t', 'ssize_t', 'intptr_t', 'off_t',
|
||||
@@ -4691,8 +4691,10 @@ enum MHD_DigestAuthMultiAlgo3
|
||||
* upon return
|
||||
* @param bin_buf_size the size of the @a userhash_bin buffer, must be
|
||||
* at least #MHD_digest_get_hash_size(algo3) bytes long
|
||||
* @return MHD_YES on success, MHD_NO if @a bin_buf_size is too small or
|
||||
* if @a algo3 algorithm is not supported.
|
||||
* @return MHD_YES on success,
|
||||
* MHD_NO if @a bin_buf_size is too small or if @a algo3 algorithm is
|
||||
* not supported (or external error has occurred,
|
||||
* see #MHD_FEATURE_EXTERN_HASH)
|
||||
* @note Available since #MHD_VERSION 0x00097535
|
||||
* @ingroup authentication
|
||||
*/
|
||||
@@ -4736,8 +4738,10 @@ MHD_digest_auth_calc_userhash (enum MHD_DigestAuthAlgo3 algo3,
|
||||
* userhash string
|
||||
* @param bin_buf_size the size of the @a userhash_bin buffer, must be
|
||||
* at least #MHD_digest_get_hash_size(algo3)*2+1 chars long
|
||||
* @return MHD_YES on success, MHD_NO if @a bin_buf_size is too small or
|
||||
* if @a algo3 algorithm is not supported.
|
||||
* @return MHD_YES on success,
|
||||
* MHD_NO if @a bin_buf_size is too small or if @a algo3 algorithm is
|
||||
* not supported (or external error has occurred,
|
||||
* see #MHD_FEATURE_EXTERN_HASH).
|
||||
* @note Available since #MHD_VERSION 0x00097535
|
||||
* @ingroup authentication
|
||||
*/
|
||||
@@ -5287,8 +5291,10 @@ MHD_digest_auth_check3 (struct MHD_Connection *connection,
|
||||
* userdigest upon return
|
||||
* @param userdigest_bin the size of the @a userdigest_bin buffer, must be
|
||||
* at least #MHD_digest_get_hash_size(algo3) bytes long
|
||||
* @return MHD_YES on success, MHD_NO if @a userdigest_bin is too small or
|
||||
* if @a algo3 algorithm is not supported.
|
||||
* @return MHD_YES on success,
|
||||
* MHD_NO if @a userdigest_bin is too small or if @a algo3 algorithm is
|
||||
* not supported (or external error has occurred,
|
||||
* see #MHD_FEATURE_EXTERN_HASH).
|
||||
* @sa #MHD_digest_auth_check_digest3()
|
||||
* @note Available since #MHD_VERSION 0x00097535
|
||||
* @ingroup authentication
|
||||
@@ -5651,6 +5657,9 @@ MHD_queue_auth_fail_response (struct MHD_Connection *connection,
|
||||
int signal_stale);
|
||||
|
||||
|
||||
/* ********************* Basic Authentication functions *************** */
|
||||
|
||||
|
||||
/**
|
||||
* Information decoded from Basic Authentication client's header.
|
||||
*
|
||||
@@ -6138,7 +6147,21 @@ enum MHD_FEATURE
|
||||
* module is built.
|
||||
* @note Available since #MHD_VERSION 0x00097536
|
||||
*/
|
||||
MHD_FEATURE_DIGEST_AUTH_USERHASH = 31
|
||||
MHD_FEATURE_DIGEST_AUTH_USERHASH = 31,
|
||||
|
||||
/**
|
||||
* Get whether any of hashing algorithms is implemented by external
|
||||
* function (like TLS library) and may fail due to external conditions,
|
||||
* like "out-of-memory".
|
||||
*
|
||||
* If result is #MHD_YES then functions which use hash calculations
|
||||
* like #MHD_digest_auth_calc_userhash(), #MHD_digest_auth_check3() and others
|
||||
* potentially may fail even with valid input because of out-of-memory error
|
||||
* or crypto accelerator device failure, however in practice such fails are
|
||||
* unlikely.
|
||||
* @note Available since #MHD_VERSION 0x00097540
|
||||
*/
|
||||
MHD_FEATURE_EXTERN_HASH = 32
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -170,12 +170,26 @@ libmicrohttpd_la_SOURCES += \
|
||||
digestauth.c digestauth.h \
|
||||
mhd_bithelpers.h mhd_byteorder.h mhd_align.h
|
||||
if ENABLE_MD5
|
||||
libmicrohttpd_la_SOURCES += \
|
||||
mhd_md5_wrap.h
|
||||
if ! ENABLE_MD5_EXT
|
||||
libmicrohttpd_la_SOURCES += \
|
||||
md5.c md5.h
|
||||
else
|
||||
libmicrohttpd_la_SOURCES += \
|
||||
md5_ext.c md5_ext.h
|
||||
endif
|
||||
endif
|
||||
if ENABLE_SHA256
|
||||
libmicrohttpd_la_SOURCES += \
|
||||
mhd_sha256_wrap.h
|
||||
if ! ENABLE_SHA256_EXT
|
||||
libmicrohttpd_la_SOURCES += \
|
||||
sha256.c sha256.h
|
||||
else
|
||||
libmicrohttpd_la_SOURCES += \
|
||||
sha256_ext.c sha256_ext.h
|
||||
endif
|
||||
endif
|
||||
if ENABLE_SHA512_256
|
||||
libmicrohttpd_la_SOURCES += \
|
||||
@@ -462,12 +476,40 @@ test_http_reasons_SOURCES = \
|
||||
reason_phrase.c mhd_str.c mhd_str.h
|
||||
|
||||
test_md5_SOURCES = \
|
||||
test_md5.c test_helpers.h \
|
||||
test_md5.c test_helpers.h mhd_md5_wrap.h ../include/mhd_options.h
|
||||
if ! ENABLE_MD5_EXT
|
||||
test_md5_SOURCES += \
|
||||
md5.c md5.h mhd_bithelpers.h mhd_byteorder.h mhd_align.h
|
||||
test_md5_CPPFLAGS = $(AM_CPPFLAGS)
|
||||
test_md5_CFLAGS = $(AM_CFLAGS)
|
||||
test_md5_LDFLAGS = $(AM_LDFLAGS)
|
||||
test_md5_LDADD = $(LDADD)
|
||||
else
|
||||
test_md5_SOURCES += \
|
||||
md5_ext.c md5_ext.h
|
||||
test_md5_CPPFLAGS = $(AM_CPPFLAGS) $(MHD_TLS_LIB_CPPFLAGS)
|
||||
test_md5_CFLAGS = $(AM_CFLAGS) $(MHD_TLS_LIB_CFLAGS)
|
||||
test_md5_LDFLAGS = $(AM_LDFLAGS) $(MHD_TLS_LIB_LDFLAGS)
|
||||
test_md5_LDADD = $(MHD_TLS_LIBDEPS) $(LDADD)
|
||||
endif
|
||||
|
||||
test_sha256_SOURCES = \
|
||||
test_sha256.c test_helpers.h \
|
||||
test_sha256.c test_helpers.h mhd_sha256_wrap.h ../include/mhd_options.h
|
||||
if ! ENABLE_SHA256_EXT
|
||||
test_sha256_SOURCES += \
|
||||
sha256.c sha256.h mhd_bithelpers.h mhd_byteorder.h mhd_align.h
|
||||
test_sha256_CPPFLAGS = $(AM_CPPFLAGS)
|
||||
test_sha256_CFLAGS = $(AM_CFLAGS)
|
||||
test_sha256_LDFLAGS = $(AM_LDFLAGS)
|
||||
test_sha256_LDADD = $(LDADD)
|
||||
else
|
||||
test_sha256_SOURCES += \
|
||||
sha256_ext.c sha256_ext.h
|
||||
test_sha256_CPPFLAGS = $(AM_CPPFLAGS) $(MHD_TLS_LIB_CPPFLAGS)
|
||||
test_sha256_CFLAGS = $(AM_CFLAGS) $(MHD_TLS_LIB_CFLAGS)
|
||||
test_sha256_LDFLAGS = $(AM_LDFLAGS) $(MHD_TLS_LIB_LDFLAGS)
|
||||
test_sha256_LDADD = $(MHD_TLS_LIBDEPS) $(LDADD)
|
||||
endif
|
||||
|
||||
test_sha512_256_SOURCES = \
|
||||
test_sha512_256.c test_helpers.h \
|
||||
|
||||
@@ -8465,6 +8465,12 @@ MHD_is_feature_supported (enum MHD_FEATURE feature)
|
||||
#else
|
||||
return MHD_NO;
|
||||
#endif
|
||||
case MHD_FEATURE_EXTERN_HASH:
|
||||
#if defined(MHD_MD5_TLSLIB) || defined(MHD_SHA256_TLSLIB)
|
||||
return MHD_YES;
|
||||
#else
|
||||
return MHD_NO;
|
||||
#endif
|
||||
|
||||
default:
|
||||
break;
|
||||
|
||||
+510
-155
@@ -34,10 +34,10 @@
|
||||
#include "internal.h"
|
||||
#include "response.h"
|
||||
#ifdef MHD_MD5_SUPPORT
|
||||
# include "md5.h"
|
||||
# include "mhd_md5_wrap.h"
|
||||
#endif /* MHD_MD5_SUPPORT */
|
||||
#ifdef MHD_SHA256_SUPPORT
|
||||
# include "sha256.h"
|
||||
# include "mhd_sha256_wrap.h"
|
||||
#endif /* MHD_SHA256_SUPPORT */
|
||||
#ifdef MHD_SHA512_256_SUPPORT
|
||||
# include "sha512_256.h"
|
||||
@@ -304,10 +304,10 @@ MHD_digest_get_hash_size (enum MHD_DigestAuthAlgo3 algo3)
|
||||
union DigestCtx
|
||||
{
|
||||
#ifdef MHD_MD5_SUPPORT
|
||||
struct Md5Ctx md5_ctx;
|
||||
struct Md5CtxWr md5_ctx;
|
||||
#endif /* MHD_MD5_SUPPORT */
|
||||
#ifdef MHD_SHA256_SUPPORT
|
||||
struct Sha256Ctx sha256_ctx;
|
||||
struct Sha256CtxWr sha256_ctx;
|
||||
#endif /* MHD_SHA256_SUPPORT */
|
||||
#ifdef MHD_SHA512_256_SUPPORT
|
||||
struct Sha512_256Ctx sha512_256_ctx;
|
||||
@@ -334,9 +334,10 @@ struct DigestAlgorithm
|
||||
* Buffer for hex-print of the final digest.
|
||||
*/
|
||||
#if _DEBUG
|
||||
bool setup; /**< The structure was set-up */
|
||||
bool inited; /**< The calculation was initialised */
|
||||
bool hashing; /**< Some data has been hashed, but digest is not yet finalised */
|
||||
bool uninitialised; /**< The structure has been not set-up */
|
||||
bool algo_selected; /**< The algorithm has been selected */
|
||||
bool ready_for_hashing; /**< The structure is ready to hash data */
|
||||
bool hashing; /**< Some data has been hashed, but the digest has not finalised yet */
|
||||
#endif /* _DEBUG */
|
||||
};
|
||||
|
||||
@@ -349,7 +350,8 @@ struct DigestAlgorithm
|
||||
_MHD_static_inline unsigned int
|
||||
digest_get_size (struct DigestAlgorithm *da)
|
||||
{
|
||||
mhd_assert (da->setup);
|
||||
mhd_assert (! da->uninitialised);
|
||||
mhd_assert (da->algo_selected);
|
||||
#ifdef MHD_MD5_SUPPORT
|
||||
if (MHD_DIGEST_BASE_ALGO_MD5 == da->algo)
|
||||
return MD5_DIGEST_SIZE;
|
||||
@@ -367,90 +369,136 @@ digest_get_size (struct DigestAlgorithm *da)
|
||||
}
|
||||
|
||||
|
||||
#if defined(MHD_MD5_HAS_DEINIT) || defined(MHD_SHA256_HAS_DEINIT)
|
||||
/**
|
||||
* Set-up the digest calculation structure.
|
||||
* Indicates presence of digest_deinit() function
|
||||
*/
|
||||
#define MHD_DIGEST_HAS_DEINIT 1
|
||||
#endif /* MHD_MD5_HAS_DEINIT || MHD_SHA256_HAS_DEINIT */
|
||||
|
||||
#ifdef MHD_DIGEST_HAS_DEINIT
|
||||
/**
|
||||
* Zero-initialise digest calculation structure.
|
||||
*
|
||||
* This initialisation is enough to safely call #digest_deinit() only.
|
||||
* To make any real digest calculation, #digest_setup_and_init() must be called.
|
||||
* @param da the digest calculation
|
||||
*/
|
||||
_MHD_static_inline void
|
||||
digest_setup_zero (struct DigestAlgorithm *da)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
da->uninitialised = false;
|
||||
da->algo_selected = false;
|
||||
da->ready_for_hashing = false;
|
||||
da->hashing = false;
|
||||
#endif /* _DEBUG */
|
||||
da->algo = MHD_DIGEST_BASE_ALGO_INVALID;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* De-initialise digest calculation structure.
|
||||
*
|
||||
* This function must be called if #digest_setup_and_init() was called for
|
||||
* @a da.
|
||||
* This function must not be called if @a da was not initialised by
|
||||
* #digest_setup_and_init() or by #digest_setup_zero().
|
||||
* @param da the digest calculation
|
||||
*/
|
||||
_MHD_static_inline void
|
||||
digest_deinit (struct DigestAlgorithm *da)
|
||||
{
|
||||
mhd_assert (! da->uninitialised);
|
||||
#ifdef MHD_MD5_HAS_DEINIT
|
||||
if (MHD_DIGEST_BASE_ALGO_MD5 == da->algo)
|
||||
MHD_MD5_deinit (&da->ctx.md5_ctx);
|
||||
else
|
||||
#endif /* MHD_MD5_HAS_DEINIT */
|
||||
#ifdef MHD_SHA256_HAS_DEINIT
|
||||
if (MHD_DIGEST_BASE_ALGO_SHA256 == da->algo)
|
||||
MHD_SHA256_deinit (&da->ctx.sha256_ctx);
|
||||
else
|
||||
#endif /* MHD_SHA256_HAS_DEINIT */
|
||||
(void) 0;
|
||||
digest_setup_zero (da);
|
||||
}
|
||||
|
||||
|
||||
#else /* ! MHD_DIGEST_HAS_DEINIT */
|
||||
#define digest_setup_zero(da) (void)0
|
||||
#define digest_deinit(da) (void)0
|
||||
#endif /* ! MHD_DIGEST_HAS_DEINIT */
|
||||
|
||||
|
||||
/**
|
||||
* Set-up the digest calculation structure and initialise with initial values.
|
||||
*
|
||||
* If @a da was successfully initialised, #digest_deinit() must be called
|
||||
* after finishing using of the @a da.
|
||||
*
|
||||
* This function must not be called more than once for any @a da.
|
||||
*
|
||||
* @param da the structure to set-up
|
||||
* @param algo the algorithm to use for digest calculation
|
||||
* @return boolean 'true' if successfully set-up,
|
||||
* false otherwise.
|
||||
*/
|
||||
_MHD_static_inline bool
|
||||
digest_setup (struct DigestAlgorithm *da,
|
||||
enum MHD_DigestBaseAlgo algo)
|
||||
digest_init_one_time (struct DigestAlgorithm *da,
|
||||
enum MHD_DigestBaseAlgo algo)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
da->setup = false;
|
||||
da->inited = false;
|
||||
da->uninitialised = false;
|
||||
da->algo_selected = false;
|
||||
da->ready_for_hashing = false;
|
||||
da->hashing = false;
|
||||
#endif /* _DEBUG */
|
||||
if (false
|
||||
#ifdef MHD_MD5_SUPPORT
|
||||
|| (MHD_DIGEST_BASE_ALGO_MD5 == algo)
|
||||
#endif /* MHD_MD5_SUPPORT */
|
||||
#ifdef MHD_SHA256_SUPPORT
|
||||
|| (MHD_DIGEST_BASE_ALGO_SHA256 == algo)
|
||||
#endif /* MHD_SHA256_SUPPORT */
|
||||
#ifdef MHD_SHA512_256_SUPPORT
|
||||
|| (MHD_DIGEST_BASE_ALGO_SHA512_256 == algo)
|
||||
#endif /* MHD_SHA512_256_SUPPORT */
|
||||
)
|
||||
if (MHD_DIGEST_BASE_ALGO_MD5 == algo)
|
||||
{
|
||||
da->algo = algo;
|
||||
da->algo = MHD_DIGEST_BASE_ALGO_MD5;
|
||||
#ifdef _DEBUG
|
||||
da->setup = true;
|
||||
#endif /* _DEBUG */
|
||||
da->algo_selected = true;
|
||||
#endif
|
||||
MHD_MD5_init_one_time (&da->ctx.md5_ctx);
|
||||
#ifdef _DEBUG
|
||||
da->ready_for_hashing = true;
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
return false; /* Bad or unsupported algorithm */
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Initialise/reset the digest calculation structure.
|
||||
* @param da the structure to initialise/reset
|
||||
*/
|
||||
_MHD_static_inline void
|
||||
digest_init (struct DigestAlgorithm *da)
|
||||
{
|
||||
mhd_assert (da->setup);
|
||||
mhd_assert (! da->hashing);
|
||||
mhd_assert (! da->inited);
|
||||
#ifdef MHD_MD5_SUPPORT
|
||||
if (MHD_DIGEST_BASE_ALGO_MD5 == da->algo)
|
||||
{
|
||||
MHD_MD5_init (&da->ctx.md5_ctx);
|
||||
#ifdef _DEBUG
|
||||
da->inited = true;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
#endif /* MHD_MD5_SUPPORT */
|
||||
#ifdef MHD_SHA256_SUPPORT
|
||||
if (MHD_DIGEST_BASE_ALGO_SHA256 == da->algo)
|
||||
if (MHD_DIGEST_BASE_ALGO_SHA256 == algo)
|
||||
{
|
||||
MHD_SHA256_init (&da->ctx.sha256_ctx);
|
||||
da->algo = MHD_DIGEST_BASE_ALGO_SHA256;
|
||||
#ifdef _DEBUG
|
||||
da->inited = true;
|
||||
da->algo_selected = true;
|
||||
#endif
|
||||
MHD_SHA256_init_one_time (&da->ctx.sha256_ctx);
|
||||
#ifdef _DEBUG
|
||||
da->ready_for_hashing = true;
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
else
|
||||
#endif /* MHD_SHA256_SUPPORT */
|
||||
#ifdef MHD_SHA512_256_SUPPORT
|
||||
if (MHD_DIGEST_BASE_ALGO_SHA512_256 == da->algo)
|
||||
if (MHD_DIGEST_BASE_ALGO_SHA512_256 == algo)
|
||||
{
|
||||
da->algo = MHD_DIGEST_BASE_ALGO_SHA512_256;
|
||||
#ifdef _DEBUG
|
||||
da->algo_selected = true;
|
||||
#endif
|
||||
MHD_SHA512_256_init (&da->ctx.sha512_256_ctx);
|
||||
#ifdef _DEBUG
|
||||
da->inited = true;
|
||||
da->ready_for_hashing = true;
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
else
|
||||
#endif /* MHD_SHA512_256_SUPPORT */
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
da->inited = false;
|
||||
#endif
|
||||
mhd_assert (0); /* Bad algorithm */
|
||||
}
|
||||
|
||||
da->algo = MHD_DIGEST_BASE_ALGO_INVALID;
|
||||
return false; /* Unsupported or bad algorithm */
|
||||
}
|
||||
|
||||
|
||||
@@ -465,7 +513,9 @@ digest_update (struct DigestAlgorithm *da,
|
||||
const void *data,
|
||||
size_t length)
|
||||
{
|
||||
mhd_assert (da->inited);
|
||||
mhd_assert (! da->uninitialised);
|
||||
mhd_assert (da->algo_selected);
|
||||
mhd_assert (da->ready_for_hashing);
|
||||
#ifdef MHD_MD5_SUPPORT
|
||||
if (MHD_DIGEST_BASE_ALGO_MD5 == da->algo)
|
||||
MHD_MD5_update (&da->ctx.md5_ctx, (const uint8_t *) data, length);
|
||||
@@ -525,30 +575,160 @@ digest_update_with_colon (struct DigestAlgorithm *da)
|
||||
_MHD_static_inline void
|
||||
digest_calc_hash (struct DigestAlgorithm *da, uint8_t *digest)
|
||||
{
|
||||
mhd_assert (da->inited);
|
||||
mhd_assert (! da->uninitialised);
|
||||
mhd_assert (da->algo_selected);
|
||||
mhd_assert (da->ready_for_hashing);
|
||||
#ifdef MHD_MD5_SUPPORT
|
||||
if (MHD_DIGEST_BASE_ALGO_MD5 == da->algo)
|
||||
{
|
||||
#ifdef MHD_MD5_HAS_FINISH
|
||||
MHD_MD5_finish (&da->ctx.md5_ctx, digest);
|
||||
#ifdef _DEBUG
|
||||
da->ready_for_hashing = false;
|
||||
#endif /* _DEBUG */
|
||||
#else /* ! MHD_MD5_HAS_FINISH */
|
||||
MHD_MD5_finish_reset (&da->ctx.md5_ctx, digest);
|
||||
#ifdef _DEBUG
|
||||
da->ready_for_hashing = true;
|
||||
#endif /* _DEBUG */
|
||||
#endif /* ! MHD_MD5_HAS_FINISH */
|
||||
}
|
||||
else
|
||||
#endif /* MHD_MD5_SUPPORT */
|
||||
#ifdef MHD_SHA256_SUPPORT
|
||||
if (MHD_DIGEST_BASE_ALGO_SHA256 == da->algo)
|
||||
{
|
||||
#ifdef MHD_SHA256_HAS_FINISH
|
||||
MHD_SHA256_finish (&da->ctx.sha256_ctx, digest);
|
||||
#ifdef _DEBUG
|
||||
da->ready_for_hashing = false;
|
||||
#endif /* _DEBUG */
|
||||
#else /* ! MHD_SHA256_HAS_FINISH */
|
||||
MHD_SHA256_finish_reset (&da->ctx.sha256_ctx, digest);
|
||||
#ifdef _DEBUG
|
||||
da->ready_for_hashing = true;
|
||||
#endif /* _DEBUG */
|
||||
#endif /* ! MHD_SHA256_HAS_FINISH */
|
||||
}
|
||||
else
|
||||
#endif /* MHD_SHA256_SUPPORT */
|
||||
#ifdef MHD_SHA512_256_SUPPORT
|
||||
if (MHD_DIGEST_BASE_ALGO_SHA512_256 == da->algo)
|
||||
{
|
||||
MHD_SHA512_256_finish (&da->ctx.sha512_256_ctx, digest);
|
||||
#ifdef _DEBUG
|
||||
da->ready_for_hashing = false;
|
||||
#endif /* _DEBUG */
|
||||
}
|
||||
else
|
||||
#endif /* MHD_SHA512_256_SUPPORT */
|
||||
mhd_assert (0); /* May not happen */
|
||||
mhd_assert (0); /* Should not happen */
|
||||
#ifdef _DEBUG
|
||||
da->hashing = false;
|
||||
da->inited = false;
|
||||
#endif
|
||||
#endif /* _DEBUG */
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Reset the digest calculation structure.
|
||||
*
|
||||
* @param da the structure to reset
|
||||
*/
|
||||
_MHD_static_inline void
|
||||
digest_reset (struct DigestAlgorithm *da)
|
||||
{
|
||||
mhd_assert (! da->uninitialised);
|
||||
mhd_assert (da->algo_selected);
|
||||
mhd_assert (! da->hashing);
|
||||
#ifdef MHD_MD5_SUPPORT
|
||||
if (MHD_DIGEST_BASE_ALGO_MD5 == da->algo)
|
||||
{
|
||||
#ifdef MHD_MD5_HAS_FINISH
|
||||
mhd_assert (! da->ready_for_hashing);
|
||||
#else /* ! MHD_MD5_HAS_FINISH */
|
||||
mhd_assert (da->ready_for_hashing);
|
||||
#endif /* ! MHD_MD5_HAS_FINISH */
|
||||
MHD_MD5_reset (&da->ctx.md5_ctx);
|
||||
#ifdef _DEBUG
|
||||
da->ready_for_hashing = true;
|
||||
#endif /* _DEBUG */
|
||||
}
|
||||
else
|
||||
#endif /* MHD_MD5_SUPPORT */
|
||||
#ifdef MHD_SHA256_SUPPORT
|
||||
if (MHD_DIGEST_BASE_ALGO_SHA256 == da->algo)
|
||||
{
|
||||
#ifdef MHD_SHA256_HAS_FINISH
|
||||
mhd_assert (! da->ready_for_hashing);
|
||||
#else /* ! MHD_SHA256_HAS_FINISH */
|
||||
mhd_assert (da->ready_for_hashing);
|
||||
#endif /* ! MHD_SHA256_HAS_FINISH */
|
||||
MHD_SHA256_reset (&da->ctx.sha256_ctx);
|
||||
#ifdef _DEBUG
|
||||
da->ready_for_hashing = true;
|
||||
#endif /* _DEBUG */
|
||||
}
|
||||
else
|
||||
#endif /* MHD_SHA256_SUPPORT */
|
||||
#ifdef MHD_SHA512_256_SUPPORT
|
||||
if (MHD_DIGEST_BASE_ALGO_SHA512_256 == da->algo)
|
||||
{
|
||||
mhd_assert (! da->ready_for_hashing);
|
||||
MHD_SHA512_256_init (&da->ctx.sha512_256_ctx);
|
||||
#ifdef _DEBUG
|
||||
da->ready_for_hashing = true;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
#endif /* MHD_SHA512_256_SUPPORT */
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
da->ready_for_hashing = false;
|
||||
#endif
|
||||
mhd_assert (0); /* May not happen, bad algorithm */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if defined(MHD_MD5_HAS_EXT_ERROR) || defined(MHD_SHA256_HAS_EXT_ERROR)
|
||||
/**
|
||||
* Indicates that digest algorithm has external error status
|
||||
*/
|
||||
#define MHD_DIGEST_HAS_EXT_ERROR 1
|
||||
#endif /* MHD_MD5_HAS_EXT_ERROR || MHD_SHA256_HAS_EXT_ERROR */
|
||||
|
||||
#ifdef MHD_DIGEST_HAS_EXT_ERROR
|
||||
/**
|
||||
* Get external error code.
|
||||
*
|
||||
* When external digest calculation used, an error may occur during
|
||||
* initialisation or hashing data. This function checks whether external
|
||||
* error has been reported for digest calculation.
|
||||
* @param da the digest calculation
|
||||
* @return true if external error occurs
|
||||
*/
|
||||
_MHD_static_inline bool
|
||||
digest_ext_error (struct DigestAlgorithm *da)
|
||||
{
|
||||
mhd_assert (! da->uninitialised);
|
||||
mhd_assert (da->algo_selected);
|
||||
#ifdef MHD_MD5_HAS_EXT_ERROR
|
||||
if (MHD_DIGEST_BASE_ALGO_MD5 == da->algo)
|
||||
return 0 != da->ctx.md5_ctx.ext_error;
|
||||
#endif /* MHD_MD5_HAS_EXT_ERROR */
|
||||
#ifdef MHD_SHA256_HAS_EXT_ERROR
|
||||
if (MHD_DIGEST_BASE_ALGO_SHA256 == da->algo)
|
||||
return 0 != da->ctx.sha256_ctx.ext_error;
|
||||
#endif /* MHD_MD5_HAS_EXT_ERROR */
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
#else /* ! MHD_DIGEST_HAS_EXT_ERROR */
|
||||
#define digest_ext_error(da) (false)
|
||||
#endif /* ! MHD_DIGEST_HAS_EXT_ERROR */
|
||||
|
||||
|
||||
/**
|
||||
* Extract timestamp from the given nonce.
|
||||
* @param nonce the nonce to check
|
||||
@@ -1314,7 +1494,7 @@ calculate_nonce (uint64_t nonce_time,
|
||||
struct DigestAlgorithm *da,
|
||||
char *nonce)
|
||||
{
|
||||
digest_init (da);
|
||||
mhd_assert (! da->hashing);
|
||||
if (1)
|
||||
{
|
||||
/* Add the timestamp to the hash calculation */
|
||||
@@ -1522,6 +1702,7 @@ calculate_add_nonce (struct MHD_Connection *const connection,
|
||||
const size_t nonce_size = NONCE_STD_LEN (digest_get_size (da));
|
||||
bool ret;
|
||||
|
||||
mhd_assert (! da->hashing);
|
||||
mhd_assert (MAX_DIGEST_NONCE_LENGTH >= nonce_size);
|
||||
mhd_assert (0 != nonce_size);
|
||||
|
||||
@@ -1541,6 +1722,11 @@ calculate_add_nonce (struct MHD_Connection *const connection,
|
||||
da,
|
||||
nonce);
|
||||
|
||||
#ifdef MHD_DIGEST_HAS_EXT_ERROR
|
||||
if (digest_ext_error (da))
|
||||
return false;
|
||||
#endif /* MHD_DIGEST_HAS_EXT_ERROR */
|
||||
|
||||
if (0 == daemon->nonce_nc_size)
|
||||
return false;
|
||||
|
||||
@@ -1589,6 +1775,7 @@ calculate_add_nonce_with_retry (struct MHD_Connection *const connection,
|
||||
{
|
||||
const uint64_t timestamp1 = MHD_monotonic_msec_counter ();
|
||||
const size_t realm_len = strlen (realm);
|
||||
mhd_assert (! da->hashing);
|
||||
|
||||
#ifdef HAVE_MESSAGES
|
||||
if (0 == MHD_get_master (connection->daemon)->digest_auth_rand_size)
|
||||
@@ -1612,6 +1799,10 @@ calculate_add_nonce_with_retry (struct MHD_Connection *const connection,
|
||||
const size_t digest_size = digest_get_size (da);
|
||||
char nonce2[NONCE_STD_LEN (MAX_DIGEST) + 1];
|
||||
uint64_t timestamp2;
|
||||
#ifdef MHD_DIGEST_HAS_EXT_ERROR
|
||||
if (digest_ext_error (da))
|
||||
return false; /* No need to re-try */
|
||||
#endif /* MHD_DIGEST_HAS_EXT_ERROR */
|
||||
if (0 == MHD_get_master (connection->daemon)->nonce_nc_size)
|
||||
return false; /* No need to re-try */
|
||||
|
||||
@@ -1652,6 +1843,7 @@ calculate_add_nonce_with_retry (struct MHD_Connection *const connection,
|
||||
if (timestamp1 == timestamp2)
|
||||
timestamp2 -= 2; /* Fallback value */
|
||||
}
|
||||
digest_reset (da);
|
||||
if (! calculate_add_nonce (connection, timestamp2, realm, realm_len, da,
|
||||
nonce2))
|
||||
{
|
||||
@@ -1690,7 +1882,7 @@ calc_userdigest (struct DigestAlgorithm *da,
|
||||
const char *password,
|
||||
uint8_t *ha1_bin)
|
||||
{
|
||||
digest_init (da);
|
||||
mhd_assert (! da->hashing);
|
||||
digest_update (da, username, username_len);
|
||||
digest_update_with_colon (da);
|
||||
digest_update (da, realm, realm_len);
|
||||
@@ -1725,8 +1917,10 @@ calc_userdigest (struct DigestAlgorithm *da,
|
||||
* userdigest upon return
|
||||
* @param userdigest_bin the size of the @a userdigest_bin buffer, must be
|
||||
* at least #MHD_digest_get_hash_size(algo3) bytes long
|
||||
* @return MHD_YES on success, MHD_NO if @a userdigest_bin is too small or
|
||||
* if @a algo3 algorithm is not supported.
|
||||
* @return MHD_YES on success,
|
||||
* MHD_NO if @a userdigest_bin is too small or if @a algo3 algorithm is
|
||||
* not supported (or external error has occurred,
|
||||
* see #MHD_FEATURE_EXTERN_HASH).
|
||||
* @sa #MHD_digest_auth_check_digest3()
|
||||
* @note Available since #MHD_VERSION 0x00097535
|
||||
* @ingroup authentication
|
||||
@@ -1740,18 +1934,31 @@ MHD_digest_auth_calc_userdigest (enum MHD_DigestAuthAlgo3 algo3,
|
||||
size_t bin_buf_size)
|
||||
{
|
||||
struct DigestAlgorithm da;
|
||||
if (! digest_setup (&da, get_base_digest_algo (algo3)))
|
||||
enum MHD_Result ret;
|
||||
if (! digest_init_one_time (&da, get_base_digest_algo (algo3)))
|
||||
return MHD_NO;
|
||||
|
||||
if (digest_get_size (&da) > bin_buf_size)
|
||||
return MHD_NO;
|
||||
calc_userdigest (&da,
|
||||
username,
|
||||
strlen (username),
|
||||
realm,
|
||||
strlen (realm),
|
||||
password,
|
||||
userdigest_bin);
|
||||
return MHD_YES;
|
||||
ret = MHD_NO;
|
||||
else
|
||||
{
|
||||
calc_userdigest (&da,
|
||||
username,
|
||||
strlen (username),
|
||||
realm,
|
||||
strlen (realm),
|
||||
password,
|
||||
userdigest_bin);
|
||||
ret = MHD_YES;
|
||||
|
||||
#ifdef MHD_DIGEST_HAS_EXT_ERROR
|
||||
if (digest_ext_error (&da))
|
||||
ret = MHD_NO;
|
||||
#endif /* MHD_DIGEST_HAS_EXT_ERROR */
|
||||
}
|
||||
digest_deinit (&da);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -1775,7 +1982,7 @@ calc_userhash (struct DigestAlgorithm *da,
|
||||
uint8_t *digest_bin)
|
||||
{
|
||||
mhd_assert (NULL != username);
|
||||
digest_init (da);
|
||||
mhd_assert (! da->hashing);
|
||||
digest_update (da, username, username_len);
|
||||
digest_update_with_colon (da);
|
||||
digest_update (da, realm, realm_len);
|
||||
@@ -1815,8 +2022,10 @@ calc_userhash (struct DigestAlgorithm *da,
|
||||
* upon return
|
||||
* @param bin_buf_size the size of the @a userhash_bin buffer, must be
|
||||
* at least #MHD_digest_get_hash_size(algo3) bytes long
|
||||
* @return MHD_YES on success, MHD_NO if @a bin_buf_size is too small or
|
||||
* if @a algo3 algorithm is not supported.
|
||||
* @return MHD_YES on success,
|
||||
* MHD_NO if @a bin_buf_size is too small or if @a algo3 algorithm is
|
||||
* not supported (or external error has occurred,
|
||||
* see #MHD_FEATURE_EXTERN_HASH)
|
||||
* @note Available since #MHD_VERSION 0x00097535
|
||||
* @ingroup authentication
|
||||
*/
|
||||
@@ -1828,17 +2037,30 @@ MHD_digest_auth_calc_userhash (enum MHD_DigestAuthAlgo3 algo3,
|
||||
size_t bin_buf_size)
|
||||
{
|
||||
struct DigestAlgorithm da;
|
||||
if (! digest_setup (&da, get_base_digest_algo (algo3)))
|
||||
enum MHD_Result ret;
|
||||
|
||||
if (! digest_init_one_time (&da, get_base_digest_algo (algo3)))
|
||||
return MHD_NO;
|
||||
if (digest_get_size (&da) > bin_buf_size)
|
||||
return MHD_NO;
|
||||
calc_userhash (&da,
|
||||
username,
|
||||
strlen (username),
|
||||
realm,
|
||||
strlen (realm),
|
||||
userhash_bin);
|
||||
return MHD_YES;
|
||||
ret = MHD_NO;
|
||||
else
|
||||
{
|
||||
calc_userhash (&da,
|
||||
username,
|
||||
strlen (username),
|
||||
realm,
|
||||
strlen (realm),
|
||||
userhash_bin);
|
||||
ret = MHD_YES;
|
||||
|
||||
#ifdef MHD_DIGEST_HAS_EXT_ERROR
|
||||
if (digest_ext_error (&da))
|
||||
ret = MHD_NO;
|
||||
#endif /* MHD_DIGEST_HAS_EXT_ERROR */
|
||||
}
|
||||
digest_deinit (&da);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -1874,8 +2096,10 @@ MHD_digest_auth_calc_userhash (enum MHD_DigestAuthAlgo3 algo3,
|
||||
* userhash string
|
||||
* @param bin_buf_size the size of the @a userhash_bin buffer, must be
|
||||
* at least #MHD_digest_get_hash_size(algo3)*2+1 chars long
|
||||
* @return MHD_YES on success, MHD_NO if @a bin_buf_size is too small or
|
||||
* if @a algo3 algorithm is not supported.
|
||||
* @return MHD_YES on success,
|
||||
* MHD_NO if @a bin_buf_size is too small or if @a algo3 algorithm is
|
||||
* not supported (or external error has occurred,
|
||||
* see #MHD_FEATURE_EXTERN_HASH).
|
||||
* @note Available since #MHD_VERSION 0x00097535
|
||||
* @ingroup authentication
|
||||
*/
|
||||
@@ -2302,12 +2526,12 @@ digest_auth_check_all_inner (struct MHD_Connection *connection,
|
||||
uint32_t max_nc,
|
||||
enum MHD_DigestAuthMultiQOP mqop,
|
||||
enum MHD_DigestAuthMultiAlgo3 malgo3,
|
||||
char **pbuf)
|
||||
char **pbuf,
|
||||
struct DigestAlgorithm *da)
|
||||
{
|
||||
struct MHD_Daemon *daemon = MHD_get_master (connection->daemon);
|
||||
enum MHD_DigestAuthAlgo3 c_algo; /**< Client's algorithm */
|
||||
enum MHD_DigestAuthQOP c_qop; /**< Client's QOP */
|
||||
struct DigestAlgorithm da;
|
||||
unsigned int digest_size;
|
||||
uint8_t hash1_bin[MAX_DIGEST];
|
||||
uint8_t hash2_bin[MAX_DIGEST];
|
||||
@@ -2383,7 +2607,7 @@ digest_auth_check_all_inner (struct MHD_Connection *connection,
|
||||
return MHD_DAUTH_WRONG_ALGO;
|
||||
}
|
||||
#endif /* ! MHD_SHA512_256_SUPPORT */
|
||||
if (! digest_setup (&da, get_base_digest_algo (c_algo)))
|
||||
if (! digest_init_one_time (da, get_base_digest_algo (c_algo)))
|
||||
MHD_PANIC (_ ("Wrong 'malgo3' value, API violation"));
|
||||
/* Check 'mqop' value */
|
||||
c_qop = params->qop;
|
||||
@@ -2407,7 +2631,7 @@ digest_auth_check_all_inner (struct MHD_Connection *connection,
|
||||
"non-standard extension.\n"));
|
||||
#endif /* HAVE_MESSAGES */
|
||||
|
||||
digest_size = digest_get_size (&da);
|
||||
digest_size = digest_get_size (da);
|
||||
|
||||
/* ** A quick check for presence of all required parameters ** */
|
||||
|
||||
@@ -2525,11 +2749,18 @@ digest_auth_check_all_inner (struct MHD_Connection *connection,
|
||||
else
|
||||
{ /* Userhash */
|
||||
mhd_assert (NULL != params->username.value.str);
|
||||
calc_userhash (&da, username, username_len, realm, realm_len, hash1_bin);
|
||||
calc_userhash (da, username, username_len, realm, realm_len, hash1_bin);
|
||||
#ifdef MHD_DIGEST_HAS_EXT_ERROR
|
||||
if (digest_ext_error (da))
|
||||
return MHD_DAUTH_ERROR;
|
||||
#endif /* MHD_DIGEST_HAS_EXT_ERROR */
|
||||
mhd_assert (sizeof (tmp1) >= (2 * digest_size));
|
||||
MHD_bin_to_hex (hash1_bin, digest_size, tmp1);
|
||||
if (! is_param_equal_caseless (¶ms->username, tmp1, 2 * digest_size))
|
||||
return MHD_DAUTH_WRONG_USERNAME;
|
||||
/* To simplify the logic, the digest is reset here instead of resetting
|
||||
before the next hash calculation. */
|
||||
digest_reset (da);
|
||||
}
|
||||
/* 'username' valid */
|
||||
|
||||
@@ -2643,9 +2874,9 @@ digest_auth_check_all_inner (struct MHD_Connection *connection,
|
||||
/* ** Build H(A2) and check URI match in the header and in the request ** */
|
||||
|
||||
/* Get 'uri' */
|
||||
digest_init (&da);
|
||||
digest_update_str (&da, connection->rq.method);
|
||||
digest_update_with_colon (&da);
|
||||
mhd_assert (! da->hashing);
|
||||
digest_update_str (da, connection->rq.method);
|
||||
digest_update_with_colon (da);
|
||||
#if 0
|
||||
/* TODO: add support for "auth-int" */
|
||||
digest_update_str (da, hentity);
|
||||
@@ -2656,33 +2887,45 @@ digest_auth_check_all_inner (struct MHD_Connection *connection,
|
||||
if (_MHD_UNQ_OK != unq_res)
|
||||
return MHD_DAUTH_ERROR;
|
||||
|
||||
digest_update (&da, unq_copy.str, unq_copy.len);
|
||||
digest_update (da, unq_copy.str, unq_copy.len);
|
||||
/* The next check will modify copied URI string */
|
||||
if (! check_uri_match (connection, unq_copy.str, unq_copy.len))
|
||||
return MHD_DAUTH_WRONG_URI;
|
||||
digest_calc_hash (&da, hash2_bin);
|
||||
digest_calc_hash (da, hash2_bin);
|
||||
#ifdef MHD_DIGEST_HAS_EXT_ERROR
|
||||
/* Skip digest calculation external error check, the next one checks both */
|
||||
#endif /* MHD_DIGEST_HAS_EXT_ERROR */
|
||||
/* Got H(A2) */
|
||||
|
||||
/* ** Build H(A1) ** */
|
||||
if (NULL == userdigest)
|
||||
calc_userdigest (&da,
|
||||
{
|
||||
mhd_assert (! da->hashing);
|
||||
digest_reset (da);
|
||||
calc_userdigest (da,
|
||||
username, username_len,
|
||||
realm, realm_len,
|
||||
password,
|
||||
hash1_bin);
|
||||
}
|
||||
/* TODO: support '-sess' versions */
|
||||
#ifdef MHD_DIGEST_HAS_EXT_ERROR
|
||||
if (digest_ext_error (da))
|
||||
return MHD_DAUTH_ERROR;
|
||||
#endif /* MHD_DIGEST_HAS_EXT_ERROR */
|
||||
/* Got H(A1) */
|
||||
|
||||
/* ** Check 'response' ** */
|
||||
|
||||
digest_init (&da);
|
||||
mhd_assert (! da->hashing);
|
||||
digest_reset (da);
|
||||
/* Update digest with H(A1) */
|
||||
mhd_assert (sizeof (tmp1) >= (digest_size * 2));
|
||||
if (NULL == userdigest)
|
||||
MHD_bin_to_hex (hash1_bin, digest_size, tmp1);
|
||||
else
|
||||
MHD_bin_to_hex (userdigest, digest_size, tmp1);
|
||||
digest_update (&da, (const uint8_t *) tmp1, digest_size * 2);
|
||||
digest_update (da, (const uint8_t *) tmp1, digest_size * 2);
|
||||
|
||||
/* H(A1) is not needed anymore, reuse the buffer.
|
||||
* Use hash1_bin for the client's 'response' decoded to binary form. */
|
||||
@@ -2694,15 +2937,15 @@ digest_auth_check_all_inner (struct MHD_Connection *connection,
|
||||
return MHD_DAUTH_RESPONSE_WRONG;
|
||||
|
||||
/* Update digest with ':' */
|
||||
digest_update_with_colon (&da);
|
||||
digest_update_with_colon (da);
|
||||
/* Update digest with 'nonce' text value */
|
||||
unq_res = get_unquoted_param (¶ms->nonce, tmp1, ptmp2, &tmp2_size,
|
||||
&unquoted);
|
||||
if (_MHD_UNQ_OK != unq_res)
|
||||
return MHD_DAUTH_ERROR;
|
||||
digest_update (&da, (const uint8_t *) unquoted.str, unquoted.len);
|
||||
digest_update (da, (const uint8_t *) unquoted.str, unquoted.len);
|
||||
/* Update digest with ':' */
|
||||
digest_update_with_colon (&da);
|
||||
digest_update_with_colon (da);
|
||||
if (MHD_DIGEST_AUTH_QOP_NONE != c_qop)
|
||||
{
|
||||
/* Update digest with 'nc' text value */
|
||||
@@ -2710,33 +2953,37 @@ digest_auth_check_all_inner (struct MHD_Connection *connection,
|
||||
&unquoted);
|
||||
if (_MHD_UNQ_OK != unq_res)
|
||||
return MHD_DAUTH_ERROR;
|
||||
digest_update (&da, (const uint8_t *) unquoted.str, unquoted.len);
|
||||
digest_update (da, (const uint8_t *) unquoted.str, unquoted.len);
|
||||
/* Update digest with ':' */
|
||||
digest_update_with_colon (&da);
|
||||
digest_update_with_colon (da);
|
||||
/* Update digest with 'cnonce' value */
|
||||
unq_res = get_unquoted_param (¶ms->cnonce, tmp1, ptmp2, &tmp2_size,
|
||||
&unquoted);
|
||||
if (_MHD_UNQ_OK != unq_res)
|
||||
return MHD_DAUTH_ERROR;
|
||||
digest_update (&da, (const uint8_t *) unquoted.str, unquoted.len);
|
||||
digest_update (da, (const uint8_t *) unquoted.str, unquoted.len);
|
||||
/* Update digest with ':' */
|
||||
digest_update_with_colon (&da);
|
||||
digest_update_with_colon (da);
|
||||
/* Update digest with 'qop' value */
|
||||
unq_res = get_unquoted_param (¶ms->qop_raw, tmp1, ptmp2, &tmp2_size,
|
||||
&unquoted);
|
||||
if (_MHD_UNQ_OK != unq_res)
|
||||
return MHD_DAUTH_ERROR;
|
||||
digest_update (&da, (const uint8_t *) unquoted.str, unquoted.len);
|
||||
digest_update (da, (const uint8_t *) unquoted.str, unquoted.len);
|
||||
/* Update digest with ':' */
|
||||
digest_update_with_colon (&da);
|
||||
digest_update_with_colon (da);
|
||||
}
|
||||
/* Update digest with H(A2) */
|
||||
MHD_bin_to_hex (hash2_bin, digest_size, tmp1);
|
||||
digest_update (&da, (const uint8_t *) tmp1, digest_size * 2);
|
||||
digest_update (da, (const uint8_t *) tmp1, digest_size * 2);
|
||||
|
||||
/* H(A2) is not needed anymore, reuse the buffer.
|
||||
* Use hash2_bin for the calculated response in binary form */
|
||||
digest_calc_hash (&da, hash2_bin);
|
||||
digest_calc_hash (da, hash2_bin);
|
||||
#ifdef MHD_DIGEST_HAS_EXT_ERROR
|
||||
if (digest_ext_error (da))
|
||||
return MHD_DAUTH_ERROR;
|
||||
#endif /* MHD_DIGEST_HAS_EXT_ERROR */
|
||||
|
||||
if (0 != memcmp (hash1_bin, hash2_bin, digest_size))
|
||||
return MHD_DAUTH_RESPONSE_WRONG;
|
||||
@@ -2746,6 +2993,8 @@ digest_auth_check_all_inner (struct MHD_Connection *connection,
|
||||
mhd_assert (sizeof(tmp1) >= (NONCE_STD_LEN (digest_size) + 1));
|
||||
/* It was already checked that 'nonce' (including timestamp) was generated
|
||||
by MHD. */
|
||||
mhd_assert (! da->hashing);
|
||||
digest_reset (da);
|
||||
calculate_nonce (nonce_time,
|
||||
connection->rq.http_mthd,
|
||||
connection->rq.method,
|
||||
@@ -2759,9 +3008,13 @@ digest_auth_check_all_inner (struct MHD_Connection *connection,
|
||||
realm,
|
||||
realm_len,
|
||||
daemon->dauth_bind_type,
|
||||
&da,
|
||||
da,
|
||||
tmp1);
|
||||
|
||||
#ifdef MHD_DIGEST_HAS_EXT_ERROR
|
||||
if (digest_ext_error (da))
|
||||
return MHD_DAUTH_ERROR;
|
||||
#endif /* MHD_DIGEST_HAS_EXT_ERROR */
|
||||
|
||||
if (! is_param_equal (¶ms->nonce, tmp1,
|
||||
NONCE_STD_LEN (digest_size)))
|
||||
@@ -2816,13 +3069,16 @@ digest_auth_check_all (struct MHD_Connection *connection,
|
||||
{
|
||||
enum MHD_DigestAuthResult res;
|
||||
char *buf;
|
||||
struct DigestAlgorithm da;
|
||||
|
||||
buf = NULL;
|
||||
digest_setup_zero (&da);
|
||||
res = digest_auth_check_all_inner (connection, realm, username, password,
|
||||
userdigest,
|
||||
nonce_timeout,
|
||||
max_nc, mqop, malgo3,
|
||||
&buf);
|
||||
&buf, &da);
|
||||
digest_deinit (&da);
|
||||
if (NULL != buf)
|
||||
free (buf);
|
||||
|
||||
@@ -3173,20 +3429,8 @@ MHD_digest_auth_check_digest (struct MHD_Connection *connection,
|
||||
|
||||
|
||||
/**
|
||||
* Queues a response to request authentication from the client
|
||||
*
|
||||
* This function modifies provided @a response. The @a response must not be
|
||||
* reused and should be destroyed (by #MHD_destroy_response()) after call of
|
||||
* this function.
|
||||
*
|
||||
* If @a mqop allows both RFC 2069 (MHD_DIGEST_AUTH_QOP_NONE) and QOP with
|
||||
* value, then response is formed like if MHD_DIGEST_AUTH_QOP_NONE bit was
|
||||
* not set, because such response should be backward-compatible with RFC 2069.
|
||||
*
|
||||
* If @a mqop allows only MHD_DIGEST_AUTH_MULT_QOP_NONE, then the response is
|
||||
* formed in strict accordance with RFC 2069 (no 'qop', no 'userhash', no
|
||||
* 'charset'). For better compatibility with clients, it is recommended (but
|
||||
* not required) to set @a domain to NULL in this mode.
|
||||
* Internal version of #MHD_queue_auth_required_response3() to simplify
|
||||
* cleanups.
|
||||
*
|
||||
* @param connection the MHD connection structure
|
||||
* @param realm the realm presented to the client
|
||||
@@ -3226,21 +3470,26 @@ MHD_digest_auth_check_digest (struct MHD_Connection *connection,
|
||||
* @param prefer_utf8 if not set to #MHD_NO, parameter 'charset=UTF-8' is
|
||||
* added, indicating for the client that UTF-8 encoding
|
||||
* is preferred
|
||||
* @param prefer_utf8 if not set to #MHD_NO, parameter 'charset=UTF-8' is
|
||||
* added, indicating for the client that UTF-8 encoding
|
||||
* is preferred
|
||||
* @return #MHD_YES on success, #MHD_NO otherwise
|
||||
* @note Available since #MHD_VERSION 0x00097526
|
||||
* @ingroup authentication
|
||||
*/
|
||||
_MHD_EXTERN enum MHD_Result
|
||||
MHD_queue_auth_required_response3 (struct MHD_Connection *connection,
|
||||
const char *realm,
|
||||
const char *opaque,
|
||||
const char *domain,
|
||||
struct MHD_Response *response,
|
||||
int signal_stale,
|
||||
enum MHD_DigestAuthMultiQOP mqop,
|
||||
enum MHD_DigestAuthMultiAlgo3 malgo3,
|
||||
int userhash_support,
|
||||
int prefer_utf8)
|
||||
static enum MHD_Result
|
||||
queue_auth_required_response3_inner (struct MHD_Connection *connection,
|
||||
const char *realm,
|
||||
const char *opaque,
|
||||
const char *domain,
|
||||
struct MHD_Response *response,
|
||||
int signal_stale,
|
||||
enum MHD_DigestAuthMultiQOP mqop,
|
||||
enum MHD_DigestAuthMultiAlgo3 malgo3,
|
||||
int userhash_support,
|
||||
int prefer_utf8,
|
||||
char **buf_ptr,
|
||||
struct DigestAlgorithm *da)
|
||||
{
|
||||
static const char prefix_realm[] = "realm=\"";
|
||||
static const char prefix_qop[] = "qop=\"";
|
||||
@@ -3258,7 +3507,6 @@ MHD_queue_auth_required_response3 (struct MHD_Connection *connection,
|
||||
size_t buf_size;
|
||||
char *buf;
|
||||
size_t p; /* The position in the buffer */
|
||||
struct DigestAlgorithm da;
|
||||
|
||||
if (0 != (((unsigned int) malgo3) & MHD_DIGEST_AUTH_ALGO3_SESSION))
|
||||
{
|
||||
@@ -3302,7 +3550,7 @@ MHD_queue_auth_required_response3 (struct MHD_Connection *connection,
|
||||
(((unsigned int) mqop) & MHD_DIGEST_AUTH_MULT_QOP_ANY_NON_INT))
|
||||
MHD_PANIC (_ ("Wrong 'mqop' value, API violation"));
|
||||
|
||||
if (! digest_setup (&da, get_base_digest_algo (s_algo)))
|
||||
if (! digest_init_one_time (da, get_base_digest_algo (s_algo)))
|
||||
MHD_PANIC (_ ("Wrong 'algo' value, API violation"));
|
||||
|
||||
if (MHD_DIGEST_AUTH_MULT_QOP_NONE == mqop)
|
||||
@@ -3348,6 +3596,7 @@ MHD_queue_auth_required_response3 (struct MHD_Connection *connection,
|
||||
if ((NULL != memchr (realm, '\r', realm_len)) ||
|
||||
(NULL != memchr (realm, '\n', realm_len)))
|
||||
return MHD_NO;
|
||||
|
||||
buf_size += realm_len * 2; /* Quoting may double the size */
|
||||
/* 'qop="xxxx", ' */
|
||||
if (MHD_DIGEST_AUTH_MULT_QOP_NONE != mqop)
|
||||
@@ -3379,7 +3628,7 @@ MHD_queue_auth_required_response3 (struct MHD_Connection *connection,
|
||||
}
|
||||
/* 'nonce="xxxx", ' */
|
||||
buf_size += MHD_STATICSTR_LEN_ (prefix_nonce) + 3; /* 3 for '", ' */
|
||||
buf_size += NONCE_STD_LEN (digest_get_size (&da)); /* Escaping not needed */
|
||||
buf_size += NONCE_STD_LEN (digest_get_size (da)); /* Escaping not needed */
|
||||
/* 'opaque="xxxx", ' */
|
||||
if (NULL != opaque)
|
||||
{
|
||||
@@ -3388,6 +3637,7 @@ MHD_queue_auth_required_response3 (struct MHD_Connection *connection,
|
||||
if ((NULL != memchr (opaque, '\r', opaque_len)) ||
|
||||
(NULL != memchr (opaque, '\n', opaque_len)))
|
||||
return MHD_NO;
|
||||
|
||||
buf_size += opaque_len * 2; /* Quoting may double the size */
|
||||
}
|
||||
else
|
||||
@@ -3400,6 +3650,7 @@ MHD_queue_auth_required_response3 (struct MHD_Connection *connection,
|
||||
if ((NULL != memchr (domain, '\r', domain_len)) ||
|
||||
(NULL != memchr (domain, '\n', domain_len)))
|
||||
return MHD_NO;
|
||||
|
||||
buf_size += domain_len * 2; /* Quoting may double the size */
|
||||
}
|
||||
else
|
||||
@@ -3421,6 +3672,7 @@ MHD_queue_auth_required_response3 (struct MHD_Connection *connection,
|
||||
buf = malloc (buf_size);
|
||||
if (NULL == buf)
|
||||
return MHD_NO;
|
||||
*buf_ptr = buf;
|
||||
|
||||
/* Build the challenge string */
|
||||
p = 0;
|
||||
@@ -3444,7 +3696,6 @@ MHD_queue_auth_required_response3 (struct MHD_Connection *connection,
|
||||
MHD_DLOG (connection->daemon,
|
||||
_ ("The 'realm' is too large after 'quoting'.\n"));
|
||||
#endif /* HAVE_MESSAGES */
|
||||
free (buf);
|
||||
return MHD_NO;
|
||||
}
|
||||
p += quoted_size;
|
||||
@@ -3507,9 +3758,20 @@ MHD_queue_auth_required_response3 (struct MHD_Connection *connection,
|
||||
memcpy (buf + p, prefix_nonce,
|
||||
MHD_STATICSTR_LEN_ (prefix_nonce));
|
||||
p += MHD_STATICSTR_LEN_ (prefix_nonce);
|
||||
mhd_assert ((buf_size - p) >= (NONCE_STD_LEN (digest_get_size (&da))));
|
||||
if (! calculate_add_nonce_with_retry (connection, realm, &da, buf + p))
|
||||
mhd_assert ((buf_size - p) >= (NONCE_STD_LEN (digest_get_size (da))));
|
||||
if (! calculate_add_nonce_with_retry (connection, realm, da, buf + p))
|
||||
{
|
||||
#ifdef MHD_DIGEST_HAS_EXT_ERROR
|
||||
if (digest_ext_error (da))
|
||||
{
|
||||
#ifdef HAVE_MESSAGES
|
||||
MHD_DLOG (connection->daemon,
|
||||
_ ("TLS library reported hash calculation error, nonce could "
|
||||
"not be generated.\n"));
|
||||
#endif /* HAVE_MESSAGES */
|
||||
return MHD_NO;
|
||||
}
|
||||
#endif /* MHD_DIGEST_HAS_EXT_ERROR */
|
||||
#ifdef HAVE_MESSAGES
|
||||
MHD_DLOG (connection->daemon,
|
||||
_ ("Could not register nonce. Client's requests with this "
|
||||
@@ -3518,7 +3780,7 @@ MHD_queue_auth_required_response3 (struct MHD_Connection *connection,
|
||||
#endif /* HAVE_MESSAGES */
|
||||
(void) 0; /* Mute compiler warning for builds without messages */
|
||||
}
|
||||
p += NONCE_STD_LEN (digest_get_size (&da));
|
||||
p += NONCE_STD_LEN (digest_get_size (da));
|
||||
buf[p++] = '\"';
|
||||
buf[p++] = ',';
|
||||
buf[p++] = ' ';
|
||||
@@ -3588,15 +3850,108 @@ MHD_queue_auth_required_response3 (struct MHD_Connection *connection,
|
||||
MHD_DLOG (connection->daemon,
|
||||
_ ("Failed to add Digest auth header.\n"));
|
||||
#endif /* HAVE_MESSAGES */
|
||||
free (buf);
|
||||
return MHD_NO;
|
||||
}
|
||||
free (buf);
|
||||
|
||||
return MHD_queue_response (connection, MHD_HTTP_UNAUTHORIZED, response);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Queues a response to request authentication from the client
|
||||
*
|
||||
* This function modifies provided @a response. The @a response must not be
|
||||
* reused and should be destroyed (by #MHD_destroy_response()) after call of
|
||||
* this function.
|
||||
*
|
||||
* If @a mqop allows both RFC 2069 (MHD_DIGEST_AUTH_QOP_NONE) and QOP with
|
||||
* value, then response is formed like if MHD_DIGEST_AUTH_QOP_NONE bit was
|
||||
* not set, because such response should be backward-compatible with RFC 2069.
|
||||
*
|
||||
* If @a mqop allows only MHD_DIGEST_AUTH_MULT_QOP_NONE, then the response is
|
||||
* formed in strict accordance with RFC 2069 (no 'qop', no 'userhash', no
|
||||
* 'charset'). For better compatibility with clients, it is recommended (but
|
||||
* not required) to set @a domain to NULL in this mode.
|
||||
*
|
||||
* @param connection the MHD connection structure
|
||||
* @param realm the realm presented to the client
|
||||
* @param opaque the string for opaque value, can be NULL, but NULL is
|
||||
* not recommended for better compatibility with clients;
|
||||
* the recommended format is hex or Base64 encoded string
|
||||
* @param domain the optional space-separated list of URIs for which the
|
||||
* same authorisation could be used, URIs can be in form
|
||||
* "path-absolute" (the path for the same host with initial slash)
|
||||
* or in form "absolute-URI" (the full path with protocol), in
|
||||
* any case client may assume that URI is in the same "protection
|
||||
* space" if it starts with any of values specified here;
|
||||
* could be NULL (clients typically assume that the same
|
||||
* credentials could be used for any URI on the same host)
|
||||
* @param response the reply to send; should contain the "access denied"
|
||||
* body; note that this function sets the "WWW Authenticate"
|
||||
* header and that the caller should not do this;
|
||||
* the NULL is tolerated
|
||||
* @param signal_stale set to #MHD_YES if the nonce is stale to add 'stale=true'
|
||||
* to the authentication header, this instructs the client
|
||||
* to retry immediately with the new nonce and the same
|
||||
* credentials, without asking user for the new password
|
||||
* @param mqop the QOP to use
|
||||
* @param malgo3 digest algorithm to use, MHD selects; if several algorithms
|
||||
* are allowed then MD5 is preferred (currently, may be changed
|
||||
* in next versions)
|
||||
* @param userhash_support if set to non-zero value (#MHD_YES) then support of
|
||||
* userhash is indicated, the client may provide
|
||||
* hash("username:realm") instead of username in
|
||||
* clear text;
|
||||
* note that clients are allowed to provide the username
|
||||
* in cleartext even if this parameter set to non-zero;
|
||||
* when userhash is used, application must be ready to
|
||||
* identify users by provided userhash value instead of
|
||||
* username; see #MHD_digest_auth_calc_userhash() and
|
||||
* #MHD_digest_auth_calc_userhash_hex()
|
||||
* @param prefer_utf8 if not set to #MHD_NO, parameter 'charset=UTF-8' is
|
||||
* added, indicating for the client that UTF-8 encoding
|
||||
* is preferred
|
||||
* @return #MHD_YES on success, #MHD_NO otherwise
|
||||
* @note Available since #MHD_VERSION 0x00097526
|
||||
* @ingroup authentication
|
||||
*/
|
||||
_MHD_EXTERN enum MHD_Result
|
||||
MHD_queue_auth_required_response3 (struct MHD_Connection *connection,
|
||||
const char *realm,
|
||||
const char *opaque,
|
||||
const char *domain,
|
||||
struct MHD_Response *response,
|
||||
int signal_stale,
|
||||
enum MHD_DigestAuthMultiQOP mqop,
|
||||
enum MHD_DigestAuthMultiAlgo3 malgo3,
|
||||
int userhash_support,
|
||||
int prefer_utf8)
|
||||
{
|
||||
struct DigestAlgorithm da;
|
||||
char *buf_ptr;
|
||||
enum MHD_Result ret;
|
||||
|
||||
buf_ptr = NULL;
|
||||
digest_setup_zero (&da);
|
||||
ret = queue_auth_required_response3_inner (connection,
|
||||
realm,
|
||||
opaque,
|
||||
domain,
|
||||
response,
|
||||
signal_stale,
|
||||
mqop,
|
||||
malgo3,
|
||||
userhash_support,
|
||||
prefer_utf8,
|
||||
&buf_ptr,
|
||||
&da);
|
||||
digest_deinit (&da);
|
||||
if (NULL != buf_ptr)
|
||||
free (buf_ptr);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Queues a response to request authentication from the client
|
||||
*
|
||||
|
||||
@@ -123,4 +123,9 @@ void
|
||||
MHD_MD5_finish (struct Md5Ctx *ctx,
|
||||
uint8_t digest[MD5_DIGEST_SIZE]);
|
||||
|
||||
/**
|
||||
* Indicates that function MHD_MD5_finish() (without context reset) is available
|
||||
*/
|
||||
#define MHD_MD5_HAS_FINISH 1
|
||||
|
||||
#endif /* MHD_MD5_H */
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
This file is part of GNU libmicrohttpd
|
||||
Copyright (C) 2022 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.
|
||||
|
||||
This library 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.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with GNU libmicrohttpd.
|
||||
If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file microhttpd/md5_ext.h
|
||||
* @brief Wrapper for MD5 calculation performed by TLS library
|
||||
* @author Karlson2k (Evgeny Grin)
|
||||
*/
|
||||
|
||||
#include <gnutls/crypto.h>
|
||||
#include "md5_ext.h"
|
||||
#include "mhd_assert.h"
|
||||
|
||||
|
||||
/**
|
||||
* Initialise structure for MD5 calculation, allocate resources.
|
||||
*
|
||||
* This function must not be called more than one time for @a ctx.
|
||||
*
|
||||
* @param ctx the calculation context
|
||||
*/
|
||||
void
|
||||
MHD_MD5_init_one_time (struct Md5CtxExt *ctx)
|
||||
{
|
||||
ctx->handle = NULL;
|
||||
ctx->ext_error = gnutls_hash_init (&ctx->handle, GNUTLS_DIG_MD5);
|
||||
if ((0 != ctx->ext_error) && (NULL != ctx->handle))
|
||||
{
|
||||
gnutls_free (ctx->handle);
|
||||
ctx->handle = NULL;
|
||||
}
|
||||
else
|
||||
mhd_assert (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_MD5_update (struct Md5CtxExt *ctx,
|
||||
const uint8_t *data,
|
||||
size_t length)
|
||||
{
|
||||
if (0 == ctx->ext_error)
|
||||
ctx->ext_error = gnutls_hash (ctx->handle, data, length);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Finalise MD5 calculation, return digest, reset hash calculation.
|
||||
*
|
||||
* @param ctx the calculation context
|
||||
* @param[out] digest set to the hash, must be #MD5_DIGEST_SIZE bytes
|
||||
*/
|
||||
void
|
||||
MHD_MD5_finish_reset (struct Md5CtxExt *ctx,
|
||||
uint8_t digest[MD5_DIGEST_SIZE])
|
||||
{
|
||||
if (0 == ctx->ext_error)
|
||||
gnutls_hash_output (ctx->handle, digest);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Free allocated resources.
|
||||
*
|
||||
* @param ctx the calculation context
|
||||
*/
|
||||
void
|
||||
MHD_MD5_deinit (struct Md5CtxExt *ctx)
|
||||
{
|
||||
if (NULL != ctx->handle)
|
||||
gnutls_hash_deinit (ctx->handle, NULL);
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
This file is part of GNU libmicrohttpd
|
||||
Copyright (C) 2022 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.
|
||||
|
||||
This library 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.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with GNU libmicrohttpd.
|
||||
If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file microhttpd/md5_ext.h
|
||||
* @brief Wrapper declarations for MD5 calculation performed by TLS library
|
||||
* @author Karlson2k (Evgeny Grin)
|
||||
*/
|
||||
|
||||
#ifndef MHD_MD5_EXT_H
|
||||
#define MHD_MD5_EXT_H 1
|
||||
|
||||
#include "mhd_options.h"
|
||||
#include <stdint.h>
|
||||
#ifdef HAVE_STDDEF_H
|
||||
#include <stddef.h> /* for size_t */
|
||||
#endif /* HAVE_STDDEF_H */
|
||||
|
||||
/**
|
||||
* Size of MD5 resulting digest in bytes
|
||||
* This is the final digest size, not intermediate hash.
|
||||
*/
|
||||
#define MD5_DIGEST_SIZE (16)
|
||||
|
||||
/* Actual declaration is in GnuTLS lib header */
|
||||
struct hash_hd_st;
|
||||
|
||||
/**
|
||||
* Indicates that struct Md5CtxExt has 'ext_error'
|
||||
*/
|
||||
#define MHD_MD5_HAS_EXT_ERROR 1
|
||||
|
||||
/**
|
||||
* MD5 calculation context
|
||||
*/
|
||||
struct Md5CtxExt
|
||||
{
|
||||
struct hash_hd_st *handle; /**< Hash calculation handle */
|
||||
int ext_error; /**< Non-zero if external error occurs during init or hashing */
|
||||
};
|
||||
|
||||
/**
|
||||
* Indicates that MHD_MD5_init_one_time() function is present.
|
||||
*/
|
||||
#define MHD_MD5_HAS_INIT_ONE_TIME 1
|
||||
|
||||
/**
|
||||
* Initialise structure for MD5 calculation, allocate resources.
|
||||
*
|
||||
* This function must not be called more than one time for @a ctx.
|
||||
*
|
||||
* @param ctx the calculation context
|
||||
*/
|
||||
void
|
||||
MHD_MD5_init_one_time (struct Md5CtxExt *ctx);
|
||||
|
||||
|
||||
/**
|
||||
* MD5 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_MD5_update (struct Md5CtxExt *ctx,
|
||||
const uint8_t *data,
|
||||
size_t length);
|
||||
|
||||
|
||||
/**
|
||||
* Indicates that MHD_MD5_finish_reset() function is available
|
||||
*/
|
||||
#define MHD_MD5_HAS_FINISH_RESET 1
|
||||
|
||||
/**
|
||||
* Finalise MD5 calculation, return digest, reset hash calculation.
|
||||
*
|
||||
* @param ctx the calculation context
|
||||
* @param[out] digest set to the hash, must be #MD5_DIGEST_SIZE bytes
|
||||
*/
|
||||
void
|
||||
MHD_MD5_finish_reset (struct Md5CtxExt *ctx,
|
||||
uint8_t digest[MD5_DIGEST_SIZE]);
|
||||
|
||||
/**
|
||||
* Indicates that MHD_MD5_deinit() function is present
|
||||
*/
|
||||
#define MHD_MD5_HAS_DEINIT 1
|
||||
|
||||
/**
|
||||
* Free allocated resources.
|
||||
*
|
||||
* @param ctx the calculation context
|
||||
*/
|
||||
void
|
||||
MHD_MD5_deinit (struct Md5CtxExt *ctx);
|
||||
|
||||
#endif /* MHD_MD5_EXT_H */
|
||||
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
This file is part of GNU libmicrohttpd
|
||||
Copyright (C) 2022 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.
|
||||
|
||||
This library 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.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with GNU libmicrohttpd.
|
||||
If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file microhttpd/mhd_md5_wrap.h
|
||||
* @brief Simple wrapper for selection of built-in/external MD5 implementation
|
||||
* @author Karlson2k (Evgeny Grin)
|
||||
*/
|
||||
|
||||
#ifndef MHD_MD5_WRAP_H
|
||||
#define MHD_MD5_WRAP_H 1
|
||||
|
||||
#include "mhd_options.h"
|
||||
#ifndef MHD_MD5_SUPPORT
|
||||
#error This file must be used only when MD5 is enabled
|
||||
#endif
|
||||
#ifndef MHD_MD5_TLSLIB
|
||||
#include "md5.h"
|
||||
#else /* MHD_MD5_TLSLIB */
|
||||
#include "md5_ext.h"
|
||||
#endif /* MHD_MD5_TLSLIB */
|
||||
|
||||
#ifndef MD5_DIGEST_SIZE
|
||||
/**
|
||||
* Size of MD5 resulting digest in bytes
|
||||
* This is the final digest size, not intermediate hash.
|
||||
*/
|
||||
#define MD5_DIGEST_SIZE (16)
|
||||
#endif /* ! MD5_DIGEST_SIZE */
|
||||
|
||||
#ifndef MD5_DIGEST_STRING_SIZE
|
||||
/**
|
||||
* Size of MD5 digest string in chars including termination NUL.
|
||||
*/
|
||||
#define MD5_DIGEST_STRING_SIZE ((MD5_DIGEST_SIZE) * 2 + 1)
|
||||
#endif /* ! MD5_DIGEST_STRING_SIZE */
|
||||
|
||||
#ifndef MHD_MD5_TLSLIB
|
||||
/**
|
||||
* Universal ctx type mapped for chosen implementation
|
||||
*/
|
||||
#define Md5CtxWr Md5Ctx
|
||||
#else /* MHD_MD5_TLSLIB */
|
||||
/**
|
||||
* Universal ctx type mapped for chosen implementation
|
||||
*/
|
||||
#define Md5CtxWr Md5CtxExt
|
||||
#endif /* MHD_MD5_TLSLIB */
|
||||
|
||||
#ifndef MHD_MD5_HAS_INIT_ONE_TIME
|
||||
/**
|
||||
* Setup and prepare ctx for hash calculation
|
||||
*/
|
||||
#define MHD_MD5_init_one_time(ctx) MHD_MD5_init(ctx)
|
||||
#endif /* ! MHD_MD5_HAS_INIT_ONE_TIME */
|
||||
|
||||
#ifndef MHD_MD5_HAS_FINISH_RESET
|
||||
/**
|
||||
* Re-use the same ctx for the new hashing after digest calculated
|
||||
*/
|
||||
#define MHD_MD5_reset(ctx) MHD_MD5_init(ctx)
|
||||
/**
|
||||
* Finalise MD5 calculation, return digest, reset hash calculation.
|
||||
*/
|
||||
#define MHD_MD5_finish_reset(ctx,digest) MHD_MD5_finish(ctx,digest), \
|
||||
MHD_MD5_reset(ctx)
|
||||
|
||||
#else /* MHD_MD5_HAS_FINISH_RESET */
|
||||
#define MHD_MD5_reset(ctx) (void)0
|
||||
#endif /* MHD_MD5_HAS_FINISH_RESET */
|
||||
|
||||
#ifndef MHD_MD5_HAS_DEINIT
|
||||
#define MHD_MD5_deinit(ignore) (void)0
|
||||
#endif /* HAVE_MD5_DEINIT */
|
||||
|
||||
/* Sanity checks */
|
||||
|
||||
#if ! defined(MHD_MD5_HAS_FINISH_RESET) && ! defined(MHD_MD5_HAS_FINISH)
|
||||
#error Required at least one of MHD_MD5_finish_reset(), MHD_MD5_finish_reset()
|
||||
#endif /* ! MHD_MD5_HAS_FINISH_RESET && ! MHD_MD5_HAS_FINISH */
|
||||
|
||||
#endif /* MHD_MD5_WRAP_H */
|
||||
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
This file is part of GNU libmicrohttpd
|
||||
Copyright (C) 2022 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.
|
||||
|
||||
This library 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.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with GNU libmicrohttpd.
|
||||
If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file microhttpd/mhd_sha256_wrap.h
|
||||
* @brief Simple wrapper for selection of built-in/external SHA-256
|
||||
* implementation
|
||||
* @author Karlson2k (Evgeny Grin)
|
||||
*/
|
||||
|
||||
#ifndef MHD_SHA256_WRAP_H
|
||||
#define MHD_SHA256_WRAP_H 1
|
||||
|
||||
#include "mhd_options.h"
|
||||
#include "mhd_options.h"
|
||||
#ifndef MHD_SHA256_SUPPORT
|
||||
#error This file must be used only when SHA-256 is enabled
|
||||
#endif
|
||||
#ifndef MHD_SHA256_TLSLIB
|
||||
#include "sha256.h"
|
||||
#else /* MHD_SHA256_TLSLIB */
|
||||
#include "sha256_ext.h"
|
||||
#endif /* MHD_SHA256_TLSLIB */
|
||||
|
||||
#ifndef SHA256_DIGEST_SIZE
|
||||
/**
|
||||
* Size of SHA-256 resulting digest in bytes
|
||||
* This is the final digest size, not intermediate hash.
|
||||
*/
|
||||
#define SHA256_DIGEST_SIZE (32)
|
||||
#endif /* ! SHA256_DIGEST_SIZE */
|
||||
|
||||
#ifndef SHA256_DIGEST_STRING_SIZE
|
||||
/**
|
||||
* Size of MD5 digest string in chars including termination NUL.
|
||||
*/
|
||||
#define SHA256_DIGEST_STRING_SIZE ((SHA256_DIGEST_SIZE) * 2 + 1)
|
||||
#endif /* ! SHA256_DIGEST_STRING_SIZE */
|
||||
|
||||
#ifndef MHD_SHA256_TLSLIB
|
||||
/**
|
||||
* Universal ctx type mapped for chosen implementation
|
||||
*/
|
||||
#define Sha256CtxWr Sha256Ctx
|
||||
#else /* MHD_SHA256_TLSLIB */
|
||||
/**
|
||||
* Universal ctx type mapped for chosen implementation
|
||||
*/
|
||||
#define Sha256CtxWr Sha256CtxExt
|
||||
#endif /* MHD_SHA256_TLSLIB */
|
||||
|
||||
#ifndef MHD_SHA256_HAS_INIT_ONE_TIME
|
||||
/**
|
||||
* Setup and prepare ctx for hash calculation
|
||||
*/
|
||||
#define MHD_SHA256_init_one_time(ctx) MHD_SHA256_init(ctx)
|
||||
#endif /* ! MHD_SHA256_HAS_INIT_ONE_TIME */
|
||||
|
||||
#ifndef MHD_SHA256_HAS_FINISH_RESET
|
||||
/**
|
||||
* Re-use the same ctx for the new hashing after digest calculated
|
||||
*/
|
||||
#define MHD_SHA256_reset(ctx) MHD_SHA256_init(ctx)
|
||||
/**
|
||||
* Finalise MD5 calculation, return digest, reset hash calculation.
|
||||
*/
|
||||
#define MHD_SHA256_finish_reset(ctx,digest) MHD_SHA256_finish(ctx,digest), \
|
||||
MHD_SHA256_reset(ctx)
|
||||
|
||||
#else /* MHD_SHA256_HAS_FINISH_RESET */
|
||||
#define MHD_SHA256_reset(ctx) (void)0
|
||||
#endif /* MHD_SHA256_HAS_FINISH_RESET */
|
||||
|
||||
#ifndef MHD_SHA256_HAS_DEINIT
|
||||
#define MHD_SHA256_deinit(ignore) (void)0
|
||||
#endif /* HAVE_SHA256_DEINIT */
|
||||
|
||||
/* Sanity checks */
|
||||
|
||||
#if ! defined(MHD_SHA256_HAS_FINISH_RESET) && ! defined(MHD_SHA256_HAS_FINISH)
|
||||
#error Required MHD_SHA256_finish_reset() or MHD_SHA256_finish_reset()
|
||||
#endif /* ! MHD_SHA256_HAS_FINISH_RESET && ! MHD_SHA256_HAS_FINISH */
|
||||
|
||||
#endif /* MHD_SHA256_WRAP_H */
|
||||
@@ -114,4 +114,9 @@ void
|
||||
MHD_SHA256_finish (struct Sha256Ctx *ctx,
|
||||
uint8_t digest[SHA256_DIGEST_SIZE]);
|
||||
|
||||
/**
|
||||
* Indicates that function MHD_SHA256_finish() (without context reset) is available
|
||||
*/
|
||||
#define MHD_SHA256_HAS_FINISH 1
|
||||
|
||||
#endif /* MHD_SHA256_H */
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
This file is part of GNU libmicrohttpd
|
||||
Copyright (C) 2022 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.
|
||||
|
||||
This library 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.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with GNU libmicrohttpd.
|
||||
If not, see <http://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 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_free (ctx->handle);
|
||||
ctx->handle = NULL;
|
||||
}
|
||||
else
|
||||
mhd_assert (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 Sha256CtxExt *ctx,
|
||||
const uint8_t *data,
|
||||
size_t length)
|
||||
{
|
||||
if (0 == ctx->ext_error)
|
||||
ctx->ext_error = gnutls_hash (ctx->handle, data, length);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Finalise SHA-256 calculation, return digest, reset hash calculation.
|
||||
*
|
||||
* @param ctx the calculation context
|
||||
* @param[out] digest set to the hash, must be #SHA256_DIGEST_SIZE bytes
|
||||
*/
|
||||
void
|
||||
MHD_SHA256_finish_reset (struct Sha256CtxExt *ctx,
|
||||
uint8_t digest[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 Sha256CtxExt *ctx)
|
||||
{
|
||||
if (NULL != ctx->handle)
|
||||
gnutls_hash_deinit (ctx->handle, NULL);
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
This file is part of GNU libmicrohttpd
|
||||
Copyright (C) 2022 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.
|
||||
|
||||
This library 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.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with GNU libmicrohttpd.
|
||||
If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file microhttpd/sha256_ext.h
|
||||
* @brief Wrapper declarations for SHA-256 calculation performed by TLS library
|
||||
* @author Karlson2k (Evgeny Grin)
|
||||
*/
|
||||
|
||||
#ifndef MHD_SHA256_EXT_H
|
||||
#define MHD_SHA256_EXT_H 1
|
||||
|
||||
#include "mhd_options.h"
|
||||
#include <stdint.h>
|
||||
#ifdef HAVE_STDDEF_H
|
||||
#include <stddef.h> /* for size_t */
|
||||
#endif /* HAVE_STDDEF_H */
|
||||
|
||||
/**
|
||||
* Size of SHA-256 resulting digest in bytes
|
||||
* This is the final digest size, not intermediate hash.
|
||||
*/
|
||||
#define SHA256_DIGEST_SIZE (32)
|
||||
|
||||
/* Actual declaration is in GnuTLS lib header */
|
||||
struct hash_hd_st;
|
||||
|
||||
/**
|
||||
* Indicates that struct Sha256CtxExt has 'ext_error'
|
||||
*/
|
||||
#define MHD_SHA256_HAS_EXT_ERROR 1
|
||||
|
||||
/**
|
||||
* SHA-256 calculation context
|
||||
*/
|
||||
struct Sha256CtxExt
|
||||
{
|
||||
struct hash_hd_st *handle; /**< Hash calculation handle */
|
||||
int ext_error; /**< Non-zero if external error occurs during init or hashing */
|
||||
};
|
||||
|
||||
/**
|
||||
* Indicates that MHD_SHA256_init_one_time() function is present.
|
||||
*/
|
||||
#define MHD_SHA256_HAS_INIT_ONE_TIME 1
|
||||
|
||||
/**
|
||||
* 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 Sha256CtxExt *ctx);
|
||||
|
||||
|
||||
/**
|
||||
* SHA-256 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 Sha256CtxExt *ctx,
|
||||
const uint8_t *data,
|
||||
size_t length);
|
||||
|
||||
|
||||
/**
|
||||
* Indicates that MHD_SHA256_finish_reset() function is available
|
||||
*/
|
||||
#define MHD_SHA256_HAS_FINISH_RESET 1
|
||||
|
||||
/**
|
||||
* Finalise SHA-256 calculation, return digest, reset hash calculation.
|
||||
*
|
||||
* @param ctx the calculation context
|
||||
* @param[out] digest set to the hash, must be #SHA256_DIGEST_SIZE bytes
|
||||
*/
|
||||
void
|
||||
MHD_SHA256_finish_reset (struct Sha256CtxExt *ctx,
|
||||
uint8_t digest[SHA256_DIGEST_SIZE]);
|
||||
|
||||
/**
|
||||
* Indicates that MHD_SHA256_deinit() function is present
|
||||
*/
|
||||
#define MHD_SHA256_HAS_DEINIT 1
|
||||
|
||||
/**
|
||||
* Free allocated resources.
|
||||
*
|
||||
* @param ctx the calculation context
|
||||
*/
|
||||
void
|
||||
MHD_SHA256_deinit (struct Sha256CtxExt *ctx);
|
||||
|
||||
#endif /* MHD_SHA256_EXT_H */
|
||||
@@ -23,12 +23,19 @@
|
||||
* @author Karlson2k (Evgeny Grin)
|
||||
*/
|
||||
|
||||
#include "mhd_options.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "microhttpd.h"
|
||||
#include "test_helpers.h"
|
||||
|
||||
#if defined(MHD_HTTPS_REQUIRE_GCRYPT) && \
|
||||
(defined(MHD_SHA256_TLSLIB) || defined(MHD_MD5_TLSLIB))
|
||||
#define NEED_GCRYP_INIT 1
|
||||
#include <gcrypt.h>
|
||||
#endif /* MHD_HTTPS_REQUIRE_GCRYPT && (MHD_SHA256_TLSLIB || MHD_MD5_TLSLIB) */
|
||||
|
||||
static int verbose = 1; /* verbose level (0-1)*/
|
||||
|
||||
/* Declarations and data */
|
||||
@@ -619,6 +626,13 @@ main (int argc, char *argv[])
|
||||
if (has_param (argc, argv, "-s") || has_param (argc, argv, "--silent"))
|
||||
verbose = 0;
|
||||
|
||||
#ifdef NEED_GCRYP_INIT
|
||||
gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
|
||||
#ifdef GCRYCTL_INITIALIZATION_FINISHED
|
||||
gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
|
||||
#endif /* GCRYCTL_INITIALIZATION_FINISHED */
|
||||
#endif /* NEED_GCRYP_INIT */
|
||||
|
||||
if (MHD_is_feature_supported (MHD_FEATURE_DIGEST_AUTH_MD5))
|
||||
num_failed += test_md5 ();
|
||||
num_failed += test_md5_failure ();
|
||||
|
||||
@@ -26,9 +26,16 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "mhd_options.h"
|
||||
#include "microhttpd.h"
|
||||
#include "test_helpers.h"
|
||||
|
||||
#if defined(MHD_HTTPS_REQUIRE_GCRYPT) && \
|
||||
(defined(MHD_SHA256_TLSLIB) || defined(MHD_MD5_TLSLIB))
|
||||
#define NEED_GCRYP_INIT 1
|
||||
#include <gcrypt.h>
|
||||
#endif /* MHD_HTTPS_REQUIRE_GCRYPT && (MHD_SHA256_TLSLIB || MHD_MD5_TLSLIB) */
|
||||
|
||||
static int verbose = 1; /* verbose level (0-1)*/
|
||||
|
||||
/* Declarations and data */
|
||||
@@ -748,6 +755,13 @@ main (int argc, char *argv[])
|
||||
if (has_param (argc, argv, "-s") || has_param (argc, argv, "--silent"))
|
||||
verbose = 0;
|
||||
|
||||
#ifdef NEED_GCRYP_INIT
|
||||
gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
|
||||
#ifdef GCRYCTL_INITIALIZATION_FINISHED
|
||||
gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
|
||||
#endif /* GCRYCTL_INITIALIZATION_FINISHED */
|
||||
#endif /* NEED_GCRYP_INIT */
|
||||
|
||||
if (MHD_is_feature_supported (MHD_FEATURE_DIGEST_AUTH_MD5))
|
||||
num_failed += test_md5 ();
|
||||
num_failed += test_md5_failure ();
|
||||
|
||||
+76
-19
@@ -24,11 +24,16 @@
|
||||
*/
|
||||
|
||||
#include "mhd_options.h"
|
||||
#include "md5.h"
|
||||
#include "mhd_md5_wrap.h"
|
||||
#include "test_helpers.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#if defined(MHD_MD5_TLSLIB) && defined(MHD_HTTPS_REQUIRE_GCRYPT)
|
||||
#define NEED_GCRYP_INIT 1
|
||||
#include <gcrypt.h>
|
||||
#endif /* MHD_MD5_TLSLIB && MHD_HTTPS_REQUIRE_GCRYPT */
|
||||
|
||||
static int verbose = 0; /* verbose level (0-1)*/
|
||||
|
||||
|
||||
@@ -293,9 +298,9 @@ check_result (const char *test_name,
|
||||
{
|
||||
char calc_str[MD5_DIGEST_STRING_SIZE];
|
||||
bin2hex (calculated, MD5_DIGEST_SIZE, calc_str);
|
||||
printf (
|
||||
"PASSED: %s check %u: calculated digest %s match expected digest.\n",
|
||||
test_name, check_num, calc_str);
|
||||
printf ("PASSED: %s check %u: calculated digest %s "
|
||||
"matches expected digest.\n",
|
||||
test_name, check_num, calc_str);
|
||||
fflush (stdout);
|
||||
}
|
||||
return failed ? 1 : 0;
|
||||
@@ -312,19 +317,28 @@ test1_str (void)
|
||||
{
|
||||
unsigned int i;
|
||||
int num_failed = 0;
|
||||
struct Md5Ctx ctx;
|
||||
struct Md5CtxWr ctx;
|
||||
|
||||
MHD_MD5_init_one_time (&ctx);
|
||||
|
||||
for (i = 0; i < units1_num; i++)
|
||||
{
|
||||
uint8_t digest[MD5_DIGEST_SIZE];
|
||||
|
||||
MHD_MD5_init (&ctx);
|
||||
MHD_MD5_update (&ctx, (const uint8_t *) data_units1[i].str_l.str,
|
||||
data_units1[i].str_l.len);
|
||||
MHD_MD5_finish (&ctx, digest);
|
||||
MHD_MD5_finish_reset (&ctx, digest);
|
||||
#ifdef MHD_MD5_HAS_EXT_ERROR
|
||||
if (0 != ctx.ext_error)
|
||||
{
|
||||
fprintf (stderr, "External hashing error: %d.\n", ctx.ext_error);
|
||||
exit (99);
|
||||
}
|
||||
#endif
|
||||
num_failed += check_result (__FUNCTION__, i, digest,
|
||||
data_units1[i].digest);
|
||||
}
|
||||
MHD_MD5_deinit (&ctx);
|
||||
return num_failed;
|
||||
}
|
||||
|
||||
@@ -334,18 +348,27 @@ test1_bin (void)
|
||||
{
|
||||
unsigned int i;
|
||||
int num_failed = 0;
|
||||
struct Md5Ctx ctx;
|
||||
struct Md5CtxWr ctx;
|
||||
|
||||
MHD_MD5_init_one_time (&ctx);
|
||||
|
||||
for (i = 0; i < units2_num; i++)
|
||||
{
|
||||
uint8_t digest[MD5_DIGEST_SIZE];
|
||||
|
||||
MHD_MD5_init (&ctx);
|
||||
MHD_MD5_update (&ctx, data_units2[i].bin_l.bin, data_units2[i].bin_l.len);
|
||||
MHD_MD5_finish (&ctx, digest);
|
||||
MHD_MD5_finish_reset (&ctx, digest);
|
||||
#ifdef MHD_MD5_HAS_EXT_ERROR
|
||||
if (0 != ctx.ext_error)
|
||||
{
|
||||
fprintf (stderr, "External hashing error: %d.\n", ctx.ext_error);
|
||||
exit (99);
|
||||
}
|
||||
#endif
|
||||
num_failed += check_result (__FUNCTION__, i, digest,
|
||||
data_units2[i].digest);
|
||||
}
|
||||
MHD_MD5_deinit (&ctx);
|
||||
return num_failed;
|
||||
}
|
||||
|
||||
@@ -356,24 +379,33 @@ test2_str (void)
|
||||
{
|
||||
unsigned int i;
|
||||
int num_failed = 0;
|
||||
struct Md5Ctx ctx;
|
||||
struct Md5CtxWr ctx;
|
||||
|
||||
MHD_MD5_init_one_time (&ctx);
|
||||
|
||||
for (i = 0; i < units1_num; i++)
|
||||
{
|
||||
uint8_t digest[MD5_DIGEST_SIZE];
|
||||
size_t part_s = data_units1[i].str_l.len / 4;
|
||||
|
||||
MHD_MD5_init (&ctx);
|
||||
MHD_MD5_update (&ctx, (const uint8_t *) "", 0);
|
||||
MHD_MD5_update (&ctx, (const uint8_t *) data_units1[i].str_l.str, part_s);
|
||||
MHD_MD5_update (&ctx, (const uint8_t *) "", 0);
|
||||
MHD_MD5_update (&ctx, (const uint8_t *) data_units1[i].str_l.str + part_s,
|
||||
data_units1[i].str_l.len - part_s);
|
||||
MHD_MD5_update (&ctx, (const uint8_t *) "", 0);
|
||||
MHD_MD5_finish (&ctx, digest);
|
||||
MHD_MD5_finish_reset (&ctx, digest);
|
||||
#ifdef MHD_MD5_HAS_EXT_ERROR
|
||||
if (0 != ctx.ext_error)
|
||||
{
|
||||
fprintf (stderr, "External hashing error: %d.\n", ctx.ext_error);
|
||||
exit (99);
|
||||
}
|
||||
#endif
|
||||
num_failed += check_result (__FUNCTION__, i, digest,
|
||||
data_units1[i].digest);
|
||||
}
|
||||
MHD_MD5_deinit (&ctx);
|
||||
return num_failed;
|
||||
}
|
||||
|
||||
@@ -383,22 +415,31 @@ test2_bin (void)
|
||||
{
|
||||
unsigned int i;
|
||||
int num_failed = 0;
|
||||
struct Md5Ctx ctx;
|
||||
struct Md5CtxWr ctx;
|
||||
|
||||
MHD_MD5_init_one_time (&ctx);
|
||||
|
||||
for (i = 0; i < units2_num; i++)
|
||||
{
|
||||
uint8_t digest[MD5_DIGEST_SIZE];
|
||||
size_t part_s = data_units2[i].bin_l.len * 2 / 3;
|
||||
|
||||
MHD_MD5_init (&ctx);
|
||||
MHD_MD5_update (&ctx, data_units2[i].bin_l.bin, part_s);
|
||||
MHD_MD5_update (&ctx, (const uint8_t *) "", 0);
|
||||
MHD_MD5_update (&ctx, data_units2[i].bin_l.bin + part_s,
|
||||
data_units2[i].bin_l.len - part_s);
|
||||
MHD_MD5_finish (&ctx, digest);
|
||||
MHD_MD5_finish_reset (&ctx, digest);
|
||||
#ifdef MHD_MD5_HAS_EXT_ERROR
|
||||
if (0 != ctx.ext_error)
|
||||
{
|
||||
fprintf (stderr, "External hashing error: %d.\n", ctx.ext_error);
|
||||
exit (99);
|
||||
}
|
||||
#endif
|
||||
num_failed += check_result (__FUNCTION__, i, digest,
|
||||
data_units2[i].digest);
|
||||
}
|
||||
MHD_MD5_deinit (&ctx);
|
||||
return num_failed;
|
||||
}
|
||||
|
||||
@@ -414,7 +455,7 @@ test_unaligned (void)
|
||||
unsigned int offset;
|
||||
uint8_t *buf;
|
||||
uint8_t *digest_buf;
|
||||
struct Md5Ctx ctx;
|
||||
struct Md5CtxWr ctx;
|
||||
|
||||
const struct data_unit2 *const tdata = data_units2 + DATA_POS;
|
||||
|
||||
@@ -423,6 +464,8 @@ test_unaligned (void)
|
||||
if ((NULL == buf) || (NULL == digest_buf))
|
||||
exit (99);
|
||||
|
||||
MHD_MD5_init_one_time (&ctx);
|
||||
|
||||
for (offset = MAX_OFFSET; offset >= 1; --offset)
|
||||
{
|
||||
uint8_t *unaligned_digest;
|
||||
@@ -433,12 +476,19 @@ test_unaligned (void)
|
||||
unaligned_digest = digest_buf + MAX_OFFSET - offset;
|
||||
memset (unaligned_digest, 0, MD5_DIGEST_SIZE);
|
||||
|
||||
MHD_MD5_init (&ctx);
|
||||
MHD_MD5_update (&ctx, unaligned_buf, tdata->bin_l.len);
|
||||
MHD_MD5_finish (&ctx, unaligned_digest);
|
||||
MHD_MD5_finish_reset (&ctx, unaligned_digest);
|
||||
#ifdef MHD_MD5_HAS_EXT_ERROR
|
||||
if (0 != ctx.ext_error)
|
||||
{
|
||||
fprintf (stderr, "External hashing error: %d.\n", ctx.ext_error);
|
||||
exit (99);
|
||||
}
|
||||
#endif
|
||||
num_failed += check_result (__FUNCTION__, MAX_OFFSET - offset,
|
||||
unaligned_digest, tdata->digest);
|
||||
}
|
||||
MHD_MD5_deinit (&ctx);
|
||||
free (digest_buf);
|
||||
free (buf);
|
||||
return num_failed;
|
||||
@@ -453,6 +503,13 @@ main (int argc, char *argv[])
|
||||
if (has_param (argc, argv, "-v") || has_param (argc, argv, "--verbose"))
|
||||
verbose = 1;
|
||||
|
||||
#ifdef NEED_GCRYP_INIT
|
||||
gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
|
||||
#ifdef GCRYCTL_INITIALIZATION_FINISHED
|
||||
gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
|
||||
#endif /* GCRYCTL_INITIALIZATION_FINISHED */
|
||||
#endif /* NEED_GCRYP_INIT */
|
||||
|
||||
num_failed += test1_str ();
|
||||
num_failed += test1_bin ();
|
||||
|
||||
|
||||
@@ -24,11 +24,16 @@
|
||||
*/
|
||||
|
||||
#include "mhd_options.h"
|
||||
#include "sha256.h"
|
||||
#include "mhd_sha256_wrap.h"
|
||||
#include "test_helpers.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#if defined(MHD_SHA256_TLSLIB) && defined(MHD_HTTPS_REQUIRE_GCRYPT)
|
||||
#define NEED_GCRYP_INIT 1
|
||||
#include <gcrypt.h>
|
||||
#endif /* MHD_SHA256_TLSLIB && MHD_HTTPS_REQUIRE_GCRYPT */
|
||||
|
||||
static int verbose = 0; /* verbose level (0-1)*/
|
||||
|
||||
|
||||
@@ -320,9 +325,9 @@ check_result (const char *test_name,
|
||||
{
|
||||
char calc_str[SHA256_DIGEST_STRING_SIZE];
|
||||
bin2hex (calculated, SHA256_DIGEST_SIZE, calc_str);
|
||||
printf (
|
||||
"PASSED: %s check %u: calculated digest %s matches expected digest.\n",
|
||||
test_name, check_num, calc_str);
|
||||
printf ("PASSED: %s check %u: calculated digest %s "
|
||||
"matches expected digest.\n",
|
||||
test_name, check_num, calc_str);
|
||||
fflush (stdout);
|
||||
}
|
||||
return failed ? 1 : 0;
|
||||
@@ -339,19 +344,27 @@ test1_str (void)
|
||||
{
|
||||
int num_failed = 0;
|
||||
unsigned int i;
|
||||
struct Sha256Ctx ctx;
|
||||
struct Sha256CtxWr ctx;
|
||||
|
||||
MHD_SHA256_init_one_time (&ctx);
|
||||
for (i = 0; i < units1_num; i++)
|
||||
{
|
||||
uint8_t digest[SHA256_DIGEST_SIZE];
|
||||
|
||||
MHD_SHA256_init (&ctx);
|
||||
MHD_SHA256_update (&ctx, (const uint8_t *) data_units1[i].str_l.str,
|
||||
data_units1[i].str_l.len);
|
||||
MHD_SHA256_finish (&ctx, digest);
|
||||
MHD_SHA256_finish_reset (&ctx, digest);
|
||||
#ifdef MHD_SHA256_HAS_EXT_ERROR
|
||||
if (0 != ctx.ext_error)
|
||||
{
|
||||
fprintf (stderr, "External hashing error: %d.\n", ctx.ext_error);
|
||||
exit (99);
|
||||
}
|
||||
#endif /* MHD_SHA256_HAS_EXT_ERROR */
|
||||
num_failed += check_result (__FUNCTION__, i, digest,
|
||||
data_units1[i].digest);
|
||||
}
|
||||
MHD_SHA256_deinit (&ctx);
|
||||
return num_failed;
|
||||
}
|
||||
|
||||
@@ -361,19 +374,27 @@ test1_bin (void)
|
||||
{
|
||||
int num_failed = 0;
|
||||
unsigned int i;
|
||||
struct Sha256Ctx ctx;
|
||||
struct Sha256CtxWr ctx;
|
||||
|
||||
MHD_SHA256_init_one_time (&ctx);
|
||||
for (i = 0; i < units2_num; i++)
|
||||
{
|
||||
uint8_t digest[SHA256_DIGEST_SIZE];
|
||||
|
||||
MHD_SHA256_init (&ctx);
|
||||
MHD_SHA256_update (&ctx, data_units2[i].bin_l.bin,
|
||||
data_units2[i].bin_l.len);
|
||||
MHD_SHA256_finish (&ctx, digest);
|
||||
MHD_SHA256_finish_reset (&ctx, digest);
|
||||
#ifdef MHD_SHA256_HAS_EXT_ERROR
|
||||
if (0 != ctx.ext_error)
|
||||
{
|
||||
fprintf (stderr, "External hashing error: %d.\n", ctx.ext_error);
|
||||
exit (99);
|
||||
}
|
||||
#endif /* MHD_SHA256_HAS_EXT_ERROR */
|
||||
num_failed += check_result (__FUNCTION__, i, digest,
|
||||
data_units2[i].digest);
|
||||
}
|
||||
MHD_SHA256_deinit (&ctx);
|
||||
return num_failed;
|
||||
}
|
||||
|
||||
@@ -384,14 +405,14 @@ test2_str (void)
|
||||
{
|
||||
int num_failed = 0;
|
||||
unsigned int i;
|
||||
struct Sha256Ctx ctx;
|
||||
struct Sha256CtxWr ctx;
|
||||
|
||||
MHD_SHA256_init_one_time (&ctx);
|
||||
for (i = 0; i < units1_num; i++)
|
||||
{
|
||||
uint8_t digest[SHA256_DIGEST_SIZE];
|
||||
size_t part_s = data_units1[i].str_l.len / 4;
|
||||
|
||||
MHD_SHA256_init (&ctx);
|
||||
MHD_SHA256_update (&ctx, (const uint8_t *) "", 0);
|
||||
MHD_SHA256_update (&ctx, (const uint8_t *) data_units1[i].str_l.str,
|
||||
part_s);
|
||||
@@ -400,10 +421,18 @@ test2_str (void)
|
||||
+ part_s,
|
||||
data_units1[i].str_l.len - part_s);
|
||||
MHD_SHA256_update (&ctx, (const uint8_t *) "", 0);
|
||||
MHD_SHA256_finish (&ctx, digest);
|
||||
MHD_SHA256_finish_reset (&ctx, digest);
|
||||
#ifdef MHD_SHA256_HAS_EXT_ERROR
|
||||
if (0 != ctx.ext_error)
|
||||
{
|
||||
fprintf (stderr, "External hashing error: %d.\n", ctx.ext_error);
|
||||
exit (99);
|
||||
}
|
||||
#endif /* MHD_SHA256_HAS_EXT_ERROR */
|
||||
num_failed += check_result (__FUNCTION__, i, digest,
|
||||
data_units1[i].digest);
|
||||
}
|
||||
MHD_SHA256_deinit (&ctx);
|
||||
return num_failed;
|
||||
}
|
||||
|
||||
@@ -413,22 +442,30 @@ test2_bin (void)
|
||||
{
|
||||
int num_failed = 0;
|
||||
unsigned int i;
|
||||
struct Sha256Ctx ctx;
|
||||
struct Sha256CtxWr ctx;
|
||||
|
||||
MHD_SHA256_init_one_time (&ctx);
|
||||
for (i = 0; i < units2_num; i++)
|
||||
{
|
||||
uint8_t digest[SHA256_DIGEST_SIZE];
|
||||
size_t part_s = data_units2[i].bin_l.len * 2 / 3;
|
||||
|
||||
MHD_SHA256_init (&ctx);
|
||||
MHD_SHA256_update (&ctx, data_units2[i].bin_l.bin, part_s);
|
||||
MHD_SHA256_update (&ctx, (const uint8_t *) "", 0);
|
||||
MHD_SHA256_update (&ctx, data_units2[i].bin_l.bin + part_s,
|
||||
data_units2[i].bin_l.len - part_s);
|
||||
MHD_SHA256_finish (&ctx, digest);
|
||||
MHD_SHA256_finish_reset (&ctx, digest);
|
||||
#ifdef MHD_SHA256_HAS_EXT_ERROR
|
||||
if (0 != ctx.ext_error)
|
||||
{
|
||||
fprintf (stderr, "External hashing error: %d.\n", ctx.ext_error);
|
||||
exit (99);
|
||||
}
|
||||
#endif /* MHD_SHA256_HAS_EXT_ERROR */
|
||||
num_failed += check_result (__FUNCTION__, i, digest,
|
||||
data_units2[i].digest);
|
||||
}
|
||||
MHD_SHA256_deinit (&ctx);
|
||||
return num_failed;
|
||||
}
|
||||
|
||||
@@ -444,10 +481,11 @@ test_unaligned (void)
|
||||
unsigned int offset;
|
||||
uint8_t *buf;
|
||||
uint8_t *digest_buf;
|
||||
struct Sha256Ctx ctx;
|
||||
struct Sha256CtxWr ctx;
|
||||
|
||||
const struct data_unit2 *const tdata = data_units2 + DATA_POS;
|
||||
|
||||
MHD_SHA256_init_one_time (&ctx);
|
||||
buf = malloc (tdata->bin_l.len + MAX_OFFSET);
|
||||
digest_buf = malloc (SHA256_DIGEST_SIZE + MAX_OFFSET);
|
||||
if ((NULL == buf) || (NULL == digest_buf))
|
||||
@@ -463,14 +501,21 @@ test_unaligned (void)
|
||||
unaligned_digest = digest_buf + MAX_OFFSET - offset;
|
||||
memset (unaligned_digest, 0, SHA256_DIGEST_SIZE);
|
||||
|
||||
MHD_SHA256_init (&ctx);
|
||||
MHD_SHA256_update (&ctx, unaligned_buf, tdata->bin_l.len);
|
||||
MHD_SHA256_finish (&ctx, unaligned_digest);
|
||||
MHD_SHA256_finish_reset (&ctx, unaligned_digest);
|
||||
#ifdef MHD_SHA256_HAS_EXT_ERROR
|
||||
if (0 != ctx.ext_error)
|
||||
{
|
||||
fprintf (stderr, "External hashing error: %d.\n", ctx.ext_error);
|
||||
exit (99);
|
||||
}
|
||||
#endif /* MHD_SHA256_HAS_EXT_ERROR */
|
||||
num_failed += check_result (__FUNCTION__, MAX_OFFSET - offset,
|
||||
unaligned_digest, tdata->digest);
|
||||
}
|
||||
free (digest_buf);
|
||||
free (buf);
|
||||
MHD_SHA256_deinit (&ctx);
|
||||
return num_failed;
|
||||
}
|
||||
|
||||
@@ -483,6 +528,13 @@ main (int argc, char *argv[])
|
||||
if (has_param (argc, argv, "-v") || has_param (argc, argv, "--verbose"))
|
||||
verbose = 1;
|
||||
|
||||
#ifdef NEED_GCRYP_INIT
|
||||
gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
|
||||
#ifdef GCRYCTL_INITIALIZATION_FINISHED
|
||||
gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
|
||||
#endif /* GCRYCTL_INITIALIZATION_FINISHED */
|
||||
#endif /* NEED_GCRYP_INIT */
|
||||
|
||||
num_failed += test1_str ();
|
||||
num_failed += test1_bin ();
|
||||
|
||||
|
||||
@@ -26,18 +26,19 @@
|
||||
* @author Karlson2k (Evgeny Grin)
|
||||
*/
|
||||
|
||||
#include "MHD_config.h"
|
||||
#include "mhd_options.h"
|
||||
#include "platform.h"
|
||||
#include <curl/curl.h>
|
||||
#include <microhttpd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#ifdef MHD_HTTPS_REQUIRE_GCRYPT
|
||||
#ifdef HAVE_GCRYPT_H
|
||||
|
||||
#if defined(MHD_HTTPS_REQUIRE_GCRYPT) && \
|
||||
(defined(MHD_SHA256_TLSLIB) || defined(MHD_MD5_TLSLIB))
|
||||
#define NEED_GCRYP_INIT 1
|
||||
#include <gcrypt.h>
|
||||
#endif
|
||||
#endif /* MHD_HTTPS_REQUIRE_GCRYPT */
|
||||
#endif /* MHD_HTTPS_REQUIRE_GCRYPT && (MHD_SHA256_TLSLIB || MHD_MD5_TLSLIB) */
|
||||
|
||||
#ifndef WINDOWS
|
||||
#include <sys/socket.h>
|
||||
@@ -491,14 +492,12 @@ main (int argc, char *const *argv)
|
||||
unsigned int errorCount = 0;
|
||||
(void) argc; (void) argv; /* Unused. Silent compiler warning. */
|
||||
|
||||
#ifdef MHD_HTTPS_REQUIRE_GCRYPT
|
||||
#ifdef HAVE_GCRYPT_H
|
||||
#ifdef NEED_GCRYP_INIT
|
||||
gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
|
||||
#ifdef GCRYCTL_INITIALIZATION_FINISHED
|
||||
gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
|
||||
#endif
|
||||
#endif
|
||||
#endif /* MHD_HTTPS_REQUIRE_GCRYPT */
|
||||
#endif /* GCRYCTL_INITIALIZATION_FINISHED */
|
||||
#endif /* NEED_GCRYP_INIT */
|
||||
if (0 != curl_global_init (CURL_GLOBAL_WIN32))
|
||||
return 2;
|
||||
errorCount += testDigestAuth ();
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
* @author Karlson2k (Evgeny Grin)
|
||||
*/
|
||||
|
||||
#include "MHD_config.h"
|
||||
#include "mhd_options.h"
|
||||
#include "platform.h"
|
||||
#include <curl/curl.h>
|
||||
#include <microhttpd.h>
|
||||
@@ -33,6 +33,12 @@
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#if defined(MHD_HTTPS_REQUIRE_GCRYPT) && \
|
||||
(defined(MHD_SHA256_TLSLIB) || defined(MHD_MD5_TLSLIB))
|
||||
#define NEED_GCRYP_INIT 1
|
||||
#include <gcrypt.h>
|
||||
#endif /* MHD_HTTPS_REQUIRE_GCRYPT && (MHD_SHA256_TLSLIB || MHD_MD5_TLSLIB) */
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <sys/socket.h>
|
||||
#include <unistd.h>
|
||||
@@ -1464,6 +1470,12 @@ main (int argc, char *const *argv)
|
||||
int curl_sspi;
|
||||
(void) argc; (void) argv; /* Unused. Silent compiler warning. */
|
||||
|
||||
#ifdef NEED_GCRYP_INIT
|
||||
gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
|
||||
#ifdef GCRYCTL_INITIALIZATION_FINISHED
|
||||
gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
|
||||
#endif /* GCRYCTL_INITIALIZATION_FINISHED */
|
||||
#endif /* NEED_GCRYP_INIT */
|
||||
/* Test type and test parameters */
|
||||
verbose = ! (has_param (argc, argv, "-q") ||
|
||||
has_param (argc, argv, "--quiet") ||
|
||||
|
||||
@@ -26,18 +26,18 @@
|
||||
* @author Karlson2k (Evgeny Grin)
|
||||
*/
|
||||
|
||||
#include "MHD_config.h"
|
||||
#include "mhd_options.h"
|
||||
#include "platform.h"
|
||||
#include <curl/curl.h>
|
||||
#include <microhttpd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#ifdef MHD_HTTPS_REQUIRE_GCRYPT
|
||||
#ifdef HAVE_GCRYPT_H
|
||||
#if defined(MHD_HTTPS_REQUIRE_GCRYPT) && \
|
||||
(defined(MHD_SHA256_TLSLIB) || defined(MHD_MD5_TLSLIB))
|
||||
#define NEED_GCRYP_INIT 1
|
||||
#include <gcrypt.h>
|
||||
#endif
|
||||
#endif /* MHD_HTTPS_REQUIRE_GCRYPT */
|
||||
#endif /* MHD_HTTPS_REQUIRE_GCRYPT && (MHD_SHA256_TLSLIB || MHD_MD5_TLSLIB) */
|
||||
|
||||
#ifndef WINDOWS
|
||||
#include <sys/socket.h>
|
||||
@@ -669,14 +669,12 @@ main (int argc, char *const *argv)
|
||||
has_param (argc, argv, "-s") ||
|
||||
has_param (argc, argv, "--silent"));
|
||||
|
||||
#ifdef MHD_HTTPS_REQUIRE_GCRYPT
|
||||
#ifdef HAVE_GCRYPT_H
|
||||
#ifdef NEED_GCRYP_INIT
|
||||
gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
|
||||
#ifdef GCRYCTL_INITIALIZATION_FINISHED
|
||||
gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
|
||||
#endif
|
||||
#endif
|
||||
#endif /* MHD_HTTPS_REQUIRE_GCRYPT */
|
||||
#endif /* GCRYCTL_INITIALIZATION_FINISHED */
|
||||
#endif /* NEED_GCRYP_INIT */
|
||||
if (0 != curl_global_init (CURL_GLOBAL_WIN32))
|
||||
return 2;
|
||||
errorCount += testDigestAuth ();
|
||||
|
||||
@@ -27,18 +27,19 @@
|
||||
* @author Karlson2k (Evgeny Grin)
|
||||
*/
|
||||
|
||||
#include "MHD_config.h"
|
||||
#include "mhd_options.h"
|
||||
#include "platform.h"
|
||||
#include <curl/curl.h>
|
||||
#include <microhttpd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#ifdef MHD_HTTPS_REQUIRE_GCRYPT
|
||||
#ifdef HAVE_GCRYPT_H
|
||||
|
||||
#if defined(MHD_HTTPS_REQUIRE_GCRYPT) && \
|
||||
(defined(MHD_SHA256_TLSLIB) || defined(MHD_MD5_TLSLIB))
|
||||
#define NEED_GCRYP_INIT 1
|
||||
#include <gcrypt.h>
|
||||
#endif
|
||||
#endif /* MHD_HTTPS_REQUIRE_GCRYPT */
|
||||
#endif /* MHD_HTTPS_REQUIRE_GCRYPT && (MHD_SHA256_TLSLIB || MHD_MD5_TLSLIB) */
|
||||
|
||||
#ifndef WINDOWS
|
||||
#include <sys/socket.h>
|
||||
@@ -320,14 +321,12 @@ main (int argc, char *const *argv)
|
||||
/* curl added SHA256 support in 7.57 = 7.0x39 */
|
||||
if (d->version_num < 0x073900)
|
||||
return 77; /* skip test, curl is too old */
|
||||
#ifdef MHD_HTTPS_REQUIRE_GCRYPT
|
||||
#ifdef HAVE_GCRYPT_H
|
||||
#ifdef NEED_GCRYP_INIT
|
||||
gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
|
||||
#ifdef GCRYCTL_INITIALIZATION_FINISHED
|
||||
gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
|
||||
#endif
|
||||
#endif
|
||||
#endif /* MHD_HTTPS_REQUIRE_GCRYPT */
|
||||
#endif /* GCRYCTL_INITIALIZATION_FINISHED */
|
||||
#endif /* NEED_GCRYP_INIT */
|
||||
if (0 != curl_global_init (CURL_GLOBAL_WIN32))
|
||||
return 2;
|
||||
errorCount += testDigestAuth ();
|
||||
|
||||
@@ -25,18 +25,19 @@
|
||||
* @author Amr Ali
|
||||
* @author Karlson2k (Evgeny Grin)
|
||||
*/
|
||||
#include "MHD_config.h"
|
||||
#include "mhd_options.h"
|
||||
#include "platform.h"
|
||||
#include <curl/curl.h>
|
||||
#include <microhttpd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#ifdef MHD_HTTPS_REQUIRE_GCRYPT
|
||||
#ifdef HAVE_GCRYPT_H
|
||||
|
||||
#if defined(MHD_HTTPS_REQUIRE_GCRYPT) && \
|
||||
(defined(MHD_SHA256_TLSLIB) || defined(MHD_MD5_TLSLIB))
|
||||
#define NEED_GCRYP_INIT 1
|
||||
#include <gcrypt.h>
|
||||
#endif
|
||||
#endif /* MHD_HTTPS_REQUIRE_GCRYPT */
|
||||
#endif /* MHD_HTTPS_REQUIRE_GCRYPT && (MHD_SHA256_TLSLIB || MHD_MD5_TLSLIB) */
|
||||
|
||||
#ifndef WINDOWS
|
||||
#include <sys/socket.h>
|
||||
|
||||
@@ -74,6 +74,12 @@
|
||||
/* Enable digest Auth support */
|
||||
#define DAUTH_SUPPORT 1
|
||||
|
||||
/* Enable MD5 hashing support. */
|
||||
#define MHD_MD5_SUPPORT 1
|
||||
|
||||
/* Enable SHA-256 hashing support. */
|
||||
#define MHD_SHA256_SUPPORT 1
|
||||
|
||||
/* Enable postprocessor.c */
|
||||
#define HAVE_POSTPROCESSOR 1
|
||||
|
||||
|
||||
@@ -38,7 +38,9 @@
|
||||
<ClInclude Include="$(MhdSrc)microhttpd\digestauth.h" />
|
||||
<ClInclude Include="$(MhdSrc)microhttpd\gen_auth.h" />
|
||||
<ClInclude Include="$(MhdSrc)microhttpd\internal.h" />
|
||||
<ClInclude Include="$(MhdSrc)microhttpd\mhd_md5_wrap.h" />
|
||||
<ClInclude Include="$(MhdSrc)microhttpd\md5.h" />
|
||||
<ClInclude Include="$(MhdSrc)microhttpd\mhd_sha256_wrap.h" />
|
||||
<ClInclude Include="$(MhdSrc)microhttpd\sha256.h" />
|
||||
<ClInclude Include="$(MhdSrc)microhttpd\memorypool.h" />
|
||||
<ClInclude Include="$(MhdSrc)microhttpd\mhd_assert.h" />
|
||||
|
||||
@@ -58,9 +58,15 @@
|
||||
<ClInclude Include="$(MhdSrc)microhttpd\internal.h">
|
||||
<Filter>Internal Headers</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="$(MhdSrc)microhttpd\mhd_md5_wrap.h">
|
||||
<Filter>Internal Headers</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="$(MhdSrc)microhttpd\md5.h">
|
||||
<Filter>Internal Headers</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="$(MhdSrc)microhttpd\mhd_sha256_wrap.h">
|
||||
<Filter>Internal Headers</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="$(MhdSrc)microhttpd\sha256.h">
|
||||
<Filter>Internal Headers</Filter>
|
||||
</ClInclude>
|
||||
|
||||
Reference in New Issue
Block a user