test.c 89.8 KB
Newer Older
Roger Dingledine's avatar
Roger Dingledine committed
1
/* Copyright 2001-2004 Roger Dingledine.
2
 * Copyright 2004-2007 Roger Dingledine, Nick Mathewson. */
3
4
/* See LICENSE for licensing information */
/* $Id$ */
5
6
const char test_c_id[] =
  "$Id$";
7

8
9
const char tor_svn_revision[] = "";

10
11
12
13
14
/**
 * \file test.c
 * \brief Unit tests for many pieces of the lower level Tor modules.
 **/

Nick Mathewson's avatar
Nick Mathewson committed
15
#include "orconfig.h"
16
#include <stdio.h>
17
#ifdef HAVE_FCNTL_H
18
#include <fcntl.h>
19
20
#endif

21
#ifdef MS_WINDOWS
22
23
/* For mkdir() */
#include <direct.h>
Nick Mathewson's avatar
Nick Mathewson committed
24
#else
25
#include <dirent.h>
Nick Mathewson's avatar
Nick Mathewson committed
26
27
#endif

28
29
30
31
/* These macros pull in declarations for some functions and structures that
 * are typically file-private. */
#define CONFIG_PRIVATE
#define CONTROL_PRIVATE
32
33
#define CRYPTO_PRIVATE
#define DIRSERV_PRIVATE
34
#define DIRVOTE_PRIVATE
35
#define MEMPOOL_PRIVATE
36
#define ROUTER_PRIVATE
37

Nick Mathewson's avatar
Nick Mathewson committed
38
39
#include "or.h"
#include "../common/test.h"
40
#include "../common/torgzip.h"
41
#include "../common/mempool.h"
Nick Mathewson's avatar
Nick Mathewson committed
42

43
44
int have_failed = 0;

45
46
static char temp_dir[256];

47
static void
Nick Mathewson's avatar
Nick Mathewson committed
48
setup_directory(void)
49
50
{
  static int is_setup = 0;
51
  int r;
52
53
  if (is_setup) return;

54
#ifdef MS_WINDOWS
Nick Mathewson's avatar
Nick Mathewson committed
55
  // XXXX
56
57
  tor_snprintf(temp_dir, sizeof(temp_dir),
               "c:\\windows\\temp\\tor_test_%d", (int)getpid());
58
  r = mkdir(temp_dir);
59
#else
Nick Mathewson's avatar
Nick Mathewson committed
60
  tor_snprintf(temp_dir, sizeof(temp_dir), "/tmp/tor_test_%d", (int) getpid());
61
62
63
64
65
66
67
68
69
70
  r = mkdir(temp_dir, 0700);
#endif
  if (r) {
    fprintf(stderr, "Can't create directory %s:", temp_dir);
    perror("");
    exit(1);
  }
  is_setup = 1;
}

71
static const char *
72
73
74
75
get_fname(const char *name)
{
  static char buf[1024];
  setup_directory();
76
  tor_snprintf(buf,sizeof(buf),"%s/%s",temp_dir,name);
77
78
79
  return buf;
}

80
static void
Nick Mathewson's avatar
Nick Mathewson committed
81
remove_directory(void)
82
{
83
84
85
86
87
88
89
90
91
92
93
94
  smartlist_t *elements = tor_listdir(temp_dir);
  if (elements) {
    SMARTLIST_FOREACH(elements, const char *, cp,
       {
         size_t len = strlen(cp)+strlen(temp_dir)+16;
         char *tmp = tor_malloc(len);
         tor_snprintf(tmp, len, "%s"PATH_SEPARATOR"%s", temp_dir, cp);
         unlink(tmp);
         tor_free(tmp);
       });
    SMARTLIST_FOREACH(elements, char *, cp, tor_free(cp));
    smartlist_free(elements);
Nick Mathewson's avatar
Nick Mathewson committed
95
  }
96
  rmdir(temp_dir);
97
98
}

99
100
101
102
103
104
105
106
107
108
109
110
static crypto_pk_env_t *
pk_generate(int idx)
{
  static crypto_pk_env_t *pregen[3] = {NULL, NULL, NULL};
  tor_assert(idx < (int)(sizeof(pregen)/sizeof(pregen[0])));
  if (! pregen[idx]) {
    pregen[idx] = crypto_new_pk_env();
    tor_assert(!crypto_pk_generate_key(pregen[idx]));
  }
  return crypto_pk_dup_key(pregen[idx]);
}

