LCOV - code coverage report
Current view: top level - test - test_relaycrypt.c (source / functions) Hit Total Coverage
Test: lcov.info Lines: 73 76 96.1 %
Date: 2021-11-24 03:28:48 Functions: 4 4 100.0 %

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

Generated by: LCOV version 1.14