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