111
static void
112
113
test_buffers(void)
{
114
115
116
  char str[256];
  char str2[256];

117
  buf_t *buf, *buf2;
Nick Mathewson's avatar
Nick Mathewson committed
118

Nick Mathewson's avatar
Nick Mathewson committed
119
  int j;
120
  size_t r;
121
122
123
124

  /****
   * buf_new
   ****/
125
  if (!(buf = buf_new()))
Nick Mathewson's avatar
Nick Mathewson committed
126
    test_fail();
127

128
  test_eq(buf_capacity(buf), 4096);
129
  test_eq(buf_datalen(buf), 0);
130
131

  /****
132
133
   * General pointer frobbing
   */
134
135
  for (j=0;j<256;++j) {
    str[j] = (char)j;
Nick Mathewson's avatar
Nick Mathewson committed
136
  }
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
  write_to_buf(str, 256, buf);
  write_to_buf(str, 256, buf);
  test_eq(buf_datalen(buf), 512);
  fetch_from_buf(str2, 200, buf);
  test_memeq(str, str2, 200);
  test_eq(buf_datalen(buf), 312);
  memset(str2, 0, sizeof(str2));

  fetch_from_buf(str2, 256, buf);
  test_memeq(str+200, str2, 56);
  test_memeq(str, str2+56, 200);
  test_eq(buf_datalen(buf), 56);
  memset(str2, 0, sizeof(str2));
  /* Okay, now we should be 512 bytes into the 4096-byte buffer.  If we add
   * another 3584 bytes, we hit the end. */
Nick Mathewson's avatar
Nick Mathewson committed
152
  for (j=0;j<15;++j) {
153
154
155
156
157
158
159
    write_to_buf(str, 256, buf);
  }
  assert_buf_ok(buf);
  test_eq(buf_datalen(buf), 3896);
  fetch_from_buf(str2, 56, buf);
  test_eq(buf_datalen(buf), 3840);
  test_memeq(str+200, str2, 56);
Nick Mathewson's avatar
Nick Mathewson committed
160
  for (j=0;j<15;++j) {
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
    memset(str2, 0, sizeof(str2));
    fetch_from_buf(str2, 256, buf);
    test_memeq(str, str2, 256);
  }
  test_eq(buf_datalen(buf), 0);
  buf_free(buf);

  /* Okay, now make sure growing can work. */
  buf = buf_new_with_capacity(16);
  test_eq(buf_capacity(buf), 16);
  write_to_buf(str+1, 255, buf);
  test_eq(buf_capacity(buf), 256);
  fetch_from_buf(str2, 254, buf);
  test_memeq(str+1, str2, 254);
  test_eq(buf_capacity(buf), 256);
  assert_buf_ok(buf);
  write_to_buf(str, 32, buf);
  test_eq(buf_capacity(buf), 256);
  assert_buf_ok(buf);
  write_to_buf(str, 256, buf);
  assert_buf_ok(buf);
  test_eq(buf_capacity(buf), 512);
  test_eq(buf_datalen(buf), 33+256);
  fetch_from_buf(str2, 33, buf);
  test_eq(*str2, str[255]);

  test_memeq(str2+1, str, 32);
  test_eq(buf_capacity(buf), 512);
  test_eq(buf_datalen(buf), 256);
  fetch_from_buf(str2, 256, buf);
  test_memeq(str, str2, 256);

  /* now try shrinking: case 1. */
  buf_free(buf);
  buf = buf_new_with_capacity(33668);
  for (j=0;j<67;++j) {
    write_to_buf(str,255, buf);
  }
  test_eq(buf_capacity(buf), 33668);
  test_eq(buf_datalen(buf), 17085);
  for (j=0; j < 40; ++j) {
    fetch_from_buf(str2, 255,buf);
    test_memeq(str2, str, 255);
  }

  /* now try shrinking: case 2. */
  buf_free(buf);
  buf = buf_new_with_capacity(33668);
  for (j=0;j<67;++j) {
    write_to_buf(str,255, buf);
  }
  for (j=0; j < 20; ++j) {
    fetch_from_buf(str2, 255,buf);
    test_memeq(str2, str, 255);
  }
  for (j=0;j<80;++j) {
    write_to_buf(str,255, buf);
  }
  test_eq(buf_capacity(buf),33668);
  for (j=0; j < 120; ++j) {
    fetch_from_buf(str2, 255,buf);
    test_memeq(str2, str, 255);
  }

225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
  /* Move from buf to buf. */
  buf_free(buf);
  buf = buf_new_with_capacity(4096);
  buf2 = buf_new_with_capacity(4096);
  for (j=0;j<100;++j)
    write_to_buf(str, 255, buf);
  test_eq(buf_datalen(buf), 25500);
  for (j=0;j<100;++j) {
    r = 10;
    move_buf_to_buf(buf2, buf, &r);
    test_eq(r, 0);
  }
  test_eq(buf_datalen(buf), 24500);
  test_eq(buf_datalen(buf2), 1000);
  for (j=0;j<3;++j) {
    fetch_from_buf(str2, 255, buf2);
    test_memeq(str2, str, 255);
  }
  r = 8192; /*big move*/
  move_buf_to_buf(buf2, buf, &r);
  test_eq(r, 0);
  r = 30000; /* incomplete move */
  move_buf_to_buf(buf2, buf, &r);
  test_eq(r, 13692);
  for (j=0;j<97;++j) {
    fetch_from_buf(str2, 255, buf2);
    test_memeq(str2, str, 255);
  }
  buf_free(buf);
  buf_free(buf2);

Nick Mathewson's avatar
Nick Mathewson committed
256
#if 0
257
258
259
260
261
  {
  int s;
  int eof;
  int i;
  buf_t *buf2;
262
263
264
265
  /****
   * read_to_buf
   ****/
  s = open(get_fname("data"), O_WRONLY|O_CREAT|O_TRUNC, 0600);
266
267
  write(s, str, 256);
  close(s);
Roger Dingledine's avatar
Roger Dingledine committed
268

269
  s = open(get_fname("data"), O_RDONLY, 0);
270
  eof = 0;
271
  errno = 0; /* XXXX */
272
  i = read_to_buf(s, 10, buf, &eof);
273
  printf("%s\n", strerror(errno));
274
  test_eq(i, 10);
275
276
277
278
  test_eq(eof, 0);
  test_eq(buf_capacity(buf), 4096);
  test_eq(buf_datalen(buf), 10);

279
  test_memeq(str, (char*)_buf_peek_raw_buffer(buf), 10);
280
281

  /* Test reading 0 bytes. */
282
  i = read_to_buf(s, 0, buf, &eof);
283
  test_eq(buf_capacity(buf), 512*1024);
284
  test_eq(buf_datalen(buf), 10);
285
286
  test_eq(eof, 0);
  test_eq(i, 0);
Nick Mathewson's avatar
Nick Mathewson committed
287

288
  /* Now test when buffer is filled exactly. */
289
290
291
292
  buf2 = buf_new_with_capacity(6);
  i = read_to_buf(s, 6, buf2, &eof);
  test_eq(buf_capacity(buf2), 6);
  test_eq(buf_datalen(buf2), 6);
293
294
  test_eq(eof, 0);
  test_eq(i, 6);
295
296
  test_memeq(str+10, (char*)_buf_peek_raw_buffer(buf2), 6);
  buf_free(buf2);
Roger Dingledine's avatar
Roger Dingledine committed
297

298
  /* Now test when buffer is filled with more data to read. */
299
300
  buf2 = buf_new_with_capacity(32);
  i = read_to_buf(s, 128, buf2, &eof);
301
  test_eq(buf_capacity(buf2), 128);
302
  test_eq(buf_datalen(buf2), 32);
303
  test_eq(eof, 0);
304
305
  test_eq(i, 32);
  buf_free(buf2);
306
307

  /* Now read to eof. */
308
309
310
311
312
313
  test_assert(buf_capacity(buf) > 256);
  i = read_to_buf(s, 1024, buf, &eof);
  test_eq(i, (256-32-10-6));
  test_eq(buf_capacity(buf), MAX_BUF_SIZE);
  test_eq(buf_datalen(buf), 256-6-32);
  test_memeq(str, (char*)_buf_peek_raw_buffer(buf), 10); /* XXX Check rest. */
314
315
  test_eq(eof, 0);

316
  i = read_to_buf(s, 1024, buf, &eof);
317
  test_eq(i, 0);
318
319
  test_eq(buf_capacity(buf), MAX_BUF_SIZE);
  test_eq(buf_datalen(buf), 256-6-32);
320
  test_eq(eof, 1);
321
  }
Nick Mathewson's avatar
Nick Mathewson committed
322
#endif
Nick Mathewson's avatar
Nick Mathewson committed
323
324
}

