commit f438804c181e8652df4f3428f90011909d3d51e0
parent 3b898eaea7eae514f1f0496499bc26a4fdd10d41
Author: Christian Grothoff <christian@grothoff.org>
Date: Tue, 28 Jul 2026 10:55:44 +0200
do not abort on nonce slot collisions with different algorithms
Diffstat:
1 file changed, 21 insertions(+), 8 deletions(-)
diff --git 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
{