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