325
static void
Nick Mathewson's avatar
Nick Mathewson committed
326
test_crypto_dh(void)
327
328
{
  crypto_dh_env_t *dh1, *dh2;
329
330
331
332
  char p1[DH_BYTES];
  char p2[DH_BYTES];
  char s1[DH_BYTES];
  char s2[DH_BYTES];
333
  int s1len, s2len;
334
335
336

  dh1 = crypto_dh_new();
  dh2 = crypto_dh_new();
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
  test_eq(crypto_dh_get_bytes(dh1), DH_BYTES);
  test_eq(crypto_dh_get_bytes(dh2), DH_BYTES);

  memset(p1, 0, DH_BYTES);
  memset(p2, 0, DH_BYTES);
  test_memeq(p1, p2, DH_BYTES);
  test_assert(! crypto_dh_get_public(dh1, p1, DH_BYTES));
  test_memneq(p1, p2, DH_BYTES);
  test_assert(! crypto_dh_get_public(dh2, p2, DH_BYTES));
  test_memneq(p1, p2, DH_BYTES);

  memset(s1, 0, DH_BYTES);
  memset(s2, 0xFF, DH_BYTES);
  s1len = crypto_dh_compute_secret(dh1, p2, DH_BYTES, s1, 50);
  s2len = crypto_dh_compute_secret(dh2, p1, DH_BYTES, s2, 50);
352
353
354
  test_assert(s1len > 0);
  test_eq(s1len, s2len);
  test_memeq(s1, s2, s1len);
Roger Dingledine's avatar
Roger Dingledine committed
355

356
357
358
359
  crypto_dh_free(dh1);
  crypto_dh_free(dh2);
}

