|
@@ -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
|
|
|
};
|
|
|
|