changelog typo fix
[tor.git] / src / test / test_keypin.c
blob95657349c6d47b615ca95c12e6cff1f335075579
1 /* Copyright (c) 2014-2016, The Tor Project, Inc. */
2 /* See LICENSE for licensing information */
4 #include "orconfig.h"
5 #define KEYPIN_PRIVATE
6 #include "or.h"
7 #include "keypin.h"
8 #include "util.h"
10 #include "test.h"
12 static void
13 test_keypin_parse_line(void *arg)
15 (void)arg;
16 keypin_ent_t *ent = NULL;
18 /* Good line */
19 ent = keypin_parse_journal_line(
20 "aGVyZSBpcyBhIGdvb2Qgc2hhMSE "
21 "VGhpcyBlZDI1NTE5IHNjb2ZmcyBhdCB0aGUgc2hhMS4");
22 tt_assert(ent);
23 tt_mem_op(ent->rsa_id, ==, "here is a good sha1!", 20);
24 tt_mem_op(ent->ed25519_key, ==, "This ed25519 scoffs at the sha1.", 32);
25 tor_free(ent); ent = NULL;
27 /* Good line with extra stuff we will ignore. */
28 ent = keypin_parse_journal_line(
29 "aGVyZSBpcyBhIGdvb2Qgc2hhMSE "
30 "VGhpcyBlZDI1NTE5IHNjb2ZmcyBhdCB0aGUgc2hhMS4helloworld");
31 tt_assert(ent);
32 tt_mem_op(ent->rsa_id, ==, "here is a good sha1!", 20);
33 tt_mem_op(ent->ed25519_key, ==, "This ed25519 scoffs at the sha1.", 32);
34 tor_free(ent); ent = NULL;
36 /* Bad line: no space in the middle. */
37 ent = keypin_parse_journal_line(
38 "aGVyZSBpcyBhIGdvb2Qgc2hhMSE?"
39 "VGhpcyBlZDI1NTE5IHNjb2ZmcyBhdCB0aGUgc2hhMS4");
40 tt_assert(! ent);
42 /* Bad line: bad base64 in RSA ID */
43 ent = keypin_parse_journal_line(
44 "aGVyZSBpcyBhIGdv!2Qgc2hhMSE "
45 "VGhpcyBlZDI1NTE5IHNjb2ZmcyBhdCB0aGUgc2hhMS4");
46 tt_assert(! ent);
48 /* Bad line: bad base64 in Ed25519 */
49 ent = keypin_parse_journal_line(
50 "aGVyZSBpcyBhIGdvb2Qgc2hhMSE "
51 "VGhpcyBlZDI1NTE5IHNjb2ZmcyB!dCB0aGUgc2hhMS4");
52 tt_assert(! ent);
54 done:
55 tor_free(ent);
58 static smartlist_t *mock_addent_got = NULL;
59 static void
60 mock_addent(keypin_ent_t *ent)
62 smartlist_add(mock_addent_got, ent);
63 keypin_add_entry_to_map__real(ent);
66 static void
67 test_keypin_parse_file(void *arg)
69 (void)arg;
71 mock_addent_got = smartlist_new();
72 MOCK(keypin_add_entry_to_map, mock_addent);
74 /* Simple, minimal, correct example. */
75 const char data1[] =
76 "PT09PT09PT09PT09PT09PT09PT0 PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0\n"
77 "TG9yYXggaXBzdW0gZ3J1dnZ1bHU cyB0aG5lZWQgYW1ldCwgc25lcmdlbGx5IG9uY2UtbGU\n"
78 "ciBsZXJraW0sIHNlZCBkbyBiYXI YmFsb290IHRlbXBvciBnbHVwcGl0dXMgdXQgbGFib3I\n"
79 "ZSBldCB0cnVmZnVsYSBtYWduYSA YWxpcXVhLiBVdCBlbmltIGFkIGdyaWNrbGUtZ3Jhc3M\n"
80 "dmVuaWFtLCBxdWlzIG1pZmYtbXU ZmZlcmVkIGdhLXp1bXBjbyBsYWJvcmlzIG5pc2kgdXQ\n"
81 "Y3J1ZmZ1bHVzIGV4IGVhIHNjaGw b3BwaXR5IGNvbnNlcXVhdC4gRHVpcyBhdXRlIHNuYXI\n"
82 "Z2dsZSBpbiBzd29tZWVzd2FucyA aW4gdm9sdXB0YXRlIGF4ZS1oYWNrZXIgZXNzZSByaXA\n"
83 "cHVsdXMgY3J1bW1paSBldSBtb28 ZiBudWxsYSBzbnV2di5QTFVHSFBMT1ZFUlhZWlpZLi4\n";
85 tt_int_op(0, ==, keypin_load_journal_impl(data1, strlen(data1)));
86 tt_int_op(8, ==, smartlist_len(mock_addent_got));
87 keypin_ent_t *ent = smartlist_get(mock_addent_got, 2);
88 tt_mem_op(ent->rsa_id, ==, "r lerkim, sed do bar", 20);
89 tt_mem_op(ent->ed25519_key, ==, "baloot tempor gluppitus ut labor", 32);
91 /* More complex example: weird lines, bogus lines,
92 duplicate/conflicting lines */
93 const char data2[] =
94 "PT09PT09PT09PT09PT09PT09PT0 PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0\n"
95 "# This is a comment.\n"
96 " \n"
97 "QXQgdGhlIGVuZCBvZiB0aGUgeWU YXIgS3VycmVta2FybWVycnVrIHNhaWQgdG8gaGltLCA\n"
98 "IllvdSBoYXZlIG1hZGUgYSBnb28 ZCBiZWdpbm5pbmcuIiBCdXQgbm8gbW9yZS4gV2l6YXI\n"
99 "\n"
100 "ZHMgc3BlYWsgdHJ1dGgsIGFuZCA aXQgd2FzIHRydWUgdGhhdCBhbGwgdGhlIG1hc3Rlcgo\n"
101 "@reserved for a future extension \n"
102 "eSBvZiBOYW1lcyB0aGF0IEdlZCA aGFkIHRvaWxlZCbyB3aW4gdGhhdCB5ZWFyIHdhcyA\n"
103 "eSBvZiBOYW1lcyB0aGF0IEdlZCA aGFkIHRvaWxlZCbyB3aW4gdGhhdCB5ZWFyIHdhcy"
104 "A line too long\n"
105 "dGhlIG1lcmUgc3RhcnQgb2Ygd2g YXQgaGUgbXVzdCBnbyBvb!BsZWFybmluZy4uLi4uLi4\n"
106 "ZHMgc3BlYWsgdaJ1dGgsIGFuZCA aXQgd2FzIHRydWUgdGhhdCBhbGwgdGhlIG1hc3Rlcgo\n"
107 "ZHMgc3BlYWsgdHJ1dGgsIGFuZCA aXQgd2FzIHRydaUgdGhhdCBhbGwgdGhlIG1hc3Rlcgo\n"
110 tt_int_op(0, ==, keypin_load_journal_impl(data2, strlen(data2)));
111 tt_int_op(13, ==, smartlist_len(mock_addent_got));
112 ent = smartlist_get(mock_addent_got, 9);
113 tt_mem_op(ent->rsa_id, ==, "\"You have made a goo", 20);
114 tt_mem_op(ent->ed25519_key, ==, "d beginning.\" But no more. Wizar", 32);
116 ent = smartlist_get(mock_addent_got, 12);
117 tt_mem_op(ent->rsa_id, ==, "ds speak truth, and ", 20);
118 tt_mem_op(ent->ed25519_key, ==, "it was tru\xa5 that all the master\n", 32);
120 /* File truncated before NL */
121 const char data3[] =
122 "Tm8gZHJhZ29uIGNhbiByZXNpc3Q IHRoZSBmYXNjaW5hdGlvbiBvZiByaWRkbGluZyB0YWw";
123 tt_int_op(0, ==, keypin_load_journal_impl(data3, strlen(data3)));
124 tt_int_op(14, ==, smartlist_len(mock_addent_got));
125 ent = smartlist_get(mock_addent_got, 13);
126 tt_mem_op(ent->rsa_id, ==, "No dragon can resist", 20);
127 tt_mem_op(ent->ed25519_key, ==, " the fascination of riddling tal", 32);
129 done:
130 keypin_clear();
131 smartlist_free(mock_addent_got);
134 #define ADD(a,b) keypin_check_and_add((const uint8_t*)(a),\
135 (const uint8_t*)(b),0)
136 #define LONE_RSA(a) keypin_check_lone_rsa((const uint8_t*)(a))
138 static void
139 test_keypin_add_entry(void *arg)
141 (void)arg;
142 keypin_clear();
144 tt_int_op(KEYPIN_ADDED, ==, ADD("ambassadors-at-large",
145 "bread-and-butter thing-in-itself"));
146 tt_int_op(KEYPIN_ADDED, ==, ADD("gentleman-adventurer",
147 "cloak-and-dagger what's-his-face"));
149 tt_int_op(KEYPIN_FOUND, ==, ADD("ambassadors-at-large",
150 "bread-and-butter thing-in-itself"));
151 tt_int_op(KEYPIN_FOUND, ==, ADD("ambassadors-at-large",
152 "bread-and-butter thing-in-itself"));
153 tt_int_op(KEYPIN_FOUND, ==, ADD("gentleman-adventurer",
154 "cloak-and-dagger what's-his-face"));
156 tt_int_op(KEYPIN_ADDED, ==, ADD("Johnnies-come-lately",
157 "run-of-the-mill root-mean-square"));
159 tt_int_op(KEYPIN_MISMATCH, ==, ADD("gentleman-adventurer",
160 "hypersentimental closefistedness"));
162 tt_int_op(KEYPIN_MISMATCH, ==, ADD("disestablismentarian",
163 "cloak-and-dagger what's-his-face"));
165 tt_int_op(KEYPIN_FOUND, ==, ADD("gentleman-adventurer",
166 "cloak-and-dagger what's-his-face"));
168 tt_int_op(KEYPIN_NOT_FOUND, ==, LONE_RSA("Llanfairpwllgwyngyll"));
169 tt_int_op(KEYPIN_MISMATCH, ==, LONE_RSA("Johnnies-come-lately"));
171 done:
172 keypin_clear();
175 static void
176 test_keypin_journal(void *arg)
178 (void)arg;
179 char *contents = NULL;
180 const char *fname = get_fname("keypin-journal");
182 tt_int_op(0, ==, keypin_load_journal(fname)); /* ENOENT is okay */
183 update_approx_time(1217709000);
184 tt_int_op(0, ==, keypin_open_journal(fname));
186 tt_int_op(KEYPIN_ADDED, ==, ADD("king-of-the-herrings",
187 "good-for-nothing attorney-at-law"));
188 tt_int_op(KEYPIN_ADDED, ==, ADD("yellowish-red-yellow",
189 "salt-and-pepper high-muck-a-muck"));
190 tt_int_op(KEYPIN_FOUND, ==, ADD("yellowish-red-yellow",
191 "salt-and-pepper high-muck-a-muck"));
192 keypin_close_journal();
193 keypin_clear();
195 tt_int_op(0, ==, keypin_load_journal(fname));
196 update_approx_time(1231041600);
197 tt_int_op(0, ==, keypin_open_journal(fname));
198 tt_int_op(KEYPIN_FOUND, ==, ADD("yellowish-red-yellow",
199 "salt-and-pepper high-muck-a-muck"));
200 tt_int_op(KEYPIN_ADDED, ==, ADD("theatre-in-the-round",
201 "holier-than-thou jack-in-the-box"));
202 tt_int_op(KEYPIN_ADDED, ==, ADD("no-deposit-no-return",
203 "across-the-board will-o-the-wisp"));
204 tt_int_op(KEYPIN_MISMATCH, ==, ADD("intellectualizations",
205 "salt-and-pepper high-muck-a-muck"));
206 keypin_close_journal();
207 keypin_clear();
209 tt_int_op(0, ==, keypin_load_journal(fname));
210 update_approx_time(1412278354);
211 tt_int_op(0, ==, keypin_open_journal(fname));
212 tt_int_op(KEYPIN_FOUND, ==, ADD("yellowish-red-yellow",
213 "salt-and-pepper high-muck-a-muck"));
214 tt_int_op(KEYPIN_MISMATCH, ==, ADD("intellectualizations",
215 "salt-and-pepper high-muck-a-muck"));
216 tt_int_op(KEYPIN_FOUND, ==, ADD("theatre-in-the-round",
217 "holier-than-thou jack-in-the-box"));
218 tt_int_op(KEYPIN_MISMATCH, ==, ADD("counterrevolutionary",
219 "holier-than-thou jack-in-the-box"));
220 tt_int_op(KEYPIN_MISMATCH, ==, ADD("no-deposit-no-return",
221 "floccinaucinihilipilificationism"));
222 keypin_close_journal();
224 contents = read_file_to_str(fname, RFTS_BIN, NULL);
225 tt_assert(contents);
226 tt_str_op(contents,==,
227 "\n"
228 "@opened-at 2008-08-02 20:30:00\n"
229 "a2luZy1vZi10aGUtaGVycmluZ3M Z29vZC1mb3Itbm90aGluZyBhdHRvcm5leS1hdC1sYXc\n"
230 "eWVsbG93aXNoLXJlZC15ZWxsb3c c2FsdC1hbmQtcGVwcGVyIGhpZ2gtbXVjay1hLW11Y2s\n"
231 "\n"
232 "@opened-at 2009-01-04 04:00:00\n"
233 "dGhlYXRyZS1pbi10aGUtcm91bmQ aG9saWVyLXRoYW4tdGhvdSBqYWNrLWluLXRoZS1ib3g\n"
234 "bm8tZGVwb3NpdC1uby1yZXR1cm4 YWNyb3NzLXRoZS1ib2FyZCB3aWxsLW8tdGhlLXdpc3A\n"
235 "\n"
236 "@opened-at 2014-10-02 19:32:34\n");
238 done:
239 tor_free(contents);
240 keypin_clear();
243 #undef ADD
244 #undef LONE_RSA
246 #define TEST(name, flags) \
247 { #name , test_keypin_ ## name, (flags), NULL, NULL }
249 struct testcase_t keypin_tests[] = {
250 TEST( parse_line, 0 ),
251 TEST( parse_file, TT_FORK ),
252 TEST( add_entry, TT_FORK ),
253 TEST( journal, TT_FORK ),
254 END_OF_TESTCASES