360
static void
Nick Mathewson's avatar
Nick Mathewson committed
361
test_crypto(void)
362
{
363
364
365
  crypto_cipher_env_t *env1, *env2;
  crypto_pk_env_t *pk1, *pk2;
  char *data1, *data2, *data3, *cp;
366
  int i, j, p, len;
Roger Dingledine's avatar
Roger Dingledine committed
367
  size_t size;
Nick Mathewson's avatar
Nick Mathewson committed
368

369
370
371
  data1 = tor_malloc(1024);
  data2 = tor_malloc(1024);
  data3 = tor_malloc(1024);
372
  test_assert(data1 && data2 && data3);
373

374
  /* Try out RNG. */
375
  test_assert(! crypto_seed_rng());
376
377
  crypto_rand(data1, 100);
  crypto_rand(data2, 100);
378
  test_memneq(data1,data2,100);
Roger Dingledine's avatar
Roger Dingledine committed
379

380
  /* Now, test encryption and decryption with stream cipher. */
381
  data1[0]='\0';
382
  for (i = 1023; i>0; i -= 35)
383
    strncat(data1, "Now is the time for all good onions", i);
384
385
386
387
388
389
390
391
392
393
394
395
396

  memset(data2, 0, 1024);
  memset(data3, 0, 1024);
  env1 = crypto_new_cipher_env();
  test_neq(env1, 0);
  env2 = crypto_new_cipher_env();
  test_neq(env2, 0);
  j = crypto_cipher_generate_key(env1);
  crypto_cipher_set_key(env2, crypto_cipher_get_key(env1));
  crypto_cipher_encrypt_init_cipher(env1);
  crypto_cipher_decrypt_init_cipher(env2);

  /* Try encrypting 512 chars. */
397
398
  crypto_cipher_encrypt(env1, data2, data1, 512);
  crypto_cipher_decrypt(env2, data3, data2, 512);
399
400
401
402
403
  test_memeq(data1, data3, 512);
  test_memneq(data1, data2, 512);

  /* Now encrypt 1 at a time, and get 1 at a time. */
  for (j = 512; j < 560; ++j) {
404
    crypto_cipher_encrypt(env1, data2+j, data1+j, 1);
405
406
  }
  for (j = 512; j < 560; ++j) {
407
    crypto_cipher_decrypt(env2, data3+j, data2+j, 1);
408
409
410
411
  }
  test_memeq(data1, data3, 560);
  /* Now encrypt 3 at a time, and get 5 at a time. */
  for (j = 560; j < 1024-5; j += 3) {
412
    crypto_cipher_encrypt(env1, data2+j, data1+j, 3);
413
414
  }
  for (j = 560; j < 1024-5; j += 5) {
415
    crypto_cipher_decrypt(env2, data3+j, data2+j, 5);
416
417
418
419
420
421
422
423
424
425
426
427
  }
  test_memeq(data1, data3, 1024-5);
  /* Now make sure that when we encrypt with different chunk sizes, we get
     the same results. */
  crypto_free_cipher_env(env2);

  memset(data3, 0, 1024);
  env2 = crypto_new_cipher_env();
  test_neq(env2, 0);
  crypto_cipher_set_key(env2, crypto_cipher_get_key(env1));
  crypto_cipher_encrypt_init_cipher(env2);
  for (j = 0; j < 1024-16; j += 17) {
428
    crypto_cipher_encrypt(env2, data3+j, data1+j, 17);
429
430
431
432
  }
  for (j= 0; j < 1024-16; ++j) {
    if (data2[j] != data3[j]) {
      printf("%d:  %d\t%d\n", j, (int) data2[j], (int) data3[j]);
433
434
    }
  }
435
436
437
  test_memeq(data2, data3, 1024-16);
  crypto_free_cipher_env(env1);
  crypto_free_cipher_env(env2);
Roger Dingledine's avatar
Roger Dingledine committed
438

439
440
441
442
  /* Test vectors for stream ciphers. */
  /* XXXX Look up some test vectors for the ciphers and make sure we match. */

  /* Test SHA-1 with a test vector from the specification. */
443
  i = crypto_digest(data1, "abc", 3);
444
445
446
447
448
  test_memeq(data1,
             "\xA9\x99\x3E\x36\x47\x06\x81\x6A\xBA\x3E\x25\x71\x78"
             "\x50\xC2\x6C\x9C\xD0\xD8\x9D", 20);

  /* Public-key ciphers */
449
  pk1 = pk_generate(0);
450
  pk2 = crypto_new_pk_env();
451
  test_assert(pk1 && pk2);
452
453
  test_assert(! crypto_pk_write_public_key_to_string(pk1, &cp, &size));
  test_assert(! crypto_pk_read_public_key_from_string(pk2, cp, size));
454
  test_eq(0, crypto_pk_cmp_keys(pk1, pk2));
455
456
  tor_free(cp);

457
458
  test_eq(128, crypto_pk_keysize(pk1));
  test_eq(128, crypto_pk_keysize(pk2));
Roger Dingledine's avatar
Roger Dingledine committed
459

460
  test_eq(128, crypto_pk_public_encrypt(pk2, data1, "Hello whirled.", 15,
461
                                        PK_PKCS1_OAEP_PADDING));
462
  test_eq(128, crypto_pk_public_encrypt(pk1, data2, "Hello whirled.", 15,
463
                                        PK_PKCS1_OAEP_PADDING));
464
465
  /* oaep padding should make encryption not match */
  test_memneq(data1, data2, 128);
466
  test_eq(15, crypto_pk_private_decrypt(pk1, data3, data1, 128,
467
                                        PK_PKCS1_OAEP_PADDING,1));
468
469
  test_streq(data3, "Hello whirled.");
  memset(data3, 0, 1024);
470
  test_eq(15, crypto_pk_private_decrypt(pk1, data3, data2, 128,
471
                                        PK_PKCS1_OAEP_PADDING,1));
472
473
  test_streq(data3, "Hello whirled.");
  /* Can't decrypt with public key. */
474
  test_eq(-1, crypto_pk_private_decrypt(pk2, data3, data2, 128,
475
                                        PK_PKCS1_OAEP_PADDING,1));
476
477
  /* Try again with bad padding */
  memcpy(data2+1, "XYZZY", 5);  /* This has fails ~ once-in-2^40 */
478
  test_eq(-1, crypto_pk_private_decrypt(pk1, data3, data2, 128,
479
                                        PK_PKCS1_OAEP_PADDING,1));
Roger Dingledine's avatar
Roger Dingledine committed
480

481
  /* File operations: save and load private key */
482
  test_assert(! crypto_pk_write_private_key_to_filename(pk1,
483
                                                        get_fname("pkey1")));
484

Roger Dingledine's avatar
Roger Dingledine committed
485
  test_assert(! crypto_pk_read_private_key_from_filename(pk2,
486
                                                         get_fname("pkey1")));
487
  test_eq(15, crypto_pk_private_decrypt(pk2, data3, data1, 128,
488
                                        PK_PKCS1_OAEP_PADDING,1));
489

490
  /* Now try signing. */
491
  strlcpy(data1, "Ossifrage", 1024);
492
493
  test_eq(128, crypto_pk_private_sign(pk1, data2, data1, 10));
  test_eq(10, crypto_pk_public_checksig(pk1, data3, data2, 128));
494
  test_streq(data3, "Ossifrage");
495
  /* Try signing digests. */
496
497
  test_eq(128, crypto_pk_private_sign_digest(pk1, data2, data1, 10));
  test_eq(20, crypto_pk_public_checksig(pk1, data3, data2, 128));
498
499
  test_eq(0, crypto_pk_public_checksig_digest(pk1, data1, 10, data2, 128));
  test_eq(-1, crypto_pk_public_checksig_digest(pk1, data1, 11, data2, 128));
500
  /*XXXX test failed signing*/
Roger Dingledine's avatar
Roger Dingledine committed
501

502
503
504
505
506
507
508
509
  /* Try encoding */
  crypto_free_pk_env(pk2);
  pk2 = NULL;
  i = crypto_pk_asn1_encode(pk1, data1, 1024);
  test_assert(i>0);
  pk2 = crypto_pk_asn1_decode(data1, i);
  test_assert(crypto_pk_cmp_keys(pk1,pk2) == 0);

510
  /* Try with hybrid encryption wrappers. */
511
  crypto_rand(data1, 1024);
512
513
514
515
516
517
  for (i = 0; i < 3; ++i) {
    for (j = 85; j < 140; ++j) {
      memset(data2,0,1024);
      memset(data3,0,1024);
      if (i == 0 && j < 129)
        continue;
518
519
      p = (i==0)?PK_NO_PADDING:
        (i==1)?PK_PKCS1_PADDING:PK_PKCS1_OAEP_PADDING;
520
      len = crypto_pk_public_hybrid_encrypt(pk1,data2,data1,j,p,0);
521
      test_assert(len>=0);
522
      len = crypto_pk_private_hybrid_decrypt(pk1,data3,data2,len,p,1);
523
524
525
526
      test_eq(len,j);
      test_memeq(data1,data3,j);
    }
  }
Roger Dingledine's avatar
Roger Dingledine committed
527
528
  crypto_free_pk_env(pk1);
  crypto_free_pk_env(pk2);
529

530
  /* Base64 tests */
531
532
  strlcpy(data1, "Test string that contains 35 chars.", 1024);
  strlcat(data1, " 2nd string that contains 35 chars.", 1024);
533
534
535
536
537
538
539

  i = base64_encode(data2, 1024, data1, 71);
  j = base64_decode(data3, 1024, data2, i);
  test_streq(data3, data1);
  test_eq(j, 71);
  test_assert(data2[i] == '\0');

540
541
542
543
544
545
546
547
548
549
  crypto_rand(data1, DIGEST_LEN);
  memset(data2, 100, 1024);
  digest_to_base64(data2, data1);
  test_eq(BASE64_DIGEST_LEN, strlen(data2));
  test_eq(100, data2[BASE64_DIGEST_LEN+2]);
  memset(data3, 99, 1024);
  digest_from_base64(data3, data2);
  test_memeq(data1, data3, DIGEST_LEN);
  test_eq(99, data3[DIGEST_LEN+1]);

550
  /* Base32 tests */
551
  strlcpy(data1, "5chrs", 1024);
552
553
554
555
  /* bit pattern is:  [35 63 68 72 73] ->
   *        [00110101 01100011 01101000 01110010 01110011]
   * By 5s: [00110 10101 10001 10110 10000 11100 10011 10011]
   */
556
  base32_encode(data2, 9, data1, 5);
557
558
  test_streq(data2, "gvrwq4tt");

559
  strlcpy(data1, "\xFF\xF5\x6D\x44\xAE\x0D\x5C\xC9\x62\xC4", 1024);
560
  base32_encode(data2, 30, data1, 10);
561
  test_streq(data2, "772w2rfobvomsywe");
562

Nick Mathewson's avatar
Nick Mathewson committed
563
  /* Base16 tests */
564
  strlcpy(data1, "6chrs\xff", 1024);
565
  base16_encode(data2, 13, data1, 6);
Nick Mathewson's avatar
Nick Mathewson committed
566
567
  test_streq(data2, "3663687273FF");

568
  strlcpy(data1, "f0d678affc000100", 1024);
Nick Mathewson's avatar
Nick Mathewson committed
569
570
571
572
  i = base16_decode(data2, 8, data1, 16);
  test_eq(i,0);
  test_memeq(data2, "\xf0\xd6\x78\xaf\xfc\x00\x01\x00",8);

573
574
575
576
577
578
  /* now try some failing base16 decodes */
  test_eq(-1, base16_decode(data2, 8, data1, 15)); /* odd input len */
  test_eq(-1, base16_decode(data2, 7, data1, 16)); /* dest too short */
  strlcpy(data1, "f0dz!8affc000100", 1024);
  test_eq(-1, base16_decode(data2, 8, data1, 16));

579
580
581
  tor_free(data1);
  tor_free(data2);
  tor_free(data3);
582
583
}

