source: trunk/libtransmission/crypto-test.c

Last change on this file was 14726, checked in by jordan, 5 years ago

crypto.h and crypto-utils.h can't use #pragma once, it breaks our name munging in crypto-test-ref.h

  • Property svn:keywords set to Date Rev Author Id
File size: 6.8 KB
Line 
1/*
2 * This file Copyright (C) 2013-2014 Mnemosyne LLC
3 *
4 * It may be used under the GNU GPL versions 2 or 3
5 * or any future license endorsed by Mnemosyne LLC.
6 *
7 * $Id: crypto-test.c 14726 2016-03-29 19:02:26Z mikedld $
8 */
9
10#include <string.h>
11
12#include "transmission.h"
13#include "crypto.h"
14#include "crypto-utils.h"
15
16#include "libtransmission-test.h"
17
18#include "crypto-test-ref.h"
19
20static int
21test_torrent_hash (void)
22{
23  tr_crypto a;
24  uint8_t hash[SHA_DIGEST_LENGTH];
25  uint8_t i;
26
27  for (i = 0; i < SHA_DIGEST_LENGTH; ++i)
28    hash[i] = i;
29
30  tr_cryptoConstruct (&a, NULL, true);
31
32  check (!tr_cryptoHasTorrentHash (&a));
33  check (tr_cryptoGetTorrentHash (&a) == NULL);
34
35  tr_cryptoSetTorrentHash (&a, hash);
36  check (tr_cryptoHasTorrentHash (&a));
37  check (tr_cryptoGetTorrentHash (&a) != NULL);
38  check (memcmp (tr_cryptoGetTorrentHash (&a), hash, SHA_DIGEST_LENGTH) == 0);
39
40  tr_cryptoDestruct (&a);
41
42  for (i = 0; i < SHA_DIGEST_LENGTH; ++i)
43    hash[i] = i + 1;
44
45  tr_cryptoConstruct (&a, hash, false);
46
47  check (tr_cryptoHasTorrentHash (&a));
48  check (tr_cryptoGetTorrentHash (&a) != NULL);
49  check (memcmp (tr_cryptoGetTorrentHash (&a), hash, SHA_DIGEST_LENGTH) == 0);
50
51  tr_cryptoSetTorrentHash (&a, NULL);
52  check (!tr_cryptoHasTorrentHash (&a));
53  check (tr_cryptoGetTorrentHash (&a) == NULL);
54
55  tr_cryptoDestruct (&a);
56
57  return 0;
58}
59
60static int
61test_encrypt_decrypt (void)
62{
63  tr_crypto a;
64  tr_crypto_ b;
65  uint8_t hash[SHA_DIGEST_LENGTH];
66  const char test1[] = { "test1" };
67  char buf11[sizeof (test1)], buf12[sizeof (test1)];
68  const char test2[] = { "@#)C$@)#(*%bvkdjfhwbc039bc4603756VB3)" };
69  char buf21[sizeof (test2)], buf22[sizeof (test2)];
70  int i;
71
72  for (i = 0; i < SHA_DIGEST_LENGTH; ++i)
73    hash[i] = (uint8_t)i;
74
75  tr_cryptoConstruct (&a, hash, false);
76  tr_cryptoConstruct_ (&b, hash, true);
77  check (tr_cryptoComputeSecret (&a, tr_cryptoGetMyPublicKey_ (&b, &i)));
78  check (tr_cryptoComputeSecret_ (&b, tr_cryptoGetMyPublicKey (&a, &i)));
79
80  tr_cryptoEncryptInit (&a);
81  tr_cryptoEncrypt (&a, sizeof (test1), test1, buf11);
82  tr_cryptoDecryptInit_ (&b);
83  tr_cryptoDecrypt_ (&b, sizeof (test1), buf11, buf12);
84  check_streq (test1, buf12);
85
86  tr_cryptoEncryptInit_ (&b);
87  tr_cryptoEncrypt_ (&b, sizeof (test2), test2, buf21);
88  tr_cryptoDecryptInit (&a);
89  tr_cryptoDecrypt (&a, sizeof (test2), buf21, buf22);
90  check_streq (test2, buf22);
91
92  tr_cryptoDestruct_ (&b);
93  tr_cryptoDestruct (&a);
94
95  return 0;
96}
97
98static int
99test_sha1 (void)
100{
101  uint8_t hash[SHA_DIGEST_LENGTH];
102  uint8_t hash_[SHA_DIGEST_LENGTH];
103
104  check (tr_sha1 (hash, "test", 4, NULL));
105  check (tr_sha1_ (hash_, "test", 4, NULL));
106  check (memcmp (hash, "\xa9\x4a\x8f\xe5\xcc\xb1\x9b\xa6\x1c\x4c\x08\x73\xd3\x91\xe9\x87\x98\x2f\xbb\xd3", SHA_DIGEST_LENGTH) == 0);
107  check (memcmp (hash, hash_, SHA_DIGEST_LENGTH) == 0);
108
109  check (tr_sha1 (hash, "1", 1, "22", 2, "333", 3, NULL));
110  check (tr_sha1_ (hash_, "1", 1, "22", 2, "333", 3, NULL));
111  check (memcmp (hash, "\x1f\x74\x64\x8e\x50\xa6\xa6\x70\x8e\xc5\x4a\xb3\x27\xa1\x63\xd5\x53\x6b\x7c\xed", SHA_DIGEST_LENGTH) == 0);
112  check (memcmp (hash, hash_, SHA_DIGEST_LENGTH) == 0);
113
114  return 0;
115}
116
117static int
118test_ssha1 (void)
119{
120  const char * const test_data[] =
121    {
122      "test",
123      "QNY)(*#$B)!_X$B !_B#($^!)*&$%CV!#)&$C!@$(P*)"
124    };
125
126  size_t i;
127
128#define HASH_COUNT (16 * 1024)
129
130  for (i = 0; i < sizeof (test_data) / sizeof (*test_data); ++i)
131    {
132      char * const phrase = tr_strdup (test_data[i]);
133      char ** hashes = tr_new (char *, HASH_COUNT);
134      size_t j;
135
136      for (j = 0; j < HASH_COUNT; ++j)
137        {
138          hashes[j] = j % 2 == 0 ? tr_ssha1 (phrase) : tr_ssha1_ (phrase);
139
140          check (hashes[j] != NULL);
141
142          /* phrase matches each of generated hashes */
143          check (tr_ssha1_matches (hashes[j], phrase));
144          check (tr_ssha1_matches_ (hashes[j], phrase));
145        }
146
147      for (j = 0; j < HASH_COUNT; ++j)
148        {
149          size_t k;
150
151          /* all hashes are different */
152          for (k = 0; k < HASH_COUNT; ++k)
153            check (k == j || strcmp (hashes[j], hashes[k]) != 0);
154        }
155
156      /* exchange two first chars */
157      phrase[0] ^= phrase[1];
158      phrase[1] ^= phrase[0];
159      phrase[0] ^= phrase[1];
160
161      for (j = 0; j < HASH_COUNT; ++j)
162        {
163          /* changed phrase doesn't match the hashes */
164          check (!tr_ssha1_matches (hashes[j], phrase));
165          check (!tr_ssha1_matches_ (hashes[j], phrase));
166        }
167
168      for (j = 0; j < HASH_COUNT; ++j)
169        tr_free (hashes[j]);
170
171      tr_free (hashes);
172      tr_free (phrase);
173    }
174
175#undef HASH_COUNT
176
177  return 0;
178}
179
180static int
181test_random (void)
182{
183  int i;
184
185  /* test that tr_rand_int () stays in-bounds */
186  for (i = 0; i < 100000; ++i)
187    {
188      const int val = tr_rand_int (100);
189      check (val >= 0);
190      check (val < 100);
191    }
192
193  return 0;
194}
195
196static bool
197base64_eq (const char * a,
198           const char * b)
199{
200  for (; ; ++a, ++b)
201    {
202      while (*a == '\r' || *a == '\n')
203        ++a;
204      while (*b == '\r' || *b == '\n')
205        ++b;
206      if (*a == '\0' || *b == '\0' || *a != *b)
207        break;
208    }
209
210  return *a == *b;
211}
212
213static int
214test_base64 (void)
215{
216  size_t len;
217  char * in, * out;
218  size_t i;
219
220  out = tr_base64_encode_str ("YOYO!", &len);
221  check_uint_eq (strlen (out), len);
222  check (base64_eq ("WU9ZTyE=", out));
223  in = tr_base64_decode_str (out, &len);
224  check_uint_eq (5, len);
225  check_streq ("YOYO!", in);
226  tr_free (in);
227  tr_free (out);
228
229  out = tr_base64_encode ("", 0, &len);
230  check_uint_eq (0, len);
231  check_streq ("", out);
232  tr_free (out);
233  out = tr_base64_decode ("", 0, &len);
234  check_uint_eq (0, len);
235  check_streq ("", out);
236  tr_free (out);
237
238  out = tr_base64_encode (NULL, 0, &len);
239  check_uint_eq (0, len);
240  check (out == NULL);
241  out = tr_base64_decode (NULL, 0, &len);
242  check_uint_eq (0, len);
243  check (out == NULL);
244
245#define MAX_BUF_SIZE 1024
246
247  for (i = 1; i <= MAX_BUF_SIZE; ++i)
248    {
249      size_t j;
250      char buf[MAX_BUF_SIZE + 1];
251
252      for (j = 0; j < i; ++j)
253        buf[j] = (char) tr_rand_int_weak (256);
254
255      out = tr_base64_encode (buf, j, &len);
256      check_uint_eq (strlen (out), len);
257      in = tr_base64_decode (out, len, &len);
258      check_uint_eq (j, len);
259      check (memcmp (in, buf, len) == 0);
260      tr_free (in);
261      tr_free (out);
262
263      for (j = 0; j < i; ++j)
264        buf[j] = (char)(1 + tr_rand_int_weak (255));
265      buf[j] = '\0';
266
267      out = tr_base64_encode_str (buf, &len);
268      check_uint_eq (strlen (out), len);
269      in = tr_base64_decode_str (out, &len);
270      check_uint_eq (j, len);
271      check_streq (in, buf);
272      tr_free (in);
273      tr_free (out);
274    }
275
276#undef MAX_BUF_SIZE
277
278  return 0;
279}
280
281int
282main (void)
283{
284  const testFunc tests[] = { test_torrent_hash,
285                             test_encrypt_decrypt,
286                             test_sha1,
287                             test_ssha1,
288                             test_random,
289                             test_base64 };
290
291  return runTests (tests, NUM_TESTS (tests));
292}
Note: See TracBrowser for help on using the repository browser.