]> git.ipfire.org Git - thirdparty/tor.git/commitdiff
Merge remote-tracking branch 'isis/bug24660_r1'
authorNick Mathewson <nickm@torproject.org>
Thu, 3 May 2018 17:50:18 +0000 (13:50 -0400)
committerNick Mathewson <nickm@torproject.org>
Thu, 3 May 2018 17:50:18 +0000 (13:50 -0400)
54 files changed:
1  2 
src/common/aes.c
src/common/compat_libevent.c
src/common/crypto.c
src/common/include.am
src/common/tortls.c
src/common/workqueue.c
src/or/channelpadding.c
src/or/circuitbuild.c
src/or/circuitlist.c
src/or/circuitmux_ewma.c
src/or/circuitstats.c
src/or/command.c
src/or/config.c
src/or/connection.c
src/or/connection_edge.c
src/or/connection_or.c
src/or/control.c
src/or/cpuworker.c
src/or/dirauth/shared_random.c
src/or/dirauth/shared_random_state.c
src/or/directory.c
src/or/dns.c
src/or/dos.c
src/or/entrynodes.c
src/or/hibernate.c
src/or/hs_circuit.c
src/or/hs_common.c
src/or/hs_control.c
src/or/hs_service.c
src/or/main.c
src/or/networkstatus.c
src/or/relay.c
src/or/relay_crypto.c
src/or/rendservice.c
src/or/rephist.c
src/or/router.c
src/or/routerlist.c
src/or/routerparse.c
src/test/bench.c
src/test/test-timers.c
src/test/test.c
src/test/test_channel.c
src/test/test_dir.c
src/test/test_dir_common.c
src/test/test_entrynodes.c
src/test/test_helpers.c
src/test/test_hs_common.c
src/test/test_hs_service.c
src/test/test_relaycrypt.c
src/test/test_routerlist.c
src/test/test_shared_random.c
src/test/test_util.c
src/test/test_workqueue.c
src/test/testing_common.c

Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
index 12e31414e70b59e1ce86f2fefd90eb1dc0576a9f,de0079b7575bc9e97fdd435f4ae7df6d31da10e9..563a98af9608e2654125b46833e8d2af321e36ac
@@@ -25,9 -24,8 +25,9 @@@
  
  #include "orconfig.h"
  #include "compat.h"
 +#include "compat_libevent.h"
  #include "compat_threads.h"
- #include "crypto.h"
+ #include "crypto_rand.h"
  #include "util.h"
  #include "workqueue.h"
  #include "tor_queue.h"
Simple merge
Simple merge
Simple merge
index e85301b26d97500e4a672d4c4ebc9d584c52c1c3,b2ace8a9fa06d3b91af5486943c08f7438a41ed2..e5d5a14581f7a69ede601c39e3279df6972efe7a
@@@ -37,6 -37,6 +37,7 @@@
  #include "or.h"
  #include "circuitmux.h"
  #include "circuitmux_ewma.h"
++#include "crypto_rand.h"
  #include "networkstatus.h"
  
  /*** EWMA parameter #defines ***/
Simple merge
Simple merge
diff --cc src/or/config.c
index 23f1d4f5a37ff37fdd86bc0b4868f6f3d3a09a30,18298937e4902e15a90eec0a7026db3f0fbd7698..9af613e9316ea229935ced81e4621d30171b8314
  #include "control.h"
  #include "confparse.h"
  #include "cpuworker.h"
+ #include "crypto_rand.h"
+ #include "crypto_util.h"
  #include "dirserv.h"
 -#include "dirvote.h"
  #include "dns.h"
  #include "dos.h"
  #include "entrynodes.h"
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
index 0a89fa8d2d706eb550863898a5b9880827c463a2,74556687737ac452c89a983a813a031bedd75891..6dd1f330e01b0ba782edea1761ddc9e94ede733e
  #include "shared_random.h"
  #include "config.h"
  #include "confparse.h"
 -#include "dirvote.h"
+ #include "crypto_rand.h"
+ #include "crypto_util.h"
  #include "networkstatus.h"
--#include "routerkeys.h"
  #include "router.h"
++#include "routerkeys.h"
  #include "routerlist.h"
- #include "shared_random_state.h"
 +#include "shared_random_client.h"