Nick Mathewson's avatar
Nick Mathewson committed
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
static void
test_crypto_s2k(void)
{
  char buf[29];
  char buf2[29];
  char *buf3;
  int i;

  memset(buf, 0, sizeof(buf));
  memset(buf2, 0, sizeof(buf2));
  buf3 = tor_malloc(65536);
  memset(buf3, 0, 65536);

  secret_to_key(buf+9, 20, "", 0, buf);
  crypto_digest(buf2+9, buf3, 1024);
  test_memeq(buf, buf2, 29);

  memcpy(buf,"vrbacrda",8);
  memcpy(buf2,"vrbacrda",8);
  buf[8] = 96;
  buf2[8] = 96;
  secret_to_key(buf+9, 20, "12345678", 8, buf);
  for (i = 0; i < 65536; i += 16) {
    memcpy(buf3+i, "vrbacrda12345678", 16);
  }
  crypto_digest(buf2+9, buf3, 65536);
  test_memeq(buf, buf2, 29);
}

613
614
615
616
617
618
619
620
621
622
623
624
625
626
static int
_compare_strs(const void **a, const void **b)
{
  const char *s1 = *a, *s2 = *b;
  return strcmp(s1, s2);
}

static int
_compare_without_first_ch(const void *a, const void **b)
{
  const char *s1 = a, *s2 = *b;
  return strcasecmp(s1+1, s2);
}

