From f438804c181e8652df4f3428f90011909d3d51e0 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Tue, 28 Jul 2026 10:55:44 +0200 Subject: [PATCH] do not abort on nonce slot collisions with different algorithms --- src/microhttpd/digestauth.c | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/src/microhttpd/digestauth.c b/src/microhttpd/digestauth.c index 09eb49c6..38f51fc4 100644 --- a/src/microhttpd/digestauth.c +++ b/src/microhttpd/digestauth.c @@ -857,19 +857,32 @@ check_nonce_nc (struct MHD_Connection *connection, MHD_mutex_lock_chk_ (&daemon->nnc_lock); - mhd_assert (0 == nn->nonce[noncelen]); /* The old value must be valid */ - - if ( (0 != memcmp (nn->nonce, nonce, noncelen)) || - (0 != nn->nonce[noncelen]) ) - { /* The nonce in the slot does not match nonce from the client */ + /* The nonces recorded in the array do not all have the same length: the + * daemon may serve several digest algorithms at the same time and the + * length of the nonce depends on the size of the digest (44 characters + * for MD5, 76 for SHA-256 and SHA-512/256). The slot selected by the + * hash of the client's nonce may therefore hold a nonce of a completely + * different length, which must not be inspected with the client's + * length. */ + if (strlen (nn->nonce) != noncelen) + { if (0 == nn->nonce[0]) { /* The slot was never used, while the client's nonce value should be * recorded when it was generated by MHD */ ret = MHD_CHECK_NONCENC_WRONG; } - else if (0 != nn->nonce[noncelen]) - { /* The value is the slot is wrong */ - ret = MHD_CHECK_NONCENC_STALE; + else + { /* The slot holds a nonce generated for another digest algorithm. + * The client's nonce is not (or no longer) recorded. */ + ret = MHD_CHECK_NONCENC_STALE; + } + } + else if (0 != memcmp (nn->nonce, nonce, noncelen)) + { /* The nonce in the slot does not match nonce from the client */ + if (0 == nn->nonce[0]) + { /* The slot was never used, while the client's nonce value should be + * recorded when it was generated by MHD */ + ret = MHD_CHECK_NONCENC_WRONG; } else {