+ #include "shared_random_state.h"
  #include "util.h"
 +#include "voting_schedule.h"
 +
 +#include "dirauth/dirvote.h"
 +#include "dirauth/mode.h"
  
  /* String prefix of shared random values in votes/consensuses. */
  static const char previous_srv_str[] = "shared-rand-previous-value";
index 56c12c8c72c4d8fe923f04023ab2d464e9bb94f2,80470e4e98362d360ff8dcb1e3fa481e8a9d63bc..245fb99ce7fa81306d8d0a6e451d8430f0329063
  #define SHARED_RANDOM_STATE_PRIVATE
  
  #include "or.h"
--#include "shared_random.h"
  #include "config.h"
  #include "confparse.h"
- #include "voting_schedule.h"
+ #include "crypto_util.h"
 -#include "dirvote.h"
++#include "dirauth/dirvote.h"
  #include "networkstatus.h"
  #include "router.h"
- #include "shared_random_state.h"
++#include "shared_random.h"
 +#include "shared_random_client.h"
- #include "dirauth/dirvote.h"
+ #include "shared_random_state.h"
++#include "voting_schedule.h"
  
  /* Default filename of the shared random state on disk. */
  static const char default_fname[] = "sr-state";
index 76caab6a3c2156f345c8386cb941fd6963a98e01,44e3d2f2a0a5b9353b90eb5397b5a460da916c7f..3e8d5ae9cfaaf81492bae8b683f161a18c877fc0
  #include "consdiffmgr.h"
  #include "control.h"
  #include "compat.h"
+ #include "crypto_rand.h"
+ #include "crypto_util.h"
  #include "directory.h"
  #include "dirserv.h"
 -#include "dirvote.h"
  #include "entrynodes.h"
  #include "geoip.h"
  #include "hs_cache.h"
diff --cc src/or/dns.c
Simple merge
diff --cc src/or/dos.c
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
diff --cc src/or/main.c
index 08dfeb80f0c5abb5f7dea18f478c50cb162b1aef,b3f0a85cda72e8662b7d212e09d288baf9ecc681..c3505a2d9161ca89ff062ae302aeb1e2145d0f31
  #include "control.h"
  #include "cpuworker.h"
  #include "crypto_s2k.h"
+ #include "crypto_rand.h"
  #include "directory.h"
  #include "dirserv.h"
 -#include "dirvote.h"
  #include "dns.h"
  #include "dnsserv.h"
  #include "dos.h"
index a7a76b236c757f92aac89aded5102c9ca507180d,e223b6f1b90ba3422d0f5a46ead63dbe9c6bfaa9..7579893421a4b631831e2dda80933e394c517429
  #include "connection_or.h"
  #include "consdiffmgr.h"
  #include "control.h"
+ #include "crypto_rand.h"
+ #include "crypto_util.h"
  #include "directory.h"
  #include "dirserv.h"
 -#include "dirvote.h"
  #include "dos.h"
  #include "entrynodes.h"
  #include "hibernate.h"
diff --cc src/or/relay.c
Simple merge
index c42a4f9ccaa951f0af5405a55c084b09342a8979,0000000000000000000000000000000000000000..530c8e582807ff3160784fb8b76da86ee7977c0f
mode 100644,000000..100644
--- /dev/null
@@@ -1,326 -1,0 +1,327 @@@
- #include "relay_crypto.h"
 +/* Copyright (c) 2001 Matej Pfajfar.
 + * Copyright (c) 2001-2004, Roger Dingledine.
 + * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
 + * Copyright (c) 2007-2018, The Tor Project, Inc. */
 +/* See LICENSE for licensing information */
 +
 +#include "or.h"
 +#include "config.h"
++#include "crypto_util.h"
 +#include "hs_ntor.h" // for HS_NTOR_KEY_EXPANSION_KDF_OUT_LEN
 +#include "relay.h"
