1 /* Copyright (c) 2014-2021, The Tor Project, Inc. */
2 /* See LICENSE for licensing information */
6 #include "core/or/or.h"
7 #include "feature/dirauth/keypin.h"
12 test_keypin_parse_line(void *arg
)
15 keypin_ent_t
*ent
= NULL
;
18 ent
= keypin_parse_journal_line(
19 "aGVyZSBpcyBhIGdvb2Qgc2hhMSE "
20 "VGhpcyBlZDI1NTE5IHNjb2ZmcyBhdCB0aGUgc2hhMS4");
22 tt_mem_op(ent
->rsa_id
, OP_EQ
, "here is a good sha1!", 20);
23 tt_mem_op(ent
->ed25519_key
, OP_EQ
, "This ed25519 scoffs at the sha1.", 32);
24 tor_free(ent
); ent
= NULL
;
26 /* Good line with extra stuff we will ignore. */
27 ent
= keypin_parse_journal_line(
28 "aGVyZSBpcyBhIGdvb2Qgc2hhMSE "
29 "VGhpcyBlZDI1NTE5IHNjb2ZmcyBhdCB0aGUgc2hhMS4helloworld");
31 tt_mem_op(ent
->rsa_id
, OP_EQ
, "here is a good sha1!", 20);
32 tt_mem_op(ent
->ed25519_key
, OP_EQ
, "This ed25519 scoffs at the sha1.", 32);
33 tor_free(ent
); ent
= NULL
;
35 /* Bad line: no space in the middle. */
36 ent
= keypin_parse_journal_line(
37 "aGVyZSBpcyBhIGdvb2Qgc2hhMSE?"
38 "VGhpcyBlZDI1NTE5IHNjb2ZmcyBhdCB0aGUgc2hhMS4");
39 tt_ptr_op(ent
, OP_EQ
, NULL
);
41 /* Bad line: bad base64 in RSA ID */
42 ent
= keypin_parse_journal_line(
43 "aGVyZSBpcyBhIGdv!2Qgc2hhMSE "
44 "VGhpcyBlZDI1NTE5IHNjb2ZmcyBhdCB0aGUgc2hhMS4");
45 tt_ptr_op(ent
, OP_EQ
, NULL
);
47 /* Bad line: bad base64 in Ed25519 */
48 ent
= keypin_parse_journal_line(
49 "aGVyZSBpcyBhIGdvb2Qgc2hhMSE "
50 "VGhpcyBlZDI1NTE5IHNjb2ZmcyB!dCB0aGUgc2hhMS4");
51 tt_ptr_op(ent
, OP_EQ
, NULL
);
57 static smartlist_t
*mock_addent_got
= NULL
;
59 mock_addent(keypin_ent_t
*ent
)
61 smartlist_add(mock_addent_got
, ent
);
62 keypin_add_entry_to_map__real(ent
);
66 test_keypin_parse_file(void *arg
)
70 mock_addent_got
= smartlist_new();
71 MOCK(keypin_add_entry_to_map
, mock_addent
);
73 /* Simple, minimal, correct example. */
75 "PT09PT09PT09PT09PT09PT09PT0 PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0\n"
76 "TG9yYXggaXBzdW0gZ3J1dnZ1bHU cyB0aG5lZWQgYW1ldCwgc25lcmdlbGx5IG9uY2UtbGU\n"
77 "ciBsZXJraW0sIHNlZCBkbyBiYXI YmFsb290IHRlbXBvciBnbHVwcGl0dXMgdXQgbGFib3I\n"
78 "ZSBldCB0cnVmZnVsYSBtYWduYSA YWxpcXVhLiBVdCBlbmltIGFkIGdyaWNrbGUtZ3Jhc3M\n"
79 "dmVuaWFtLCBxdWlzIG1pZmYtbXU ZmZlcmVkIGdhLXp1bXBjbyBsYWJvcmlzIG5pc2kgdXQ\n"
80 "Y3J1ZmZ1bHVzIGV4IGVhIHNjaGw b3BwaXR5IGNvbnNlcXVhdC4gRHVpcyBhdXRlIHNuYXI\n"
81 "Z2dsZSBpbiBzd29tZWVzd2FucyA aW4gdm9sdXB0YXRlIGF4ZS1oYWNrZXIgZXNzZSByaXA\n"
82 "cHVsdXMgY3J1bW1paSBldSBtb28 ZiBudWxsYSBzbnV2di5QTFVHSFBMT1ZFUlhZWlpZLi4\n";
84 tt_int_op(0, OP_EQ
, keypin_load_journal_impl(data1
, strlen(data1
)));
85 tt_int_op(8, OP_EQ
, smartlist_len(mock_addent_got
));
86 keypin_ent_t
*ent
= smartlist_get(mock_addent_got
, 2);
87 tt_mem_op(ent
->rsa_id
, OP_EQ
, "r lerkim, sed do bar", 20);
88 tt_mem_op(ent
->ed25519_key
, OP_EQ
, "baloot tempor gluppitus ut labor", 32);
90 /* More complex example: weird lines, bogus lines,
91 duplicate/conflicting lines */
93 "PT09PT09PT09PT09PT09PT09PT0 PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0\n"
94 "# This is a comment.\n"
96 "QXQgdGhlIGVuZCBvZiB0aGUgeWU YXIgS3VycmVta2FybWVycnVrIHNhaWQgdG8gaGltLCA\n"
97 "IllvdSBoYXZlIG1hZGUgYSBnb28 ZCBiZWdpbm5pbmcuIiBCdXQgbm8gbW9yZS4gV2l6YXI\n"
99 "ZHMgc3BlYWsgdHJ1dGgsIGFuZCA aXQgd2FzIHRydWUgdGhhdCBhbGwgdGhlIG1hc3Rlcgo\n"
100 "@reserved for a future extension \n"
101 "eSBvZiBOYW1lcyB0aGF0IEdlZCA aGFkIHRvaWxlZCbyB3aW4gdGhhdCB5ZWFyIHdhcyA\n"
102 "eSBvZiBOYW1lcyB0aGF0IEdlZCA aGFkIHRvaWxlZCbyB3aW4gdGhhdCB5ZWFyIHdhcy"
104 "dGhlIG1lcmUgc3RhcnQgb2Ygd2g YXQgaGUgbXVzdCBnbyBvb!BsZWFybmluZy4uLi4uLi4\n"
105 "ZHMgc3BlYWsgdaJ1dGgsIGFuZCA aXQgd2FzIHRydWUgdGhhdCBhbGwgdGhlIG1hc3Rlcgo\n"
106 "ZHMgc3BlYWsgdHJ1dGgsIGFuZCA aXQgd2FzIHRydaUgdGhhdCBhbGwgdGhlIG1hc3Rlcgo\n"
109 tt_int_op(0, OP_EQ
, keypin_load_journal_impl(data2
, strlen(data2
)));
110 tt_int_op(13, OP_EQ
, smartlist_len(mock_addent_got
));
111 ent
= smartlist_get(mock_addent_got
, 9);
112 tt_mem_op(ent
->rsa_id
, OP_EQ
, "\"You have made a goo", 20);
113 tt_mem_op(ent
->ed25519_key
, OP_EQ
, "d beginning.\" But no more. Wizar", 32);
115 ent
= smartlist_get(mock_addent_got
, 12);
116 tt_mem_op(ent
->rsa_id
, OP_EQ
, "ds speak truth, and ", 20);
117 tt_mem_op(ent
->ed25519_key
, OP_EQ
,
118 "it was tru\xa5 that all the master\n", 32);
120 /* File truncated before NL */
122 "Tm8gZHJhZ29uIGNhbiByZXNpc3Q IHRoZSBmYXNjaW5hdGlvbiBvZiByaWRkbGluZyB0YWw";
123 tt_int_op(0, OP_EQ
, keypin_load_journal_impl(data3
, strlen(data3
)));
124 tt_int_op(14, OP_EQ
, smartlist_len(mock_addent_got
));
125 ent
= smartlist_get(mock_addent_got
, 13);
126 tt_mem_op(ent
->rsa_id
, OP_EQ
, "No dragon can resist", 20);
127 tt_mem_op(ent
->ed25519_key
, OP_EQ
, " the fascination of riddling tal", 32);
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))
139 test_keypin_add_entry(void *arg
)
144 tt_int_op(KEYPIN_ADDED
, OP_EQ
, ADD("ambassadors-at-large",
145 "bread-and-butter thing-in-itself"));
146 tt_int_op(KEYPIN_ADDED
, OP_EQ
, ADD("gentleman-adventurer",
147 "cloak-and-dagger what's-his-face"));
149 tt_int_op(KEYPIN_FOUND
, OP_EQ
, ADD("ambassadors-at-large",
150 "bread-and-butter thing-in-itself"));
151 tt_int_op(KEYPIN_FOUND
, OP_EQ
, ADD("ambassadors-at-large",
152 "bread-and-butter thing-in-itself"));
153 tt_int_op(KEYPIN_FOUND
, OP_EQ
, ADD("gentleman-adventurer",
154 "cloak-and-dagger what's-his-face"));
156 tt_int_op(KEYPIN_ADDED
, OP_EQ
, ADD("Johnnies-come-lately",
157 "run-of-the-mill root-mean-square"));
159 tt_int_op(KEYPIN_MISMATCH
, OP_EQ
, ADD("gentleman-adventurer",
160 "hypersentimental closefistedness"));
162 tt_int_op(KEYPIN_MISMATCH
, OP_EQ
, ADD("disestablismentarian",
163 "cloak-and-dagger what's-his-face"));
165 tt_int_op(KEYPIN_FOUND
, OP_EQ
, ADD("gentleman-adventurer",
166 "cloak-and-dagger what's-his-face"));
168 tt_int_op(KEYPIN_NOT_FOUND
, OP_EQ
, LONE_RSA("Llanfairpwllgwyngyll"));
169 tt_int_op(KEYPIN_MISMATCH
, OP_EQ
, LONE_RSA("Johnnies-come-lately"));
176 test_keypin_journal(void *arg
)
179 char *contents
= NULL
;
180 const char *fname
= get_fname("keypin-journal");
182 tt_int_op(0, OP_EQ
, keypin_load_journal(fname
)); /* ENOENT is okay */
183 update_approx_time(1217709000);
184 tt_int_op(0, OP_EQ
, keypin_open_journal(fname
));
186 tt_int_op(KEYPIN_ADDED
, OP_EQ
, ADD("king-of-the-herrings",
187 "good-for-nothing attorney-at-law"));
188 tt_int_op(KEYPIN_ADDED
, OP_EQ
, ADD("yellowish-red-yellow",
189 "salt-and-pepper high-muck-a-muck"));
190 tt_int_op(KEYPIN_FOUND
, OP_EQ
, ADD("yellowish-red-yellow",
191 "salt-and-pepper high-muck-a-muck"));
192 keypin_close_journal();
195 tt_int_op(0, OP_EQ
, keypin_load_journal(fname
));
196 update_approx_time(1231041600);
197 tt_int_op(0, OP_EQ
, keypin_open_journal(fname
));
198 tt_int_op(KEYPIN_FOUND
, OP_EQ
, ADD("yellowish-red-yellow",
199 "salt-and-pepper high-muck-a-muck"));
200 tt_int_op(KEYPIN_ADDED
, OP_EQ
, ADD("theatre-in-the-round",
201 "holier-than-thou jack-in-the-box"));
202 tt_int_op(KEYPIN_ADDED
, OP_EQ
, ADD("no-deposit-no-return",
203 "across-the-board will-o-the-wisp"));
204 tt_int_op(KEYPIN_MISMATCH
, OP_EQ
, ADD("intellectualizations",
205 "salt-and-pepper high-muck-a-muck"));
206 keypin_close_journal();
209 tt_int_op(0, OP_EQ
, keypin_load_journal(fname
));
210 update_approx_time(1412278354);
211 tt_int_op(0, OP_EQ
, keypin_open_journal(fname
));
212 tt_int_op(KEYPIN_FOUND
, OP_EQ
, ADD("yellowish-red-yellow",
213 "salt-and-pepper high-muck-a-muck"));
214 tt_int_op(KEYPIN_MISMATCH
, OP_EQ
, ADD("intellectualizations",
215 "salt-and-pepper high-muck-a-muck"));
216 tt_int_op(KEYPIN_FOUND
, OP_EQ
, ADD("theatre-in-the-round",
217 "holier-than-thou jack-in-the-box"));
218 tt_int_op(KEYPIN_MISMATCH
, OP_EQ
, ADD("counterrevolutionary",
219 "holier-than-thou jack-in-the-box"));
220 tt_int_op(KEYPIN_MISMATCH
, OP_EQ
, ADD("no-deposit-no-return",
221 "floccinaucinihilipilificationism"));
222 keypin_close_journal();
224 contents
= read_file_to_str(fname
, RFTS_BIN
, NULL
);
226 tt_str_op(contents
,OP_EQ
,
228 "@opened-at 2008-08-02 20:30:00\n"
229 "a2luZy1vZi10aGUtaGVycmluZ3M Z29vZC1mb3Itbm90aGluZyBhdHRvcm5leS1hdC1sYXc\n"
230 "eWVsbG93aXNoLXJlZC15ZWxsb3c c2FsdC1hbmQtcGVwcGVyIGhpZ2gtbXVjay1hLW11Y2s\n"
232 "@opened-at 2009-01-04 04:00:00\n"
233 "dGhlYXRyZS1pbi10aGUtcm91bmQ aG9saWVyLXRoYW4tdGhvdSBqYWNrLWluLXRoZS1ib3g\n"
234 "bm8tZGVwb3NpdC1uby1yZXR1cm4 YWNyb3NzLXRoZS1ib2FyZCB3aWxsLW8tdGhlLXdpc3A\n"
236 "@opened-at 2014-10-02 19:32:34\n");
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
),