mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-14 07:03:44 +01:00
257 lines
9.7 KiB
C
257 lines
9.7 KiB
C
/* Copyright (c) 2014-2019, The Tor Project, Inc. */
|
|
/* See LICENSE for licensing information */
|
|
|
|
#include "orconfig.h"
|
|
#define KEYPIN_PRIVATE
|
|
#include "core/or/or.h"
|
|
#include "feature/dirauth/keypin.h"
|
|
|
|
#include "test/test.h"
|
|
|
|
static void
|
|
test_keypin_parse_line(void *arg)
|
|
{
|
|
(void)arg;
|
|
keypin_ent_t *ent = NULL;
|
|
|
|
/* Good line */
|
|
ent = keypin_parse_journal_line(
|
|
"aGVyZSBpcyBhIGdvb2Qgc2hhMSE "
|
|
"VGhpcyBlZDI1NTE5IHNjb2ZmcyBhdCB0aGUgc2hhMS4");
|
|
tt_assert(ent);
|
|
tt_mem_op(ent->rsa_id, OP_EQ, "here is a good sha1!", 20);
|
|
tt_mem_op(ent->ed25519_key, OP_EQ, "This ed25519 scoffs at the sha1.", 32);
|
|
tor_free(ent); ent = NULL;
|
|
|
|
/* Good line with extra stuff we will ignore. */
|
|
ent = keypin_parse_journal_line(
|
|
"aGVyZSBpcyBhIGdvb2Qgc2hhMSE "
|
|
"VGhpcyBlZDI1NTE5IHNjb2ZmcyBhdCB0aGUgc2hhMS4helloworld");
|
|
tt_assert(ent);
|
|
tt_mem_op(ent->rsa_id, OP_EQ, "here is a good sha1!", 20);
|
|
tt_mem_op(ent->ed25519_key, OP_EQ, "This ed25519 scoffs at the sha1.", 32);
|
|
tor_free(ent); ent = NULL;
|
|
|
|
/* Bad line: no space in the middle. */
|
|
ent = keypin_parse_journal_line(
|
|
"aGVyZSBpcyBhIGdvb2Qgc2hhMSE?"
|
|
"VGhpcyBlZDI1NTE5IHNjb2ZmcyBhdCB0aGUgc2hhMS4");
|
|
tt_ptr_op(ent, OP_EQ, NULL);
|
|
|
|
/* Bad line: bad base64 in RSA ID */
|
|
ent = keypin_parse_journal_line(
|
|
"aGVyZSBpcyBhIGdv!2Qgc2hhMSE "
|
|
"VGhpcyBlZDI1NTE5IHNjb2ZmcyBhdCB0aGUgc2hhMS4");
|
|
tt_ptr_op(ent, OP_EQ, NULL);
|
|
|
|
/* Bad line: bad base64 in Ed25519 */
|
|
ent = keypin_parse_journal_line(
|
|
"aGVyZSBpcyBhIGdvb2Qgc2hhMSE "
|
|
"VGhpcyBlZDI1NTE5IHNjb2ZmcyB!dCB0aGUgc2hhMS4");
|
|
tt_ptr_op(ent, OP_EQ, NULL);
|
|
|
|
done:
|
|
tor_free(ent);
|
|
}
|
|
|
|
static smartlist_t *mock_addent_got = NULL;
|
|
static void
|
|
mock_addent(keypin_ent_t *ent)
|
|
{
|
|
smartlist_add(mock_addent_got, ent);
|
|
keypin_add_entry_to_map__real(ent);
|
|
}
|
|
|
|
static void
|
|
test_keypin_parse_file(void *arg)
|
|
{
|
|
(void)arg;
|
|
|
|
mock_addent_got = smartlist_new();
|
|
MOCK(keypin_add_entry_to_map, mock_addent);
|
|
|
|
/* Simple, minimal, correct example. */
|
|
const char data1[] =
|
|
"PT09PT09PT09PT09PT09PT09PT0 PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0\n"
|
|
"TG9yYXggaXBzdW0gZ3J1dnZ1bHU cyB0aG5lZWQgYW1ldCwgc25lcmdlbGx5IG9uY2UtbGU\n"
|
|
"ciBsZXJraW0sIHNlZCBkbyBiYXI YmFsb290IHRlbXBvciBnbHVwcGl0dXMgdXQgbGFib3I\n"
|
|
"ZSBldCB0cnVmZnVsYSBtYWduYSA YWxpcXVhLiBVdCBlbmltIGFkIGdyaWNrbGUtZ3Jhc3M\n"
|
|
"dmVuaWFtLCBxdWlzIG1pZmYtbXU ZmZlcmVkIGdhLXp1bXBjbyBsYWJvcmlzIG5pc2kgdXQ\n"
|
|
"Y3J1ZmZ1bHVzIGV4IGVhIHNjaGw b3BwaXR5IGNvbnNlcXVhdC4gRHVpcyBhdXRlIHNuYXI\n"
|
|
"Z2dsZSBpbiBzd29tZWVzd2FucyA aW4gdm9sdXB0YXRlIGF4ZS1oYWNrZXIgZXNzZSByaXA\n"
|
|
"cHVsdXMgY3J1bW1paSBldSBtb28 ZiBudWxsYSBzbnV2di5QTFVHSFBMT1ZFUlhZWlpZLi4\n";
|
|
|
|
tt_int_op(0, OP_EQ, keypin_load_journal_impl(data1, strlen(data1)));
|
|
tt_int_op(8, OP_EQ, smartlist_len(mock_addent_got));
|
|
keypin_ent_t *ent = smartlist_get(mock_addent_got, 2);
|
|
tt_mem_op(ent->rsa_id, OP_EQ, "r lerkim, sed do bar", 20);
|
|
tt_mem_op(ent->ed25519_key, OP_EQ, "baloot tempor gluppitus ut labor", 32);
|
|
|
|
/* More complex example: weird lines, bogus lines,
|
|
duplicate/conflicting lines */
|
|
const char data2[] =
|
|
"PT09PT09PT09PT09PT09PT09PT0 PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0\n"
|
|
"# This is a comment.\n"
|
|
" \n"
|
|
"QXQgdGhlIGVuZCBvZiB0aGUgeWU YXIgS3VycmVta2FybWVycnVrIHNhaWQgdG8gaGltLCA\n"
|
|
"IllvdSBoYXZlIG1hZGUgYSBnb28 ZCBiZWdpbm5pbmcuIiBCdXQgbm8gbW9yZS4gV2l6YXI\n"
|
|
"\n"
|
|
"ZHMgc3BlYWsgdHJ1dGgsIGFuZCA aXQgd2FzIHRydWUgdGhhdCBhbGwgdGhlIG1hc3Rlcgo\n"
|
|
"@reserved for a future extension \n"
|
|
"eSBvZiBOYW1lcyB0aGF0IEdlZCA aGFkIHRvaWxlZCbyB3aW4gdGhhdCB5ZWFyIHdhcyA\n"
|
|
"eSBvZiBOYW1lcyB0aGF0IEdlZCA aGFkIHRvaWxlZCbyB3aW4gdGhhdCB5ZWFyIHdhcy"
|
|
"A line too long\n"
|
|
"dGhlIG1lcmUgc3RhcnQgb2Ygd2g YXQgaGUgbXVzdCBnbyBvb!BsZWFybmluZy4uLi4uLi4\n"
|
|
"ZHMgc3BlYWsgdaJ1dGgsIGFuZCA aXQgd2FzIHRydWUgdGhhdCBhbGwgdGhlIG1hc3Rlcgo\n"
|
|
"ZHMgc3BlYWsgdHJ1dGgsIGFuZCA aXQgd2FzIHRydaUgdGhhdCBhbGwgdGhlIG1hc3Rlcgo\n"
|
|
;
|
|
|
|
tt_int_op(0, OP_EQ, keypin_load_journal_impl(data2, strlen(data2)));
|
|
tt_int_op(13, OP_EQ, smartlist_len(mock_addent_got));
|
|
ent = smartlist_get(mock_addent_got, 9);
|
|
tt_mem_op(ent->rsa_id, OP_EQ, "\"You have made a goo", 20);
|
|
tt_mem_op(ent->ed25519_key, OP_EQ, "d beginning.\" But no more. Wizar", 32);
|
|
|
|
ent = smartlist_get(mock_addent_got, 12);
|
|
tt_mem_op(ent->rsa_id, OP_EQ, "ds speak truth, and ", 20);
|
|
tt_mem_op(ent->ed25519_key, OP_EQ,
|
|
"it was tru\xa5 that all the master\n", 32);
|
|
|
|
/* File truncated before NL */
|
|
const char data3[] =
|
|
"Tm8gZHJhZ29uIGNhbiByZXNpc3Q IHRoZSBmYXNjaW5hdGlvbiBvZiByaWRkbGluZyB0YWw";
|
|
tt_int_op(0, OP_EQ, keypin_load_journal_impl(data3, strlen(data3)));
|
|
tt_int_op(14, OP_EQ, smartlist_len(mock_addent_got));
|
|
ent = smartlist_get(mock_addent_got, 13);
|
|
tt_mem_op(ent->rsa_id, OP_EQ, "No dragon can resist", 20);
|
|
tt_mem_op(ent->ed25519_key, OP_EQ, " the fascination of riddling tal", 32);
|
|
|
|
done:
|
|
keypin_clear();
|
|
smartlist_free(mock_addent_got);
|
|
}
|
|
|
|
#define ADD(a,b) keypin_check_and_add((const uint8_t*)(a),\
|
|
(const uint8_t*)(b),0)
|
|
#define LONE_RSA(a) keypin_check_lone_rsa((const uint8_t*)(a))
|
|
|
|
static void
|
|
test_keypin_add_entry(void *arg)
|
|
{
|
|
(void)arg;
|
|
keypin_clear();
|
|
|
|
tt_int_op(KEYPIN_ADDED, OP_EQ, ADD("ambassadors-at-large",
|
|
"bread-and-butter thing-in-itself"));
|
|
tt_int_op(KEYPIN_ADDED, OP_EQ, ADD("gentleman-adventurer",
|
|
"cloak-and-dagger what's-his-face"));
|
|
|
|
tt_int_op(KEYPIN_FOUND, OP_EQ, ADD("ambassadors-at-large",
|
|
"bread-and-butter thing-in-itself"));
|
|
tt_int_op(KEYPIN_FOUND, OP_EQ, ADD("ambassadors-at-large",
|
|
"bread-and-butter thing-in-itself"));
|
|
tt_int_op(KEYPIN_FOUND, OP_EQ, ADD("gentleman-adventurer",
|
|
"cloak-and-dagger what's-his-face"));
|
|
|
|
tt_int_op(KEYPIN_ADDED, OP_EQ, ADD("Johnnies-come-lately",
|
|
"run-of-the-mill root-mean-square"));
|
|
|
|
tt_int_op(KEYPIN_MISMATCH, OP_EQ, ADD("gentleman-adventurer",
|
|
"hypersentimental closefistedness"));
|
|
|
|
tt_int_op(KEYPIN_MISMATCH, OP_EQ, ADD("disestablismentarian",
|
|
"cloak-and-dagger what's-his-face"));
|
|
|
|
tt_int_op(KEYPIN_FOUND, OP_EQ, ADD("gentleman-adventurer",
|
|
"cloak-and-dagger what's-his-face"));
|
|
|
|
tt_int_op(KEYPIN_NOT_FOUND, OP_EQ, LONE_RSA("Llanfairpwllgwyngyll"));
|
|
tt_int_op(KEYPIN_MISMATCH, OP_EQ, LONE_RSA("Johnnies-come-lately"));
|
|
|
|
done:
|
|
keypin_clear();
|
|
}
|
|
|
|
static void
|
|
test_keypin_journal(void *arg)
|
|
{
|
|
(void)arg;
|
|
char *contents = NULL;
|
|
const char *fname = get_fname("keypin-journal");
|
|
|
|
tt_int_op(0, OP_EQ, keypin_load_journal(fname)); /* ENOENT is okay */
|
|
update_approx_time(1217709000);
|
|
tt_int_op(0, OP_EQ, keypin_open_journal(fname));
|
|
|
|
tt_int_op(KEYPIN_ADDED, OP_EQ, ADD("king-of-the-herrings",
|
|
"good-for-nothing attorney-at-law"));
|
|
tt_int_op(KEYPIN_ADDED, OP_EQ, ADD("yellowish-red-yellow",
|
|
"salt-and-pepper high-muck-a-muck"));
|
|
tt_int_op(KEYPIN_FOUND, OP_EQ, ADD("yellowish-red-yellow",
|
|
"salt-and-pepper high-muck-a-muck"));
|
|
keypin_close_journal();
|
|
keypin_clear();
|
|
|
|
tt_int_op(0, OP_EQ, keypin_load_journal(fname));
|
|
update_approx_time(1231041600);
|
|
tt_int_op(0, OP_EQ, keypin_open_journal(fname));
|
|
tt_int_op(KEYPIN_FOUND, OP_EQ, ADD("yellowish-red-yellow",
|
|
"salt-and-pepper high-muck-a-muck"));
|
|
tt_int_op(KEYPIN_ADDED, OP_EQ, ADD("theatre-in-the-round",
|
|
"holier-than-thou jack-in-the-box"));
|
|
tt_int_op(KEYPIN_ADDED, OP_EQ, ADD("no-deposit-no-return",
|
|
"across-the-board will-o-the-wisp"));
|
|
tt_int_op(KEYPIN_MISMATCH, OP_EQ, ADD("intellectualizations",
|
|
"salt-and-pepper high-muck-a-muck"));
|
|
keypin_close_journal();
|
|
keypin_clear();
|
|
|
|
tt_int_op(0, OP_EQ, keypin_load_journal(fname));
|
|
update_approx_time(1412278354);
|
|
tt_int_op(0, OP_EQ, keypin_open_journal(fname));
|
|
tt_int_op(KEYPIN_FOUND, OP_EQ, ADD("yellowish-red-yellow",
|
|
"salt-and-pepper high-muck-a-muck"));
|
|
tt_int_op(KEYPIN_MISMATCH, OP_EQ, ADD("intellectualizations",
|
|
"salt-and-pepper high-muck-a-muck"));
|
|
tt_int_op(KEYPIN_FOUND, OP_EQ, ADD("theatre-in-the-round",
|
|
"holier-than-thou jack-in-the-box"));
|
|
tt_int_op(KEYPIN_MISMATCH, OP_EQ, ADD("counterrevolutionary",
|
|
"holier-than-thou jack-in-the-box"));
|
|
tt_int_op(KEYPIN_MISMATCH, OP_EQ, ADD("no-deposit-no-return",
|
|
"floccinaucinihilipilificationism"));
|
|
keypin_close_journal();
|
|
|
|
contents = read_file_to_str(fname, RFTS_BIN, NULL);
|
|
tt_assert(contents);
|
|
tt_str_op(contents,OP_EQ,
|
|
"\n"
|
|
"@opened-at 2008-08-02 20:30:00\n"
|
|
"a2luZy1vZi10aGUtaGVycmluZ3M Z29vZC1mb3Itbm90aGluZyBhdHRvcm5leS1hdC1sYXc\n"
|
|
"eWVsbG93aXNoLXJlZC15ZWxsb3c c2FsdC1hbmQtcGVwcGVyIGhpZ2gtbXVjay1hLW11Y2s\n"
|
|
"\n"
|
|
"@opened-at 2009-01-04 04:00:00\n"
|
|
"dGhlYXRyZS1pbi10aGUtcm91bmQ aG9saWVyLXRoYW4tdGhvdSBqYWNrLWluLXRoZS1ib3g\n"
|
|
"bm8tZGVwb3NpdC1uby1yZXR1cm4 YWNyb3NzLXRoZS1ib2FyZCB3aWxsLW8tdGhlLXdpc3A\n"
|
|
"\n"
|
|
"@opened-at 2014-10-02 19:32:34\n");
|
|
|
|
done:
|
|
tor_free(contents);
|
|
keypin_clear();
|
|
}
|
|
|
|
#undef ADD
|
|
#undef LONE_RSA
|
|
|
|
#define TEST(name, flags) \
|
|
{ #name , test_keypin_ ## name, (flags), NULL, NULL }
|
|
|
|
struct testcase_t keypin_tests[] = {
|
|
TEST( parse_line, 0 ),
|
|
TEST( parse_file, TT_FORK ),
|
|
TEST( add_entry, TT_FORK ),
|
|
TEST( journal, TT_FORK ),
|
|
END_OF_TESTCASES
|
|
};
|
|
|