++#include "relay_crypto.h"
 +
 +/** Update digest from the payload of cell. Assign integrity part to
 + * cell.
 + */
 +static void
 +relay_set_digest(crypto_digest_t *digest, cell_t *cell)
 +{
 +  char integrity[4];
 +  relay_header_t rh;
 +
 +  crypto_digest_add_bytes(digest, (char*)cell->payload, CELL_PAYLOAD_SIZE);
 +  crypto_digest_get_digest(digest, integrity, 4);
 +//  log_fn(LOG_DEBUG,"Putting digest of %u %u %u %u into relay cell.",
 +//    integrity[0], integrity[1], integrity[2], integrity[3]);
 +  relay_header_unpack(&rh, cell->payload);
 +  memcpy(rh.integrity, integrity, 4);
 +  relay_header_pack(cell->payload, &rh);
 +}
 +
 +/** Does the digest for this circuit indicate that this cell is for us?
 + *
 + * Update digest from the payload of cell (with the integrity part set
 + * to 0). If the integrity part is valid, return 1, else restore digest
 + * and cell to their original state and return 0.
 + */
 +static int
 +relay_digest_matches(crypto_digest_t *digest, cell_t *cell)
 +{
 +  uint32_t received_integrity, calculated_integrity;
 +  relay_header_t rh;
 +  crypto_digest_checkpoint_t backup_digest;
 +
 +  crypto_digest_checkpoint(&backup_digest, digest);
 +
 +  relay_header_unpack(&rh, cell->payload);
 +  memcpy(&received_integrity, rh.integrity, 4);
 +  memset(rh.integrity, 0, 4);
 +  relay_header_pack(cell->payload, &rh);
 +
 +//  log_fn(LOG_DEBUG,"Reading digest of %u %u %u %u from relay cell.",
 +//    received_integrity[0], received_integrity[1],
 +//    received_integrity[2], received_integrity[3]);
 +
 +  crypto_digest_add_bytes(digest, (char*) cell->payload, CELL_PAYLOAD_SIZE);
 +  crypto_digest_get_digest(digest, (char*) &calculated_integrity, 4);
 +
 +  int rv = 1;
 +
 +  if (calculated_integrity != received_integrity) {
 +//    log_fn(LOG_INFO,"Recognized=0 but bad digest. Not recognizing.");
 +// (%d vs %d).", received_integrity, calculated_integrity);
 +    /* restore digest to its old form */
 +    crypto_digest_restore(digest, &backup_digest);
 +    /* restore the relay header */
 +    memcpy(rh.integrity, &received_integrity, 4);
 +    relay_header_pack(cell->payload, &rh);
 +    rv = 0;
 +  }
 +
 +  memwipe(&backup_digest, 0, sizeof(backup_digest));
 +  return rv;
 +}
 +
 +/** Apply <b>cipher</b> to CELL_PAYLOAD_SIZE bytes of <b>in</b>
 + * (in place).
 + *
 + * Note that we use the same operation for encrypting and for decrypting.
 + */
 +static void
 +relay_crypt_one_payload(crypto_cipher_t *cipher, uint8_t *in)
 +{
 +  crypto_cipher_crypt_inplace(cipher, (char*) in, CELL_PAYLOAD_SIZE);
 +}
 +
 +/** Do the appropriate en/decryptions for <b>cell</b> arriving on
 + * <b>circ</b> in direction <b>cell_direction</b>.
 + *
 + * If cell_direction == CELL_DIRECTION_IN:
 + *   - If we're at the origin (we're the OP), for hops 1..N,
 + *     decrypt cell. If recognized, stop.
 + *   - Else (we're not the OP), encrypt one hop. Cell is not recognized.
 + *
 + * If cell_direction == CELL_DIRECTION_OUT:
 + *   - decrypt one hop. Check if recognized.
 + *
 + * If cell is recognized, set *recognized to 1, and set
 + * *layer_hint to the hop that recognized it.
 + *
 + * Return -1 to indicate that we should mark the circuit for close,
 + * else return 0.
 + */
 +int
 +relay_decrypt_cell(circuit_t *circ, cell_t *cell,
 +                   cell_direction_t cell_direction,
 +                   crypt_path_t **layer_hint, char *recognized)
 +{
 +  relay_header_t rh;
 +
 +  tor_assert(circ);
 +  tor_assert(cell);
 +  tor_assert(recognized);
 +  tor_assert(cell_direction == CELL_DIRECTION_IN ||
 +             cell_direction == CELL_DIRECTION_OUT);
 +
 +  if (cell_direction == CELL_DIRECTION_IN) {
 +    if (CIRCUIT_IS_ORIGIN(circ)) { /* We're at the beginning of the circuit.
 +                                    * We'll want to do layered decrypts. */
 +      crypt_path_t *thishop, *cpath = TO_ORIGIN_CIRCUIT(circ)->cpath;
 +      thishop = cpath;
 +      if (thishop->state != CPATH_STATE_OPEN) {
 +        log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
 +               "Relay cell before first created cell? Closing.");
 +        return -1;
 +      }
 +      do { /* Remember: cpath is in forward order, that is, first hop first. */
 +        tor_assert(thishop);
 +
 +        /* decrypt one layer */
 +        relay_crypt_one_payload(thishop->crypto.b_crypto, cell->payload);
 +
 +        relay_header_unpack(&rh, cell->payload);
 +        if (rh.recognized == 0) {
 +          /* it's possibly recognized. have to check digest to be sure. */
 +          if (relay_digest_matches(thishop->crypto.b_digest, cell)) {
 +            *recognized = 1;
 +            *layer_hint = thishop;
 +            return 0;
 +          }
 +        }
 +
 +        thishop = thishop->next;
 +      } while (thishop != cpath && thishop->state == CPATH_STATE_OPEN);
 +      log_fn(LOG_PROTOCOL_WARN, LD_OR,
 +             "Incoming cell at client not recognized. Closing.");
 +      return -1;
 +    } else {
 +      relay_crypto_t *crypto = &TO_OR_CIRCUIT(circ)->crypto;
 +      /* We're in the middle. Encrypt one layer. */
 +      relay_crypt_one_payload(crypto->b_crypto, cell->payload);
 +    }
 +  } else /* cell_direction == CELL_DIRECTION_OUT */ {
 +    /* We're in the middle. Decrypt one layer. */
 +    relay_crypto_t *crypto = &TO_OR_CIRCUIT(circ)->crypto;
 +
 +    relay_crypt_one_payload(crypto->f_crypto, cell->payload);
 +
 +    relay_header_unpack(&rh, cell->payload);
 +    if (rh.recognized == 0) {
 +      /* it's possibly recognized. have to check digest to be sure. */
 +      if (relay_digest_matches(crypto->f_digest, cell)) {
 +        *recognized = 1;
 +        return 0;
 +      }
 +    }
 +  }
 +  return 0;
 +}
 +
 +/**
 + * Encrypt a cell <b>cell</b> that we are creating, and sending outbound on
 + * <b>circ</b> until the hop corresponding to <b>layer_hint</b>.
 + *
 + * The integrity field and recognized field of <b>cell</b>'s relay headers
 + * must be set to zero.
 + */
 +void
 +relay_encrypt_cell_outbound(cell_t *cell,
 +                            origin_circuit_t *circ,
 +                            crypt_path_t *layer_hint)
 +{
 +  crypt_path_t *thishop; /* counter for repeated crypts */
 +  relay_set_digest(layer_hint->crypto.f_digest, cell);
 +
 +  thishop = layer_hint;
 +  /* moving from farthest to nearest hop */
 +  do {
 +    tor_assert(thishop);
 +    log_debug(LD_OR,"encrypting a layer of the relay cell.");
 +    relay_crypt_one_payload(thishop->crypto.f_crypto, cell->payload);
 +
 +    thishop = thishop->prev;
 +  } while (thishop != circ->cpath->prev);
 +}
 +
 +/**
 + * Encrypt a cell <b>cell</b> that we are creating, and sending on
 + * <b>circuit</b> to the origin.
 + *
 + * The integrity field and recognized field of <b>cell</b>'s relay headers
 + * must be set to zero.
 + */
 +void
 +relay_encrypt_cell_inbound(cell_t *cell,
 +                           or_circuit_t *or_circ)
 +{
 +  relay_set_digest(or_circ->crypto.b_digest, cell);
 +  /* encrypt one layer */
 +  relay_crypt_one_payload(or_circ->crypto.b_crypto, cell->payload);
 +}
 +
 +/**
 + * Release all storage held inside <b>crypto</b>, but do not free
 + * <b>crypto</b> itself: it lives inside another object.
 + */
 +void
 +relay_crypto_clear(relay_crypto_t *crypto)
 +{
 +  if (BUG(!crypto))
 +    return;
 +  crypto_cipher_free(crypto->f_crypto);
 +  crypto_cipher_free(crypto->b_crypto);
 +  crypto_digest_free(crypto->f_digest);
 +  crypto_digest_free(crypto->b_digest);
 +}
 +
 +/** Initialize <b>crypto</b> from the key material in key_data.
 + *
 + * If <b>is_hs_v3</b> is set, this cpath will be used for next gen hidden
 + * service circuits and <b>key_data</b> must be at least
 + * HS_NTOR_KEY_EXPANSION_KDF_OUT_LEN bytes in length.
 + *
 + * If <b>is_hs_v3</b> is not set, key_data must contain CPATH_KEY_MATERIAL_LEN
 + * bytes, which are used as follows:
 + *   - 20 to initialize f_digest
 + *   - 20 to initialize b_digest
 + *   - 16 to key f_crypto
 + *   - 16 to key b_crypto
 + *
 + * (If 'reverse' is true, then f_XX and b_XX are swapped.)
 + *
 + * Return 0 if init was successful, else -1 if it failed.
 + */
 +int
 +relay_crypto_init(relay_crypto_t *crypto,
 +                  const char *key_data, size_t key_data_len,
 +                  int reverse, int is_hs_v3)
 +{
 +  crypto_digest_t *tmp_digest;
 +  crypto_cipher_t *tmp_crypto;
 +  size_t digest_len = 0;
 +  size_t cipher_key_len = 0;
 +
 +  tor_assert(crypto);
 +  tor_assert(key_data);
 +  tor_assert(!(crypto->f_crypto || crypto->b_crypto ||
 +             crypto->f_digest || crypto->b_digest));
 +
 +  /* Basic key size validation */
 +  if (is_hs_v3 && BUG(key_data_len != HS_NTOR_KEY_EXPANSION_KDF_OUT_LEN)) {
 +    goto err;
 +  } else if (!is_hs_v3 && BUG(key_data_len != CPATH_KEY_MATERIAL_LEN)) {
 +    goto err;
 +  }
 +
 +  /* If we are using this crypto for next gen onion services use SHA3-256,
 +     otherwise use good ol' SHA1 */
 +  if (is_hs_v3) {
 +    digest_len = DIGEST256_LEN;
 +    cipher_key_len = CIPHER256_KEY_LEN;
 +    crypto->f_digest = crypto_digest256_new(DIGEST_SHA3_256);
 +    crypto->b_digest = crypto_digest256_new(DIGEST_SHA3_256);
 +  } else {
 +    digest_len = DIGEST_LEN;
 +    cipher_key_len = CIPHER_KEY_LEN;
 +    crypto->f_digest = crypto_digest_new();
 +    crypto->b_digest = crypto_digest_new();
 +  }
 +
 +  tor_assert(digest_len != 0);
 +  tor_assert(cipher_key_len != 0);
 +  const int cipher_key_bits = (int) cipher_key_len * 8;
 +
 +  crypto_digest_add_bytes(crypto->f_digest, key_data, digest_len);
 +  crypto_digest_add_bytes(crypto->b_digest, key_data+digest_len, digest_len);
 +
 +  crypto->f_crypto = crypto_cipher_new_with_bits(key_data+(2*digest_len),
 +                                                cipher_key_bits);
 +  if (!crypto->f_crypto) {
 +    log_warn(LD_BUG,"Forward cipher initialization failed.");
 +    goto err;
 +  }
 +
 +  crypto->b_crypto = crypto_cipher_new_with_bits(
 +                                        key_data+(2*digest_len)+cipher_key_len,
 +                                        cipher_key_bits);
 +  if (!crypto->b_crypto) {
 +    log_warn(LD_BUG,"Backward cipher initialization failed.");
 +    goto err;
 +  }
 +
 +  if (reverse) {
 +    tmp_digest = crypto->f_digest;
 +    crypto->f_digest = crypto->b_digest;
 +    crypto->b_digest = tmp_digest;
 +    tmp_crypto = crypto->f_crypto;
 +    crypto->f_crypto = crypto->b_crypto;
 +    crypto->b_crypto = tmp_crypto;
 +  }
 +
 +  return 0;
 + err:
 +  relay_crypto_clear(crypto);
 +  return -1;
 +}
 +
 +/** Assert that <b>crypto</b> is valid and set. */
 +void
 +relay_crypto_assert_ok(const relay_crypto_t *crypto)
 +{
 +  tor_assert(crypto->f_crypto);
 +  tor_assert(crypto->b_crypto);
 +  tor_assert(crypto->f_digest);
 +  tor_assert(crypto->b_digest);
 +}
 +
