aboutsummaryrefslogtreecommitdiff
path: root/src/microhttpd/digestauth.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/microhttpd/digestauth.c')
-rw-r--r--src/microhttpd/digestauth.c333
1 files changed, 288 insertions, 45 deletions
diff --git a/src/microhttpd/digestauth.c b/src/microhttpd/digestauth.c
index a6792930..1155e6ff 100644
--- a/src/microhttpd/digestauth.c
+++ b/src/microhttpd/digestauth.c
@@ -33,8 +33,15 @@
33#include "mhd_limits.h" 33#include "mhd_limits.h"
34#include "internal.h" 34#include "internal.h"
35#include "response.h" 35#include "response.h"
36#include "md5.h" 36#ifdef MHD_MD5_SUPPORT
37#include "sha256.h" 37# include "md5.h"
38#endif /* MHD_MD5_SUPPORT */
39#ifdef MHD_SHA256_SUPPORT
40# include "sha256.h"
41#endif /* MHD_SHA256_SUPPORT */
42#ifdef MHD_SHA512_256_SUPPORT
43# include "sha512_256.h"
44#endif /* MHD_SHA512_256_SUPPORT */
38#include "mhd_locks.h" 45#include "mhd_locks.h"
39#include "mhd_mono_clock.h" 46#include "mhd_mono_clock.h"
40#include "mhd_str.h" 47#include "mhd_str.h"
@@ -86,6 +93,18 @@
86 ((digest_size) * 2 + TIMESTAMP_CHARS_LEN) 93 ((digest_size) * 2 + TIMESTAMP_CHARS_LEN)
87 94
88 95
96#ifdef MHD_SHA512_256_SUPPORT
97/**
98 * Maximum size of any digest hash supported by MHD.
99 * (SHA-512/256 > MD5).
100 */
101#define MAX_DIGEST SHA512_256_DIGEST_SIZE
102
103/**
104 * The common size of SHA-256 digest and SHA-512/256 digest
105 */
106#define SHA256_SHA512_256_DIGEST_SIZE SHA512_256_DIGEST_SIZE
107#elif defined(MHD_SHA256_SUPPORT)
89/** 108/**
90 * Maximum size of any digest hash supported by MHD. 109 * Maximum size of any digest hash supported by MHD.
91 * (SHA-256 > MD5). 110 * (SHA-256 > MD5).
@@ -93,6 +112,20 @@
93#define MAX_DIGEST SHA256_DIGEST_SIZE 112#define MAX_DIGEST SHA256_DIGEST_SIZE
94 113
95/** 114/**
115 * The common size of SHA-256 digest and SHA-512/256 digest
116 */
117#define SHA256_SHA512_256_DIGEST_SIZE SHA256_DIGEST_SIZE
118#elif defined(MHD_MD5_SUPPORT)
119/**
120 * Maximum size of any digest hash supported by MHD.
121 */
122#define MAX_DIGEST MD5_DIGEST_SIZE
123#else /* ! MHD_MD5_SUPPORT */
124#error At least one hashing algorithm must be enabled
125#endif /* ! MHD_MD5_SUPPORT */
126
127
128/**
96 * Macro to avoid using VLAs if the compiler does not support them. 129 * Macro to avoid using VLAs if the compiler does not support them.
97 */ 130 */
98#ifndef HAVE_C_VARARRAYS 131#ifndef HAVE_C_VARARRAYS
@@ -193,26 +226,54 @@ get_base_digest_algo (enum MHD_DigestAuthAlgo3 algo3)
193 * Internal inline version. 226 * Internal inline version.
194 * @param algo3 the algorithm to check 227 * @param algo3 the algorithm to check
195 * @return the size of the digest or zero if the input value is not 228 * @return the size of the digest or zero if the input value is not
196 * recognised/valid 229 * supported/valid
197 */ 230 */
198_MHD_static_inline size_t 231_MHD_static_inline size_t
199digest_get_hash_size (enum MHD_DigestAuthAlgo3 algo3) 232digest_get_hash_size (enum MHD_DigestAuthAlgo3 algo3)
200{ 233{
234#ifdef MHD_MD5_SUPPORT
201 mhd_assert (MHD_MD5_DIGEST_SIZE == MD5_DIGEST_SIZE); 235 mhd_assert (MHD_MD5_DIGEST_SIZE == MD5_DIGEST_SIZE);
236#endif /* MHD_MD5_SUPPORT */
237#ifdef MHD_SHA256_SUPPORT
202 mhd_assert (MHD_SHA256_DIGEST_SIZE == SHA256_DIGEST_SIZE); 238 mhd_assert (MHD_SHA256_DIGEST_SIZE == SHA256_DIGEST_SIZE);
203 /* Both MD5 and SHA-256 must not be specified at the same time */ 239#endif /* MHD_SHA256_SUPPORT */
204 mhd_assert ( (0 == (((unsigned int) algo3) \ 240#ifdef MHD_SHA512_256_SUPPORT
205 & ((unsigned int) MHD_DIGEST_BASE_ALGO_MD5))) || \ 241 mhd_assert (MHD_SHA512_256_DIGEST_SIZE == SHA512_256_DIGEST_SIZE);
206 (0 == (((unsigned int) algo3) \ 242#ifdef MHD_SHA256_SUPPORT
207 & ((unsigned int) MHD_DIGEST_BASE_ALGO_SHA256))) ); 243 mhd_assert (SHA256_DIGEST_SIZE == SHA512_256_DIGEST_SIZE);
244#endif /* MHD_SHA256_SUPPORT */
245#endif /* MHD_SHA512_256_SUPPORT */
246 /* Only one algorithm must be specified */
247 mhd_assert (1 == \
248 (((0 != (algo3 & MHD_DIGEST_BASE_ALGO_MD5)) ? 1 : 0) \
249 + ((0 != (algo3 & MHD_DIGEST_BASE_ALGO_SHA256)) ? 1 : 0) \
250 + ((0 != (algo3 & MHD_DIGEST_BASE_ALGO_SHA512_256)) ? 1 : 0)));
251#ifdef MHD_MD5_SUPPORT
208 if (0 != (((unsigned int) algo3) 252 if (0 != (((unsigned int) algo3)
209 & ((unsigned int) MHD_DIGEST_BASE_ALGO_MD5))) 253 & ((unsigned int) MHD_DIGEST_BASE_ALGO_MD5)))
210 return MHD_MD5_DIGEST_SIZE; 254 return MHD_MD5_DIGEST_SIZE;
211 else if (0 != (((unsigned int) algo3) 255 else
212 & ((unsigned int) MHD_DIGEST_BASE_ALGO_SHA256))) 256#endif /* MHD_MD5_SUPPORT */
257#if defined(MHD_SHA256_SUPPORT) && defined(MHD_SHA512_256_SUPPORT)
258 if (0 != (((unsigned int) algo3)
259 & ( ((unsigned int) MHD_DIGEST_BASE_ALGO_SHA256)
260 | ((unsigned int) MHD_DIGEST_BASE_ALGO_SHA512_256))))
261 return MHD_SHA256_DIGEST_SIZE; /* The same as SHA512_256_DIGEST_SIZE */
262 else
263#elif defined(MHD_SHA256_SUPPORT)
264 if (0 != (((unsigned int) algo3)
265 & ((unsigned int) MHD_DIGEST_BASE_ALGO_SHA256)))
213 return MHD_SHA256_DIGEST_SIZE; 266 return MHD_SHA256_DIGEST_SIZE;
267 else
268#elif defined(MHD_SHA512_256_SUPPORT)
269 if (0 != (((unsigned int) algo3)
270 & ((unsigned int) MHD_DIGEST_BASE_ALGO_SHA512_256)))
271 return MHD_SHA512_256_DIGEST_SIZE;
272 else
273#endif /* MHD_SHA512_256_SUPPORT */
274 (void) 0; /* Unsupported algorithm */
214 275
215 return 0; /* Wrong input */ 276 return 0; /* Wrong input or unsupported algorithm */
216} 277}
217 278
218 279
@@ -223,8 +284,8 @@ digest_get_hash_size (enum MHD_DigestAuthAlgo3 algo3)
223 * and other parameters which size depends on used hash algorithm. 284 * and other parameters which size depends on used hash algorithm.
224 * @param algo3 the algorithm to check 285 * @param algo3 the algorithm to check
225 * @return the size of the digest (either #MHD_MD5_DIGEST_SIZE or 286 * @return the size of the digest (either #MHD_MD5_DIGEST_SIZE or
226 * #MHD_SHA256_DIGEST_SIZE) or zero if the input value is not 287 * #MHD_SHA256_DIGEST_SIZE/MHD_SHA512_256_DIGEST_SIZE)
227 * recognised/valid 288 * or zero if the input value is not supported or not valid
228 * @sa #MHD_digest_auth_calc_userdigest() 289 * @sa #MHD_digest_auth_calc_userdigest()
229 * @sa #MHD_digest_auth_calc_userhash(), #MHD_digest_auth_calc_userhash_hex() 290 * @sa #MHD_digest_auth_calc_userhash(), #MHD_digest_auth_calc_userhash_hex()
230 * @note Available since #MHD_VERSION 0x00097526 291 * @note Available since #MHD_VERSION 0x00097526
@@ -242,8 +303,15 @@ MHD_digest_get_hash_size (enum MHD_DigestAuthAlgo3 algo3)
242 */ 303 */
243union DigestCtx 304union DigestCtx
244{ 305{
306#ifdef MHD_MD5_SUPPORT
245 struct MD5Context md5_ctx; 307 struct MD5Context md5_ctx;
308#endif /* MHD_MD5_SUPPORT */
309#ifdef MHD_SHA256_SUPPORT
246 struct Sha256Ctx sha256_ctx; 310 struct Sha256Ctx sha256_ctx;
311#endif /* MHD_SHA256_SUPPORT */
312#ifdef MHD_SHA512_256_SUPPORT
313 struct Sha512_256Ctx sha512_256_ctx;
314#endif /* MHD_SHA512_256_SUPPORT */
247}; 315};
248 316
249/** 317/**
@@ -282,10 +350,18 @@ _MHD_static_inline unsigned int
282digest_get_size (struct DigestAlgorithm *da) 350digest_get_size (struct DigestAlgorithm *da)
283{ 351{
284 mhd_assert (da->setup); 352 mhd_assert (da->setup);
353#ifdef MHD_MD5_SUPPORT
285 if (MHD_DIGEST_BASE_ALGO_MD5 == da->algo) 354 if (MHD_DIGEST_BASE_ALGO_MD5 == da->algo)
286 return MD5_DIGEST_SIZE; 355 return MD5_DIGEST_SIZE;
356#endif /* MHD_MD5_SUPPORT */
357#ifdef MHD_SHA256_SUPPORT
287 if (MHD_DIGEST_BASE_ALGO_SHA256 == da->algo) 358 if (MHD_DIGEST_BASE_ALGO_SHA256 == da->algo)
288 return SHA256_DIGEST_SIZE; 359 return SHA256_DIGEST_SIZE;
360#endif /* MHD_SHA256_SUPPORT */
361#ifdef MHD_SHA512_256_SUPPORT
362 if (MHD_DIGEST_BASE_ALGO_SHA512_256 == da->algo)
363 return SHA512_256_DIGEST_SIZE;
364#endif /* MHD_SHA512_256_SUPPORT */
289 mhd_assert (0); /* May not happen */ 365 mhd_assert (0); /* May not happen */
290 return 0; 366 return 0;
291} 367}
@@ -307,8 +383,17 @@ digest_setup (struct DigestAlgorithm *da,
307 da->inited = false; 383 da->inited = false;
308 da->digest_calculated = false; 384 da->digest_calculated = false;
309#endif /* _DEBUG */ 385#endif /* _DEBUG */
310 if ((MHD_DIGEST_BASE_ALGO_MD5 == algo) || 386 if (false
311 (MHD_DIGEST_BASE_ALGO_SHA256 == algo)) 387#ifdef MHD_MD5_SUPPORT
388 || (MHD_DIGEST_BASE_ALGO_MD5 == algo)
389#endif /* MHD_MD5_SUPPORT */
390#ifdef MHD_SHA256_SUPPORT
391 || (MHD_DIGEST_BASE_ALGO_SHA256 == algo)
392#endif /* MHD_SHA256_SUPPORT */
393#ifdef MHD_SHA512_256_SUPPORT
394 || (MHD_DIGEST_BASE_ALGO_SHA512_256 == algo)
395#endif /* MHD_SHA512_256_SUPPORT */
396 )
312 { 397 {
313 da->algo = algo; 398 da->algo = algo;
314#ifdef _DEBUG 399#ifdef _DEBUG
@@ -316,8 +401,7 @@ digest_setup (struct DigestAlgorithm *da,
316#endif /* _DEBUG */ 401#endif /* _DEBUG */
317 return true; 402 return true;
318 } 403 }
319 mhd_assert (0); /* Bad parameter */ 404 return false; /* Bad or unsupported algorithm */
320 return false;
321} 405}
322 406
323 407
@@ -332,6 +416,7 @@ digest_init (struct DigestAlgorithm *da)
332#ifdef _DEBUG 416#ifdef _DEBUG
333 da->digest_calculated = false; 417 da->digest_calculated = false;
334#endif 418#endif
419#ifdef MHD_MD5_SUPPORT
335 if (MHD_DIGEST_BASE_ALGO_MD5 == da->algo) 420 if (MHD_DIGEST_BASE_ALGO_MD5 == da->algo)
336 { 421 {
337 MHD_MD5Init (&da->ctx.md5_ctx); 422 MHD_MD5Init (&da->ctx.md5_ctx);
@@ -339,7 +424,10 @@ digest_init (struct DigestAlgorithm *da)
339 da->inited = true; 424 da->inited = true;
340#endif 425#endif
341 } 426 }
342 else if (MHD_DIGEST_BASE_ALGO_SHA256 == da->algo) 427 else
428#endif /* MHD_MD5_SUPPORT */
429#ifdef MHD_SHA256_SUPPORT
430 if (MHD_DIGEST_BASE_ALGO_SHA256 == da->algo)
343 { 431 {
344 MHD_SHA256_init (&da->ctx.sha256_ctx); 432 MHD_SHA256_init (&da->ctx.sha256_ctx);
345#ifdef _DEBUG 433#ifdef _DEBUG
@@ -347,6 +435,17 @@ digest_init (struct DigestAlgorithm *da)
347#endif 435#endif
348 } 436 }
349 else 437 else
438#endif /* MHD_SHA256_SUPPORT */
439#ifdef MHD_SHA512_256_SUPPORT
440 if (MHD_DIGEST_BASE_ALGO_SHA512_256 == da->algo)
441 {
442 MHD_SHA512_256_init (&da->ctx.sha512_256_ctx);
443#ifdef _DEBUG
444 da->inited = true;
445#endif
446 }
447 else
448#endif /* MHD_SHA512_256_SUPPORT */
350 { 449 {
351#ifdef _DEBUG 450#ifdef _DEBUG
352 da->inited = false; 451 da->inited = false;
@@ -369,12 +468,23 @@ digest_update (struct DigestAlgorithm *da,
369{ 468{
370 mhd_assert (da->inited); 469 mhd_assert (da->inited);
371 mhd_assert (! da->digest_calculated); 470 mhd_assert (! da->digest_calculated);
471#ifdef MHD_MD5_SUPPORT
372 if (MHD_DIGEST_BASE_ALGO_MD5 == da->algo) 472 if (MHD_DIGEST_BASE_ALGO_MD5 == da->algo)
373 MHD_MD5Update (&da->ctx.md5_ctx, (const uint8_t *) data, length); 473 MHD_MD5Update (&da->ctx.md5_ctx, (const uint8_t *) data, length);
374 else if (MHD_DIGEST_BASE_ALGO_SHA256 == da->algo) 474 else
475#endif /* MHD_MD5_SUPPORT */
476#ifdef MHD_SHA256_SUPPORT
477 if (MHD_DIGEST_BASE_ALGO_SHA256 == da->algo)
375 MHD_SHA256_update (&da->ctx.sha256_ctx, (const uint8_t *) data, length); 478 MHD_SHA256_update (&da->ctx.sha256_ctx, (const uint8_t *) data, length);
376 else 479 else
377 mhd_assert (0); /* May not happen */ 480#endif /* MHD_SHA256_SUPPORT */
481#ifdef MHD_SHA512_256_SUPPORT
482 if (MHD_DIGEST_BASE_ALGO_SHA512_256 == da->algo)
483 MHD_SHA512_256_update (&da->ctx.sha512_256_ctx,
484 (const uint8_t *) data, length);
485 else
486#endif /* MHD_SHA512_256_SUPPORT */
487 mhd_assert (0); /* May not happen */
378} 488}
379 489
380 490
@@ -416,12 +526,22 @@ digest_calc_hash (struct DigestAlgorithm *da, uint8_t *digest)
416{ 526{
417 mhd_assert (da->inited); 527 mhd_assert (da->inited);
418 mhd_assert (! da->digest_calculated); 528 mhd_assert (! da->digest_calculated);
529#ifdef MHD_MD5_SUPPORT
419 if (MHD_DIGEST_BASE_ALGO_MD5 == da->algo) 530 if (MHD_DIGEST_BASE_ALGO_MD5 == da->algo)
420 MHD_MD5Final (&da->ctx.md5_ctx, digest); 531 MHD_MD5Final (&da->ctx.md5_ctx, digest);
421 else if (MHD_DIGEST_BASE_ALGO_SHA256 == da->algo) 532 else
533#endif /* MHD_MD5_SUPPORT */
534#ifdef MHD_SHA256_SUPPORT
535 if (MHD_DIGEST_BASE_ALGO_SHA256 == da->algo)
422 MHD_SHA256_finish (&da->ctx.sha256_ctx, digest); 536 MHD_SHA256_finish (&da->ctx.sha256_ctx, digest);
423 else 537 else
424 mhd_assert (0); /* May not happen */ 538#endif /* MHD_SHA256_SUPPORT */
539#ifdef MHD_SHA512_256_SUPPORT
540 if (MHD_DIGEST_BASE_ALGO_SHA512_256 == da->algo)
541 MHD_SHA512_256_finish (&da->ctx.sha512_256_ctx, digest);
542 else
543#endif /* MHD_SHA512_256_SUPPORT */
544 mhd_assert (0); /* May not happen */
425#ifdef _DEBUG 545#ifdef _DEBUG
426 da->digest_calculated = true; 546 da->digest_calculated = true;
427#endif 547#endif
@@ -444,8 +564,14 @@ get_nonce_timestamp (const char *const nonce,
444 if (0 == noncelen) 564 if (0 == noncelen)
445 noncelen = strlen (nonce); 565 noncelen = strlen (nonce);
446 566
447 if ( (NONCE_STD_LEN (SHA256_DIGEST_SIZE) != noncelen) && 567 if (true
448 (NONCE_STD_LEN (MD5_DIGEST_SIZE) != noncelen) ) 568#ifdef MHD_MD5_SUPPORT
569 && (NONCE_STD_LEN (MD5_DIGEST_SIZE) != noncelen)
570#endif /* MHD_MD5_SUPPORT */
571#if defined(MHD_SHA256_SUPPORT) || defined(MHD_SHA512_256_SUPPORT)
572 && (NONCE_STD_LEN (SHA256_SHA512_256_DIGEST_SIZE) != noncelen)
573#endif /* MHD_SHA256_SUPPORT */
574 )
449 return false; 575 return false;
450 576
451 if (TIMESTAMP_CHARS_LEN != 577 if (TIMESTAMP_CHARS_LEN !=
@@ -2213,19 +2339,43 @@ digest_auth_check_all_inner (struct MHD_Connection *connection,
2213#endif /* HAVE_MESSAGES */ 2339#endif /* HAVE_MESSAGES */
2214 return MHD_DAUTH_WRONG_ALGO; 2340 return MHD_DAUTH_WRONG_ALGO;
2215 } 2341 }
2342#ifndef MHD_MD5_SUPPORT
2343 if (0 != (((unsigned int) c_algo) & MHD_DIGEST_BASE_ALGO_MD5))
2344 {
2345#ifdef HAVE_MESSAGES
2346 MHD_DLOG (connection->daemon,
2347 _ ("The MD5 algorithm is not supported by this MHD build.\n"));
2348#endif /* HAVE_MESSAGES */
2349 return MHD_DAUTH_WRONG_ALGO;
2350 }
2351#endif /* ! MHD_MD5_SUPPORT */
2352#ifndef MHD_SHA256_SUPPORT
2353 if (0 != (((unsigned int) c_algo) & MHD_DIGEST_BASE_ALGO_SHA256))
2354 {
2355#ifdef HAVE_MESSAGES
2356 MHD_DLOG (connection->daemon,
2357 _ ("The SHA-256 algorithm is not supported by "
2358 "this MHD build.\n"));
2359#endif /* HAVE_MESSAGES */
2360 return MHD_DAUTH_WRONG_ALGO;
2361 }
2362#endif /* ! MHD_SHA256_SUPPORT */
2363#ifndef MHD_SHA512_256_SUPPORT
2216 if (0 != (((unsigned int) c_algo) & MHD_DIGEST_BASE_ALGO_SHA512_256)) 2364 if (0 != (((unsigned int) c_algo) & MHD_DIGEST_BASE_ALGO_SHA512_256))
2217 { 2365 {
2218#ifdef HAVE_MESSAGES 2366#ifdef HAVE_MESSAGES
2219 MHD_DLOG (connection->daemon, 2367 MHD_DLOG (connection->daemon,
2220 _ ("The SHA-512/256 algorithm is not supported.\n")); 2368 _ ("The SHA-512/256 algorithm is not supported by "
2369 "this MHD build.\n"));
2221#endif /* HAVE_MESSAGES */ 2370#endif /* HAVE_MESSAGES */
2222 return MHD_DAUTH_WRONG_ALGO; 2371 return MHD_DAUTH_WRONG_ALGO;
2223 } 2372 }
2373#endif /* ! MHD_SHA512_256_SUPPORT */
2224 if (! digest_setup (&da, get_base_digest_algo (c_algo))) 2374 if (! digest_setup (&da, get_base_digest_algo (c_algo)))
2225 MHD_PANIC (_ ("Wrong 'malgo3' value, API violation")); 2375 MHD_PANIC (_ ("Wrong 'malgo3' value, API violation"));
2226 /* Check 'mqop' value */ 2376 /* Check 'mqop' value */
2227 c_qop = params->qop; 2377 c_qop = params->qop;
2228 /* Check whether client's algorithm is allowed by function parameter */ 2378 /* Check whether client's QOP is allowed by function parameter */
2229 if (((unsigned int) c_qop) != 2379 if (((unsigned int) c_qop) !=
2230 (((unsigned int) c_qop) & ((unsigned int) mqop))) 2380 (((unsigned int) c_qop) & ((unsigned int) mqop)))
2231 return MHD_DAUTH_WRONG_QOP; 2381 return MHD_DAUTH_WRONG_QOP;
@@ -2241,8 +2391,8 @@ digest_auth_check_all_inner (struct MHD_Connection *connection,
2241 if ((MHD_DIGEST_AUTH_QOP_NONE == c_qop) && 2391 if ((MHD_DIGEST_AUTH_QOP_NONE == c_qop) &&
2242 (0 == (((unsigned int) c_algo) & MHD_DIGEST_BASE_ALGO_MD5))) 2392 (0 == (((unsigned int) c_algo) & MHD_DIGEST_BASE_ALGO_MD5)))
2243 MHD_DLOG (connection->daemon, 2393 MHD_DLOG (connection->daemon,
2244 _ ("RFC2069 with SHA-256 algorithm is non-standard " \ 2394 _ ("RFC2069 with SHA-256 or SHA-512/256 algorithm is " \
2245 "extension.\n")); 2395 "non-standard extension.\n"));
2246#endif /* HAVE_MESSAGES */ 2396#endif /* HAVE_MESSAGES */
2247 2397
2248 digest_size = digest_get_size (&da); 2398 digest_size = digest_get_size (&da);
@@ -2776,7 +2926,8 @@ MHD_digest_auth_check3 (struct MHD_Connection *connection,
2776 * see #MHD_digest_auth_calc_userdigest() 2926 * see #MHD_digest_auth_calc_userdigest()
2777 * @param userdigest_size the size of the @a userdigest in bytes, must match the 2927 * @param userdigest_size the size of the @a userdigest in bytes, must match the
2778 * hashing algorithm (see #MHD_MD5_DIGEST_SIZE, 2928 * hashing algorithm (see #MHD_MD5_DIGEST_SIZE,
2779 * #MHD_SHA256_DIGEST_SIZE, #MHD_digest_get_hash_size()) 2929 * #MHD_SHA256_DIGEST_SIZE, #MHD_SHA512_256_DIGEST_SIZE,
2930 * #MHD_digest_get_hash_size())
2780 * @param nonce_timeout the period of seconds since nonce generation, when 2931 * @param nonce_timeout the period of seconds since nonce generation, when
2781 * the nonce is recognised as valid and not stale. 2932 * the nonce is recognised as valid and not stale.
2782 * @param max_nc the maximum allowed nc (Nonce Count) value, if client's nc 2933 * @param max_nc the maximum allowed nc (Nonce Count) value, if client's nc
@@ -2786,9 +2937,9 @@ MHD_digest_auth_check3 (struct MHD_Connection *connection,
2786 * @param mqop the QOP to use 2937 * @param mqop the QOP to use
2787 * @param malgo3 digest algorithms allowed to use, fail if algorithm used 2938 * @param malgo3 digest algorithms allowed to use, fail if algorithm used
2788 * by the client is not allowed by this parameter; 2939 * by the client is not allowed by this parameter;
2789 * both MD5-based and SHA-256-based algorithms cannot be used at 2940 * more than one base algorithms (MD5, SHA-256, SHA-512/256)
2790 * the same time for this function as @a userdigest_size must 2941 * cannot be used at the same time for this function
2791 * match specified algorithm 2942 * as @a userdigest must match specified algorithm
2792 * @return #MHD_DAUTH_OK if authenticated, 2943 * @return #MHD_DAUTH_OK if authenticated,
2793 * the error code otherwise 2944 * the error code otherwise
2794 * @sa #MHD_digest_auth_calc_userdigest() 2945 * @sa #MHD_digest_auth_calc_userdigest()
@@ -2806,13 +2957,46 @@ MHD_digest_auth_check_digest3 (struct MHD_Connection *connection,
2806 enum MHD_DigestAuthMultiQOP mqop, 2957 enum MHD_DigestAuthMultiQOP mqop,
2807 enum MHD_DigestAuthMultiAlgo3 malgo3) 2958 enum MHD_DigestAuthMultiAlgo3 malgo3)
2808{ 2959{
2809 if (((unsigned int) (MHD_DIGEST_BASE_ALGO_MD5 2960 if (1 != (((0 != (malgo3 & MHD_DIGEST_BASE_ALGO_MD5)) ? 1 : 0)
2810 | MHD_DIGEST_BASE_ALGO_SHA256)) == 2961 + ((0 != (malgo3 & MHD_DIGEST_BASE_ALGO_SHA256)) ? 1 : 0)
2811 (((unsigned int) malgo3) & (MHD_DIGEST_BASE_ALGO_MD5 2962 + ((0 != (malgo3 & MHD_DIGEST_BASE_ALGO_SHA512_256)) ? 1 : 0)))
2812 | MHD_DIGEST_BASE_ALGO_SHA256))) 2963 MHD_PANIC (_ ("Wrong 'malgo3' value, only one base hashing algorithm " \
2813 MHD_PANIC (_ ("Wrong 'malgo3' value, both MD5 and SHA-256 specified, " 2964 "(MD5, SHA-256 or SHA-512/256) must be specified, " \
2814 "API violation")); 2965 "API violation"));
2815 2966
2967#ifndef MHD_MD5_SUPPORT
2968 if (0 != (((unsigned int) malgo3) & MHD_DIGEST_BASE_ALGO_MD5))
2969 {
2970#ifdef HAVE_MESSAGES
2971 MHD_DLOG (connection->daemon,
2972 _ ("The MD5 algorithm is not supported by this MHD build.\n"));
2973#endif /* HAVE_MESSAGES */
2974 return MHD_DAUTH_WRONG_ALGO;
2975 }
2976#endif /* ! MHD_MD5_SUPPORT */
2977#ifndef MHD_SHA256_SUPPORT
2978 if (0 != (((unsigned int) malgo3) & MHD_DIGEST_BASE_ALGO_SHA256))
2979 {
2980#ifdef HAVE_MESSAGES
2981 MHD_DLOG (connection->daemon,
2982 _ ("The SHA-256 algorithm is not supported by "
2983 "this MHD build.\n"));
2984#endif /* HAVE_MESSAGES */
2985 return MHD_DAUTH_WRONG_ALGO;
2986 }
2987#endif /* ! MHD_SHA256_SUPPORT */
2988#ifndef MHD_SHA512_256_SUPPORT
2989 if (0 != (((unsigned int) malgo3) & MHD_DIGEST_BASE_ALGO_SHA512_256))
2990 {
2991#ifdef HAVE_MESSAGES
2992 MHD_DLOG (connection->daemon,
2993 _ ("The SHA-512/256 algorithm is not supported by "
2994 "this MHD build.\n"));
2995#endif /* HAVE_MESSAGES */
2996 return MHD_DAUTH_WRONG_ALGO;
2997 }
2998#endif /* ! MHD_SHA512_256_SUPPORT */
2999
2816 if (digest_get_hash_size ((enum MHD_DigestAuthAlgo3) malgo3) != 3000 if (digest_get_hash_size ((enum MHD_DigestAuthAlgo3) malgo3) !=
2817 userdigest_size) 3001 userdigest_size)
2818 MHD_PANIC (_ ("Wrong 'userdigest_size' value, does not match 'malgo3', " 3002 MHD_PANIC (_ ("Wrong 'userdigest_size' value, does not match 'malgo3', "
@@ -3072,12 +3256,45 @@ MHD_queue_auth_required_response3 (struct MHD_Connection *connection,
3072#endif /* HAVE_MESSAGES */ 3256#endif /* HAVE_MESSAGES */
3073 return MHD_NO; 3257 return MHD_NO;
3074 } 3258 }
3259#ifndef MHD_SHA512_256_SUPPORT
3260 if (0 != (((unsigned int) malgo3) & MHD_DIGEST_BASE_ALGO_SHA512_256))
3261 {
3262#ifdef HAVE_MESSAGES
3263 MHD_DLOG (connection->daemon,
3264 _ ("The SHA-512/256 algorithm is not enabled.\n"));
3265#endif /* HAVE_MESSAGES */
3266 return MHD_NO;
3267 }
3268#endif /* ! MHD_SHA512_256_SUPPORT */
3269#ifdef MHD_MD5_SUPPORT
3075 if (0 != (((unsigned int) malgo3) & MHD_DIGEST_BASE_ALGO_MD5)) 3270 if (0 != (((unsigned int) malgo3) & MHD_DIGEST_BASE_ALGO_MD5))
3076 s_algo = MHD_DIGEST_AUTH_ALGO3_MD5; 3271 s_algo = MHD_DIGEST_AUTH_ALGO3_MD5;
3077 else if (0 != (((unsigned int) malgo3) & MHD_DIGEST_BASE_ALGO_SHA256)) 3272 else
3273#endif /* MHD_MD5_SUPPORT */
3274#ifdef MHD_SHA256_SUPPORT
3275 if (0 != (((unsigned int) malgo3) & MHD_DIGEST_BASE_ALGO_SHA256))
3078 s_algo = MHD_DIGEST_AUTH_ALGO3_SHA256; 3276 s_algo = MHD_DIGEST_AUTH_ALGO3_SHA256;
3079 else 3277 else
3080 MHD_PANIC (_ ("Wrong 'malgo3' value, API violation")); 3278#endif /* MHD_SHA256_SUPPORT */
3279#ifdef MHD_SHA512_256_SUPPORT
3280 if (0 != (((unsigned int) malgo3) & MHD_DIGEST_BASE_ALGO_SHA512_256))
3281 s_algo = MHD_DIGEST_AUTH_ALGO3_SHA512_256;
3282 else
3283#endif /* MHD_SHA512_256_SUPPORT */
3284 {
3285 if (0 == (((unsigned int) malgo3)
3286 & (MHD_DIGEST_BASE_ALGO_MD5 | MHD_DIGEST_BASE_ALGO_SHA512_256
3287 | MHD_DIGEST_BASE_ALGO_SHA512_256)))
3288 MHD_PANIC (_ ("Wrong 'malgo3' value, API violation"));
3289 else
3290 {
3291#ifdef HAVE_MESSAGES
3292 MHD_DLOG (connection->daemon,
3293 _ ("No requested algorithm is supported by this MHD build.\n"));
3294#endif /* HAVE_MESSAGES */
3295 }
3296 return MHD_NO;
3297 }
3081 3298
3082 if (((unsigned int) mqop) != 3299 if (((unsigned int) mqop) !=
3083 (((unsigned int) mqop) & MHD_DIGEST_AUTH_MULT_QOP_ANY_NON_INT)) 3300 (((unsigned int) mqop) & MHD_DIGEST_AUTH_MULT_QOP_ANY_NON_INT))
@@ -3095,8 +3312,8 @@ MHD_queue_auth_required_response3 (struct MHD_Connection *connection,
3095 "are not compatible with RFC2069 and ignored.\n")); 3312 "are not compatible with RFC2069 and ignored.\n"));
3096 if (0 == (((unsigned int) s_algo) & MHD_DIGEST_BASE_ALGO_MD5)) 3313 if (0 == (((unsigned int) s_algo) & MHD_DIGEST_BASE_ALGO_MD5))
3097 MHD_DLOG (connection->daemon, 3314 MHD_DLOG (connection->daemon,
3098 _ ("RFC2069 with SHA-256 algorithm is non-standard " \ 3315 _ ("RFC2069 with SHA-256 or SHA-512/256 algorithm is " \
3099 "extension.\n")); 3316 "non-standard extension.\n"));
3100#endif 3317#endif
3101 userhash_support = 0; 3318 userhash_support = 0;
3102 prefer_utf8 = 0; 3319 prefer_utf8 = 0;
@@ -3141,12 +3358,22 @@ MHD_queue_auth_required_response3 (struct MHD_Connection *connection,
3141 (0 == (((unsigned int) s_algo) & MHD_DIGEST_BASE_ALGO_MD5))) 3358 (0 == (((unsigned int) s_algo) & MHD_DIGEST_BASE_ALGO_MD5)))
3142 { 3359 {
3143 buf_size += MHD_STATICSTR_LEN_ (prefix_algo) + 2; /* 2 for ', ' */ 3360 buf_size += MHD_STATICSTR_LEN_ (prefix_algo) + 2; /* 2 for ', ' */
3361#ifdef MHD_MD5_SUPPORT
3144 if (MHD_DIGEST_AUTH_ALGO3_MD5 == s_algo) 3362 if (MHD_DIGEST_AUTH_ALGO3_MD5 == s_algo)
3145 buf_size += MHD_STATICSTR_LEN_ (_MHD_MD5_TOKEN); 3363 buf_size += MHD_STATICSTR_LEN_ (_MHD_MD5_TOKEN);
3146 else if (MHD_DIGEST_AUTH_ALGO3_SHA256 == s_algo) 3364 else
3365#endif /* MHD_MD5_SUPPORT */
3366#ifdef MHD_SHA256_SUPPORT
3367 if (MHD_DIGEST_AUTH_ALGO3_SHA256 == s_algo)
3147 buf_size += MHD_STATICSTR_LEN_ (_MHD_SHA256_TOKEN); 3368 buf_size += MHD_STATICSTR_LEN_ (_MHD_SHA256_TOKEN);
3148 else 3369 else
3149 mhd_assert (0); 3370#endif /* MHD_SHA256_SUPPORT */
3371#ifdef MHD_SHA512_256_SUPPORT
3372 if (MHD_DIGEST_AUTH_ALGO3_SHA512_256 == s_algo)
3373 buf_size += MHD_STATICSTR_LEN_ (_MHD_SHA512_256_TOKEN);
3374 else
3375#endif /* MHD_SHA512_256_SUPPORT */
3376 mhd_assert (0);
3150 } 3377 }
3151 /* 'nonce="xxxx", ' */ 3378 /* 'nonce="xxxx", ' */
3152 buf_size += MHD_STATICSTR_LEN_ (prefix_nonce) + 3; /* 3 for '", ' */ 3379 buf_size += MHD_STATICSTR_LEN_ (prefix_nonce) + 3; /* 3 for '", ' */
@@ -3243,18 +3470,34 @@ MHD_queue_auth_required_response3 (struct MHD_Connection *connection,
3243 memcpy (buf + p, prefix_algo, 3470 memcpy (buf + p, prefix_algo,
3244 MHD_STATICSTR_LEN_ (prefix_algo)); 3471 MHD_STATICSTR_LEN_ (prefix_algo));
3245 p += MHD_STATICSTR_LEN_ (prefix_algo); 3472 p += MHD_STATICSTR_LEN_ (prefix_algo);
3473#ifdef MHD_MD5_SUPPORT
3246 if (MHD_DIGEST_AUTH_ALGO3_MD5 == s_algo) 3474 if (MHD_DIGEST_AUTH_ALGO3_MD5 == s_algo)
3247 { 3475 {
3248 memcpy (buf + p, _MHD_MD5_TOKEN, 3476 memcpy (buf + p, _MHD_MD5_TOKEN,
3249 MHD_STATICSTR_LEN_ (_MHD_MD5_TOKEN)); 3477 MHD_STATICSTR_LEN_ (_MHD_MD5_TOKEN));
3250 p += MHD_STATICSTR_LEN_ (_MHD_MD5_TOKEN); 3478 p += MHD_STATICSTR_LEN_ (_MHD_MD5_TOKEN);
3251 } 3479 }
3252 else if (MHD_DIGEST_AUTH_ALGO3_SHA256 == s_algo) 3480 else
3481#endif /* MHD_MD5_SUPPORT */
3482#ifdef MHD_SHA256_SUPPORT
3483 if (MHD_DIGEST_AUTH_ALGO3_SHA256 == s_algo)
3253 { 3484 {
3254 memcpy (buf + p, _MHD_SHA256_TOKEN, 3485 memcpy (buf + p, _MHD_SHA256_TOKEN,
3255 MHD_STATICSTR_LEN_ (_MHD_SHA256_TOKEN)); 3486 MHD_STATICSTR_LEN_ (_MHD_SHA256_TOKEN));
3256 p += MHD_STATICSTR_LEN_ (_MHD_SHA256_TOKEN); 3487 p += MHD_STATICSTR_LEN_ (_MHD_SHA256_TOKEN);
3257 } 3488 }
3489 else
3490#endif /* MHD_SHA256_SUPPORT */
3491#ifdef MHD_SHA512_256_SUPPORT
3492 if (MHD_DIGEST_AUTH_ALGO3_SHA512_256 == s_algo)
3493 {
3494 memcpy (buf + p, _MHD_SHA512_256_TOKEN,
3495 MHD_STATICSTR_LEN_ (_MHD_SHA512_256_TOKEN));
3496 p += MHD_STATICSTR_LEN_ (_MHD_SHA512_256_TOKEN);
3497 }
3498 else
3499#endif /* MHD_SHA512_256_SUPPORT */
3500 mhd_assert (0);
3258 buf[p++] = ','; 3501 buf[p++] = ',';
3259 buf[p++] = ' '; 3502 buf[p++] = ' ';
3260 } 3503 }
@@ -3382,7 +3625,7 @@ MHD_queue_auth_fail_response2 (struct MHD_Connection *connection,
3382 algo3 = MHD_DIGEST_AUTH_MULT_ALGO3_MD5; 3625 algo3 = MHD_DIGEST_AUTH_MULT_ALGO3_MD5;
3383 else if (MHD_DIGEST_ALG_SHA256 == algo) 3626 else if (MHD_DIGEST_ALG_SHA256 == algo)
3384 algo3 = MHD_DIGEST_AUTH_MULT_ALGO3_SHA256; 3627 algo3 = MHD_DIGEST_AUTH_MULT_ALGO3_SHA256;
3385 else if ((MHD_DIGEST_ALG_MD5 == algo) || (MHD_DIGEST_ALG_AUTO == algo)) 3628 else if (MHD_DIGEST_ALG_AUTO == algo)
3386 algo3 = MHD_DIGEST_AUTH_MULT_ALGO3_ANY_NON_SESSION; 3629 algo3 = MHD_DIGEST_AUTH_MULT_ALGO3_ANY_NON_SESSION;
3387 else 3630 else
3388 MHD_PANIC (_ ("Wrong algo value.\n")); /* API violation! */ 3631 MHD_PANIC (_ ("Wrong algo value.\n")); /* API violation! */