diff --git a/changes/15554 b/changes/15554 new file mode 100644 index 0000000000..c7ae7e5579 --- /dev/null +++ b/changes/15554 @@ -0,0 +1,4 @@ + o Minor features (testing): + - Add a unit test to verify that we can parse a hardcoded v2 + hidden service descriptor. Closes ticket 15554. + diff --git a/src/or/rendcommon.c b/src/or/rendcommon.c index e1236bdd0f..986bfde75f 100644 --- a/src/or/rendcommon.c +++ b/src/or/rendcommon.c @@ -8,6 +8,8 @@ * introducers, services, clients, and rendezvous points. **/ +#define RENDCOMMON_PRIVATE + #include "or.h" #include "circuitbuild.h" #include "config.h" @@ -395,7 +397,7 @@ rend_encrypt_v2_intro_points_stealth(char **encrypted_out, /** Attempt to parse the given desc_str and return true if this * succeeds, false otherwise. */ -static int +STATIC int rend_desc_v2_is_parsable(rend_encoded_v2_service_descriptor_t *desc) { rend_service_descriptor_t *test_parsed = NULL; diff --git a/src/or/rendcommon.h b/src/or/rendcommon.h index 94c2480d86..292f9277e8 100644 --- a/src/or/rendcommon.h +++ b/src/or/rendcommon.h @@ -63,5 +63,12 @@ int rend_non_anonymous_mode_enabled(const or_options_t *options); void assert_circ_anonymity_ok(origin_circuit_t *circ, const or_options_t *options); +#ifdef RENDCOMMON_PRIVATE + +STATIC int +rend_desc_v2_is_parsable(rend_encoded_v2_service_descriptor_t *desc); + +#endif + #endif diff --git a/src/test/test_hs.c b/src/test/test_hs.c index b4817a21ea..178f94d273 100644 --- a/src/test/test_hs.c +++ b/src/test/test_hs.c @@ -8,6 +8,7 @@ #define CONTROL_PRIVATE #define CIRCUITBUILD_PRIVATE +#define RENDCOMMON_PRIVATE #define RENDSERVICE_PRIVATE #include "or.h" @@ -32,8 +33,9 @@ #define STR_HSDIR_NONE_EXIST_LONGNAME \ "$BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" -/* DuckDuckGo descriptor as an example. */ -static const char *hs_desc_content = "\ +/* DuckDuckGo descriptor as an example. This one has extra "\r" at the end so + * the control port is happy. */ +static const char *hs_desc_content_control = "\ rendezvous-service-descriptor g5ojobzupf275beh5ra72uyhb3dkpxwg\r\n\ version 2\r\n\ permanent-key\r\n\ @@ -94,6 +96,68 @@ PcftsZf2ztN0sbNCtPgDL3d0PqvxY3iHTQAI8EbaGq/IAJUZ8U4y963dD5+Bn6JQ\r\n\ myE3ctmh0vy5+QxSiRjmQBkuEpCyks7LvWvHYrhnmcg=\r\n\ -----END SIGNATURE-----"; +/* DuckDuckGo descriptor as an example. */ +static const char *hs_desc_content = "\ +rendezvous-service-descriptor g5ojobzupf275beh5ra72uyhb3dkpxwg\n\ +version 2\n\ +permanent-key\n\ +-----BEGIN RSA PUBLIC KEY-----\n\ +MIGJAoGBAJ/SzzgrXPxTlFrKVhXh3buCWv2QfcNgncUpDpKouLn3AtPH5Ocys0jE\n\ +aZSKdvaiQ62md2gOwj4x61cFNdi05tdQjS+2thHKEm/KsB9BGLSLBNJYY356bupg\n\ +I5gQozM65ENelfxYlysBjJ52xSDBd8C4f/p9umdzaaaCmzXG/nhzAgMBAAE=\n\ +-----END RSA PUBLIC KEY-----\n\ +secret-id-part anmjoxxwiupreyajjt5yasimfmwcnxlf\n\ +publication-time 2015-03-11 19:00:00\n\ +protocol-versions 2,3\n\ +introduction-points\n\ +-----BEGIN MESSAGE-----\n\ +aW50cm9kdWN0aW9uLXBvaW50IDd1bnd4cmg2dG5kNGh6eWt1Z3EzaGZzdHduc2ll\n\ +cmhyCmlwLWFkZHJlc3MgMTg4LjEzOC4xMjEuMTE4Cm9uaW9uLXBvcnQgOTAwMQpv\n\ +bmlvbi1rZXkKLS0tLS1CRUdJTiBSU0EgUFVCTElDIEtFWS0tLS0tCk1JR0pBb0dC\n\ +QUxGRVVyeVpDbk9ROEhURmV5cDVjMTRObWVqL1BhekFLTTBxRENTNElKUWh0Y3g1\n\ +NXpRSFdOVWIKQ2hHZ0JqR1RjV3ZGRnA0N3FkdGF6WUZhVXE2c0lQKzVqeWZ5b0Q4\n\ +UmJ1bzBwQmFWclJjMmNhYUptWWM0RDh6Vgpuby9sZnhzOVVaQnZ1cWY4eHIrMDB2\n\ +S0JJNmFSMlA2OE1WeDhrMExqcUpUU2RKOE9idm9yQWdNQkFBRT0KLS0tLS1FTkQg\n\ +UlNBIFBVQkxJQyBLRVktLS0tLQpzZXJ2aWNlLWtleQotLS0tLUJFR0lOIFJTQSBQ\n\ +VUJMSUMgS0VZLS0tLS0KTUlHSkFvR0JBTnJHb0ozeTlHNXQzN2F2ekI1cTlwN1hG\n\ +VUplRUVYMUNOaExnWmJXWGJhVk5OcXpoZFhyL0xTUQppM1Z6dW5OaUs3cndUVnE2\n\ +K2QyZ1lRckhMMmIvMXBBY3ZKWjJiNSs0bTRRc0NibFpjRENXTktRbHJnRWN5WXRJ\n\ +CkdscXJTbFFEaXA0ZnNrUFMvNDVkWTI0QmJsQ3NGU1k3RzVLVkxJck4zZFpGbmJr\n\ +NEZIS1hBZ01CQUFFPQotLS0tLUVORCBSU0EgUFVCTElDIEtFWS0tLS0tCmludHJv\n\ +ZHVjdGlvbi1wb2ludCBiNGM3enlxNXNheGZzN2prNXFibG1wN3I1b3pwdHRvagpp\n\ +cC1hZGRyZXNzIDEwOS4xNjkuNDUuMjI2Cm9uaW9uLXBvcnQgOTAwMQpvbmlvbi1r\n\ +ZXkKLS0tLS1CRUdJTiBSU0EgUFVCTElDIEtFWS0tLS0tCk1JR0pBb0dCQU8xSXpw\n\ +WFFUTUY3RXZUb1NEUXpzVnZiRVFRQUQrcGZ6NzczMVRXZzVaUEJZY1EyUkRaeVp4\n\ +OEQKNUVQSU1FeUE1RE83cGd0ak5LaXJvYXJGMC8yempjMkRXTUlSaXZyU29YUWVZ\n\ +ZXlMM1pzKzFIajJhMDlCdkYxZAp6MEswblRFdVhoNVR5V3lyMHdsbGI1SFBnTlI0\n\ +MS9oYkprZzkwZitPVCtIeGhKL1duUml2QWdNQkFBRT0KLS0tLS1FTkQgUlNBIFBV\n\ +QkxJQyBLRVktLS0tLQpzZXJ2aWNlLWtleQotLS0tLUJFR0lOIFJTQSBQVUJMSUMg\n\ +S0VZLS0tLS0KTUlHSkFvR0JBSzNWZEJ2ajFtQllLL3JrcHNwcm9Ub0llNUtHVmth\n\ +QkxvMW1tK1I2YUVJek1VZFE1SjkwNGtyRwpCd3k5NC8rV0lGNFpGYXh5Z2phejl1\n\ +N2pKY1k3ZGJhd1pFeG1hYXFCRlRwL2h2ZG9rcHQ4a1ByRVk4OTJPRHJ1CmJORUox\n\ +N1FPSmVMTVZZZk5Kcjl4TWZCQ3JQai8zOGh2RUdrbWVRNmRVWElvbVFNaUJGOVRB\n\ +Z01CQUFFPQotLS0tLUVORCBSU0EgUFVCTElDIEtFWS0tLS0tCmludHJvZHVjdGlv\n\ +bi1wb2ludCBhdjVtcWl0Y2Q3cjJkandsYmN0c2Jlc2R3eGt0ZWtvegppcC1hZGRy\n\ +ZXNzIDE0NC43Ni44LjczCm9uaW9uLXBvcnQgNDQzCm9uaW9uLWtleQotLS0tLUJF\n\ +R0lOIFJTQSBQVUJMSUMgS0VZLS0tLS0KTUlHSkFvR0JBTzVweVZzQmpZQmNmMXBE\n\ +dklHUlpmWXUzQ05nNldka0ZLMGlvdTBXTGZtejZRVDN0NWhzd3cyVwpjejlHMXhx\n\ +MmN0Nkd6VWkrNnVkTDlITTRVOUdHTi9BbW8wRG9GV1hKWHpBQkFXd2YyMVdsd1lW\n\ +eFJQMHRydi9WCkN6UDkzcHc5OG5vSmdGUGRUZ05iMjdKYmVUZENLVFBrTEtscXFt\n\ +b3NveUN2RitRa25vUS9BZ01CQUFFPQotLS0tLUVORCBSU0EgUFVCTElDIEtFWS0t\n\ +LS0tCnNlcnZpY2Uta2V5Ci0tLS0tQkVHSU4gUlNBIFBVQkxJQyBLRVktLS0tLQpN\n\ +SUdKQW9HQkFMVjNKSmtWN3lTNU9jc1lHMHNFYzFQOTVRclFRR3ZzbGJ6Wi9zRGxl\n\ +RlpKYXFSOUYvYjRUVERNClNGcFMxcU1GbldkZDgxVmRGMEdYRmN2WVpLamRJdHU2\n\ +SndBaTRJeEhxeXZtdTRKdUxrcXNaTEFLaXRLVkx4eGsKeERlMjlDNzRWMmJrOTRJ\n\ +MEgybTNKS2tzTHVwc3VxWWRVUmhOVXN0SElKZmgyZmNIalF0bEFnTUJBQUU9Ci0t\n\ +LS0tRU5EIFJTQSBQVUJMSUMgS0VZLS0tLS0KCg==\n\ +-----END MESSAGE-----\n\ +signature\n\ +-----BEGIN SIGNATURE-----\n\ +d4OuCE5OLAOnRB6cQN6WyMEmg/BHem144Vec+eYgeWoKwx3MxXFplUjFxgnMlmwN\n\ +PcftsZf2ztN0sbNCtPgDL3d0PqvxY3iHTQAI8EbaGq/IAJUZ8U4y963dD5+Bn6JQ\n\ +myE3ctmh0vy5+QxSiRjmQBkuEpCyks7LvWvHYrhnmcg=\n\ +-----END SIGNATURE-----"; + /* Helper global variable for hidden service descriptor event test. * It's used as a pointer to dynamically created message buffer in * send_control_event_string_replacement function, which mocks @@ -125,6 +189,30 @@ node_describe_longname_by_id_replacement(const char *id_digest) } } +/** Test that we can parse a hardcoded v2 HS desc. */ +static void +test_hs_parse_static_v2_desc(void *arg) +{ + int ret; + rend_encoded_v2_service_descriptor_t desc; + + (void) arg; + + /* Test an obviously not parseable string */ + desc.desc_str = tor_strdup("ceci n'est pas un HS descriptor"); + ret = rend_desc_v2_is_parsable(&desc); + tor_free(desc.desc_str); + tt_int_op(ret, OP_EQ, 0); + + /* Test an actual descriptor */ + desc.desc_str = tor_strdup(hs_desc_content); + ret = rend_desc_v2_is_parsable(&desc); + tor_free(desc.desc_str); + tt_int_op(ret, OP_EQ, 1); + + done: ; +} + /** Make sure each hidden service descriptor async event generation * * function generates the message in expected format. @@ -235,10 +323,10 @@ test_hs_desc_event(void *arg) /* test valid content. */ control_event_hs_descriptor_content(rend_query.onion_address, STR_HS_CONTENT_DESC_ID, HSDIR_EXIST_ID, - hs_desc_content); + hs_desc_content_control); tor_asprintf(&exp_msg, "650+HS_DESC_CONTENT " STR_HS_ADDR " "\ STR_HS_CONTENT_DESC_ID " " STR_HSDIR_EXIST_LONGNAME\ - "\r\n%s\r\n.\r\n650 OK\r\n", hs_desc_content); + "\r\n%s\r\n.\r\n650 OK\r\n", hs_desc_content_control); tt_assert(received_msg); tt_str_op(received_msg, OP_EQ, exp_msg); @@ -941,6 +1029,8 @@ test_prune_services_on_reload(void *arg) struct testcase_t hs_tests[] = { { "hs_rend_data", test_hs_rend_data, TT_FORK, NULL, NULL }, + { "hs_parse_static_v2_desc", test_hs_parse_static_v2_desc, TT_FORK, + NULL, NULL }, { "hs_desc_event", test_hs_desc_event, TT_FORK, NULL, NULL }, { "pick_tor2web_rendezvous_node", test_pick_tor2web_rendezvous_node, TT_FORK,