Simple merge
Simple merge
diff --cc src/or/router.c
Simple merge
index 914cf4ef160e50e191d34c919fcf14d0f38b0599,8793c64ed3242c50dfb36261d922ad6d16d20488..7603eb3ecf66e6774c68e040fe2667f49faf8bf5
  #include "config.h"
  #include "connection.h"
  #include "control.h"
+ #include "crypto_rand.h"
  #include "directory.h"
  #include "dirserv.h"
 -#include "dirvote.h"
  #include "entrynodes.h"
  #include "fp_pair.h"
  #include "geoip.h"
index a729aa4b11602e9618dc5168807dfc5750a2c338,b00b1c636f7a8d162e7b79b7177b4d2a20713d6b..7af41c3baf4b708b751346bc757b10d4ea3673ff
  #define ROUTERPARSE_PRIVATE
  
  #include "or.h"
- #include "config.h"
  #include "circuitstats.h"
+ #include "config.h"
+ #include "crypto_util.h"
++#include "dirauth/shared_random.h"
  #include "dirserv.h"
 -#include "dirvote.h"
+ #include "entrynodes.h"
+ #include "memarea.h"
+ #include "microdesc.h"
+ #include "networkstatus.h"
  #include "parsecommon.h"
  #include "policies.h"
  #include "protover.h"
  #include "rendcommon.h"
