test_microdesc.c 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985
  1. /* Copyright (c) 2010-2019, The Tor Project, Inc. */
  2. /* See LICENSE for licensing information */
  3. #include "orconfig.h"
  4. #include "core/or/or.h"
  5. #define DIRVOTE_PRIVATE
  6. #include "app/config/config.h"
  7. #include "feature/dirauth/dirvote.h"
  8. #include "feature/dirparse/microdesc_parse.h"
  9. #include "feature/dirparse/routerparse.h"
  10. #include "feature/nodelist/microdesc.h"
  11. #include "feature/nodelist/networkstatus.h"
  12. #include "feature/nodelist/nodefamily.h"
  13. #include "feature/nodelist/routerlist.h"
  14. #include "feature/nodelist/torcert.h"
  15. #include "feature/nodelist/microdesc_st.h"
  16. #include "feature/nodelist/networkstatus_st.h"
  17. #include "feature/nodelist/routerinfo_st.h"
  18. #include "feature/nodelist/routerstatus_st.h"
  19. #include "test/test.h"
  20. #include "test/log_test_helpers.h"
  21. #ifdef HAVE_SYS_STAT_H
  22. #include <sys/stat.h>
  23. #endif
  24. #ifdef _WIN32
  25. /* For mkdir() */
  26. #include <direct.h>
  27. #else
  28. #include <dirent.h>
  29. #endif /* defined(_WIN32) */
  30. static const char test_md1[] =
  31. "onion-key\n"
  32. "-----BEGIN RSA PUBLIC KEY-----\n"
  33. "MIGJAoGBAMjlHH/daN43cSVRaHBwgUfnszzAhg98EvivJ9Qxfv51mvQUxPjQ07es\n"
  34. "gV/3n8fyh3Kqr/ehi9jxkdgSRfSnmF7giaHL1SLZ29kA7KtST+pBvmTpDtHa3ykX\n"
  35. "Xorc7hJvIyTZoc1HU+5XSynj3gsBE5IGK1ZRzrNS688LnuZMVp1tAgMBAAE=\n"
  36. "-----END RSA PUBLIC KEY-----\n";
  37. static const char test_md2[] =
  38. "onion-key\n"
  39. "-----BEGIN RSA PUBLIC KEY-----\n"
  40. "MIGJAoGBAMIixIowh2DyPmDNMDwBX2DHcYcqdcH1zdIQJZkyV6c6rQHnvbcaDoSg\n"
  41. "jgFSLJKpnGmh71FVRqep+yVB0zI1JY43kuEnXry2HbZCD9UDo3d3n7t015X5S7ON\n"
  42. "bSSYtQGPwOr6Epf96IF6DoQxy4iDnPUAlejuhAG51s1y6/rZQ3zxAgMBAAE=\n"
  43. "-----END RSA PUBLIC KEY-----\n";
  44. static const char test_md3[] =
  45. "@last-listed 2009-06-22\n"
  46. "onion-key\n"
  47. "-----BEGIN RSA PUBLIC KEY-----\n"
  48. "MIGJAoGBAMH3340d4ENNGrqx7UxT+lB7x6DNUKOdPEOn4teceE11xlMyZ9TPv41c\n"
  49. "qj2fRZzfxlc88G/tmiaHshmdtEpklZ740OFqaaJVj4LjPMKFNE+J7Xc1142BE9Ci\n"
  50. "KgsbjGYe2RY261aADRWLetJ8T9QDMm+JngL4288hc8pq1uB/3TAbAgMBAAE=\n"
  51. "-----END RSA PUBLIC KEY-----\n"
  52. "p accept 1-700,800-1000\n"
  53. "family nodeX nodeY nodeZ\n";
  54. static void
  55. test_md_cache(void *data)
  56. {
  57. or_options_t *options = NULL;
  58. microdesc_cache_t *mc = NULL ;
  59. smartlist_t *added = NULL, *wanted = NULL;
  60. microdesc_t *md1, *md2, *md3;
  61. char d1[DIGEST256_LEN], d2[DIGEST256_LEN], d3[DIGEST256_LEN];
  62. const char *test_md3_noannotation = strchr(test_md3, '\n')+1;
  63. time_t time1, time2, time3;
  64. char *fn = NULL, *s = NULL;
  65. char *encoded_family = NULL;
  66. (void)data;
  67. options = get_options_mutable();
  68. tt_assert(options);
  69. time1 = time(NULL);
  70. time2 = time(NULL) - 2*24*60*60;
  71. time3 = time(NULL) - 15*24*60*60;
  72. /* Possibly, turn this into a test setup/cleanup pair */
  73. tor_free(options->CacheDirectory);
  74. options->CacheDirectory = tor_strdup(get_fname("md_datadir_test"));
  75. #ifdef _WIN32
  76. tt_int_op(0, OP_EQ, mkdir(options->CacheDirectory));
  77. #else
  78. tt_int_op(0, OP_EQ, mkdir(options->CacheDirectory, 0700));
  79. #endif
  80. tt_assert(!strcmpstart(test_md3_noannotation, "onion-key"));
  81. crypto_digest256(d1, test_md1, strlen(test_md1), DIGEST_SHA256);
  82. crypto_digest256(d2, test_md2, strlen(test_md1), DIGEST_SHA256);
  83. crypto_digest256(d3, test_md3_noannotation, strlen(test_md3_noannotation),
  84. DIGEST_SHA256);
  85. mc = get_microdesc_cache();
  86. added = microdescs_add_to_cache(mc, test_md1, NULL, SAVED_NOWHERE, 0,
  87. time1, NULL);
  88. tt_int_op(1, OP_EQ, smartlist_len(added));
  89. md1 = smartlist_get(added, 0);
  90. smartlist_free(added);
  91. added = NULL;
  92. wanted = smartlist_new();
  93. added = microdescs_add_to_cache(mc, test_md2, NULL, SAVED_NOWHERE, 0,
  94. time2, wanted);
  95. /* Should fail, since we didn't list test_md2's digest in wanted */
  96. tt_int_op(0, OP_EQ, smartlist_len(added));
  97. smartlist_free(added);
  98. added = NULL;
  99. smartlist_add(wanted, tor_memdup(d2, DIGEST256_LEN));
  100. smartlist_add(wanted, tor_memdup(d3, DIGEST256_LEN));
  101. added = microdescs_add_to_cache(mc, test_md2, NULL, SAVED_NOWHERE, 0,
  102. time2, wanted);
  103. /* Now it can work. md2 should have been added */
  104. tt_int_op(1, OP_EQ, smartlist_len(added));
  105. md2 = smartlist_get(added, 0);
  106. /* And it should have gotten removed from 'wanted' */
  107. tt_int_op(smartlist_len(wanted), OP_EQ, 1);
  108. tt_mem_op(smartlist_get(wanted, 0), OP_EQ, d3, DIGEST256_LEN);
  109. smartlist_free(added);
  110. added = NULL;
  111. added = microdescs_add_to_cache(mc, test_md3, NULL,
  112. SAVED_NOWHERE, 0, -1, NULL);
  113. /* Must fail, since SAVED_NOWHERE precludes annotations */
  114. tt_int_op(0, OP_EQ, smartlist_len(added));
  115. smartlist_free(added);
  116. added = NULL;
  117. added = microdescs_add_to_cache(mc, test_md3_noannotation, NULL,
  118. SAVED_NOWHERE, 0, time3, NULL);
  119. /* Now it can work */
  120. tt_int_op(1, OP_EQ, smartlist_len(added));
  121. md3 = smartlist_get(added, 0);
  122. smartlist_free(added);
  123. added = NULL;
  124. /* Okay. We added 1...3. Let's poke them to see how they look, and make
  125. * sure they're really in the journal. */
  126. tt_ptr_op(md1, OP_EQ, microdesc_cache_lookup_by_digest256(mc, d1));
  127. tt_ptr_op(md2, OP_EQ, microdesc_cache_lookup_by_digest256(mc, d2));
  128. tt_ptr_op(md3, OP_EQ, microdesc_cache_lookup_by_digest256(mc, d3));
  129. tt_int_op(md1->last_listed, OP_EQ, time1);
  130. tt_int_op(md2->last_listed, OP_EQ, time2);
  131. tt_int_op(md3->last_listed, OP_EQ, time3);
  132. tt_int_op(md1->saved_location, OP_EQ, SAVED_IN_JOURNAL);
  133. tt_int_op(md2->saved_location, OP_EQ, SAVED_IN_JOURNAL);
  134. tt_int_op(md3->saved_location, OP_EQ, SAVED_IN_JOURNAL);
  135. tt_int_op(md1->bodylen, OP_EQ, strlen(test_md1));
  136. tt_int_op(md2->bodylen, OP_EQ, strlen(test_md2));
  137. tt_int_op(md3->bodylen, OP_EQ, strlen(test_md3_noannotation));
  138. tt_mem_op(md1->body, OP_EQ, test_md1, strlen(test_md1));
  139. tt_mem_op(md2->body, OP_EQ, test_md2, strlen(test_md2));
  140. tt_mem_op(md3->body, OP_EQ, test_md3_noannotation,
  141. strlen(test_md3_noannotation));
  142. tor_asprintf(&fn, "%s"PATH_SEPARATOR"cached-microdescs.new",
  143. options->CacheDirectory);
  144. s = read_file_to_str(fn, RFTS_BIN, NULL);
  145. tt_assert(s);
  146. tt_mem_op(md1->body, OP_EQ, s + md1->off, md1->bodylen);
  147. tt_mem_op(md2->body, OP_EQ, s + md2->off, md2->bodylen);
  148. tt_mem_op(md3->body, OP_EQ, s + md3->off, md3->bodylen);
  149. tt_ptr_op(md1->family, OP_EQ, NULL);
  150. tt_ptr_op(md3->family, OP_NE, NULL);
  151. encoded_family = nodefamily_format(md3->family);
  152. tt_str_op(encoded_family, OP_EQ, "nodex nodey nodez");
  153. /* Now rebuild the cache! */
  154. tt_int_op(microdesc_cache_rebuild(mc, 1), OP_EQ, 0);
  155. tt_int_op(md1->saved_location, OP_EQ, SAVED_IN_CACHE);
  156. tt_int_op(md2->saved_location, OP_EQ, SAVED_IN_CACHE);
  157. tt_int_op(md3->saved_location, OP_EQ, SAVED_IN_CACHE);
  158. /* The journal should be empty now */
  159. tor_free(s);
  160. s = read_file_to_str(fn, RFTS_BIN, NULL);
  161. tt_str_op(s, OP_EQ, "");
  162. tor_free(s);
  163. tor_free(fn);
  164. /* read the cache. */
  165. tor_asprintf(&fn, "%s"PATH_SEPARATOR"cached-microdescs",
  166. options->CacheDirectory);
  167. s = read_file_to_str(fn, RFTS_BIN, NULL);
  168. tt_mem_op(md1->body, OP_EQ, s + md1->off, strlen(test_md1));
  169. tt_mem_op(md2->body, OP_EQ, s + md2->off, strlen(test_md2));
  170. tt_mem_op(md3->body, OP_EQ, s + md3->off, strlen(test_md3_noannotation));
  171. /* Okay, now we are going to forget about the cache entirely, and reload it
  172. * from the disk. */
  173. microdesc_free_all();
  174. mc = get_microdesc_cache();
  175. md1 = microdesc_cache_lookup_by_digest256(mc, d1);
  176. md2 = microdesc_cache_lookup_by_digest256(mc, d2);
  177. md3 = microdesc_cache_lookup_by_digest256(mc, d3);
  178. tt_assert(md1);
  179. tt_assert(md2);
  180. tt_assert(md3);
  181. tt_mem_op(md1->body, OP_EQ, s + md1->off, strlen(test_md1));
  182. tt_mem_op(md2->body, OP_EQ, s + md2->off, strlen(test_md2));
  183. tt_mem_op(md3->body, OP_EQ, s + md3->off, strlen(test_md3_noannotation));
  184. tt_int_op(md1->last_listed, OP_EQ, time1);
  185. tt_int_op(md2->last_listed, OP_EQ, time2);
  186. tt_int_op(md3->last_listed, OP_EQ, time3);
  187. /* Okay, now we are going to clear out everything older than a week old.
  188. * In practice, that means md3 */
  189. microdesc_cache_clean(mc, time(NULL)-7*24*60*60, 1/*force*/);
  190. tt_ptr_op(md1, OP_EQ, microdesc_cache_lookup_by_digest256(mc, d1));
  191. tt_ptr_op(md2, OP_EQ, microdesc_cache_lookup_by_digest256(mc, d2));
  192. tt_ptr_op(NULL, OP_EQ, microdesc_cache_lookup_by_digest256(mc, d3));
  193. md3 = NULL; /* it's history now! */
  194. /* rebuild again, make sure it stays gone. */
  195. tt_int_op(microdesc_cache_rebuild(mc, 1), OP_EQ, 0);
  196. tt_ptr_op(md1, OP_EQ, microdesc_cache_lookup_by_digest256(mc, d1));
  197. tt_ptr_op(md2, OP_EQ, microdesc_cache_lookup_by_digest256(mc, d2));
  198. tt_ptr_op(NULL, OP_EQ, microdesc_cache_lookup_by_digest256(mc, d3));
  199. /* Re-add md3, and make sure we can rebuild the cache. */
  200. added = microdescs_add_to_cache(mc, test_md3_noannotation, NULL,
  201. SAVED_NOWHERE, 0, time3, NULL);
  202. tt_int_op(1, OP_EQ, smartlist_len(added));
  203. md3 = smartlist_get(added, 0);
  204. smartlist_free(added);
  205. added = NULL;
  206. tt_int_op(md1->saved_location, OP_EQ, SAVED_IN_CACHE);
  207. tt_int_op(md2->saved_location, OP_EQ, SAVED_IN_CACHE);
  208. tt_int_op(md3->saved_location, OP_EQ, SAVED_IN_JOURNAL);
  209. tt_int_op(microdesc_cache_rebuild(mc, 1), OP_EQ, 0);
  210. tt_int_op(md3->saved_location, OP_EQ, SAVED_IN_CACHE);
  211. done:
  212. if (options)
  213. tor_free(options->CacheDirectory);
  214. microdesc_free_all();
  215. smartlist_free(added);
  216. if (wanted)
  217. SMARTLIST_FOREACH(wanted, char *, cp, tor_free(cp));
  218. smartlist_free(wanted);
  219. tor_free(s);
  220. tor_free(fn);
  221. tor_free(encoded_family);
  222. }
  223. static const char truncated_md[] =
  224. "@last-listed 2013-08-08 19:02:59\n"
  225. "onion-key\n"
  226. "-----BEGIN RSA PUBLIC KEY-----\n"
  227. "MIGJAoGBAM91vLFNaM+gGhnRIdz2Cm/Kl7Xz0cOobIdVzhS3cKUJfk867hCuTipS\n"
  228. "NveLBzNopvgXKruAAzEj3cACxk6Q8lv5UWOGCD1UolkgsWSE62RBjap44g+oc9J1\n"
  229. "RI9968xOTZw0VaBQg9giEILNXl0djoikQ+5tQRUvLDDa67gpa5Q1AgMBAAE=\n"
  230. "-----END RSA PUBLIC KEY-----\n"
  231. "family @\n";
  232. static void
  233. test_md_cache_broken(void *data)
  234. {
  235. or_options_t *options;
  236. char *fn=NULL;
  237. microdesc_cache_t *mc = NULL;
  238. (void)data;
  239. options = get_options_mutable();
  240. tt_assert(options);
  241. tor_free(options->CacheDirectory);
  242. options->CacheDirectory = tor_strdup(get_fname("md_datadir_test2"));
  243. #ifdef _WIN32
  244. tt_int_op(0, OP_EQ, mkdir(options->CacheDirectory));
  245. #else
  246. tt_int_op(0, OP_EQ, mkdir(options->CacheDirectory, 0700));
  247. #endif
  248. tor_asprintf(&fn, "%s"PATH_SEPARATOR"cached-microdescs",
  249. options->CacheDirectory);
  250. write_str_to_file(fn, truncated_md, 1);
  251. mc = get_microdesc_cache();
  252. tt_assert(mc);
  253. done:
  254. if (options)
  255. tor_free(options->CacheDirectory);
  256. tor_free(fn);
  257. microdesc_free_all();
  258. }
  259. /* Generated by chutney. */
  260. static const char test_ri[] =
  261. "router test005r 127.0.0.1 5005 0 7005\n"
  262. "platform Tor 0.2.5.4-alpha-dev on Linux\n"
  263. "protocols Link 1 2 Circuit 1\n"
  264. "published 2014-05-06 22:57:55\n"
  265. "fingerprint 09DE 3BA2 48C2 1C3F 3760 6CD3 8460 43A6 D5EC F59E\n"
  266. "uptime 0\n"
  267. "bandwidth 1073741824 1073741824 0\n"
  268. "extra-info-digest 361F9428F9FA4DD854C03DDBCC159D0D9FA996C9\n"
  269. "onion-key\n"
  270. "-----BEGIN RSA PUBLIC KEY-----\n"
  271. "MIGJAoGBANBJz8Vldl12aFeSMPLiA4nOetLDN0oxU8bB1SDhO7Uu2zdWYVYAF5J0\n"
  272. "st7WvrVy/jA9v/fsezNAPskBanecHRSkdMTpkcgRPMHE7CTGEwIy1Yp1X4bPgDlC\n"
  273. "VCnbs5Pcts5HnWEYNK7qHDAUn+IlmjOO+pTUY8uyq+GQVz6H9wFlAgMBAAE=\n"
  274. "-----END RSA PUBLIC KEY-----\n"
  275. "signing-key\n"
  276. "-----BEGIN RSA PUBLIC KEY-----\n"
  277. "MIGJAoGBANbGUC4802Ke6C3nOVxN0U0HhIRrs32cQFEL4v+UUMJPgjbistHBvOax\n"
  278. "CWVR/sMXM2kKJeGThJ9ZUs2p9dDG4WHPUXgkMqzTTEeeFa7pQKU0brgbmLaJq0Pi\n"
  279. "mxmqC5RkTHa5bQvq6QlSFprAEoovV27cWqBM9jVdV9hyc//6kwPzAgMBAAE=\n"
  280. "-----END RSA PUBLIC KEY-----\n"
  281. "hidden-service-dir\n"
  282. "ntor-onion-key Gg73xH7+kTfT6bi1uNVx9gwQdQas9pROIfmc4NpAdC4=\n"
  283. "reject *:25\n"
  284. "reject *:119\n"
  285. "reject *:135-139\n"
  286. "reject *:445\n"
  287. "reject *:563\n"
  288. "reject *:1214\n"
  289. "reject *:4661-4666\n"
  290. "reject *:6346-6429\n"
  291. "reject *:6699\n"
  292. "reject *:6881-6999\n"
  293. "accept *:*\n"
  294. "router-signature\n"
  295. "-----BEGIN SIGNATURE-----\n"
  296. "ImzX5PF2vRCrG1YzGToyjoxYhgh1vtHEDjmP+tIS/iil1DSnHZNpHSuHp0L1jE9S\n"
  297. "yZyrtKaqpBE/aecAM3j4CWCn/ipnAAQkHcyRLin1bYvqBtRzyopVCRlUhF+uWrLq\n"
  298. "t0xkIE39ss/EwmQr7iIgkdVH4oRIMsjYnFFJBG26nYY=\n"
  299. "-----END SIGNATURE-----\n";
  300. static const char test_ri2[] =
  301. "router test001a 127.0.0.1 5001 0 7001\n"
  302. "identity-ed25519\n"
  303. "-----BEGIN ED25519 CERT-----\n"
  304. "AQQABf/FAf5iDuKCZP2VxnAaQWdklilAh6kaEeFX4z8261Yx2T1/AQAgBADCp8vO\n"
  305. "B8K1F9g2DzwuwvVCnPFLSK1qknVqPpNucHLH9DY7fuIYogBAdz4zHv1qC7RKaMNG\n"
  306. "Jux/tMO2tzPcm62Ky5PjClMQplKUOnZNQ+RIpA3wYCIfUDy/cQnY7XWgNQ0=\n"
  307. "-----END ED25519 CERT-----\n"
  308. "platform Tor 0.2.6.0-alpha-dev on Darwin\n"
  309. "protocols Link 1 2 Circuit 1\n"
  310. "published 2014-10-08 12:58:04\n"
  311. "fingerprint B7E2 7F10 4213 C36F 13E7 E982 9182 845E 4959 97A0\n"
  312. "uptime 0\n"
  313. "bandwidth 1073741824 1073741824 0\n"
  314. "extra-info-digest 568F27331B6D8C73E7024F1EF5D097B90DFC7CDB\n"
  315. "caches-extra-info\n"
  316. "onion-key\n"
  317. "-----BEGIN RSA PUBLIC KEY-----\n"
  318. "MIGJAoGBAL2R8EfubUcahxha4u02P4VAR0llQIMwFAmrHPjzcK7apcQgDOf2ovOA\n"
  319. "+YQnJFxlpBmCoCZC6ssCi+9G0mqo650lFuTMP5I90BdtjotfzESfTykHLiChyvhd\n"
  320. "l0dlqclb2SU/GKem/fLRXH16aNi72CdSUu/1slKs/70ILi34QixRAgMBAAE=\n"
  321. "-----END RSA PUBLIC KEY-----\n"
  322. "signing-key\n"
  323. "-----BEGIN RSA PUBLIC KEY-----\n"
  324. "MIGJAoGBAN8+78KUVlgHXdMMkYJxcwh1Zv2y+Gb5eWUyltUaQRajhrT9ij2T5JZs\n"
  325. "M0g85xTcuM3jNVVpV79+33hiTohdC6UZ+Bk4USQ7WBFzRbVFSXoVKLBJFkCOIexg\n"
  326. "SMGNd5WEDtHWrXl58mizmPFu1eG6ZxHzt7RuLSol5cwBvawXPNkFAgMBAAE=\n"
  327. "-----END RSA PUBLIC KEY-----\n"
  328. "onion-key-crosscert\n"
  329. "-----BEGIN CROSSCERT-----\n"
  330. "ETFDzU49bvNfoZnKK1j6JeBP2gDirgj6bBCgWpUYs663OO9ypbZRO0JwWANssKl6\n"
  331. "oaq9vKTsKGRsaNnqnz/JGMhehymakjjNtqg7crWwsahe8+7Pw9GKmW+YjFtcOkUf\n"
  332. "KfOn2bmKBa1FoJb4yW3oXzHcdlLSRuCciKqPn+Hky5o=\n"
  333. "-----END CROSSCERT-----\n"
  334. "ntor-onion-key-crosscert 0\n"
  335. "-----BEGIN ED25519 CERT-----\n"
  336. "AQoABf2dAcKny84HwrUX2DYPPC7C9UKc8UtIrWqSdWo+k25wcsf0AFohutG+xI06\n"
  337. "Ef21c5Zl1j8Hw6DzHDjYyJevXLFuOneaL3zcH2Ldn4sjrG3kc5UuVvRfTvV120UO\n"
  338. "xk4f5s5LGwY=\n"
  339. "-----END ED25519 CERT-----\n"
  340. "hidden-service-dir\n"
  341. "contact auth1@test.test\n"
  342. "ntor-onion-key hbxdRnfVUJJY7+KcT4E3Rs7/zuClbN3hJrjSBiEGMgI=\n"
  343. "reject *:*\n"
  344. "router-sig-ed25519 5aQXyTif7PExIuL2di37UvktmJECKnils2OWz2vDi"
  345. "hFxi+5TTAAPxYkS5clhc/Pjvw34itfjGmTKFic/8httAQ\n"
  346. "router-signature\n"
  347. "-----BEGIN SIGNATURE-----\n"
  348. "BaUB+aFPQbb3BwtdzKsKqV3+6cRlSqJF5bI3UTmwRoJk+Z5Pz+W5NWokNI0xArHM\n"
  349. "T4T5FZCCP9350jXsUCIvzyIyktU6aVRCGFt76rFlo1OETpN8GWkMnQU0w18cxvgS\n"
  350. "cf34GXHv61XReJF3AlzNHFpbrPOYmowmhrTULKyMqow=\n"
  351. "-----END SIGNATURE-----\n";
  352. static const char test_md_18[] =
  353. "onion-key\n"
  354. "-----BEGIN RSA PUBLIC KEY-----\n"
  355. "MIGJAoGBANBJz8Vldl12aFeSMPLiA4nOetLDN0oxU8bB1SDhO7Uu2zdWYVYAF5J0\n"
  356. "st7WvrVy/jA9v/fsezNAPskBanecHRSkdMTpkcgRPMHE7CTGEwIy1Yp1X4bPgDlC\n"
  357. "VCnbs5Pcts5HnWEYNK7qHDAUn+IlmjOO+pTUY8uyq+GQVz6H9wFlAgMBAAE=\n"
  358. "-----END RSA PUBLIC KEY-----\n"
  359. "ntor-onion-key Gg73xH7+kTfT6bi1uNVx9gwQdQas9pROIfmc4NpAdC4=\n"
  360. "p reject 25,119,135-139,445,563,1214,4661-4666,6346-6429,6699,6881-6999\n"
  361. "id rsa1024 Cd47okjCHD83YGzThGBDptXs9Z4\n";
  362. static const char test_md2_21[] =
  363. "onion-key\n"
  364. "-----BEGIN RSA PUBLIC KEY-----\n"
  365. "MIGJAoGBAL2R8EfubUcahxha4u02P4VAR0llQIMwFAmrHPjzcK7apcQgDOf2ovOA\n"
  366. "+YQnJFxlpBmCoCZC6ssCi+9G0mqo650lFuTMP5I90BdtjotfzESfTykHLiChyvhd\n"
  367. "l0dlqclb2SU/GKem/fLRXH16aNi72CdSUu/1slKs/70ILi34QixRAgMBAAE=\n"
  368. "-----END RSA PUBLIC KEY-----\n"
  369. "ntor-onion-key hbxdRnfVUJJY7+KcT4E3Rs7/zuClbN3hJrjSBiEGMgI=\n"
  370. "id ed25519 wqfLzgfCtRfYNg88LsL1QpzxS0itapJ1aj6TbnByx/Q\n";
  371. static const char test_md2_withfamily_28[] =
  372. "onion-key\n"
  373. "-----BEGIN RSA PUBLIC KEY-----\n"
  374. "MIGJAoGBAL2R8EfubUcahxha4u02P4VAR0llQIMwFAmrHPjzcK7apcQgDOf2ovOA\n"
  375. "+YQnJFxlpBmCoCZC6ssCi+9G0mqo650lFuTMP5I90BdtjotfzESfTykHLiChyvhd\n"
  376. "l0dlqclb2SU/GKem/fLRXH16aNi72CdSUu/1slKs/70ILi34QixRAgMBAAE=\n"
  377. "-----END RSA PUBLIC KEY-----\n"
  378. "ntor-onion-key hbxdRnfVUJJY7+KcT4E3Rs7/zuClbN3hJrjSBiEGMgI=\n"
  379. "family OtherNode !Strange\n"
  380. "id ed25519 wqfLzgfCtRfYNg88LsL1QpzxS0itapJ1aj6TbnByx/Q\n";
  381. static const char test_md2_withfamily_29[] =
  382. "onion-key\n"
  383. "-----BEGIN RSA PUBLIC KEY-----\n"
  384. "MIGJAoGBAL2R8EfubUcahxha4u02P4VAR0llQIMwFAmrHPjzcK7apcQgDOf2ovOA\n"
  385. "+YQnJFxlpBmCoCZC6ssCi+9G0mqo650lFuTMP5I90BdtjotfzESfTykHLiChyvhd\n"
  386. "l0dlqclb2SU/GKem/fLRXH16aNi72CdSUu/1slKs/70ILi34QixRAgMBAAE=\n"
  387. "-----END RSA PUBLIC KEY-----\n"
  388. "ntor-onion-key hbxdRnfVUJJY7+KcT4E3Rs7/zuClbN3hJrjSBiEGMgI=\n"
  389. "family !Strange $B7E27F104213C36F13E7E9829182845E495997A0 othernode\n"
  390. "id ed25519 wqfLzgfCtRfYNg88LsL1QpzxS0itapJ1aj6TbnByx/Q\n";
  391. static void
  392. test_md_generate(void *arg)
  393. {
  394. routerinfo_t *ri;
  395. microdesc_t *md = NULL;
  396. (void)arg;
  397. ri = router_parse_entry_from_string(test_ri, NULL, 0, 0, NULL, NULL);
  398. tt_assert(ri);
  399. microdesc_free(md);
  400. md = NULL;
  401. md = dirvote_create_microdescriptor(ri, 18);
  402. tt_str_op(md->body, OP_EQ, test_md_18);
  403. microdesc_free(md);
  404. md = NULL;
  405. md = dirvote_create_microdescriptor(ri, 21);
  406. tt_str_op(md->body, OP_EQ, test_md_18);
  407. routerinfo_free(ri);
  408. ri = router_parse_entry_from_string(test_ri2, NULL, 0, 0, NULL, NULL);
  409. microdesc_free(md);
  410. md = NULL;
  411. md = dirvote_create_microdescriptor(ri, 21);
  412. tt_str_op(md->body, OP_EQ, test_md2_21);
  413. tt_assert(ed25519_pubkey_eq(md->ed25519_identity_pkey,
  414. &ri->cache_info.signing_key_cert->signing_key));
  415. // Try family encoding.
  416. microdesc_free(md);
  417. ri->declared_family = smartlist_new();
  418. smartlist_add_strdup(ri->declared_family, "OtherNode !Strange");
  419. md = dirvote_create_microdescriptor(ri, 28);
  420. tt_str_op(md->body, OP_EQ, test_md2_withfamily_28);
  421. microdesc_free(md);
  422. md = dirvote_create_microdescriptor(ri, 29);
  423. tt_str_op(md->body, OP_EQ, test_md2_withfamily_29);
  424. done:
  425. microdesc_free(md);
  426. routerinfo_free(ri);
  427. }
  428. #ifdef HAVE_CFLAG_WOVERLENGTH_STRINGS
  429. DISABLE_GCC_WARNING(overlength-strings)
  430. /* We allow huge string constants in the unit tests, but not in the code
  431. * at large. */
  432. #endif
  433. /* Taken at random from my ~/.tor/cached-microdescs file and then
  434. * hand-munged */
  435. static const char MD_PARSE_TEST_DATA[] =
  436. /* Good 0 */
  437. "onion-key\n"
  438. "-----BEGIN RSA PUBLIC KEY-----\n"
  439. "MIGJAoGBANsKd1GRfOuSR1MkcwKqs6SVy4Gi/JXplt/bHDkIGm6Q96TeJ5uyVgUL\n"
  440. "DBr/ij6+JqgVFeriuiMzHKREytzjdaTuKsKBFFpLwb+Ppcjr5nMIH/AR6/aHO8hW\n"
  441. "T3B9lx5T6Kl7CqZ4yqXxYRHzn50EPTIZuz0y9se4J4gi9mLmL+pHAgMBAAE=\n"
  442. "-----END RSA PUBLIC KEY-----\n"
  443. "p accept 20-23,43,53,79-81,88,110,143,194,220,443,464,531,543-544\n"
  444. "id rsa1024 GEo59/iR1GWSIWZDzXTd5QxtqnU\n"
  445. /* Bad 0: I've messed with the onion-key in the second one. */
  446. "onion-key\n"
  447. "-----BEGIN RSA PUBLIC KEY-----\n"
  448. "MIGJAoGBAMr4o/pflVwscx11vC1AKEADlKEqnhpvCIjAEzNEenMhvGQHRlA0EXLC\n"
  449. "7G7O5bhnCwEHqK8Pvg8cuX/fD8v08TF1EVPhwPa0UI6ab8KnPP2F!!!!!!b92DG7EQIk3q\n"
  450. "d68Uxp7E9/t3v1WWZjzDqvEe0par6ul+DKW6HMlTGebFo5Q4e8R1AgMBAAE=\n"
  451. "-----END RSA PUBLIC KEY-----\n"
  452. "ntor-onion-key 761Dmm27via7lXygNHM3l+oJLrYU2Nye0Uz4pkpipyY=\n"
  453. "p accept 53\n"
  454. "id rsa1024 3Y4fwXhtgkdGDZ5ef5mtb6TJRQQ\n"
  455. /* Good 1 */
  456. "onion-key\n"
  457. "-----BEGIN RSA PUBLIC KEY-----\n"
  458. "MIGJAoGBANsMSjVi3EX8ZHfm/dvPF6KdVR66k1tVul7Jp+dDbDajBYNhgKRzVCxy\n"
  459. "Yac1CBuQjOqK89tKap9PQBnhF087eDrfaZDqYTLwB2W2sBJncVej15WEPXPRBifo\n"
  460. "iFZ8337kgczkaY+IOfSuhtbOUyDOoDpRJheIKBNq0ZiTqtLbbadVAgMBAAE=\n"
  461. "-----END RSA PUBLIC KEY-----\n"
  462. "ntor-onion-key ncfiHJjSgdDEW/gc6q6/7idac7j+x7ejQrRm6i75pGA=\n"
  463. "p accept 443,6660-6669,6697,7000-7001\n"
  464. "id rsa1024 XXuLzw3mfBELEq3veXoNhdehwD4\n"
  465. /* Good 2 */
  466. "onion-key\n"
  467. "-----BEGIN RSA PUBLIC KEY-----\n"
  468. "MIGJAoGBANQfBlrHrh9F/CAOytrNFgi0ikWMW/HZxuoszF9X+AQ+MudR8bcxxOGl\n"
  469. "1RFwb74s8E3uuzrCkNFvSw9Ar1L02F2DOX0gLsxEGuYC4Ave9NUteGqSqDyEJQUJ\n"
  470. "KlfxCPn2qC9nvNT7wR/Dg2WRvAEKnJmkpb57N3+WSAOPLjKOFEz3AgMBAAE=\n"
  471. "-----END RSA PUBLIC KEY-----\n"
  472. "ntor-onion-key AppBt6CSeb1kKid/36ototmFA24ddfW5JpjWPLuoJgs=\n"
  473. "id rsa1024 6y60AEI9a1PUUlRPO0YQT9WzrjI\n"
  474. /* Bad 1: Here I've messed with the ntor key */
  475. "onion-key\n"
  476. "-----BEGIN RSA PUBLIC KEY-----\n"
  477. "MIGJAoGBAPjy2HacU3jDNO5nTOFGSwNa0qKCNn4yhtrDVcAJ5alIQeBWZZGJLZ0q\n"
  478. "Cqylw1vYqxu8E09g+QXXFbAgBv1U9TICaATxrIJhIJzc8TJPhqJemp1kq0DvHLDx\n"
  479. "mxwlkNnCD/P5NS+JYB3EjOlU9EnSKUWNU61+Co344m2JqhEau40vAgMBAAE=\n"
  480. "-----END RSA PUBLIC KEY-----\n"
  481. "ntor-onion-key 4i2Fp9JHTUr1uQs0pxD5j5spl4/RG56S2P0gQxU=\n"
  482. "id rsa1024 nMRmNEGysA0NmlALVaUmI7D5jLU\n"
  483. /* Good 3: I've added a weird token in this one. This shouldn't prevent
  484. * it parsing */
  485. "onion-key\n"
  486. "-----BEGIN RSA PUBLIC KEY-----\n"
  487. "MIGJAoGBAKmosxudyNA/yJNz3S890VqV/ebylzoD11Sc0b/d5tyNNaNZjcYy5vRD\n"
  488. "kwyxFRMbP2TLZQ1zRfNwY7IDnYjU2SbW0pxuM6M8WRtsmx/YOE3kHMVAFJNrTUqU\n"
  489. "6D1zB3IiRDS5q5+NoRxwqo+hYUck60O3WTwEoqb+l3lvXeu7z9rFAgMBAAE=\n"
  490. "-----END RSA PUBLIC KEY-----\n"
  491. "flux-capacitor 1.21 GW\n"
  492. "ntor-onion-key MWBoEkl+RlBiGX44XKIvTSqbznTNZStOmUYtcYRQQyY=\n"
  493. "id rsa1024 R+A5O9qRvRac4FT3C4L2QnFyxsc\n"
  494. /* Good 4: Here I've made the 'id rsa' token odd. It should still parse
  495. * just fine. */
  496. "onion-key\n"
  497. "-----BEGIN RSA PUBLIC KEY-----\n"
  498. "MIGJAoGBAOh+WMkdNe/Pkjb8UjQyfLOlFgpuVFrxAIGnJsmWWx0yBE97DQxGyh2n\n"
  499. "h8G5OJZHRarJQyCIf7vpZQAi0oP0OkGGaCaDQsM+D8TnqhnU++RWGnMqY/cXxPrL\n"
  500. "MEq+n6aGiLmzkO7ah8yorZpoREk4GqLUIN89/tHHGOhJL3c4CPGjAgMBAAE=\n"
  501. "-----END RSA PUBLIC KEY-----\n"
  502. "p reject 25,119,135-139,445,563,1214,4661-4666,6346-6429,6699,6881-6999\n"
  503. "id rsa1234 jlqAKFD2E7uMKv+8TmKSeo7NBho\n"
  504. /* Good 5: Extra id type. */
  505. "onion-key\n"
  506. "-----BEGIN RSA PUBLIC KEY-----\n"
  507. "MIGJAoGBAMdgPPc5uaw4y/q+SUTN/I8Y+Gvdx9kKgWV4dmDGJ0mxsVZmo1v6+v3F\n"
  508. "12M2f9m99G3WB8F8now29C+9XyEv8MBHj1lHRdUFHSQes3YTFvDNlgj+FjLqO5TJ\n"
  509. "adOOmfu4DCUUtUEDyQKbNVL4EkMTXY73omTVsjcH3xxFjTx5wixhAgMBAAE=\n"
  510. "-----END RSA PUBLIC KEY-----\n"
  511. "ntor-onion-key AAVnWZcnDbxasdZwKqb4fL6O9sZV+XsRNHTpNd1YMz8=\n"
  512. "id rsa1024 72EfBL11QuwX2vU8y+p9ExGfGEg\n"
  513. "id expolding hedgehog 0+A5O9qRvRac4FT3C4L2QnFyxsc\n"
  514. /* Good 6: I've given this a bogus policy. It should parse. */
  515. "onion-key\n"
  516. "-----BEGIN RSA PUBLIC KEY-----\n"
  517. "MIGJAoGBALNuufwhPMF8BooxYMNvhYJMPqUB8hQDt8wGmPKphJcD1sVD1i4gAZM2\n"
  518. "HIo+zUBlljDrRWL5NzVzd1yxUJAiQxvXS5dRRFY3B70M7wTVpXw53xe0/BM5t1AX\n"
  519. "n0MFk7Jl6XIKMlzRalZvmMvE/odtyWXkP4Nd1MyZ1QcIwrQ2iwyrAgMBAAE=\n"
  520. "-----END RSA PUBLIC KEY-----\n"
  521. "p condone 1-10\n"
  522. "ntor-onion-key 2/nMJ+L4dd/2GpMyTYjz3zC59MvQy4MIzJZhdzKHekg=\n"
  523. "id rsa1024 FHyh10glEMA6MCmBb5R9Y+X/MhQ\n"
  524. /* Good 7: I've given this one another sort of odd policy. Should parse. */
  525. "onion-key\n"
  526. "-----BEGIN RSA PUBLIC KEY-----\n"
  527. "MIGJAoGBAKcd3FmQ8iAADghyvX8eca0ePqtJ2w1IDdUdTlf5Y/8+OMdp//sD01yC\n"
  528. "YmiX45LK5ge1O3AzcakYCO6fb3pyIqvXdvm24OjyYZELQ40cmKSLjdhcSf4Fr/N9\n"
  529. "uR/CkknR9cEePu1wZ5WBIGmGdXI6s7t3LB+e7XFyBYAx6wMGlnX7AgMBAAE=\n"
  530. "-----END RSA PUBLIC KEY-----\n"
  531. "p accept frogs-mice\n"
  532. "ntor-onion-key AMxvhaQ1Qg7jBJFoyHuPRgETvLbFmJ194hExV24FuAI=\n"
  533. "family $D8CFEA0D996F5D1473D2063C041B7910DB23981E\n"
  534. "id rsa1024 d0VVZC/cHh1P3y4MMbfKlQHFycc\n"
  535. /* Good 8: This one has the ntor-onion-key without terminating =. That's
  536. * allowed. */
  537. "onion-key\n"
  538. "-----BEGIN RSA PUBLIC KEY-----\n"
  539. "MIGJAoGBAL438YfjrJE2SPqkkXeQwICygu8KNO54Juj6sjqk5hgsiazIWMOBgbaX\n"
  540. "LIRqPNGaiSq01xSqwjwCBCfwZYT/nSdDBqj1h9aoR8rnjxZjyQ+m3rWpdDqeCDMx\n"
  541. "I3NgZ5w4bNX4poRb42lrV6NmQiFdjzpqszVbv5Lpn2CSKu32CwKVAgMBAAE=\n"
  542. "-----END RSA PUBLIC KEY-----\n"
  543. "ntor-onion-key UKL6Dnj2KwYsFlkCvOkXVatxvOPB4MaxqwPQQgZMTwI\n"
  544. "id rsa1024 FPIXc6k++JnKCtSKWUxaR6oXEKs\n"
  545. /* Good 9: Another totally normal one.*/
  546. "onion-key\n"
  547. "-----BEGIN RSA PUBLIC KEY-----\n"
  548. "MIGJAoGBANNGIKRd8PFNXkJ2JPV1ohDMFNbJwKbwybeieaQFjtU9KWedHCbr+QD4\n"
  549. "B6zNY5ysguNjHNnlq2f6D09+uhnfDBON8tAz0mPQH/6JqnOXm+EiUn+8bN0E8Nke\n"
  550. "/i3GEgDeaxJJMNQcpsJvmmSmKFOlYy9Fy7ejAjTGqtAnqOte7BnTAgMBAAE=\n"
  551. "-----END RSA PUBLIC KEY-----\n"
  552. "ntor-onion-key gUsq3e5iYgsQQvyxINtLzBpHxmIt5rtuFlEbKfI4gFk=\n"
  553. "id rsa1024 jv+LdatDzsMfEW6pLBeL/5uzwCc\n"
  554. /* Bad 2: RSA key has bad exponent of 3. */
  555. "onion-key\n"
  556. "-----BEGIN RSA PUBLIC KEY-----\n"
  557. "MIGHAoGBAMMTWtvPxYnUNJ5Y7B+XENcpxzPoGstrdiUszCBS+/42xvluLJ+JDSdR\n"
  558. "qJaMD6ax8vKAeLS5C6O17MNdG2VldlPRbtgl41MXsOoUqEJ+nY9e3WG9Snjp47xC\n"
  559. "zmWIfeduXSavIsb3a43/MLIz/9qO0TkgAAiuQr79JlwKhLdzCqTLAgED\n"
  560. "-----END RSA PUBLIC KEY-----\n"
  561. "ntor-onion-key NkRB4wTUFogiVp5jYmjGORe2ffb/y5Kk8Itw8jdzMjA=\n"
  562. "p reject 25,119,135-139,445,563,1214,4661-4666,6346-6429,6699,6881-6999\n"
  563. "id rsa1024 fKvYjP7TAjCC1FzYee5bYAwYkoDg\n"
  564. /* Bad 3: Bogus annotation */
  565. "@last-listed with strange aeons\n"
  566. "onion-key\n"
  567. "-----BEGIN RSA PUBLIC KEY-----\n"
  568. "MIGJAoGBALcRBFNCZtpd2TFJysU77/fJMFzKisRQEBOtDGtTZ2Bg4aEGosssa0Id\n"
  569. "YtUagRLYle08QVGvGB+EHBI5qf6Ah2yPH7k5QiN2a3Sq+nyh85dXKPazBGBBbM+C\n"
  570. "DOfDauV02CAnADNMLJEf1voY3oBVvYyIsmHxn5i1R19ZYIiR8NX5AgMBAAE=\n"
  571. "-----END RSA PUBLIC KEY-----\n"
  572. "ntor-onion-key m4xcFXMWMjCvZDXq8FT3XmS0EHYseGOeu+fV+6FYDlk=\n"
  573. "p accept 20-23,43,53,79-81,88,110,143,194,220,389,443,464,531,543-544\n"
  574. "id rsa1024 SSbfNE9vmaiwRKH+eqNAkiKQhds\n"
  575. /* Good 10: Normal, with added ipv6 address and added other address */
  576. "onion-key\n"
  577. "-----BEGIN RSA PUBLIC KEY-----\n"
  578. "MIGJAoGBAM7uUtq5F6h63QNYIvC+4NcWaD0DjtnrOORZMkdpJhinXUOwce3cD5Dj\n"
  579. "sgdN1wJpWpTQMXJ2DssfSgmOVXETP7qJuZyRprxalQhaEATMDNJA/66Ml1jSO9mZ\n"
  580. "+8Xb7m/4q778lNtkSbsvMaYD2Dq6k2QQ3kMhr9z8oUtX0XA23+pfAgMBAAE=\n"
  581. "-----END RSA PUBLIC KEY-----\n"
  582. "a [::1:2:3:4]:9090\n"
  583. "a 18.0.0.1:9999\n"
  584. "ntor-onion-key k2yFqTU2vzMCQDEiE/j9UcEHxKrXMLpB3IL0or09sik=\n"
  585. "id rsa1024 2A8wYpHxnkKJ92orocvIQBzeHlE\n"
  586. "p6 allow 80\n"
  587. /* Good 11: Normal, non-exit relay with ipv6 address */
  588. "onion-key\n"
  589. "-----BEGIN RSA PUBLIC KEY-----\n"
  590. "MIGJAoGBAM7uUtq5F6h63QNYIvC+4NcWaD0DjtnrOORZMkdpJhinXUOwce3cD5Dj\n"
  591. "sgdN1wJpWpTQMXJ2DssfSgmOVXETP7qJuZyRprxalQhaEATMDNJA/66Ml1jSO9mZ\n"
  592. "+8Xb7m/4q778lNtkSbsvMaYD2Dq6k2QQ3kMhr9z8oUtX0XA23+pfAgMBAAE=\n"
  593. "-----END RSA PUBLIC KEY-----\n"
  594. "a [::1:2:3:4]:9090\n"
  595. "a 18.0.0.1:9999\n"
  596. "ntor-onion-key k2yFqTU2vzMCQDEiE/j9UcEHxKrXMLpB3IL0or09sik=\n"
  597. "id rsa1024 2A8wYpHxnkKJ92orocvIQBzeHlE\n"
  598. /* Good 12: Normal, exit relay with ipv6 address */
  599. "onion-key\n"
  600. "-----BEGIN RSA PUBLIC KEY-----\n"
  601. "MIGJAoGBAM7uUtq5F6h63QNYIvC+4NcWaD0DjtnrOORZMkdpJhinXUOwce3cD5Dj\n"
  602. "sgdN1wJpWpTQMXJ2DssfSgmOVXETP7qJuZyRprxalQhaEATMDNJA/66Ml1jSO9mZ\n"
  603. "+8Xb7m/4q778lNtkSbsvMaYD2Dq6k2QQ3kMhr9z8oUtX0XA23+pfAgMBAAE=\n"
  604. "-----END RSA PUBLIC KEY-----\n"
  605. "a [::1:2:3:4]:9090\n"
  606. "a 18.0.0.1:9999\n"
  607. "ntor-onion-key k2yFqTU2vzMCQDEiE/j9UcEHxKrXMLpB3IL0or09sik=\n"
  608. "p accept 20-23,43,53,79-81,88,110,143,194,220,389,443,464,531,543-544\n"
  609. "id rsa1024 2A8wYpHxnkKJ92orocvIQBzeHlE\n"
  610. /* Good 13: Normal, exit relay with only ipv6 exit policy */
  611. "onion-key\n"
  612. "-----BEGIN RSA PUBLIC KEY-----\n"
  613. "MIGJAoGBAM7uUtq5F6h63QNYIvC+4NcWaD0DjtnrOORZMkdpJhinXUOwce3cD5Dj\n"
  614. "sgdN1wJpWpTQMXJ2DssfSgmOVXETP7qJuZyRprxalQhaEATMDNJA/66Ml1jSO9mZ\n"
  615. "+8Xb7m/4q778lNtkSbsvMaYD2Dq6k2QQ3kMhr9z8oUtX0XA23+pfAgMBAAE=\n"
  616. "-----END RSA PUBLIC KEY-----\n"
  617. "a [::1:2:3:4]:9090\n"
  618. "a 18.0.0.1:9999\n"
  619. "ntor-onion-key k2yFqTU2vzMCQDEiE/j9UcEHxKrXMLpB3IL0or09sik=\n"
  620. "p6 accept 20-23,43,53,79-81,88,110,143,194,220,389,443,464,531,543-544\n"
  621. "id rsa1024 2A8wYpHxnkKJ92orocvIQBzeHlE\n"
  622. ;
  623. #ifdef HAVE_CFLAG_WOVERLENGTH_STRINGS
  624. ENABLE_GCC_WARNING(overlength-strings)
  625. #endif
  626. /** More tests for parsing different kinds of microdescriptors, and getting
  627. * invalid digests trackd from them. */
  628. static void
  629. test_md_parse(void *arg)
  630. {
  631. (void) arg;
  632. char *mem_op_hex_tmp = NULL;
  633. smartlist_t *invalid = smartlist_new();
  634. smartlist_t *mds = microdescs_parse_from_string(MD_PARSE_TEST_DATA,
  635. NULL, 1, SAVED_NOWHERE,
  636. invalid);
  637. tt_int_op(smartlist_len(mds), OP_EQ, 14);
  638. tt_int_op(smartlist_len(invalid), OP_EQ, 4);
  639. test_memeq_hex(smartlist_get(invalid,0),
  640. "5d76bf1c6614e885614a1e0ad074e1ab"
  641. "4ea14655ebeefb1736a71b5ed8a15a51");
  642. test_memeq_hex(smartlist_get(invalid,1),
  643. "2fde0ee3343669c2444cd9d53cbd39c6"
  644. "a7d1fc0513513e840ca7f6e68864b36c");
  645. test_memeq_hex(smartlist_get(invalid,2),
  646. "20d1576c5ab11bbcff0dedb1db4a3cfc"
  647. "c8bc8dd839d8cbfef92d00a1a7d7b294");
  648. test_memeq_hex(smartlist_get(invalid,3),
  649. "074770f394c73dbde7b44412e9692add"
  650. "691a478d4727f9804b77646c95420a96");
  651. /* Spot-check the valid ones. */
  652. const microdesc_t *md = smartlist_get(mds, 5);
  653. test_memeq_hex(md->digest,
  654. "54bb6d733ddeb375d2456c79ae103961"
  655. "da0cae29620375ac4cf13d54da4d92b3");
  656. tt_int_op(md->last_listed, OP_EQ, 0);
  657. tt_int_op(md->saved_location, OP_EQ, SAVED_NOWHERE);
  658. tt_int_op(md->no_save, OP_EQ, 0);
  659. tt_uint_op(md->held_in_map, OP_EQ, 0);
  660. tt_uint_op(md->held_by_nodes, OP_EQ, 0);
  661. tt_assert(md->onion_curve25519_pkey);
  662. md = smartlist_get(mds, 6);
  663. test_memeq_hex(md->digest,
  664. "53f740bd222ab37f19f604b1d3759aa6"
  665. "5eff1fbce9ac254bd0fa50d4af9b1bae");
  666. tt_assert(! md->exit_policy);
  667. md = smartlist_get(mds, 8);
  668. test_memeq_hex(md->digest,
  669. "a0a155562d8093d8fd0feb7b93b7226e"
  670. "17f056c2142aab7a4ea8c5867a0376d5");
  671. tt_assert(md->onion_curve25519_pkey);
  672. md = smartlist_get(mds, 10);
  673. test_memeq_hex(md->digest,
  674. "409ebd87d23925a2732bd467a92813c9"
  675. "21ca378fcb9ca193d354c51550b6d5e9");
  676. tt_assert(tor_addr_family(&md->ipv6_addr) == AF_INET6);
  677. tt_int_op(md->ipv6_orport, OP_EQ, 9090);
  678. md = smartlist_get(mds, 11);
  679. tt_assert(tor_addr_family(&md->ipv6_addr) == AF_INET6);
  680. tt_int_op(md->ipv6_orport, OP_EQ, 9090);
  681. tt_int_op(md->policy_is_reject_star, OP_EQ, 1);
  682. md = smartlist_get(mds, 12);
  683. tt_assert(tor_addr_family(&md->ipv6_addr) == AF_INET6);
  684. tt_int_op(md->ipv6_orport, OP_EQ, 9090);
  685. tt_int_op(md->policy_is_reject_star, OP_EQ, 0);
  686. md = smartlist_get(mds, 13);
  687. tt_assert(tor_addr_family(&md->ipv6_addr) == AF_INET6);
  688. tt_int_op(md->ipv6_orport, OP_EQ, 9090);
  689. tt_int_op(md->policy_is_reject_star, OP_EQ, 0);
  690. done:
  691. SMARTLIST_FOREACH(mds, microdesc_t *, mdsc, microdesc_free(mdsc));
  692. smartlist_free(mds);
  693. SMARTLIST_FOREACH(invalid, char *, cp, tor_free(cp));
  694. smartlist_free(invalid);
  695. tor_free(mem_op_hex_tmp);
  696. }
  697. static void
  698. test_md_parse_id_ed25519(void *arg)
  699. {
  700. (void)arg;
  701. /* A correct MD with an ed25519 ID ... and an unspecified ID type,
  702. * which is permitted. */
  703. const char GOOD_MD[] =
  704. "onion-key\n"
  705. "-----BEGIN RSA PUBLIC KEY-----\n"
  706. "MIGJAoGBAM7uUtq5F6h63QNYIvC+4NcWaD0DjtnrOORZMkdpJhinXUOwce3cD5Dj\n"
  707. "sgdN1wJpWpTQMXJ2DssfSgmOVXETP7qJuZyRprxalQhaEATMDNJA/66Ml1jSO9mZ\n"
  708. "+8Xb7m/4q778lNtkSbsvMaYD2Dq6k2QQ3kMhr9z8oUtX0XA23+pfAgMBAAE=\n"
  709. "-----END RSA PUBLIC KEY-----\n"
  710. "id ed25519 VGhpcyBpc24ndCBhY3R1YWxseSBhIHB1YmxpYyBrZXk\n"
  711. "id wumpus dodecahedron\n";
  712. smartlist_t *mds = NULL;
  713. const microdesc_t *md;
  714. mds = microdescs_parse_from_string(GOOD_MD,
  715. NULL, 1, SAVED_NOWHERE, NULL);
  716. tt_assert(mds);
  717. tt_int_op(smartlist_len(mds), OP_EQ, 1);
  718. md = smartlist_get(mds, 0);
  719. tt_mem_op(md->ed25519_identity_pkey, OP_EQ,
  720. "This isn't actually a public key", ED25519_PUBKEY_LEN);
  721. SMARTLIST_FOREACH(mds, microdesc_t *, m, microdesc_free(m));
  722. smartlist_free(mds);
  723. /* As above, but ed25519 ID key appears twice. */
  724. const char DUPLICATE_KEY[] =
  725. "onion-key\n"
  726. "-----BEGIN RSA PUBLIC KEY-----\n"
  727. "MIGJAoGBAM7uUtq5F6h63QNYIvC+4NcWaD0DjtnrOORZMkdpJhinXUOwce3cD5Dj\n"
  728. "sgdN1wJpWpTQMXJ2DssfSgmOVXETP7qJuZyRprxalQhaEATMDNJA/66Ml1jSO9mZ\n"
  729. "+8Xb7m/4q778lNtkSbsvMaYD2Dq6k2QQ3kMhr9z8oUtX0XA23+pfAgMBAAE=\n"
  730. "-----END RSA PUBLIC KEY-----\n"
  731. "id ed25519 VGhpcyBpc24ndCBhY3R1YWxseSBhIHB1YmxpYyBrZXk\n"
  732. "id ed25519 VGhpcyBpc24ndCBhY3R1YWxseSBhIHB1YmxpYyBrZXk\n";
  733. setup_capture_of_logs(LOG_WARN);
  734. mds = microdescs_parse_from_string(DUPLICATE_KEY,
  735. NULL, 1, SAVED_NOWHERE, NULL);
  736. tt_assert(mds);
  737. tt_int_op(smartlist_len(mds), OP_EQ, 0); // no entries.
  738. expect_single_log_msg_containing("Extra ed25519 key");
  739. mock_clean_saved_logs();
  740. smartlist_free(mds);
  741. /* As above, but ed25519 ID key is invalid. */
  742. const char BOGUS_KEY[] =
  743. "onion-key\n"
  744. "-----BEGIN RSA PUBLIC KEY-----\n"
  745. "MIGJAoGBAM7uUtq5F6h63QNYIvC+4NcWaD0DjtnrOORZMkdpJhinXUOwce3cD5Dj\n"
  746. "sgdN1wJpWpTQMXJ2DssfSgmOVXETP7qJuZyRprxalQhaEATMDNJA/66Ml1jSO9mZ\n"
  747. "+8Xb7m/4q778lNtkSbsvMaYD2Dq6k2QQ3kMhr9z8oUtX0XA23+pfAgMBAAE=\n"
  748. "-----END RSA PUBLIC KEY-----\n"
  749. "id ed25519 VGhpcyBpc24ndCBhY3R1YWxseSBhIHB1YmxpYyZZZZZZZZZZZ\n";
  750. mds = microdescs_parse_from_string(BOGUS_KEY,
  751. NULL, 1, SAVED_NOWHERE, NULL);
  752. tt_assert(mds);
  753. tt_int_op(smartlist_len(mds), OP_EQ, 0); // no entries.
  754. expect_single_log_msg_containing("Bogus ed25519 key");
  755. done:
  756. if (mds) {
  757. SMARTLIST_FOREACH(mds, microdesc_t *, m, microdesc_free(m));
  758. smartlist_free(mds);
  759. }
  760. teardown_capture_of_logs();
  761. }
  762. static int mock_rgsbd_called = 0;
  763. static routerstatus_t *mock_rgsbd_val_a = NULL;
  764. static routerstatus_t *mock_rgsbd_val_b = NULL;
  765. static routerstatus_t *
  766. mock_router_get_status_by_digest(networkstatus_t *c, const char *d)
  767. {
  768. (void) c;
  769. ++mock_rgsbd_called;
  770. if (fast_memeq(d, "\x5d\x76", 2)) {
  771. memcpy(mock_rgsbd_val_a->descriptor_digest, d, 32);
  772. return mock_rgsbd_val_a;
  773. } else if (fast_memeq(d, "\x20\xd1", 2)) {
  774. memcpy(mock_rgsbd_val_b->descriptor_digest, d, 32);
  775. return mock_rgsbd_val_b;
  776. } else {
  777. return NULL;
  778. }
  779. }
  780. static networkstatus_t *mock_ns_val = NULL;
  781. static networkstatus_t *
  782. mock_ns_get_by_flavor(consensus_flavor_t f)
  783. {
  784. (void)f;
  785. return mock_ns_val;
  786. }
  787. static void
  788. test_md_reject_cache(void *arg)
  789. {
  790. (void) arg;
  791. microdesc_cache_t *mc = NULL ;
  792. smartlist_t *added = NULL, *wanted = smartlist_new();
  793. or_options_t *options = get_options_mutable();
  794. char buf[DIGEST256_LEN];
  795. tor_free(options->CacheDirectory);
  796. options->CacheDirectory = tor_strdup(get_fname("md_datadir_test_rej"));
  797. mock_rgsbd_val_a = tor_malloc_zero(sizeof(routerstatus_t));
  798. mock_rgsbd_val_b = tor_malloc_zero(sizeof(routerstatus_t));
  799. mock_ns_val = tor_malloc_zero(sizeof(networkstatus_t));
  800. mock_ns_val->valid_after = time(NULL) - 86400;
  801. mock_ns_val->valid_until = time(NULL) + 86400;
  802. mock_ns_val->flavor = FLAV_MICRODESC;
  803. #ifdef _WIN32
  804. tt_int_op(0, OP_EQ, mkdir(options->CacheDirectory));
  805. #else
  806. tt_int_op(0, OP_EQ, mkdir(options->CacheDirectory, 0700));
  807. #endif
  808. MOCK(router_get_mutable_consensus_status_by_descriptor_digest,
  809. mock_router_get_status_by_digest);
  810. MOCK(networkstatus_get_latest_consensus_by_flavor, mock_ns_get_by_flavor);
  811. mc = get_microdesc_cache();
  812. #define ADD(hex) \
  813. do { \
  814. tt_int_op(sizeof(buf),OP_EQ,base16_decode(buf,sizeof(buf), \
  815. hex,strlen(hex)));\
  816. smartlist_add(wanted, tor_memdup(buf, DIGEST256_LEN)); \
  817. } while (0)
  818. /* invalid,0 */
  819. ADD("5d76bf1c6614e885614a1e0ad074e1ab4ea14655ebeefb1736a71b5ed8a15a51");
  820. /* invalid,2 */
  821. ADD("20d1576c5ab11bbcff0dedb1db4a3cfcc8bc8dd839d8cbfef92d00a1a7d7b294");
  822. /* valid, 6 */
  823. ADD("53f740bd222ab37f19f604b1d3759aa65eff1fbce9ac254bd0fa50d4af9b1bae");
  824. /* valid, 8 */
  825. ADD("a0a155562d8093d8fd0feb7b93b7226e17f056c2142aab7a4ea8c5867a0376d5");
  826. added = microdescs_add_to_cache(mc, MD_PARSE_TEST_DATA, NULL,
  827. SAVED_NOWHERE, 0, time(NULL), wanted);
  828. tt_int_op(smartlist_len(added), OP_EQ, 2);
  829. tt_int_op(mock_rgsbd_called, OP_EQ, 2);
  830. tt_int_op(mock_rgsbd_val_a->dl_status.n_download_failures, OP_EQ, 255);
  831. tt_int_op(mock_rgsbd_val_b->dl_status.n_download_failures, OP_EQ, 255);
  832. done:
  833. UNMOCK(networkstatus_get_latest_consensus_by_flavor);
  834. UNMOCK(router_get_mutable_consensus_status_by_descriptor_digest);
  835. tor_free(options->CacheDirectory);
  836. microdesc_free_all();
  837. smartlist_free(added);
  838. SMARTLIST_FOREACH(wanted, char *, cp, tor_free(cp));
  839. smartlist_free(wanted);
  840. tor_free(mock_rgsbd_val_a);
  841. tor_free(mock_rgsbd_val_b);
  842. tor_free(mock_ns_val);
  843. }
  844. static void
  845. test_md_corrupt_desc(void *arg)
  846. {
  847. char *cp = NULL;
  848. smartlist_t *sl = NULL;
  849. (void) arg;
  850. sl = microdescs_add_to_cache(get_microdesc_cache(),
  851. "@last-listed 2015-06-22 10:00:00\n"
  852. "onion-k\n",
  853. NULL, SAVED_IN_JOURNAL, 0, time(NULL), NULL);
  854. tt_int_op(smartlist_len(sl), OP_EQ, 0);
  855. smartlist_free(sl);
  856. sl = microdescs_add_to_cache(get_microdesc_cache(),
  857. "@last-listed 2015-06-22 10:00:00\n"
  858. "wiggly\n",
  859. NULL, SAVED_IN_JOURNAL, 0, time(NULL), NULL);
  860. tt_int_op(smartlist_len(sl), OP_EQ, 0);
  861. smartlist_free(sl);
  862. tor_asprintf(&cp, "%s\n%s", test_md1, "@foobar\nonion-wobble\n");
  863. sl = microdescs_add_to_cache(get_microdesc_cache(),
  864. cp, cp+strlen(cp),
  865. SAVED_IN_JOURNAL, 0, time(NULL), NULL);
  866. tt_int_op(smartlist_len(sl), OP_EQ, 0);
  867. done:
  868. tor_free(cp);
  869. smartlist_free(sl);
  870. }
  871. struct testcase_t microdesc_tests[] = {
  872. { "cache", test_md_cache, TT_FORK, NULL, NULL },
  873. { "broken_cache", test_md_cache_broken, TT_FORK, NULL, NULL },
  874. { "generate", test_md_generate, 0, NULL, NULL },
  875. { "parse", test_md_parse, 0, NULL, NULL },
  876. { "parse_id_ed25519", test_md_parse_id_ed25519, 0, NULL, NULL },
  877. { "reject_cache", test_md_reject_cache, TT_FORK, NULL, NULL },
  878. { "corrupt_desc", test_md_corrupt_desc, TT_FORK, NULL, NULL },
  879. END_OF_TESTCASES
  880. };