diff --git a/src/test/test_hs_intropoint.c b/src/test/test_hs_intropoint.c index 608988ba9a..b4a81eaacd 100644 --- a/src/test/test_hs_intropoint.c +++ b/src/test/test_hs_intropoint.c @@ -12,12 +12,14 @@ #define CIRCUITLIST_PRIVATE #include "test.h" +#include "log_test_helpers.h" #include "crypto.h" #include "or.h" #include "ht.h" #include "hs/cell_establish_intro.h" +#include "hs_common.h" #include "hs_service.h" #include "hs_circuitmap.h" #include "hs_intropoint.h" @@ -143,6 +145,163 @@ test_establish_intro_wrong_keytype2(void *arg) circuit_free(TO_CIRCUIT(intro_circ)); } +/* Send a legit ESTABLISH_INTRO cell but with a wrong MAC. Should fail. */ +static void +test_establish_intro_wrong_mac(void *arg) +{ + int retval; + hs_cell_establish_intro_t *establish_intro_cell = NULL; + or_circuit_t *intro_circ = or_circuit_new(0,NULL);; + uint8_t cell_body[RELAY_PAYLOAD_SIZE]; + ssize_t cell_len = 0; + uint8_t circuit_key_material[DIGEST_LEN] = {0}; + + (void)arg; + + /* Get the auth key of the intro point */ + crypto_rand((char *) circuit_key_material, sizeof(circuit_key_material)); + helper_prepare_circ_for_intro(intro_circ, circuit_key_material); + + /* Create outgoing ESTABLISH_INTRO cell and extract its payload so that we + attempt to parse it. */ + establish_intro_cell = generate_establish_intro_cell(circuit_key_material, + sizeof(circuit_key_material)); + tt_assert(establish_intro_cell); + /* Mangle one byte of the MAC. */ + uint8_t *handshake_ptr = + hs_cell_establish_intro_getarray_handshake_mac(establish_intro_cell); + handshake_ptr[TRUNNEL_SHA3_256_LEN - 1]++; + /* We need to resign the payload with that change. */ + { + ed25519_signature_t sig; + ed25519_keypair_t key_struct; + /* New keypair for the signature since we don't have access to the private + * key material generated earlier when creating the cell. */ + retval = ed25519_keypair_generate(&key_struct, 0); + tt_int_op(retval, OP_EQ, 0); + uint8_t *auth_key_ptr = + hs_cell_establish_intro_getarray_auth_key(establish_intro_cell); + memcpy(auth_key_ptr, key_struct.pubkey.pubkey, ED25519_PUBKEY_LEN); + /* Encode payload so we can sign it. */ + cell_len = get_establish_intro_payload(cell_body, sizeof(cell_body), + establish_intro_cell); + tt_int_op(cell_len, >, 0); + + retval = ed25519_sign_prefixed(&sig, cell_body, + cell_len - + (ED25519_SIG_LEN + + sizeof(establish_intro_cell->sig_len)), + ESTABLISH_INTRO_SIG_PREFIX, &key_struct); + tt_int_op(retval, OP_EQ, 0); + /* And write the signature to the cell */ + uint8_t *sig_ptr = + hs_cell_establish_intro_getarray_sig(establish_intro_cell); + memcpy(sig_ptr, sig.sig, establish_intro_cell->sig_len); + /* Re-encode with the new signature. */ + cell_len = get_establish_intro_payload(cell_body, sizeof(cell_body), + establish_intro_cell); + } + + /* Receive the cell. Should fail because our MAC is wrong. */ + setup_full_capture_of_logs(LOG_INFO); + retval = hs_intro_received_establish_intro(intro_circ, cell_body, cell_len); + expect_log_msg_containing("ESTABLISH_INTRO handshake_auth not as expected"); + teardown_capture_of_logs(); + tt_int_op(retval, ==, -1); + + done: + hs_cell_establish_intro_free(establish_intro_cell); + circuit_free(TO_CIRCUIT(intro_circ)); +} + +/* Send a legit ESTABLISH_INTRO cell but with a wrong auth key length. Should + * fail. */ +static void +test_establish_intro_wrong_auth_key_len(void *arg) +{ + int retval; + hs_cell_establish_intro_t *establish_intro_cell = NULL; + or_circuit_t *intro_circ = or_circuit_new(0,NULL);; + uint8_t cell_body[RELAY_PAYLOAD_SIZE]; + ssize_t cell_len = 0; + size_t bad_auth_key_len = ED25519_PUBKEY_LEN - 1; + uint8_t circuit_key_material[DIGEST_LEN] = {0}; + + (void)arg; + + /* Get the auth key of the intro point */ + crypto_rand((char *) circuit_key_material, sizeof(circuit_key_material)); + helper_prepare_circ_for_intro(intro_circ, circuit_key_material); + + /* Create outgoing ESTABLISH_INTRO cell and extract its payload so that we + attempt to parse it. */ + establish_intro_cell = generate_establish_intro_cell(circuit_key_material, + sizeof(circuit_key_material)); + tt_assert(establish_intro_cell); + /* Mangle the auth key length. */ + hs_cell_establish_intro_set_auth_key_len(establish_intro_cell, + bad_auth_key_len); + hs_cell_establish_intro_setlen_auth_key(establish_intro_cell, + bad_auth_key_len); + cell_len = get_establish_intro_payload(cell_body, sizeof(cell_body), + establish_intro_cell); + tt_int_op(cell_len, >, 0); + + /* Receive the cell. Should fail. */ + setup_full_capture_of_logs(LOG_INFO); + retval = hs_intro_received_establish_intro(intro_circ, cell_body, cell_len); + expect_log_msg_containing("ESTABLISH_INTRO auth key length is invalid"); + teardown_capture_of_logs(); + tt_int_op(retval, ==, -1); + + done: + hs_cell_establish_intro_free(establish_intro_cell); + circuit_free(TO_CIRCUIT(intro_circ)); +} + +/* Send a legit ESTABLISH_INTRO cell but with a wrong sig length. Should + * fail. */ +static void +test_establish_intro_wrong_sig_len(void *arg) +{ + int retval; + hs_cell_establish_intro_t *establish_intro_cell = NULL; + or_circuit_t *intro_circ = or_circuit_new(0,NULL);; + uint8_t cell_body[RELAY_PAYLOAD_SIZE]; + ssize_t cell_len = 0; + size_t bad_sig_len = ED25519_SIG_LEN - 1; + uint8_t circuit_key_material[DIGEST_LEN] = {0}; + + (void)arg; + + /* Get the auth key of the intro point */ + crypto_rand((char *) circuit_key_material, sizeof(circuit_key_material)); + helper_prepare_circ_for_intro(intro_circ, circuit_key_material); + + /* Create outgoing ESTABLISH_INTRO cell and extract its payload so that we + attempt to parse it. */ + establish_intro_cell = generate_establish_intro_cell(circuit_key_material, + sizeof(circuit_key_material)); + tt_assert(establish_intro_cell); + /* Mangle the signature length. */ + hs_cell_establish_intro_set_sig_len(establish_intro_cell, bad_sig_len); + hs_cell_establish_intro_setlen_sig(establish_intro_cell, bad_sig_len); + cell_len = get_establish_intro_payload(cell_body, sizeof(cell_body), + establish_intro_cell); + tt_int_op(cell_len, >, 0); + + /* Receive the cell. Should fail. */ + setup_full_capture_of_logs(LOG_INFO); + retval = hs_intro_received_establish_intro(intro_circ, cell_body, cell_len); + expect_log_msg_containing("ESTABLISH_INTRO sig len is invalid"); + teardown_capture_of_logs(); + tt_int_op(retval, ==, -1); + + done: + hs_cell_establish_intro_free(establish_intro_cell); + circuit_free(TO_CIRCUIT(intro_circ)); +} + /* Send a legit ESTABLISH_INTRO cell but slightly change the signature. Should * fail. */ static void @@ -356,6 +515,15 @@ struct testcase_t hs_intropoint_tests[] = { { "receive_establish_intro_wrong_sig", test_establish_intro_wrong_sig, TT_FORK, NULL, NULL }, + { "receive_establish_intro_wrong_sig_len", + test_establish_intro_wrong_sig_len, TT_FORK, NULL, NULL }, + + { "receive_establish_intro_wrong_auth_key_len", + test_establish_intro_wrong_auth_key_len, TT_FORK, NULL, NULL }, + + { "receive_establish_intro_wrong_mac", + test_establish_intro_wrong_mac, TT_FORK, NULL, NULL }, + END_OF_TESTCASES };