- #include "router.h"
- #include "routerlist.h"
- #include "memarea.h"
- #include "microdesc.h"
- #include "networkstatus.h"
  #include "rephist.h"
+ #include "router.h"
  #include "routerkeys.h"
+ #include "routerlist.h"
  #include "routerparse.h"
- #include "entrynodes.h"
- #include "torcert.h"
  #include "sandbox.h"
 -#include "shared_random.h"
 +#include "shared_random_client.h"
+ #include "torcert.h"
 +#include "voting_schedule.h"
- #include "dirauth/shared_random.h"
  
  #undef log
  #include <math.h>
Simple merge
index 5efd99cacf130d7c1d8e1ba538d8de913c081f2f,a5c3a3b9658f1a0d030dede8e0d2787e6a2c7a24..f20f29578b967ec45a9bf160f659e1b6ef971d1b
@@@ -7,9 -7,11 +7,9 @@@
  #include <stdio.h>
  #include <string.h>
  
 -#include <event2/event.h>
 -
  #include "compat.h"
  #include "compat_libevent.h"
- #include "crypto.h"
+ #include "crypto_rand.h"
  #include "timers.h"
  #include "util.h"
  
diff --cc src/test/test.c
Simple merge
Simple merge
index 49275302966db90a9ec2dd3724cabd62d7dd82ca,7d3b5344bc4990fe340d367696febeb260113dc0..25b4e42877dce73146d588e33384999cf02d75c8
  #include "config.h"
  #include "control.h"
  #include "crypto_ed25519.h"
