tor

The Tor anonymity network
git clone https://git.dasho.dev/tor.git
Log | Files | Refs | README | LICENSE

test_ntor_v3.c (11856B)


      1 /* Copyright (c) 2001-2004, Roger Dingledine.
      2 * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
      3 * Copyright (c) 2007-2021, The Tor Project, Inc. */
      4 /* See LICENSE for licensing information */
      5 
      6 #include "orconfig.h"
      7 #define ONION_NTOR_V3_PRIVATE
      8 #include "core/or/or.h"
      9 #include "test/test.h"
     10 #include "lib/crypt_ops/crypto_curve25519.h"
     11 #include "lib/crypt_ops/crypto_ed25519.h"
     12 #include "core/crypto/onion_ntor_v3.h"
     13 #include "core/crypto/onion_crypto.h"
     14 #include "core/or/extend_info_st.h"
     15 #include "core/or/crypt_path_st.h"
     16 #define TOR_CONGESTION_CONTROL_PRIVATE
     17 #define TOR_CONGESTION_CONTROL_COMMON_PRIVATE
     18 #include "core/or/congestion_control_st.h"
     19 #include "core/or/congestion_control_common.h"
     20 #include "app/config/config.h"
     21 
     22 #define unhex(arry, s)                                                  \
     23  { tt_int_op(sizeof(arry), OP_EQ,                                      \
     24              base16_decode((char*)arry, sizeof(arry), s, strlen(s)));  \
     25  }
     26 
     27 static void
     28 test_ntor3_testvecs(void *arg)
     29 {
     30  (void)arg;
     31  char *mem_op_hex_tmp = NULL; // temp val to make test_memeq_hex work.
     32 
     33  ntor3_server_handshake_state_t *relay_state = NULL;
     34  uint8_t *onion_skin = NULL;
     35  size_t onion_skin_len;
     36  ntor3_handshake_state_t *client_state = NULL;
     37  uint8_t *cm = NULL, *sm = NULL;
     38  size_t cm_len, sm_len;
     39  di_digest256_map_t *private_keys = NULL;
     40  uint8_t *server_handshake = NULL;
     41  size_t server_handshake_len;
     42 
     43  // Test vectors from python implementation, confirmed with rust
     44  // implementation.
     45  curve25519_keypair_t relay_keypair_b;
     46  curve25519_keypair_t client_keypair_x;
     47  curve25519_keypair_t relay_keypair_y;
     48  ed25519_public_key_t relay_id;
     49 
     50  unhex(relay_keypair_b.seckey.secret_key,
     51        "4051daa5921cfa2a1c27b08451324919538e79e788a81b38cbed097a5dff454a");
     52  unhex(relay_keypair_b.pubkey.public_key,
     53        "f8307a2bc1870b00b828bb74dbb8fd88e632a6375ab3bcd1ae706aaa8b6cdd1d");
     54  unhex(relay_id.pubkey,
     55        "9fad2af287ef942632833d21f946c6260c33fae6172b60006e86e4a6911753a2");
     56  unhex(client_keypair_x.seckey.secret_key,
     57        "b825a3719147bcbe5fb1d0b0fcb9c09e51948048e2e3283d2ab7b45b5ef38b49");
     58  unhex(client_keypair_x.pubkey.public_key,
     59        "252fe9ae91264c91d4ecb8501f79d0387e34ad8ca0f7c995184f7d11d5da4f46");
     60  unhex(relay_keypair_y.seckey.secret_key,
     61        "4865a5b7689dafd978f529291c7171bc159be076b92186405d13220b80e2a053");
     62  unhex(relay_keypair_y.pubkey.public_key,
     63        "4bf4814326fdab45ad5184f5518bd7fae25dc59374062698201a50a22954246d");
     64 
     65  uint8_t client_message[11];
     66  uint8_t verification[5];
     67  unhex(client_message, "68656c6c6f20776f726c64");
     68  unhex(verification, "78797a7a79");
     69 
     70  // ========= Client handshake 1.
     71 
     72  onion_skin_ntor3_create_nokeygen(
     73                    &client_keypair_x,
     74                    &relay_id,
     75                    &relay_keypair_b.pubkey,
     76                    verification,
     77                    sizeof(verification),
     78                    client_message,
     79                    sizeof(client_message),
     80                    &client_state,
     81                    &onion_skin,
     82                    &onion_skin_len);
     83 
     84  const char expect_client_handshake[] = "9fad2af287ef942632833d21f946c6260c"
     85    "33fae6172b60006e86e4a6911753a2f8307a2bc1870b00b828bb74dbb8fd88e632a6375"
     86    "ab3bcd1ae706aaa8b6cdd1d252fe9ae91264c91d4ecb8501f79d0387e34ad8ca0f7c995"
     87    "184f7d11d5da4f463bebd9151fd3b47c180abc9e044d53565f04d82bbb3bebed3d06cea"
     88    "65db8be9c72b68cd461942088502f67";
     89 
     90  tt_int_op(onion_skin_len, OP_EQ, strlen(expect_client_handshake)/2);
     91  test_memeq_hex(onion_skin, expect_client_handshake);
     92 
     93  // ========= Relay handshake.
     94 
     95  dimap_add_entry(&private_keys,
     96                  relay_keypair_b.pubkey.public_key,
     97                  &relay_keypair_b);
     98 
     99  int r = onion_skin_ntor3_server_handshake_part1(
    100                    private_keys,
    101                    &client_keypair_x,
    102                    &relay_id,
    103                    onion_skin,
    104                    onion_skin_len,
    105                    verification,
    106                    sizeof(verification),
    107                    &cm,
    108                    &cm_len,
    109                    &relay_state);
    110  tt_int_op(r, OP_EQ, 0);
    111  tt_int_op(cm_len, OP_EQ, sizeof(client_message));
    112  tt_mem_op(cm, OP_EQ, client_message, cm_len);
    113 
    114  uint8_t server_message[10];
    115  unhex(server_message, "486f6c61204d756e646f");
    116 
    117  uint8_t server_keys[256];
    118  onion_skin_ntor3_server_handshake_part2_nokeygen(
    119                    &relay_keypair_y,
    120                    relay_state,
    121                    verification,
    122                    sizeof(verification),
    123                    server_message,
    124                    sizeof(server_message),
    125                    &server_handshake,
    126                    &server_handshake_len,
    127                    server_keys,
    128                    sizeof(server_keys));
    129 
    130  const char expect_server_handshake[] = "4bf4814326fdab45ad5184f5518bd7fae25"
    131    "dc59374062698201a50a22954246d2fc5f8773ca824542bc6cf6f57c7c29bbf4e5476461"
    132    "ab130c5b18ab0a91276651202c3e1e87c0d32054c";
    133  tt_int_op(server_handshake_len, OP_EQ, strlen(expect_server_handshake)/2);
    134  test_memeq_hex(server_handshake, expect_server_handshake);
    135 
    136  uint8_t expect_keys[256];
    137  unhex(expect_keys, "9c19b631fd94ed86a817e01f6c80b0743a43f5faebd39cfaa8b00f"
    138        "a8bcc65c3bfeaa403d91acbd68a821bf6ee8504602b094a254392a07737d5662768"
    139        "c7a9fb1b2814bb34780eaee6e867c773e28c212ead563e98a1cd5d5b4576f5ee61c"
    140        "59bde025ff2851bb19b721421694f263818e3531e43a9e4e3e2c661e2ad547d8984"
    141        "caa28ebecd3e4525452299be26b9185a20a90ce1eac20a91f2832d731b54502b097"
    142        "49b5a2a2949292f8cfcbeffb790c7790ed935a9d251e7e336148ea83b063a5618fc"
    143        "ff674a44581585fd22077ca0e52c59a24347a38d1a1ceebddbf238541f226b8f88d"
    144        "0fb9c07a1bcd2ea764bbbb5dacdaf5312a14c0b9e4f06309b0333b4a");
    145  tt_mem_op(server_keys, OP_EQ, expect_keys, 256);
    146 
    147  // ===== Client handshake 2
    148 
    149  uint8_t client_keys[256];
    150  r = onion_ntor3_client_handshake(
    151                  client_state,
    152                  server_handshake,
    153                  server_handshake_len,
    154                  verification,
    155                  sizeof(verification),
    156                  client_keys,
    157                  sizeof(client_keys),
    158                  &sm,
    159                  &sm_len);
    160 
    161  tt_int_op(r, OP_EQ, 0);
    162  tt_int_op(sm_len, OP_EQ, sizeof(server_message));
    163  tt_mem_op(sm, OP_EQ, server_message, sizeof(server_message));
    164  tt_mem_op(client_keys, OP_EQ, server_keys, 256);
    165 
    166 done:
    167  tor_free(onion_skin);
    168  tor_free(server_handshake);
    169  tor_free(mem_op_hex_tmp);
    170  ntor3_handshake_state_free(client_state);
    171  ntor3_server_handshake_state_free(relay_state);
    172  tor_free(cm);
    173  tor_free(sm);
    174  dimap_free(private_keys, NULL);
    175 }
    176 
    177 static void
    178 run_full_handshake(circuit_params_t *serv_params_in,
    179                   circuit_params_t *client_params_out,
    180                   circuit_params_t *serv_params_out)
    181 {
    182  extend_info_t info = {0};
    183  uint8_t onionskin[CELL_PAYLOAD_SIZE];
    184  int onionskin_len = 0;
    185  int reply_len = 0;
    186  onion_handshake_state_t handshake_state = {0};
    187  server_onion_keys_t server_keys = {0};
    188  curve25519_keypair_t relay_onion_key;
    189  uint8_t serv_reply[CELL_PAYLOAD_SIZE];
    190  uint8_t serv_keys[100];
    191  uint8_t rend_nonce[DIGEST_LEN];
    192  uint8_t client_keys[CELL_PAYLOAD_SIZE];
    193  uint8_t rend_auth[DIGEST_LEN];
    194 
    195  info.supports_ntor_v3 = true;
    196  info.exit_supports_congestion_control = 1;
    197 
    198  unhex(relay_onion_key.seckey.secret_key,
    199        "4051daa5921cfa2a1c27b08451324919538e79e788a81b38cbed097a5dff454a");
    200  unhex(relay_onion_key.pubkey.public_key,
    201        "f8307a2bc1870b00b828bb74dbb8fd88e632a6375ab3bcd1ae706aaa8b6cdd1d");
    202 
    203  memcpy(&info.curve25519_onion_key,
    204         &relay_onion_key.pubkey, sizeof(info.curve25519_onion_key));
    205  unhex(info.ed_identity.pubkey,
    206        "9fad2af287ef942632833d21f946c6260c33fae6172b60006e86e4a6911753a2");
    207 
    208  memcpy(&server_keys.my_ed_identity, &info.ed_identity,
    209         sizeof(server_keys.my_ed_identity));
    210 
    211  dimap_add_entry(&server_keys.curve25519_key_map,
    212                  relay_onion_key.pubkey.public_key,
    213                  &relay_onion_key);
    214 
    215  onionskin_len = onion_skin_create(ONION_HANDSHAKE_TYPE_NTOR_V3, &info,
    216                    &handshake_state, onionskin,
    217                    sizeof(onionskin));
    218  tt_int_op(onionskin_len, OP_NE, -1);
    219 
    220  server_keys.junk_keypair = &handshake_state.u.ntor3->client_keypair;
    221 
    222  size_t serv_keylen = sizeof(serv_keys);
    223  size_t client_keylen = sizeof(serv_keys);
    224  reply_len = onion_skin_server_handshake(ONION_HANDSHAKE_TYPE_NTOR_V3,
    225                              onionskin, onionskin_len,
    226                              &server_keys, serv_params_in,
    227                              serv_reply, sizeof(serv_reply),
    228                              serv_keys, &serv_keylen,
    229                              rend_nonce, serv_params_out);
    230  tt_int_op(reply_len, OP_NE, -1);
    231 
    232  tt_int_op(onion_skin_client_handshake(ONION_HANDSHAKE_TYPE_NTOR_V3,
    233                              &handshake_state,
    234                              serv_reply, reply_len,
    235                              client_keys, &client_keylen,
    236                              rend_auth, client_params_out,
    237                              NULL), OP_EQ, 0);
    238 
    239 done:
    240  dimap_free(server_keys.curve25519_key_map, NULL);
    241  ntor3_handshake_state_free(handshake_state.u.ntor3);
    242 
    243  return;
    244 }
    245 
    246 /**
    247 * Test congestion control negotiation logic.
    248 *
    249 * This tests that congestion control is only enabled when both
    250 * client and server agree, via consensus param or torrc.
    251 *
    252 * It also tests that when they agree, they agree on the server's
    253 * version of sendme_inc.
    254 */
    255 static void
    256 test_ntor3_handshake(void *arg)
    257 {
    258  (void)arg;
    259  circuit_params_t client_params, serv_params, serv_ns_params;
    260 
    261  serv_ns_params.sendme_inc_cells = congestion_control_sendme_inc();
    262 
    263  /* client off, serv off -> off */
    264  serv_ns_params.cc_enabled = 0;
    265  run_full_handshake(&serv_ns_params, &client_params, &serv_params);
    266  tt_int_op(client_params.cc_enabled, OP_EQ, 0);
    267  tt_int_op(serv_params.cc_enabled, OP_EQ, 0);
    268 
    269  /* client off, serv on -> off */
    270  congestion_control_set_cc_disabled();
    271  serv_ns_params.cc_enabled = 1;
    272  run_full_handshake(&serv_ns_params, &client_params, &serv_params);
    273  tt_int_op(client_params.cc_enabled, OP_EQ, 0);
    274  tt_int_op(serv_params.cc_enabled, OP_EQ, 0);
    275 
    276  /* client off + param, serv on -> on */
    277  serv_ns_params.cc_enabled = 1;
    278  get_options_mutable()->AlwaysCongestionControl = 1;
    279  run_full_handshake(&serv_ns_params, &client_params, &serv_params);
    280  tt_int_op(client_params.cc_enabled, OP_EQ, 1);
    281  tt_int_op(serv_params.cc_enabled, OP_EQ, 1);
    282 
    283  /* client on, serv off -> off */
    284  serv_ns_params.cc_enabled = 0;
    285  congestion_control_set_cc_enabled();
    286  run_full_handshake(&serv_ns_params, &client_params, &serv_params);
    287  tt_int_op(client_params.cc_enabled, OP_EQ, 0);
    288  tt_int_op(serv_params.cc_enabled, OP_EQ, 0);
    289 
    290  /* client on, serv on -> on */
    291  serv_ns_params.cc_enabled = 1;
    292  run_full_handshake(&serv_ns_params, &client_params, &serv_params);
    293  tt_int_op(client_params.cc_enabled, OP_EQ, 1);
    294  tt_int_op(serv_params.cc_enabled, OP_EQ, 1);
    295 
    296  /* client on, serv on, sendme_inc diff -> serv sendme_inc */
    297  serv_ns_params.cc_enabled = 1;
    298  serv_ns_params.sendme_inc_cells += 1;
    299  run_full_handshake(&serv_ns_params, &client_params, &serv_params);
    300  tt_int_op(client_params.cc_enabled, OP_EQ, 1);
    301  tt_int_op(serv_params.cc_enabled, OP_EQ, 1);
    302  tt_int_op(serv_params.sendme_inc_cells, OP_EQ,
    303            client_params.sendme_inc_cells);
    304  tt_int_op(client_params.sendme_inc_cells, OP_EQ,
    305            serv_ns_params.sendme_inc_cells);
    306  tt_int_op(client_params.sendme_inc_cells, OP_NE,
    307            congestion_control_sendme_inc());
    308 
    309 done:
    310  return;
    311 }
    312 
    313 struct testcase_t ntor_v3_tests[] = {
    314  { "testvecs", test_ntor3_testvecs, 0, NULL, NULL, },
    315  { "handshake_negtotiation", test_ntor3_handshake, 0, NULL, NULL, },
    316  END_OF_TESTCASES,
    317 };