627
static void
628
629
test_util(void)
{
630
  struct timeval start, end;
631
  struct tm a_time;
632
  char timestr[RFC1123_TIME_LEN+1];
633
  char buf[1024];
634
635
  time_t t_res;
  int i;
636
637
  uint32_t u32;
  uint16_t u16;
638
  char *cp, *k, *v;
639
640
641
642
643
644
645
646
647
648
649

  start.tv_sec = 5;
  start.tv_usec = 5000;

  end.tv_sec = 5;
  end.tv_usec = 5000;

  test_eq(0L, tv_udiff(&start, &end));

  end.tv_usec = 7000;

650
651
652
653
  test_assert(tv_cmp(&start, &end)<0);
  test_assert(tv_cmp(&end, &start)>0);
  test_assert(tv_cmp(&end, &end)==0);

654
655
656
657
658
659
660
661
662
663
664
665
  test_eq(2000L, tv_udiff(&start, &end));

  end.tv_sec = 6;

  test_eq(1002000L, tv_udiff(&start, &end));

  end.tv_usec = 0;

  test_eq(995000L, tv_udiff(&start, &end));

  end.tv_sec = 4;

666
  test_eq(-1005000L, tv_udiff(&start, &end));
667

668
669
670
671
672
673
674
675
676
677
678
  tv_addms(&end, 5090);
  test_eq(end.tv_sec, 9);
  test_eq(end.tv_usec, 90000);

  end.tv_usec = 999990;
  start.tv_sec = 1;
  start.tv_usec = 500;
  tv_add(&start, &end);
  test_eq(start.tv_sec, 11);
  test_eq(start.tv_usec, 490);

679
  /* The test values here are confirmed to be correct on a platform
680
   * with a working timegm. */
681
682
683
684
685
686
687
688
689
690
691
692
  a_time.tm_year = 2003-1900;
  a_time.tm_mon = 7;
  a_time.tm_mday = 30;
  a_time.tm_hour = 6;
  a_time.tm_min = 14;
  a_time.tm_sec = 55;
  test_eq((time_t) 1062224095UL, tor_timegm(&a_time));
  a_time.tm_year = 2004-1900; /* Try a leap year, after feb. */
  test_eq((time_t) 1093846495UL, tor_timegm(&a_time));
  a_time.tm_mon = 1;          /* Try a leap year, in feb. */
  a_time.tm_mday = 10;
  test_eq((time_t) 1076393695UL, tor_timegm(&a_time));
693

694
  format_rfc1123_time(timestr, 0);
695
  test_streq("Thu, 01 Jan 1970 00:00:00 GMT", timestr);
696
  format_rfc1123_time(timestr, (time_t)1091580502UL);
697
698
699
  test_streq("Wed, 04 Aug 2004 00:48:22 GMT", timestr);

  t_res = 0;
700
  i = parse_rfc1123_time(timestr, &t_res);
701
702
  test_eq(i,0);
  test_eq(t_res, (time_t)1091580502UL);
703
704
  test_eq(-1, parse_rfc1123_time("Wed, zz Aug 2004 99-99x99 GMT", &t_res));
  tor_gettimeofday(&start);
705

706
  /* Test tor_strstrip() */
707
  strlcpy(buf, "Testing 1 2 3", sizeof(buf));
708
709
  test_eq(0, tor_strstrip(buf, ",!"));
  test_streq(buf, "Testing 1 2 3");
710
  strlcpy(buf, "!Testing 1 2 3?", sizeof(buf));
711
712
713
714
  test_eq(5, tor_strstrip(buf, "!? "));
  test_streq(buf, "Testing123");

  /* Test tor_strpartition() */
715
  test_assert(! tor_strpartition(buf, sizeof(buf), "abcdefghi", "##", 3));
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
  test_streq(buf, "abc##def##ghi");

  /* Test parse_addr_port */
  cp = NULL; u32 = 3; u16 = 3;
  test_assert(!parse_addr_port(LOG_WARN, "1.2.3.4", &cp, &u32, &u16));
  test_streq(cp, "1.2.3.4");
  test_eq(u32, 0x01020304u);
  test_eq(u16, 0);
  tor_free(cp);
  test_assert(!parse_addr_port(LOG_WARN, "4.3.2.1:99", &cp, &u32, &u16));
  test_streq(cp, "4.3.2.1");
  test_eq(u32, 0x04030201u);
  test_eq(u16, 99);
  tor_free(cp);
  test_assert(!parse_addr_port(LOG_WARN, "nonexistent.address:4040",
                               &cp, NULL, &u16));
  test_streq(cp, "nonexistent.address");
  test_eq(u16, 4040);
  tor_free(cp);
  test_assert(!parse_addr_port(LOG_WARN, "localhost:9999", &cp, &u32, &u16));
  test_streq(cp, "localhost");
  test_eq(u32, 0x7f000001u);
  test_eq(u16, 9999);
  tor_free(cp);
  u32 = 3;
  test_assert(!parse_addr_port(LOG_WARN, "localhost", NULL, &u32, &u16));
  test_eq(cp, NULL);
  test_eq(u32, 0x7f000001u);
  test_eq(u16, 0);
  tor_free(cp);
  test_eq(0, addr_mask_get_bits(0x0u));
  test_eq(32, addr_mask_get_bits(0xFFFFFFFFu));
  test_eq(16, addr_mask_get_bits(0xFFFF0000u));
  test_eq(31, addr_mask_get_bits(0xFFFFFFFEu));
  test_eq(1, addr_mask_get_bits(0x80000000u));

  /* Test tor_parse_long. */
  test_eq(10L, tor_parse_long("10",10,0,100,NULL,NULL));
  test_eq(0L, tor_parse_long("10",10,50,100,NULL,NULL));
755
756
757
758
759
  test_eq(-50L, tor_parse_long("-50",10,-100,100,NULL,NULL));

  /* Test tor_parse_ulong */
  test_eq(10UL, tor_parse_ulong("10",10,0,100,NULL,NULL));
  test_eq(0UL, tor_parse_ulong("10",10,50,100,NULL,NULL));
760

761
762
763
764
765
766
767
768
769
770
771
772
  /* Test tor_parse_uint64. */
  test_assert(U64_LITERAL(10) == tor_parse_uint64("10 x",10,0,100, &i, &cp));
  test_assert(i == 1);
  test_streq(cp, " x");
  test_assert(U64_LITERAL(12345678901) ==
              tor_parse_uint64("12345678901",10,0,UINT64_MAX, &i, &cp));
  test_assert(i == 1);
  test_streq(cp, "");
  test_assert(U64_LITERAL(0) ==
              tor_parse_uint64("12345678901",10,500,INT32_MAX, &i, &cp));
  test_assert(i == 0);

773
774
775
776
777
  /* Test printf with uint64 */
  tor_snprintf(buf, sizeof(buf), "x!"U64_FORMAT"!x",
               U64_PRINTF_ARG(U64_LITERAL(12345678901)));
  test_streq(buf, "x!12345678901!x");

778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
  /* Test parse_line_from_str */
  strlcpy(buf, "k v\n" " key    value with spaces   \n" "keykey val\n"
          "k2\n"
          "k3 \n" "\n" "   \n" "#comment\n"
          "k4#a\n" "k5#abc\n" "k6 val #with comment\n", sizeof(buf));
  cp = buf;

  cp = parse_line_from_str(cp, &k, &v);
  test_streq(k, "k");
  test_streq(v, "v");
  test_assert(!strcmpstart(cp, " key    value with"));

  cp = parse_line_from_str(cp, &k, &v);
  test_streq(k, "key");
  test_streq(v, "value with spaces");
  test_assert(!strcmpstart(cp, "keykey"));

  cp = parse_line_from_str(cp, &k, &v);
  test_streq(k, "keykey");
  test_streq(v, "val");
  test_assert(!strcmpstart(cp, "k2\n"));

  cp = parse_line_from_str(cp, &k, &v);
  test_streq(k, "k2");
  test_streq(v, "");
  test_assert(!strcmpstart(cp, "k3 \n"));

  cp = parse_line_from_str(cp, &k, &v);
  test_streq(k, "k3");
  test_streq(v, "");
  test_assert(!strcmpstart(cp, "\n   \n"));

  cp = parse_line_from_str(cp, &k, &v);
  test_streq(k, "k4");
  test_streq(v, "");
  test_assert(!strcmpstart(cp, "k5#abc"));

  cp = parse_line_from_str(cp, &k, &v);
  test_streq(k, "k5");
  test_streq(v, "");
  test_assert(!strcmpstart(cp, "k6"));

  cp = parse_line_from_str(cp, &k, &v);
  test_streq(k, "k6");
  test_streq(v, "val");
  test_streq(cp, "");

  /* Test for strcmpstart and strcmpend. */
  test_assert(strcmpstart("abcdef", "abcdef")==0);
  test_assert(strcmpstart("abcdef", "abc")==0);
  test_assert(strcmpstart("abcdef", "abd")<0);
  test_assert(strcmpstart("abcdef", "abb")>0);
  test_assert(strcmpstart("ab", "abb")<0);

  test_assert(strcmpend("abcdef", "abcdef")==0);
  test_assert(strcmpend("abcdef", "def")==0);
  test_assert(strcmpend("abcdef", "deg")<0);
  test_assert(strcmpend("abcdef", "dee")>0);
  test_assert(strcmpend("ab", "abb")<0);

838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
  test_assert(strcasecmpend("AbcDEF", "abcdef")==0);
  test_assert(strcasecmpend("abcdef", "dEF")==0);
  test_assert(strcasecmpend("abcDEf", "deg")<0);
  test_assert(strcasecmpend("abcdef", "DEE")>0);
  test_assert(strcasecmpend("ab", "abB")<0);

  /* Test mem_is_zero */
  memset(buf,0,128);
  buf[128] = 'x';
  test_assert(tor_digest_is_zero(buf));
  test_assert(tor_mem_is_zero(buf, 10));
  test_assert(tor_mem_is_zero(buf, 20));
  test_assert(tor_mem_is_zero(buf, 128));
  test_assert(!tor_mem_is_zero(buf, 129));
  buf[60] = (char)255;
  test_assert(!tor_mem_is_zero(buf, 128));
  buf[0] = (char)1;
  test_assert(!tor_mem_is_zero(buf, 10));

  /* Test inet_ntoa */
858
859
860
861
862
863
864
865
866
867
868
869
870
  {
    char tmpbuf[INET_NTOA_BUF_LEN];
    struct in_addr in;
    tor_inet_aton("18.244.0.188",&in);
    tor_inet_ntoa(&in, tmpbuf, sizeof(tmpbuf));
    test_streq(tmpbuf, "18.244.0.188");
  }

  /* Test 'escaped' */
  test_streq("\"\"", escaped(""));
  test_streq("\"abcd\"", escaped("abcd"));
  test_streq("\"\\\\\\n\\r\\t\\\"\\'\"", escaped("\\\n\r\t\"\'"));
  test_streq("\"z\\001abc\\277d\"", escaped("z\001abc\277d"));
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
  test_assert(NULL == escaped(NULL));

  /* Test strndup and memdup */
  {
    const char *s = "abcdefghijklmnopqrstuvwxyz";
    cp = tor_strndup(s, 30);
    test_streq(cp, s); /* same string, */
    test_neq(cp, s); /* but different pointers. */
    tor_free(cp);

    cp = tor_strndup(s, 5);
    test_streq(cp, "abcde");
    tor_free(cp);

    s = "a\0b\0c\0d\0e\0";
    cp = tor_memdup(s,10);
    test_memeq(cp, s, 10); /* same ram, */
    test_neq(cp, s); /* but different pointers. */
    tor_free(cp);
  }

  /* Test str-foo functions */
  cp = tor_strdup("abcdef");
  test_assert(tor_strisnonupper(cp));
  cp[3] = 'D';
  test_assert(!tor_strisnonupper(cp));
  tor_strupper(cp);
  test_streq(cp, "ABCDEF");
  test_assert(tor_strisprint(cp));
  cp[3] = 3;
  test_assert(!tor_strisprint(cp));
  tor_free(cp);

  /* Test eat_whitespace. */
  {
    const char *s = "  \n a";
    test_eq_ptr(eat_whitespace(s), s+4);
    s = "abcd";
    test_eq_ptr(eat_whitespace(s), s);
    s = "#xyz\nab";
    test_eq_ptr(eat_whitespace(s), s+5);
  }

  /* Test memmem */
  {
    const char *haystack = "abcde";
    tor_assert(!tor_memmem(haystack, 5, "ef", 2));
    test_eq_ptr(tor_memmem(haystack, 5, "cd", 2), haystack + 2);
    test_eq_ptr(tor_memmem(haystack, 5, "cde", 3), haystack + 2);
    haystack = "ababcad";
    test_eq_ptr(tor_memmem(haystack, 7, "abc", 3), haystack + 2);
  }
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946

  /* Test wrap_string */
  {
    smartlist_t *sl = smartlist_create();
    wrap_string(sl, "This is a test of string wrapping functionality: woot.",
                10, "", "");
    cp = smartlist_join_strings(sl, "", 0, NULL);
    test_streq(cp,
            "This is a\ntest of\nstring\nwrapping\nfunctional\nity: woot.\n");
    tor_free(cp);
    SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
    smartlist_clear(sl);

    wrap_string(sl, "This is a test of string wrapping functionality: woot.",
                16, "### ", "# ");
    cp = smartlist_join_strings(sl, "", 0, NULL);
    test_streq(cp,
             "### This is a\n# test of string\n# wrapping\n# functionality:\n"
             "# woot.\n");

    tor_free(cp);
    SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
    smartlist_clear(sl);
  }
947
948
949
950
951

  /* now make sure time works. */
  tor_gettimeofday(&end);
  /* We might've timewarped a little. */
  test_assert(tv_udiff(&start, &end) >= -5000);
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971

  /* Test tor_log2(). */
  test_eq(tor_log2(64), 6);
  test_eq(tor_log2(65), 6);
  test_eq(tor_log2(63), 5);
  test_eq(tor_log2(1), 0);
  test_eq(tor_log2(2), 1);
  test_eq(tor_log2(3), 1);
  test_eq(tor_log2(4), 2);
  test_eq(tor_log2(5), 2);
  test_eq(tor_log2(U64_LITERAL(40000000000000000)), 55);
  test_eq(tor_log2(UINT64_MAX), 63);

  /* Test round_to_power_of_2 */
  test_eq(round_to_power_of_2(120), 128);
  test_eq(round_to_power_of_2(128), 128);
  test_eq(round_to_power_of_2(130), 128);
  test_eq(round_to_power_of_2(U64_LITERAL(40000000000000000)),
          U64_LITERAL(1)<<55);
  test_eq(round_to_power_of_2(0), 2);
972
973
}

974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
static void
_test_eq_ip6(struct in6_addr *a, struct in6_addr *b, const char *e1,
             const char *e2, int line)
{
  int i;
  int ok = 1;
  for (i = 0; i < 16; ++i) {
    if (a->s6_addr[i] != b->s6_addr[i]) {
      ok = 0;
      break;
    }
  }
  if (ok) {
    printf("."); fflush(stdout);
  } else {
    char buf1[128], *cp1;
    char buf2[128], *cp2;
    have_failed = 1;
    cp1 = buf1; cp2 = buf2;
    for (i=0; i<16; ++i) {
      tor_snprintf(cp1, sizeof(buf1)-(cp1-buf1), "%02x", a->s6_addr[i]);
      tor_snprintf(cp2, sizeof(buf2)-(cp2-buf2), "%02x", b->s6_addr[i]);
      cp1 += 2; cp2 += 2;
      if ((i%2)==1 && i != 15) {
        *cp1++ = ':';
        *cp2++ = ':';
      }