test_keypin.c 9.5 KB

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