+ #include "crypto_rand.h"
  #include "directory.h"
  #include "dirserv.h"
 -#include "dirvote.h"
 +#include "dirauth/dirvote.h"
  #include "entrynodes.h"
  #include "hibernate.h"
  #include "memarea.h"
Simple merge
Simple merge
Simple merge
Simple merge
index d2198c621bf74066c965fd83165e00cdee4fa5d8,cad12481c93add3576917222c57cd3f94917e404..33b5e96070b078200a46e8bd8daad1dcd12bcba4
  #include "circuitbuild.h"
  #include "circuitlist.h"
  #include "circuituse.h"
- #include "crypto.h"
+ #include "crypto_rand.h"
 -#include "dirvote.h"
 +#include "dirauth/dirvote.h"
  #include "networkstatus.h"
  #include "nodelist.h"
  #include "relay.h"
  #include "routerparse.h"
--
  #include "hs_common.h"
  #include "hs_config.h"
  #include "hs_ident.h"
index eba98971845a3da7fbbe6c83a0ef8d5d4eebef30,0000000000000000000000000000000000000000..60bd4797192ef6be59467c97d1f67c1c224ed141
mode 100644,000000..100644
--- /dev/null
@@@ -1,184 -1,0 +1,185 @@@
 +/* Copyright 2001-2004 Roger Dingledine.
 + * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
 + * Copyright (c) 2007-2018, The Tor Project, Inc. */
 +/* See LICENSE for licensing information */
 +
 +#include "or.h"
 +#include "circuitbuild.h"
 +#define CIRCUITLIST_PRIVATE
 +#include "circuitlist.h"
