tor

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

test_relaycrypt.c (5728B)


      1 /* Copyright 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 #define CRYPT_PATH_PRIVATE
      7 
      8 #include "core/or/or.h"
      9 #include "core/or/circuitbuild.h"
     10 #define CIRCUITLIST_PRIVATE
     11 #include "core/or/circuitlist.h"
     12 #include "lib/crypt_ops/crypto_rand.h"
     13 #include "core/or/relay.h"
     14 #include "core/crypto/relay_crypto.h"
     15 #include "core/or/crypt_path.h"
     16 #include "core/or/cell_st.h"
     17 #include "core/or/or_circuit_st.h"
     18 #include "core/or/origin_circuit_st.h"
     19 
     20 #include "test/test.h"
     21 
     22 #ifdef __GNUC__
     23 #pragma GCC diagnostic push
     24 #pragma GCC diagnostic ignored "-Wattributes"
     25 #endif
     26 NONSTRING static const char KEY_MATERIAL[3][CPATH_KEY_MATERIAL_LEN] = {
     27  "    'My public key is in this signed x509 object', said Tom assertively.",
     28  "'Let's chart the pedal phlanges in the tomb', said Tom cryptographically",
     29  "     'Segmentation fault bugs don't _just happen_', said Tom seethingly.",
     30 };
     31 #ifdef __GNUC__
     32 #pragma GCC diagnostic pop
     33 #endif
     34 
     35 typedef struct testing_circuitset_t {
     36  or_circuit_t *or_circ[3];
     37  origin_circuit_t *origin_circ;
     38 } testing_circuitset_t;
     39 
     40 static int testing_circuitset_teardown(const struct testcase_t *testcase,
     41                                       void *ptr);
     42 
     43 static void *
     44 testing_circuitset_setup(const struct testcase_t *testcase)
     45 {
     46  testing_circuitset_t *cs = tor_malloc_zero(sizeof(testing_circuitset_t));
     47  int i;
     48 
     49  for (i=0; i<3; ++i) {
     50    cs->or_circ[i] = or_circuit_new(0, NULL);
     51    tt_int_op(0, OP_EQ,
     52              relay_crypto_init(RELAY_CRYPTO_ALG_TOR1,
     53                                &cs->or_circ[i]->crypto,
     54                                KEY_MATERIAL[i], sizeof(KEY_MATERIAL[i])));
     55  }
     56 
     57  cs->origin_circ = origin_circuit_new();
     58  cs->origin_circ->base_.purpose = CIRCUIT_PURPOSE_C_GENERAL;
     59  for (i=0; i<3; ++i) {
     60    crypt_path_t *hop = tor_malloc_zero(sizeof(*hop));
     61    relay_crypto_init(RELAY_CRYPTO_ALG_TOR1,
     62                      &hop->pvt_crypto, KEY_MATERIAL[i],
     63                      sizeof(KEY_MATERIAL[i]));
     64    hop->state = CPATH_STATE_OPEN;
     65    cpath_extend_linked_list(&cs->origin_circ->cpath, hop);
     66    tt_ptr_op(hop, OP_EQ, cs->origin_circ->cpath->prev);
     67  }
     68 
     69  return cs;
     70 done:
     71  testing_circuitset_teardown(testcase, cs);
     72  return NULL;
     73 }
     74 
     75 static int
     76 testing_circuitset_teardown(const struct testcase_t *testcase, void *ptr)
     77 {
     78  (void)testcase;
     79  testing_circuitset_t *cs = ptr;
     80  int i;
     81  for (i=0; i<3; ++i) {
     82    circuit_free_(TO_CIRCUIT(cs->or_circ[i]));
     83  }
     84  circuit_free_(TO_CIRCUIT(cs->origin_circ));
     85  tor_free(cs);
     86  return 1;
     87 }
     88 
     89 static const struct testcase_setup_t relaycrypt_setup = {
     90  testing_circuitset_setup, testing_circuitset_teardown
     91 };
     92 
     93 /* Test encrypting a cell to the final hop on a circuit, decrypting it
     94 * at each hop, and recognizing it at the other end.  Then do it again
     95 * and again as the state evolves. */
     96 static void
     97 test_relaycrypt_outbound(void *arg)
     98 {
     99  testing_circuitset_t *cs = arg;
    100  tt_assert(cs);
    101 
    102  relay_header_t rh;
    103  cell_t orig;
    104  cell_t encrypted;
    105  int i, j;
    106 
    107  for (i = 0; i < 50; ++i) {
    108    crypto_rand((char *)&orig, sizeof(orig));
    109 
    110    relay_header_unpack(&rh, orig.payload);
    111    rh.recognized = 0;
    112    memset(rh.integrity, 0, sizeof(rh.integrity));
    113    relay_header_pack(orig.payload, &rh);
    114 
    115    memcpy(&encrypted, &orig, sizeof(orig));
    116 
    117    /* Encrypt the cell to the last hop */
    118    relay_encrypt_cell_outbound(&encrypted, cs->origin_circ,
    119                                cs->origin_circ->cpath->prev);
    120 
    121    for (j = 0; j < 3; ++j) {
    122      crypt_path_t *layer_hint = NULL;
    123      char recognized = 0;
    124      int r = relay_decrypt_cell(TO_CIRCUIT(cs->or_circ[j]),
    125                                 &encrypted,
    126                                 CELL_DIRECTION_OUT,
    127                                 &layer_hint, &recognized);
    128      tt_int_op(r, OP_EQ, 0);
    129      tt_ptr_op(layer_hint, OP_EQ, NULL);
    130      tt_int_op(recognized != 0, OP_EQ, j == 2);
    131    }
    132 
    133    tt_mem_op(orig.payload, OP_EQ, encrypted.payload, CELL_PAYLOAD_SIZE);
    134  }
    135 
    136 done:
    137  ;
    138 }
    139 
    140 /* As above, but simulate inbound cells from the last hop. */
    141 static void
    142 test_relaycrypt_inbound(void *arg)
    143 {
    144  testing_circuitset_t *cs = arg;
    145  tt_assert(cs);
    146 
    147  relay_header_t rh;
    148  cell_t orig;
    149  cell_t encrypted;
    150  int i, j;
    151 
    152  for (i = 0; i < 50; ++i) {
    153    crypto_rand((char *)&orig, sizeof(orig));
    154 
    155    relay_header_unpack(&rh, orig.payload);
    156    rh.recognized = 0;
    157    memset(rh.integrity, 0, sizeof(rh.integrity));
    158    relay_header_pack(orig.payload, &rh);
    159 
    160    memcpy(&encrypted, &orig, sizeof(orig));
    161 
    162    /* Encrypt the cell to the last hop */
    163    relay_encrypt_cell_inbound(&encrypted, cs->or_circ[2]);
    164 
    165    crypt_path_t *layer_hint = NULL;
    166    char recognized = 0;
    167    int r;
    168    for (j = 1; j >= 0; --j) {
    169      r = relay_decrypt_cell(TO_CIRCUIT(cs->or_circ[j]),
    170                             &encrypted,
    171                             CELL_DIRECTION_IN,
    172                             &layer_hint, &recognized);
    173      tt_int_op(r, OP_EQ, 0);
    174      tt_ptr_op(layer_hint, OP_EQ, NULL);
    175      tt_int_op(recognized, OP_EQ, 0);
    176    }
    177 
    178    relay_decrypt_cell(TO_CIRCUIT(cs->origin_circ),
    179                       &encrypted,
    180                       CELL_DIRECTION_IN,
    181                       &layer_hint, &recognized);
    182    tt_int_op(r, OP_EQ, 0);
    183    tt_int_op(recognized, OP_EQ, 1);
    184    tt_ptr_op(layer_hint, OP_EQ, cs->origin_circ->cpath->prev);
    185 
    186    tt_mem_op(orig.payload, OP_EQ, encrypted.payload, CELL_PAYLOAD_SIZE);
    187  }
    188 done:
    189  ;
    190 }
    191 
    192 #define TEST(name) \
    193  { # name, test_relaycrypt_ ## name, 0, &relaycrypt_setup, NULL }
    194 
    195 struct testcase_t relaycrypt_tests[] = {
    196  TEST(outbound),
    197  TEST(inbound),
    198  END_OF_TESTCASES
    199 };