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;
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   dbus_error_init (&error);
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