test_dauth_userhash.c (25064B)
1 /* 2 This file is part of libmicrohttpd 3 Copyright (C) 2022 Evgeny Grin (Karlson2) 4 5 This test tool is free software; you can redistribute it and/or 6 modify it under the terms of the GNU General Public License as 7 published by the Free Software Foundation; either version 2, or 8 (at your option) any later version. 9 10 This test tool is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 Lesser General Public License for more details. 14 15 You should have received a copy of the GNU Lesser General Public 16 License along with this library; if not, write to the Free Software 17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 18 */ 19 20 /** 21 * @file microhttpd/test_dauth_userhash.c 22 * @brief Tests for Digest Auth calculations of userhash 23 * @author Karlson2k (Evgeny Grin) 24 */ 25 26 #include "mhd_options.h" 27 #include <stdio.h> 28 #include <stdlib.h> 29 #include <string.h> 30 #include "microhttpd.h" 31 #include "test_helpers.h" 32 33 /* Turn any MHD_PANIC() or failing mhd_assert() reached from this 34 test into a marked, classifiable test error (TESTING.md, P5). */ 35 #include "mhd_panic_tripwire.h" 36 37 #if defined(MHD_HTTPS_REQUIRE_GCRYPT) && \ 38 (defined(MHD_SHA256_TLSLIB) || defined(MHD_MD5_TLSLIB)) 39 #define NEED_GCRYP_INIT 1 40 #include <gcrypt.h> 41 #endif /* MHD_HTTPS_REQUIRE_GCRYPT && (MHD_SHA256_TLSLIB || MHD_MD5_TLSLIB) */ 42 43 static int verbose = 1; /* verbose level (0-1)*/ 44 45 /* Declarations and data */ 46 47 struct data_md5 48 { 49 unsigned int line_num; 50 const char *const username; 51 const char *const realm; 52 const uint8_t hash[MHD_MD5_DIGEST_SIZE]; 53 }; 54 55 56 static const struct data_md5 md5_tests[] = { 57 {__LINE__, 58 "u", "r", 59 {0xba, 0x84, 0xbe, 0x20, 0x3f, 0xdf, 0xc7, 0xd3, 0x4e, 0x05, 0x4a, 0x76, 60 0xd2, 0x85, 0xd0, 0xc9}}, 61 {__LINE__, 62 "testuser", "testrealm", 63 {0xab, 0xae, 0x15, 0x95, 0x24, 0xe5, 0x17, 0xbf, 0x48, 0xf4, 0x4a, 0xab, 64 0xfe, 0xb9, 0x37, 0x40}}, 65 {__LINE__, 66 "test_user", "TestRealm", /* Values from testcurl/test_digestauth2.c */ 67 {0xc5, 0x3c, 0x60, 0x15, 0x03, 0xff, 0x17, 0x6f, 0x18, 0xf6, 0x23, 0x72, 68 0x5f, 0xba, 0x42, 0x81}}, 69 {__LINE__, 70 "Mufasa", "myhost@testrealm.com", 71 {0x26, 0x45, 0xae, 0x13, 0xd1, 0xa2, 0xa6, 0x9e, 0xd2, 0x6d, 0xd2, 0x1a, 72 0xa5, 0x52, 0x86, 0xe3}}, 73 {__LINE__, 74 "Mufasa", "myhost@example.com", 75 {0x4f, 0xc8, 0x64, 0x02, 0xd7, 0x18, 0x5d, 0x7b, 0x38, 0xd4, 0x38, 0xad, 76 0xd5, 0x5a, 0x35, 0x84}}, 77 {__LINE__, 78 "Mufasa", "http-auth@example.org", 79 {0x42, 0x38, 0xf3, 0xa1, 0x61, 0x67, 0x37, 0x3f, 0xeb, 0xb9, 0xbc, 0x4d, 80 0x43, 0xdb, 0x9c, 0xc4}}, 81 {__LINE__, 82 "J" "\xC3\xA4" "s" "\xC3\xB8" "n Doe" /* "Jäsøn Doe" */, "api@example.org", 83 {0x2e, 0x06, 0x3f, 0xa2, 0xc5, 0x4d, 0xea, 0x1c, 0x36, 0x80, 0x8b, 0x7a, 84 0x6e, 0x3b, 0x14, 0xc9}} 85 }; 86 87 struct data_sha256 88 { 89 unsigned int line_num; 90 const char *const username; 91 const char *const realm; 92 const uint8_t hash[MHD_SHA256_DIGEST_SIZE]; 93 }; 94 95 static const struct data_sha256 sha256_tests[] = { 96 {__LINE__, 97 "u", "r", 98 {0x1d, 0x8a, 0x03, 0xa6, 0xe2, 0x1a, 0x4c, 0xe7, 0x75, 0x06, 0x0e, 0xa5, 99 0x73, 0x60, 0x32, 0x9a, 0xc7, 0x50, 0xde, 0xa5, 0xd8, 0x47, 0x29, 0x7b, 100 0x42, 0xf0, 0xd4, 0x65, 0x39, 0xaf, 0x8a, 0xb2}}, 101 {__LINE__, 102 "testuser", "testrealm", 103 {0x75, 0xaf, 0x8a, 0x35, 0x00, 0xf7, 0x71, 0xe5, 0x8a, 0x52, 0x09, 0x3a, 104 0x25, 0xe7, 0x90, 0x5d, 0x6e, 0x42, 0x8a, 0x51, 0x12, 0x85, 0xc1, 0x2e, 105 0xa1, 0x42, 0x0c, 0x73, 0x07, 0x8d, 0xfd, 0x61}}, 106 {__LINE__, 107 "test_user", "TestRealm", /* Values from testcurl/test_digestauth2.c */ 108 {0x09, 0x0c, 0x7e, 0x06, 0xb7, 0x7d, 0x66, 0x14, 0xcf, 0x5f, 0xe6, 0xca, 109 0xfa, 0x00, 0x4d, 0x2e, 0x5f, 0x8f, 0xb3, 0x6b, 0xa4, 0x5a, 0x0e, 0x35, 110 0xea, 0xcb, 0x2e, 0xb7, 0x72, 0x8f, 0x34, 0xde}}, 111 {__LINE__, 112 "Mufasa", "myhost@testrealm.com", 113 {0x92, 0x9f, 0xac, 0x9e, 0x6c, 0x8b, 0x76, 0xcc, 0xab, 0xa9, 0xe0, 0x6f, 114 0xf6, 0x4d, 0xf2, 0x6f, 0xcb, 0x40, 0x56, 0x4c, 0x19, 0x9c, 0x32, 0xd9, 115 0xea, 0xd9, 0x12, 0x4b, 0x25, 0x34, 0xe1, 0xf9}}, 116 {__LINE__, 117 "Mufasa", "myhost@example.com", 118 {0x97, 0x06, 0xf0, 0x07, 0x1c, 0xec, 0x05, 0x3f, 0x88, 0x22, 0xb6, 0x63, 119 0x69, 0xc4, 0xa4, 0x00, 0x39, 0x79, 0xb7, 0xe7, 0x42, 0xb7, 0x4e, 0x42, 120 0x59, 0x63, 0x57, 0xf4, 0xd3, 0x02, 0xae, 0x16}}, 121 {__LINE__, 122 "Mufasa", "http-auth@example.org", 123 {0xa9, 0x47, 0xaa, 0xd2, 0x05, 0xe8, 0x0e, 0x42, 0x99, 0x58, 0xa3, 0x87, 124 0x39, 0x49, 0x44, 0xc6, 0xb4, 0x96, 0x30, 0x1e, 0x79, 0xf8, 0x9d, 0x35, 125 0xa4, 0xcc, 0x23, 0xb6, 0xee, 0x12, 0xb5, 0xb6}}, 126 {__LINE__, 127 "J" "\xC3\xA4" "s" "\xC3\xB8" "n Doe" /* "Jäsøn Doe" */, "api@example.org", 128 {0x5a, 0x1a, 0x8a, 0x47, 0xdf, 0x5c, 0x29, 0x85, 0x51, 0xb9, 0xb4, 0x2b, 129 0xa9, 0xb0, 0x58, 0x35, 0x17, 0x4a, 0x5b, 0xd7, 0xd5, 0x11, 0xff, 0x7f, 130 0xe9, 0x19, 0x1d, 0x8e, 0x94, 0x6f, 0xc4, 0xe7}} 131 }; 132 133 struct data_sha512_256 134 { 135 unsigned int line_num; 136 const char *const username; 137 const char *const realm; 138 const uint8_t hash[MHD_SHA512_256_DIGEST_SIZE]; 139 }; 140 141 142 static const struct data_sha512_256 sha512_256_tests[] = { 143 {__LINE__, 144 "u", "r", 145 {0xc7, 0x38, 0xf2, 0xad, 0x40, 0x1b, 0xc8, 0x7a, 0x71, 0xfe, 0x78, 0x09, 146 0x60, 0x15, 0xc9, 0x7b, 0x9a, 0x26, 0xd5, 0x5f, 0x15, 0xe9, 0xf5, 0x0a, 147 0xc3, 0xa6, 0xde, 0x73, 0xdd, 0xcd, 0x3d, 0x08}}, 148 {__LINE__, 149 "testuser", "testrealm", 150 {0x4f, 0x69, 0x1e, 0xe9, 0x50, 0x8a, 0xe4, 0x55, 0x21, 0x32, 0x9e, 0xcf, 151 0xd4, 0x91, 0xf7, 0xe2, 0x77, 0x4b, 0x6f, 0xb8, 0x60, 0x2c, 0x14, 0x86, 152 0xad, 0x94, 0x9d, 0x1c, 0x23, 0xd8, 0xa1, 0xf5}}, 153 {__LINE__, 154 "test_user", "TestRealm", /* Values from testcurl/test_digestauth2.c */ 155 {0x62, 0xe1, 0xac, 0x9f, 0x6c, 0xb1, 0xeb, 0x26, 0xaa, 0x75, 0xeb, 0x5d, 156 0x46, 0xef, 0xcd, 0xc8, 0x9c, 0xcb, 0xa7, 0x81, 0xf0, 0xf9, 0xf7, 0x2f, 157 0x6a, 0xfd, 0xb9, 0x42, 0x65, 0xd9, 0xa7, 0x9a}}, 158 {__LINE__, 159 "Mufasa", "myhost@testrealm.com", 160 {0xbd, 0x3e, 0xbc, 0x30, 0x10, 0x0b, 0x7c, 0xf1, 0x61, 0x45, 0x6c, 0xfe, 161 0x64, 0x1c, 0x4c, 0xd2, 0x82, 0xe0, 0x62, 0x6e, 0x2c, 0x5e, 0x09, 0xc2, 162 0x4c, 0x90, 0xb1, 0x60, 0x8a, 0xec, 0x28, 0x64}}, 163 {__LINE__, 164 "Mufasa", "myhost@example.com", 165 {0xea, 0x4b, 0x59, 0x37, 0xde, 0x2c, 0x4e, 0x9f, 0x16, 0xf9, 0x9c, 0x31, 166 0x01, 0xb6, 0xdd, 0xf8, 0x8c, 0x85, 0xd7, 0xe8, 0xf1, 0x75, 0x90, 0xd0, 167 0x63, 0x2a, 0x75, 0x75, 0xe4, 0x80, 0x13, 0x69}}, 168 {__LINE__, 169 "Mufasa", "http-auth@example.org", 170 {0xe2, 0xdf, 0xab, 0xd1, 0xa9, 0x6d, 0xdf, 0x86, 0x77, 0x10, 0xb6, 0x53, 171 0xb6, 0xe6, 0x85, 0x7d, 0x1f, 0x14, 0x70, 0x86, 0xde, 0x7d, 0x7e, 0xf7, 172 0x9d, 0xcd, 0x24, 0x98, 0x59, 0x87, 0x25, 0x70}}, 173 {__LINE__, 174 "J" "\xC3\xA4" "s" "\xC3\xB8" "n Doe" /* "Jäsøn Doe" */, "api@example.org", 175 {0x79, 0x32, 0x63, 0xca, 0xab, 0xb7, 0x07, 0xa5, 0x62, 0x11, 0x94, 0x0d, 176 0x90, 0x41, 0x1e, 0xa4, 0xa5, 0x75, 0xad, 0xec, 0xcb, 0x7e, 0x36, 0x0a, 177 0xeb, 0x62, 0x4e, 0xd0, 0x6e, 0xce, 0x9b, 0x0b}} 178 }; 179 180 181 /* 182 * Helper functions 183 */ 184 185 /** 186 * Print bin as lower case hex 187 * 188 * @param bin binary data 189 * @param len number of bytes in bin 190 * @param hex pointer to len*2+1 bytes buffer 191 */ 192 static void 193 bin2hex (const uint8_t *bin, 194 size_t len, 195 char *hex) 196 { 197 while (len-- > 0) 198 { 199 unsigned int b1, b2; 200 b1 = (*bin >> 4) & 0xf; 201 *hex++ = (char) ((b1 > 9) ? (b1 + 'a' - 10) : (b1 + '0')); 202 b2 = *bin++ & 0xf; 203 *hex++ = (char) ((b2 > 9) ? (b2 + 'a' - 10) : (b2 + '0')); 204 } 205 *hex = 0; 206 } 207 208 209 /* Tests */ 210 211 static unsigned int 212 check_md5 (const struct data_md5 *const data) 213 { 214 static const enum MHD_DigestAuthAlgo3 algo3 = MHD_DIGEST_AUTH_ALGO3_MD5; 215 uint8_t hash_bin[MHD_MD5_DIGEST_SIZE]; 216 char hash_hex[MHD_MD5_DIGEST_SIZE * 2 + 1]; 217 char expected_hex[MHD_MD5_DIGEST_SIZE * 2 + 1]; 218 const char *func_name; 219 unsigned int failed = 0; 220 221 func_name = "MHD_digest_auth_calc_userhash"; 222 if (MHD_YES != MHD_digest_auth_calc_userhash (algo3, 223 data->username, data->realm, 224 hash_bin, sizeof(hash_bin))) 225 { 226 failed++; 227 fprintf (stderr, 228 "FAILED: %s() has not returned MHD_YES.\n", 229 func_name); 230 } 231 else if (0 != memcmp (hash_bin, data->hash, sizeof(data->hash))) 232 { 233 failed++; 234 bin2hex (hash_bin, sizeof(hash_bin), hash_hex); 235 bin2hex (data->hash, sizeof(data->hash), expected_hex); 236 fprintf (stderr, 237 "FAILED: %s() produced wrong hash. " 238 "Calculated digest %s, expected digest %s.\n", 239 func_name, 240 hash_hex, expected_hex); 241 } 242 243 func_name = "MHD_digest_auth_calc_userhash_hex"; 244 if (MHD_YES != 245 MHD_digest_auth_calc_userhash_hex (algo3, 246 data->username, data->realm, 247 hash_hex, sizeof(hash_hex))) 248 { 249 failed++; 250 fprintf (stderr, 251 "FAILED: %s() has not returned MHD_YES.\n", 252 func_name); 253 } 254 else if (sizeof(hash_hex) - 1 != strlen (hash_hex)) 255 { 256 failed++; 257 fprintf (stderr, 258 "FAILED: %s produced hash with wrong length. " 259 "Calculated length %u, expected digest %u.\n", 260 func_name, 261 (unsigned) strlen (hash_hex), 262 (unsigned) (sizeof(hash_hex) - 1)); 263 } 264 else 265 { 266 bin2hex (data->hash, sizeof(data->hash), expected_hex); 267 if (0 != memcmp (hash_hex, expected_hex, sizeof(hash_hex))) 268 { 269 failed++; 270 fprintf (stderr, 271 "FAILED: %s() produced wrong hash. " 272 "Calculated digest %s, expected digest %s.\n", 273 func_name, 274 hash_hex, expected_hex); 275 } 276 } 277 278 if (failed) 279 { 280 fprintf (stderr, 281 "The check failed for data located at line: %u.\n", 282 data->line_num); 283 fflush (stderr); 284 } 285 else if (verbose) 286 { 287 printf ("PASSED: check for data at line: %u.\n", 288 data->line_num); 289 } 290 return failed ? 1 : 0; 291 } 292 293 294 static unsigned int 295 test_md5 (void) 296 { 297 unsigned int num_failed = 0; 298 size_t i; 299 300 for (i = 0; i < sizeof(md5_tests) / sizeof(md5_tests[0]); i++) 301 num_failed += check_md5 (md5_tests + i); 302 return num_failed; 303 } 304 305 306 static unsigned int 307 test_md5_failure (void) 308 { 309 static const enum MHD_DigestAuthAlgo3 algo3 = MHD_DIGEST_AUTH_ALGO3_MD5; 310 uint8_t hash_bin[MHD_MD5_DIGEST_SIZE]; 311 char hash_hex[MHD_MD5_DIGEST_SIZE * 2 + 1]; 312 const char *func_name; 313 unsigned int failed = 0; 314 315 func_name = "MHD_digest_auth_calc_userhash"; 316 if (MHD_NO != MHD_digest_auth_calc_userhash (algo3, 317 "u", "r", 318 hash_bin, sizeof(hash_bin) - 1)) 319 { 320 failed++; 321 fprintf (stderr, 322 "FAILED: %s() has not returned MHD_NO at line: %u.\n", 323 func_name, (unsigned) __LINE__); 324 } 325 if (MHD_NO != MHD_digest_auth_calc_userhash (algo3, 326 "u", "r", 327 hash_bin, 0)) 328 { 329 failed++; 330 fprintf (stderr, 331 "FAILED: %s() has not returned MHD_NO at line: %u.\n", 332 func_name, (unsigned) __LINE__); 333 } 334 if (MHD_NO == MHD_is_feature_supported (MHD_FEATURE_DIGEST_AUTH_MD5)) 335 { 336 if (MHD_NO != MHD_digest_auth_calc_userhash (algo3, 337 "u", "r", 338 hash_bin, sizeof(hash_bin))) 339 { 340 failed++; 341 fprintf (stderr, 342 "FAILED: %s() has not returned MHD_NO at line: %u.\n", 343 func_name, (unsigned) __LINE__); 344 } 345 } 346 347 func_name = "MHD_digest_auth_calc_userhash_hex"; 348 if (MHD_NO != 349 MHD_digest_auth_calc_userhash_hex (algo3, 350 "u", "r", 351 hash_hex, sizeof(hash_hex) - 1)) 352 { 353 failed++; 354 fprintf (stderr, 355 "FAILED: %s() has not returned MHD_NO at line: %u.\n", 356 func_name, (unsigned) __LINE__); 357 } 358 if (MHD_NO != 359 MHD_digest_auth_calc_userhash_hex (algo3, 360 "u", "r", 361 hash_hex, 0)) 362 { 363 failed++; 364 fprintf (stderr, 365 "FAILED: %s() has not returned MHD_NO at line: %u.\n", 366 func_name, (unsigned) __LINE__); 367 } 368 if (MHD_NO == MHD_is_feature_supported (MHD_FEATURE_DIGEST_AUTH_MD5)) 369 { 370 if (MHD_NO != 371 MHD_digest_auth_calc_userhash_hex (algo3, 372 "u", "r", 373 hash_hex, sizeof(hash_hex))) 374 { 375 failed++; 376 fprintf (stderr, 377 "FAILED: %s() has not returned MHD_NO at line: %u.\n", 378 func_name, (unsigned) __LINE__); 379 } 380 } 381 382 if (! failed && verbose) 383 { 384 printf ("PASSED: all checks with expected MHD_NO result near line: %u.\n", 385 (unsigned) __LINE__); 386 } 387 return failed ? 1 : 0; 388 } 389 390 391 static unsigned int 392 check_sha256 (const struct data_sha256 *const data) 393 { 394 static const enum MHD_DigestAuthAlgo3 algo3 = MHD_DIGEST_AUTH_ALGO3_SHA256; 395 uint8_t hash_bin[MHD_SHA256_DIGEST_SIZE]; 396 char hash_hex[MHD_SHA256_DIGEST_SIZE * 2 + 1]; 397 char expected_hex[MHD_SHA256_DIGEST_SIZE * 2 + 1]; 398 const char *func_name; 399 unsigned int failed = 0; 400 401 func_name = "MHD_digest_auth_calc_userhash"; 402 if (MHD_YES != MHD_digest_auth_calc_userhash (algo3, 403 data->username, data->realm, 404 hash_bin, sizeof(hash_bin))) 405 { 406 failed++; 407 fprintf (stderr, 408 "FAILED: %s() has not returned MHD_YES.\n", 409 func_name); 410 } 411 else if (0 != memcmp (hash_bin, data->hash, sizeof(data->hash))) 412 { 413 failed++; 414 bin2hex (hash_bin, sizeof(hash_bin), hash_hex); 415 bin2hex (data->hash, sizeof(data->hash), expected_hex); 416 fprintf (stderr, 417 "FAILED: %s() produced wrong hash. " 418 "Calculated digest %s, expected digest %s.\n", 419 func_name, 420 hash_hex, expected_hex); 421 } 422 423 func_name = "MHD_digest_auth_calc_userhash_hex"; 424 if (MHD_YES != 425 MHD_digest_auth_calc_userhash_hex (algo3, 426 data->username, data->realm, 427 hash_hex, sizeof(hash_hex))) 428 { 429 failed++; 430 fprintf (stderr, 431 "FAILED: %s() has not returned MHD_YES.\n", 432 func_name); 433 } 434 else if (sizeof(hash_hex) - 1 != strlen (hash_hex)) 435 { 436 failed++; 437 fprintf (stderr, 438 "FAILED: %s produced hash with wrong length. " 439 "Calculated length %u, expected digest %u.\n", 440 func_name, 441 (unsigned) strlen (hash_hex), 442 (unsigned) (sizeof(hash_hex) - 1)); 443 } 444 else 445 { 446 bin2hex (data->hash, sizeof(data->hash), expected_hex); 447 if (0 != memcmp (hash_hex, expected_hex, sizeof(hash_hex))) 448 { 449 failed++; 450 fprintf (stderr, 451 "FAILED: %s() produced wrong hash. " 452 "Calculated digest %s, expected digest %s.\n", 453 func_name, 454 hash_hex, expected_hex); 455 } 456 } 457 458 if (failed) 459 { 460 fprintf (stderr, 461 "The check failed for data located at line: %u.\n", 462 data->line_num); 463 fflush (stderr); 464 } 465 else if (verbose) 466 { 467 printf ("PASSED: check for data at line: %u.\n", 468 data->line_num); 469 } 470 return failed ? 1 : 0; 471 } 472 473 474 static unsigned int 475 test_sha256 (void) 476 { 477 unsigned int num_failed = 0; 478 size_t i; 479 480 for (i = 0; i < sizeof(sha256_tests) / sizeof(sha256_tests[0]); i++) 481 num_failed += check_sha256 (sha256_tests + i); 482 return num_failed; 483 } 484 485 486 static unsigned int 487 test_sha256_failure (void) 488 { 489 static const enum MHD_DigestAuthAlgo3 algo3 = MHD_DIGEST_AUTH_ALGO3_SHA256; 490 uint8_t hash_bin[MHD_SHA256_DIGEST_SIZE]; 491 char hash_hex[MHD_SHA256_DIGEST_SIZE * 2 + 1]; 492 const char *func_name; 493 unsigned int failed = 0; 494 495 func_name = "MHD_digest_auth_calc_userhash"; 496 if (MHD_NO != MHD_digest_auth_calc_userhash (algo3, 497 "u", "r", 498 hash_bin, sizeof(hash_bin) - 1)) 499 { 500 failed++; 501 fprintf (stderr, 502 "FAILED: %s() has not returned MHD_NO at line: %u.\n", 503 func_name, (unsigned) __LINE__); 504 } 505 if (MHD_NO != MHD_digest_auth_calc_userhash (algo3, 506 "u", "r", 507 hash_bin, 0)) 508 { 509 failed++; 510 fprintf (stderr, 511 "FAILED: %s() has not returned MHD_NO at line: %u.\n", 512 func_name, (unsigned) __LINE__); 513 } 514 if (MHD_NO == MHD_is_feature_supported (MHD_FEATURE_DIGEST_AUTH_SHA256)) 515 { 516 if (MHD_NO != MHD_digest_auth_calc_userhash (algo3, 517 "u", "r", 518 hash_bin, sizeof(hash_bin))) 519 { 520 failed++; 521 fprintf (stderr, 522 "FAILED: %s() has not returned MHD_NO at line: %u.\n", 523 func_name, (unsigned) __LINE__); 524 } 525 } 526 527 func_name = "MHD_digest_auth_calc_userhash_hex"; 528 if (MHD_NO != 529 MHD_digest_auth_calc_userhash_hex (algo3, 530 "u", "r", 531 hash_hex, sizeof(hash_hex) - 1)) 532 { 533 failed++; 534 fprintf (stderr, 535 "FAILED: %s() has not returned MHD_NO at line: %u.\n", 536 func_name, (unsigned) __LINE__); 537 } 538 if (MHD_NO != 539 MHD_digest_auth_calc_userhash_hex (algo3, 540 "u", "r", 541 hash_hex, 0)) 542 { 543 failed++; 544 fprintf (stderr, 545 "FAILED: %s() has not returned MHD_NO at line: %u.\n", 546 func_name, (unsigned) __LINE__); 547 } 548 if (MHD_NO == MHD_is_feature_supported (MHD_FEATURE_DIGEST_AUTH_SHA256)) 549 { 550 if (MHD_NO != 551 MHD_digest_auth_calc_userhash_hex (algo3, 552 "u", "r", 553 hash_hex, sizeof(hash_hex))) 554 { 555 failed++; 556 fprintf (stderr, 557 "FAILED: %s() has not returned MHD_NO at line: %u.\n", 558 func_name, (unsigned) __LINE__); 559 } 560 } 561 562 if (! failed && verbose) 563 { 564 printf ("PASSED: all checks with expected MHD_NO result near line: %u.\n", 565 (unsigned) __LINE__); 566 } 567 return failed ? 1 : 0; 568 } 569 570 571 static unsigned int 572 check_sha512_256 (const struct data_sha512_256 *const data) 573 { 574 static const enum MHD_DigestAuthAlgo3 algo3 = 575 MHD_DIGEST_AUTH_ALGO3_SHA512_256; 576 uint8_t hash_bin[MHD_SHA512_256_DIGEST_SIZE]; 577 char hash_hex[MHD_SHA512_256_DIGEST_SIZE * 2 + 1]; 578 char expected_hex[MHD_SHA512_256_DIGEST_SIZE * 2 + 1]; 579 const char *func_name; 580 unsigned int failed = 0; 581 582 func_name = "MHD_digest_auth_calc_userhash"; 583 if (MHD_YES != MHD_digest_auth_calc_userhash (algo3, 584 data->username, data->realm, 585 hash_bin, sizeof(hash_bin))) 586 { 587 failed++; 588 fprintf (stderr, 589 "FAILED: %s() has not returned MHD_YES.\n", 590 func_name); 591 } 592 else if (0 != memcmp (hash_bin, data->hash, sizeof(data->hash))) 593 { 594 failed++; 595 bin2hex (hash_bin, sizeof(hash_bin), hash_hex); 596 bin2hex (data->hash, sizeof(data->hash), expected_hex); 597 fprintf (stderr, 598 "FAILED: %s() produced wrong hash. " 599 "Calculated digest %s, expected digest %s.\n", 600 func_name, 601 hash_hex, expected_hex); 602 } 603 604 func_name = "MHD_digest_auth_calc_userhash_hex"; 605 if (MHD_YES != 606 MHD_digest_auth_calc_userhash_hex (algo3, 607 data->username, data->realm, 608 hash_hex, sizeof(hash_hex))) 609 { 610 failed++; 611 fprintf (stderr, 612 "FAILED: %s() has not returned MHD_YES.\n", 613 func_name); 614 } 615 else if (sizeof(hash_hex) - 1 != strlen (hash_hex)) 616 { 617 failed++; 618 fprintf (stderr, 619 "FAILED: %s produced hash with wrong length. " 620 "Calculated length %u, expected digest %u.\n", 621 func_name, 622 (unsigned) strlen (hash_hex), 623 (unsigned) (sizeof(hash_hex) - 1)); 624 } 625 else 626 { 627 bin2hex (data->hash, sizeof(data->hash), expected_hex); 628 if (0 != memcmp (hash_hex, expected_hex, sizeof(hash_hex))) 629 { 630 failed++; 631 fprintf (stderr, 632 "FAILED: %s() produced wrong hash. " 633 "Calculated digest %s, expected digest %s.\n", 634 func_name, 635 hash_hex, expected_hex); 636 } 637 } 638 639 if (failed) 640 { 641 fprintf (stderr, 642 "The check failed for data located at line: %u.\n", 643 data->line_num); 644 fflush (stderr); 645 } 646 else if (verbose) 647 { 648 printf ("PASSED: check for data at line: %u.\n", 649 data->line_num); 650 } 651 return failed ? 1 : 0; 652 } 653 654 655 static unsigned int 656 test_sha512_256 (void) 657 { 658 unsigned int num_failed = 0; 659 size_t i; 660 661 for (i = 0; i < sizeof(sha512_256_tests) / sizeof(sha512_256_tests[0]); i++) 662 num_failed += check_sha512_256 (sha512_256_tests + i); 663 return num_failed; 664 } 665 666 667 static unsigned int 668 test_sha512_256_failure (void) 669 { 670 static const enum MHD_DigestAuthAlgo3 algo3 = 671 MHD_DIGEST_AUTH_ALGO3_SHA512_256; 672 static const enum MHD_FEATURE feature = MHD_FEATURE_DIGEST_AUTH_SHA512_256; 673 uint8_t hash_bin[MHD_SHA512_256_DIGEST_SIZE]; 674 char hash_hex[MHD_SHA512_256_DIGEST_SIZE * 2 + 1]; 675 const char *func_name; 676 unsigned int failed = 0; 677 678 func_name = "MHD_digest_auth_calc_userhash"; 679 if (MHD_NO != MHD_digest_auth_calc_userhash (algo3, 680 "u", "r", 681 hash_bin, sizeof(hash_bin) - 1)) 682 { 683 failed++; 684 fprintf (stderr, 685 "FAILED: %s() has not returned MHD_NO at line: %u.\n", 686 func_name, (unsigned) __LINE__); 687 } 688 if (MHD_NO != MHD_digest_auth_calc_userhash (algo3, 689 "u", "r", 690 hash_bin, 0)) 691 { 692 failed++; 693 fprintf (stderr, 694 "FAILED: %s() has not returned MHD_NO at line: %u.\n", 695 func_name, (unsigned) __LINE__); 696 } 697 if (MHD_NO == MHD_is_feature_supported (feature)) 698 { 699 if (MHD_NO != MHD_digest_auth_calc_userhash (algo3, 700 "u", "r", 701 hash_bin, sizeof(hash_bin))) 702 { 703 failed++; 704 fprintf (stderr, 705 "FAILED: %s() has not returned MHD_NO at line: %u.\n", 706 func_name, (unsigned) __LINE__); 707 } 708 } 709 710 func_name = "MHD_digest_auth_calc_userhash_hex"; 711 if (MHD_NO != 712 MHD_digest_auth_calc_userhash_hex (algo3, 713 "u", "r", 714 hash_hex, sizeof(hash_hex) - 1)) 715 { 716 failed++; 717 fprintf (stderr, 718 "FAILED: %s() has not returned MHD_NO at line: %u.\n", 719 func_name, (unsigned) __LINE__); 720 } 721 if (MHD_NO != 722 MHD_digest_auth_calc_userhash_hex (algo3, 723 "u", "r", 724 hash_hex, 0)) 725 { 726 failed++; 727 fprintf (stderr, 728 "FAILED: %s() has not returned MHD_NO at line: %u.\n", 729 func_name, (unsigned) __LINE__); 730 } 731 if (MHD_NO == MHD_is_feature_supported (feature)) 732 { 733 if (MHD_NO != 734 MHD_digest_auth_calc_userhash_hex (algo3, 735 "u", "r", 736 hash_hex, sizeof(hash_hex))) 737 { 738 failed++; 739 fprintf (stderr, 740 "FAILED: %s() has not returned MHD_NO at line: %u.\n", 741 func_name, (unsigned) __LINE__); 742 } 743 } 744 745 if (! failed && verbose) 746 { 747 printf ("PASSED: all checks with expected MHD_NO result near line: %u.\n", 748 (unsigned) __LINE__); 749 } 750 return failed ? 1 : 0; 751 } 752 753 754 int 755 main (int argc, char *argv[]) 756 { 757 unsigned int num_failed = 0; 758 (void) has_in_name; /* Mute compiler warning. */ 759 if (has_param (argc, argv, "-s") || has_param (argc, argv, "--silent")) 760 verbose = 0; 761 762 #ifdef NEED_GCRYP_INIT 763 gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0); 764 #ifdef GCRYCTL_INITIALIZATION_FINISHED 765 gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); 766 #endif /* GCRYCTL_INITIALIZATION_FINISHED */ 767 #endif /* NEED_GCRYP_INIT */ 768 769 if (MHD_is_feature_supported (MHD_FEATURE_DIGEST_AUTH_MD5)) 770 num_failed += test_md5 (); 771 num_failed += test_md5_failure (); 772 if (MHD_is_feature_supported (MHD_FEATURE_DIGEST_AUTH_SHA256)) 773 num_failed += test_sha256 (); 774 num_failed += test_sha256_failure (); 775 if (MHD_is_feature_supported (MHD_FEATURE_DIGEST_AUTH_SHA512_256)) 776 num_failed += test_sha512_256 (); 777 num_failed += test_sha512_256_failure (); 778 779 return num_failed ? 1 : 0; 780 }