00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include <config.h>
00026 #include "dbus-internals.h"
00027 #include "dbus-sha.h"
00028 #include "dbus-marshal-basic.h"
00029 #include <string.h>
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00088 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00089
00090
00091
00092 #define SHA_DATASIZE 64
00093 #define SHA_DIGESTSIZE 20
00094
00095
00096
00097
00098
00099
00100 #define f1(x,y,z) ( z ^ ( x & ( y ^ z ) ) )
00101 #define f2(x,y,z) ( x ^ y ^ z )
00102
00103 #define f3(x,y,z) ( ( x & y ) | ( z & ( x | y ) ) )
00104 #define f4(x,y,z) ( x ^ y ^ z )
00105
00106
00107
00108 #define K1 0x5A827999L
00109 #define K2 0x6ED9EBA1L
00110 #define K3 0x8F1BBCDCL
00111 #define K4 0xCA62C1D6L
00112
00113
00114
00115 #define h0init 0x67452301L
00116 #define h1init 0xEFCDAB89L
00117 #define h2init 0x98BADCFEL
00118 #define h3init 0x10325476L
00119 #define h4init 0xC3D2E1F0L
00120
00121
00122
00123
00124
00125 #define ROTL(n,X) ( ( ( X ) << n ) | ( ( X ) >> ( 32 - n ) ) )
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141 #define expand(W,i) ( W[ i & 15 ] = ROTL( 1, ( W[ i & 15 ] ^ W[ (i - 14) & 15 ] ^ \
00142 W[ (i - 8) & 15 ] ^ W[ (i - 3) & 15 ] ) ) )
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158 #define subRound(a, b, c, d, e, f, k, data) \
00159 ( e += ROTL( 5, a ) + f( b, c, d ) + k + data, b = ROTL( 30, b ) )
00160
00161 #endif
00162
00163
00164
00165
00166
00167
00168
00169
00170 static void
00171 SHATransform(dbus_uint32_t *digest, dbus_uint32_t *data)
00172 {
00173 dbus_uint32_t A, B, C, D, E;
00174 dbus_uint32_t eData[16];
00175
00176
00177 A = digest[0];
00178 B = digest[1];
00179 C = digest[2];
00180 D = digest[3];
00181 E = digest[4];
00182 memmove (eData, data, SHA_DATASIZE);
00183
00184
00185 subRound (A, B, C, D, E, f1, K1, eData[0]);
00186 subRound (E, A, B, C, D, f1, K1, eData[1]);
00187 subRound (D, E, A, B, C, f1, K1, eData[2]);
00188 subRound (C, D, E, A, B, f1, K1, eData[3]);
00189 subRound (B, C, D, E, A, f1, K1, eData[4]);
00190 subRound (A, B, C, D, E, f1, K1, eData[5]);
00191 subRound (E, A, B, C, D, f1, K1, eData[6]);
00192 subRound (D, E, A, B, C, f1, K1, eData[7]);
00193 subRound (C, D, E, A, B, f1, K1, eData[8]);
00194 subRound (B, C, D, E, A, f1, K1, eData[9]);
00195 subRound (A, B, C, D, E, f1, K1, eData[10]);
00196 subRound (E, A, B, C, D, f1, K1, eData[11]);
00197 subRound (D, E, A, B, C, f1, K1, eData[12]);
00198 subRound (C, D, E, A, B, f1, K1, eData[13]);
00199 subRound (B, C, D, E, A, f1, K1, eData[14]);
00200 subRound (A, B, C, D, E, f1, K1, eData[15]);
00201 subRound (E, A, B, C, D, f1, K1, expand ( eData, 16) );
00202 subRound (D, E, A, B, C, f1, K1, expand ( eData, 17) );
00203 subRound (C, D, E, A, B, f1, K1, expand ( eData, 18) );
00204 subRound (B, C, D, E, A, f1, K1, expand ( eData, 19) );
00205
00206 subRound (A, B, C, D, E, f2, K2, expand ( eData, 20) );
00207 subRound (E, A, B, C, D, f2, K2, expand ( eData, 21) );
00208 subRound (D, E, A, B, C, f2, K2, expand ( eData, 22) );
00209 subRound (C, D, E, A, B, f2, K2, expand ( eData, 23) );
00210 subRound (B, C, D, E, A, f2, K2, expand ( eData, 24) );
00211 subRound (A, B, C, D, E, f2, K2, expand ( eData, 25) );
00212 subRound (E, A, B, C, D, f2, K2, expand ( eData, 26) );
00213 subRound (D, E, A, B, C, f2, K2, expand ( eData, 27) );
00214 subRound (C, D, E, A, B, f2, K2, expand ( eData, 28) );
00215 subRound (B, C, D, E, A, f2, K2, expand ( eData, 29) );
00216 subRound (A, B, C, D, E, f2, K2, expand ( eData, 30) );
00217 subRound (E, A, B, C, D, f2, K2, expand ( eData, 31) );
00218 subRound (D, E, A, B, C, f2, K2, expand ( eData, 32) );
00219 subRound (C, D, E, A, B, f2, K2, expand ( eData, 33) );
00220 subRound (B, C, D, E, A, f2, K2, expand ( eData, 34) );
00221 subRound (A, B, C, D, E, f2, K2, expand ( eData, 35) );
00222 subRound (E, A, B, C, D, f2, K2, expand ( eData, 36) );
00223 subRound (D, E, A, B, C, f2, K2, expand ( eData, 37) );
00224 subRound (C, D, E, A, B, f2, K2, expand ( eData, 38) );
00225 subRound (B, C, D, E, A, f2, K2, expand ( eData, 39) );
00226
00227 subRound (A, B, C, D, E, f3, K3, expand ( eData, 40) );
00228 subRound (E, A, B, C, D, f3, K3, expand ( eData, 41) );
00229 subRound (D, E, A, B, C, f3, K3, expand ( eData, 42) );
00230 subRound (C, D, E, A, B, f3, K3, expand ( eData, 43) );
00231 subRound (B, C, D, E, A, f3, K3, expand ( eData, 44) );
00232 subRound (A, B, C, D, E, f3, K3, expand ( eData, 45) );
00233 subRound (E, A, B, C, D, f3, K3, expand ( eData, 46) );
00234 subRound (D, E, A, B, C, f3, K3, expand ( eData, 47) );
00235 subRound (C, D, E, A, B, f3, K3, expand ( eData, 48) );
00236 subRound (B, C, D, E, A, f3, K3, expand ( eData, 49) );
00237 subRound (A, B, C, D, E, f3, K3, expand ( eData, 50) );
00238 subRound (E, A, B, C, D, f3, K3, expand ( eData, 51) );
00239 subRound (D, E, A, B, C, f3, K3, expand ( eData, 52) );
00240 subRound (C, D, E, A, B, f3, K3, expand ( eData, 53) );
00241 subRound (B, C, D, E, A, f3, K3, expand ( eData, 54) );
00242 subRound (A, B, C, D, E, f3, K3, expand ( eData, 55) );
00243 subRound (E, A, B, C, D, f3, K3, expand ( eData, 56) );
00244 subRound (D, E, A, B, C, f3, K3, expand ( eData, 57) );
00245 subRound (C, D, E, A, B, f3, K3, expand ( eData, 58) );
00246 subRound (B, C, D, E, A, f3, K3, expand ( eData, 59) );
00247
00248 subRound (A, B, C, D, E, f4, K4, expand ( eData, 60) );
00249 subRound (E, A, B, C, D, f4, K4, expand ( eData, 61) );
00250 subRound (D, E, A, B, C, f4, K4, expand ( eData, 62) );
00251 subRound (C, D, E, A, B, f4, K4, expand ( eData, 63) );
00252 subRound (B, C, D, E, A, f4, K4, expand ( eData, 64) );
00253 subRound (A, B, C, D, E, f4, K4, expand ( eData, 65) );
00254 subRound (E, A, B, C, D, f4, K4, expand ( eData, 66) );
00255 subRound (D, E, A, B, C, f4, K4, expand ( eData, 67) );
00256 subRound (C, D, E, A, B, f4, K4, expand ( eData, 68) );
00257 subRound (B, C, D, E, A, f4, K4, expand ( eData, 69) );
00258 subRound (A, B, C, D, E, f4, K4, expand ( eData, 70) );
00259 subRound (E, A, B, C, D, f4, K4, expand ( eData, 71) );
00260 subRound (D, E, A, B, C, f4, K4, expand ( eData, 72) );
00261 subRound (C, D, E, A, B, f4, K4, expand ( eData, 73) );
00262 subRound (B, C, D, E, A, f4, K4, expand ( eData, 74) );
00263 subRound (A, B, C, D, E, f4, K4, expand ( eData, 75) );
00264 subRound (E, A, B, C, D, f4, K4, expand ( eData, 76) );
00265 subRound (D, E, A, B, C, f4, K4, expand ( eData, 77) );
00266 subRound (C, D, E, A, B, f4, K4, expand ( eData, 78) );
00267 subRound (B, C, D, E, A, f4, K4, expand ( eData, 79) );
00268
00269
00270 digest[0] += A;
00271 digest[1] += B;
00272 digest[2] += C;
00273 digest[3] += D;
00274 digest[4] += E;
00275 }
00276
00277
00278
00279
00280 #ifdef WORDS_BIGENDIAN
00281 #define swap_words(buffer, byte_count)
00282 #else
00283 static void
00284 swap_words (dbus_uint32_t *buffer,
00285 int byte_count)
00286 {
00287 byte_count /= sizeof (dbus_uint32_t);
00288 while (byte_count--)
00289 {
00290 *buffer = DBUS_UINT32_SWAP_LE_BE (*buffer);
00291 ++buffer;
00292 }
00293 }
00294 #endif
00295
00296 static void
00297 sha_init (DBusSHAContext *context)
00298 {
00299
00300 context->digest[0] = h0init;
00301 context->digest[1] = h1init;
00302 context->digest[2] = h2init;
00303 context->digest[3] = h3init;
00304 context->digest[4] = h4init;
00305
00306
00307 context->count_lo = context->count_hi = 0;
00308 }
00309
00310 static void
00311 sha_append (DBusSHAContext *context,
00312 const unsigned char *buffer,
00313 unsigned int count)
00314 {
00315 dbus_uint32_t tmp;
00316 unsigned int dataCount;
00317
00318
00319 tmp = context->count_lo;
00320 if (( context->count_lo = tmp + ( ( dbus_uint32_t) count << 3) ) < tmp)
00321 context->count_hi++;
00322 context->count_hi += count >> 29;
00323
00324
00325 dataCount = (int) (tmp >> 3) & 0x3F;
00326
00327
00328 if (dataCount)
00329 {
00330 unsigned char *p = (unsigned char *) context->data + dataCount;
00331
00332 dataCount = SHA_DATASIZE - dataCount;
00333 if (count < dataCount)
00334 {
00335 memmove (p, buffer, count);
00336 return;
00337 }
00338 memmove (p, buffer, dataCount);
00339 swap_words (context->data, SHA_DATASIZE);
00340 SHATransform (context->digest, context->data);
00341 buffer += dataCount;
00342 count -= dataCount;
00343 }
00344
00345
00346 while (count >= SHA_DATASIZE)
00347 {
00348 memmove (context->data, buffer, SHA_DATASIZE);
00349 swap_words (context->data, SHA_DATASIZE);
00350 SHATransform (context->digest, context->data);
00351 buffer += SHA_DATASIZE;
00352 count -= SHA_DATASIZE;
00353 }
00354
00355
00356 memmove (context->data, buffer, count);
00357 }
00358
00359
00360
00361
00362
00363 static void
00364 sha_finish (DBusSHAContext *context, unsigned char digest[20])
00365 {
00366 int count;
00367 unsigned char *data_p;
00368
00369
00370 count = (int) context->count_lo;
00371 count = (count >> 3) & 0x3F;
00372
00373
00374
00375 data_p = (unsigned char *) context->data + count;
00376 *data_p++ = 0x80;
00377
00378
00379 count = SHA_DATASIZE - 1 - count;
00380
00381
00382 if (count < 8)
00383 {
00384
00385 memset (data_p, 0, count);
00386 swap_words (context->data, SHA_DATASIZE);
00387 SHATransform (context->digest, context->data);
00388
00389
00390 memset (context->data, 0, SHA_DATASIZE - 8);
00391 }
00392 else
00393
00394 memset (data_p, 0, count - 8);
00395
00396
00397 context->data[14] = context->count_hi;
00398 context->data[15] = context->count_lo;
00399
00400 swap_words (context->data, SHA_DATASIZE - 8);
00401 SHATransform (context->digest, context->data);
00402 swap_words (context->digest, SHA_DIGESTSIZE);
00403 memmove (digest, context->digest, SHA_DIGESTSIZE);
00404 }
00405
00407
00419 void
00420 _dbus_sha_init (DBusSHAContext *context)
00421 {
00422 sha_init (context);
00423 }
00424
00431 void
00432 _dbus_sha_update (DBusSHAContext *context,
00433 const DBusString *data)
00434 {
00435 unsigned int inputLen;
00436 const unsigned char *input;
00437
00438 input = (const unsigned char*) _dbus_string_get_const_data (data);
00439 inputLen = _dbus_string_get_length (data);
00440
00441 sha_append (context, input, inputLen);
00442 }
00443
00455 dbus_bool_t
00456 _dbus_sha_final (DBusSHAContext *context,
00457 DBusString *results)
00458 {
00459 unsigned char digest[20];
00460
00461 sha_finish (context, digest);
00462
00463 if (!_dbus_string_append_len (results, digest, 20))
00464 return FALSE;
00465
00466
00467
00468
00469 _DBUS_ZERO(*context);
00470
00471 return TRUE;
00472 }
00473
00482 dbus_bool_t
00483 _dbus_sha_compute (const DBusString *data,
00484 DBusString *ascii_output)
00485 {
00486 DBusSHAContext context;
00487 DBusString digest;
00488
00489 _dbus_sha_init (&context);
00490
00491 _dbus_sha_update (&context, data);
00492
00493 if (!_dbus_string_init (&digest))
00494 return FALSE;
00495
00496 if (!_dbus_sha_final (&context, &digest))
00497 goto error;
00498
00499 if (!_dbus_string_hex_encode (&digest, 0, ascii_output,
00500 _dbus_string_get_length (ascii_output)))
00501 goto error;
00502
00503 _dbus_string_free (&digest);
00504
00505 return TRUE;
00506
00507 error:
00508 _dbus_string_free (&digest);
00509 return FALSE;
00510 }
00511
00513
00514 #ifdef DBUS_BUILD_TESTS
00515 #include "dbus-test.h"
00516 #include <stdio.h>
00517
00518 static dbus_bool_t
00519 check_sha_binary (const unsigned char *input,
00520 int input_len,
00521 const char *expected)
00522 {
00523 DBusString input_str;
00524 DBusString expected_str;
00525 DBusString results;
00526
00527 _dbus_string_init_const_len (&input_str, input, input_len);
00528 _dbus_string_init_const (&expected_str, expected);
00529
00530 if (!_dbus_string_init (&results))
00531 _dbus_assert_not_reached ("no memory for SHA-1 results");
00532
00533 if (!_dbus_sha_compute (&input_str, &results))
00534 _dbus_assert_not_reached ("no memory for SHA-1 results");
00535
00536 if (!_dbus_string_equal (&expected_str, &results))
00537 {
00538 _dbus_warn ("Expected hash %s got %s for SHA-1 sum\n",
00539 expected,
00540 _dbus_string_get_const_data (&results));
00541 _dbus_string_free (&results);
00542 return FALSE;
00543 }
00544
00545 _dbus_string_free (&results);
00546 return TRUE;
00547 }
00548
00549 static dbus_bool_t
00550 check_sha_str (const char *input,
00551 const char *expected)
00552 {
00553 return check_sha_binary (input, strlen (input), expected);
00554 }
00555
00556 static dbus_bool_t
00557 decode_compact_string (const DBusString *line,
00558 DBusString *decoded)
00559 {
00560 int n_bits;
00561 dbus_bool_t current_b;
00562 int offset;
00563 int next;
00564 long val;
00565 int length_bytes;
00566
00567 offset = 0;
00568 next = 0;
00569
00570 if (!_dbus_string_parse_int (line, offset, &val, &next))
00571 {
00572 fprintf (stderr, "could not parse length at start of compact string: %s\n",
00573 _dbus_string_get_const_data (line));
00574 return FALSE;
00575 }
00576
00577 _dbus_string_skip_blank (line, next, &next);
00578
00579 offset = next;
00580 if (!_dbus_string_parse_int (line, offset, &val, &next))
00581 {
00582 fprintf (stderr, "could not parse start bit 'b' in compact string: %s\n",
00583 _dbus_string_get_const_data (line));
00584 return FALSE;
00585 }
00586
00587 if (!(val == 0 || val == 1))
00588 {
00589 fprintf (stderr, "the value 'b' must be 0 or 1, see sha-1/Readme.txt\n");
00590 return FALSE;
00591 }
00592
00593 _dbus_string_skip_blank (line, next, &next);
00594
00595 current_b = val;
00596 n_bits = 0;
00597
00598 while (next < _dbus_string_get_length (line))
00599 {
00600 int total_bits;
00601
00602 offset = next;
00603
00604 if (_dbus_string_get_byte (line, offset) == '^')
00605 break;
00606
00607 if (!_dbus_string_parse_int (line, offset, &val, &next))
00608 {
00609 fprintf (stderr, "could not parse bit count in compact string\n");
00610 return FALSE;
00611 }
00612
00613
00614 total_bits = n_bits + val;
00615 while (n_bits < total_bits)
00616 {
00617 int byte_containing_next_bit = n_bits / 8;
00618 int bit_containing_next_bit = 7 - (n_bits % 8);
00619 unsigned char old_byte;
00620
00621 if (byte_containing_next_bit >= _dbus_string_get_length (decoded))
00622 {
00623 if (!_dbus_string_set_length (decoded, byte_containing_next_bit + 1))
00624 _dbus_assert_not_reached ("no memory to extend to next byte");
00625 }
00626
00627 old_byte = _dbus_string_get_byte (decoded, byte_containing_next_bit);
00628 old_byte |= current_b << bit_containing_next_bit;
00629
00630 #if 0
00631 printf ("Appending bit %d to byte %d at bit %d resulting in byte 0x%x\n",
00632 current_b, byte_containing_next_bit,
00633 bit_containing_next_bit, old_byte);
00634 #endif
00635
00636 _dbus_string_set_byte (decoded, byte_containing_next_bit, old_byte);
00637
00638 ++n_bits;
00639 }
00640
00641 _dbus_string_skip_blank (line, next, &next);
00642
00643 current_b = !current_b;
00644 }
00645
00646 length_bytes = (n_bits / 8 + ((n_bits % 8) ? 1 : 0));
00647
00648 if (_dbus_string_get_length (decoded) != length_bytes)
00649 {
00650 fprintf (stderr, "Expected length %d bytes %d bits for compact string, got %d bytes\n",
00651 length_bytes, n_bits, _dbus_string_get_length (decoded));
00652 return FALSE;
00653 }
00654 else
00655 return TRUE;
00656 }
00657
00658 static dbus_bool_t
00659 get_next_expected_result (DBusString *results,
00660 DBusString *result)
00661 {
00662 DBusString line;
00663 dbus_bool_t retval;
00664
00665 retval = FALSE;
00666
00667 if (!_dbus_string_init (&line))
00668 _dbus_assert_not_reached ("no memory");
00669
00670 next_iteration:
00671 while (_dbus_string_pop_line (results, &line))
00672 {
00673 _dbus_string_delete_leading_blanks (&line);
00674
00675 if (_dbus_string_get_length (&line) == 0)
00676 goto next_iteration;
00677 else if (_dbus_string_starts_with_c_str (&line, "#"))
00678 goto next_iteration;
00679 else if (_dbus_string_starts_with_c_str (&line, "H>"))
00680 {
00681
00682 }
00683 else if (_dbus_string_starts_with_c_str (&line, "D>") ||
00684 _dbus_string_starts_with_c_str (&line, "<D"))
00685 goto next_iteration;
00686 else
00687 {
00688 int i;
00689
00690 if (!_dbus_string_move (&line, 0, result, 0))
00691 _dbus_assert_not_reached ("no memory");
00692
00693 i = 0;
00694 while (i < _dbus_string_get_length (result))
00695 {
00696 switch (_dbus_string_get_byte (result, i))
00697 {
00698 case 'A':
00699 _dbus_string_set_byte (result, i, 'a');
00700 break;
00701 case 'B':
00702 _dbus_string_set_byte (result, i, 'b');
00703 break;
00704 case 'C':
00705 _dbus_string_set_byte (result, i, 'c');
00706 break;
00707 case 'D':
00708 _dbus_string_set_byte (result, i, 'd');
00709 break;
00710 case 'E':
00711 _dbus_string_set_byte (result, i, 'e');
00712 break;
00713 case 'F':
00714 _dbus_string_set_byte (result, i, 'f');
00715 break;
00716 case '^':
00717 case ' ':
00718 _dbus_string_delete (result, i, 1);
00719 --i;
00720 break;
00721 }
00722
00723 ++i;
00724 }
00725
00726 break;
00727 }
00728 }
00729
00730 retval = TRUE;
00731
00732
00733 _dbus_string_free (&line);
00734 return retval;
00735 }
00736
00737 static dbus_bool_t
00738 process_test_data (const char *test_data_dir)
00739 {
00740 DBusString tests_file;
00741 DBusString results_file;
00742 DBusString tests;
00743 DBusString results;
00744 DBusString line;
00745 DBusString tmp;
00746 int line_no;
00747 dbus_bool_t retval;
00748 int success_count;
00749 DBusError error = DBUS_ERROR_INIT;
00750
00751 retval = FALSE;
00752
00753 if (!_dbus_string_init (&tests_file))
00754 _dbus_assert_not_reached ("no memory");
00755
00756 if (!_dbus_string_init (&results_file))
00757 _dbus_assert_not_reached ("no memory");
00758
00759 if (!_dbus_string_init (&tests))
00760 _dbus_assert_not_reached ("no memory");
00761
00762 if (!_dbus_string_init (&results))
00763 _dbus_assert_not_reached ("no memory");
00764
00765 if (!_dbus_string_init (&line))
00766 _dbus_assert_not_reached ("no memory");
00767
00768 if (!_dbus_string_append (&tests_file, test_data_dir))
00769 _dbus_assert_not_reached ("no memory");
00770
00771 if (!_dbus_string_append (&results_file, test_data_dir))
00772 _dbus_assert_not_reached ("no memory");
00773
00774 _dbus_string_init_const (&tmp, "sha-1/byte-messages.sha1");
00775 if (!_dbus_concat_dir_and_file (&tests_file, &tmp))
00776 _dbus_assert_not_reached ("no memory");
00777
00778 _dbus_string_init_const (&tmp, "sha-1/byte-hashes.sha1");
00779 if (!_dbus_concat_dir_and_file (&results_file, &tmp))
00780 _dbus_assert_not_reached ("no memory");
00781
00782 if (!_dbus_file_get_contents (&tests, &tests_file, &error))
00783 {
00784 fprintf (stderr, "could not load test data file %s: %s\n",
00785 _dbus_string_get_const_data (&tests_file),
00786 error.message);
00787 dbus_error_free (&error);
00788 goto out;
00789 }
00790
00791 if (!_dbus_file_get_contents (&results, &results_file, &error))
00792 {
00793 fprintf (stderr, "could not load results data file %s: %s\n",
00794 _dbus_string_get_const_data (&results_file), error.message);
00795 dbus_error_free (&error);
00796 goto out;
00797 }
00798
00799 success_count = 0;
00800 line_no = 0;
00801 next_iteration:
00802 while (_dbus_string_pop_line (&tests, &line))
00803 {
00804 line_no += 1;
00805
00806 _dbus_string_delete_leading_blanks (&line);
00807
00808 if (_dbus_string_get_length (&line) == 0)
00809 goto next_iteration;
00810 else if (_dbus_string_starts_with_c_str (&line, "#"))
00811 goto next_iteration;
00812 else if (_dbus_string_starts_with_c_str (&line, "H>"))
00813 {
00814 printf ("SHA-1: %s\n", _dbus_string_get_const_data (&line));
00815
00816 if (_dbus_string_find (&line, 0, "Type 3", NULL))
00817 {
00818
00819
00820
00821
00822
00823
00824 printf (" (ending tests due to Type 3 tests seen - this is normal)\n");
00825 break;
00826 }
00827 }
00828 else if (_dbus_string_starts_with_c_str (&line, "D>") ||
00829 _dbus_string_starts_with_c_str (&line, "<D"))
00830 goto next_iteration;
00831 else
00832 {
00833 DBusString test;
00834 DBusString result;
00835 DBusString next_line;
00836 DBusString expected;
00837 dbus_bool_t success;
00838
00839 success = FALSE;
00840
00841 if (!_dbus_string_init (&next_line))
00842 _dbus_assert_not_reached ("no memory");
00843
00844 if (!_dbus_string_init (&expected))
00845 _dbus_assert_not_reached ("no memory");
00846
00847 if (!_dbus_string_init (&test))
00848 _dbus_assert_not_reached ("no memory");
00849
00850 if (!_dbus_string_init (&result))
00851 _dbus_assert_not_reached ("no memory");
00852
00853
00854
00855
00856
00857 while (!_dbus_string_find (&line, 0, "^", NULL) &&
00858 _dbus_string_pop_line (&tests, &next_line))
00859 {
00860 if (!_dbus_string_append_byte (&line, ' ') ||
00861 !_dbus_string_move (&next_line, 0, &line,
00862 _dbus_string_get_length (&line)))
00863 _dbus_assert_not_reached ("no memory");
00864 }
00865
00866 if (!decode_compact_string (&line, &test))
00867 {
00868 fprintf (stderr, "Failed to decode line %d as a compact string\n",
00869 line_no);
00870 goto failure;
00871 }
00872
00873 if (!_dbus_sha_compute (&test, &result))
00874 _dbus_assert_not_reached ("no memory for SHA-1 result");
00875
00876 if (!get_next_expected_result (&results, &expected))
00877 {
00878 fprintf (stderr, "Failed to read an expected result\n");
00879 goto failure;
00880 }
00881
00882 if (!_dbus_string_equal (&result, &expected))
00883 {
00884 fprintf (stderr, " for line %d got hash %s expected %s\n",
00885 line_no,
00886 _dbus_string_get_const_data (&result),
00887 _dbus_string_get_const_data (&expected));
00888 goto failure;
00889 }
00890 else
00891 {
00892 success_count += 1;
00893 }
00894
00895 success = TRUE;
00896
00897 failure:
00898 _dbus_string_free (&test);
00899 _dbus_string_free (&result);
00900 _dbus_string_free (&next_line);
00901 _dbus_string_free (&expected);
00902
00903 if (!success)
00904 goto out;
00905 }
00906 }
00907
00908 retval = TRUE;
00909
00910 printf ("Passed the %d SHA-1 tests in the test file\n",
00911 success_count);
00912
00913 out:
00914 _dbus_string_free (&tests_file);
00915 _dbus_string_free (&results_file);
00916 _dbus_string_free (&tests);
00917 _dbus_string_free (&results);
00918 _dbus_string_free (&line);
00919
00920 return retval;
00921 }
00922
00929 dbus_bool_t
00930 _dbus_sha_test (const char *test_data_dir)
00931 {
00932 unsigned char all_bytes[256];
00933 int i;
00934
00935 if (test_data_dir != NULL)
00936 {
00937 if (!process_test_data (test_data_dir))
00938 return FALSE;
00939 }
00940 else
00941 printf ("No test data dir\n");
00942
00943 i = 0;
00944 while (i < 256)
00945 {
00946 all_bytes[i] = i;
00947 ++i;
00948 }
00949
00950 if (!check_sha_binary (all_bytes, 256,
00951 "4916d6bdb7f78e6803698cab32d1586ea457dfc8"))
00952 return FALSE;
00953
00954 #define CHECK(input,expected) if (!check_sha_str (input, expected)) return FALSE
00955
00956 CHECK ("", "da39a3ee5e6b4b0d3255bfef95601890afd80709");
00957 CHECK ("a", "86f7e437faa5a7fce15d1ddcb9eaeaea377667b8");
00958 CHECK ("abc", "a9993e364706816aba3e25717850c26c9cd0d89d");
00959 CHECK ("message digest", "c12252ceda8be8994d5fa0290a47231c1d16aae3");
00960 CHECK ("abcdefghijklmnopqrstuvwxyz", "32d10c7b8cf96570ca04ce37f2a19d84240d3a89");
00961 CHECK ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
00962 "761c457bf73b14d27e9e9265c46f4b4dda11f940");
00963 CHECK ("12345678901234567890123456789012345678901234567890123456789012345678901234567890",
00964 "50abf5706a150990a08b2c5ea40fa0e585554732");
00965
00966 return TRUE;
00967 }
00968
00969 #endif