LCOV - code coverage report
Current view: top level - test - test_hs_intropoint.c (source / functions) Hit Total Coverage
Test: lcov.info Lines: 516 529 97.5 %
Date: 2021-11-24 03:28:48 Functions: 21 23 91.3 %

          Line data    Source code
       1             : /* Copyright (c) 2016-2021, The Tor Project, Inc. */
       2             : /* See LICENSE for licensing information */
       3             : 
       4             : /**
       5             :  * \file test_hs_service.c
       6             :  * \brief Test hidden service functionality.
       7             :  */
       8             : 
       9             : #define HS_SERVICE_PRIVATE
      10             : #define HS_INTROPOINT_PRIVATE
      11             : #define RENDSERVICE_PRIVATE
      12             : #define CIRCUITLIST_PRIVATE
      13             : 
      14             : #include "test/test.h"
      15             : #include "test/log_test_helpers.h"
      16             : #include "lib/crypt_ops/crypto_rand.h"
      17             : 
      18             : #include "core/or/or.h"
      19             : #include "core/or/channel.h"
      20             : #include "core/or/circuitlist.h"
      21             : #include "core/or/circuituse.h"
      22             : #include "ht.h"
      23             : #include "core/or/relay.h"
      24             : 
      25             : #include "feature/hs/hs_cell.h"
      26             : #include "feature/hs/hs_circuitmap.h"
      27             : #include "feature/hs/hs_common.h"
      28             : #include "feature/hs/hs_config.h"
      29             : #include "feature/hs/hs_dos.h"
      30             : #include "feature/hs/hs_intropoint.h"
      31             : #include "feature/hs/hs_service.h"
      32             : 
      33             : #include "core/or/or_circuit_st.h"
      34             : 
      35             : /* Trunnel. */
      36             : #include "trunnel/hs/cell_establish_intro.h"
      37             : #include "trunnel/hs/cell_introduce1.h"
      38             : #include "trunnel/hs/cell_common.h"
      39             : 
      40             : static size_t
      41           4 : new_establish_intro_cell(const char *circ_nonce,
      42             :                          trn_cell_establish_intro_t **cell_out)
      43             : {
      44           4 :   ssize_t cell_len = 0;
      45           4 :   uint8_t buf[RELAY_PAYLOAD_SIZE] = {0};
      46           4 :   trn_cell_establish_intro_t *cell = NULL;
      47           4 :   hs_service_intro_point_t *ip = NULL;
      48           4 :   hs_service_config_t config;
      49             : 
      50           4 :   memset(&config, 0, sizeof(config));
      51             : 
      52             :   /* Ensure that *cell_out is NULL such that we can use to check if we need to
      53             :    * free `cell` in case of an error. */
      54           4 :   *cell_out = NULL;
      55             : 
      56             :   /* Auth key pair is generated in the constructor so we are all set for
      57             :    * using this IP object. */
      58           4 :   ip = service_intro_point_new(NULL);
      59           4 :   tt_assert(ip);
      60           4 :   cell_len = hs_cell_build_establish_intro(circ_nonce, &config, ip, buf);
      61           4 :   tt_i64_op(cell_len, OP_GT, 0);
      62             : 
      63           4 :   cell_len = trn_cell_establish_intro_parse(&cell, buf, sizeof(buf));
      64           4 :   tt_i64_op(cell_len, OP_GT, 0);
      65           4 :   tt_assert(cell);
      66           4 :   *cell_out = cell;
      67             : 
      68           4 :  done:
      69           4 :   if (*cell_out == NULL)
      70           0 :     trn_cell_establish_intro_free(cell);
      71             : 
      72           4 :   service_intro_point_free(ip);
      73           4 :   return cell_len;
      74             : }
      75             : 
      76             : static ssize_t
      77           3 : new_establish_intro_encoded_cell(const char *circ_nonce, uint8_t *cell_out)
      78             : {
      79           3 :   ssize_t cell_len = 0;
      80           3 :   hs_service_intro_point_t *ip = NULL;
      81           3 :   hs_service_config_t config;
      82             : 
      83           3 :   memset(&config, 0, sizeof(config));
      84             : 
      85             :   /* Auth key pair is generated in the constructor so we are all set for
      86             :    * using this IP object. */
      87           3 :   ip = service_intro_point_new(NULL);
      88           3 :   tt_assert(ip);
      89           3 :   cell_len = hs_cell_build_establish_intro(circ_nonce, &config, ip, cell_out);
      90           3 :   tt_i64_op(cell_len, OP_GT, 0);
      91             : 
      92           3 :  done:
      93           3 :   service_intro_point_free(ip);
      94           3 :   return cell_len;
      95             : }
      96             : 
      97             : /* Mock function to avoid networking in unittests */
      98             : static int
      99           1 : mock_send_intro_established_cell(or_circuit_t *circ)
     100             : {
     101           1 :   (void) circ;
     102           1 :   return 0;
     103             : }
     104             : 
     105             : static int
     106           8 : mock_relay_send_command_from_edge(streamid_t stream_id, circuit_t *circ,
     107             :                                   uint8_t relay_command, const char *payload,
     108             :                                   size_t payload_len,
     109             :                                   crypt_path_t *cpath_layer,
     110             :                                   const char *filename, int lineno)
     111             : {
     112           8 :   (void) stream_id;
     113           8 :   (void) circ;
     114           8 :   (void) relay_command;
     115           8 :   (void) payload;
     116           8 :   (void) payload_len;
     117           8 :   (void) cpath_layer;
     118           8 :   (void) filename;
     119           8 :   (void) lineno;
     120           8 :   return 0;
     121             : }
     122             : 
     123             : static or_circuit_t *
     124           4 : helper_create_intro_circuit(void)
     125             : {
     126           4 :   or_circuit_t *circ = or_circuit_new(0, NULL);
     127           4 :   tt_assert(circ);
     128           4 :   circuit_change_purpose(TO_CIRCUIT(circ), CIRCUIT_PURPOSE_OR);
     129           4 :   token_bucket_ctr_init(&circ->introduce2_bucket, 100, 100,
     130           4 :                         (uint32_t) approx_time());
     131           4 :  done:
     132           4 :   return circ;
     133             : }
     134             : 
     135             : static trn_cell_introduce1_t *
     136           2 : helper_create_introduce1_cell(void)
     137             : {
     138           2 :   trn_cell_introduce1_t *cell = NULL;
     139           2 :   ed25519_keypair_t auth_key_kp;
     140             : 
     141             :   /* Generate the auth_key of the cell. */
     142           2 :   if (ed25519_keypair_generate(&auth_key_kp, 0) < 0) {
     143           0 :     goto err;
     144             :   }
     145             : 
     146           2 :   cell = trn_cell_introduce1_new();
     147           2 :   tt_assert(cell);
     148             : 
     149             :   /* Set the auth key. */
     150             :   {
     151           2 :     size_t auth_key_len = sizeof(auth_key_kp.pubkey);
     152           2 :     trn_cell_introduce1_set_auth_key_type(cell,
     153             :                                      TRUNNEL_HS_INTRO_AUTH_KEY_TYPE_ED25519);
     154           2 :     trn_cell_introduce1_set_auth_key_len(cell, auth_key_len);
     155           2 :     trn_cell_introduce1_setlen_auth_key(cell, auth_key_len);
     156           2 :     uint8_t *auth_key_ptr = trn_cell_introduce1_getarray_auth_key(cell);
     157           2 :     memcpy(auth_key_ptr, auth_key_kp.pubkey.pubkey, auth_key_len);
     158             :   }
     159             : 
     160             :   /* Set the cell extensions to none. */
     161             :   {
     162           2 :     trn_cell_extension_t *ext = trn_cell_extension_new();
     163           2 :     trn_cell_extension_set_num(ext, 0);
     164           2 :     trn_cell_introduce1_set_extensions(cell, ext);
     165             :   }
     166             : 
     167             :   /* Set the encrypted section to some data. */
     168             :   {
     169           2 :     size_t enc_len = 128;
     170           2 :     trn_cell_introduce1_setlen_encrypted(cell, enc_len);
     171           2 :     uint8_t *enc_ptr = trn_cell_introduce1_getarray_encrypted(cell);
     172           2 :     memset(enc_ptr, 'a', enc_len);
     173             :   }
     174             : 
     175           2 :   return cell;
     176           0 :  err:
     177           0 :  done:
     178           0 :   trn_cell_introduce1_free(cell);
     179           0 :   return NULL;
     180             : }
     181             : 
     182             : /* Try sending an ESTABLISH_INTRO cell on a circuit that is already an intro
     183             :  * point. Should fail. */
     184             : static void
     185           1 : test_establish_intro_wrong_purpose(void *arg)
     186             : {
     187           1 :   int retval;
     188           1 :   ssize_t cell_len = 0;
     189           1 :   char circ_nonce[DIGEST_LEN] = {0};
     190           1 :   uint8_t cell_body[RELAY_PAYLOAD_SIZE];
     191           1 :   or_circuit_t *intro_circ = or_circuit_new(0,NULL);
     192             : 
     193           1 :   (void)arg;
     194             : 
     195             :   /* Get the auth key of the intro point */
     196           1 :   crypto_rand(circ_nonce, sizeof(circ_nonce));
     197           1 :   memcpy(intro_circ->rend_circ_nonce, circ_nonce, DIGEST_LEN);
     198             : 
     199             :   /* Set a bad circuit purpose!! :) */
     200           1 :   circuit_change_purpose(TO_CIRCUIT(intro_circ), CIRCUIT_PURPOSE_INTRO_POINT);
     201             : 
     202             :   /* Create outgoing ESTABLISH_INTRO cell and extract its payload so that we
     203             :      attempt to parse it. */
     204           1 :   cell_len = new_establish_intro_encoded_cell(circ_nonce, cell_body);
     205           1 :   tt_i64_op(cell_len, OP_GT, 0);
     206             : 
     207             :   /* Receive the cell. Should fail. */
     208           1 :   setup_full_capture_of_logs(LOG_INFO);
     209           1 :   retval = hs_intro_received_establish_intro(intro_circ, cell_body, cell_len);
     210           1 :   expect_log_msg_containing("Rejecting ESTABLISH_INTRO on non-OR circuit.");
     211           1 :   teardown_capture_of_logs();
     212           1 :   tt_int_op(retval, OP_EQ, -1);
     213             : 
     214           1 :  done:
     215           1 :   circuit_free_(TO_CIRCUIT(intro_circ));
     216           1 : }
     217             : 
     218             : /* Prepare a circuit for accepting an ESTABLISH_INTRO cell */
     219             : static void
     220          12 : helper_prepare_circ_for_intro(or_circuit_t *circ, const char *circ_nonce)
     221             : {
     222             :   /* Prepare the circuit for the incoming ESTABLISH_INTRO */
     223          12 :   circuit_change_purpose(TO_CIRCUIT(circ), CIRCUIT_PURPOSE_OR);
     224          12 :   memcpy(circ->rend_circ_nonce, circ_nonce, DIGEST_LEN);
     225          12 : }
     226             : 
     227             : /* Send an empty ESTABLISH_INTRO cell. Should fail. */
     228             : static void
     229           1 : test_establish_intro_wrong_keytype(void *arg)
     230             : {
     231           1 :   int retval;
     232           1 :   or_circuit_t *intro_circ = or_circuit_new(0,NULL);
     233           1 :   char circ_nonce[DIGEST_LEN] = {0};
     234             : 
     235           1 :   (void) arg;
     236             : 
     237             :   /* Get the auth key of the intro point */
     238           1 :   crypto_rand(circ_nonce, sizeof(circ_nonce));
     239           1 :   helper_prepare_circ_for_intro(intro_circ, circ_nonce);
     240             : 
     241             :   /* Receive the cell. Should fail. */
     242           1 :   setup_full_capture_of_logs(LOG_INFO);
     243           1 :   retval = hs_intro_received_establish_intro(intro_circ, (uint8_t *) "", 0);
     244           1 :   expect_log_msg_containing("Empty ESTABLISH_INTRO cell.");
     245           1 :   teardown_capture_of_logs();
     246           1 :   tt_int_op(retval, OP_EQ, -1);
     247             : 
     248           1 :  done:
     249           1 :   circuit_free_(TO_CIRCUIT(intro_circ));
     250           1 : }
     251             : 
     252             : /* Send an ESTABLISH_INTRO cell with an unknown auth key type. Should fail. */
     253             : static void
     254           1 : test_establish_intro_wrong_keytype2(void *arg)
     255             : {
     256           1 :   int retval;
     257           1 :   char circ_nonce[DIGEST_LEN] = {0};
     258           1 :   uint8_t cell_body[RELAY_PAYLOAD_SIZE];
     259           1 :   ssize_t cell_len = 0;
     260           1 :   or_circuit_t *intro_circ = or_circuit_new(0,NULL);
     261             : 
     262           1 :   (void) arg;
     263             : 
     264             :   /* Get the auth key of the intro point */
     265           1 :   crypto_rand(circ_nonce, sizeof(circ_nonce));
     266           1 :   helper_prepare_circ_for_intro(intro_circ, circ_nonce);
     267             : 
     268             :   /* Create outgoing ESTABLISH_INTRO cell and extract its payload so that we
     269             :    * attempt to parse it. */
     270           1 :   cell_len = new_establish_intro_encoded_cell(circ_nonce, cell_body);
     271           1 :   tt_i64_op(cell_len, OP_GT, 0);
     272             : 
     273             :   /* Mutate the auth key type! :) */
     274           1 :   cell_body[0] = 42;
     275             : 
     276             :   /* Receive the cell. Should fail. */
     277           1 :   setup_full_capture_of_logs(LOG_INFO);
     278           1 :   retval = hs_intro_received_establish_intro(intro_circ, cell_body, cell_len);
     279           1 :   expect_log_msg_containing("Unrecognized AUTH_KEY_TYPE 42.");
     280           1 :   teardown_capture_of_logs();
     281           1 :   tt_int_op(retval, OP_EQ, -1);
     282             : 
     283           1 :  done:
     284           1 :   circuit_free_(TO_CIRCUIT(intro_circ));
     285           1 : }
     286             : 
     287             : /* Send a legit ESTABLISH_INTRO cell but with a wrong MAC. Should fail. */
     288             : static void
     289           1 : test_establish_intro_wrong_mac(void *arg)
     290             : {
     291           1 :   int retval;
     292           1 :   char circ_nonce[DIGEST_LEN] = {0};
     293           1 :   ssize_t cell_len = 0;
     294           1 :   uint8_t cell_body[RELAY_PAYLOAD_SIZE];
     295           1 :   trn_cell_establish_intro_t *cell = NULL;
     296           1 :   or_circuit_t *intro_circ = or_circuit_new(0,NULL);
     297             : 
     298           1 :   (void) arg;
     299             : 
     300             :   /* Get the auth key of the intro point */
     301           1 :   crypto_rand(circ_nonce, sizeof(circ_nonce));
     302           1 :   helper_prepare_circ_for_intro(intro_circ, circ_nonce);
     303             : 
     304             :   /* Create outgoing ESTABLISH_INTRO cell and extract its payload so that we
     305             :    * attempt to parse it. */
     306           1 :   cell_len = new_establish_intro_cell(circ_nonce, &cell);
     307           1 :   tt_i64_op(cell_len, OP_GT, 0);
     308           1 :   tt_assert(cell);
     309             : 
     310             :   /* Mangle one byte of the MAC. */
     311           1 :   uint8_t *handshake_ptr =
     312           1 :     trn_cell_establish_intro_getarray_handshake_mac(cell);
     313           1 :   handshake_ptr[TRUNNEL_SHA3_256_LEN - 1]++;
     314             :   /* We need to resign the payload with that change. */
     315             :   {
     316           1 :     ed25519_signature_t sig;
     317           1 :     ed25519_keypair_t key_struct;
     318             :     /* New keypair for the signature since we don't have access to the private
     319             :      * key material generated earlier when creating the cell. */
     320           1 :     retval = ed25519_keypair_generate(&key_struct, 0);
     321           1 :     tt_int_op(retval, OP_EQ, 0);
     322           1 :     uint8_t *auth_key_ptr =
     323           1 :       trn_cell_establish_intro_getarray_auth_key(cell);
     324           1 :     memcpy(auth_key_ptr, key_struct.pubkey.pubkey, ED25519_PUBKEY_LEN);
     325             :     /* Encode payload so we can sign it. */
     326           1 :     cell_len = trn_cell_establish_intro_encode(cell_body, sizeof(cell_body),
     327             :                                                cell);
     328           1 :     tt_i64_op(cell_len, OP_GT, 0);
     329             : 
     330           1 :     retval = ed25519_sign_prefixed(&sig, cell_body,
     331             :                                    cell_len -
     332             :                                    (ED25519_SIG_LEN + sizeof(cell->sig_len)),
     333             :                                    ESTABLISH_INTRO_SIG_PREFIX, &key_struct);
     334           1 :     tt_int_op(retval, OP_EQ, 0);
     335             :     /* And write the signature to the cell */
     336           1 :     uint8_t *sig_ptr =
     337           1 :       trn_cell_establish_intro_getarray_sig(cell);
     338           1 :     memcpy(sig_ptr, sig.sig, cell->sig_len);
     339             :     /* Re-encode with the new signature. */
     340           1 :     cell_len = trn_cell_establish_intro_encode(cell_body, sizeof(cell_body),
     341             :                                                cell);
     342           1 :     tt_i64_op(cell_len, OP_GT, 0);
     343             :   }
     344             : 
     345             :   /* Receive the cell. Should fail because our MAC is wrong. */
     346           1 :   setup_full_capture_of_logs(LOG_INFO);
     347           1 :   retval = hs_intro_received_establish_intro(intro_circ, cell_body, cell_len);
     348           1 :   expect_log_msg_containing("ESTABLISH_INTRO handshake_auth not as expected");
     349           1 :   teardown_capture_of_logs();
     350           1 :   tt_int_op(retval, OP_EQ, -1);
     351             : 
     352           1 :  done:
     353           1 :   trn_cell_establish_intro_free(cell);
     354           1 :   circuit_free_(TO_CIRCUIT(intro_circ));
     355           1 : }
     356             : 
     357             : /* Send a legit ESTABLISH_INTRO cell but with a wrong auth key length. Should
     358             :  * fail. */
     359             : static void
     360           1 : test_establish_intro_wrong_auth_key_len(void *arg)
     361             : {
     362           1 :   int retval;
     363           1 :   char circ_nonce[DIGEST_LEN] = {0};
     364           1 :   uint8_t cell_body[RELAY_PAYLOAD_SIZE];
     365           1 :   ssize_t cell_len = 0;
     366           1 :   size_t bad_auth_key_len = ED25519_PUBKEY_LEN - 1;
     367           1 :   trn_cell_establish_intro_t *cell = NULL;
     368           1 :   or_circuit_t *intro_circ = or_circuit_new(0,NULL);
     369             : 
     370           1 :   (void) arg;
     371             : 
     372             :   /* Get the auth key of the intro point */
     373           1 :   crypto_rand(circ_nonce, sizeof(circ_nonce));
     374           1 :   helper_prepare_circ_for_intro(intro_circ, circ_nonce);
     375             : 
     376             :   /* Create outgoing ESTABLISH_INTRO cell and extract its payload so that we
     377             :    * attempt to parse it. */
     378           1 :   cell_len = new_establish_intro_cell(circ_nonce, &cell);
     379           1 :   tt_i64_op(cell_len, OP_GT, 0);
     380           1 :   tt_assert(cell);
     381             : 
     382             :   /* Mangle the auth key length. */
     383           1 :   trn_cell_establish_intro_set_auth_key_len(cell, bad_auth_key_len);
     384           1 :   trn_cell_establish_intro_setlen_auth_key(cell, bad_auth_key_len);
     385             :   /* Encode cell. */
     386           1 :   cell_len = trn_cell_establish_intro_encode(cell_body, sizeof(cell_body),
     387             :                                              cell);
     388           1 :   tt_int_op(cell_len, OP_GT, 0);
     389             : 
     390             :   /* Receive the cell. Should fail. */
     391           1 :   setup_full_capture_of_logs(LOG_INFO);
     392           1 :   retval = hs_intro_received_establish_intro(intro_circ, cell_body, cell_len);
     393           1 :   expect_log_msg_containing("ESTABLISH_INTRO auth key length is invalid");
     394           1 :   teardown_capture_of_logs();
     395           1 :   tt_int_op(retval, OP_EQ, -1);
     396             : 
     397           1 :  done:
     398           1 :   trn_cell_establish_intro_free(cell);
     399           1 :   circuit_free_(TO_CIRCUIT(intro_circ));
     400           1 : }
     401             : 
     402             : /* Send a legit ESTABLISH_INTRO cell but with a wrong sig length. Should
     403             :  * fail. */
     404             : static void
     405           1 : test_establish_intro_wrong_sig_len(void *arg)
     406             : {
     407           1 :   int retval;
     408           1 :   char circ_nonce[DIGEST_LEN] = {0};
     409           1 :   uint8_t cell_body[RELAY_PAYLOAD_SIZE];
     410           1 :   ssize_t cell_len = 0;
     411           1 :   size_t bad_sig_len = ED25519_SIG_LEN - 1;
     412           1 :   trn_cell_establish_intro_t *cell = NULL;
     413           1 :   or_circuit_t *intro_circ = or_circuit_new(0,NULL);
     414             : 
     415           1 :   (void) arg;
     416             : 
     417             :   /* Get the auth key of the intro point */
     418           1 :   crypto_rand(circ_nonce, sizeof(circ_nonce));
     419           1 :   helper_prepare_circ_for_intro(intro_circ, circ_nonce);
     420             : 
     421             :   /* Create outgoing ESTABLISH_INTRO cell and extract its payload so that we
     422             :    * attempt to parse it. */
     423           1 :   cell_len = new_establish_intro_cell(circ_nonce, &cell);
     424           1 :   tt_i64_op(cell_len, OP_GT, 0);
     425           1 :   tt_assert(cell);
     426             : 
     427             :   /* Mangle the signature length. */
     428           1 :   trn_cell_establish_intro_set_sig_len(cell, bad_sig_len);
     429           1 :   trn_cell_establish_intro_setlen_sig(cell, bad_sig_len);
     430             :   /* Encode cell. */
     431           1 :   cell_len = trn_cell_establish_intro_encode(cell_body, sizeof(cell_body),
     432             :                                              cell);
     433           1 :   tt_int_op(cell_len, OP_GT, 0);
     434             : 
     435             :   /* Receive the cell. Should fail. */
     436           1 :   setup_full_capture_of_logs(LOG_INFO);
     437           1 :   retval = hs_intro_received_establish_intro(intro_circ, cell_body, cell_len);
     438           1 :   expect_log_msg_containing("ESTABLISH_INTRO sig len is invalid");
     439           1 :   teardown_capture_of_logs();
     440           1 :   tt_int_op(retval, OP_EQ, -1);
     441             : 
     442           1 :  done:
     443           1 :   trn_cell_establish_intro_free(cell);
     444           1 :   circuit_free_(TO_CIRCUIT(intro_circ));
     445           1 : }
     446             : 
     447             : /* Send a legit ESTABLISH_INTRO cell but slightly change the signature. Should
     448             :  * fail. */
     449             : static void
     450           1 : test_establish_intro_wrong_sig(void *arg)
     451             : {
     452           1 :   int retval;
     453           1 :   char circ_nonce[DIGEST_LEN] = {0};
     454           1 :   uint8_t cell_body[RELAY_PAYLOAD_SIZE];
     455           1 :   ssize_t cell_len = 0;
     456           1 :   or_circuit_t *intro_circ = or_circuit_new(0,NULL);
     457             : 
     458           1 :   (void) arg;
     459             : 
     460             :   /* Get the auth key of the intro point */
     461           1 :   crypto_rand(circ_nonce, sizeof(circ_nonce));
     462           1 :   helper_prepare_circ_for_intro(intro_circ, circ_nonce);
     463             : 
     464             :   /* Create outgoing ESTABLISH_INTRO cell and extract its payload so that we
     465             :      attempt to parse it. */
     466           1 :   cell_len = new_establish_intro_encoded_cell(circ_nonce, cell_body);
     467           1 :   tt_i64_op(cell_len, OP_GT, 0);
     468             : 
     469             :   /* Mutate the last byte (signature)! :) */
     470           1 :   cell_body[cell_len - 1]++;
     471             : 
     472             :   /* Receive the cell. Should fail. */
     473           1 :   setup_full_capture_of_logs(LOG_INFO);
     474           1 :   retval = hs_intro_received_establish_intro(intro_circ, cell_body,
     475             :                                              (size_t)cell_len);
     476           1 :   expect_log_msg_containing("Failed to verify ESTABLISH_INTRO cell.");
     477           1 :   teardown_capture_of_logs();
     478           1 :   tt_int_op(retval, OP_EQ, -1);
     479             : 
     480           1 :  done:
     481           1 :   circuit_free_(TO_CIRCUIT(intro_circ));
     482           1 : }
     483             : 
     484             : /* Helper function: Send a well-formed v3 ESTABLISH_INTRO cell to
     485             :  * <b>intro_circ</b>. Return the cell. */
     486             : static trn_cell_establish_intro_t *
     487           1 : helper_establish_intro_v3(or_circuit_t *intro_circ)
     488             : {
     489           1 :   int retval;
     490           1 :   char circ_nonce[DIGEST_LEN] = {0};
     491           1 :   uint8_t cell_body[RELAY_PAYLOAD_SIZE];
     492           1 :   ssize_t cell_len = 0;
     493           1 :   trn_cell_establish_intro_t *cell = NULL;
     494             : 
     495           1 :   tt_assert(intro_circ);
     496             : 
     497             :   /* Prepare the circuit for the incoming ESTABLISH_INTRO */
     498           1 :   crypto_rand(circ_nonce, sizeof(circ_nonce));
     499           1 :   helper_prepare_circ_for_intro(intro_circ, circ_nonce);
     500             : 
     501             :   /* Create outgoing ESTABLISH_INTRO cell and extract its payload so that we
     502             :    * attempt to parse it. */
     503           1 :   cell_len = new_establish_intro_cell(circ_nonce, &cell);
     504           1 :   tt_i64_op(cell_len, OP_GT, 0);
     505           1 :   tt_assert(cell);
     506           1 :   cell_len = trn_cell_establish_intro_encode(cell_body, sizeof(cell_body),
     507             :                                              cell);
     508           1 :   tt_int_op(cell_len, OP_GT, 0);
     509             : 
     510             :   /* Receive the cell */
     511           1 :   retval = hs_intro_received_establish_intro(intro_circ, cell_body,
     512             :                                              (size_t) cell_len);
     513           1 :   tt_int_op(retval, OP_EQ, 0);
     514             : 
     515           1 :  done:
     516           1 :   return cell;
     517             : }
     518             : 
     519             : /* Helper function: test circuitmap free_all function outside of
     520             :  * test_intro_point_registration to prevent Coverity from seeing a
     521             :  * double free if the assertion hypothetically fails.
     522             :  */
     523             : static void
     524           1 : test_circuitmap_free_all(void)
     525             : {
     526           1 :   hs_circuitmap_ht *the_hs_circuitmap = NULL;
     527             : 
     528           1 :   the_hs_circuitmap = get_hs_circuitmap();
     529           1 :   tt_assert(the_hs_circuitmap);
     530           1 :   hs_circuitmap_free_all();
     531           1 :   the_hs_circuitmap = get_hs_circuitmap();
     532           1 :   tt_ptr_op(the_hs_circuitmap, OP_EQ, NULL);
     533           1 :  done:
     534           1 :   ;
     535           1 : }
     536             : 
     537             : /** Successfully register a v3 intro point. Ensure that HS
     538             :  *  circuitmap is maintained properly. */
     539             : static void
     540           1 : test_intro_point_registration(void *arg)
     541             : {
     542           1 :   hs_circuitmap_ht *the_hs_circuitmap = NULL;
     543             : 
     544           1 :   or_circuit_t *intro_circ = NULL;
     545           1 :   trn_cell_establish_intro_t *establish_intro_cell = NULL;
     546           1 :   ed25519_public_key_t auth_key;
     547             : 
     548           1 :   or_circuit_t *returned_intro_circ = NULL;
     549             : 
     550           1 :   (void) arg;
     551             : 
     552           1 :   MOCK(hs_intro_send_intro_established_cell, mock_send_intro_established_cell);
     553             : 
     554           1 :   hs_circuitmap_init();
     555             : 
     556             :   /* Check that the circuitmap is currently empty */
     557             :   {
     558           1 :     the_hs_circuitmap = get_hs_circuitmap();
     559           1 :     tt_assert(the_hs_circuitmap);
     560           1 :     tt_int_op(0, OP_EQ, HT_SIZE(the_hs_circuitmap));
     561             :     /* Do a circuitmap query in any case */
     562           1 :     returned_intro_circ =hs_circuitmap_get_intro_circ_v3_relay_side(&auth_key);
     563           1 :     tt_ptr_op(returned_intro_circ, OP_EQ, NULL);
     564             :   }
     565             : 
     566             :   /* Create a v3 intro point */
     567             :   {
     568           1 :     intro_circ = or_circuit_new(0, NULL);
     569           1 :     tt_assert(intro_circ);
     570           1 :     establish_intro_cell = helper_establish_intro_v3(intro_circ);
     571             : 
     572             :     /* Check that the intro point was registered on the HS circuitmap */
     573           1 :     the_hs_circuitmap = get_hs_circuitmap();
     574           1 :     tt_assert(the_hs_circuitmap);
     575           1 :     tt_int_op(1, OP_EQ, HT_SIZE(the_hs_circuitmap));
     576           1 :     get_auth_key_from_cell(&auth_key, RELAY_COMMAND_ESTABLISH_INTRO,
     577             :                            establish_intro_cell);
     578           1 :     returned_intro_circ =
     579           1 :       hs_circuitmap_get_intro_circ_v3_relay_side(&auth_key);
     580           1 :     tt_ptr_op(intro_circ, OP_EQ, returned_intro_circ);
     581             :   }
     582             : 
     583             :   /* XXX Continue test and try to register a second v3 intro point with the
     584             :    * same auth key. Make sure that old intro circuit gets closed. */
     585             : 
     586           1 :  done:
     587           1 :   circuit_free_(TO_CIRCUIT(intro_circ));
     588           1 :   trn_cell_establish_intro_free(establish_intro_cell);
     589           1 :   test_circuitmap_free_all();
     590             : 
     591           1 :   UNMOCK(hs_intro_send_intro_established_cell);
     592           1 : }
     593             : 
     594             : static void
     595           1 : test_introduce1_suitable_circuit(void *arg)
     596             : {
     597           1 :   int ret;
     598           1 :   or_circuit_t *circ = NULL;
     599             : 
     600           1 :   (void) arg;
     601             : 
     602             :   /* Valid suitable circuit. */
     603             :   {
     604           1 :     circ = or_circuit_new(0, NULL);
     605           1 :     circuit_change_purpose(TO_CIRCUIT(circ), CIRCUIT_PURPOSE_OR);
     606           1 :     ret = circuit_is_suitable_for_introduce1(circ);
     607           1 :     circuit_free_(TO_CIRCUIT(circ));
     608           1 :     tt_int_op(ret, OP_EQ, 1);
     609             :   }
     610             : 
     611             :   /* Test if the circuit purpose safeguard works correctly. */
     612             :   {
     613           1 :     circ = or_circuit_new(0, NULL);
     614           1 :     circuit_change_purpose(TO_CIRCUIT(circ), CIRCUIT_PURPOSE_INTRO_POINT);
     615           1 :     ret = circuit_is_suitable_for_introduce1(circ);
     616           1 :     circuit_free_(TO_CIRCUIT(circ));
     617           1 :     tt_int_op(ret, OP_EQ, 0);
     618             :   }
     619             : 
     620             :   /* Test the non-edge circuit safeguard works correctly. */
     621             :   {
     622           1 :     circ = or_circuit_new(0, NULL);
     623           1 :     circuit_change_purpose(TO_CIRCUIT(circ), CIRCUIT_PURPOSE_OR);
     624             :     /* Bogus pointer, the check is against NULL on n_chan. */
     625           1 :     circ->base_.n_chan = (channel_t *) circ;
     626           1 :     ret = circuit_is_suitable_for_introduce1(circ);
     627           1 :     circuit_free_(TO_CIRCUIT(circ));
     628           1 :     tt_int_op(ret, OP_EQ, 0);
     629             :   }
     630             : 
     631             :   /* Mangle the circuit a bit more so see if our only one INTRODUCE1 cell
     632             :    * limit works correctly. */
     633             :   {
     634           1 :     circ = or_circuit_new(0, NULL);
     635           1 :     circuit_change_purpose(TO_CIRCUIT(circ), CIRCUIT_PURPOSE_OR);
     636           1 :     circ->already_received_introduce1 = 1;
     637           1 :     ret = circuit_is_suitable_for_introduce1(circ);
     638           1 :     circuit_free_(TO_CIRCUIT(circ));
     639           1 :     tt_int_op(ret, OP_EQ, 0);
     640             :   }
     641             : 
     642             :   /* Single hop circuit should not be allowed. */
     643             :   {
     644           1 :     circ = or_circuit_new(0, NULL);
     645           1 :     circ->p_chan = tor_malloc_zero(sizeof(channel_t));
     646           1 :     circ->p_chan->is_client = 1;
     647           1 :     ret = circuit_is_suitable_for_introduce1(circ);
     648           1 :     tor_free(circ->p_chan);
     649           1 :     circuit_free_(TO_CIRCUIT(circ));
     650           1 :     tt_int_op(ret, OP_EQ, 0);
     651             :   }
     652             : 
     653           1 :  done:
     654           1 :   ;
     655           1 : }
     656             : 
     657             : static void
     658           1 : test_introduce1_validation(void *arg)
     659             : {
     660           1 :   int ret;
     661           1 :   trn_cell_introduce1_t *cell = NULL;
     662             : 
     663           1 :   (void) arg;
     664             : 
     665             :   /* Create our decoy cell that we'll modify as we go to test the validation
     666             :    * function of that parsed cell. */
     667           1 :   cell = helper_create_introduce1_cell();
     668           1 :   tt_assert(cell);
     669             : 
     670             :   /* Non existing auth key type. */
     671           1 :   cell->auth_key_type = 42;
     672           1 :   ret = validate_introduce1_parsed_cell(cell);
     673           1 :   tt_int_op(ret, OP_EQ, -1);
     674             :   /* Reset is to correct value and make sure it's correct. */
     675           1 :   cell->auth_key_type = TRUNNEL_HS_INTRO_AUTH_KEY_TYPE_ED25519;
     676           1 :   ret = validate_introduce1_parsed_cell(cell);
     677           1 :   tt_int_op(ret, OP_EQ, 0);
     678             : 
     679             :   /* Really bad key length. */
     680           1 :   cell->auth_key_len = 0;
     681           1 :   ret = validate_introduce1_parsed_cell(cell);
     682           1 :   tt_int_op(ret, OP_EQ, -1);
     683           1 :   cell->auth_key_len = UINT16_MAX;
     684           1 :   ret = validate_introduce1_parsed_cell(cell);
     685           1 :   tt_int_op(ret, OP_EQ, -1);
     686             :   /* Correct size, let's try that. */
     687           1 :   cell->auth_key_len = sizeof(ed25519_public_key_t);
     688           1 :   ret = validate_introduce1_parsed_cell(cell);
     689           1 :   tt_int_op(ret, OP_EQ, 0);
     690             :   /* Set an invalid size of the auth key buffer. */
     691           1 :   trn_cell_introduce1_setlen_auth_key(cell, 3);
     692           1 :   ret = validate_introduce1_parsed_cell(cell);
     693           1 :   tt_int_op(ret, OP_EQ, -1);
     694             :   /* Reset auth key buffer and make sure it works. */
     695           1 :   trn_cell_introduce1_setlen_auth_key(cell, sizeof(ed25519_public_key_t));
     696           1 :   ret = validate_introduce1_parsed_cell(cell);
     697           1 :   tt_int_op(ret, OP_EQ, 0);
     698             : 
     699             :   /* Empty encrypted section. */
     700           1 :   trn_cell_introduce1_setlen_encrypted(cell, 0);
     701           1 :   ret = validate_introduce1_parsed_cell(cell);
     702           1 :   tt_int_op(ret, OP_EQ, -1);
     703             :   /* Reset it to some non zero bytes and validate. */
     704           1 :   trn_cell_introduce1_setlen_encrypted(cell, 1);
     705           1 :   ret = validate_introduce1_parsed_cell(cell);
     706           1 :   tt_int_op(ret, OP_EQ, 0);
     707             : 
     708           1 :  done:
     709           1 :   trn_cell_introduce1_free(cell);
     710           1 : }
     711             : 
     712             : static void
     713           1 : test_received_introduce1_handling(void *arg)
     714             : {
     715           1 :   int ret;
     716           1 :   uint8_t *request = NULL, buf[128];
     717           1 :   trn_cell_introduce1_t *cell = NULL;
     718           1 :   or_circuit_t *circ = NULL;
     719             : 
     720           1 :   (void) arg;
     721             : 
     722           1 :   MOCK(relay_send_command_from_edge_, mock_relay_send_command_from_edge);
     723             : 
     724           1 :   hs_circuitmap_init();
     725             : 
     726             :   /* Too small request length. An INTRODUCE1 expect at the very least a
     727             :    * DIGEST_LEN size. */
     728             :   {
     729           1 :     memset(buf, 0, sizeof(buf));
     730           1 :     circ = helper_create_intro_circuit();
     731           1 :     ret = hs_intro_received_introduce1(circ, buf, DIGEST_LEN - 1);
     732           1 :     tt_int_op(ret, OP_EQ, -1);
     733           1 :     circuit_free_(TO_CIRCUIT(circ));
     734             :   }
     735             : 
     736             :   /* We have a unit test only for the suitability of a circuit to receive an
     737             :    * INTRODUCE1 cell so from now on we'll only test the handling of a cell. */
     738             : 
     739             :   /* Bad request. */
     740             :   {
     741           1 :     circ = helper_create_intro_circuit();
     742           1 :     uint8_t test[2]; /* Too small request. */
     743           1 :     memset(test, 0, sizeof(test));
     744           1 :     ret = handle_introduce1(circ, test, sizeof(test));
     745           1 :     tor_free(circ->p_chan);
     746           1 :     circuit_free_(TO_CIRCUIT(circ));
     747           1 :     tt_int_op(ret, OP_EQ, -1);
     748             :   }
     749             : 
     750             :   /* Valid case. */
     751             :   {
     752           1 :     cell = helper_create_introduce1_cell();
     753           1 :     ssize_t request_len = trn_cell_introduce1_encoded_len(cell);
     754           1 :     tt_int_op((int)request_len, OP_GT, 0);
     755           1 :     request = tor_malloc_zero(request_len);
     756           1 :     ssize_t encoded_len =
     757           1 :       trn_cell_introduce1_encode(request, request_len, cell);
     758           1 :     tt_int_op((int)encoded_len, OP_GT, 0);
     759             : 
     760           1 :     circ = helper_create_intro_circuit();
     761           1 :     or_circuit_t *service_circ = helper_create_intro_circuit();
     762           1 :     circuit_change_purpose(TO_CIRCUIT(service_circ),
     763             :                            CIRCUIT_PURPOSE_INTRO_POINT);
     764             :     /* Register the circuit in the map for the auth key of the cell. */
     765           1 :     ed25519_public_key_t auth_key;
     766           1 :     const uint8_t *cell_auth_key =
     767           1 :       trn_cell_introduce1_getconstarray_auth_key(cell);
     768           1 :     memcpy(auth_key.pubkey, cell_auth_key, ED25519_PUBKEY_LEN);
     769           1 :     hs_circuitmap_register_intro_circ_v3_relay_side(service_circ, &auth_key);
     770           1 :     ret = hs_intro_received_introduce1(circ, request, request_len);
     771           1 :     circuit_free_(TO_CIRCUIT(circ));
     772           1 :     circuit_free_(TO_CIRCUIT(service_circ));
     773           1 :     tt_int_op(ret, OP_EQ, 0);
     774             :   }
     775             : 
     776           1 :  done:
     777           1 :   trn_cell_introduce1_free(cell);
     778           1 :   tor_free(request);
     779           1 :   hs_circuitmap_free_all();
     780           1 :   UNMOCK(relay_send_command_from_edge_);
     781           1 : }
     782             : 
     783             : static void
     784           1 : test_received_establish_intro_dos_ext(void *arg)
     785             : {
     786           1 :   int ret;
     787           1 :   ssize_t cell_len = 0;
     788           1 :   uint8_t cell[RELAY_PAYLOAD_SIZE] = {0};
     789           1 :   char circ_nonce[DIGEST_LEN] = {0};
     790           1 :   hs_service_intro_point_t *ip = NULL;
     791           1 :   hs_service_config_t config;
     792           1 :   or_circuit_t *intro_circ = or_circuit_new(0,NULL);
     793             : 
     794           1 :   (void) arg;
     795             : 
     796           1 :   MOCK(relay_send_command_from_edge_, mock_relay_send_command_from_edge);
     797             : 
     798           1 :   hs_circuitmap_init();
     799             : 
     800             :   /* Setup. */
     801           1 :   crypto_rand(circ_nonce, sizeof(circ_nonce));
     802           1 :   ip = service_intro_point_new(NULL);
     803           1 :   tt_assert(ip);
     804           1 :   ip->support_intro2_dos_defense = 1;
     805           1 :   memset(&config, 0, sizeof(config));
     806           1 :   config.has_dos_defense_enabled = 1;
     807           1 :   config.intro_dos_rate_per_sec = 13;
     808           1 :   config.intro_dos_burst_per_sec = 42;
     809           1 :   helper_prepare_circ_for_intro(intro_circ, circ_nonce);
     810             :   /* The INTRO2 bucket should be 0 at this point. */
     811           1 :   tt_u64_op(token_bucket_ctr_get(&intro_circ->introduce2_bucket), OP_EQ, 0);
     812           1 :   tt_u64_op(intro_circ->introduce2_bucket.cfg.rate, OP_EQ, 0);
     813           1 :   tt_int_op(intro_circ->introduce2_bucket.cfg.burst, OP_EQ, 0);
     814           1 :   tt_int_op(intro_circ->introduce2_dos_defense_enabled, OP_EQ, 0);
     815             : 
     816             :   /* Case 1: Build encoded cell. Usable DoS parameters. */
     817           1 :   cell_len = hs_cell_build_establish_intro(circ_nonce, &config, ip, cell);
     818           1 :   tt_size_op(cell_len, OP_GT, 0);
     819             :   /* Pass it to the intro point. */
     820           1 :   ret = hs_intro_received_establish_intro(intro_circ, cell, cell_len);
     821           1 :   tt_int_op(ret, OP_EQ, 0);
     822             :   /* Should be set to the burst value. */
     823           1 :   tt_u64_op(token_bucket_ctr_get(&intro_circ->introduce2_bucket), OP_EQ, 42);
     824             :   /* Validate the config of the intro2 bucket. */
     825           1 :   tt_u64_op(intro_circ->introduce2_bucket.cfg.rate, OP_EQ, 13);
     826           1 :   tt_int_op(intro_circ->introduce2_bucket.cfg.burst, OP_EQ, 42);
     827           1 :   tt_int_op(intro_circ->introduce2_dos_defense_enabled, OP_EQ, 1);
     828             : 
     829             :   /* Need to reset the circuit in between test cases. */
     830           1 :   circuit_free_(TO_CIRCUIT(intro_circ));
     831           1 :   intro_circ = or_circuit_new(0,NULL);
     832           1 :   helper_prepare_circ_for_intro(intro_circ, circ_nonce);
     833             : 
     834             :   /* Case 2: Build encoded cell. Bad DoS parameters. */
     835           1 :   config.has_dos_defense_enabled = 1;
     836           1 :   config.intro_dos_rate_per_sec = UINT_MAX;
     837           1 :   config.intro_dos_burst_per_sec = 13;
     838           1 :   cell_len = hs_cell_build_establish_intro(circ_nonce, &config, ip, cell);
     839           1 :   tt_size_op(cell_len, OP_GT, 0);
     840             :   /* Pass it to the intro point. */
     841           1 :   ret = hs_intro_received_establish_intro(intro_circ, cell, cell_len);
     842           1 :   tt_int_op(ret, OP_EQ, 0);
     843           1 :   tt_u64_op(token_bucket_ctr_get(&intro_circ->introduce2_bucket), OP_EQ,
     844             :             HS_CONFIG_V3_DOS_DEFENSE_BURST_PER_SEC_DEFAULT);
     845           1 :   tt_u64_op(intro_circ->introduce2_bucket.cfg.rate, OP_EQ,
     846             :             HS_CONFIG_V3_DOS_DEFENSE_RATE_PER_SEC_DEFAULT);
     847           1 :   tt_int_op(intro_circ->introduce2_bucket.cfg.burst, OP_EQ,
     848             :             HS_CONFIG_V3_DOS_DEFENSE_BURST_PER_SEC_DEFAULT);
     849           1 :   tt_int_op(intro_circ->introduce2_dos_defense_enabled, OP_EQ,
     850             :             HS_CONFIG_V3_DOS_DEFENSE_DEFAULT);
     851             : 
     852             :   /* Need to reset the circuit in between test cases. */
     853           1 :   circuit_free_(TO_CIRCUIT(intro_circ));
     854           1 :   intro_circ = or_circuit_new(0,NULL);
     855           1 :   helper_prepare_circ_for_intro(intro_circ, circ_nonce);
     856             : 
     857             :   /* Case 3: Build encoded cell. Burst is smaller than rate. Not allowed. */
     858           1 :   config.has_dos_defense_enabled = 1;
     859           1 :   config.intro_dos_rate_per_sec = 87;
     860           1 :   config.intro_dos_burst_per_sec = 45;
     861           1 :   cell_len = hs_cell_build_establish_intro(circ_nonce, &config, ip, cell);
     862           1 :   tt_size_op(cell_len, OP_GT, 0);
     863             :   /* Pass it to the intro point. */
     864           1 :   ret = hs_intro_received_establish_intro(intro_circ, cell, cell_len);
     865           1 :   tt_int_op(ret, OP_EQ, 0);
     866           1 :   tt_u64_op(token_bucket_ctr_get(&intro_circ->introduce2_bucket), OP_EQ,
     867             :             HS_CONFIG_V3_DOS_DEFENSE_BURST_PER_SEC_DEFAULT);
     868           1 :   tt_u64_op(intro_circ->introduce2_bucket.cfg.rate, OP_EQ,
     869             :             HS_CONFIG_V3_DOS_DEFENSE_RATE_PER_SEC_DEFAULT);
     870           1 :   tt_int_op(intro_circ->introduce2_bucket.cfg.burst, OP_EQ,
     871             :             HS_CONFIG_V3_DOS_DEFENSE_BURST_PER_SEC_DEFAULT);
     872           1 :   tt_int_op(intro_circ->introduce2_dos_defense_enabled, OP_EQ,
     873             :             HS_CONFIG_V3_DOS_DEFENSE_DEFAULT);
     874             : 
     875             :   /* Need to reset the circuit in between test cases. */
     876           1 :   circuit_free_(TO_CIRCUIT(intro_circ));
     877           1 :   intro_circ = or_circuit_new(0,NULL);
     878           1 :   helper_prepare_circ_for_intro(intro_circ, circ_nonce);
     879             : 
     880             :   /* Case 4: Build encoded cell. Rate is 0 but burst is not 0. Disables the
     881             :    * defense. */
     882           1 :   config.has_dos_defense_enabled = 1;
     883           1 :   config.intro_dos_rate_per_sec = 0;
     884           1 :   config.intro_dos_burst_per_sec = 45;
     885           1 :   cell_len = hs_cell_build_establish_intro(circ_nonce, &config, ip, cell);
     886           1 :   tt_size_op(cell_len, OP_GT, 0);
     887             :   /* Pass it to the intro point. */
     888           1 :   ret = hs_intro_received_establish_intro(intro_circ, cell, cell_len);
     889           1 :   tt_int_op(ret, OP_EQ, 0);
     890           1 :   tt_u64_op(token_bucket_ctr_get(&intro_circ->introduce2_bucket), OP_EQ,
     891             :             HS_CONFIG_V3_DOS_DEFENSE_BURST_PER_SEC_DEFAULT);
     892           1 :   tt_u64_op(intro_circ->introduce2_bucket.cfg.rate, OP_EQ,
     893             :             HS_CONFIG_V3_DOS_DEFENSE_RATE_PER_SEC_DEFAULT);
     894           1 :   tt_int_op(intro_circ->introduce2_bucket.cfg.burst, OP_EQ,
     895             :             HS_CONFIG_V3_DOS_DEFENSE_BURST_PER_SEC_DEFAULT);
     896           1 :   tt_int_op(intro_circ->introduce2_dos_defense_enabled, OP_EQ,
     897             :             HS_CONFIG_V3_DOS_DEFENSE_DEFAULT);
     898             : 
     899             :   /* Need to reset the circuit in between test cases. */
     900           1 :   circuit_free_(TO_CIRCUIT(intro_circ));
     901           1 :   intro_circ = or_circuit_new(0,NULL);
     902           1 :   helper_prepare_circ_for_intro(intro_circ, circ_nonce);
     903             : 
     904             :   /* Case 5: Build encoded cell. Burst is 0 but rate is not 0. Disables the
     905             :    * defense. */
     906           1 :   config.has_dos_defense_enabled = 1;
     907           1 :   config.intro_dos_rate_per_sec = 45;
     908           1 :   config.intro_dos_burst_per_sec = 0;
     909           1 :   cell_len = hs_cell_build_establish_intro(circ_nonce, &config, ip, cell);
     910           1 :   tt_size_op(cell_len, OP_GT, 0);
     911             :   /* Pass it to the intro point. */
     912           1 :   ret = hs_intro_received_establish_intro(intro_circ, cell, cell_len);
     913           1 :   tt_int_op(ret, OP_EQ, 0);
     914           1 :   tt_u64_op(token_bucket_ctr_get(&intro_circ->introduce2_bucket), OP_EQ,
     915             :             HS_CONFIG_V3_DOS_DEFENSE_BURST_PER_SEC_DEFAULT);
     916           1 :   tt_u64_op(intro_circ->introduce2_bucket.cfg.rate, OP_EQ,
     917             :             HS_CONFIG_V3_DOS_DEFENSE_RATE_PER_SEC_DEFAULT);
     918           1 :   tt_int_op(intro_circ->introduce2_bucket.cfg.burst, OP_EQ,
     919             :             HS_CONFIG_V3_DOS_DEFENSE_BURST_PER_SEC_DEFAULT);
     920           1 :   tt_int_op(intro_circ->introduce2_dos_defense_enabled, OP_EQ,
     921             :             HS_CONFIG_V3_DOS_DEFENSE_DEFAULT);
     922             : 
     923           1 :  done:
     924           1 :   circuit_free_(TO_CIRCUIT(intro_circ));
     925           1 :   service_intro_point_free(ip);
     926           1 :   hs_circuitmap_free_all();
     927           1 :   UNMOCK(relay_send_command_from_edge_);
     928           1 : }
     929             : 
     930             : static void *
     931           0 : hs_subsystem_setup_fn(const struct testcase_t *tc)
     932             : {
     933           0 :   (void) tc;
     934             : 
     935           0 :   return NULL;
     936             : }
     937             : 
     938             : static int
     939           0 : hs_subsystem_cleanup_fn(const struct testcase_t *tc, void *arg)
     940             : {
     941           0 :   (void) tc;
     942           0 :   (void) arg;
     943             : 
     944           0 :   return 1;
     945             : }
     946             : 
     947             : static struct testcase_setup_t test_setup = {
     948             :   hs_subsystem_setup_fn, hs_subsystem_cleanup_fn
     949             : };
     950             : 
     951             : struct testcase_t hs_intropoint_tests[] = {
     952             :   { "intro_point_registration",
     953             :     test_intro_point_registration, TT_FORK, NULL, &test_setup},
     954             : 
     955             :   { "receive_establish_intro_wrong_keytype",
     956             :     test_establish_intro_wrong_keytype, TT_FORK, NULL, &test_setup},
     957             : 
     958             :   { "receive_establish_intro_wrong_keytype2",
     959             :     test_establish_intro_wrong_keytype2, TT_FORK, NULL, &test_setup},
     960             : 
     961             :   { "receive_establish_intro_wrong_purpose",
     962             :     test_establish_intro_wrong_purpose, TT_FORK, NULL, &test_setup},
     963             : 
     964             :   { "receive_establish_intro_wrong_sig",
     965             :     test_establish_intro_wrong_sig, TT_FORK, NULL, &test_setup},
     966             : 
     967             :   { "receive_establish_intro_wrong_sig_len",
     968             :     test_establish_intro_wrong_sig_len, TT_FORK, NULL, &test_setup},
     969             : 
     970             :   { "receive_establish_intro_wrong_auth_key_len",
     971             :     test_establish_intro_wrong_auth_key_len, TT_FORK, NULL, &test_setup},
     972             : 
     973             :   { "receive_establish_intro_wrong_mac",
     974             :     test_establish_intro_wrong_mac, TT_FORK, NULL, &test_setup},
     975             : 
     976             :   { "introduce1_suitable_circuit",
     977             :     test_introduce1_suitable_circuit, TT_FORK, NULL, &test_setup},
     978             : 
     979             :   { "introduce1_validation",
     980             :     test_introduce1_validation, TT_FORK, NULL, &test_setup},
     981             : 
     982             :   { "received_introduce1_handling",
     983             :     test_received_introduce1_handling, TT_FORK, NULL, &test_setup},
     984             : 
     985             :   { "received_establish_intro_dos_ext",
     986             :     test_received_establish_intro_dos_ext, TT_FORK, NULL, &test_setup},
     987             : 
     988             :   END_OF_TESTCASES
     989             : };

Generated by: LCOV version 1.14