diff options
-rw-r--r-- | src/microhttpd/digestauth.c | 639 | ||||
-rw-r--r-- | src/microhttpd/md5.c | 16 | ||||
-rw-r--r-- | src/microhttpd/md5.h | 12 | ||||
-rw-r--r-- | src/microhttpd/sha256.c | 17 | ||||
-rw-r--r-- | src/microhttpd/sha256.h | 14 | ||||
-rw-r--r-- | src/microhttpd/test_sha256.c | 18 |
6 files changed, 416 insertions, 300 deletions
diff --git a/src/microhttpd/digestauth.c b/src/microhttpd/digestauth.c index a560f2a6..7ac5ad8b 100644 --- a/src/microhttpd/digestauth.c +++ b/src/microhttpd/digestauth.c | |||
@@ -175,74 +175,261 @@ enum MHD_CheckNonceNC_ | |||
175 | 175 | ||
176 | 176 | ||
177 | /** | 177 | /** |
178 | * Context passed to functions that need to calculate | 178 | * Digest context data |
179 | * a digest but are orthogonal to the specific | ||
180 | * algorithm. | ||
181 | */ | 179 | */ |
182 | struct DigestAlgorithm | 180 | union DigestCtx |
183 | { | 181 | { |
184 | /** | 182 | struct MD5Context md5_ctx; |
185 | * Size of the final digest returned by @e digest. | 183 | struct Sha256Ctx sha256_ctx; |
186 | */ | 184 | }; |
187 | unsigned int digest_size; | 185 | |
186 | /** | ||
187 | * Digest printed as hex digits. | ||
188 | */ | ||
189 | union DigestHex | ||
190 | { | ||
191 | char md5[MD5_DIGEST_STRING_LENGTH]; | ||
192 | char sha256[SHA256_DIGEST_STRING_SIZE]; | ||
193 | }; | ||
194 | |||
195 | /** | ||
196 | * Digest in binary form. | ||
197 | */ | ||
198 | union DigestBin | ||
199 | { | ||
200 | uint8_t md5[MD5_DIGEST_SIZE]; | ||
201 | uint8_t sha256[SHA256_DIGEST_SIZE]; | ||
202 | }; | ||
188 | 203 | ||
204 | /** | ||
205 | * The digest calculation structure. | ||
206 | */ | ||
207 | struct DigestAlgorithm | ||
208 | { | ||
189 | /** | 209 | /** |
190 | * A context for the digest algorithm, already initialized to be | 210 | * A context for the digest algorithm, already initialized to be |
191 | * useful for @e init, @e update and @e digest. | 211 | * useful for @e init, @e update and @e digest. |
192 | */ | 212 | */ |
193 | void *ctx; | 213 | union DigestCtx ctx; |
194 | 214 | ||
195 | /** | 215 | /** |
196 | * Name of the algorithm, "MD5" or "SHA-256". | 216 | * Digest in binary form. |
197 | * @sa #_MHD_MD5_TOKEN, #_MHD_SHA256_TOKEN | ||
198 | */ | 217 | */ |
199 | const char *alg; | 218 | union DigestBin digest; |
200 | |||
201 | /** | 219 | /** |
202 | * Buffer of @e digest_size * 2 + 1 bytes. | 220 | * The digest algorithm. |
203 | */ | 221 | */ |
204 | char *sessionkey; | 222 | enum MHD_DigestAuthAlgorithm algo; |
205 | 223 | ||
206 | /** | 224 | /** |
207 | * Call to initialize @e ctx. | 225 | * Buffer for hex-print of the final digest. |
208 | */ | 226 | */ |
209 | void | 227 | union DigestHex digest_hex; |
210 | (*init)(void *ctx); | 228 | #if _DEBUG |
229 | bool setup; /**< The structure was set-up */ | ||
230 | bool inited; /**< The calculation was initialised */ | ||
231 | bool digest_calculated; /**< The digest was calculated */ | ||
232 | #endif /* _DEBUG */ | ||
233 | }; | ||
211 | 234 | ||
212 | /** | ||
213 | * Feed more data into the digest function. | ||
214 | * | ||
215 | * @param ctx context to feed | ||
216 | * @param length number of bytes in @a data | ||
217 | * @param data data to add | ||
218 | */ | ||
219 | void | ||
220 | (*update)(void *ctx, | ||
221 | const uint8_t *data, | ||
222 | size_t length); | ||
223 | 235 | ||
224 | /** | 236 | /** |
225 | * Compute final @a digest. | 237 | * Return name of the algorithm as a string. |
226 | * | 238 | * @param da the digest calculation structure to identify |
227 | * @param ctx context to use | 239 | * @return the name of the @a algo as a string. |
228 | * @param[out] digest where to write the result, | 240 | */ |
229 | * must be @e digest_length bytes long | 241 | _MHD_static_inline const char * |
230 | */ | 242 | digest_get_algo_name (struct DigestAlgorithm *da) |
231 | void | 243 | { |
232 | (*digest)(void *ctx, | 244 | mhd_assert (da->setup); |
233 | uint8_t *digest); | 245 | if (MHD_DIGEST_ALG_MD5 == da->algo) |
234 | }; | 246 | return _MHD_MD5_TOKEN; |
247 | if (MHD_DIGEST_ALG_SHA256 == da->algo) | ||
248 | return _MHD_SHA256_TOKEN; | ||
249 | mhd_assert (0); /* May not happen */ | ||
250 | return ""; | ||
251 | } | ||
252 | |||
253 | |||
254 | /** | ||
255 | * Return the size of the digest. | ||
256 | * @param da the digest calculation structure to identify | ||
257 | * @return the size of the digest. | ||
258 | */ | ||
259 | _MHD_static_inline unsigned int | ||
260 | digest_get_size (struct DigestAlgorithm *da) | ||
261 | { | ||
262 | mhd_assert (da->setup); | ||
263 | if (MHD_DIGEST_ALG_MD5 == da->algo) | ||
264 | return MD5_DIGEST_SIZE; | ||
265 | if (MHD_DIGEST_ALG_SHA256 == da->algo) | ||
266 | return SHA256_DIGEST_SIZE; | ||
267 | mhd_assert (0); /* May not happen */ | ||
268 | return 0; | ||
269 | } | ||
270 | |||
271 | |||
272 | /** | ||
273 | * Set-up the digest calculation structure. | ||
274 | * @param da the structure to set-up | ||
275 | * @param algo the algorithm to use for digest calculation | ||
276 | * @return boolean 'true' if successfully set-up, | ||
277 | * false otherwise. | ||
278 | */ | ||
279 | _MHD_static_inline bool | ||
280 | digest_setup (struct DigestAlgorithm *da, | ||
281 | enum MHD_DigestAuthAlgorithm algo) | ||
282 | { | ||
283 | #ifdef _DEBUG | ||
284 | da->setup = false; | ||
285 | da->inited = false; | ||
286 | da->digest_calculated = false; | ||
287 | #endif /* _DEBUG */ | ||
288 | if (MHD_DIGEST_ALG_AUTO == algo) | ||
289 | algo = MHD_DIGEST_ALG_SHA256; | ||
290 | |||
291 | if ((MHD_DIGEST_ALG_MD5 == algo) || | ||
292 | (MHD_DIGEST_ALG_SHA256 == algo)) | ||
293 | { | ||
294 | da->algo = algo; | ||
295 | #ifdef _DEBUG | ||
296 | da->setup = true; | ||
297 | #endif /* _DEBUG */ | ||
298 | return true; | ||
299 | } | ||
300 | mhd_assert (0); /* Bad parameter */ | ||
301 | return false; | ||
302 | } | ||
303 | |||
304 | |||
305 | /** | ||
306 | * Initialise/reset the digest calculation structure. | ||
307 | * @param da the structure to initialise/reset | ||
308 | */ | ||
309 | _MHD_static_inline void | ||
310 | digest_init (struct DigestAlgorithm *da) | ||
311 | { | ||
312 | mhd_assert (da->setup); | ||
313 | #ifdef _DEBUG | ||
314 | da->digest_calculated = false; | ||
315 | #endif | ||
316 | if (MHD_DIGEST_ALG_MD5 == da->algo) | ||
317 | { | ||
318 | MHD_MD5Init (&da->ctx.md5_ctx); | ||
319 | #ifdef _DEBUG | ||
320 | da->inited = true; | ||
321 | #endif | ||
322 | } | ||
323 | else if (MHD_DIGEST_ALG_SHA256 == da->algo) | ||
324 | { | ||
325 | MHD_SHA256_init (&da->ctx.sha256_ctx); | ||
326 | #ifdef _DEBUG | ||
327 | da->inited = true; | ||
328 | #endif | ||
329 | } | ||
330 | else | ||
331 | { | ||
332 | #ifdef _DEBUG | ||
333 | da->inited = false; | ||
334 | #endif | ||
335 | mhd_assert (0); /* Bad algorithm */ | ||
336 | } | ||
337 | } | ||
338 | |||
339 | |||
340 | /** | ||
341 | * Feed digest calculation with more data. | ||
342 | * @param da the digest calculation | ||
343 | * @param data the data to process | ||
344 | * @param length the size of the @a data in bytes | ||
345 | */ | ||
346 | _MHD_static_inline void | ||
347 | digest_update (struct DigestAlgorithm *da, | ||
348 | const uint8_t *data, | ||
349 | size_t length) | ||
350 | { | ||
351 | mhd_assert (da->inited); | ||
352 | mhd_assert (! da->digest_calculated); | ||
353 | if (MHD_DIGEST_ALG_MD5 == da->algo) | ||
354 | MHD_MD5Update (&da->ctx.md5_ctx, data, length); | ||
355 | else if (MHD_DIGEST_ALG_SHA256 == da->algo) | ||
356 | MHD_SHA256_update (&da->ctx.sha256_ctx, data, length); | ||
357 | else | ||
358 | mhd_assert (0); /* May not happen */ | ||
359 | } | ||
360 | |||
361 | |||
362 | /** | ||
363 | * Finally calculate hash (the digest). | ||
364 | * @param da the digest calculation | ||
365 | */ | ||
366 | _MHD_static_inline void | ||
367 | digest_calc_hash (struct DigestAlgorithm *da) | ||
368 | { | ||
369 | mhd_assert (da->inited); | ||
370 | mhd_assert (! da->digest_calculated); | ||
371 | if (MHD_DIGEST_ALG_MD5 == da->algo) | ||
372 | MHD_MD5Final (&da->ctx.md5_ctx, da->digest.md5); | ||
373 | else if (MHD_DIGEST_ALG_SHA256 == da->algo) | ||
374 | MHD_SHA256_finish (&da->ctx.sha256_ctx, da->digest.sha256); | ||
375 | else | ||
376 | mhd_assert (0); /* May not happen */ | ||
377 | #ifdef _DEBUG | ||
378 | da->digest_calculated = true; | ||
379 | #endif | ||
380 | } | ||
381 | |||
382 | |||
383 | /** | ||
384 | * Get pointer to the calculated digest in binary form. | ||
385 | * @param da the digest calculation | ||
386 | * @return the pointer to the calculated digest | ||
387 | */ | ||
388 | _MHD_static_inline const uint8_t * | ||
389 | digest_get_bin (struct DigestAlgorithm *da) | ||
390 | { | ||
391 | mhd_assert (da->inited); | ||
392 | mhd_assert (da->digest_calculated); | ||
393 | mhd_assert (da->digest.md5 == da->digest.sha256); | ||
394 | return da->digest.sha256; | ||
395 | } | ||
396 | |||
397 | |||
398 | /** | ||
399 | * Get pointer to the buffer for the printed digest. | ||
400 | * @param da the digest calculation | ||
401 | * @return the pointer to the buffer | ||
402 | */ | ||
403 | _MHD_static_inline char * | ||
404 | digest_get_hex_buffer (struct DigestAlgorithm *da) | ||
405 | { | ||
406 | return da->digest_hex.sha256; | ||
407 | } | ||
408 | |||
409 | |||
410 | /** | ||
411 | * Put calculated digest to the buffer as hex digits. | ||
412 | * @param da the digest calculation | ||
413 | * @return the pointer to the calculated digest | ||
414 | */ | ||
415 | _MHD_static_inline void | ||
416 | digest_make_hex (struct DigestAlgorithm *da) | ||
417 | { | ||
418 | MHD_bin_to_hex (digest_get_bin (da), | ||
419 | digest_get_size (da), | ||
420 | digest_get_hex_buffer (da)); | ||
421 | } | ||
235 | 422 | ||
236 | 423 | ||
237 | /** | 424 | /** |
238 | * calculate H(A1) from given hash as per RFC2617 spec | 425 | * calculate H(A1) from given hash as per RFC2617 spec |
239 | * and store the * result in 'sessionkey'. | 426 | * and store the result in 'digest_hex'. |
240 | * | 427 | * |
241 | * @param alg The hash algorithm used, can be "MD5" or "MD5-sess" | 428 | * @param alg The hash algorithm used, can be "MD5" or "MD5-sess" |
242 | * or "SHA-256" or "SHA-256-sess" | 429 | * or "SHA-256" or "SHA-256-sess" |
243 | * Note that the rest of the code does not support the the "-sess" variants! | 430 | * Note that the rest of the code does not support the the "-sess" variants! |
244 | * @param[in,out] da digest implementation, must match @a alg; the | 431 | * @param[in,out] da digest implementation, must match @a alg; the |
245 | * da->sessionkey will be initialized to the digest in HEX | 432 | * da->digest_hex will be initialized to the digest in HEX |
246 | * @param digest An `unsigned char *' pointer to the binary MD5 sum | 433 | * @param digest An `unsigned char *' pointer to the binary MD5 sum |
247 | * for the precalculated hash value "username:realm:password" | 434 | * for the precalculated hash value "username:realm:password" |
248 | * of #MHD_MD5_DIGEST_SIZE or #SHA256_DIGEST_SIZE bytes | 435 | * of #MHD_MD5_DIGEST_SIZE or #SHA256_DIGEST_SIZE bytes |
@@ -256,49 +443,43 @@ digest_calc_ha1_from_digest (const char *alg, | |||
256 | const char *nonce, | 443 | const char *nonce, |
257 | const char *cnonce) | 444 | const char *cnonce) |
258 | { | 445 | { |
259 | const unsigned int digest_size = da->digest_size; | 446 | /* TODO: disable unsupported code paths */ |
260 | if ( (MHD_str_equal_caseless_ (alg, | 447 | if ( (MHD_str_equal_caseless_ (alg, |
261 | _MHD_MD5_TOKEN _MHD_SESS_TOKEN)) || | 448 | _MHD_MD5_TOKEN _MHD_SESS_TOKEN)) || |
262 | (MHD_str_equal_caseless_ (alg, | 449 | (MHD_str_equal_caseless_ (alg, |
263 | _MHD_SHA256_TOKEN _MHD_SESS_TOKEN)) ) | 450 | _MHD_SHA256_TOKEN _MHD_SESS_TOKEN)) ) |
264 | { | 451 | { |
265 | uint8_t dig[VLA_ARRAY_LEN_DIGEST (digest_size)]; | 452 | digest_init (da); |
266 | 453 | digest_update (da, | |
267 | VLA_CHECK_LEN_DIGEST (digest_size); | 454 | digest, |
268 | da->init (da->ctx); | 455 | digest_get_size (da)); |
269 | da->update (da->ctx, | 456 | digest_update (da, |
270 | digest, | 457 | (const unsigned char *) ":", |
271 | MHD_MD5_DIGEST_SIZE); | 458 | 1); |
272 | da->update (da->ctx, | 459 | digest_update (da, |
273 | (const unsigned char *) ":", | 460 | (const unsigned char *) nonce, |
274 | 1); | 461 | strlen (nonce)); |
275 | da->update (da->ctx, | 462 | digest_update (da, |
276 | (const unsigned char *) nonce, | 463 | (const unsigned char *) ":", |
277 | strlen (nonce)); | 464 | 1); |
278 | da->update (da->ctx, | 465 | digest_update (da, |
279 | (const unsigned char *) ":", | 466 | (const unsigned char *) cnonce, |
280 | 1); | 467 | strlen (cnonce)); |
281 | da->update (da->ctx, | 468 | digest_calc_hash (da); |
282 | (const unsigned char *) cnonce, | 469 | digest_make_hex (da); |
283 | strlen (cnonce)); | ||
284 | da->digest (da->ctx, | ||
285 | dig); | ||
286 | MHD_bin_to_hex (dig, | ||
287 | digest_size, | ||
288 | da->sessionkey); | ||
289 | } | 470 | } |
290 | else | 471 | else |
291 | { | 472 | { |
292 | MHD_bin_to_hex (digest, | 473 | MHD_bin_to_hex (digest, |
293 | digest_size, | 474 | digest_get_size (da), |
294 | da->sessionkey); | 475 | digest_get_hex_buffer (da)); |
295 | } | 476 | } |
296 | } | 477 | } |
297 | 478 | ||
298 | 479 | ||
299 | /** | 480 | /** |
300 | * calculate H(A1) from username, realm and password as per RFC2617 spec | 481 | * calculate H(A1) from username, realm and password as per RFC2617 spec |
301 | * and store the result in 'sessionkey'. | 482 | * and store the result in 'digest_hex'. |
302 | * | 483 | * |
303 | * @param alg The hash algorithm used, can be "MD5" or "MD5-sess" | 484 | * @param alg The hash algorithm used, can be "MD5" or "MD5-sess" |
304 | * or "SHA-256" or "SHA-256-sess" | 485 | * or "SHA-256" or "SHA-256-sess" |
@@ -319,30 +500,26 @@ digest_calc_ha1_from_user (const char *alg, | |||
319 | const char *cnonce, | 500 | const char *cnonce, |
320 | struct DigestAlgorithm *da) | 501 | struct DigestAlgorithm *da) |
321 | { | 502 | { |
322 | unsigned char ha1[VLA_ARRAY_LEN_DIGEST (da->digest_size)]; | 503 | digest_init (da); |
323 | 504 | digest_update (da, | |
324 | VLA_CHECK_LEN_DIGEST (da->digest_size); | 505 | (const unsigned char *) username, |
325 | da->init (da->ctx); | 506 | strlen (username)); |
326 | da->update (da->ctx, | 507 | digest_update (da, |
327 | (const unsigned char *) username, | 508 | (const unsigned char *) ":", |
328 | strlen (username)); | 509 | 1); |
329 | da->update (da->ctx, | 510 | digest_update (da, |
330 | (const unsigned char *) ":", | 511 | (const unsigned char *) realm, |
331 | 1); | 512 | strlen (realm)); |
332 | da->update (da->ctx, | 513 | digest_update (da, |
333 | (const unsigned char *) realm, | 514 | (const unsigned char *) ":", |
334 | strlen (realm)); | 515 | 1); |
335 | da->update (da->ctx, | 516 | digest_update (da, |
336 | (const unsigned char *) ":", | 517 | (const unsigned char *) password, |
337 | 1); | 518 | strlen (password)); |
338 | da->update (da->ctx, | 519 | digest_calc_hash (da); |
339 | (const unsigned char *) password, | ||
340 | strlen (password)); | ||
341 | da->digest (da->ctx, | ||
342 | ha1); | ||
343 | digest_calc_ha1_from_digest (alg, | 520 | digest_calc_ha1_from_digest (alg, |
344 | da, | 521 | da, |
345 | ha1, | 522 | digest_get_bin (da), |
346 | nonce, | 523 | nonce, |
347 | cnonce); | 524 | cnonce); |
348 | } | 525 | } |
@@ -375,85 +552,78 @@ digest_calc_response (const char *ha1, | |||
375 | const char *hentity, | 552 | const char *hentity, |
376 | struct DigestAlgorithm *da) | 553 | struct DigestAlgorithm *da) |
377 | { | 554 | { |
378 | const unsigned int digest_size = da->digest_size; | ||
379 | unsigned char ha2[VLA_ARRAY_LEN_DIGEST (digest_size)]; | ||
380 | unsigned char resphash[VLA_ARRAY_LEN_DIGEST (digest_size)]; | ||
381 | (void) hentity; /* Unused. Silence compiler warning. */ | 555 | (void) hentity; /* Unused. Silence compiler warning. */ |
382 | 556 | ||
383 | VLA_CHECK_LEN_DIGEST (digest_size); | 557 | /* Calculate h(a2) */ |
384 | da->init (da->ctx); | 558 | digest_init (da); |
385 | da->update (da->ctx, | 559 | digest_update (da, |
386 | (const unsigned char *) method, | 560 | (const unsigned char *) method, |
387 | strlen (method)); | 561 | strlen (method)); |
388 | da->update (da->ctx, | 562 | digest_update (da, |
389 | (const unsigned char *) ":", | 563 | (const unsigned char *) ":", |
390 | 1); | 564 | 1); |
391 | da->update (da->ctx, | 565 | digest_update (da, |
392 | (const unsigned char *) uri, | 566 | (const unsigned char *) uri, |
393 | strlen (uri)); | 567 | strlen (uri)); |
394 | #if 0 | 568 | #if 0 |
395 | if (0 == strcasecmp (qop, | 569 | if (0 == strcasecmp (qop, |
396 | "auth-int")) | 570 | "auth-int")) |
397 | { | 571 | { |
398 | /* This is dead code since the rest of this module does | 572 | /* This is dead code since the rest of this module does |
399 | not support auth-int. */ | 573 | not support auth-int. */ |
400 | da->update (da->ctx, | 574 | digest_update (da, |
401 | ":", | 575 | ":", |
402 | 1); | 576 | 1); |
403 | if (NULL != hentity) | 577 | if (NULL != hentity) |
404 | da->update (da->ctx, | 578 | da->update (da->ctx, |
405 | hentity, | 579 | hentity, |
406 | strlen (hentity)); | 580 | strlen (hentity)); |
407 | } | 581 | } |
408 | #endif | 582 | #endif |
409 | da->digest (da->ctx, | 583 | digest_calc_hash (da); |
410 | ha2); | 584 | digest_make_hex (da); |
411 | MHD_bin_to_hex (ha2, | 585 | |
412 | digest_size, | ||
413 | da->sessionkey); | ||
414 | da->init (da->ctx); | ||
415 | /* calculate response */ | 586 | /* calculate response */ |
416 | da->update (da->ctx, | 587 | digest_init (da); |
417 | (const unsigned char *) ha1, | 588 | digest_update (da, |
418 | digest_size * 2); | 589 | (const unsigned char *) ha1, |
419 | da->update (da->ctx, | 590 | digest_get_size (da) * 2); |
420 | (const unsigned char *) ":", | 591 | digest_update (da, |
421 | 1); | 592 | (const unsigned char *) ":", |
422 | da->update (da->ctx, | 593 | 1); |
423 | (const unsigned char *) nonce, | 594 | digest_update (da, |
424 | strlen (nonce)); | 595 | (const unsigned char *) nonce, |
425 | da->update (da->ctx, | 596 | strlen (nonce)); |
426 | (const unsigned char *) ":", | 597 | digest_update (da, |
427 | 1); | 598 | (const unsigned char *) ":", |
599 | 1); | ||
428 | if ('\0' != *qop) | 600 | if ('\0' != *qop) |
429 | { | 601 | { |
430 | da->update (da->ctx, | 602 | digest_update (da, |
431 | (const unsigned char *) noncecount, | 603 | (const unsigned char *) noncecount, |
432 | strlen (noncecount)); | 604 | strlen (noncecount)); |
433 | da->update (da->ctx, | 605 | digest_update (da, |
434 | (const unsigned char *) ":", | 606 | (const unsigned char *) ":", |
435 | 1); | 607 | 1); |
436 | da->update (da->ctx, | 608 | digest_update (da, |
437 | (const unsigned char *) cnonce, | 609 | (const unsigned char *) cnonce, |
438 | strlen (cnonce)); | 610 | strlen (cnonce)); |
439 | da->update (da->ctx, | 611 | digest_update (da, |
440 | (const unsigned char *) ":", | 612 | (const unsigned char *) ":", |
441 | 1); | 613 | 1); |
442 | da->update (da->ctx, | 614 | digest_update (da, |
443 | (const unsigned char *) qop, | 615 | (const unsigned char *) qop, |
444 | strlen (qop)); | 616 | strlen (qop)); |
445 | da->update (da->ctx, | 617 | digest_update (da, |
446 | (const unsigned char *) ":", | 618 | (const unsigned char *) ":", |
447 | 1); | 619 | 1); |
448 | } | 620 | } |
449 | da->update (da->ctx, | 621 | digest_update (da, |
450 | (const unsigned char *) da->sessionkey, | 622 | (const unsigned char *) digest_get_hex_buffer (da), |
451 | digest_size * 2); | 623 | digest_get_size (da) * 2); |
452 | da->digest (da->ctx, | 624 | |
453 | resphash); | 625 | digest_calc_hash (da); |
454 | MHD_bin_to_hex (resphash, | 626 | digest_make_hex (da); |
455 | digest_size, | ||
456 | da->sessionkey); | ||
457 | } | 627 | } |
458 | 628 | ||
459 | 629 | ||
@@ -828,13 +998,8 @@ calculate_nonce (uint64_t nonce_time, | |||
828 | char *nonce) | 998 | char *nonce) |
829 | { | 999 | { |
830 | uint8_t timestamp[TIMESTAMP_BIN_SIZE]; | 1000 | uint8_t timestamp[TIMESTAMP_BIN_SIZE]; |
831 | const unsigned int digest_size = da->digest_size; | ||
832 | char tmpnonce[VLA_ARRAY_LEN_DIGEST (digest_size)]; | ||
833 | 1001 | ||
834 | mhd_assert (0 == (digest_size % 2)); | 1002 | digest_init (da); |
835 | mhd_assert (0 != digest_size); | ||
836 | VLA_CHECK_LEN_DIGEST (digest_size); | ||
837 | da->init (da->ctx); | ||
838 | /* If the nonce_time is milliseconds, then the same 48 bit value will repeat | 1003 | /* If the nonce_time is milliseconds, then the same 48 bit value will repeat |
839 | * every 8 925 years, which is more than enough to mitigate a replay attack */ | 1004 | * every 8 925 years, which is more than enough to mitigate a replay attack */ |
840 | #if TIMESTAMP_BIN_SIZE != 6 | 1005 | #if TIMESTAMP_BIN_SIZE != 6 |
@@ -846,42 +1011,41 @@ calculate_nonce (uint64_t nonce_time, | |||
846 | timestamp[3] = (uint8_t) (nonce_time >> (8 * (TIMESTAMP_BIN_SIZE - 1 - 3))); | 1011 | timestamp[3] = (uint8_t) (nonce_time >> (8 * (TIMESTAMP_BIN_SIZE - 1 - 3))); |
847 | timestamp[4] = (uint8_t) (nonce_time >> (8 * (TIMESTAMP_BIN_SIZE - 1 - 4))); | 1012 | timestamp[4] = (uint8_t) (nonce_time >> (8 * (TIMESTAMP_BIN_SIZE - 1 - 4))); |
848 | timestamp[5] = (uint8_t) (nonce_time >> (8 * (TIMESTAMP_BIN_SIZE - 1 - 5))); | 1013 | timestamp[5] = (uint8_t) (nonce_time >> (8 * (TIMESTAMP_BIN_SIZE - 1 - 5))); |
849 | da->update (da->ctx, | 1014 | digest_update (da, |
850 | timestamp, | 1015 | timestamp, |
851 | sizeof (timestamp)); | 1016 | sizeof (timestamp)); |
852 | da->update (da->ctx, | 1017 | digest_update (da, |
853 | (const unsigned char *) ":", | 1018 | (const unsigned char *) ":", |
854 | 1); | 1019 | 1); |
855 | da->update (da->ctx, | 1020 | digest_update (da, |
856 | (const unsigned char *) method, | 1021 | (const unsigned char *) method, |
857 | strlen (method)); | 1022 | strlen (method)); |
858 | da->update (da->ctx, | 1023 | digest_update (da, |
859 | (const unsigned char *) ":", | 1024 | (const unsigned char *) ":", |
860 | 1); | 1025 | 1); |
861 | if (rnd_size > 0) | 1026 | if (rnd_size > 0) |
862 | da->update (da->ctx, | 1027 | digest_update (da, |
863 | (const unsigned char *) rnd, | 1028 | (const unsigned char *) rnd, |
864 | rnd_size); | 1029 | rnd_size); |
865 | da->update (da->ctx, | 1030 | digest_update (da, |
866 | (const unsigned char *) ":", | 1031 | (const unsigned char *) ":", |
867 | 1); | 1032 | 1); |
868 | da->update (da->ctx, | 1033 | digest_update (da, |
869 | (const unsigned char *) uri, | 1034 | (const unsigned char *) uri, |
870 | strlen (uri)); | 1035 | strlen (uri)); |
871 | da->update (da->ctx, | 1036 | digest_update (da, |
872 | (const unsigned char *) ":", | 1037 | (const unsigned char *) ":", |
873 | 1); | 1038 | 1); |
874 | da->update (da->ctx, | 1039 | digest_update (da, |
875 | (const unsigned char *) realm, | 1040 | (const unsigned char *) realm, |
876 | strlen (realm)); | 1041 | strlen (realm)); |
877 | da->digest (da->ctx, | 1042 | digest_calc_hash (da); |
878 | (uint8_t *) tmpnonce); | 1043 | MHD_bin_to_hex (digest_get_bin (da), |
879 | MHD_bin_to_hex (tmpnonce, | 1044 | digest_get_size (da), |
880 | digest_size, | ||
881 | nonce); | 1045 | nonce); |
882 | MHD_bin_to_hex (timestamp, | 1046 | MHD_bin_to_hex (timestamp, |
883 | sizeof (timestamp), | 1047 | sizeof (timestamp), |
884 | nonce + digest_size * 2); | 1048 | nonce + digest_get_size (da) * 2); |
885 | } | 1049 | } |
886 | 1050 | ||
887 | 1051 | ||
@@ -965,7 +1129,7 @@ calculate_add_nonce (struct MHD_Connection *const connection, | |||
965 | { | 1129 | { |
966 | struct MHD_Daemon *const daemon = MHD_get_master (connection->daemon); | 1130 | struct MHD_Daemon *const daemon = MHD_get_master (connection->daemon); |
967 | struct MHD_NonceNc *nn; | 1131 | struct MHD_NonceNc *nn; |
968 | const size_t nonce_size = NONCE_STD_LEN (da->digest_size); | 1132 | const size_t nonce_size = NONCE_STD_LEN (digest_get_size (da)); |
969 | bool ret; | 1133 | bool ret; |
970 | 1134 | ||
971 | mhd_assert (MAX_NONCE_LENGTH >= nonce_size); | 1135 | mhd_assert (MAX_NONCE_LENGTH >= nonce_size); |
@@ -1033,7 +1197,7 @@ calculate_add_nonce_with_retry (struct MHD_Connection *const connection, | |||
1033 | * 2. Another nonce uses the same slot, and this nonce never has been | 1197 | * 2. Another nonce uses the same slot, and this nonce never has been |
1034 | * used by the client and this nonce is still fresh enough. | 1198 | * used by the client and this nonce is still fresh enough. |
1035 | */ | 1199 | */ |
1036 | const size_t digest_size = da->digest_size; | 1200 | const size_t digest_size = digest_get_size (da); |
1037 | char nonce2[NONCE_STD_LEN (VLA_ARRAY_LEN_DIGEST (digest_size)) + 1]; | 1201 | char nonce2[NONCE_STD_LEN (VLA_ARRAY_LEN_DIGEST (digest_size)) + 1]; |
1038 | uint64_t timestamp2; | 1202 | uint64_t timestamp2; |
1039 | if (0 == MHD_get_master (connection->daemon)->nonce_nc_size) | 1203 | if (0 == MHD_get_master (connection->daemon)->nonce_nc_size) |
@@ -1216,7 +1380,7 @@ digest_auth_check_all (struct MHD_Connection *connection, | |||
1216 | char nonce[MAX_NONCE_LENGTH]; | 1380 | char nonce[MAX_NONCE_LENGTH]; |
1217 | size_t nonce_len; | 1381 | size_t nonce_len; |
1218 | char cnonce[MAX_NONCE_LENGTH]; | 1382 | char cnonce[MAX_NONCE_LENGTH]; |
1219 | const unsigned int digest_size = da->digest_size; | 1383 | const unsigned int digest_size = digest_get_size (da); |
1220 | char ha1[VLA_ARRAY_LEN_DIGEST (digest_size) * 2 + 1]; | 1384 | char ha1[VLA_ARRAY_LEN_DIGEST (digest_size) * 2 + 1]; |
1221 | char qop[15]; /* auth,auth-int */ | 1385 | char qop[15]; /* auth,auth-int */ |
1222 | char nc[20]; | 1386 | char nc[20]; |
@@ -1441,8 +1605,8 @@ digest_auth_check_all (struct MHD_Connection *connection, | |||
1441 | } | 1605 | } |
1442 | if (NULL != digest) | 1606 | if (NULL != digest) |
1443 | { | 1607 | { |
1444 | /* This will initialize da->sessionkey (ha1) */ | 1608 | /* This will initialize da->digest_hex (ha1) */ |
1445 | digest_calc_ha1_from_digest (da->alg, | 1609 | digest_calc_ha1_from_digest (digest_get_algo_name (da), |
1446 | da, | 1610 | da, |
1447 | digest, | 1611 | digest, |
1448 | nonce, | 1612 | nonce, |
@@ -1450,9 +1614,9 @@ digest_auth_check_all (struct MHD_Connection *connection, | |||
1450 | } | 1614 | } |
1451 | else | 1615 | else |
1452 | { | 1616 | { |
1453 | /* This will initialize da->sessionkey (ha1) */ | 1617 | /* This will initialize da->digest_hex (ha1) */ |
1454 | mhd_assert (NULL != password); /* NULL == digest => password != NULL */ | 1618 | mhd_assert (NULL != password); /* NULL == digest => password != NULL */ |
1455 | digest_calc_ha1_from_user (da->alg, | 1619 | digest_calc_ha1_from_user (digest_get_algo_name (da), |
1456 | username, | 1620 | username, |
1457 | realm, | 1621 | realm, |
1458 | password, | 1622 | password, |
@@ -1461,7 +1625,7 @@ digest_auth_check_all (struct MHD_Connection *connection, | |||
1461 | da); | 1625 | da); |
1462 | } | 1626 | } |
1463 | memcpy (ha1, | 1627 | memcpy (ha1, |
1464 | da->sessionkey, | 1628 | digest_get_hex_buffer (da), |
1465 | digest_size * 2 + 1); | 1629 | digest_size * 2 + 1); |
1466 | /* This will initialize da->sessionkey (respexp) */ | 1630 | /* This will initialize da->sessionkey (respexp) */ |
1467 | digest_calc_response (ha1, | 1631 | digest_calc_response (ha1, |
@@ -1516,7 +1680,7 @@ digest_auth_check_all (struct MHD_Connection *connection, | |||
1516 | free (uri); | 1680 | free (uri); |
1517 | } | 1681 | } |
1518 | return (0 == strcmp (response, | 1682 | return (0 == strcmp (response, |
1519 | da->sessionkey)) | 1683 | digest_get_hex_buffer (da))) |
1520 | ? MHD_DAUTH_OK | 1684 | ? MHD_DAUTH_OK |
1521 | : MHD_DAUTH_RESPONSE_WRONG; | 1685 | : MHD_DAUTH_RESPONSE_WRONG; |
1522 | } | 1686 | } |
@@ -1557,55 +1721,6 @@ MHD_digest_auth_check (struct MHD_Connection *connection, | |||
1557 | 1721 | ||
1558 | 1722 | ||
1559 | /** | 1723 | /** |
1560 | * Setup digest authentication data structures (on the | ||
1561 | * stack, hence must be done inline!). Initializes a | ||
1562 | * "struct DigestAlgorithm da" for algorithm @a algo. | ||
1563 | * | ||
1564 | * @param algo digest algorithm to provide | ||
1565 | * @param da data structure to setup | ||
1566 | */ | ||
1567 | #define SETUP_DA(algo,da) \ | ||
1568 | union { \ | ||
1569 | struct MD5Context md5; \ | ||
1570 | struct sha256_ctx sha256; \ | ||
1571 | } ctx; \ | ||
1572 | union { \ | ||
1573 | char md5[MD5_DIGEST_SIZE * 2 + 1]; \ | ||
1574 | char sha256[SHA256_DIGEST_SIZE * 2 + 1]; \ | ||
1575 | } skey; \ | ||
1576 | struct DigestAlgorithm da; \ | ||
1577 | \ | ||
1578 | do { \ | ||
1579 | switch (algo) { \ | ||
1580 | case MHD_DIGEST_ALG_MD5: \ | ||
1581 | da.digest_size = MD5_DIGEST_SIZE; \ | ||
1582 | da.ctx = &ctx.md5; \ | ||
1583 | da.alg = _MHD_MD5_TOKEN; \ | ||
1584 | da.sessionkey = skey.md5; \ | ||
1585 | da.init = &MHD_MD5Init; \ | ||
1586 | da.update = &MHD_MD5Update; \ | ||
1587 | da.digest = &MHD_MD5Final; \ | ||
1588 | break; \ | ||
1589 | case MHD_DIGEST_ALG_AUTO: \ | ||
1590 | /* auto == SHA256, fall-though thus intentional! */ \ | ||
1591 | case MHD_DIGEST_ALG_SHA256: \ | ||
1592 | da.digest_size = SHA256_DIGEST_SIZE; \ | ||
1593 | da.ctx = &ctx.sha256; \ | ||
1594 | da.alg = _MHD_SHA256_TOKEN; \ | ||
1595 | da.sessionkey = skey.sha256; \ | ||
1596 | da.init = &MHD_SHA256_init; \ | ||
1597 | da.update = &MHD_SHA256_update; \ | ||
1598 | da.digest = &MHD_SHA256_finish; \ | ||
1599 | break; \ | ||
1600 | default: \ | ||
1601 | da.digest_size = 0; \ | ||
1602 | mhd_assert (false); \ | ||
1603 | break; \ | ||
1604 | } \ | ||
1605 | } while (0) | ||
1606 | |||
1607 | |||
1608 | /** | ||
1609 | * Authenticates the authorization header sent by the client. | 1724 | * Authenticates the authorization header sent by the client. |
1610 | * | 1725 | * |
1611 | * @param connection the MHD connection structure | 1726 | * @param connection the MHD connection structure |
@@ -1627,10 +1742,11 @@ MHD_digest_auth_check3 (struct MHD_Connection *connection, | |||
1627 | unsigned int nonce_timeout, | 1742 | unsigned int nonce_timeout, |
1628 | enum MHD_DigestAuthAlgorithm algo) | 1743 | enum MHD_DigestAuthAlgorithm algo) |
1629 | { | 1744 | { |
1630 | SETUP_DA (algo, da); | 1745 | struct DigestAlgorithm da; |
1631 | 1746 | ||
1632 | mhd_assert (NULL != password); | 1747 | mhd_assert (NULL != password); |
1633 | if (0 == da.digest_size) | 1748 | |
1749 | if (! digest_setup (&da, algo)) | ||
1634 | MHD_PANIC (_ ("Wrong algo value.\n")); /* API violation! */ | 1750 | MHD_PANIC (_ ("Wrong algo value.\n")); /* API violation! */ |
1635 | 1751 | ||
1636 | return digest_auth_check_all (connection, | 1752 | return digest_auth_check_all (connection, |
@@ -1669,10 +1785,13 @@ MHD_digest_auth_check_digest3 (struct MHD_Connection *connection, | |||
1669 | unsigned int nonce_timeout, | 1785 | unsigned int nonce_timeout, |
1670 | enum MHD_DigestAuthAlgorithm algo) | 1786 | enum MHD_DigestAuthAlgorithm algo) |
1671 | { | 1787 | { |
1672 | SETUP_DA (algo, da); | 1788 | struct DigestAlgorithm da; |
1673 | 1789 | ||
1674 | mhd_assert (NULL != digest); | 1790 | mhd_assert (NULL != digest); |
1675 | if ((da.digest_size != digest_size) || (0 == digest_size)) | 1791 | if (! digest_setup (&da, algo)) |
1792 | MHD_PANIC (_ ("Wrong algo value.\n")); /* API violation! */ | ||
1793 | |||
1794 | if (digest_get_size (&da) != digest_size) | ||
1676 | MHD_PANIC (_ ("Digest size mismatch.\n")); /* API violation! */ | 1795 | MHD_PANIC (_ ("Digest size mismatch.\n")); /* API violation! */ |
1677 | 1796 | ||
1678 | return digest_auth_check_all (connection, | 1797 | return digest_auth_check_all (connection, |
@@ -1832,9 +1951,10 @@ MHD_queue_auth_fail_response2 (struct MHD_Connection *connection, | |||
1832 | { | 1951 | { |
1833 | int ret; | 1952 | int ret; |
1834 | int hlen; | 1953 | int hlen; |
1835 | SETUP_DA (algo, da); | ||
1836 | 1954 | ||
1837 | if (0 == da.digest_size) | 1955 | struct DigestAlgorithm da; |
1956 | |||
1957 | if (! digest_setup (&da, algo)) | ||
1838 | MHD_PANIC (_ ("Wrong algo value.\n")); /* API violation! */ | 1958 | MHD_PANIC (_ ("Wrong algo value.\n")); /* API violation! */ |
1839 | 1959 | ||
1840 | if (NULL == response) | 1960 | if (NULL == response) |
@@ -1851,9 +1971,10 @@ MHD_queue_auth_fail_response2 (struct MHD_Connection *connection, | |||
1851 | 1971 | ||
1852 | if (1) | 1972 | if (1) |
1853 | { | 1973 | { |
1854 | char nonce[NONCE_STD_LEN (VLA_ARRAY_LEN_DIGEST (da.digest_size)) + 1]; | 1974 | char nonce[NONCE_STD_LEN (VLA_ARRAY_LEN_DIGEST (digest_get_size (&da))) |
1975 | + 1]; | ||
1855 | 1976 | ||
1856 | VLA_CHECK_LEN_DIGEST (da.digest_size); | 1977 | VLA_CHECK_LEN_DIGEST (digest_get_size (&da)); |
1857 | if (! calculate_add_nonce_with_retry (connection, realm, &da, nonce)) | 1978 | if (! calculate_add_nonce_with_retry (connection, realm, &da, nonce)) |
1858 | { | 1979 | { |
1859 | #ifdef HAVE_MESSAGES | 1980 | #ifdef HAVE_MESSAGES |
@@ -1872,7 +1993,7 @@ MHD_queue_auth_fail_response2 (struct MHD_Connection *connection, | |||
1872 | realm, | 1993 | realm, |
1873 | nonce, | 1994 | nonce, |
1874 | opaque, | 1995 | opaque, |
1875 | da.alg, | 1996 | digest_get_algo_name (&da), |
1876 | signal_stale | 1997 | signal_stale |
1877 | ? ",stale=\"true\"" | 1998 | ? ",stale=\"true\"" |
1878 | : ""); | 1999 | : ""); |
@@ -1897,7 +2018,7 @@ MHD_queue_auth_fail_response2 (struct MHD_Connection *connection, | |||
1897 | realm, | 2018 | realm, |
1898 | nonce, | 2019 | nonce, |
1899 | opaque, | 2020 | opaque, |
1900 | da.alg, | 2021 | digest_get_algo_name (&da), |
1901 | signal_stale | 2022 | signal_stale |
1902 | ? ",stale=\"true\"" | 2023 | ? ",stale=\"true\"" |
1903 | : "") == hlen) | 2024 | : "") == hlen) |
diff --git a/src/microhttpd/md5.c b/src/microhttpd/md5.c index a467ccac..ada6fd31 100644 --- a/src/microhttpd/md5.c +++ b/src/microhttpd/md5.c | |||
@@ -37,13 +37,11 @@ | |||
37 | * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious | 37 | * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious |
38 | * initialization constants. | 38 | * initialization constants. |
39 | * | 39 | * |
40 | * @param ctx_ must be a `struct MD5Context *` | 40 | * @param ctx must be a `struct MD5Context *` |
41 | */ | 41 | */ |
42 | void | 42 | void |
43 | MHD_MD5Init (void *ctx_) | 43 | MHD_MD5Init (struct MD5Context *ctx) |
44 | { | 44 | { |
45 | struct MD5Context *ctx = ctx_; | ||
46 | |||
47 | mhd_assert (ctx != NULL); | 45 | mhd_assert (ctx != NULL); |
48 | ctx->count = 0; | 46 | ctx->count = 0; |
49 | ctx->state[0] = UINT32_C (0x67452301); | 47 | ctx->state[0] = UINT32_C (0x67452301); |
@@ -61,13 +59,12 @@ MD5Transform (uint32_t state[4], | |||
61 | /** | 59 | /** |
62 | * Final wrapup--call MD5Pad, fill in digest and zero out ctx. | 60 | * Final wrapup--call MD5Pad, fill in digest and zero out ctx. |
63 | * | 61 | * |
64 | * @param ctx_ must be a `struct MD5Context *` | 62 | * @param ctx must be a `struct MD5Context *` |
65 | */ | 63 | */ |
66 | void | 64 | void |
67 | MHD_MD5Final (void *ctx_, | 65 | MHD_MD5Final (struct MD5Context *ctx, |
68 | uint8_t digest[MD5_DIGEST_SIZE]) | 66 | uint8_t digest[MD5_DIGEST_SIZE]) |
69 | { | 67 | { |
70 | struct MD5Context *ctx = ctx_; | ||
71 | uint64_t count_bits; | 68 | uint64_t count_bits; |
72 | size_t have_bytes; | 69 | size_t have_bytes; |
73 | 70 | ||
@@ -267,16 +264,15 @@ MD5Transform (uint32_t state[4], | |||
267 | * Update context to reflect the concatenation of another buffer full | 264 | * Update context to reflect the concatenation of another buffer full |
268 | * of bytes. | 265 | * of bytes. |
269 | * | 266 | * |
270 | * @param ctx_ must be a `struct MD5Context *` | 267 | * @param ctx must be a `struct MD5Context *` |
271 | * @param input bytes to add to hash | 268 | * @param input bytes to add to hash |
272 | * @param len the number of bytes in @a data | 269 | * @param len the number of bytes in @a data |
273 | */ | 270 | */ |
274 | void | 271 | void |
275 | MHD_MD5Update (void *ctx_, | 272 | MHD_MD5Update (struct MD5Context *ctx, |
276 | const uint8_t *input, | 273 | const uint8_t *input, |
277 | size_t len) | 274 | size_t len) |
278 | { | 275 | { |
279 | struct MD5Context *ctx = ctx_; | ||
280 | size_t have, need; | 276 | size_t have, need; |
281 | 277 | ||
282 | mhd_assert (ctx != NULL); | 278 | mhd_assert (ctx != NULL); |
diff --git a/src/microhttpd/md5.h b/src/microhttpd/md5.h index 239cf664..bdfc031c 100644 --- a/src/microhttpd/md5.h +++ b/src/microhttpd/md5.h | |||
@@ -40,22 +40,22 @@ struct MD5Context | |||
40 | * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious | 40 | * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious |
41 | * initialization constants. | 41 | * initialization constants. |
42 | * | 42 | * |
43 | * @param ctx_ must be a `struct MD5Context *` | 43 | * @param ctx must be a `struct MD5Context *` |
44 | */ | 44 | */ |
45 | void | 45 | void |
46 | MHD_MD5Init (void *ctx_); | 46 | MHD_MD5Init (struct MD5Context *ctx); |
47 | 47 | ||
48 | 48 | ||
49 | /** | 49 | /** |
50 | * Update context to reflect the concatenation of another buffer full | 50 | * Update context to reflect the concatenation of another buffer full |
51 | * of bytes. | 51 | * of bytes. |
52 | * | 52 | * |
53 | * @param ctx_ must be a `struct MD5Context *` | 53 | * @param ctx must be a `struct MD5Context *` |
54 | * @param input bytes to add to hash | 54 | * @param input bytes to add to hash |
55 | * @param len the number of bytes in @a data | 55 | * @param len the number of bytes in @a data |
56 | */ | 56 | */ |
57 | void | 57 | void |
58 | MHD_MD5Update (void *ctx_, | 58 | MHD_MD5Update (struct MD5Context *ctx, |
59 | const uint8_t *input, | 59 | const uint8_t *input, |
60 | size_t len); | 60 | size_t len); |
61 | 61 | ||
@@ -63,10 +63,10 @@ MHD_MD5Update (void *ctx_, | |||
63 | /** | 63 | /** |
64 | * Final wrapup--call MD5Pad, fill in digest and zero out ctx. | 64 | * Final wrapup--call MD5Pad, fill in digest and zero out ctx. |
65 | * | 65 | * |
66 | * @param ctx_ must be a `struct MD5Context *` | 66 | * @param ctx must be a `struct MD5Context *` |
67 | */ | 67 | */ |
68 | void | 68 | void |
69 | MHD_MD5Final (void *ctx_, | 69 | MHD_MD5Final (struct MD5Context *ctx, |
70 | uint8_t digest[MD5_DIGEST_SIZE]); | 70 | uint8_t digest[MD5_DIGEST_SIZE]); |
71 | 71 | ||
72 | 72 | ||
diff --git a/src/microhttpd/sha256.c b/src/microhttpd/sha256.c index 825b80b3..f62b4ba1 100644 --- a/src/microhttpd/sha256.c +++ b/src/microhttpd/sha256.c | |||
@@ -35,12 +35,11 @@ | |||
35 | /** | 35 | /** |
36 | * Initialise structure for SHA256 calculation. | 36 | * Initialise structure for SHA256 calculation. |
37 | * | 37 | * |
38 | * @param ctx_ must be a `struct sha256_ctx *` | 38 | * @param ctx must be a `struct Sha256Ctx *` |
39 | */ | 39 | */ |
40 | void | 40 | void |
41 | MHD_SHA256_init (void *ctx_) | 41 | MHD_SHA256_init (struct Sha256Ctx *ctx) |
42 | { | 42 | { |
43 | struct sha256_ctx *const ctx = ctx_; | ||
44 | /* Initial hash values, see FIPS PUB 180-4 paragraph 5.3.3 */ | 43 | /* Initial hash values, see FIPS PUB 180-4 paragraph 5.3.3 */ |
45 | /* First thirty-two bits of the fractional parts of the square | 44 | /* First thirty-two bits of the fractional parts of the square |
46 | * roots of the first eight prime numbers: 2, 3, 5, 7, 11, 13, | 45 | * roots of the first eight prime numbers: 2, 3, 5, 7, 11, 13, |
@@ -306,16 +305,15 @@ sha256_transform (uint32_t H[_SHA256_DIGEST_LENGTH], | |||
306 | /** | 305 | /** |
307 | * Process portion of bytes. | 306 | * Process portion of bytes. |
308 | * | 307 | * |
309 | * @param ctx_ must be a `struct sha256_ctx *` | 308 | * @param ctx_ must be a `struct Sha256Ctx *` |
310 | * @param data bytes to add to hash | 309 | * @param data bytes to add to hash |
311 | * @param length number of bytes in @a data | 310 | * @param length number of bytes in @a data |
312 | */ | 311 | */ |
313 | void | 312 | void |
314 | MHD_SHA256_update (void *ctx_, | 313 | MHD_SHA256_update (struct Sha256Ctx *ctx, |
315 | const uint8_t *data, | 314 | const uint8_t *data, |
316 | size_t length) | 315 | size_t length) |
317 | { | 316 | { |
318 | struct sha256_ctx *const ctx = ctx_; | ||
319 | unsigned bytes_have; /**< Number of bytes in buffer */ | 317 | unsigned bytes_have; /**< Number of bytes in buffer */ |
320 | 318 | ||
321 | mhd_assert ((data != NULL) || (length == 0)); | 319 | mhd_assert ((data != NULL) || (length == 0)); |
@@ -369,14 +367,13 @@ MHD_SHA256_update (void *ctx_, | |||
369 | /** | 367 | /** |
370 | * Finalise SHA256 calculation, return digest. | 368 | * Finalise SHA256 calculation, return digest. |
371 | * | 369 | * |
372 | * @param ctx_ must be a `struct sha256_ctx *` | 370 | * @param ctx_ must be a `struct Sha256Ctx *` |
373 | * @param[out] digest set to the hash, must be #SHA256_DIGEST_SIZE bytes | 371 | * @param[out] digest set to the hash, must be #SHA256_DIGEST_SIZE bytes |
374 | */ | 372 | */ |
375 | void | 373 | void |
376 | MHD_SHA256_finish (void *ctx_, | 374 | MHD_SHA256_finish (struct Sha256Ctx *ctx, |
377 | uint8_t digest[SHA256_DIGEST_SIZE]) | 375 | uint8_t digest[SHA256_DIGEST_SIZE]) |
378 | { | 376 | { |
379 | struct sha256_ctx *const ctx = ctx_; | ||
380 | uint64_t num_bits; /**< Number of processed bits */ | 377 | uint64_t num_bits; /**< Number of processed bits */ |
381 | unsigned bytes_have; /**< Number of bytes in buffer */ | 378 | unsigned bytes_have; /**< Number of bytes in buffer */ |
382 | 379 | ||
@@ -448,5 +445,5 @@ MHD_SHA256_finish (void *ctx_, | |||
448 | } | 445 | } |
449 | 446 | ||
450 | /* Erase potentially sensitive data. */ | 447 | /* Erase potentially sensitive data. */ |
451 | memset (ctx, 0, sizeof(struct sha256_ctx)); | 448 | memset (ctx, 0, sizeof(struct Sha256Ctx)); |
452 | } | 449 | } |
diff --git a/src/microhttpd/sha256.h b/src/microhttpd/sha256.h index cac3cb28..8feb52fe 100644 --- a/src/microhttpd/sha256.h +++ b/src/microhttpd/sha256.h | |||
@@ -70,7 +70,7 @@ | |||
70 | #define SHA256_BLOCK_SIZE (SHA256_BLOCK_SIZE_BITS / 8) | 70 | #define SHA256_BLOCK_SIZE (SHA256_BLOCK_SIZE_BITS / 8) |
71 | 71 | ||
72 | 72 | ||
73 | struct sha256_ctx | 73 | struct Sha256Ctx |
74 | { | 74 | { |
75 | uint32_t H[_SHA256_DIGEST_LENGTH]; /**< Intermediate hash value / digest at end of calculation */ | 75 | uint32_t H[_SHA256_DIGEST_LENGTH]; /**< Intermediate hash value / digest at end of calculation */ |
76 | uint8_t buffer[SHA256_BLOCK_SIZE]; /**< SHA256 input data buffer */ | 76 | uint8_t buffer[SHA256_BLOCK_SIZE]; /**< SHA256 input data buffer */ |
@@ -80,21 +80,21 @@ struct sha256_ctx | |||
80 | /** | 80 | /** |
81 | * Initialise structure for SHA256 calculation. | 81 | * Initialise structure for SHA256 calculation. |
82 | * | 82 | * |
83 | * @param ctx_ must be a `struct sha256_ctx *` | 83 | * @param ctx must be a `struct Sha256Ctx *` |
84 | */ | 84 | */ |
85 | void | 85 | void |
86 | MHD_SHA256_init (void *ctx_); | 86 | MHD_SHA256_init (struct Sha256Ctx *ctx); |
87 | 87 | ||
88 | 88 | ||
89 | /** | 89 | /** |
90 | * Process portion of bytes. | 90 | * Process portion of bytes. |
91 | * | 91 | * |
92 | * @param ctx_ must be a `struct sha256_ctx *` | 92 | * @param ctx must be a `struct Sha256Ctx *` |
93 | * @param data bytes to add to hash | 93 | * @param data bytes to add to hash |
94 | * @param length number of bytes in @a data | 94 | * @param length number of bytes in @a data |
95 | */ | 95 | */ |
96 | void | 96 | void |
97 | MHD_SHA256_update (void *ctx_, | 97 | MHD_SHA256_update (struct Sha256Ctx *ctx, |
98 | const uint8_t *data, | 98 | const uint8_t *data, |
99 | size_t length); | 99 | size_t length); |
100 | 100 | ||
@@ -102,11 +102,11 @@ MHD_SHA256_update (void *ctx_, | |||
102 | /** | 102 | /** |
103 | * Finalise SHA256 calculation, return digest. | 103 | * Finalise SHA256 calculation, return digest. |
104 | * | 104 | * |
105 | * @param ctx_ must be a `struct sha256_ctx *` | 105 | * @param ctx must be a `struct Sha256Ctx *` |
106 | * @param[out] digest set to the hash, must be #SHA256_DIGEST_SIZE bytes | 106 | * @param[out] digest set to the hash, must be #SHA256_DIGEST_SIZE bytes |
107 | */ | 107 | */ |
108 | void | 108 | void |
109 | MHD_SHA256_finish (void *ctx_, | 109 | MHD_SHA256_finish (struct Sha256Ctx *ctx, |
110 | uint8_t digest[SHA256_DIGEST_SIZE]); | 110 | uint8_t digest[SHA256_DIGEST_SIZE]); |
111 | 111 | ||
112 | #endif /* MHD_SHA256_H */ | 112 | #endif /* MHD_SHA256_H */ |
diff --git a/src/microhttpd/test_sha256.c b/src/microhttpd/test_sha256.c index 91b28af2..74061cfb 100644 --- a/src/microhttpd/test_sha256.c +++ b/src/microhttpd/test_sha256.c | |||
@@ -332,11 +332,11 @@ test1_str (void) | |||
332 | 332 | ||
333 | for (i = 0; i < units1_num; i++) | 333 | for (i = 0; i < units1_num; i++) |
334 | { | 334 | { |
335 | struct sha256_ctx ctx; | 335 | struct Sha256Ctx ctx; |
336 | uint8_t digest[SHA256_DIGEST_SIZE]; | 336 | uint8_t digest[SHA256_DIGEST_SIZE]; |
337 | 337 | ||
338 | MHD_SHA256_init (&ctx); | 338 | MHD_SHA256_init (&ctx); |
339 | MHD_SHA256_update (&ctx, (const uint8_t*) data_units1[i].str_l.str, | 339 | MHD_SHA256_update (&ctx, (const uint8_t *) data_units1[i].str_l.str, |
340 | data_units1[i].str_l.len); | 340 | data_units1[i].str_l.len); |
341 | MHD_SHA256_finish (&ctx, digest); | 341 | MHD_SHA256_finish (&ctx, digest); |
342 | num_failed += check_result (__FUNCTION__, i, digest, | 342 | num_failed += check_result (__FUNCTION__, i, digest, |
@@ -354,7 +354,7 @@ test1_bin (void) | |||
354 | 354 | ||
355 | for (i = 0; i < units2_num; i++) | 355 | for (i = 0; i < units2_num; i++) |
356 | { | 356 | { |
357 | struct sha256_ctx ctx; | 357 | struct Sha256Ctx ctx; |
358 | uint8_t digest[SHA256_DIGEST_SIZE]; | 358 | uint8_t digest[SHA256_DIGEST_SIZE]; |
359 | 359 | ||
360 | MHD_SHA256_init (&ctx); | 360 | MHD_SHA256_init (&ctx); |
@@ -377,13 +377,15 @@ test2_str (void) | |||
377 | 377 | ||
378 | for (i = 0; i < units1_num; i++) | 378 | for (i = 0; i < units1_num; i++) |
379 | { | 379 | { |
380 | struct sha256_ctx ctx; | 380 | struct Sha256Ctx ctx; |
381 | uint8_t digest[SHA256_DIGEST_SIZE]; | 381 | uint8_t digest[SHA256_DIGEST_SIZE]; |
382 | size_t part_s = data_units1[i].str_l.len / 4; | 382 | size_t part_s = data_units1[i].str_l.len / 4; |
383 | 383 | ||
384 | MHD_SHA256_init (&ctx); | 384 | MHD_SHA256_init (&ctx); |
385 | MHD_SHA256_update (&ctx, (const uint8_t*) data_units1[i].str_l.str, part_s); | 385 | MHD_SHA256_update (&ctx, (const uint8_t *) data_units1[i].str_l.str, |
386 | MHD_SHA256_update (&ctx, (const uint8_t*) data_units1[i].str_l.str + part_s, | 386 | part_s); |
387 | MHD_SHA256_update (&ctx, (const uint8_t *) data_units1[i].str_l.str | ||
388 | + part_s, | ||
387 | data_units1[i].str_l.len - part_s); | 389 | data_units1[i].str_l.len - part_s); |
388 | MHD_SHA256_finish (&ctx, digest); | 390 | MHD_SHA256_finish (&ctx, digest); |
389 | num_failed += check_result (__FUNCTION__, i, digest, | 391 | num_failed += check_result (__FUNCTION__, i, digest, |
@@ -401,7 +403,7 @@ test2_bin (void) | |||
401 | 403 | ||
402 | for (i = 0; i < units2_num; i++) | 404 | for (i = 0; i < units2_num; i++) |
403 | { | 405 | { |
404 | struct sha256_ctx ctx; | 406 | struct Sha256Ctx ctx; |
405 | uint8_t digest[SHA256_DIGEST_SIZE]; | 407 | uint8_t digest[SHA256_DIGEST_SIZE]; |
406 | size_t part_s = data_units2[i].bin_l.len * 2 / 3; | 408 | size_t part_s = data_units2[i].bin_l.len * 2 / 3; |
407 | 409 | ||
@@ -438,7 +440,7 @@ test_unaligned (void) | |||
438 | 440 | ||
439 | for (offset = MAX_OFFSET; offset >= 1; --offset) | 441 | for (offset = MAX_OFFSET; offset >= 1; --offset) |
440 | { | 442 | { |
441 | struct sha256_ctx ctx; | 443 | struct Sha256Ctx ctx; |
442 | uint8_t *unaligned_digest; | 444 | uint8_t *unaligned_digest; |
443 | uint8_t *unaligned_buf; | 445 | uint8_t *unaligned_buf; |
444 | 446 | ||