++#include "crypto_rand.h"
 +#include "relay.h"
 +#include "relay_crypto.h"
 +#include "test.h"
 +
 +static const char KEY_MATERIAL[3][CPATH_KEY_MATERIAL_LEN] = {
 +  "    'My public key is in this signed x509 object', said Tom assertively.",
 +  "'Let's chart the pedal phlanges in the tomb', said Tom cryptographically",
 +  "     'Segmentation fault bugs don't _just happen_', said Tom seethingly.",
 +};
 +
 +typedef struct testing_circuitset_t {
 +  or_circuit_t *or_circ[3];
 +  origin_circuit_t *origin_circ;
 +} testing_circuitset_t;
 +
 +static int testing_circuitset_teardown(const struct testcase_t *testcase,
 +                                       void *ptr);
 +
 +static void *
 +testing_circuitset_setup(const struct testcase_t *testcase)
 +{
 +  testing_circuitset_t *cs = tor_malloc_zero(sizeof(testing_circuitset_t));
 +  int i;
 +
 +  for (i=0; i<3; ++i) {
 +    cs->or_circ[i] = or_circuit_new(0, NULL);
 +    tt_int_op(0, OP_EQ,
 +              relay_crypto_init(&cs->or_circ[i]->crypto,
 +                                KEY_MATERIAL[i], sizeof(KEY_MATERIAL[i]),
 +                                0, 0));
 +  }
 +
 +  cs->origin_circ = origin_circuit_new();
 +  cs->origin_circ->base_.purpose = CIRCUIT_PURPOSE_C_GENERAL;
 +  for (i=0; i<3; ++i) {
 +    crypt_path_t *hop = tor_malloc_zero(sizeof(*hop));
 +    relay_crypto_init(&hop->crypto, KEY_MATERIAL[i], sizeof(KEY_MATERIAL[i]),
 +                      0, 0);
 +    hop->state = CPATH_STATE_OPEN;
 +    onion_append_to_cpath(&cs->origin_circ->cpath, hop);
 +    tt_ptr_op(hop, OP_EQ, cs->origin_circ->cpath->prev);
 +  }
 +
 +  return cs;
 + done:
 +  testing_circuitset_teardown(testcase, cs);
 +  return NULL;
 +}
 +
 +static int
 +testing_circuitset_teardown(const struct testcase_t *testcase, void *ptr)
 +{
 +  (void)testcase;
 +  testing_circuitset_t *cs = ptr;
 +  int i;
 +  for (i=0; i<3; ++i) {
 +    circuit_free_(TO_CIRCUIT(cs->or_circ[i]));
 +  }
 +  circuit_free_(TO_CIRCUIT(cs->origin_circ));
 +  tor_free(cs);
 +  return 1;
 +}
 +
 +static const struct testcase_setup_t relaycrypt_setup = {
 +  testing_circuitset_setup, testing_circuitset_teardown
 +};
 +
 +/* Test encrypting a cell to the final hop on a circuit, decrypting it
 + * at each hop, and recognizing it at the other end.  Then do it again
 + * and again as the state evolves. */
 +static void
 +test_relaycrypt_outbound(void *arg)
 +{
 +  testing_circuitset_t *cs = arg;
 +  tt_assert(cs);
 +
 +  relay_header_t rh;
 +  cell_t orig;
 +  cell_t encrypted;
 +  int i, j;
 +
 +  for (i = 0; i < 50; ++i) {
 +    crypto_rand((char *)&orig, sizeof(orig));
 +
 +    relay_header_unpack(&rh, orig.payload);
 +    rh.recognized = 0;
 +    memset(rh.integrity, 0, sizeof(rh.integrity));
 +    relay_header_pack(orig.payload, &rh);
 +
 +    memcpy(&encrypted, &orig, sizeof(orig));
 +
 +    /* Encrypt the cell to the last hop */
 +    relay_encrypt_cell_outbound(&encrypted, cs->origin_circ,
 +                                cs->origin_circ->cpath->prev);
 +
 +    for (j = 0; j < 3; ++j) {
 +      crypt_path_t *layer_hint = NULL;
 +      char recognized = 0;
 +      int r = relay_decrypt_cell(TO_CIRCUIT(cs->or_circ[j]),
 +                                 &encrypted,
 +                                 CELL_DIRECTION_OUT,
 +                                 &layer_hint, &recognized);
 +      tt_int_op(r, OP_EQ, 0);
 +      tt_ptr_op(layer_hint, OP_EQ, NULL);
 +      tt_int_op(recognized != 0, OP_EQ, j == 2);
 +    }
 +
 +    tt_mem_op(orig.payload, OP_EQ, encrypted.payload, CELL_PAYLOAD_SIZE);
 +  }
 +
 + done:
 +  ;
 +}
 +
 +/* As above, but simulate inbound cells from the last hop. */
 +static void
 +test_relaycrypt_inbound(void *arg)
 +{
 +  testing_circuitset_t *cs = arg;
 +  tt_assert(cs);
 +
 +  relay_header_t rh;
 +  cell_t orig;
 +  cell_t encrypted;
 +  int i, j;
 +
 +  for (i = 0; i < 50; ++i) {
 +    crypto_rand((char *)&orig, sizeof(orig));
 +
 +    relay_header_unpack(&rh, orig.payload);
 +    rh.recognized = 0;
 +    memset(rh.integrity, 0, sizeof(rh.integrity));
 +    relay_header_pack(orig.payload, &rh);
 +
 +    memcpy(&encrypted, &orig, sizeof(orig));
 +
 +    /* Encrypt the cell to the last hop */
 +    relay_encrypt_cell_inbound(&encrypted, cs->or_circ[2]);
 +
 +    crypt_path_t *layer_hint = NULL;
 +    char recognized = 0;
 +    int r;
 +    for (j = 1; j >= 0; --j) {
 +      r = relay_decrypt_cell(TO_CIRCUIT(cs->or_circ[j]),
 +                             &encrypted,
 +                             CELL_DIRECTION_IN,
 +                             &layer_hint, &recognized);
 +      tt_int_op(r, OP_EQ, 0);
 +      tt_ptr_op(layer_hint, OP_EQ, NULL);
 +      tt_int_op(recognized, OP_EQ, 0);
 +    }
 +
 +    relay_decrypt_cell(TO_CIRCUIT(cs->origin_circ),
 +                       &encrypted,
 +                       CELL_DIRECTION_IN,
 +                       &layer_hint, &recognized);
 +    tt_int_op(r, OP_EQ, 0);
 +    tt_int_op(recognized, OP_EQ, 1);
 +    tt_ptr_op(layer_hint, OP_EQ, cs->origin_circ->cpath->prev);
 +
 +    tt_mem_op(orig.payload, OP_EQ, encrypted.payload, CELL_PAYLOAD_SIZE);
 +  }
 + done:
 +  ;
 +}
 +
 +#define TEST(name) \
 +  { # name, test_relaycrypt_ ## name, 0, &relaycrypt_setup, NULL }
 +
 +struct testcase_t relaycrypt_tests[] = {
 +  TEST(outbound),
 +  TEST(inbound),
 +  END_OF_TESTCASES
 +};
 +
index 71b487f35bffd112abcdeb320d566e43f6704b90,e56a868e0ecdf5a440cf39a1bf76bb9afb853a2e..7fed6562821747ecca9b808f4a63d7de99fa6288
@@@ -18,8 -18,9 +18,9 @@@
  #include "connection.h"
  #include "container.h"
  #include "control.h"
+ #include "crypto_rand.h"
  #include "directory.h"
 -#include "dirvote.h"
 +#include "dirauth/dirvote.h"
  #include "entrynodes.h"
  #include "hibernate.h"
  #include "microdesc.h"
index 775a1c1d235c25227b16fa85566306fbd63b3a00,7928518efb1f5b88b2a038539fdc1f9fa2bd7e81..f6ab0dfabd8b895c3c48098ffdbf3abb9f8797d2
@@@ -9,17 -9,16 +9,18 @@@
  #include "or.h"
  #include "test.h"
  #include "config.h"
 -#include "dirvote.h"
 -#include "shared_random.h"
 -#include "shared_random_state.h"
+ #include "crypto_rand.h"
 +#include "dirauth/dirvote.h"
 +#include "dirauth/shared_random.h"
 +#include "dirauth/shared_random_state.h"
++#include "log_test_helpers.h"
++#include "networkstatus.h"
++#include "router.h"
  #include "routerkeys.h"
  #include "routerlist.h"
--#include "router.h"
  #include "routerparse.h"
 -#include "networkstatus.h"
 -#include "log_test_helpers.h"
 +#include "shared_random_client.h"
- #include "networkstatus.h"
- #include "log_test_helpers.h"
 +#include "voting_schedule.h"
  
  static authority_cert_t *mock_cert;
  
Simple merge
Simple merge
Simple merge