aboutsummaryrefslogtreecommitdiff
path: root/src/test/test_ntor_v3.c
diff options
context:
space:
mode:
authorMike Perry <mikeperry-git@torproject.org>2021-11-23 20:47:24 +0000
committerMike Perry <mikeperry-git@torproject.org>2022-02-22 19:28:34 +0000
commit6b2086773c7604e6db331c13cb44cd756022ab00 (patch)
treef6a9aeba0d8ce32507058e85ab6ba1808386a925 /src/test/test_ntor_v3.c
parentf3283266c2e8425725d62fc4796cc0633e0c2f37 (diff)
downloadtor-6b2086773c7604e6db331c13cb44cd756022ab00.tar.gz
tor-6b2086773c7604e6db331c13cb44cd756022ab00.zip
Add test for congestion control negotiation logic.
Diffstat (limited to 'src/test/test_ntor_v3.c')
-rw-r--r--src/test/test_ntor_v3.c139
1 files changed, 139 insertions, 0 deletions
diff --git a/src/test/test_ntor_v3.c b/src/test/test_ntor_v3.c
index 096ac6668f..1d06403076 100644
--- a/src/test/test_ntor_v3.c
+++ b/src/test/test_ntor_v3.c
@@ -10,6 +10,12 @@
#include "lib/crypt_ops/crypto_curve25519.h"
#include "lib/crypt_ops/crypto_ed25519.h"
#include "core/crypto/onion_ntor_v3.h"
+#include "core/crypto/onion_crypto.h"
+#include "core/or/extend_info_st.h"
+#include "core/or/crypt_path_st.h"
+#define TOR_CONGESTION_CONTROL_PRIVATE
+#include "core/or/congestion_control_common.h"
+#include "app/config/config.h"
#define unhex(arry, s) \
{ tt_int_op(sizeof(arry), OP_EQ, \
@@ -166,7 +172,140 @@ test_ntor3_testvecs(void *arg)
dimap_free(private_keys, NULL);
}
+static void
+run_full_handshake(circuit_params_t *serv_params_in,
+ circuit_params_t *client_params_out,
+ circuit_params_t *serv_params_out)
+{
+ extend_info_t info = {0};
+ uint8_t onionskin[CELL_PAYLOAD_SIZE];
+ int onionskin_len = 0;
+ int reply_len = 0;
+ onion_handshake_state_t handshake_state = {0};
+ server_onion_keys_t server_keys = {0};
+ curve25519_keypair_t relay_onion_key;
+ uint8_t serv_reply[CELL_PAYLOAD_SIZE];
+ uint8_t serv_keys[100];
+ uint8_t rend_nonce[DIGEST_LEN];
+ uint8_t client_keys[CELL_PAYLOAD_SIZE];
+ uint8_t rend_auth[DIGEST_LEN];
+
+ info.exit_supports_congestion_control = 1;
+
+ unhex(relay_onion_key.seckey.secret_key,
+ "4051daa5921cfa2a1c27b08451324919538e79e788a81b38cbed097a5dff454a");
+ unhex(relay_onion_key.pubkey.public_key,
+ "f8307a2bc1870b00b828bb74dbb8fd88e632a6375ab3bcd1ae706aaa8b6cdd1d");
+
+ memcpy(&info.curve25519_onion_key,
+ &relay_onion_key.pubkey, sizeof(info.curve25519_onion_key));
+ unhex(info.ed_identity.pubkey,
+ "9fad2af287ef942632833d21f946c6260c33fae6172b60006e86e4a6911753a2");
+
+ memcpy(&server_keys.my_ed_identity, &info.ed_identity,
+ sizeof(server_keys.my_ed_identity));
+
+ dimap_add_entry(&server_keys.curve25519_key_map,
+ relay_onion_key.pubkey.public_key,
+ &relay_onion_key);
+
+ onionskin_len = onion_skin_create(ONION_HANDSHAKE_TYPE_NTOR_V3, &info,
+ &handshake_state, onionskin,
+ sizeof(onionskin));
+ tt_int_op(onionskin_len, OP_NE, -1);
+
+ server_keys.junk_keypair = &handshake_state.u.ntor3->client_keypair;
+
+ reply_len = onion_skin_server_handshake(ONION_HANDSHAKE_TYPE_NTOR_V3,
+ onionskin, onionskin_len,
+ &server_keys, serv_params_in,
+ serv_reply, sizeof(serv_reply),
+ serv_keys, sizeof(serv_keys),
+ rend_nonce, serv_params_out);
+ tt_int_op(reply_len, OP_NE, -1);
+
+ tt_int_op(onion_skin_client_handshake(ONION_HANDSHAKE_TYPE_NTOR_V3,
+ &handshake_state,
+ serv_reply, reply_len,
+ client_keys, sizeof(client_keys),
+ rend_auth, client_params_out,
+ NULL), OP_EQ, 0);
+
+ done:
+ dimap_free(server_keys.curve25519_key_map, NULL);
+ ntor3_handshake_state_free(handshake_state.u.ntor3);
+
+ return;
+}
+
+/**
+ * Test congestion control negotiation logic.
+ *
+ * This tests that congestion control is only enabled when both
+ * client and server agree, via consensus param or torrc.
+ *
+ * It also tests that when they agree, they agree on the server's
+ * version of sendme_inc.
+ */
+static void
+test_ntor3_handshake(void *arg)
+{
+ (void)arg;
+ circuit_params_t client_params, serv_params, serv_ns_params;
+
+ serv_ns_params.sendme_inc_cells = congestion_control_sendme_inc();
+
+ /* client off, serv off -> off */
+ serv_ns_params.cc_enabled = 0;
+ run_full_handshake(&serv_ns_params, &client_params, &serv_params);
+ tt_int_op(client_params.cc_enabled, OP_EQ, 0);
+ tt_int_op(serv_params.cc_enabled, OP_EQ, 0);
+
+ /* client off, serv on -> off */
+ serv_ns_params.cc_enabled = 1;
+ run_full_handshake(&serv_ns_params, &client_params, &serv_params);
+ tt_int_op(client_params.cc_enabled, OP_EQ, 0);
+ tt_int_op(serv_params.cc_enabled, OP_EQ, 0);
+
+ /* client off + param, serv on -> on */
+ serv_ns_params.cc_enabled = 1;
+ get_options_mutable()->AlwaysCongestionControl = 1;
+ run_full_handshake(&serv_ns_params, &client_params, &serv_params);
+ tt_int_op(client_params.cc_enabled, OP_EQ, 1);
+ tt_int_op(serv_params.cc_enabled, OP_EQ, 1);
+
+ /* client on, serv off -> off */
+ serv_ns_params.cc_enabled = 0;
+ congestion_control_set_cc_enabled();
+ run_full_handshake(&serv_ns_params, &client_params, &serv_params);
+ tt_int_op(client_params.cc_enabled, OP_EQ, 0);
+ tt_int_op(serv_params.cc_enabled, OP_EQ, 0);
+
+ /* client on, serv on -> on */
+ serv_ns_params.cc_enabled = 1;
+ run_full_handshake(&serv_ns_params, &client_params, &serv_params);
+ tt_int_op(client_params.cc_enabled, OP_EQ, 1);
+ tt_int_op(serv_params.cc_enabled, OP_EQ, 1);
+
+ /* client on, serv on, sendme_inc diff -> serv sendme_inc */
+ serv_ns_params.cc_enabled = 1;
+ serv_ns_params.sendme_inc_cells += 1;
+ run_full_handshake(&serv_ns_params, &client_params, &serv_params);
+ tt_int_op(client_params.cc_enabled, OP_EQ, 1);
+ tt_int_op(serv_params.cc_enabled, OP_EQ, 1);
+ tt_int_op(serv_params.sendme_inc_cells, OP_EQ,
+ client_params.sendme_inc_cells);
+ tt_int_op(client_params.sendme_inc_cells, OP_EQ,
+ serv_ns_params.sendme_inc_cells);
+ tt_int_op(client_params.sendme_inc_cells, OP_NE,
+ congestion_control_sendme_inc());
+
+ done:
+ return;
+}
+
struct testcase_t ntor_v3_tests[] = {
{ "testvecs", test_ntor3_testvecs, 0, NULL, NULL, },
+ { "handshake_negtotiation", test_ntor3_handshake, 0, NULL, NULL, },
END_OF_TESTCASES,
};