aboutsummaryrefslogtreecommitdiff
path: root/src/test
diff options
context:
space:
mode:
Diffstat (limited to 'src/test')
-rw-r--r--src/test/bench.c89
-rwxr-xr-xsrc/test/bt_test.py2
-rw-r--r--src/test/ed25519_exts_ref.py2
-rw-r--r--src/test/fakechans.h2
-rw-r--r--src/test/fuzz/dict/http2
-rw-r--r--src/test/fuzz/fuzz_consensus.c17
-rw-r--r--src/test/fuzz/fuzz_descriptor.c18
-rw-r--r--src/test/fuzz/fuzz_diff.c8
-rw-r--r--src/test/fuzz/fuzz_diff_apply.c8
-rw-r--r--src/test/fuzz/fuzz_extrainfo.c16
-rw-r--r--src/test/fuzz/fuzz_hsdescv2.c14
-rw-r--r--src/test/fuzz/fuzz_hsdescv3.c20
-rw-r--r--src/test/fuzz/fuzz_http.c23
-rw-r--r--src/test/fuzz/fuzz_http_connect.c23
-rw-r--r--src/test/fuzz/fuzz_iptsv2.c18
-rw-r--r--src/test/fuzz/fuzz_microdesc.c16
-rw-r--r--src/test/fuzz/fuzz_socks.c50
-rw-r--r--src/test/fuzz/fuzz_vrs.c23
-rw-r--r--src/test/fuzz/fuzzing.h2
-rw-r--r--src/test/fuzz/fuzzing_common.c29
-rw-r--r--src/test/fuzz/include.am127
-rwxr-xr-xsrc/test/fuzz_static_testcases.sh2
-rw-r--r--src/test/hs_ntor_ref.py2
-rw-r--r--src/test/hs_test_helpers.c57
-rw-r--r--src/test/hs_test_helpers.h6
-rw-r--r--src/test/include.am142
-rw-r--r--src/test/log_test_helpers.c26
-rw-r--r--src/test/log_test_helpers.h46
-rwxr-xr-xsrc/test/ntor_ref.py2
-rw-r--r--src/test/ope_ref.py40
-rw-r--r--src/test/rend_test_helpers.c15
-rw-r--r--src/test/rend_test_helpers.h4
-rw-r--r--src/test/rust_supp.txt1
-rw-r--r--src/test/test-child.c2
-rw-r--r--src/test/test-memwipe.c12
-rwxr-xr-xsrc/test/test-network.sh4
-rw-r--r--src/test/test-timers.c29
-rw-r--r--src/test/test.c471
-rw-r--r--src/test/test.h48
-rw-r--r--src/test/test_accounting.c15
-rw-r--r--src/test/test_addr.c228
-rw-r--r--src/test/test_address.c42
-rw-r--r--src/test/test_address_set.c26
-rw-r--r--src/test/test_bridges.c704
-rw-r--r--src/test/test_bt_cl.c14
-rw-r--r--src/test/test_buffers.c18
-rw-r--r--src/test/test_bwmgt.c233
-rw-r--r--src/test/test_cell_formats.c31
-rw-r--r--src/test/test_cell_queue.c15
-rw-r--r--src/test/test_channel.c46
-rw-r--r--src/test/test_channelpadding.c130
-rw-r--r--src/test/test_channeltls.c28
-rw-r--r--src/test/test_checkdir.c14
-rw-r--r--src/test/test_circuitbuild.c18
-rw-r--r--src/test/test_circuitlist.c23
-rw-r--r--src/test/test_circuitmux.c63
-rw-r--r--src/test/test_circuitstats.c27
-rw-r--r--src/test/test_circuituse.c21
-rw-r--r--src/test/test_compat_libevent.c71
-rw-r--r--src/test/test_config.c217
-rw-r--r--src/test/test_connection.c44
-rw-r--r--src/test/test_connection.h2
-rw-r--r--src/test/test_conscache.c12
-rw-r--r--src/test/test_consdiff.c12
-rw-r--r--src/test/test_consdiffmgr.c30
-rw-r--r--src/test/test_containers.c20
-rw-r--r--src/test/test_controller.c171
-rw-r--r--src/test/test_controller_events.c160
-rw-r--r--src/test/test_crypto.c271
-rw-r--r--src/test/test_crypto_ope.c154
-rw-r--r--src/test/test_crypto_openssl.c17
-rw-r--r--src/test/test_crypto_slow.c16
-rw-r--r--src/test/test_data.c4
-rw-r--r--src/test/test_dir.c692
-rw-r--r--src/test/test_dir_common.c26
-rw-r--r--src/test/test_dir_common.h7
-rw-r--r--src/test/test_dir_handle_get.c72
-rw-r--r--src/test/test_dns.c17
-rw-r--r--src/test/test_dos.c29
-rw-r--r--src/test/test_entryconn.c28
-rw-r--r--src/test/test_entrynodes.c281
-rw-r--r--src/test/test_extorport.c50
-rw-r--r--src/test/test_geoip.c580
-rw-r--r--src/test/test_guardfraction.c33
-rw-r--r--src/test/test_handles.c11
-rw-r--r--src/test/test_helpers.c68
-rw-r--r--src/test/test_helpers.h7
-rw-r--r--src/test/test_hs.c109
-rw-r--r--src/test/test_hs_cache.c51
-rw-r--r--src/test/test_hs_cell.c19
-rw-r--r--src/test/test_hs_client.c396
-rw-r--r--src/test/test_hs_common.c99
-rw-r--r--src/test/test_hs_config.c32
-rw-r--r--src/test/test_hs_control.c39
-rw-r--r--src/test/test_hs_descriptor.c288
-rw-r--r--src/test/test_hs_intropoint.c37
-rw-r--r--src/test/test_hs_ntor.c13
-rw-r--r--src/test/test_hs_ntor_cl.c22
-rw-r--r--src/test/test_hs_service.c739
-rw-r--r--src/test/test_introduce.c10
-rw-r--r--src/test/test_keypin.c9
-rw-r--r--src/test/test_link_handshake.c86
-rw-r--r--src/test/test_logging.c20
-rw-r--r--src/test/test_mainloop.c142
-rw-r--r--src/test/test_microdesc.c81
-rw-r--r--src/test/test_nodelist.c56
-rw-r--r--src/test/test_ntor_cl.c18
-rw-r--r--src/test/test_oom.c26
-rw-r--r--src/test/test_oos.c19
-rw-r--r--src/test/test_options.c174
-rw-r--r--src/test/test_pem.c122
-rw-r--r--src/test/test_periodic_event.c333
-rw-r--r--src/test/test_policy.c103
-rw-r--r--src/test/test_procmon.c10
-rw-r--r--src/test/test_proto_http.c12
-rw-r--r--src/test/test_proto_misc.c20
-rw-r--r--src/test/test_protover.c46
-rw-r--r--src/test/test_pt.c26
-rw-r--r--src/test/test_pubsub.c85
-rw-r--r--src/test/test_rebind.py93
-rwxr-xr-xsrc/test/test_rebind.sh19
-rw-r--r--src/test/test_relay.c130
-rw-r--r--src/test/test_relaycell.c837
-rw-r--r--src/test/test_relaycrypt.c190
-rw-r--r--src/test/test_rendcache.c27
-rw-r--r--src/test/test_replay.c8
-rw-r--r--src/test/test_router.c153
-rw-r--r--src/test/test_routerkeys.c63
-rw-r--r--src/test/test_routerlist.c242
-rw-r--r--src/test/test_routerset.c27
-rwxr-xr-xsrc/test/test_rust.sh3
-rw-r--r--src/test/test_scheduler.c97
-rw-r--r--src/test/test_shared_random.c112
-rw-r--r--src/test/test_slow.c6
-rw-r--r--src/test/test_socks.c29
-rw-r--r--src/test/test_status.c38
-rw-r--r--src/test/test_storagedir.c13
-rw-r--r--src/test/test_switch_id.c9
-rw-r--r--src/test/test_threads.c38
-rw-r--r--src/test/test_tortls.c2755
-rw-r--r--src/test/test_tortls.h13
-rw-r--r--src/test/test_tortls_openssl.c2316
-rw-r--r--src/test/test_util.c383
-rw-r--r--src/test/test_util_format.c13
-rw-r--r--src/test/test_util_process.c10
-rw-r--r--src/test/test_util_slow.c19
-rw-r--r--src/test/test_voting_schedule.c64
-rw-r--r--src/test/test_workqueue.c67
-rw-r--r--src/test/test_x509.c205
-rwxr-xr-xsrc/test/test_zero_length_keys.sh6
-rw-r--r--src/test/testing_common.c72
-rw-r--r--src/test/testing_rsakeys.c10
152 files changed, 12048 insertions, 5477 deletions
diff --git a/src/test/bench.c b/src/test/bench.c
index 92d7a244f7..959d4374b1 100644
--- a/src/test/bench.c
+++ b/src/test/bench.c
@@ -1,6 +1,6 @@
/* Copyright (c) 2001-2004, Roger Dingledine.
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2017, The Tor Project, Inc. */
+ * Copyright (c) 2007-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
/**
@@ -10,20 +10,33 @@
#include "orconfig.h"
-#include "or.h"
-#include "onion_tap.h"
-#include "relay.h"
+#include "core/or/or.h"
+#include "core/crypto/onion_tap.h"
+#include "core/crypto/relay_crypto.h"
+
+#ifdef ENABLE_OPENSSL
#include <openssl/opensslv.h>
#include <openssl/evp.h>
#include <openssl/ec.h>
#include <openssl/ecdh.h>
#include <openssl/obj_mac.h>
+#endif
+
+#include "core/or/circuitlist.h"
+#include "app/config/config.h"
+#include "lib/crypt_ops/crypto_curve25519.h"
+#include "lib/crypt_ops/crypto_dh.h"
+#include "core/crypto/onion_ntor.h"
+#include "lib/crypt_ops/crypto_ed25519.h"
+#include "lib/crypt_ops/crypto_rand.h"
+#include "feature/dircommon/consdiff.h"
+#include "lib/compress/compress.h"
+
+#include "core/or/cell_st.h"
+#include "core/or/or_circuit_st.h"
-#include "config.h"
-#include "crypto_curve25519.h"
-#include "onion_ntor.h"
-#include "crypto_ed25519.h"
-#include "consdiff.h"
+#include "lib/crypt_ops/digestset.h"
+#include "lib/crypt_ops/crypto_init.h"
#if defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_PROCESS_CPUTIME_ID)
static uint64_t nanostart;
@@ -370,7 +383,7 @@ bench_dmap(void)
crypto_rand(d, 20);
smartlist_add(sl2, tor_memdup(d, 20));
}
- printf("nbits=%d\n", ds->mask+1);
+ //printf("nbits=%d\n", ds->mask+1);
reset_perftime();
@@ -398,18 +411,20 @@ bench_dmap(void)
NANOCOUNT(pt3, pt4, iters*elts));
for (i = 0; i < iters; ++i) {
- SMARTLIST_FOREACH(sl, const char *, cp, n += digestset_contains(ds, cp));
- SMARTLIST_FOREACH(sl2, const char *, cp, n += digestset_contains(ds, cp));
+ SMARTLIST_FOREACH(sl, const char *, cp,
+ n += digestset_probably_contains(ds, cp));
+ SMARTLIST_FOREACH(sl2, const char *, cp,
+ n += digestset_probably_contains(ds, cp));
}
end = perftime();
- printf("digestset_contains: %.2f ns per element.\n",
+ printf("digestset_probably_contains: %.2f ns per element.\n",
NANOCOUNT(pt4, end, iters*elts*2));
/* We need to use this, or else the whole loop gets optimized out. */
printf("Hits == %d\n", n);
for (i = 0; i < fpostests; ++i) {
crypto_rand(d, 20);
- if (digestset_contains(ds, d)) ++fp;
+ if (digestset_probably_contains(ds, d)) ++fp;
}
printf("False positive rate on digestset: %.2f%%\n",
(fp/(double)fpostests)*100);
@@ -458,18 +473,19 @@ bench_digest(void)
for (int i = 0; lens[i] > 0; ++i) {
reset_perftime();
start = perftime();
+ int failures = 0;
for (int j = 0; j < N; ++j) {
switch (alg) {
case DIGEST_SHA1:
- crypto_digest(out, buf, lens[i]);
+ failures += crypto_digest(out, buf, lens[i]) < 0;
break;
case DIGEST_SHA256:
case DIGEST_SHA3_256:
- crypto_digest256(out, buf, lens[i], alg);
+ failures += crypto_digest256(out, buf, lens[i], alg) < 0;
break;
case DIGEST_SHA512:
case DIGEST_SHA3_512:
- crypto_digest512(out, buf, lens[i], alg);
+ failures += crypto_digest512(out, buf, lens[i], alg) < 0;
break;
default:
tor_assert(0);
@@ -479,6 +495,8 @@ bench_digest(void)
printf("%s(%d): %.2f ns per call\n",
crypto_digest_algorithm_get_name(alg),
lens[i], NANOCOUNT(start,end,N));
+ if (failures)
+ printf("ERROR: crypto_digest failed %d times.\n", failures);
}
}
}
@@ -505,10 +523,10 @@ bench_cell_ops(void)
char key1[CIPHER_KEY_LEN], key2[CIPHER_KEY_LEN];
crypto_rand(key1, sizeof(key1));
crypto_rand(key2, sizeof(key2));
- or_circ->p_crypto = crypto_cipher_new(key1);
- or_circ->n_crypto = crypto_cipher_new(key2);
- or_circ->p_digest = crypto_digest_new();
- or_circ->n_digest = crypto_digest_new();
+ or_circ->crypto.f_crypto = crypto_cipher_new(key1);
+ or_circ->crypto.b_crypto = crypto_cipher_new(key2);
+ or_circ->crypto.f_digest = crypto_digest_new();
+ or_circ->crypto.b_digest = crypto_digest_new();
reset_perftime();
@@ -518,7 +536,8 @@ bench_cell_ops(void)
for (i = 0; i < iters; ++i) {
char recognized = 0;
crypt_path_t *layer_hint = NULL;
- relay_crypt(TO_CIRCUIT(or_circ), cell, d, &layer_hint, &recognized);
+ relay_decrypt_cell(TO_CIRCUIT(or_circ), cell, d,
+ &layer_hint, &recognized);
}
end = perftime();
printf("%sbound cells: %.2f ns per cell. (%.2f ns per byte of payload)\n",
@@ -527,10 +546,7 @@ bench_cell_ops(void)
NANOCOUNT(start,end,iters*CELL_PAYLOAD_SIZE));
}
- crypto_digest_free(or_circ->p_digest);
- crypto_digest_free(or_circ->n_digest);
- crypto_cipher_free(or_circ->p_crypto);
- crypto_cipher_free(or_circ->n_crypto);
+ relay_crypto_clear(&or_circ->crypto);
tor_free(or_circ);
tor_free(cell);
}
@@ -545,8 +561,8 @@ bench_dh(void)
reset_perftime();
start = perftime();
for (i = 0; i < iters; ++i) {
- char dh_pubkey_a[DH_BYTES], dh_pubkey_b[DH_BYTES];
- char secret_a[DH_BYTES], secret_b[DH_BYTES];
+ char dh_pubkey_a[DH1024_KEY_LEN], dh_pubkey_b[DH1024_KEY_LEN];
+ char secret_a[DH1024_KEY_LEN], secret_b[DH1024_KEY_LEN];
ssize_t slen_a, slen_b;
crypto_dh_t *dh_a = crypto_dh_new(DH_TYPE_TLS);
crypto_dh_t *dh_b = crypto_dh_new(DH_TYPE_TLS);
@@ -570,6 +586,7 @@ bench_dh(void)
" %f millisec each.\n", NANOCOUNT(start, end, iters)/1e6);
}
+#ifdef ENABLE_OPENSSL
static void
bench_ecdh_impl(int nid, const char *name)
{
@@ -580,7 +597,7 @@ bench_ecdh_impl(int nid, const char *name)
reset_perftime();
start = perftime();
for (i = 0; i < iters; ++i) {
- char secret_a[DH_BYTES], secret_b[DH_BYTES];
+ char secret_a[DH1024_KEY_LEN], secret_b[DH1024_KEY_LEN];
ssize_t slen_a, slen_b;
EC_KEY *dh_a = EC_KEY_new_by_curve_name(nid);
EC_KEY *dh_b = EC_KEY_new_by_curve_name(nid);
@@ -591,10 +608,10 @@ bench_ecdh_impl(int nid, const char *name)
EC_KEY_generate_key(dh_a);
EC_KEY_generate_key(dh_b);
- slen_a = ECDH_compute_key(secret_a, DH_BYTES,
+ slen_a = ECDH_compute_key(secret_a, DH1024_KEY_LEN,
EC_KEY_get0_public_key(dh_b), dh_a,
NULL);
- slen_b = ECDH_compute_key(secret_b, DH_BYTES,
+ slen_b = ECDH_compute_key(secret_b, DH1024_KEY_LEN,
EC_KEY_get0_public_key(dh_a), dh_b,
NULL);
@@ -619,6 +636,7 @@ bench_ecdh_p224(void)
{
bench_ecdh_impl(NID_secp224r1, "P-224");
}
+#endif
typedef void (*bench_fn)(void);
@@ -642,8 +660,11 @@ static struct benchmark_t benchmarks[] = {
ENT(cell_aes),
ENT(cell_ops),
ENT(dh),
+
+#ifdef ENABLE_OPENSSL
ENT(ecdh_p256),
ENT(ecdh_p224),
+#endif
{NULL,NULL,0}
};
@@ -671,9 +692,9 @@ main(int argc, const char **argv)
tor_threads_init();
tor_compress_init();
+ init_logging(1);
if (argc == 4 && !strcmp(argv[1], "diff")) {
- init_logging(1);
const int N = 200;
char *f1 = read_file_to_str(argv[2], RFTS_BIN, NULL);
char *f2 = read_file_to_str(argv[3], RFTS_BIN, NULL);
@@ -709,13 +730,12 @@ main(int argc, const char **argv)
reset_perftime();
- if (crypto_seed_rng() < 0) {
+ if (crypto_global_init(0, NULL, NULL) < 0) {
printf("Couldn't seed RNG; exiting.\n");
return 1;
}
init_protocol_warning_severity_level();
- crypto_init_siphash_key();
options = options_new();
init_logging(1);
options->command = CMD_RUN_UNITTESTS;
@@ -739,4 +759,3 @@ main(int argc, const char **argv)
return 0;
}
-
diff --git a/src/test/bt_test.py b/src/test/bt_test.py
index 4cb3326042..0eeb58c16c 100755
--- a/src/test/bt_test.py
+++ b/src/test/bt_test.py
@@ -1,4 +1,4 @@
-# Copyright 2013-2017, The Tor Project, Inc
+# Copyright 2013-2018, The Tor Project, Inc
# See LICENSE for licensing information
"""
diff --git a/src/test/ed25519_exts_ref.py b/src/test/ed25519_exts_ref.py
index f84d3002d3..a9090c9ed2 100644
--- a/src/test/ed25519_exts_ref.py
+++ b/src/test/ed25519_exts_ref.py
@@ -1,5 +1,5 @@
#!/usr/bin/python
-# Copyright 2014-2017, The Tor Project, Inc
+# Copyright 2014-2018, The Tor Project, Inc
# See LICENSE for licensing information
"""
diff --git a/src/test/fakechans.h b/src/test/fakechans.h
index ab5d8461b6..0770be8e04 100644
--- a/src/test/fakechans.h
+++ b/src/test/fakechans.h
@@ -1,4 +1,4 @@
- /* Copyright (c) 2014-2017, The Tor Project, Inc. */
+ /* Copyright (c) 2014-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
#ifndef TOR_FAKECHANS_H
diff --git a/src/test/fuzz/dict/http b/src/test/fuzz/dict/http
index 3b0531579d..63627ac380 100644
--- a/src/test/fuzz/dict/http
+++ b/src/test/fuzz/dict/http
@@ -4,7 +4,7 @@
#
# Extracted from directory_handle_command() in the tor source code
#
-# Copyright (c) 2016-2017, The Tor Project, Inc.
+# Copyright (c) 2016-2018, The Tor Project, Inc.
# See LICENSE for licensing information
#
# Usage:
diff --git a/src/test/fuzz/fuzz_consensus.c b/src/test/fuzz/fuzz_consensus.c
index 6610ade7ad..b56702a650 100644
--- a/src/test/fuzz/fuzz_consensus.c
+++ b/src/test/fuzz/fuzz_consensus.c
@@ -1,10 +1,14 @@
-/* Copyright (c) 2016-2017, The Tor Project, Inc. */
+/* Copyright (c) 2016-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
-#define ROUTERPARSE_PRIVATE
-#include "or.h"
-#include "routerparse.h"
-#include "networkstatus.h"
-#include "fuzzing.h"
+#define SIGCOMMON_PRIVATE
+#include "core/or/or.h"
+#include "feature/dirparse/ns_parse.h"
+#include "feature/dirparse/sigcommon.h"
+#include "feature/dirparse/unparseable.h"
+#include "feature/nodelist/networkstatus.h"
+#include "lib/crypt_ops/crypto_ed25519.h"
+#include "feature/nodelist/networkstatus_st.h"
+#include "test/fuzz/fuzzing.h"
static void
mock_dump_desc__nodump(const char *desc, const char *type)
@@ -75,4 +79,3 @@ fuzz_main(const uint8_t *data, size_t sz)
tor_free(str);
return 0;
}
-
diff --git a/src/test/fuzz/fuzz_descriptor.c b/src/test/fuzz/fuzz_descriptor.c
index 1a50beae17..3420113717 100644
--- a/src/test/fuzz/fuzz_descriptor.c
+++ b/src/test/fuzz/fuzz_descriptor.c
@@ -1,11 +1,14 @@
-/* Copyright (c) 2016-2017, The Tor Project, Inc. */
+/* Copyright (c) 2016-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
-#define ROUTERPARSE_PRIVATE
-#include "or.h"
-#include "routerparse.h"
-#include "routerlist.h"
-#include "routerkeys.h"
-#include "fuzzing.h"
+#define SIGCOMMON_PRIVATE
+#include "core/or/or.h"
+#include "feature/dirparse/routerparse.h"
+#include "feature/dirparse/sigcommon.h"
+#include "feature/dirparse/unparseable.h"
+#include "feature/nodelist/routerlist.h"
+#include "feature/nodelist/torcert.h"
+#include "feature/keymgt/loadkey.h"
+#include "test/fuzz/fuzzing.h"
static int
mock_check_tap_onion_key_crosscert__nocheck(const uint8_t *crosscert,
@@ -76,4 +79,3 @@ fuzz_main(const uint8_t *data, size_t sz)
}
return 0;
}
-
diff --git a/src/test/fuzz/fuzz_diff.c b/src/test/fuzz/fuzz_diff.c
index 642380b512..1079856fdb 100644
--- a/src/test/fuzz/fuzz_diff.c
+++ b/src/test/fuzz/fuzz_diff.c
@@ -1,13 +1,13 @@
-/* Copyright (c) 2016, The Tor Project, Inc. */
+/* Copyright (c) 2016-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
#define CONSDIFF_PRIVATE
#include "orconfig.h"
-#include "or.h"
-#include "consdiff.h"
+#include "core/or/or.h"
+#include "feature/dircommon/consdiff.h"
-#include "fuzzing.h"
+#include "test/fuzz/fuzzing.h"
static int
mock_consensus_compute_digest_(const char *c, consensus_digest_t *d)
diff --git a/src/test/fuzz/fuzz_diff_apply.c b/src/test/fuzz/fuzz_diff_apply.c
index 8d7bf751bf..165d0e6126 100644
--- a/src/test/fuzz/fuzz_diff_apply.c
+++ b/src/test/fuzz/fuzz_diff_apply.c
@@ -1,13 +1,13 @@
-/* Copyright (c) 2016, The Tor Project, Inc. */
+/* Copyright (c) 2016-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
#define CONSDIFF_PRIVATE
#include "orconfig.h"
-#include "or.h"
-#include "consdiff.h"
+#include "core/or/or.h"
+#include "feature/dircommon/consdiff.h"
-#include "fuzzing.h"
+#include "test/fuzz/fuzzing.h"
static int
mock_consensus_compute_digest_(const char *c, consensus_digest_t *d)
diff --git a/src/test/fuzz/fuzz_extrainfo.c b/src/test/fuzz/fuzz_extrainfo.c
index 2a3de7ecf7..da0fe80838 100644
--- a/src/test/fuzz/fuzz_extrainfo.c
+++ b/src/test/fuzz/fuzz_extrainfo.c
@@ -1,11 +1,13 @@
-/* Copyright (c) 2016-2017, The Tor Project, Inc. */
+/* Copyright (c) 2016-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
-#define ROUTERPARSE_PRIVATE
-#include "or.h"
-#include "routerparse.h"
-#include "routerlist.h"
-#include "routerkeys.h"
-#include "fuzzing.h"
+#define SIGCOMMON_PRIVATE
+#include "core/or/or.h"
+#include "feature/dirparse/routerparse.h"
+#include "feature/dirparse/sigcommon.h"
+#include "feature/dirparse/unparseable.h"
+#include "feature/nodelist/routerlist.h"
+#include "feature/relay/routerkeys.h"
+#include "test/fuzz/fuzzing.h"
static void
mock_dump_desc__nodump(const char *desc, const char *type)
diff --git a/src/test/fuzz/fuzz_hsdescv2.c b/src/test/fuzz/fuzz_hsdescv2.c
index 19db265716..667b58b3aa 100644
--- a/src/test/fuzz/fuzz_hsdescv2.c
+++ b/src/test/fuzz/fuzz_hsdescv2.c
@@ -1,10 +1,11 @@
-/* Copyright (c) 2016-2017, The Tor Project, Inc. */
+/* Copyright (c) 2016-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
-#define ROUTERPARSE_PRIVATE
-#include "or.h"
-#include "routerparse.h"
-#include "rendcommon.h"
-#include "fuzzing.h"
+#include "core/or/or.h"
+#include "feature/dirparse/unparseable.h"
+#include "feature/rend/rendcommon.h"
+#include "feature/rend/rendparse.h"
+#include "lib/crypt_ops/crypto_ed25519.h"
+#include "test/fuzz/fuzzing.h"
static void
mock_dump_desc__nodump(const char *desc, const char *type)
@@ -49,4 +50,3 @@ fuzz_main(const uint8_t *data, size_t sz)
tor_free(str);
return 0;
}
-
diff --git a/src/test/fuzz/fuzz_hsdescv3.c b/src/test/fuzz/fuzz_hsdescv3.c
index 428774e330..d5ddcc2e27 100644
--- a/src/test/fuzz/fuzz_hsdescv3.c
+++ b/src/test/fuzz/fuzz_hsdescv3.c
@@ -1,17 +1,15 @@
-/* Copyright (c) 2017, The Tor Project, Inc. */
+/* Copyright (c) 2017-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
-#define ROUTERPARSE_PRIVATE
#define HS_DESCRIPTOR_PRIVATE
-#include "or.h"
-#include "ed25519_cert.h" /* Trunnel interface. */
-#include "crypto_ed25519.h"
-#include "hs_descriptor.h"
-#include "routerparse.h"
-#include "util.h"
+#include "core/or/or.h"
+#include "trunnel/ed25519_cert.h" /* Trunnel interface. */
+#include "lib/crypt_ops/crypto_ed25519.h"
+#include "feature/hs/hs_descriptor.h"
+#include "feature/dirparse/unparseable.h"
-#include "fuzzing.h"
+#include "test/fuzz/fuzzing.h"
static void
mock_dump_desc__nodump(const char *desc, const char *type)
@@ -39,11 +37,13 @@ static size_t
mock_decrypt_desc_layer(const hs_descriptor_t *desc,
const uint8_t *encrypted_blob,
size_t encrypted_blob_size,
+ const uint8_t *descriptor_cookie,
int is_superencrypted_layer,
char **decrypted_out)
{
(void)is_superencrypted_layer;
(void)desc;
+ (void)descriptor_cookie;
const size_t overhead = HS_DESC_ENCRYPTED_SALT_LEN + DIGEST256_LEN;
if (encrypted_blob_size < overhead)
return 0;
@@ -85,7 +85,7 @@ fuzz_main(const uint8_t *data, size_t sz)
char *fuzzing_data = tor_memdup_nulterm(data, sz);
memset(subcredential, 'A', sizeof(subcredential));
- hs_desc_decode_descriptor(fuzzing_data, subcredential, &desc);
+ hs_desc_decode_descriptor(fuzzing_data, subcredential, NULL, &desc);
if (desc) {
log_debug(LD_GENERAL, "Decoding okay");
hs_descriptor_free(desc);
diff --git a/src/test/fuzz/fuzz_http.c b/src/test/fuzz/fuzz_http.c
index 2ffeb60244..06483282bc 100644
--- a/src/test/fuzz/fuzz_http.c
+++ b/src/test/fuzz/fuzz_http.c
@@ -1,20 +1,22 @@
-/* Copyright (c) 2016-2017, The Tor Project, Inc. */
+/* Copyright (c) 2016-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
#include "orconfig.h"
#define BUFFERS_PRIVATE
-#define DIRECTORY_PRIVATE
+#define DIRCACHE_PRIVATE
-#include "or.h"
-#include "backtrace.h"
-#include "buffers.h"
-#include "config.h"
-#include "connection.h"
-#include "directory.h"
-#include "torlog.h"
+#include "core/or/or.h"
+#include "lib/err/backtrace.h"
+#include "lib/container/buffers.h"
+#include "app/config/config.h"
+#include "core/mainloop/connection.h"
+#include "feature/dircache/dircache.h"
+#include "lib/log/log.h"
-#include "fuzzing.h"
+#include "feature/dircommon/dir_connection_st.h"
+
+#include "test/fuzz/fuzzing.h"
static void
mock_connection_write_to_buf_impl_(const char *string, size_t len,
@@ -130,4 +132,3 @@ fuzz_main(const uint8_t *stdin_buf, size_t data_size)
return 0;
}
-
diff --git a/src/test/fuzz/fuzz_http_connect.c b/src/test/fuzz/fuzz_http_connect.c
index dc674070b2..ca007a2c7f 100644
--- a/src/test/fuzz/fuzz_http_connect.c
+++ b/src/test/fuzz/fuzz_http_connect.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016-2017, The Tor Project, Inc. */
+/* Copyright (c) 2016-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
#include "orconfig.h"
@@ -6,16 +6,19 @@
#define BUFFERS_PRIVATE
#define CONNECTION_EDGE_PRIVATE
-#include "or.h"
-#include "backtrace.h"
-#include "buffers.h"
-#include "config.h"
-#include "connection.h"
-#include "connection_edge.h"
-#include "proto_socks.h"
-#include "torlog.h"
+#include "core/or/or.h"
+#include "lib/err/backtrace.h"
+#include "lib/container/buffers.h"
+#include "app/config/config.h"
+#include "core/mainloop/connection.h"
+#include "core/or/connection_edge.h"
+#include "core/proto/proto_socks.h"
+#include "lib/log/log.h"
-#include "fuzzing.h"
+#include "core/or/entry_connection_st.h"
+#include "core/or/socks_request_st.h"
+
+#include "test/fuzz/fuzzing.h"
static void
mock_connection_write_to_buf_impl_(const char *string, size_t len,
diff --git a/src/test/fuzz/fuzz_iptsv2.c b/src/test/fuzz/fuzz_iptsv2.c
index 4abde0c16d..265677eebe 100644
--- a/src/test/fuzz/fuzz_iptsv2.c
+++ b/src/test/fuzz/fuzz_iptsv2.c
@@ -1,10 +1,15 @@
-/* Copyright (c) 2016-2017, The Tor Project, Inc. */
+/* Copyright (c) 2016-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
-#define ROUTERPARSE_PRIVATE
-#include "or.h"
-#include "routerparse.h"
-#include "rendcommon.h"
-#include "fuzzing.h"
+
+#include "core/or/or.h"
+#include "feature/dirparse/unparseable.h"
+#include "feature/rend/rendcommon.h"
+#include "feature/rend/rendparse.h"
+#include "lib/crypt_ops/crypto_ed25519.h"
+
+#include "feature/rend/rend_service_descriptor_st.h"
+
+#include "test/fuzz/fuzzing.h"
static void
mock_dump_desc__nodump(const char *desc, const char *type)
@@ -43,4 +48,3 @@ fuzz_main(const uint8_t *data, size_t sz)
rend_service_descriptor_free(desc);
return 0;
}
-
diff --git a/src/test/fuzz/fuzz_microdesc.c b/src/test/fuzz/fuzz_microdesc.c
index 396115026e..ab54cf2a34 100644
--- a/src/test/fuzz/fuzz_microdesc.c
+++ b/src/test/fuzz/fuzz_microdesc.c
@@ -1,10 +1,13 @@
-/* Copyright (c) 2016-2017, The Tor Project, Inc. */
+/* Copyright (c) 2016-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
-#define ROUTERPARSE_PRIVATE
-#include "or.h"
-#include "routerparse.h"
-#include "microdesc.h"
-#include "fuzzing.h"
+
+#include "core/or/or.h"
+#include "feature/dirparse/microdesc_parse.h"
+#include "feature/dirparse/unparseable.h"
+#include "feature/nodelist/microdesc.h"
+#include "lib/crypt_ops/crypto_ed25519.h"
+
+#include "test/fuzz/fuzzing.h"
static void
mock_dump_desc__nodump(const char *desc, const char *type)
@@ -44,4 +47,3 @@ fuzz_main(const uint8_t *data, size_t sz)
}
return 0;
}
-
diff --git a/src/test/fuzz/fuzz_socks.c b/src/test/fuzz/fuzz_socks.c
new file mode 100644
index 0000000000..14c25304b1
--- /dev/null
+++ b/src/test/fuzz/fuzz_socks.c
@@ -0,0 +1,50 @@
+/* Copyright (c) 2016-2018, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#include "orconfig.h"
+
+#define BUFFERS_PRIVATE
+#include "core/or/or.h"
+
+#include "lib/container/buffers.h"
+#include "lib/err/backtrace.h"
+#include "lib/log/log.h"
+#include "core/proto/proto_socks.h"
+#include "feature/client/addressmap.h"
+
+#include "test/fuzz/fuzzing.h"
+
+int
+fuzz_init(void)
+{
+ addressmap_init();
+ return 0;
+}
+
+int
+fuzz_cleanup(void)
+{
+ addressmap_free_all();
+ return 0;
+}
+
+int
+fuzz_main(const uint8_t *stdin_buf, size_t data_size)
+{
+ buf_t *buffer = buf_new_with_data((char*)stdin_buf, data_size);
+ if (!buffer) {
+ tor_assert(data_size==0);
+ buffer = buf_new();
+ }
+
+ socks_request_t *request = socks_request_new();
+
+ int r = fetch_from_buf_socks(buffer, request, 0, 0);
+ log_info(LD_GENERAL, "Socks request status: %d", r);
+
+ /* Reset. */
+ buf_free(buffer);
+ socks_request_free(request);
+
+ return 0;
+}
diff --git a/src/test/fuzz/fuzz_vrs.c b/src/test/fuzz/fuzz_vrs.c
index baf0610a0b..0b869aa5c0 100644
--- a/src/test/fuzz/fuzz_vrs.c
+++ b/src/test/fuzz/fuzz_vrs.c
@@ -1,13 +1,19 @@
-/* Copyright (c) 2016-2017, The Tor Project, Inc. */
+/* Copyright (c) 2016-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
-#define ROUTERPARSE_PRIVATE
+#define NS_PARSE_PRIVATE
#define NETWORKSTATUS_PRIVATE
-#include "or.h"
-#include "routerparse.h"
-#include "memarea.h"
-#include "microdesc.h"
-#include "networkstatus.h"
-#include "fuzzing.h"
+#include "core/or/or.h"
+#include "feature/dirparse/ns_parse.h"
+#include "feature/dirparse/unparseable.h"
+#include "lib/memarea/memarea.h"
+#include "feature/nodelist/microdesc.h"
+#include "feature/nodelist/networkstatus.h"
+
+#include "feature/nodelist/networkstatus_st.h"
+#include "feature/nodelist/vote_routerstatus_st.h"
+#include "lib/crypt_ops/crypto_ed25519.h"
+
+#include "test/fuzz/fuzzing.h"
static void
mock_dump_desc__nodump(const char *desc, const char *type)
@@ -79,4 +85,3 @@ fuzz_main(const uint8_t *data, size_t sz)
tor_free(str);
return 0;
}
-
diff --git a/src/test/fuzz/fuzzing.h b/src/test/fuzz/fuzzing.h
index aecdbb4e52..e90e5d58e0 100644
--- a/src/test/fuzz/fuzzing.h
+++ b/src/test/fuzz/fuzzing.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016-2017, The Tor Project, Inc. */
+/* Copyright (c) 2016-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
#ifndef FUZZING_H
#define FUZZING_H
diff --git a/src/test/fuzz/fuzzing_common.c b/src/test/fuzz/fuzzing_common.c
index a96552f0fc..1401e4c28d 100644
--- a/src/test/fuzz/fuzzing_common.c
+++ b/src/test/fuzz/fuzzing_common.c
@@ -1,13 +1,14 @@
-/* Copyright (c) 2016-2017, The Tor Project, Inc. */
+/* Copyright (c) 2016-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
#define CRYPTO_ED25519_PRIVATE
#include "orconfig.h"
-#include "or.h"
-#include "backtrace.h"
-#include "config.h"
-#include "fuzzing.h"
-#include "crypto.h"
-#include "crypto_ed25519.h"
+#include "core/or/or.h"
+#include "lib/err/backtrace.h"
+#include "app/config/config.h"
+#include "test/fuzz/fuzzing.h"
+#include "lib/compress/compress.h"
+#include "lib/crypt_ops/crypto_ed25519.h"
+#include "lib/crypt_ops/crypto_init.h"
static or_options_t *mock_options = NULL;
static const or_options_t *
@@ -95,15 +96,20 @@ global_init(void)
{
tor_threads_init();
tor_compress_init();
- {
- struct sipkey sipkey = { 1337, 7331 };
- siphash_set_global_key(&sipkey);
- }
/* Initialise logging first */
init_logging(1);
configure_backtrace_handler(get_version());
+ if (crypto_global_init(0, NULL, NULL) < 0)
+ abort();
+
+ {
+ struct sipkey sipkey = { 1337, 7331 };
+ siphash_unset_global_key();
+ siphash_set_global_key(&sipkey);
+ }
+
/* set up the options. */
mock_options = tor_malloc_zero(sizeof(or_options_t));
MOCK(get_options, mock_get_options);
@@ -189,4 +195,3 @@ main(int argc, char **argv)
}
#endif
-
diff --git a/src/test/fuzz/include.am b/src/test/fuzz/include.am
index cd16dc05be..27eeced8c5 100644
--- a/src/test/fuzz/include.am
+++ b/src/test/fuzz/include.am
@@ -5,33 +5,19 @@ FUZZING_CPPFLAGS = \
FUZZING_CFLAGS = \
$(AM_CFLAGS) $(TEST_CFLAGS)
FUZZING_LDFLAG = \
- @TOR_LDFLAGS_zlib@ @TOR_LDFLAGS_openssl@ @TOR_LDFLAGS_libevent@
+ @TOR_LDFLAGS_zlib@ $(TOR_LDFLAGS_CRYPTLIB) @TOR_LDFLAGS_libevent@
FUZZING_LIBS = \
- src/or/libtor-testing.a \
- src/common/libor-crypto-testing.a \
- $(LIBKECCAK_TINY) \
- $(LIBDONNA) \
- src/common/libor-testing.a \
- src/common/libor-ctime-testing.a \
- src/common/libor-event-testing.a \
- src/trunnel/libor-trunnel-testing.a \
+ $(TOR_INTERNAL_TESTING_LIBS) \
$(rust_ldadd) \
@TOR_ZLIB_LIBS@ @TOR_LIB_MATH@ \
- @TOR_LIBEVENT_LIBS@ @TOR_OPENSSL_LIBS@ \
- @TOR_LIB_WS32@ @TOR_LIB_GDI@ @TOR_LIB_USERENV@ @CURVE25519_LIBS@ \
+ @TOR_LIBEVENT_LIBS@ $(TOR_LIBS_CRYPTLIB) \
+ @TOR_LIB_WS32@ @TOR_LIB_IPHLPAPI@ @TOR_LIB_GDI@ @TOR_LIB_USERENV@ @CURVE25519_LIBS@ \
@TOR_SYSTEMD_LIBS@ \
@TOR_LZMA_LIBS@ \
@TOR_ZSTD_LIBS@
oss-fuzz-prereqs: \
- src/or/libtor-testing.a \
- src/common/libor-crypto-testing.a \
- $(LIBKECCAK_TINY) \
- $(LIBDONNA) \
- src/common/libor-testing.a \
- src/common/libor-ctime-testing.a \
- src/common/libor-event-testing.a \
- src/trunnel/libor-trunnel-testing.a
+ $(TOR_INTERNAL_TESTING_LIBS)
noinst_HEADERS += \
src/test/fuzz/fuzzing.h
@@ -46,6 +32,7 @@ LIBOSS_FUZZ_CPPFLAGS = $(FUZZING_CPPFLAGS) -DLLVM_FUZZ
LIBOSS_FUZZ_CFLAGS = $(FUZZING_CFLAGS)
# ===== AFL fuzzers
+if UNITTESTS_ENABLED
src_test_fuzz_fuzz_consensus_SOURCES = \
src/test/fuzz/fuzzing_common.c \
src/test/fuzz/fuzz_consensus.c
@@ -53,7 +40,9 @@ src_test_fuzz_fuzz_consensus_CPPFLAGS = $(FUZZING_CPPFLAGS)
src_test_fuzz_fuzz_consensus_CFLAGS = $(FUZZING_CFLAGS)
src_test_fuzz_fuzz_consensus_LDFLAGS = $(FUZZING_LDFLAG)
src_test_fuzz_fuzz_consensus_LDADD = $(FUZZING_LIBS)
+endif
+if UNITTESTS_ENABLED
src_test_fuzz_fuzz_descriptor_SOURCES = \
src/test/fuzz/fuzzing_common.c \
src/test/fuzz/fuzz_descriptor.c
@@ -61,7 +50,9 @@ src_test_fuzz_fuzz_descriptor_CPPFLAGS = $(FUZZING_CPPFLAGS)
src_test_fuzz_fuzz_descriptor_CFLAGS = $(FUZZING_CFLAGS)
src_test_fuzz_fuzz_descriptor_LDFLAGS = $(FUZZING_LDFLAG)
src_test_fuzz_fuzz_descriptor_LDADD = $(FUZZING_LIBS)
+endif
+if UNITTESTS_ENABLED
src_test_fuzz_fuzz_diff_SOURCES = \
src/test/fuzz/fuzzing_common.c \
src/test/fuzz/fuzz_diff.c
@@ -69,7 +60,9 @@ src_test_fuzz_fuzz_diff_CPPFLAGS = $(FUZZING_CPPFLAGS)
src_test_fuzz_fuzz_diff_CFLAGS = $(FUZZING_CFLAGS)
src_test_fuzz_fuzz_diff_LDFLAGS = $(FUZZING_LDFLAG)
src_test_fuzz_fuzz_diff_LDADD = $(FUZZING_LIBS)
+endif
+if UNITTESTS_ENABLED
src_test_fuzz_fuzz_diff_apply_SOURCES = \
src/test/fuzz/fuzzing_common.c \
src/test/fuzz/fuzz_diff_apply.c
@@ -77,7 +70,9 @@ src_test_fuzz_fuzz_diff_apply_CPPFLAGS = $(FUZZING_CPPFLAGS)
src_test_fuzz_fuzz_diff_apply_CFLAGS = $(FUZZING_CFLAGS)
src_test_fuzz_fuzz_diff_apply_LDFLAGS = $(FUZZING_LDFLAG)
src_test_fuzz_fuzz_diff_apply_LDADD = $(FUZZING_LIBS)
+endif
+if UNITTESTS_ENABLED
src_test_fuzz_fuzz_extrainfo_SOURCES = \
src/test/fuzz/fuzzing_common.c \
src/test/fuzz/fuzz_extrainfo.c
@@ -85,7 +80,9 @@ src_test_fuzz_fuzz_extrainfo_CPPFLAGS = $(FUZZING_CPPFLAGS)
src_test_fuzz_fuzz_extrainfo_CFLAGS = $(FUZZING_CFLAGS)
src_test_fuzz_fuzz_extrainfo_LDFLAGS = $(FUZZING_LDFLAG)
src_test_fuzz_fuzz_extrainfo_LDADD = $(FUZZING_LIBS)
+endif
+if UNITTESTS_ENABLED
src_test_fuzz_fuzz_hsdescv2_SOURCES = \
src/test/fuzz/fuzzing_common.c \
src/test/fuzz/fuzz_hsdescv2.c
@@ -93,7 +90,9 @@ src_test_fuzz_fuzz_hsdescv2_CPPFLAGS = $(FUZZING_CPPFLAGS)
src_test_fuzz_fuzz_hsdescv2_CFLAGS = $(FUZZING_CFLAGS)
src_test_fuzz_fuzz_hsdescv2_LDFLAGS = $(FUZZING_LDFLAG)
src_test_fuzz_fuzz_hsdescv2_LDADD = $(FUZZING_LIBS)
+endif
+if UNITTESTS_ENABLED
src_test_fuzz_fuzz_hsdescv3_SOURCES = \
src/test/fuzz/fuzzing_common.c \
src/test/fuzz/fuzz_hsdescv3.c
@@ -101,7 +100,9 @@ src_test_fuzz_fuzz_hsdescv3_CPPFLAGS = $(FUZZING_CPPFLAGS)
src_test_fuzz_fuzz_hsdescv3_CFLAGS = $(FUZZING_CFLAGS)
src_test_fuzz_fuzz_hsdescv3_LDFLAGS = $(FUZZING_LDFLAG)
src_test_fuzz_fuzz_hsdescv3_LDADD = $(FUZZING_LIBS)
+endif
+if UNITTESTS_ENABLED
src_test_fuzz_fuzz_http_SOURCES = \
src/test/fuzz/fuzzing_common.c \
src/test/fuzz/fuzz_http.c
@@ -109,7 +110,9 @@ src_test_fuzz_fuzz_http_CPPFLAGS = $(FUZZING_CPPFLAGS)
src_test_fuzz_fuzz_http_CFLAGS = $(FUZZING_CFLAGS)
src_test_fuzz_fuzz_http_LDFLAGS = $(FUZZING_LDFLAG)
src_test_fuzz_fuzz_http_LDADD = $(FUZZING_LIBS)
+endif
+if UNITTESTS_ENABLED
src_test_fuzz_fuzz_http_connect_SOURCES = \
src/test/fuzz/fuzzing_common.c \
src/test/fuzz/fuzz_http_connect.c
@@ -117,7 +120,9 @@ src_test_fuzz_fuzz_http_connect_CPPFLAGS = $(FUZZING_CPPFLAGS)
src_test_fuzz_fuzz_http_connect_CFLAGS = $(FUZZING_CFLAGS)
src_test_fuzz_fuzz_http_connect_LDFLAGS = $(FUZZING_LDFLAG)
src_test_fuzz_fuzz_http_connect_LDADD = $(FUZZING_LIBS)
+endif
+if UNITTESTS_ENABLED
src_test_fuzz_fuzz_iptsv2_SOURCES = \
src/test/fuzz/fuzzing_common.c \
src/test/fuzz/fuzz_iptsv2.c
@@ -125,7 +130,9 @@ src_test_fuzz_fuzz_iptsv2_CPPFLAGS = $(FUZZING_CPPFLAGS)
src_test_fuzz_fuzz_iptsv2_CFLAGS = $(FUZZING_CFLAGS)
src_test_fuzz_fuzz_iptsv2_LDFLAGS = $(FUZZING_LDFLAG)
src_test_fuzz_fuzz_iptsv2_LDADD = $(FUZZING_LIBS)
+endif
+if UNITTESTS_ENABLED
src_test_fuzz_fuzz_microdesc_SOURCES = \
src/test/fuzz/fuzzing_common.c \
src/test/fuzz/fuzz_microdesc.c
@@ -133,7 +140,19 @@ src_test_fuzz_fuzz_microdesc_CPPFLAGS = $(FUZZING_CPPFLAGS)
src_test_fuzz_fuzz_microdesc_CFLAGS = $(FUZZING_CFLAGS)
src_test_fuzz_fuzz_microdesc_LDFLAGS = $(FUZZING_LDFLAG)
src_test_fuzz_fuzz_microdesc_LDADD = $(FUZZING_LIBS)
+endif
+if UNITTESTS_ENABLED
+src_test_fuzz_fuzz_socks_SOURCES = \
+ src/test/fuzz/fuzzing_common.c \
+ src/test/fuzz/fuzz_socks.c
+src_test_fuzz_fuzz_socks_CPPFLAGS = $(FUZZING_CPPFLAGS)
+src_test_fuzz_fuzz_socks_CFLAGS = $(FUZZING_CFLAGS)
+src_test_fuzz_fuzz_socks_LDFLAGS = $(FUZZING_LDFLAG)
+src_test_fuzz_fuzz_socks_LDADD = $(FUZZING_LIBS)
+endif
+
+if UNITTESTS_ENABLED
src_test_fuzz_fuzz_vrs_SOURCES = \
src/test/fuzz/fuzzing_common.c \
src/test/fuzz/fuzz_vrs.c
@@ -141,7 +160,9 @@ src_test_fuzz_fuzz_vrs_CPPFLAGS = $(FUZZING_CPPFLAGS)
src_test_fuzz_fuzz_vrs_CFLAGS = $(FUZZING_CFLAGS)
src_test_fuzz_fuzz_vrs_LDFLAGS = $(FUZZING_LDFLAG)
src_test_fuzz_fuzz_vrs_LDADD = $(FUZZING_LIBS)
+endif
+if UNITTESTS_ENABLED
FUZZERS = \
src/test/fuzz/fuzz-consensus \
src/test/fuzz/fuzz-descriptor \
@@ -154,94 +175,129 @@ FUZZERS = \
src/test/fuzz/fuzz-http-connect \
src/test/fuzz/fuzz-iptsv2 \
src/test/fuzz/fuzz-microdesc \
+ src/test/fuzz/fuzz-socks \
src/test/fuzz/fuzz-vrs
+endif
# ===== libfuzzer
if LIBFUZZER_ENABLED
+if UNITTESTS_ENABLED
src_test_fuzz_lf_fuzz_consensus_SOURCES = \
$(src_test_fuzz_fuzz_consensus_SOURCES)
src_test_fuzz_lf_fuzz_consensus_CPPFLAGS = $(LIBFUZZER_CPPFLAGS)
src_test_fuzz_lf_fuzz_consensus_CFLAGS = $(LIBFUZZER_CFLAGS)
src_test_fuzz_lf_fuzz_consensus_LDFLAGS = $(LIBFUZZER_LDFLAG)
src_test_fuzz_lf_fuzz_consensus_LDADD = $(LIBFUZZER_LIBS)
+endif
+if UNITTESTS_ENABLED
src_test_fuzz_lf_fuzz_descriptor_SOURCES = \
$(src_test_fuzz_fuzz_descriptor_SOURCES)
src_test_fuzz_lf_fuzz_descriptor_CPPFLAGS = $(LIBFUZZER_CPPFLAGS)
src_test_fuzz_lf_fuzz_descriptor_CFLAGS = $(LIBFUZZER_CFLAGS)
src_test_fuzz_lf_fuzz_descriptor_LDFLAGS = $(LIBFUZZER_LDFLAG)
src_test_fuzz_lf_fuzz_descriptor_LDADD = $(LIBFUZZER_LIBS)
+endif
+if UNITTESTS_ENABLED
src_test_fuzz_lf_fuzz_diff_SOURCES = \
$(src_test_fuzz_fuzz_diff_SOURCES)
src_test_fuzz_lf_fuzz_diff_CPPFLAGS = $(LIBFUZZER_CPPFLAGS)
src_test_fuzz_lf_fuzz_diff_CFLAGS = $(LIBFUZZER_CFLAGS)
src_test_fuzz_lf_fuzz_diff_LDFLAGS = $(LIBFUZZER_LDFLAG)
src_test_fuzz_lf_fuzz_diff_LDADD = $(LIBFUZZER_LIBS)
+endif
+if UNITTESTS_ENABLED
src_test_fuzz_lf_fuzz_diff_apply_SOURCES = \
$(src_test_fuzz_fuzz_diff_apply_SOURCES)
src_test_fuzz_lf_fuzz_diff_apply_CPPFLAGS = $(LIBFUZZER_CPPFLAGS)
src_test_fuzz_lf_fuzz_diff_apply_CFLAGS = $(LIBFUZZER_CFLAGS)
src_test_fuzz_lf_fuzz_diff_apply_LDFLAGS = $(LIBFUZZER_LDFLAG)
src_test_fuzz_lf_fuzz_diff_apply_LDADD = $(LIBFUZZER_LIBS)
+endif
+if UNITTESTS_ENABLED
src_test_fuzz_lf_fuzz_extrainfo_SOURCES = \
$(src_test_fuzz_fuzz_extrainfo_SOURCES)
src_test_fuzz_lf_fuzz_extrainfo_CPPFLAGS = $(LIBFUZZER_CPPFLAGS)
src_test_fuzz_lf_fuzz_extrainfo_CFLAGS = $(LIBFUZZER_CFLAGS)
src_test_fuzz_lf_fuzz_extrainfo_LDFLAGS = $(LIBFUZZER_LDFLAG)
src_test_fuzz_lf_fuzz_extrainfo_LDADD = $(LIBFUZZER_LIBS)
+endif
+if UNITTESTS_ENABLED
src_test_fuzz_lf_fuzz_hsdescv2_SOURCES = \
$(src_test_fuzz_fuzz_hsdescv2_SOURCES)
src_test_fuzz_lf_fuzz_hsdescv2_CPPFLAGS = $(LIBFUZZER_CPPFLAGS)
src_test_fuzz_lf_fuzz_hsdescv2_CFLAGS = $(LIBFUZZER_CFLAGS)
src_test_fuzz_lf_fuzz_hsdescv2_LDFLAGS = $(LIBFUZZER_LDFLAG)
src_test_fuzz_lf_fuzz_hsdescv2_LDADD = $(LIBFUZZER_LIBS)
+endif
+if UNITTESTS_ENABLED
src_test_fuzz_lf_fuzz_hsdescv3_SOURCES = \
$(src_test_fuzz_fuzz_hsdescv3_SOURCES)
src_test_fuzz_lf_fuzz_hsdescv3_CPPFLAGS = $(LIBFUZZER_CPPFLAGS)
src_test_fuzz_lf_fuzz_hsdescv3_CFLAGS = $(LIBFUZZER_CFLAGS)
src_test_fuzz_lf_fuzz_hsdescv3_LDFLAGS = $(LIBFUZZER_LDFLAG)
src_test_fuzz_lf_fuzz_hsdescv3_LDADD = $(LIBFUZZER_LIBS)
+endif
+if UNITTESTS_ENABLED
src_test_fuzz_lf_fuzz_http_SOURCES = \
$(src_test_fuzz_fuzz_http_SOURCES)
src_test_fuzz_lf_fuzz_http_CPPFLAGS = $(LIBFUZZER_CPPFLAGS)
src_test_fuzz_lf_fuzz_http_CFLAGS = $(LIBFUZZER_CFLAGS)
src_test_fuzz_lf_fuzz_http_LDFLAGS = $(LIBFUZZER_LDFLAG)
src_test_fuzz_lf_fuzz_http_LDADD = $(LIBFUZZER_LIBS)
+endif
+if UNITTESTS_ENABLED
src_test_fuzz_lf_fuzz_http_connect_SOURCES = \
$(src_test_fuzz_fuzz_http_connect_SOURCES)
src_test_fuzz_lf_fuzz_http_connect_CPPFLAGS = $(LIBFUZZER_CPPFLAGS)
src_test_fuzz_lf_fuzz_http_connect_CFLAGS = $(LIBFUZZER_CFLAGS)
src_test_fuzz_lf_fuzz_http_connect_LDFLAGS = $(LIBFUZZER_LDFLAG)
src_test_fuzz_lf_fuzz_http_connect_LDADD = $(LIBFUZZER_LIBS)
+endif
+if UNITTESTS_ENABLED
src_test_fuzz_lf_fuzz_iptsv2_SOURCES = \
$(src_test_fuzz_fuzz_iptsv2_SOURCES)
src_test_fuzz_lf_fuzz_iptsv2_CPPFLAGS = $(LIBFUZZER_CPPFLAGS)
src_test_fuzz_lf_fuzz_iptsv2_CFLAGS = $(LIBFUZZER_CFLAGS)
src_test_fuzz_lf_fuzz_iptsv2_LDFLAGS = $(LIBFUZZER_LDFLAG)
src_test_fuzz_lf_fuzz_iptsv2_LDADD = $(LIBFUZZER_LIBS)
+endif
+if UNITTESTS_ENABLED
src_test_fuzz_lf_fuzz_microdesc_SOURCES = \
$(src_test_fuzz_fuzz_microdesc_SOURCES)
src_test_fuzz_lf_fuzz_microdesc_CPPFLAGS = $(LIBFUZZER_CPPFLAGS)
src_test_fuzz_lf_fuzz_microdesc_CFLAGS = $(LIBFUZZER_CFLAGS)
src_test_fuzz_lf_fuzz_microdesc_LDFLAGS = $(LIBFUZZER_LDFLAG)
src_test_fuzz_lf_fuzz_microdesc_LDADD = $(LIBFUZZER_LIBS)
+endif
+if UNITTESTS_ENABLED
+src_test_fuzz_lf_fuzz_socks_SOURCES = \
+ $(src_test_fuzz_fuzz_socks_SOURCES)
+src_test_fuzz_lf_fuzz_socks_CPPFLAGS = $(LIBFUZZER_CPPFLAGS)
+src_test_fuzz_lf_fuzz_socks_CFLAGS = $(LIBFUZZER_CFLAGS)
+src_test_fuzz_lf_fuzz_socks_LDFLAGS = $(LIBFUZZER_LDFLAG)
+src_test_fuzz_lf_fuzz_socks_LDADD = $(LIBFUZZER_LIBS)
+endif
+
+if UNITTESTS_ENABLED
src_test_fuzz_lf_fuzz_vrs_SOURCES = \
$(src_test_fuzz_fuzz_vrs_SOURCES)
src_test_fuzz_lf_fuzz_vrs_CPPFLAGS = $(LIBFUZZER_CPPFLAGS)
src_test_fuzz_lf_fuzz_vrs_CFLAGS = $(LIBFUZZER_CFLAGS)
src_test_fuzz_lf_fuzz_vrs_LDFLAGS = $(LIBFUZZER_LDFLAG)
src_test_fuzz_lf_fuzz_vrs_LDADD = $(LIBFUZZER_LIBS)
+endif
LIBFUZZER_FUZZERS = \
src/test/fuzz/lf-fuzz-consensus \
@@ -255,6 +311,7 @@ LIBFUZZER_FUZZERS = \
src/test/fuzz/lf-fuzz-http-connect \
src/test/fuzz/lf-fuzz-iptsv2 \
src/test/fuzz/lf-fuzz-microdesc \
+ src/test/fuzz/lf-fuzz-socks \
src/test/fuzz/lf-fuzz-vrs
else
@@ -264,65 +321,96 @@ endif
# ===== oss-fuzz
if OSS_FUZZ_ENABLED
+if UNITTESTS_ENABLED
src_test_fuzz_liboss_fuzz_consensus_a_SOURCES = \
$(src_test_fuzz_fuzz_consensus_SOURCES)
src_test_fuzz_liboss_fuzz_consensus_a_CPPFLAGS = $(LIBOSS_FUZZ_CPPFLAGS)
src_test_fuzz_liboss_fuzz_consensus_a_CFLAGS = $(LIBOSS_FUZZ_CFLAGS)
+endif
+if UNITTESTS_ENABLED
src_test_fuzz_liboss_fuzz_descriptor_a_SOURCES = \
$(src_test_fuzz_fuzz_descriptor_SOURCES)
src_test_fuzz_liboss_fuzz_descriptor_a_CPPFLAGS = $(LIBOSS_FUZZ_CPPFLAGS)
src_test_fuzz_liboss_fuzz_descriptor_a_CFLAGS = $(LIBOSS_FUZZ_CFLAGS)
+endif
+if UNITTESTS_ENABLED
src_test_fuzz_liboss_fuzz_diff_a_SOURCES = \
$(src_test_fuzz_fuzz_diff_SOURCES)
src_test_fuzz_liboss_fuzz_diff_a_CPPFLAGS = $(LIBOSS_FUZZ_CPPFLAGS)
src_test_fuzz_liboss_fuzz_diff_a_CFLAGS = $(LIBOSS_FUZZ_CFLAGS)
+endif
+if UNITTESTS_ENABLED
src_test_fuzz_liboss_fuzz_diff_apply_a_SOURCES = \
$(src_test_fuzz_fuzz_diff_apply_SOURCES)
src_test_fuzz_liboss_fuzz_diff_apply_a_CPPFLAGS = $(LIBOSS_FUZZ_CPPFLAGS)
src_test_fuzz_liboss_fuzz_diff_apply_a_CFLAGS = $(LIBOSS_FUZZ_CFLAGS)
+endif
+if UNITTESTS_ENABLED
src_test_fuzz_liboss_fuzz_extrainfo_a_SOURCES = \
$(src_test_fuzz_fuzz_extrainfo_SOURCES)
src_test_fuzz_liboss_fuzz_extrainfo_a_CPPFLAGS = $(LIBOSS_FUZZ_CPPFLAGS)
src_test_fuzz_liboss_fuzz_extrainfo_a_CFLAGS = $(LIBOSS_FUZZ_CFLAGS)
+endif
+if UNITTESTS_ENABLED
src_test_fuzz_liboss_fuzz_hsdescv2_a_SOURCES = \
$(src_test_fuzz_fuzz_hsdescv2_SOURCES)
src_test_fuzz_liboss_fuzz_hsdescv2_a_CPPFLAGS = $(LIBOSS_FUZZ_CPPFLAGS)
src_test_fuzz_liboss_fuzz_hsdescv2_a_CFLAGS = $(LIBOSS_FUZZ_CFLAGS)
+endif
+if UNITTESTS_ENABLED
src_test_fuzz_liboss_fuzz_hsdescv3_a_SOURCES = \
$(src_test_fuzz_fuzz_hsdescv3_SOURCES)
src_test_fuzz_liboss_fuzz_hsdescv3_a_CPPFLAGS = $(LIBOSS_FUZZ_CPPFLAGS)
src_test_fuzz_liboss_fuzz_hsdescv3_a_CFLAGS = $(LIBOSS_FUZZ_CFLAGS)
+endif
+if UNITTESTS_ENABLED
src_test_fuzz_liboss_fuzz_http_a_SOURCES = \
$(src_test_fuzz_fuzz_http_SOURCES)
src_test_fuzz_liboss_fuzz_http_a_CPPFLAGS = $(LIBOSS_FUZZ_CPPFLAGS)
src_test_fuzz_liboss_fuzz_http_a_CFLAGS = $(LIBOSS_FUZZ_CFLAGS)
+endif
+if UNITTESTS_ENABLED
src_test_fuzz_liboss_fuzz_http_connect_a_SOURCES = \
$(src_test_fuzz_fuzz_http_connect_SOURCES)
src_test_fuzz_liboss_fuzz_http_connect_a_CPPFLAGS = $(LIBOSS_FUZZ_CPPFLAGS)
src_test_fuzz_liboss_fuzz_http_connect_a_CFLAGS = $(LIBOSS_FUZZ_CFLAGS)
+endif
+if UNITTESTS_ENABLED
src_test_fuzz_liboss_fuzz_iptsv2_a_SOURCES = \
$(src_test_fuzz_fuzz_iptsv2_SOURCES)
src_test_fuzz_liboss_fuzz_iptsv2_a_CPPFLAGS = $(LIBOSS_FUZZ_CPPFLAGS)
src_test_fuzz_liboss_fuzz_iptsv2_a_CFLAGS = $(LIBOSS_FUZZ_CFLAGS)
+endif
+if UNITTESTS_ENABLED
src_test_fuzz_liboss_fuzz_microdesc_a_SOURCES = \
$(src_test_fuzz_fuzz_microdesc_SOURCES)
src_test_fuzz_liboss_fuzz_microdesc_a_CPPFLAGS = $(LIBOSS_FUZZ_CPPFLAGS)
src_test_fuzz_liboss_fuzz_microdesc_a_CFLAGS = $(LIBOSS_FUZZ_CFLAGS)
+endif
+if UNITTESTS_ENABLED
+src_test_fuzz_liboss_fuzz_socks_a_SOURCES = \
+ $(src_test_fuzz_fuzz_socks_SOURCES)
+src_test_fuzz_liboss_fuzz_socks_a_CPPFLAGS = $(LIBOSS_FUZZ_CPPFLAGS)
+src_test_fuzz_liboss_fuzz_socks_a_CFLAGS = $(LIBOSS_FUZZ_CFLAGS)
+endif
+
+if UNITTESTS_ENABLED
src_test_fuzz_liboss_fuzz_vrs_a_SOURCES = \
$(src_test_fuzz_fuzz_vrs_SOURCES)
src_test_fuzz_liboss_fuzz_vrs_a_CPPFLAGS = $(LIBOSS_FUZZ_CPPFLAGS)
src_test_fuzz_liboss_fuzz_vrs_a_CFLAGS = $(LIBOSS_FUZZ_CFLAGS)
+endif
OSS_FUZZ_FUZZERS = \
src/test/fuzz/liboss-fuzz-consensus.a \
@@ -336,6 +424,7 @@ OSS_FUZZ_FUZZERS = \
src/test/fuzz/liboss-fuzz-http-connect.a \
src/test/fuzz/liboss-fuzz-iptsv2.a \
src/test/fuzz/liboss-fuzz-microdesc.a \
+ src/test/fuzz/liboss-fuzz-socks.a \
src/test/fuzz/liboss-fuzz-vrs.a
else
diff --git a/src/test/fuzz_static_testcases.sh b/src/test/fuzz_static_testcases.sh
index 3cb45ad5e6..138f85b106 100755
--- a/src/test/fuzz_static_testcases.sh
+++ b/src/test/fuzz_static_testcases.sh
@@ -1,6 +1,6 @@
#!/bin/sh
-# Copyright (c) 2016-2017, The Tor Project, Inc.
+# Copyright (c) 2016-2018, The Tor Project, Inc.
# See LICENSE for licensing information
set -e
diff --git a/src/test/hs_ntor_ref.py b/src/test/hs_ntor_ref.py
index 542b02d2e0..0c5756ad73 100644
--- a/src/test/hs_ntor_ref.py
+++ b/src/test/hs_ntor_ref.py
@@ -1,5 +1,5 @@
#!/usr/bin/python
-# Copyright 2017, The Tor Project, Inc
+# Copyright 2017-2018, The Tor Project, Inc
# See LICENSE for licensing information
"""
diff --git a/src/test/hs_test_helpers.c b/src/test/hs_test_helpers.c
index 5c1b9123d8..dcec1b9d48 100644
--- a/src/test/hs_test_helpers.c
+++ b/src/test/hs_test_helpers.c
@@ -1,13 +1,13 @@
-/* Copyright (c) 2017, The Tor Project, Inc. */
+/* Copyright (c) 2017-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
-#include "or.h"
-#include "crypto_ed25519.h"
-#include "test.h"
-#include "torcert.h"
+#include "core/or/or.h"
+#include "lib/crypt_ops/crypto_ed25519.h"
+#include "test/test.h"
+#include "feature/nodelist/torcert.h"
-#include "hs_common.h"
-#include "hs_test_helpers.h"
+#include "feature/hs/hs_common.h"
+#include "test/hs_test_helpers.h"
hs_desc_intro_point_t *
hs_helper_build_intro_point(const ed25519_keypair_t *signing_kp, time_t now,
@@ -98,8 +98,11 @@ static hs_descriptor_t *
hs_helper_build_hs_desc_impl(unsigned int no_ip,
const ed25519_keypair_t *signing_kp)
{
+ int ret;
+ int i;
time_t now = approx_time();
ed25519_keypair_t blinded_kp;
+ curve25519_keypair_t auth_ephemeral_kp;
hs_descriptor_t *descp = NULL, *desc = tor_malloc_zero(sizeof(*desc));
desc->plaintext_data.version = HS_DESC_SUPPORTED_FORMAT_VERSION_MAX;
@@ -126,6 +129,20 @@ hs_helper_build_hs_desc_impl(unsigned int no_ip,
hs_get_subcredential(&signing_kp->pubkey, &blinded_kp.pubkey,
desc->subcredential);
+ /* Setup superencrypted data section. */
+ ret = curve25519_keypair_generate(&auth_ephemeral_kp, 0);
+ tt_int_op(ret, ==, 0);
+ memcpy(&desc->superencrypted_data.auth_ephemeral_pubkey,
+ &auth_ephemeral_kp.pubkey,
+ sizeof(curve25519_public_key_t));
+
+ desc->superencrypted_data.clients = smartlist_new();
+ for (i = 0; i < HS_DESC_AUTH_CLIENT_MULTIPLE; i++) {
+ hs_desc_authorized_client_t *desc_client =
+ hs_desc_build_fake_authorized_client();
+ smartlist_add(desc->superencrypted_data.clients, desc_client);
+ }
+
/* Setup encrypted data section. */
desc->encrypted_data.create2_ntor = 1;
desc->encrypted_data.intro_auth_types = smartlist_new();
@@ -207,6 +224,32 @@ hs_helper_desc_equal(const hs_descriptor_t *desc1,
* encrypted blob. As contrast to the decoding process where we populate a
* descriptor object. */
+ /* Superencrypted data section. */
+ tt_mem_op(desc1->superencrypted_data.auth_ephemeral_pubkey.public_key, OP_EQ,
+ desc2->superencrypted_data.auth_ephemeral_pubkey.public_key,
+ CURVE25519_PUBKEY_LEN);
+
+ /* Auth clients. */
+ {
+ tt_assert(desc1->superencrypted_data.clients);
+ tt_assert(desc2->superencrypted_data.clients);
+ tt_int_op(smartlist_len(desc1->superencrypted_data.clients), ==,
+ smartlist_len(desc2->superencrypted_data.clients));
+ for (int i=0;
+ i < smartlist_len(desc1->superencrypted_data.clients);
+ i++) {
+ hs_desc_authorized_client_t
+ *client1 = smartlist_get(desc1->superencrypted_data.clients, i),
+ *client2 = smartlist_get(desc2->superencrypted_data.clients, i);
+ tt_mem_op(client1->client_id, OP_EQ, client2->client_id,
+ sizeof(client1->client_id));
+ tt_mem_op(client1->iv, OP_EQ, client2->iv,
+ sizeof(client1->iv));
+ tt_mem_op(client1->encrypted_cookie, OP_EQ, client2->encrypted_cookie,
+ sizeof(client1->encrypted_cookie));
+ }
+ }
+
/* Encrypted data section. */
tt_uint_op(desc1->encrypted_data.create2_ntor, ==,
desc2->encrypted_data.create2_ntor);
diff --git a/src/test/hs_test_helpers.h b/src/test/hs_test_helpers.h
index b1b0490f05..b7c2714769 100644
--- a/src/test/hs_test_helpers.h
+++ b/src/test/hs_test_helpers.h
@@ -1,11 +1,11 @@
-/* Copyright (c) 2017, The Tor Project, Inc. */
+/* Copyright (c) 2017-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
#ifndef TOR_HS_TEST_HELPERS_H
#define TOR_HS_TEST_HELPERS_H
-#include "ed25519_cert.h"
-#include "hs_descriptor.h"
+#include "trunnel/ed25519_cert.h"
+#include "feature/hs/hs_descriptor.h"
/* Set of functions to help build and test descriptors. */
hs_desc_intro_point_t *hs_helper_build_intro_point(
diff --git a/src/test/include.am b/src/test/include.am
index 93fc008419..1055cd0a81 100644
--- a/src/test/include.am
+++ b/src/test/include.am
@@ -10,7 +10,10 @@ TESTS_ENVIRONMENT = \
export TESTING_TOR_BINARY="$(TESTING_TOR_BINARY)"; \
export CARGO="$(CARGO)"; \
export EXTRA_CARGO_OPTIONS="$(EXTRA_CARGO_OPTIONS)"; \
- export CARGO_ONLINE="$(CARGO_ONLINE)";
+ export CARGO_ONLINE="$(CARGO_ONLINE)"; \
+ export CCLD="$(CCLD)"; \
+ chmod +x "$(abs_top_builddir)/link_rust.sh"; \
+ export RUSTFLAGS="-C linker=$(abs_top_builddir)/link_rust.sh";
TESTSCRIPTS = \
src/test/fuzz_static_testcases.sh \
@@ -30,6 +33,7 @@ endif
if USEPYTHON
TESTSCRIPTS += src/test/test_ntor.sh src/test/test_hs_ntor.sh src/test/test_bt.sh
+TESTSCRIPTS += src/test/test_rebind.sh
endif
TESTS += src/test/test src/test/test-slow src/test/test-memwipe \
@@ -69,18 +73,19 @@ noinst_PROGRAMS+= \
endif
src_test_AM_CPPFLAGS = -DSHARE_DATADIR="\"$(datadir)\"" \
- -DLOCALSTATEDIR="\"$(localstatedir)\"" \
- -DBINDIR="\"$(bindir)\"" \
- -I"$(top_srcdir)/src/or" -I"$(top_srcdir)/src/ext" \
- -I"$(top_srcdir)/src/trunnel" \
- -I"$(top_srcdir)/src/ext/trunnel" \
- -DTOR_UNIT_TESTS
+ -DLOCALSTATEDIR="\"$(localstatedir)\"" \
+ -DBINDIR="\"$(bindir)\"" \
+ -DTOR_UNIT_TESTS \
+ $(AM_CPPFLAGS)
# -L flags need to go in LDFLAGS. -l flags need to go in LDADD.
# This seems to matter nowhere but on Windows, but I assure you that it
# matters a lot there, and is quite hard to debug if you forget to do it.
-src_test_test_SOURCES = \
+src_test_test_SOURCES =
+
+if UNITTESTS_ENABLED
+src_test_test_SOURCES += \
src/test/log_test_helpers.c \
src/test/hs_test_helpers.c \
src/test/rend_test_helpers.c \
@@ -89,7 +94,9 @@ src_test_test_SOURCES = \
src/test/test_addr.c \
src/test/test_address.c \
src/test/test_address_set.c \
+ src/test/test_bridges.c \
src/test/test_buffers.c \
+ src/test/test_bwmgt.c \
src/test/test_cell_formats.c \
src/test/test_cell_queue.c \
src/test/test_channel.c \
@@ -111,7 +118,7 @@ src_test_test_SOURCES = \
src/test/test_controller.c \
src/test/test_controller_events.c \
src/test/test_crypto.c \
- src/test/test_crypto_openssl.c \
+ src/test/test_crypto_ope.c \
src/test/test_data.c \
src/test/test_dir.c \
src/test/test_dir_common.c \
@@ -119,6 +126,7 @@ src_test_test_SOURCES = \
src/test/test_dos.c \
src/test/test_entryconn.c \
src/test/test_entrynodes.c \
+ src/test/test_geoip.c \
src/test/test_guardfraction.c \
src/test/test_extorport.c \
src/test/test_hs.c \
@@ -137,20 +145,23 @@ src_test_test_SOURCES = \
src/test/test_keypin.c \
src/test/test_link_handshake.c \
src/test/test_logging.c \
+ src/test/test_mainloop.c \
src/test/test_microdesc.c \
src/test/test_nodelist.c \
src/test/test_oom.c \
src/test/test_oos.c \
src/test/test_options.c \
+ src/test/test_pem.c \
+ src/test/test_periodic_event.c \
src/test/test_policy.c \
src/test/test_procmon.c \
src/test/test_proto_http.c \
src/test/test_proto_misc.c \
src/test/test_protover.c \
src/test/test_pt.c \
- src/test/test_pubsub.c \
src/test/test_relay.c \
src/test/test_relaycell.c \
+ src/test/test_relaycrypt.c \
src/test/test_rendcache.c \
src/test/test_replay.c \
src/test/test_router.c \
@@ -167,19 +178,34 @@ src_test_test_SOURCES = \
src/test/test_util.c \
src/test/test_util_format.c \
src/test/test_util_process.c \
+ src/test/test_voting_schedule.c \
+ src/test/test_x509.c \
src/test/test_helpers.c \
src/test/test_dns.c \
src/test/testing_common.c \
src/test/testing_rsakeys.c \
src/ext/tinytest.c
-src_test_test_slow_SOURCES = \
+if USE_NSS
+# ...
+else
+src_test_test_SOURCES += \
+ src/test/test_crypto_openssl.c \
+ src/test/test_tortls_openssl.c
+endif
+
+endif
+
+src_test_test_slow_SOURCES =
+if UNITTESTS_ENABLED
+src_test_test_slow_SOURCES += \
src/test/test_slow.c \
src/test/test_crypto_slow.c \
src/test/test_util_slow.c \
src/test/testing_common.c \
src/test/testing_rsakeys.c \
src/ext/tinytest.c
+endif
src_test_test_memwipe_SOURCES = \
src/test/test-memwipe.c
@@ -205,27 +231,19 @@ src_test_test_switch_id_CPPFLAGS= $(src_test_AM_CPPFLAGS)
src_test_test_switch_id_CFLAGS = $(AM_CFLAGS) $(TEST_CFLAGS)
src_test_test_switch_id_LDFLAGS = @TOR_LDFLAGS_zlib@
src_test_test_switch_id_LDADD = \
- src/common/libor-testing.a \
- src/common/libor-ctime-testing.a \
+ $(TOR_UTIL_TESTING_LIBS) \
$(rust_ldadd) \
@TOR_ZLIB_LIBS@ @TOR_LIB_MATH@ \
- @TOR_LIB_WS32@ @TOR_LIB_USERENV@ \
+ @TOR_LIB_WS32@ @TOR_LIB_IPHLPAPI@ @TOR_LIB_USERENV@ \
@TOR_LZMA_LIBS@ @TOR_ZSTD_LIBS@
-src_test_test_LDFLAGS = @TOR_LDFLAGS_zlib@ @TOR_LDFLAGS_openssl@ \
- @TOR_LDFLAGS_libevent@
-src_test_test_LDADD = src/or/libtor-testing.a \
- src/common/libor-crypto-testing.a \
- $(LIBKECCAK_TINY) \
- $(LIBDONNA) \
- src/common/libor-testing.a \
- src/common/libor-ctime-testing.a \
- src/common/libor-event-testing.a \
- src/trunnel/libor-trunnel-testing.a \
- src/trace/libor-trace.a \
+src_test_test_LDFLAGS = @TOR_LDFLAGS_zlib@ $(TOR_LDFLAGS_CRYPTLIB) \
+ @TOR_LDFLAGS_libevent@
+src_test_test_LDADD = \
+ $(TOR_INTERNAL_TESTING_LIBS) \
$(rust_ldadd) \
@TOR_ZLIB_LIBS@ @TOR_LIB_MATH@ @TOR_LIBEVENT_LIBS@ \
- @TOR_OPENSSL_LIBS@ @TOR_LIB_WS32@ @TOR_LIB_GDI@ @TOR_LIB_USERENV@ \
+ $(TOR_LIBS_CRYPTLIB) @TOR_LIB_WS32@ @TOR_LIB_IPHLPAPI@ @TOR_LIB_GDI@ @TOR_LIB_USERENV@ \
@CURVE25519_LIBS@ \
@TOR_SYSTEMD_LIBS@ @TOR_LZMA_LIBS@ @TOR_ZSTD_LIBS@
@@ -242,43 +260,35 @@ src_test_test_memwipe_LDADD = $(src_test_test_LDADD)
# successfully with the libraries built with them.
src_test_test_memwipe_LDFLAGS = $(src_test_test_LDFLAGS) @CFLAGS_BUGTRAP@
-src_test_bench_LDFLAGS = @TOR_LDFLAGS_zlib@ @TOR_LDFLAGS_openssl@ \
- @TOR_LDFLAGS_libevent@
-src_test_bench_LDADD = src/or/libtor.a src/common/libor.a \
- src/common/libor-ctime.a \
- src/common/libor-crypto.a $(LIBKECCAK_TINY) $(LIBDONNA) \
- src/common/libor-event.a src/trunnel/libor-trunnel.a \
- src/trace/libor-trace.a \
+src_test_bench_LDFLAGS = @TOR_LDFLAGS_zlib@ $(TOR_LDFLAGS_CRYPTLIB) \
+ @TOR_LDFLAGS_libevent@
+src_test_bench_LDADD = \
+ $(TOR_INTERNAL_LIBS) \
$(rust_ldadd) \
@TOR_ZLIB_LIBS@ @TOR_LIB_MATH@ @TOR_LIBEVENT_LIBS@ \
- @TOR_OPENSSL_LIBS@ @TOR_LIB_WS32@ @TOR_LIB_GDI@ @TOR_LIB_USERENV@ \
+ $(TOR_LIBS_CRYPTLIB) @TOR_LIB_WS32@ @TOR_LIB_IPHLPAPI@ @TOR_LIB_GDI@ @TOR_LIB_USERENV@ \
@CURVE25519_LIBS@ \
@TOR_SYSTEMD_LIBS@ @TOR_LZMA_LIBS@ @TOR_ZSTD_LIBS@
-src_test_test_workqueue_LDFLAGS = @TOR_LDFLAGS_zlib@ @TOR_LDFLAGS_openssl@ \
- @TOR_LDFLAGS_libevent@
-src_test_test_workqueue_LDADD = src/or/libtor-testing.a \
- src/common/libor-testing.a \
- src/common/libor-ctime-testing.a \
- src/common/libor-crypto-testing.a $(LIBKECCAK_TINY) $(LIBDONNA) \
- src/common/libor-event-testing.a \
- src/trace/libor-trace.a \
+src_test_test_workqueue_LDFLAGS = @TOR_LDFLAGS_zlib@ $(TOR_LDFLAGS_CRYPTLIB) \
+ @TOR_LDFLAGS_libevent@
+src_test_test_workqueue_LDADD = \
+ $(TOR_INTERNAL_TESTING_LIBS) \
$(rust_ldadd) \
@TOR_ZLIB_LIBS@ @TOR_LIB_MATH@ @TOR_LIBEVENT_LIBS@ \
- @TOR_OPENSSL_LIBS@ @TOR_LIB_WS32@ @TOR_LIB_GDI@ @TOR_LIB_USERENV@ \
+ $(TOR_LIBS_CRYPTLIB) @TOR_LIB_WS32@ @TOR_LIB_IPHLPAPI@ @TOR_LIB_GDI@ @TOR_LIB_USERENV@ \
@CURVE25519_LIBS@ \
@TOR_LZMA_LIBS@ @TOR_ZSTD_LIBS@
src_test_test_timers_CPPFLAGS = $(src_test_test_CPPFLAGS)
src_test_test_timers_CFLAGS = $(src_test_test_CFLAGS)
src_test_test_timers_LDADD = \
- src/common/libor-testing.a \
- src/common/libor-ctime-testing.a \
- src/common/libor-event-testing.a \
- src/common/libor-crypto-testing.a $(LIBKECCAK_TINY) $(LIBDONNA) \
+ src/lib/libtor-evloop-testing.a \
+ $(TOR_CRYPTO_TESTING_LIBS) \
+ $(TOR_UTIL_TESTING_LIBS) \
$(rust_ldadd) \
@TOR_ZLIB_LIBS@ @TOR_LIB_MATH@ @TOR_LIBEVENT_LIBS@ \
- @TOR_OPENSSL_LIBS@ @TOR_LIB_WS32@ @TOR_LIB_GDI@ @TOR_LIB_USERENV@ \
+ $(TOR_LIBS_CRYPTLIB) @TOR_LIB_WS32@ @TOR_LIB_IPHLPAPI@ @TOR_LIB_GDI@ @TOR_LIB_USERENV@ \
@CURVE25519_LIBS@ \
@TOR_LZMA_LIBS@
src_test_test_timers_LDFLAGS = $(src_test_test_LDFLAGS)
@@ -292,6 +302,7 @@ noinst_HEADERS+= \
src/test/test_helpers.h \
src/test/test_dir_common.h \
src/test/test_connection.h \
+ src/test/test_tortls.h \
src/test/test_descriptors.inc \
src/test/example_extrainfo.inc \
src/test/failing_routerdescs.inc \
@@ -303,39 +314,37 @@ noinst_HEADERS+= \
noinst_PROGRAMS+= src/test/test-ntor-cl
noinst_PROGRAMS+= src/test/test-hs-ntor-cl
src_test_test_ntor_cl_SOURCES = src/test/test_ntor_cl.c
-src_test_test_ntor_cl_LDFLAGS = @TOR_LDFLAGS_zlib@ @TOR_LDFLAGS_openssl@
-src_test_test_ntor_cl_LDADD = src/or/libtor.a src/common/libor.a \
- src/common/libor-ctime.a \
- src/common/libor-crypto.a $(LIBKECCAK_TINY) $(LIBDONNA) \
- src/trace/libor-trace.a \
+src_test_test_ntor_cl_LDFLAGS = @TOR_LDFLAGS_zlib@ $(TOR_LDFLAGS_CRYPTLIB)
+src_test_test_ntor_cl_LDADD = \
+ $(TOR_INTERNAL_LIBS) \
$(rust_ldadd) \
@TOR_ZLIB_LIBS@ @TOR_LIB_MATH@ \
- @TOR_OPENSSL_LIBS@ @TOR_LIB_WS32@ @TOR_LIB_GDI@ @TOR_LIB_USERENV@ \
+ $(TOR_LIBS_CRYPTLIB) @TOR_LIB_WS32@ @TOR_LIB_IPHLPAPI@ @TOR_LIB_GDI@ @TOR_LIB_USERENV@ \
@CURVE25519_LIBS@ @TOR_LZMA_LIBS@
src_test_test_ntor_cl_AM_CPPFLAGS = \
- -I"$(top_srcdir)/src/or"
+ $(AM_CPPFLAGS)
src_test_test_hs_ntor_cl_SOURCES = src/test/test_hs_ntor_cl.c
-src_test_test_hs_ntor_cl_LDFLAGS = @TOR_LDFLAGS_zlib@ @TOR_LDFLAGS_openssl@
-src_test_test_hs_ntor_cl_LDADD = src/or/libtor.a src/common/libor.a \
- src/common/libor-ctime.a \
- src/common/libor-crypto.a $(LIBKECCAK_TINY) $(LIBDONNA) \
+src_test_test_hs_ntor_cl_LDFLAGS = @TOR_LDFLAGS_zlib@ $(TOR_LDFLAGS_CRYPTLIB)
+src_test_test_hs_ntor_cl_LDADD = \
+ $(TOR_INTERNAL_LIBS) \
@TOR_ZLIB_LIBS@ @TOR_LIB_MATH@ \
- @TOR_OPENSSL_LIBS@ @TOR_LIB_WS32@ @TOR_LIB_GDI@ @CURVE25519_LIBS@
+ $(TOR_LIBS_CRYPTLIB) @TOR_LIB_WS32@ @TOR_LIB_IPHLPAPI@ @TOR_LIB_GDI@ @CURVE25519_LIBS@
src_test_test_hs_ntor_cl_AM_CPPFLAGS = \
- -I"$(top_srcdir)/src/or"
+ $(AM_CPPFLAGS)
+if UNITTESTS_ENABLED
noinst_PROGRAMS += src/test/test-bt-cl
src_test_test_bt_cl_SOURCES = src/test/test_bt_cl.c
-src_test_test_bt_cl_LDADD = src/common/libor-testing.a \
- src/common/libor-ctime-testing.a \
- src/trace/libor-trace.a \
+src_test_test_bt_cl_LDADD = \
+ $(TOR_UTIL_TESTING_LIBS) \
$(rust_ldadd) \
@TOR_LIB_MATH@ \
- @TOR_LIB_WS32@ @TOR_LIB_GDI@ @TOR_LIB_USERENV@
+ @TOR_LIB_WS32@ @TOR_LIB_IPHLPAPI@ @TOR_LIB_GDI@ @TOR_LIB_USERENV@
src_test_test_bt_cl_CFLAGS = $(AM_CFLAGS) $(TEST_CFLAGS)
src_test_test_bt_cl_CPPFLAGS= $(src_test_AM_CPPFLAGS) $(TEST_CPPFLAGS)
+endif
EXTRA_DIST += \
src/test/bt_test.py \
@@ -345,7 +354,10 @@ EXTRA_DIST += \
src/test/hs_indexes.py \
src/test/fuzz_static_testcases.sh \
src/test/slownacl_curve25519.py \
+ src/test/test_rebind.sh \
+ src/test/test_rebind.py \
src/test/zero_length_keys.sh \
+ src/test/rust_supp.txt \
src/test/test_keygen.sh \
src/test/test_key_expiration.sh \
src/test/test_zero_length_keys.sh \
diff --git a/src/test/log_test_helpers.c b/src/test/log_test_helpers.c
index d5a39cfeee..2e91b1ecdc 100644
--- a/src/test/log_test_helpers.c
+++ b/src/test/log_test_helpers.c
@@ -1,8 +1,8 @@
-/* Copyright (c) 2015-2017, The Tor Project, Inc. */
+/* Copyright (c) 2015-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
#define LOG_PRIVATE
-#include "torlog.h"
-#include "log_test_helpers.h"
+#include "lib/log/log.h"
+#include "test/log_test_helpers.h"
/**
* \file log_test_helpers.c
@@ -158,6 +158,26 @@ mock_saved_log_has_message_containing(const char *msg)
return 0;
}
+/**
+ * Return true iff there is not a message recorded by log capture
+ * that contains <b>msg</b> as a substring.
+ */
+int
+mock_saved_log_has_message_not_containing(const char *msg)
+{
+ if (saved_logs) {
+ SMARTLIST_FOREACH(
+ saved_logs, mock_saved_log_entry_t *, m,
+ {
+ if (msg && m->generated_msg && strstr(m->generated_msg, msg))
+ return 0;
+ }
+ );
+ }
+
+ return 1;
+}
+
/** Return true iff the saved logs have any messages with <b>severity</b> */
int
mock_saved_log_has_severity(int severity)
diff --git a/src/test/log_test_helpers.h b/src/test/log_test_helpers.h
index 70c584eb37..6a774cdfc7 100644
--- a/src/test/log_test_helpers.h
+++ b/src/test/log_test_helpers.h
@@ -1,7 +1,7 @@
-/* Copyright (c) 2014-2017, The Tor Project, Inc. */
+/* Copyright (c) 2014-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
-#include "or.h"
+#include "core/or/or.h"
#ifndef TOR_LOG_TEST_HELPERS_H
#define TOR_LOG_TEST_HELPERS_H
@@ -24,6 +24,7 @@ void teardown_capture_of_logs(void);
int mock_saved_log_has_message(const char *msg);
int mock_saved_log_has_message_containing(const char *msg);
+int mock_saved_log_has_message_not_containing(const char *msg);
int mock_saved_log_has_severity(int severity);
int mock_saved_log_has_entry(void);
int mock_saved_log_n_entries(void);
@@ -32,7 +33,7 @@ void mock_dump_saved_logs(void);
#define assert_log_predicate(predicate, failure_msg) \
do { \
if (!(predicate)) { \
- tt_fail_msg((failure_msg)); \
+ TT_FAIL(failure_msg); \
mock_dump_saved_logs(); \
TT_EXIT_TEST_FUNCTION; \
} \
@@ -40,66 +41,75 @@ void mock_dump_saved_logs(void);
#define expect_log_msg(str) \
assert_log_predicate(mock_saved_log_has_message(str), \
- "expected log to contain " # str);
+ ("expected log to contain \"%s\"", str));
#define expect_log_msg_containing(str) \
assert_log_predicate(mock_saved_log_has_message_containing(str), \
- "expected log to contain " # str);
+ ("expected log to contain \"%s\"", str));
+
+#define expect_log_msg_not_containing(str) \
+ assert_log_predicate(mock_saved_log_has_message_not_containing(str), \
+ ("expected log to not contain \"%s\"", str));
#define expect_log_msg_containing_either(str1, str2) \
assert_log_predicate(mock_saved_log_has_message_containing(str1) || \
mock_saved_log_has_message_containing(str2), \
- "expected log to contain " # str1 " or " # str2);
+ ("expected log to contain \"%s\" or \"%s\"", str1, str2));
#define expect_log_msg_containing_either3(str1, str2, str3) \
assert_log_predicate(mock_saved_log_has_message_containing(str1) || \
mock_saved_log_has_message_containing(str2) || \
mock_saved_log_has_message_containing(str3), \
- "expected log to contain " # str1 " or " # str2 \
- " or " # str3);
+ ("expected log to contain \"%s\" or \"%s\" or \"%s\"", \
+ str1, str2, str3))
#define expect_log_msg_containing_either4(str1, str2, str3, str4) \
assert_log_predicate(mock_saved_log_has_message_containing(str1) || \
mock_saved_log_has_message_containing(str2) || \
mock_saved_log_has_message_containing(str3) || \
mock_saved_log_has_message_containing(str4), \
- "expected log to contain " # str1 " or " # str2 \
- " or " # str3 " or " # str4);
+ ("expected log to contain \"%s\" or \"%s\" or \"%s\" or \"%s\"", \
+ str1, str2, str3, str4))
#define expect_single_log_msg(str) \
do { \
\
assert_log_predicate(mock_saved_log_has_message_containing(str) && \
mock_saved_log_n_entries() == 1, \
- "expected log to contain exactly 1 message " # str); \
+ ("expected log to contain exactly 1 message \"%s\"", \
+ str)); \
} while (0);
#define expect_single_log_msg_containing(str) \
do { \
assert_log_predicate(mock_saved_log_has_message_containing(str)&& \
mock_saved_log_n_entries() == 1 , \
- "expected log to contain 1 message, containing " # str); \
+ ("expected log to contain 1 message, containing \"%s\"",\
+ str)); \
} while (0);
#define expect_no_log_msg(str) \
assert_log_predicate(!mock_saved_log_has_message(str), \
- "expected log to not contain " # str);
+ ("expected log to not contain \"%s\"",str));
+
+#define expect_no_log_msg_containing(str) \
+ assert_log_predicate(!mock_saved_log_has_message_containing(str), \
+ ("expected log to not contain \"%s\"", str));
#define expect_log_severity(severity) \
assert_log_predicate(mock_saved_log_has_severity(severity), \
- "expected log to contain severity " # severity);
+ ("expected log to contain severity " # severity));
#define expect_no_log_severity(severity) \
assert_log_predicate(!mock_saved_log_has_severity(severity), \
- "expected log to not contain severity " # severity);
+ ("expected log to not contain severity " # severity));
#define expect_log_entry() \
assert_log_predicate(mock_saved_log_has_entry(), \
- "expected log to contain entries");
+ ("expected log to contain entries"));
#define expect_no_log_entry() \
assert_log_predicate(!mock_saved_log_has_entry(), \
- "expected log to not contain entries");
+ ("expected log to not contain entries"));
#endif /* !defined(TOR_LOG_TEST_HELPERS_H) */
-
diff --git a/src/test/ntor_ref.py b/src/test/ntor_ref.py
index 51f218f512..56e97ece36 100755
--- a/src/test/ntor_ref.py
+++ b/src/test/ntor_ref.py
@@ -1,5 +1,5 @@
#!/usr/bin/python
-# Copyright 2012-2017, The Tor Project, Inc
+# Copyright 2012-2018, The Tor Project, Inc
# See LICENSE for licensing information
"""
diff --git a/src/test/ope_ref.py b/src/test/ope_ref.py
new file mode 100644
index 0000000000..3677e57a61
--- /dev/null
+++ b/src/test/ope_ref.py
@@ -0,0 +1,40 @@
+#!/usr/bin/python3
+# Copyright 2018, The Tor Project, Inc. See LICENSE for licensing info.
+
+# Reference implementation for our rudimentary OPE code, used to
+# generate test vectors. See crypto_ope.c for more details.
+
+from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
+from cryptography.hazmat.primitives.ciphers.algorithms import AES
+from cryptography.hazmat.backends import default_backend
+
+from binascii import a2b_hex
+
+#randomly generated and values.
+KEY = a2b_hex(
+ "19e05891d55232c08c2cad91d612fdb9cbd6691949a0742434a76c80bc6992fe")
+PTS = [ 121132, 82283, 72661, 72941, 123122, 12154, 121574, 11391, 65845,
+ 86301, 61284, 70505, 30438, 60150, 114800, 109403, 21893, 123569,
+ 95617, 48561, 53334, 92746, 7110, 9612, 106958, 46889, 87790, 68878,
+ 47917, 121128, 108602, 28217, 69498, 63870, 57542, 122148, 46254,
+ 42850, 92661, 57720]
+
+IV = b'\x00' * 16
+
+backend = default_backend()
+
+def words():
+ cipher = Cipher(algorithms.AES(KEY), modes.CTR(IV), backend=backend)
+ e = cipher.encryptor()
+ while True:
+ v = e.update(b'\x00\x00')
+ yield v[0] + 256 * v[1] + 1
+
+def encrypt(n):
+ return sum(w for w, _ in zip(words(), range(n)))
+
+def example(n):
+ return ' {{ {}, UINT64_C({}) }},'.format(n, encrypt(n))
+
+for v in PTS:
+ print(example(v))
diff --git a/src/test/rend_test_helpers.c b/src/test/rend_test_helpers.c
index 095bfecf21..85a679a967 100644
--- a/src/test/rend_test_helpers.c
+++ b/src/test/rend_test_helpers.c
@@ -1,10 +1,15 @@
-/* Copyright (c) 2014-2017, The Tor Project, Inc. */
+/* Copyright (c) 2014-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
-#include "or.h"
-#include "test.h"
-#include "rendcommon.h"
-#include "rend_test_helpers.h"
+#include "core/or/or.h"
+#include "lib/crypt_ops/crypto_rand.h"
+#include "test/test.h"
+#include "feature/rend/rendcommon.h"
+#include "test/rend_test_helpers.h"
+
+#include "core/or/extend_info_st.h"
+#include "feature/rend/rend_intro_point_st.h"
+#include "feature/rend/rend_service_descriptor_st.h"
void
generate_desc(int time_diff, rend_encoded_v2_service_descriptor_t **desc,
diff --git a/src/test/rend_test_helpers.h b/src/test/rend_test_helpers.h
index abf4324988..103e143ec6 100644
--- a/src/test/rend_test_helpers.h
+++ b/src/test/rend_test_helpers.h
@@ -1,7 +1,7 @@
-/* Copyright (c) 2014-2017, The Tor Project, Inc. */
+/* Copyright (c) 2014-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
-#include "or.h"
+#include "core/or/or.h"
#ifndef TOR_REND_TEST_HELPERS_H
#define TOR_REND_TEST_HELPERS_H
diff --git a/src/test/rust_supp.txt b/src/test/rust_supp.txt
new file mode 100644
index 0000000000..7fa50f3fb1
--- /dev/null
+++ b/src/test/rust_supp.txt
@@ -0,0 +1 @@
+leak:backtrace_alloc
diff --git a/src/test/test-child.c b/src/test/test-child.c
index f78a829107..14df1a9b76 100644
--- a/src/test/test-child.c
+++ b/src/test/test-child.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2017, The Tor Project, Inc. */
+/* Copyright (c) 2011-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
#include "orconfig.h"
diff --git a/src/test/test-memwipe.c b/src/test/test-memwipe.c
index 89d946d506..c879013ed6 100644
--- a/src/test/test-memwipe.c
+++ b/src/test/test-memwipe.c
@@ -1,16 +1,17 @@
-/* Copyright (c) 2015-2017, The Tor Project, Inc. */
+/* Copyright (c) 2015-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
#include "orconfig.h"
+#include "lib/crypt_ops/crypto_util.h"
+
+#include "lib/intmath/cmp.h"
+#include "lib/malloc/malloc.h"
+
#include <string.h>
#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>
-#include "crypto.h"
-#include "compat.h"
-#include "util.h"
-
static unsigned fill_a_buffer_memset(void) __attribute__((noinline));
static unsigned fill_a_buffer_memwipe(void) __attribute__((noinline));
static unsigned fill_a_buffer_nothing(void) __attribute__((noinline));
@@ -215,4 +216,3 @@ main(int argc, char **argv)
return 0;
}
}
-
diff --git a/src/test/test-network.sh b/src/test/test-network.sh
index 6e0f286573..b7a9f1b3c0 100755
--- a/src/test/test-network.sh
+++ b/src/test/test-network.sh
@@ -52,12 +52,12 @@ done
# - if $PWD looks like a tor build directory, set it to $PWD, or
# - unset $TOR_DIR, and let chutney fall back to finding tor binaries in $PATH
if [ ! -d "$TOR_DIR" ]; then
- if [ -d "$BUILDDIR/src/or" -a -d "$BUILDDIR/src/tools" ]; then
+ if [ -d "$BUILDDIR/src/core/or" -a -d "$BUILDDIR/src/tools" ]; then
# Choose the build directory
# But only if it looks like one
$ECHO "$myname: \$TOR_DIR not set, trying \$BUILDDIR"
TOR_DIR="$BUILDDIR"
- elif [ -d "$PWD/src/or" -a -d "$PWD/src/tools" ]; then
+ elif [ -d "$PWD/src/core/or" -a -d "$PWD/src/tools" ]; then
# Guess the tor directory is the current directory
# But only if it looks like one
$ECHO "$myname: \$TOR_DIR not set, trying \$PWD"
diff --git a/src/test/test-timers.c b/src/test/test-timers.c
index a0b5b535c2..923f51ecce 100644
--- a/src/test/test-timers.c
+++ b/src/test/test-timers.c
@@ -1,4 +1,4 @@
-/* Copyright 2016-2017, The Tor Project, Inc. */
+/* Copyright 2016-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
#include "orconfig.h"
@@ -7,13 +7,13 @@
#include <stdio.h>
#include <string.h>
-#include <event2/event.h>
-
-#include "compat.h"
-#include "compat_libevent.h"
-#include "crypto.h"
-#include "timers.h"
-#include "util.h"
+#include "lib/evloop/compat_libevent.h"
+#include "lib/evloop/timers.h"
+#include "lib/crypt_ops/crypto_init.h"
+#include "lib/crypt_ops/crypto_rand.h"
+#include "lib/log/util_bug.h"
+#include "lib/time/compat_time.h"
+#include "lib/wallclock/timeval.h"
#define N_TIMERS 1000
#define MAX_DURATION 30
@@ -50,7 +50,7 @@ timer_cb(tor_timer_t *t, void *arg, const monotime_t *now_mono)
// printf("%d / %d\n",n_fired, N_TIMERS);
if (n_fired == n_active_timers) {
- event_base_loopbreak(tor_libevent_get_base());
+ tor_libevent_exit_loop_after_callback(tor_libevent_get_base());
}
}
@@ -63,6 +63,10 @@ main(int argc, char **argv)
memset(&cfg, 0, sizeof(cfg));
tor_libevent_initialize(&cfg);
timers_initialize();
+ init_logging(1);
+
+ if (crypto_global_init(0, NULL, NULL) < 0)
+ return 1;
int i;
int ret;
@@ -90,7 +94,7 @@ main(int argc, char **argv)
--n_active_timers;
}
- event_base_loop(tor_libevent_get_base(), 0);
+ tor_libevent_run_event_loop(tor_libevent_get_base(), 0);
int64_t total_difference = 0;
uint64_t total_square_difference = 0;
@@ -107,8 +111,8 @@ main(int argc, char **argv)
total_square_difference += diff*diff;
}
const int64_t mean_diff = total_difference / n_active_timers;
- printf("mean difference: "I64_FORMAT" usec\n",
- I64_PRINTF_ARG(mean_diff));
+ printf("mean difference: %"PRId64" usec\n",
+ (mean_diff));
const double mean_sq = ((double)total_square_difference)/ n_active_timers;
const double sq_mean = mean_diff * mean_diff;
@@ -141,4 +145,3 @@ main(int argc, char **argv)
timers_shutdown();
return ret;
}
-
diff --git a/src/test/test.c b/src/test/test.c
index 2e7d399322..70d91e3967 100644
--- a/src/test/test.c
+++ b/src/test/test.c
@@ -1,6 +1,6 @@
/* Copyright (c) 2001-2004, Roger Dingledine.
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2017, The Tor Project, Inc. */
+ * Copyright (c) 2007-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
/**
@@ -9,6 +9,9 @@
**/
#include "orconfig.h"
+#include "lib/crypt_ops/crypto_dh.h"
+#include "lib/crypt_ops/crypto_rand.h"
+#include "app/config/or_state_st.h"
#include <stdio.h>
#ifdef HAVE_FCNTL_H
@@ -26,36 +29,41 @@
/* These macros pull in declarations for some functions and structures that
* are typically file-private. */
-#define GEOIP_PRIVATE
#define ROUTER_PRIVATE
#define CIRCUITSTATS_PRIVATE
#define CIRCUITLIST_PRIVATE
-#define MAIN_PRIVATE
+#define MAINLOOP_PRIVATE
#define STATEFILE_PRIVATE
-#include "or.h"
-#include "backtrace.h"
-#include "buffers.h"
-#include "circuitlist.h"
-#include "circuitstats.h"
-#include "compress.h"
-#include "config.h"
-#include "connection_edge.h"
-#include "geoip.h"
-#include "rendcommon.h"
-#include "rendcache.h"
-#include "test.h"
-#include "main.h"
-#include "memarea.h"
-#include "onion.h"
-#include "onion_ntor.h"
-#include "onion_fast.h"
-#include "onion_tap.h"
-#include "policies.h"
-#include "rephist.h"
-#include "routerparse.h"
-#include "statefile.h"
-#include "crypto_curve25519.h"
+#include "core/or/or.h"
+#include "lib/err/backtrace.h"
+#include "lib/container/buffers.h"
+#include "core/or/circuitlist.h"
+#include "core/or/circuitstats.h"
+#include "lib/compress/compress.h"
+#include "app/config/config.h"
+#include "core/or/connection_edge.h"
+#include "feature/rend/rendcommon.h"
+#include "feature/rend/rendcache.h"
+#include "feature/rend/rendparse.h"
+#include "test/test.h"
+#include "core/mainloop/mainloop.h"
+#include "lib/memarea/memarea.h"
+#include "core/or/onion.h"
+#include "core/crypto/onion_ntor.h"
+#include "core/crypto/onion_fast.h"
+#include "core/crypto/onion_tap.h"
+#include "core/or/policies.h"
+#include "feature/stats/rephist.h"
+#include "app/config/statefile.h"
+#include "lib/crypt_ops/crypto_curve25519.h"
+
+#include "core/or/extend_info_st.h"
+#include "core/or/or_circuit_st.h"
+#include "feature/rend/rend_encoded_v2_service_descriptor_st.h"
+#include "feature/rend/rend_intro_point_st.h"
+#include "feature/rend/rend_service_descriptor_st.h"
+#include "feature/relay/onion_queue.h"
/** Run unit tests for the onion handshake code. */
static void
@@ -137,7 +145,8 @@ test_bad_onion_handshake(void *arg)
memset(junk_buf, 0, sizeof(junk_buf));
crypto_pk_obsolete_public_hybrid_encrypt(pk,
junk_buf2, TAP_ONIONSKIN_CHALLENGE_LEN,
- junk_buf, DH_KEY_LEN, PK_PKCS1_OAEP_PADDING, 1);
+ junk_buf, DH1024_KEY_LEN,
+ PK_PKCS1_OAEP_PADDING, 1);
tt_int_op(-1, OP_EQ,
onion_skin_TAP_server_handshake(junk_buf2, pk, NULL,
s_buf, s_keys, 40));
@@ -345,6 +354,18 @@ test_onion_queues(void *arg)
tor_free(onionskin);
}
+static crypto_cipher_t *crypto_rand_aes_cipher = NULL;
+
+// Mock replacement for crypto_rand: Generates bytes from a provided AES_CTR
+// cipher in <b>crypto_rand_aes_cipher</b>.
+static void
+crypto_rand_deterministic_aes(char *out, size_t n)
+{
+ tor_assert(crypto_rand_aes_cipher);
+ memset(out, 0, n);
+ crypto_cipher_crypt_inplace(crypto_rand_aes_cipher, out, n);
+}
+
static void
test_circuit_timeout(void *arg)
{
@@ -374,6 +395,11 @@ test_circuit_timeout(void *arg)
state = or_state_new();
+ // Use a deterministic RNG here, or else we'll get nondeterministic
+ // coverage in some of the circuitstats functions.
+ MOCK(crypto_rand, crypto_rand_deterministic_aes);
+ crypto_rand_aes_cipher = crypto_cipher_new("xyzzyplughplover");
+
circuitbuild_running_unit_tests();
#define timeout0 (build_time_t)(30*1000.0)
initial.Xm = 3000;
@@ -508,6 +534,8 @@ test_circuit_timeout(void *arg)
circuit_build_times_free_timeouts(&final);
or_state_free(state);
teardown_periodic_events();
+ UNMOCK(crypto_rand);
+ crypto_cipher_free(crypto_rand_aes_cipher);
}
/** Test encoding and parsing of rendezvous service descriptors. */
@@ -623,376 +651,6 @@ test_rend_fns(void *arg)
tor_free(intro_points_encrypted);
}
- /* Record odd numbered fake-IPs using ipv6, even numbered fake-IPs
- * using ipv4. Since our fake geoip database is the same between
- * ipv4 and ipv6, we should get the same result no matter which
- * address family we pick for each IP. */
-#define SET_TEST_ADDRESS(i) do { \
- if ((i) & 1) { \
- SET_TEST_IPV6(i); \
- tor_addr_from_in6(&addr, &in6); \
- } else { \
- tor_addr_from_ipv4h(&addr, (uint32_t) i); \
- } \
- } while (0)
-
- /* Make sure that country ID actually works. */
-#define SET_TEST_IPV6(i) \
- do { \
- set_uint32(in6.s6_addr + 12, htonl((uint32_t) (i))); \
- } while (0)
-#define CHECK_COUNTRY(country, val) do { \
- /* test ipv4 country lookup */ \
- tt_str_op(country, OP_EQ, \
- geoip_get_country_name(geoip_get_country_by_ipv4(val))); \
- /* test ipv6 country lookup */ \
- SET_TEST_IPV6(val); \
- tt_str_op(country, OP_EQ, \
- geoip_get_country_name(geoip_get_country_by_ipv6(&in6))); \
- } while (0)
-
-/** Run unit tests for GeoIP code. */
-static void
-test_geoip(void *arg)
-{
- int i, j;
- time_t now = 1281533250; /* 2010-08-11 13:27:30 UTC */
- char *s = NULL, *v = NULL;
- const char *bridge_stats_1 =
- "bridge-stats-end 2010-08-12 13:27:30 (86400 s)\n"
- "bridge-ips zz=24,xy=8\n"
- "bridge-ip-versions v4=16,v6=16\n"
- "bridge-ip-transports <OR>=24\n",
- *dirreq_stats_1 =
- "dirreq-stats-end 2010-08-12 13:27:30 (86400 s)\n"
- "dirreq-v3-ips ab=8\n"
- "dirreq-v3-reqs ab=8\n"
- "dirreq-v3-resp ok=0,not-enough-sigs=0,unavailable=0,not-found=0,"
- "not-modified=0,busy=0\n"
- "dirreq-v3-direct-dl complete=0,timeout=0,running=0\n"
- "dirreq-v3-tunneled-dl complete=0,timeout=0,running=0\n",
- *dirreq_stats_2 =
- "dirreq-stats-end 2010-08-12 13:27:30 (86400 s)\n"
- "dirreq-v3-ips \n"
- "dirreq-v3-reqs \n"
- "dirreq-v3-resp ok=0,not-enough-sigs=0,unavailable=0,not-found=0,"
- "not-modified=0,busy=0\n"
- "dirreq-v3-direct-dl complete=0,timeout=0,running=0\n"
- "dirreq-v3-tunneled-dl complete=0,timeout=0,running=0\n",
- *dirreq_stats_3 =
- "dirreq-stats-end 2010-08-12 13:27:30 (86400 s)\n"
- "dirreq-v3-ips \n"
- "dirreq-v3-reqs \n"
- "dirreq-v3-resp ok=8,not-enough-sigs=0,unavailable=0,not-found=0,"
- "not-modified=0,busy=0\n"
- "dirreq-v3-direct-dl complete=0,timeout=0,running=0\n"
- "dirreq-v3-tunneled-dl complete=0,timeout=0,running=0\n",
- *dirreq_stats_4 =
- "dirreq-stats-end 2010-08-12 13:27:30 (86400 s)\n"
- "dirreq-v3-ips \n"
- "dirreq-v3-reqs \n"
- "dirreq-v3-resp ok=8,not-enough-sigs=0,unavailable=0,not-found=0,"
- "not-modified=0,busy=0\n"
- "dirreq-v3-direct-dl complete=0,timeout=0,running=0\n"
- "dirreq-v3-tunneled-dl complete=0,timeout=0,running=4\n",
- *entry_stats_1 =
- "entry-stats-end 2010-08-12 13:27:30 (86400 s)\n"
- "entry-ips ab=8\n",
- *entry_stats_2 =
- "entry-stats-end 2010-08-12 13:27:30 (86400 s)\n"
- "entry-ips \n";
- tor_addr_t addr;
- struct in6_addr in6;
-
- /* Populate the DB a bit. Add these in order, since we can't do the final
- * 'sort' step. These aren't very good IP addresses, but they're perfectly
- * fine uint32_t values. */
- (void)arg;
- tt_int_op(0,OP_EQ, geoip_parse_entry("10,50,AB", AF_INET));
- tt_int_op(0,OP_EQ, geoip_parse_entry("52,90,XY", AF_INET));
- tt_int_op(0,OP_EQ, geoip_parse_entry("95,100,AB", AF_INET));
- tt_int_op(0,OP_EQ, geoip_parse_entry("\"105\",\"140\",\"ZZ\"", AF_INET));
- tt_int_op(0,OP_EQ, geoip_parse_entry("\"150\",\"190\",\"XY\"", AF_INET));
- tt_int_op(0,OP_EQ, geoip_parse_entry("\"200\",\"250\",\"AB\"", AF_INET));
-
- /* Populate the IPv6 DB equivalently with fake IPs in the same range */
- tt_int_op(0,OP_EQ, geoip_parse_entry("::a,::32,AB", AF_INET6));
- tt_int_op(0,OP_EQ, geoip_parse_entry("::34,::5a,XY", AF_INET6));
- tt_int_op(0,OP_EQ, geoip_parse_entry("::5f,::64,AB", AF_INET6));
- tt_int_op(0,OP_EQ, geoip_parse_entry("::69,::8c,ZZ", AF_INET6));
- tt_int_op(0,OP_EQ, geoip_parse_entry("::96,::be,XY", AF_INET6));
- tt_int_op(0,OP_EQ, geoip_parse_entry("::c8,::fa,AB", AF_INET6));
-
- /* We should have 4 countries: ??, ab, xy, zz. */
- tt_int_op(4,OP_EQ, geoip_get_n_countries());
- memset(&in6, 0, sizeof(in6));
-
- CHECK_COUNTRY("??", 3);
- CHECK_COUNTRY("ab", 32);
- CHECK_COUNTRY("??", 5);
- CHECK_COUNTRY("??", 51);
- CHECK_COUNTRY("xy", 150);
- CHECK_COUNTRY("xy", 190);
- CHECK_COUNTRY("??", 2000);
-
- tt_int_op(0,OP_EQ, geoip_get_country_by_ipv4(3));
- SET_TEST_IPV6(3);
- tt_int_op(0,OP_EQ, geoip_get_country_by_ipv6(&in6));
-
- get_options_mutable()->BridgeRelay = 1;
- get_options_mutable()->BridgeRecordUsageByCountry = 1;
- /* Put 9 observations in AB... */
- for (i=32; i < 40; ++i) {
- SET_TEST_ADDRESS(i);
- geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &addr, NULL, now-7200);
- }
- SET_TEST_ADDRESS(225);
- geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &addr, NULL, now-7200);
- /* and 3 observations in XY, several times. */
- for (j=0; j < 10; ++j)
- for (i=52; i < 55; ++i) {
- SET_TEST_ADDRESS(i);
- geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &addr, NULL, now-3600);
- }
- /* and 17 observations in ZZ... */
- for (i=110; i < 127; ++i) {
- SET_TEST_ADDRESS(i);
- geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &addr, NULL, now);
- }
- geoip_get_client_history(GEOIP_CLIENT_CONNECT, &s, &v);
- tt_assert(s);
- tt_assert(v);
- tt_str_op("zz=24,ab=16,xy=8",OP_EQ, s);
- tt_str_op("v4=16,v6=16",OP_EQ, v);
- tor_free(s);
- tor_free(v);
-
- /* Now clear out all the AB observations. */
- geoip_remove_old_clients(now-6000);
- geoip_get_client_history(GEOIP_CLIENT_CONNECT, &s, &v);
- tt_assert(s);
- tt_assert(v);
- tt_str_op("zz=24,xy=8",OP_EQ, s);
- tt_str_op("v4=16,v6=16",OP_EQ, v);
- tor_free(s);
- tor_free(v);
-
- /* Start testing bridge statistics by making sure that we don't output
- * bridge stats without initializing them. */
- s = geoip_format_bridge_stats(now + 86400);
- tt_ptr_op(s, OP_EQ, NULL);
-
- /* Initialize stats and generate the bridge-stats history string out of
- * the connecting clients added above. */
- geoip_bridge_stats_init(now);
- s = geoip_format_bridge_stats(now + 86400);
- tt_assert(s);
- tt_str_op(bridge_stats_1,OP_EQ, s);
- tor_free(s);
-
- /* Stop collecting bridge stats and make sure we don't write a history
- * string anymore. */
- geoip_bridge_stats_term();
- s = geoip_format_bridge_stats(now + 86400);
- tt_ptr_op(s, OP_EQ, NULL);
-
- /* Stop being a bridge and start being a directory mirror that gathers
- * directory request statistics. */
- geoip_bridge_stats_term();
- get_options_mutable()->BridgeRelay = 0;
- get_options_mutable()->BridgeRecordUsageByCountry = 0;
- get_options_mutable()->DirReqStatistics = 1;
-
- /* Start testing dirreq statistics by making sure that we don't collect
- * dirreq stats without initializing them. */
- SET_TEST_ADDRESS(100);
- geoip_note_client_seen(GEOIP_CLIENT_NETWORKSTATUS, &addr, NULL, now);
- s = geoip_format_dirreq_stats(now + 86400);
- tt_ptr_op(s, OP_EQ, NULL);
-
- /* Initialize stats, note one connecting client, and generate the
- * dirreq-stats history string. */
- geoip_dirreq_stats_init(now);
- SET_TEST_ADDRESS(100);
- geoip_note_client_seen(GEOIP_CLIENT_NETWORKSTATUS, &addr, NULL, now);
- s = geoip_format_dirreq_stats(now + 86400);
- tt_str_op(dirreq_stats_1,OP_EQ, s);
- tor_free(s);
-
- /* Stop collecting stats, add another connecting client, and ensure we
- * don't generate a history string. */
- geoip_dirreq_stats_term();
- SET_TEST_ADDRESS(101);
- geoip_note_client_seen(GEOIP_CLIENT_NETWORKSTATUS, &addr, NULL, now);
- s = geoip_format_dirreq_stats(now + 86400);
- tt_ptr_op(s, OP_EQ, NULL);
-
- /* Re-start stats, add a connecting client, reset stats, and make sure
- * that we get an all empty history string. */
- geoip_dirreq_stats_init(now);
- SET_TEST_ADDRESS(100);
- geoip_note_client_seen(GEOIP_CLIENT_NETWORKSTATUS, &addr, NULL, now);
- geoip_reset_dirreq_stats(now);
- s = geoip_format_dirreq_stats(now + 86400);
- tt_str_op(dirreq_stats_2,OP_EQ, s);
- tor_free(s);
-
- /* Note a successful network status response and make sure that it
- * appears in the history string. */
- geoip_note_ns_response(GEOIP_SUCCESS);
- s = geoip_format_dirreq_stats(now + 86400);
- tt_str_op(dirreq_stats_3,OP_EQ, s);
- tor_free(s);
-
- /* Start a tunneled directory request. */
- geoip_start_dirreq((uint64_t) 1, 1024, DIRREQ_TUNNELED);
- s = geoip_format_dirreq_stats(now + 86400);
- tt_str_op(dirreq_stats_4,OP_EQ, s);
- tor_free(s);
-
- /* Stop collecting directory request statistics and start gathering
- * entry stats. */
- geoip_dirreq_stats_term();
- get_options_mutable()->DirReqStatistics = 0;
- get_options_mutable()->EntryStatistics = 1;
-
- /* Start testing entry statistics by making sure that we don't collect
- * anything without initializing entry stats. */
- SET_TEST_ADDRESS(100);
- geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &addr, NULL, now);
- s = geoip_format_entry_stats(now + 86400);
- tt_ptr_op(s, OP_EQ, NULL);
-
- /* Initialize stats, note one connecting client, and generate the
- * entry-stats history string. */
- geoip_entry_stats_init(now);
- SET_TEST_ADDRESS(100);
- geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &addr, NULL, now);
- s = geoip_format_entry_stats(now + 86400);
- tt_str_op(entry_stats_1,OP_EQ, s);
- tor_free(s);
-
- /* Stop collecting stats, add another connecting client, and ensure we
- * don't generate a history string. */
- geoip_entry_stats_term();
- SET_TEST_ADDRESS(101);
- geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &addr, NULL, now);
- s = geoip_format_entry_stats(now + 86400);
- tt_ptr_op(s, OP_EQ, NULL);
-
- /* Re-start stats, add a connecting client, reset stats, and make sure
- * that we get an all empty history string. */
- geoip_entry_stats_init(now);
- SET_TEST_ADDRESS(100);
- geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &addr, NULL, now);
- geoip_reset_entry_stats(now);
- s = geoip_format_entry_stats(now + 86400);
- tt_str_op(entry_stats_2,OP_EQ, s);
- tor_free(s);
-
- /* Test the OOM handler. Add a client, run the OOM. */
- geoip_entry_stats_init(now);
- SET_TEST_ADDRESS(100);
- geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &addr, NULL,
- now - (12 * 60 * 60));
- /* We've seen this 12 hours ago. Run the OOM, it should clean the entry
- * because it is above the minimum cutoff of 4 hours. */
- size_t bytes_removed = geoip_client_cache_handle_oom(now, 1000);
- tt_size_op(bytes_removed, OP_GT, 0);
-
- /* Do it again but this time with an entry with a lower cutoff. */
- geoip_entry_stats_init(now);
- SET_TEST_ADDRESS(100);
- geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &addr, NULL,
- now - (3 * 60 * 60));
- bytes_removed = geoip_client_cache_handle_oom(now, 1000);
- tt_size_op(bytes_removed, OP_EQ, 0);
-
- /* Stop collecting entry statistics. */
- geoip_entry_stats_term();
- get_options_mutable()->EntryStatistics = 0;
-
- done:
- tor_free(s);
- tor_free(v);
-}
-
-static void
-test_geoip_with_pt(void *arg)
-{
- time_t now = 1281533250; /* 2010-08-11 13:27:30 UTC */
- char *s = NULL;
- int i;
- tor_addr_t addr;
- struct in6_addr in6;
-
- (void)arg;
- get_options_mutable()->BridgeRelay = 1;
- get_options_mutable()->BridgeRecordUsageByCountry = 1;
-
- memset(&in6, 0, sizeof(in6));
-
- /* No clients seen yet. */
- s = geoip_get_transport_history();
- tor_assert(!s);
-
- /* 4 connections without a pluggable transport */
- for (i=0; i < 4; ++i) {
- SET_TEST_ADDRESS(i);
- geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &addr, NULL, now-7200);
- }
-
- /* 9 connections with "alpha" */
- for (i=4; i < 13; ++i) {
- SET_TEST_ADDRESS(i);
- geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &addr, "alpha", now-7200);
- }
-
- /* one connection with "beta" */
- SET_TEST_ADDRESS(13);
- geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &addr, "beta", now-7200);
-
- /* 14 connections with "charlie" */
- for (i=14; i < 28; ++i) {
- SET_TEST_ADDRESS(i);
- geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &addr, "charlie", now-7200);
- }
-
- /* 131 connections with "ddr" */
- for (i=28; i < 159; ++i) {
- SET_TEST_ADDRESS(i);
- geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &addr, "ddr", now-7200);
- }
-
- /* 8 connections with "entropy" */
- for (i=159; i < 167; ++i) {
- SET_TEST_ADDRESS(i);
- geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &addr, "entropy", now-7200);
- }
-
- /* 2 connections from the same IP with two different transports. */
- SET_TEST_ADDRESS(++i);
- geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &addr, "fire", now-7200);
- geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &addr, "google", now-7200);
-
- /* Test the transport history string. */
- s = geoip_get_transport_history();
- tor_assert(s);
- tt_str_op(s,OP_EQ, "<OR>=8,alpha=16,beta=8,charlie=16,ddr=136,"
- "entropy=8,fire=8,google=8");
-
- /* Stop collecting entry statistics. */
- geoip_entry_stats_term();
- get_options_mutable()->EntryStatistics = 0;
-
- done:
- tor_free(s);
-}
-
-#undef SET_TEST_ADDRESS
-#undef SET_TEST_IPV6
-#undef CHECK_COUNTRY
-
/** Run unit tests for stats code. */
static void
test_stats(void *arg)
@@ -1166,8 +824,6 @@ static struct testcase_t test_array[] = {
{ "fast_handshake", test_fast_handshake, 0, NULL, NULL },
FORK(circuit_timeout),
FORK(rend_fns),
- ENT(geoip),
- FORK(geoip_with_pt),
FORK(stats),
END_OF_TESTCASES
@@ -1179,7 +835,9 @@ struct testgroup_t testgroups[] = {
{ "addr/", addr_tests },
{ "address/", address_tests },
{ "address_set/", address_set_tests },
+ { "bridges/", bridges_tests },
{ "buffer/", buffer_tests },
+ { "bwmgt/", bwmgt_tests },
{ "cellfmt/", cell_format_tests },
{ "cellqueue/", cell_queue_tests },
{ "channel/", channel_tests },
@@ -1201,15 +859,21 @@ struct testgroup_t testgroups[] = {
{ "control/", controller_tests },
{ "control/event/", controller_event_tests },
{ "crypto/", crypto_tests },
+ { "crypto/ope/", crypto_ope_tests },
+#ifdef ENABLE_OPENSSL
{ "crypto/openssl/", crypto_openssl_tests },
+#endif
+ { "crypto/pem/", pem_tests },
{ "dir/", dir_tests },
{ "dir_handle_get/", dir_handle_get_tests },
{ "dir/md/", microdesc_tests },
+ { "dir/voting-schedule/", voting_schedule_tests },
{ "dos/", dos_tests },
{ "entryconn/", entryconn_tests },
{ "entrynodes/", entrynodes_tests },
{ "guardfraction/", guardfraction_tests },
{ "extorport/", extorport_tests },
+ { "geoip/", geoip_tests },
{ "legacy_hs/", hs_tests },
{ "hs_cache/", hs_cache },
{ "hs_cell/", hs_cell_tests },
@@ -1224,10 +888,12 @@ struct testgroup_t testgroups[] = {
{ "introduce/", introduce_tests },
{ "keypin/", keypin_tests },
{ "link-handshake/", link_handshake_tests },
+ { "mainloop/", mainloop_tests },
{ "nodelist/", nodelist_tests },
{ "oom/", oom_tests },
{ "oos/", oos_tests },
{ "options/", options_tests },
+ { "periodic-event/" , periodic_event_tests },
{ "policy/" , policy_tests },
{ "procmon/", procmon_tests },
{ "proto/http/", proto_http_tests },
@@ -1236,6 +902,7 @@ struct testgroup_t testgroups[] = {
{ "pt/", pt_tests },
{ "relay/" , relay_tests },
{ "relaycell/", relaycell_tests },
+ { "relaycrypt/", relaycrypt_tests },
{ "rend_cache/", rend_cache_tests },
{ "replaycache/", replaycache_tests },
{ "router/", router_tests },
@@ -1248,14 +915,16 @@ struct testgroup_t testgroups[] = {
{ "status/" , status_tests },
{ "storagedir/", storagedir_tests },
{ "tortls/", tortls_tests },
+#ifndef ENABLE_NSS
+ { "tortls/openssl/", tortls_openssl_tests },
+#endif
+ { "tortls/x509/", x509_tests },
{ "util/", util_tests },
{ "util/format/", util_format_tests },
{ "util/logging/", logging_tests },
{ "util/process/", util_process_tests },
- { "util/pubsub/", pubsub_tests },
{ "util/thread/", thread_tests },
{ "util/handle/", handle_tests },
{ "dns/", dns_tests },
END_OF_GROUPS
};
-
diff --git a/src/test/test.h b/src/test/test.h
index 26139fc5fe..a46fedf3e0 100644
--- a/src/test/test.h
+++ b/src/test/test.h
@@ -1,6 +1,6 @@
/* Copyright (c) 2001-2003, Roger Dingledine.
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2017, The Tor Project, Inc. */
+ * Copyright (c) 2007-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
#ifndef TOR_TEST_H
@@ -11,7 +11,8 @@
* \brief Macros and functions used by unit tests.
*/
-#include "compat.h"
+#define DEBUG_SMARTLIST 1
+
#include "tinytest.h"
#define TT_EXIT_TEST_FUNCTION STMT_BEGIN goto done; STMT_END
#include "tinytest_macros.h"
@@ -49,28 +50,28 @@
tt_double_op((a), OP_LE, (b)); \
STMT_END
-#ifdef _MSC_VER
-#define U64_PRINTF_TYPE uint64_t
-#define I64_PRINTF_TYPE int64_t
-#else
-#define U64_PRINTF_TYPE unsigned long long
-#define I64_PRINTF_TYPE long long
-#endif /* defined(_MSC_VER) */
-
#define tt_size_op(a,op,b) \
tt_assert_test_fmt_type(a,b,#a" "#op" "#b,size_t,(val1_ op val2_), \
- U64_PRINTF_TYPE, U64_FORMAT, \
- {print_ = (U64_PRINTF_TYPE) value_;}, {}, TT_EXIT_TEST_FUNCTION)
+ size_t, "%"TOR_PRIuSZ, \
+ {print_ = (size_t) value_;}, {}, TT_EXIT_TEST_FUNCTION)
#define tt_u64_op(a,op,b) \
tt_assert_test_fmt_type(a,b,#a" "#op" "#b,uint64_t,(val1_ op val2_), \
- U64_PRINTF_TYPE, U64_FORMAT, \
- {print_ = (U64_PRINTF_TYPE) value_;}, {}, TT_EXIT_TEST_FUNCTION)
+ uint64_t, "%"PRIu64, \
+ {print_ = (uint64_t) value_;}, {}, TT_EXIT_TEST_FUNCTION)
#define tt_i64_op(a,op,b) \
- tt_assert_test_fmt_type(a,b,#a" "#op" "#b,int64_t,(val1_ op val2_), \
- I64_PRINTF_TYPE, I64_FORMAT, \
- {print_ = (I64_PRINTF_TYPE) value_;}, {}, TT_EXIT_TEST_FUNCTION)
+ tt_assert_test_fmt_type(a,b,#a" "#op" "#b,int64_t,(val1_ op val2_), \
+ int64_t, "%"PRId64, \
+ {print_ = (int64_t) value_;}, {}, TT_EXIT_TEST_FUNCTION)
+
+/**
+ * Declare that the test is done, even though no tt___op() calls were made.
+ *
+ * For use when you only want to test calling something, but not check
+ * any values/pointers/etc afterwards.
+ */
+#define tt_finished() TT_EXIT_TEST_FUNCTION
const char *get_fname(const char *name);
const char *get_fname_rnd(const char *name);
@@ -178,6 +179,8 @@ extern struct testcase_t accounting_tests[];
extern struct testcase_t addr_tests[];
extern struct testcase_t address_tests[];
extern struct testcase_t address_set_tests[];
+extern struct testcase_t bridges_tests[];
+extern struct testcase_t bwmgt_tests[];
extern struct testcase_t buffer_tests[];
extern struct testcase_t cell_format_tests[];
extern struct testcase_t cell_queue_tests[];
@@ -200,6 +203,7 @@ extern struct testcase_t container_tests[];
extern struct testcase_t controller_tests[];
extern struct testcase_t controller_event_tests[];
extern struct testcase_t crypto_tests[];
+extern struct testcase_t crypto_ope_tests[];
extern struct testcase_t crypto_openssl_tests[];
extern struct testcase_t dir_tests[];
extern struct testcase_t dir_handle_get_tests[];
@@ -208,6 +212,7 @@ extern struct testcase_t entryconn_tests[];
extern struct testcase_t entrynodes_tests[];
extern struct testcase_t guardfraction_tests[];
extern struct testcase_t extorport_tests[];
+extern struct testcase_t geoip_tests[];
extern struct testcase_t hs_tests[];
extern struct testcase_t hs_cache[];
extern struct testcase_t hs_cell_tests[];
@@ -223,20 +228,23 @@ extern struct testcase_t introduce_tests[];
extern struct testcase_t keypin_tests[];
extern struct testcase_t link_handshake_tests[];
extern struct testcase_t logging_tests[];
+extern struct testcase_t mainloop_tests[];
extern struct testcase_t microdesc_tests[];
extern struct testcase_t nodelist_tests[];
extern struct testcase_t oom_tests[];
extern struct testcase_t oos_tests[];
extern struct testcase_t options_tests[];
+extern struct testcase_t pem_tests[];
+extern struct testcase_t periodic_event_tests[];
extern struct testcase_t policy_tests[];
extern struct testcase_t procmon_tests[];
extern struct testcase_t proto_http_tests[];
extern struct testcase_t proto_misc_tests[];
extern struct testcase_t protover_tests[];
-extern struct testcase_t pubsub_tests[];
extern struct testcase_t pt_tests[];
extern struct testcase_t relay_tests[];
extern struct testcase_t relaycell_tests[];
+extern struct testcase_t relaycrypt_tests[];
extern struct testcase_t rend_cache_tests[];
extern struct testcase_t replaycache_tests[];
extern struct testcase_t router_tests[];
@@ -249,12 +257,15 @@ extern struct testcase_t socks_tests[];
extern struct testcase_t status_tests[];
extern struct testcase_t thread_tests[];
extern struct testcase_t tortls_tests[];
+extern struct testcase_t tortls_openssl_tests[];
extern struct testcase_t util_tests[];
extern struct testcase_t util_format_tests[];
extern struct testcase_t util_process_tests[];
+extern struct testcase_t voting_schedule_tests[];
extern struct testcase_t dns_tests[];
extern struct testcase_t handle_tests[];
extern struct testcase_t sr_tests[];
+extern struct testcase_t x509_tests[];
extern struct testcase_t slow_crypto_tests[];
extern struct testcase_t slow_util_tests[];
@@ -275,4 +286,3 @@ extern const char AUTHORITY_SIGNKEY_C_DIGEST[];
extern const char AUTHORITY_SIGNKEY_C_DIGEST256[];
#endif /* !defined(TOR_TEST_H) */
-
diff --git a/src/test/test_accounting.c b/src/test/test_accounting.c
index b0d37b2989..7721a9eb99 100644
--- a/src/test/test_accounting.c
+++ b/src/test/test_accounting.c
@@ -1,13 +1,15 @@
-/* Copyright (c) 2014-2017, The Tor Project, Inc. */
+/* Copyright (c) 2014-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
-#include "or.h"
-#include "test.h"
+#include "core/or/or.h"
+#include "test/test.h"
#define HIBERNATE_PRIVATE
-#include "hibernate.h"
-#include "config.h"
+#include "feature/hibernate/hibernate.h"
+#include "app/config/config.h"
#define STATEFILE_PRIVATE
-#include "statefile.h"
+#include "app/config/statefile.h"
+
+#include "app/config/or_state_st.h"
#define NS_MODULE accounting
@@ -102,4 +104,3 @@ struct testcase_t accounting_tests[] = {
{ "bwlimits", test_accounting_limits, TT_FORK, NULL, NULL },
END_OF_TESTCASES
};
-
diff --git a/src/test/test_addr.c b/src/test/test_addr.c
index e1a40b7e60..a9004048a5 100644
--- a/src/test/test_addr.c
+++ b/src/test/test_addr.c
@@ -1,74 +1,25 @@
/* Copyright (c) 2001-2004, Roger Dingledine.
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2017, The Tor Project, Inc. */
+ * Copyright (c) 2007-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
#define ADDRESSMAP_PRIVATE
#include "orconfig.h"
-#include "or.h"
-#include "test.h"
-#include "addressmap.h"
+#include "core/or/or.h"
+#include "lib/crypt_ops/crypto_rand.h"
+#include "test/test.h"
+#include "feature/client/addressmap.h"
+#include "test/log_test_helpers.h"
+#include "lib/net/resolve.h"
-/** Mocking replacement: only handles localhost. */
-static int
-mock_tor_addr_lookup(const char *name, uint16_t family, tor_addr_t *addr_out)
-{
- if (!strcmp(name, "localhost")) {
- if (family == AF_INET || family == AF_UNSPEC) {
- tor_addr_from_ipv4h(addr_out, 0x7f000001);
- return 0;
- } else if (family == AF_INET6) {
- char bytes[16] = { 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 1 };
- tor_addr_from_ipv6_bytes(addr_out, bytes);
- return 0;
- }
- }
- return -1;
-}
+#ifdef HAVE_SYS_UN_H
+#include <sys/un.h>
+#endif
static void
test_addr_basic(void *arg)
{
- uint32_t u32;
- uint16_t u16;
- char *cp;
-
- /* Test addr_port_lookup */
- (void)arg;
- cp = NULL; u32 = 3; u16 = 3;
- tt_assert(!addr_port_lookup(LOG_WARN, "1.2.3.4", &cp, &u32, &u16));
- tt_str_op(cp,OP_EQ, "1.2.3.4");
- tt_int_op(u32,OP_EQ, 0x01020304u);
- tt_int_op(u16,OP_EQ, 0);
- tor_free(cp);
- tt_assert(!addr_port_lookup(LOG_WARN, "4.3.2.1:99", &cp, &u32, &u16));
- tt_str_op(cp,OP_EQ, "4.3.2.1");
- tt_int_op(u32,OP_EQ, 0x04030201u);
- tt_int_op(u16,OP_EQ, 99);
- tor_free(cp);
-
- MOCK(tor_addr_lookup, mock_tor_addr_lookup);
-
- tt_assert(!addr_port_lookup(LOG_WARN, "nonexistent.address:4040",
- &cp, NULL, &u16));
- tt_str_op(cp,OP_EQ, "nonexistent.address");
- tt_int_op(u16,OP_EQ, 4040);
- tor_free(cp);
- tt_assert(!addr_port_lookup(LOG_WARN, "localhost:9999", &cp, &u32, &u16));
- tt_str_op(cp,OP_EQ, "localhost");
- tt_int_op(u16,OP_EQ, 9999);
- tt_int_op(u32,OP_EQ, 0x7f000001u);
- tor_free(cp);
- u32 = 3;
- tt_assert(!addr_port_lookup(LOG_WARN, "localhost", NULL, &u32, &u16));
- tt_ptr_op(cp,OP_EQ, NULL);
- tt_int_op(u32,OP_EQ, 0x7f000001u);
- tt_int_op(u16,OP_EQ, 0);
- tor_free(cp);
-
- tt_assert(addr_port_lookup(LOG_WARN, "localhost:3", &cp, &u32, NULL));
- tor_free(cp);
+ (void) arg;
tt_int_op(0,OP_EQ, addr_mask_get_bits(0x0u));
tt_int_op(32,OP_EQ, addr_mask_get_bits(0xFFFFFFFFu));
@@ -96,8 +47,7 @@ test_addr_basic(void *arg)
}
done:
- UNMOCK(tor_addr_lookup);
- tor_free(cp);
+ ;
}
#define test_op_ip6_(a,op,b,e1,e2) \
@@ -941,6 +891,158 @@ test_virtaddrmap(void *data)
;
}
+static const char *canned_data = NULL;
+static size_t canned_data_len = 0;
+
+/* Mock replacement for crypto_rand() that returns canned data from
+ * canned_data above. */
+static void
+crypto_canned(char *ptr, size_t n)
+{
+ if (canned_data_len) {
+ size_t to_copy = MIN(n, canned_data_len);
+ memcpy(ptr, canned_data, to_copy);
+ canned_data += to_copy;
+ canned_data_len -= to_copy;
+ n -= to_copy;
+ ptr += to_copy;
+ }
+ if (n) {
+ crypto_rand_unmocked(ptr, n);
+ }
+}
+
+static void
+test_virtaddrmap_persist(void *data)
+{
+ (void)data;
+ const char *a, *b, *c;
+ tor_addr_t addr;
+ char *ones = NULL;
+
+ addressmap_init();
+
+ // Try a hostname.
+ a = addressmap_register_virtual_address(RESOLVED_TYPE_HOSTNAME,
+ tor_strdup("foobar.baz"));
+ tt_assert(a);
+ tt_assert(!strcmpend(a, ".virtual"));
+
+ // mock crypto_rand to repeat the same result twice; make sure we get
+ // different outcomes. (Because even though the odds for receiving the
+ // same 80-bit address twice is only 1/2^40, it could still happen for
+ // some user -- but running our test through 2^40 iterations isn't
+ // reasonable.)
+ canned_data = "1234567890" // the first call returns this.
+ "1234567890" // the second call returns this.
+ "abcdefghij"; // the third call returns this.
+ canned_data_len = 30;
+ MOCK(crypto_rand, crypto_canned);
+
+ a = addressmap_register_virtual_address(RESOLVED_TYPE_HOSTNAME,
+ tor_strdup("quuxit.baz"));
+ b = addressmap_register_virtual_address(RESOLVED_TYPE_HOSTNAME,
+ tor_strdup("nescio.baz"));
+ tt_assert(a);
+ tt_assert(b);
+ tt_str_op(a, OP_EQ, "gezdgnbvgy3tqojq.virtual");
+ tt_str_op(b, OP_EQ, "mfrggzdfmztwq2lk.virtual");
+
+ // Now try something to get us an ipv4 address
+ UNMOCK(crypto_rand);
+ tt_int_op(0,OP_EQ, parse_virtual_addr_network("192.168.0.0/16",
+ AF_INET, 0, NULL));
+ a = addressmap_register_virtual_address(RESOLVED_TYPE_IPV4,
+ tor_strdup("foobar.baz"));
+ tt_assert(a);
+ tt_assert(!strcmpstart(a, "192.168."));
+ tor_addr_parse(&addr, a);
+ tt_int_op(AF_INET, OP_EQ, tor_addr_family(&addr));
+
+ b = addressmap_register_virtual_address(RESOLVED_TYPE_IPV4,
+ tor_strdup("quuxit.baz"));
+ tt_str_op(b, OP_NE, a);
+ tt_assert(!strcmpstart(b, "192.168."));
+
+ // Try some canned entropy and verify all the we discard duplicates,
+ // addresses that end with 0, and addresses that end with 255.
+ MOCK(crypto_rand, crypto_canned);
+ canned_data = "\x01\x02\x03\x04" // okay
+ "\x01\x02\x03\x04" // duplicate
+ "\x03\x04\x00\x00" // bad ending 1
+ "\x05\x05\x00\xff" // bad ending 2
+ "\x05\x06\x07\xf0"; // okay
+ canned_data_len = 20;
+ a = addressmap_register_virtual_address(RESOLVED_TYPE_IPV4,
+ tor_strdup("wumble.onion"));
+ b = addressmap_register_virtual_address(RESOLVED_TYPE_IPV4,
+ tor_strdup("wumpus.onion"));
+ tt_str_op(a, OP_EQ, "192.168.3.4");
+ tt_str_op(b, OP_EQ, "192.168.7.240");
+
+ // Now try IPv6!
+ UNMOCK(crypto_rand);
+ tt_int_op(0,OP_EQ, parse_virtual_addr_network("1010:F000::/20",
+ AF_INET6, 0, NULL));
+ a = addressmap_register_virtual_address(RESOLVED_TYPE_IPV6,
+ tor_strdup("foobar.baz"));
+ tt_assert(a);
+ tt_assert(!strcmpstart(a, "[1010:f"));
+ tor_addr_parse(&addr, a);
+ tt_int_op(AF_INET6, OP_EQ, tor_addr_family(&addr));
+
+ b = addressmap_register_virtual_address(RESOLVED_TYPE_IPV6,
+ tor_strdup("quuxit.baz"));
+ tt_str_op(b, OP_NE, a);
+ tt_assert(!strcmpstart(b, "[1010:f"));
+
+ // Try IPv6 with canned entropy, to make sure we detect duplicates.
+ MOCK(crypto_rand, crypto_canned);
+ canned_data = "acanthopterygian" // okay
+ "cinematographist" // okay
+ "acanthopterygian" // duplicate
+ "acanthopterygian" // duplicate
+ "acanthopterygian" // duplicate
+ "cinematographist" // duplicate
+ "coadministration"; // okay
+ canned_data_len = 16 * 7;
+ a = addressmap_register_virtual_address(RESOLVED_TYPE_IPV6,
+ tor_strdup("wuffle.baz"));
+ b = addressmap_register_virtual_address(RESOLVED_TYPE_IPV6,
+ tor_strdup("gribble.baz"));
+ c = addressmap_register_virtual_address(RESOLVED_TYPE_IPV6,
+ tor_strdup("surprisingly-legible.baz"));
+ tt_str_op(a, OP_EQ, "[1010:f16e:7468:6f70:7465:7279:6769:616e]");
+ tt_str_op(b, OP_EQ, "[1010:fe65:6d61:746f:6772:6170:6869:7374]");
+ tt_str_op(c, OP_EQ, "[1010:f164:6d69:6e69:7374:7261:7469:6f6e]");
+
+ // Try address exhaustion: make sure we can actually fail if we
+ // get too many already-existing addresses.
+ canned_data_len = 128*1024;
+ canned_data = ones = tor_malloc(canned_data_len);
+ memset(ones, 1, canned_data_len);
+ // There is some chance this one will fail if a previous random
+ // allocation gave out the address already.
+ a = addressmap_register_virtual_address(RESOLVED_TYPE_IPV4,
+ tor_strdup("might-work.onion"));
+ if (a) {
+ tt_str_op(a, OP_EQ, "192.168.1.1");
+ }
+ setup_capture_of_logs(LOG_WARN);
+ // This one will definitely fail, since we've set up the RNG to hand
+ // out "1" forever.
+ b = addressmap_register_virtual_address(RESOLVED_TYPE_IPV4,
+ tor_strdup("wont-work.onion"));
+ tt_assert(b == NULL);
+ expect_single_log_msg_containing("Ran out of virtual addresses!");
+
+ done:
+ UNMOCK(crypto_rand);
+ tor_free(ones);
+ addressmap_free_all();
+ teardown_capture_of_logs();
+}
+
static void
test_addr_localname(void *arg)
{
@@ -1095,6 +1197,7 @@ struct testcase_t addr_tests[] = {
ADDR_LEGACY(ip6_helpers),
ADDR_LEGACY(parse),
{ "virtaddr", test_virtaddrmap, 0, NULL, NULL },
+ { "virtaddr_persist", test_virtaddrmap_persist, TT_FORK, NULL, NULL },
{ "localname", test_addr_localname, 0, NULL, NULL },
{ "dup_ip", test_addr_dup_ip, 0, NULL, NULL },
{ "sockaddr_to_str", test_addr_sockaddr_to_str, 0, NULL, NULL },
@@ -1102,4 +1205,3 @@ struct testcase_t addr_tests[] = {
{ "make_null", test_addr_make_null, 0, NULL, NULL },
END_OF_TESTCASES
};
-
diff --git a/src/test/test_address.c b/src/test/test_address.c
index 9c88d37a41..e99220f838 100644
--- a/src/test/test_address.c
+++ b/src/test/test_address.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014-2017, The Tor Project, Inc. */
+/* Copyright (c) 2014-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
#define ADDRESS_PRIVATE
@@ -23,10 +23,11 @@
#include <net/if.h>
#endif /* defined(HAVE_IFCONF_TO_SMARTLIST) */
-#include "or.h"
-#include "address.h"
-#include "test.h"
-#include "log_test_helpers.h"
+#include "core/or/or.h"
+#include "feature/nodelist/nodelist.h"
+#include "lib/net/address.h"
+#include "test/test.h"
+#include "test/log_test_helpers.h"
/** Return 1 iff <b>sockaddr1</b> and <b>sockaddr2</b> represent
* the same IP address and port combination. Otherwise, return 0.
@@ -1139,6 +1140,36 @@ test_address_tor_addr_eq_ipv4h(void *ignored)
tor_free(a);
}
+static void
+test_address_tor_addr_in_same_network_family(void *ignored)
+{
+ (void)ignored;
+ tor_addr_t a, b;
+
+ tor_addr_parse(&a, "8.8.8.8");
+ tor_addr_parse(&b, "8.8.4.4");
+ tt_int_op(addrs_in_same_network_family(&a, &b), OP_EQ, 1);
+
+ tor_addr_parse(&a, "8.8.8.8");
+ tor_addr_parse(&b, "1.1.1.1");
+ tt_int_op(addrs_in_same_network_family(&a, &b), OP_EQ, 0);
+
+ tor_addr_parse(&a, "8.8.8.8");
+ tor_addr_parse(&b, "2001:4860:4860::8844");
+ tt_int_op(addrs_in_same_network_family(&a, &b), OP_EQ, 0);
+
+ tor_addr_parse(&a, "2001:4860:4860::8888");
+ tor_addr_parse(&b, "2001:4860:4860::8844");
+ tt_int_op(addrs_in_same_network_family(&a, &b), OP_EQ, 1);
+
+ tor_addr_parse(&a, "2001:4860:4860::8888");
+ tor_addr_parse(&b, "2001:470:20::2");
+ tt_int_op(addrs_in_same_network_family(&a, &b), OP_EQ, 0);
+
+ done:
+ return;
+}
+
#define ADDRESS_TEST(name, flags) \
{ #name, test_address_ ## name, flags, NULL, NULL }
@@ -1170,6 +1201,7 @@ struct testcase_t address_tests[] = {
ADDRESS_TEST(tor_addr_to_ipv4n, 0),
ADDRESS_TEST(tor_addr_to_mapped_ipv4h, 0),
ADDRESS_TEST(tor_addr_eq_ipv4h, 0),
+ ADDRESS_TEST(tor_addr_in_same_network_family, 0),
END_OF_TESTCASES
};
diff --git a/src/test/test_address_set.c b/src/test/test_address_set.c
index df022f539a..f231740011 100644
--- a/src/test/test_address_set.c
+++ b/src/test/test_address_set.c
@@ -1,15 +1,21 @@
-/* Copyright (c) 2017, The Tor Project, Inc. */
+/* Copyright (c) 2017-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
-#include "or.h"
-#include "address_set.h"
-#include "microdesc.h"
-#include "networkstatus.h"
-#include "nodelist.h"
-#include "routerlist.h"
-#include "torcert.h"
-
-#include "test.h"
+#include "core/or/or.h"
+#include "lib/crypt_ops/crypto_rand.h"
+#include "core/or/address_set.h"
+#include "feature/nodelist/microdesc.h"
+#include "feature/nodelist/networkstatus.h"
+#include "feature/nodelist/nodelist.h"
+#include "feature/nodelist/routerlist.h"
+#include "feature/nodelist/torcert.h"
+
+#include "feature/nodelist/microdesc_st.h"
+#include "feature/nodelist/networkstatus_st.h"
+#include "feature/nodelist/routerinfo_st.h"
+#include "feature/nodelist/routerstatus_st.h"
+
+#include "test/test.h"
static networkstatus_t *dummy_ns = NULL;
static networkstatus_t *
diff --git a/src/test/test_bridges.c b/src/test/test_bridges.c
new file mode 100644
index 0000000000..1cad5445f4
--- /dev/null
+++ b/src/test/test_bridges.c
@@ -0,0 +1,704 @@
+/* Copyright (c) 2018, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+/**
+ * \file test_bridges.c
+ * \brief Unittests for code in bridges.c
+ **/
+
+#define TOR_BRIDGES_PRIVATE
+#define PT_PRIVATE /* Only needed for the mock_* items below */
+
+#include <stdbool.h>
+
+#include "core/or/or.h"
+#include "lib/net/address.h"
+#include "feature/client/bridges.h"
+#include "app/config/config.h"
+#include "feature/client/transports.h"
+#include "feature/nodelist/node_st.h"
+#include "feature/nodelist/routerinfo_st.h"
+#include "feature/nodelist/routerstatus_st.h"
+#include "feature/nodelist/microdesc_st.h"
+
+/* Test suite stuff */
+#include "test/test.h"
+
+/**
+ * A mocked transport_t, constructed via mock_transport_get_by_name().
+ */
+static transport_t *mock_transport = NULL;
+
+/**
+ * Mock transport_get_by_name() to simply return a transport_t for the
+ * transport name that was input to it.
+ */
+static transport_t *
+mock_transport_get_by_name(const char *name)
+{
+ tor_addr_t *addr = tor_malloc(sizeof(tor_addr_t));
+ uint16_t port = 9999;
+ int socksv = 9;
+ char *args = tor_strdup("foo=bar");
+
+ if (!mock_transport) {
+ tor_addr_parse(addr, "99.99.99.99");
+ mock_transport = transport_new(addr, port, name, socksv, args);
+ }
+
+ tor_free(addr);
+ tor_free(args);
+
+ return mock_transport;
+}
+
+#undef PT_PRIVATE /* defined(PT_PRIVATE) */
+
+/**
+ * Test helper: Add a variety of bridges to our global bridgelist.
+ */
+static void
+helper_add_bridges_to_bridgelist(void *arg)
+{
+ /* Note: the two bridges which do not have specified fingerprints will be
+ * internally stored as both having the same fingerprint of all-zero bytes.
+ */
+
+ (void)arg;
+ char *bridge0 = tor_strdup("6.6.6.6:6666");
+ char *bridge1 = tor_strdup("6.6.6.7:6667 "
+ "A10C4F666D27364036B562823E5830BC448E046A");
+ char *bridge2 = tor_strdup("obfs4 198.245.60.51:443 "
+ "752CF7825B3B9EA6A98C83AC41F7099D67007EA5 "
+ "cert=xpmQtKUqQ/6v5X7ijgYE/f03+l2/EuQ1dexjyUhh16wQlu/"
+ "cpXUGalmhDIlhuiQPNEKmKw iat-mode=0");
+ char *bridge3 = tor_strdup("banana 5.5.5.5:5555 "
+ "9D6AE1BD4FDF39721CE908966E79E16F9BFCCF2F");
+ char *bridge4 = tor_strdup("obfs4 1.2.3.4:1234 "
+ "foo=abcdefghijklmnopqrstuvwxyz");
+ char *bridge5 = tor_strdup("apple 4.4.4.4:4444 "
+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA "
+ "foo=abcdefghijklmnopqrstuvwxyz");
+ char *bridge6 = tor_strdup("[2001:0db8:85a3:0000:0000:8a2e:0370:7334]:6666");
+
+ mark_bridge_list();
+
+#define ADD_BRIDGE(bridge) \
+ bridge_line_t *bridge_line_ ##bridge = parse_bridge_line(bridge); \
+ if (!bridge_line_ ##bridge) { \
+ printf("Unparseable bridge line: '%s'", #bridge); \
+ } else { \
+ bridge_add_from_config(bridge_line_ ##bridge); \
+ } \
+ tor_free(bridge);
+
+ ADD_BRIDGE(bridge0);
+ ADD_BRIDGE(bridge1);
+ ADD_BRIDGE(bridge2);
+ ADD_BRIDGE(bridge3);
+ ADD_BRIDGE(bridge4);
+ ADD_BRIDGE(bridge5);
+ ADD_BRIDGE(bridge6);
+#undef ADD_BRIDGES
+
+ sweep_bridge_list();
+}
+
+/**
+ * Make sure our test helper works too.
+ */
+static void
+test_bridges_helper_func_add_bridges_to_bridgelist(void *arg)
+{
+ helper_add_bridges_to_bridgelist(arg);
+ tt_finished();
+
+ done:
+ mark_bridge_list();
+ sweep_bridge_list();
+}
+
+/**
+ * Calling bridge_list_get() should create a new bridgelist if we
+ * didn't have one before.
+ */
+static void
+test_bridges_bridge_list_get_creates_new_bridgelist(void *arg)
+{
+ const smartlist_t *bridgelist = bridge_list_get();
+
+ (void)arg;
+
+ tt_ptr_op(bridgelist, OP_NE, NULL);
+
+ done:
+ return;
+}
+
+/**
+ * Calling clear_bridge_list() should remove all bridges from the bridgelist.
+ */
+static void
+test_bridges_clear_bridge_list(void *arg)
+{
+ const smartlist_t *bridgelist;
+ const smartlist_t *bridgelist_after;
+ const bridge_info_t *bridge;
+
+ helper_add_bridges_to_bridgelist(arg);
+ bridgelist = bridge_list_get();
+ tt_ptr_op(bridgelist, OP_NE, NULL);
+
+ bridge = smartlist_get(bridgelist, 0);
+ tt_ptr_op(bridge, OP_NE, NULL);
+
+ clear_bridge_list();
+ bridgelist_after = bridge_list_get();
+ tt_ptr_op(bridgelist_after, OP_NE, NULL);
+ tt_int_op(smartlist_len(bridgelist_after), OP_EQ, 0);
+
+ done:
+ return;
+}
+
+/**
+ * Calling bridge_get_addrport() should give me the address and port
+ * of the bridge. In this case, we sort the smartlist of bridges on
+ * fingerprints and choose the first one.
+ */
+static void
+test_bridges_bridge_get_addrport(void *arg)
+{
+ smartlist_t *bridgelist;
+ const bridge_info_t *bridge;
+ const tor_addr_port_t *addrport;
+
+ helper_add_bridges_to_bridgelist(arg);
+ bridgelist = (smartlist_t*)bridge_list_get();
+ tt_ptr_op(bridgelist, OP_NE, NULL);
+
+ // This should be the bridge at 6.6.6.6:6666 with fingerprint
+ // 0000000000000000000000000000000000000000
+ bridge = smartlist_get(bridgelist, 0);
+ tt_ptr_op(bridge, OP_NE, NULL);
+
+ addrport = bridge_get_addr_port(bridge);
+ tt_int_op(addrport->port, OP_EQ, 6666);
+
+ done:
+ mark_bridge_list();
+ sweep_bridge_list();
+}
+
+/**
+ * Calling get_configured_bridge_by_orports_digest() with two
+ * configured bridge orports and an invalid digest should return the
+ * bridge of the first addrport in the list.
+ */
+static void
+test_bridges_get_configured_bridge_by_orports_digest(void *arg)
+{
+ smartlist_t *orports = NULL;
+ const smartlist_t *bridgelist;
+ const bridge_info_t *bridge1;
+ const bridge_info_t *bridge2;
+ const bridge_info_t *ret;
+ tor_addr_port_t *addrport1;
+ tor_addr_port_t *addrport2;
+ const char *digest;
+
+ helper_add_bridges_to_bridgelist(arg);
+ bridgelist = bridge_list_get();
+ tt_ptr_op(bridgelist, OP_NE, NULL);
+
+ // This should be the bridge at 6.6.6.6:6666 with fingerprint
+ // 0000000000000000000000000000000000000000
+ bridge1 = smartlist_get(bridgelist, 0);
+ tt_ptr_op(bridge1, OP_NE, NULL);
+ // This should be the bridge at 6.6.6.7:6667 with fingerprint
+ // A10C4F666D27364036B562823E5830BC448E046A
+ bridge2 = smartlist_get(bridgelist, 1);
+ tt_ptr_op(bridge2, OP_NE, NULL);
+
+ addrport1 = (tor_addr_port_t*)bridge_get_addr_port(bridge1);
+ tt_int_op(addrport1->port, OP_EQ, 6666);
+ addrport2 = (tor_addr_port_t*)bridge_get_addr_port(bridge2);
+ tt_int_op(addrport2->port, OP_EQ, 6667);
+
+ orports = smartlist_new();
+ smartlist_add(orports, addrport1);
+ smartlist_add(orports, addrport2);
+
+ digest = "zzzzzzzzzzzzzzzz";
+
+ ret = get_configured_bridge_by_orports_digest(digest, orports);
+ tt_ptr_op(ret, OP_NE, NULL);
+
+ tt_assert(tor_addr_port_eq(addrport1, bridge_get_addr_port(ret)));
+
+ done:
+ smartlist_free(orports);
+
+ mark_bridge_list();
+ sweep_bridge_list();
+}
+
+/**
+ * Calling get_configured_bridge_by_addr_port_digest() with a digest that we do
+ * have and an addr:port pair we don't should return the bridge for that
+ * digest.
+ */
+static void
+test_bridges_get_configured_bridge_by_addr_port_digest_digest_only(void *arg)
+{
+ char digest[DIGEST_LEN];
+ bridge_info_t *bridge;
+ const char fingerprint[HEX_DIGEST_LEN] =
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
+ tor_addr_t *addr = tor_malloc(sizeof(tor_addr_t));
+ char ret_addr[16];
+ uint16_t port = 11111;
+ int ret;
+
+ helper_add_bridges_to_bridgelist(arg);
+
+ // We don't actually have a bridge with this addr:port pair
+ base16_decode(digest, DIGEST_LEN, fingerprint, HEX_DIGEST_LEN);
+ ret = tor_addr_parse(addr, "111.111.111.111");
+ tt_int_op(ret, OP_EQ, 2); // it returns the address family on success
+
+ bridge = get_configured_bridge_by_addr_port_digest(addr, port, digest);
+ tt_ptr_op(bridge, OP_NE, NULL);
+
+ tor_addr_to_str(ret_addr, &bridge_get_addr_port(bridge)->addr, 16, 0);
+ tt_str_op("4.4.4.4", OP_EQ, ret_addr);
+
+ done:
+ tor_free(addr);
+
+ mark_bridge_list();
+ sweep_bridge_list();
+}
+
+/**
+ * Calling get_configured_bridge_by_addr_port_digest() with only an
+ * addr:port (i.e. digest set to NULL) should return the bridge for
+ * that digest when there is such a bridge.
+ */
+static void
+test_bridges_get_configured_bridge_by_addr_port_digest_address_only(void *arg)
+{
+ bridge_info_t *bridge;
+ tor_addr_t *addr = tor_malloc(sizeof(tor_addr_t));
+ char ret_addr[16];
+ uint16_t port = 6666;
+ int ret;
+
+ helper_add_bridges_to_bridgelist(arg);
+
+ ret = tor_addr_parse(addr, "6.6.6.6");
+ tt_int_op(ret, OP_EQ, 2); // it returns the address family on success
+
+ bridge = get_configured_bridge_by_addr_port_digest(addr, port, NULL);
+ tt_ptr_op(bridge, OP_NE, NULL);
+
+ tor_addr_to_str(ret_addr, &bridge_get_addr_port(bridge)->addr, 16, 0);
+ tt_str_op("6.6.6.6", OP_EQ, ret_addr);
+
+ done:
+ tor_free(addr);
+
+ mark_bridge_list();
+ sweep_bridge_list();
+}
+
+/**
+ * Calling get_configured_bridge_by_exact_addr_port_digest() with a digest that
+ * we do have, and an addr:port pair we don't have, should return NULL.
+ */
+static void
+test_bridges_get_configured_bridge_by_exact_addr_port_digest_donly(void *arg)
+{
+ char digest[DIGEST_LEN];
+ bridge_info_t *bridge;
+ const char fingerprint[HEX_DIGEST_LEN] =
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
+ tor_addr_t *addr = tor_malloc(sizeof(tor_addr_t));
+ uint16_t port = 11111;
+ int ret;
+
+ helper_add_bridges_to_bridgelist(arg);
+
+ // We don't actually have a bridge with this addr:port pair
+ base16_decode(digest, DIGEST_LEN, fingerprint, HEX_DIGEST_LEN);
+ ret = tor_addr_parse(addr, "111.111.111.111");
+ tt_int_op(ret, OP_EQ, 2); // it returns the address family on success
+
+ bridge = get_configured_bridge_by_exact_addr_port_digest(addr, port, digest);
+ tt_ptr_op(bridge, OP_EQ, NULL);
+
+ done:
+ tor_free(addr);
+
+ mark_bridge_list();
+ sweep_bridge_list();
+}
+
+/**
+ * Calling get_configured_bridge_by_exact_addr_port_digest() with a digest that
+ * we do have, and an addr:port pair we do have, should return the bridge.
+ */
+static void
+test_bridges_get_configured_bridge_by_exact_addr_port_digest_both(void *arg)
+{
+ char digest[DIGEST_LEN];
+ bridge_info_t *bridge;
+ const char fingerprint[HEX_DIGEST_LEN] =
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
+ tor_addr_t *addr = tor_malloc(sizeof(tor_addr_t));
+ uint16_t port = 4444;
+ char ret_addr[16];
+ int ret;
+
+ helper_add_bridges_to_bridgelist(arg);
+
+ base16_decode(digest, DIGEST_LEN, fingerprint, HEX_DIGEST_LEN);
+ ret = tor_addr_parse(addr, "4.4.4.4");
+ tt_int_op(ret, OP_EQ, 2); // it returns the address family on success
+
+ bridge = get_configured_bridge_by_exact_addr_port_digest(addr, port, digest);
+ tt_ptr_op(bridge, OP_NE, NULL);
+
+ tor_addr_to_str(ret_addr, &bridge_get_addr_port(bridge)->addr, 16, 0);
+ tt_str_op("4.4.4.4", OP_EQ, ret_addr);
+
+ done:
+ tor_free(addr);
+
+ mark_bridge_list();
+ sweep_bridge_list();
+}
+
+/**
+ * Calling get_configured_bridge_by_exact_addr_port_digest() with no digest,
+ * and an addr:port pair we do have, should return the bridge.
+ */
+static void
+test_bridges_get_configured_bridge_by_exact_addr_port_digest_aonly(void *arg)
+{
+ bridge_info_t *bridge;
+ tor_addr_t *addr = tor_malloc(sizeof(tor_addr_t));
+ uint16_t port = 4444;
+ char ret_addr[16];
+ int ret;
+
+ helper_add_bridges_to_bridgelist(arg);
+
+ ret = tor_addr_parse(addr, "4.4.4.4");
+ tt_int_op(ret, OP_EQ, 2); // it returns the address family on success
+
+ bridge = get_configured_bridge_by_exact_addr_port_digest(addr, port, NULL);
+ tt_ptr_op(bridge, OP_NE, NULL);
+
+ tor_addr_to_str(ret_addr, &bridge_get_addr_port(bridge)->addr, 16, 0);
+ tt_str_op("4.4.4.4", OP_EQ, ret_addr);
+
+ done:
+ tor_free(addr);
+
+ mark_bridge_list();
+ sweep_bridge_list();
+}
+
+/**
+ * Calling find_bridge_by_digest() when we have a bridge with a known
+ * identity digest should return the bridge's information.
+ */
+static void
+test_bridges_find_bridge_by_digest_known(void *arg)
+{
+ char digest1[DIGEST_LEN];
+ bridge_info_t *bridge;
+ const char fingerprint[HEX_DIGEST_LEN] =
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
+
+ helper_add_bridges_to_bridgelist(arg);
+
+ base16_decode(digest1, DIGEST_LEN, fingerprint, HEX_DIGEST_LEN);
+ bridge = find_bridge_by_digest(digest1);
+
+ tt_ptr_op(bridge, OP_NE, NULL);
+
+ /* We have to call bridge_get_rsa_id_digest() here because the bridge_info_t
+ * struct is opaquely defined in bridges.h. */
+ const uint8_t *digest2 = bridge_get_rsa_id_digest(bridge);
+
+ tt_mem_op((char*)digest2, OP_EQ, digest1, DIGEST_LEN);
+
+ done:
+ mark_bridge_list();
+ sweep_bridge_list();
+}
+
+/**
+ * Calling find_bridge_by_digest() when we do NOT have a bridge with that
+ * identity digest should return NULL.
+ */
+static void
+test_bridges_find_bridge_by_digest_unknown(void *arg)
+{
+ const char *fingerprint = "cccccccccccccccccccccccccccccccccccccccc";
+ bridge_info_t *bridge;
+
+ helper_add_bridges_to_bridgelist(arg);
+
+ bridge = find_bridge_by_digest(fingerprint);
+
+ tt_ptr_op(bridge, OP_EQ, NULL);
+
+ done:
+ mark_bridge_list();
+ sweep_bridge_list();
+}
+
+/**
+ * Calling bridge_resolve_conflicts() with an identical bridge to one we've
+ * already configure should mark the pre-configured bridge for removal.
+ */
+static void
+test_bridges_bridge_resolve_conflicts(void *arg)
+{
+ tor_addr_t *addr = tor_malloc(sizeof(tor_addr_t));
+ uint16_t port = 4444;
+ const char *digest = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
+ const char *transport = "apple";
+ int ret;
+
+ helper_add_bridges_to_bridgelist(arg);
+
+ ret = tor_addr_parse(addr, "4.4.4.4");
+ tt_int_op(ret, OP_EQ, 2); // it returns the address family on success
+
+ bridge_resolve_conflicts((const tor_addr_t*)addr, port, digest, transport);
+
+ /* The bridge should now be marked for removal, and removed when we sweep the
+ * bridge_list */
+ sweep_bridge_list();
+ ret = addr_is_a_configured_bridge((const tor_addr_t*)addr, port, digest);
+ tt_int_op(ret, OP_EQ, 0);
+
+ done:
+ tor_free(addr);
+
+ mark_bridge_list();
+ sweep_bridge_list();
+}
+
+/**
+ * Calling transport_is_needed() with a transport we do need ("obfs4") and a
+ * bogus transport that we don't need should return 1 and 0, respectively.
+ */
+static void
+test_bridges_transport_is_needed(void *arg)
+{
+ int ret;
+
+ helper_add_bridges_to_bridgelist(arg);
+
+ ret = transport_is_needed("obfs4");
+ tt_int_op(ret, OP_EQ, 1);
+
+ ret = transport_is_needed("apowefjaoewpaief");
+ tt_int_op(ret, OP_EQ, 0);
+
+ done:
+ mark_bridge_list();
+ sweep_bridge_list();
+}
+
+/**
+ * Calling get_transport_by_bridge_addrport() with the address and port of a
+ * configured bridge which uses a pluggable transport when there is no global
+ * transport_list should return -1 and the transport_t should be NULL.
+ */
+static void
+test_bridges_get_transport_by_bridge_addrport_no_ptlist(void *arg)
+{
+ transport_t *transport = NULL;
+ tor_addr_t *addr = tor_malloc(sizeof(tor_addr_t));
+ uint16_t port = 1234;
+ int ret;
+
+ helper_add_bridges_to_bridgelist(arg);
+
+ ret = tor_addr_parse(addr, "1.2.3.4");
+ tt_int_op(ret, OP_EQ, 2); // it returns the address family on success?
+
+ /* This will fail because the global transport_list has nothing in it, and so
+ * transport_get_by_name() has nothing to return, even the the bridge *did*
+ * say it had an obfs4 transport.
+ */
+ ret = get_transport_by_bridge_addrport((const tor_addr_t*)addr, port,
+ (const transport_t**)&transport);
+ tt_int_op(ret, OP_EQ, -1); // returns -1 on failure
+ tt_ptr_op(transport, OP_EQ, NULL);
+
+ done:
+ tor_free(addr);
+
+ mark_bridge_list();
+ sweep_bridge_list();
+}
+
+#define PT_PRIVATE
+
+/**
+ * Calling get_transport_by_bridge_addrport() with the address and port of a
+ * configured bridge which uses a pluggable transport should return 0 and set
+ * appropriate transport_t.
+ */
+static void
+test_bridges_get_transport_by_bridge_addrport(void *arg)
+{
+ transport_t *transport = NULL;
+ tor_addr_t *addr = tor_malloc(sizeof(tor_addr_t));
+ uint16_t port = 1234;
+ int ret;
+
+ helper_add_bridges_to_bridgelist(arg);
+ mark_transport_list(); // Also initialise our transport_list
+
+ ret = tor_addr_parse(addr, "1.2.3.4");
+ tt_int_op(ret, OP_EQ, 2); // it returns the address family on success?
+
+ /* After we mock transport_get_by_name() to return a bogus transport_t with
+ * the name it was asked for, the call should succeed.
+ */
+ MOCK(transport_get_by_name, mock_transport_get_by_name);
+ ret = get_transport_by_bridge_addrport((const tor_addr_t*)addr, port,
+ (const transport_t**)&transport);
+ tt_int_op(ret, OP_EQ, 0); // returns 0 on success
+ tt_ptr_op(transport, OP_NE, NULL);
+ tt_str_op(transport->name, OP_EQ, "obfs4");
+
+ done:
+ UNMOCK(transport_get_by_name);
+
+ tor_free(addr);
+ transport_free(transport);
+
+ mark_bridge_list();
+ sweep_bridge_list();
+}
+
+static void
+test_bridges_node_is_a_configured_bridge(void *arg)
+{
+ routerinfo_t ri_ipv4 = { .addr = 0x06060606, .or_port = 6666 };
+ routerstatus_t rs_ipv4 = { .addr = 0x06060606, .or_port = 6666 };
+
+ routerinfo_t ri_ipv6 = { .ipv6_orport = 6666 };
+ tor_addr_parse(&(ri_ipv6.ipv6_addr),
+ "2001:0db8:85a3:0000:0000:8a2e:0370:7334");
+
+ routerstatus_t rs_ipv6 = { .ipv6_orport = 6666 };
+ tor_addr_parse(&(rs_ipv6.ipv6_addr),
+ "2001:0db8:85a3:0000:0000:8a2e:0370:7334");
+
+ microdesc_t md_ipv6 = { .ipv6_orport = 6666 };
+ tor_addr_parse(&(md_ipv6.ipv6_addr),
+ "2001:0db8:85a3:0000:0000:8a2e:0370:7334");
+
+ helper_add_bridges_to_bridgelist(arg);
+
+ node_t node_with_digest;
+ memset(&node_with_digest, 0, sizeof(node_with_digest));
+
+ const char fingerprint[HEX_DIGEST_LEN] =
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
+
+ const char fingerprint2[HEX_DIGEST_LEN] =
+ "ffffffffffffffffffffffffffffffffffffffff";
+
+ base16_decode(node_with_digest.identity, DIGEST_LEN,
+ fingerprint, HEX_DIGEST_LEN);
+
+ node_t node_ri_ipv4 = { .ri = &ri_ipv4 };
+ base16_decode(node_ri_ipv4.identity, DIGEST_LEN,
+ fingerprint2, HEX_DIGEST_LEN);
+ tt_assert(node_is_a_configured_bridge(&node_ri_ipv4));
+
+ /* This will still match bridge0, since bridge0 has no digest set. */
+ memset(node_ri_ipv4.identity, 0x3f, DIGEST_LEN);
+ tt_assert(node_is_a_configured_bridge(&node_ri_ipv4));
+
+ /* It won't match bridge1, though, since bridge1 has a digest, and this
+ isn't it! */
+ node_ri_ipv4.ri->addr = 0x06060607;
+ node_ri_ipv4.ri->or_port = 6667;
+ tt_assert(! node_is_a_configured_bridge(&node_ri_ipv4));
+ /* If we set the fingerprint right, though, it will match. */
+ base16_decode(node_ri_ipv4.identity, DIGEST_LEN,
+ "A10C4F666D27364036B562823E5830BC448E046A", HEX_DIGEST_LEN);
+ tt_assert(node_is_a_configured_bridge(&node_ri_ipv4));
+
+ node_t node_rs_ipv4 = { .rs = &rs_ipv4 };
+ base16_decode(node_rs_ipv4.identity, DIGEST_LEN,
+ fingerprint2, HEX_DIGEST_LEN);
+ tt_assert(node_is_a_configured_bridge(&node_rs_ipv4));
+
+ node_t node_ri_ipv6 = { .ri = &ri_ipv6 };
+ base16_decode(node_ri_ipv6.identity, DIGEST_LEN,
+ fingerprint2, HEX_DIGEST_LEN);
+ tt_assert(node_is_a_configured_bridge(&node_ri_ipv6));
+
+ node_t node_rs_ipv6 = { .rs = &rs_ipv6 };
+ base16_decode(node_rs_ipv6.identity, DIGEST_LEN,
+ fingerprint2, HEX_DIGEST_LEN);
+ tt_assert(node_is_a_configured_bridge(&node_rs_ipv6));
+
+ node_t node_md_ipv6 = { .md = &md_ipv6 };
+ base16_decode(node_md_ipv6.identity, DIGEST_LEN,
+ fingerprint2, HEX_DIGEST_LEN);
+ tt_assert(node_is_a_configured_bridge(&node_md_ipv6));
+
+ mark_bridge_list();
+ sweep_bridge_list();
+
+ tt_assert(!node_is_a_configured_bridge(&node_with_digest));
+ tt_assert(!node_is_a_configured_bridge(&node_ri_ipv4));
+ tt_assert(!node_is_a_configured_bridge(&node_ri_ipv6));
+ tt_assert(!node_is_a_configured_bridge(&node_rs_ipv4));
+ tt_assert(!node_is_a_configured_bridge(&node_rs_ipv6));
+ tt_assert(!node_is_a_configured_bridge(&node_md_ipv6));
+
+ done:
+ mark_bridge_list();
+ sweep_bridge_list();
+}
+
+#undef PT_PRIVATE /* defined(PT_PRIVATE) */
+
+#define B_TEST(name, flags) \
+ { #name, test_bridges_ ##name, (flags), NULL, NULL }
+
+struct testcase_t bridges_tests[] = {
+ B_TEST(helper_func_add_bridges_to_bridgelist, 0),
+ B_TEST(bridge_list_get_creates_new_bridgelist, 0),
+ B_TEST(clear_bridge_list, 0),
+ B_TEST(bridge_get_addrport, 0),
+ B_TEST(get_configured_bridge_by_orports_digest, 0),
+ B_TEST(get_configured_bridge_by_addr_port_digest_digest_only, 0),
+ B_TEST(get_configured_bridge_by_addr_port_digest_address_only, 0),
+ B_TEST(get_configured_bridge_by_exact_addr_port_digest_donly, 0),
+ B_TEST(get_configured_bridge_by_exact_addr_port_digest_both, 0),
+ B_TEST(get_configured_bridge_by_exact_addr_port_digest_aonly, 0),
+ B_TEST(find_bridge_by_digest_known, 0),
+ B_TEST(find_bridge_by_digest_unknown, 0),
+ B_TEST(bridge_resolve_conflicts, 0),
+ B_TEST(get_transport_by_bridge_addrport_no_ptlist, 0),
+ B_TEST(get_transport_by_bridge_addrport, 0),
+ B_TEST(transport_is_needed, 0),
+ B_TEST(node_is_a_configured_bridge, 0),
+ END_OF_TESTCASES
+};
diff --git a/src/test/test_bt_cl.c b/src/test/test_bt_cl.c
index b5c8d7cf9e..89cbca2066 100644
--- a/src/test/test_bt_cl.c
+++ b/src/test/test_bt_cl.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2017, The Tor Project, Inc. */
+/* Copyright (c) 2012-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
#include "orconfig.h"
@@ -7,10 +7,13 @@
/* To prevent 'assert' from going away. */
#undef TOR_COVERAGE
-#include "or.h"
-#include "util.h"
-#include "backtrace.h"
-#include "torlog.h"
+#include "core/or/or.h"
+#include "lib/err/backtrace.h"
+#include "lib/log/log.h"
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
/* -1: no crash.
* 0: crash with a segmentation fault.
@@ -118,4 +121,3 @@ main(int argc, char **argv)
return 0;
}
-
diff --git a/src/test/test_buffers.c b/src/test/test_buffers.c
index 057d9fa2dc..477066f699 100644
--- a/src/test/test_buffers.c
+++ b/src/test/test_buffers.c
@@ -1,16 +1,19 @@
/* Copyright (c) 2001-2004, Roger Dingledine.
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2017, The Tor Project, Inc. */
+ * Copyright (c) 2007-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
#define BUFFERS_PRIVATE
#define PROTO_HTTP_PRIVATE
-#include "or.h"
-#include "buffers.h"
-#include "buffers_tls.h"
-#include "proto_http.h"
-#include "proto_socks.h"
-#include "test.h"
+#include "core/or/or.h"
+#include "lib/container/buffers.h"
+#include "lib/tls/buffers_tls.h"
+#include "lib/tls/tortls.h"
+#include "lib/compress/compress.h"
+#include "lib/crypt_ops/crypto_rand.h"
+#include "core/proto/proto_http.h"
+#include "core/proto/proto_socks.h"
+#include "test/test.h"
/** Run unit tests for buffers.c */
static void
@@ -818,4 +821,3 @@ struct testcase_t buffer_tests[] = {
END_OF_TESTCASES
};
-
diff --git a/src/test/test_bwmgt.c b/src/test/test_bwmgt.c
new file mode 100644
index 0000000000..7a1782c2c9
--- /dev/null
+++ b/src/test/test_bwmgt.c
@@ -0,0 +1,233 @@
+/* Copyright (c) 2018, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+/**
+ * \file test_bwmgt.c
+ * \brief tests for bandwidth management / token bucket functions
+ */
+
+#define TOKEN_BUCKET_PRIVATE
+
+#include "core/or/or.h"
+#include "test/test.h"
+
+#include "lib/evloop/token_bucket.h"
+
+// an imaginary time, in timestamp units. Chosen so it will roll over.
+static const uint32_t START_TS = UINT32_MAX-10;
+static const int32_t KB = 1024;
+static const uint32_t GB = (UINT64_C(1) << 30);
+
+static void
+test_bwmgt_token_buf_init(void *arg)
+{
+ (void)arg;
+ token_bucket_rw_t b;
+
+ token_bucket_rw_init(&b, 16*KB, 64*KB, START_TS);
+ // Burst is correct
+ tt_uint_op(b.cfg.burst, OP_EQ, 64*KB);
+ // Rate is correct, within 1 percent.
+ {
+ uint32_t ticks_per_sec =
+ (uint32_t) monotime_msec_to_approx_coarse_stamp_units(1000);
+ uint32_t rate_per_sec = (b.cfg.rate * ticks_per_sec / TICKS_PER_STEP);
+
+ tt_uint_op(rate_per_sec, OP_GT, 16*KB-160);
+ tt_uint_op(rate_per_sec, OP_LT, 16*KB+160);
+ }
+ // Bucket starts out full:
+ tt_uint_op(b.last_refilled_at_timestamp, OP_EQ, START_TS);
+ tt_int_op(b.read_bucket.bucket, OP_EQ, 64*KB);
+
+ done:
+ ;
+}
+
+static void
+test_bwmgt_token_buf_adjust(void *arg)
+{
+ (void)arg;
+ token_bucket_rw_t b;
+
+ token_bucket_rw_init(&b, 16*KB, 64*KB, START_TS);
+
+ uint32_t rate_orig = b.cfg.rate;
+ // Increasing burst
+ token_bucket_rw_adjust(&b, 16*KB, 128*KB);
+ tt_uint_op(b.cfg.rate, OP_EQ, rate_orig);
+ tt_uint_op(b.read_bucket.bucket, OP_EQ, 64*KB);
+ tt_uint_op(b.cfg.burst, OP_EQ, 128*KB);
+
+ // Decreasing burst but staying above bucket
+ token_bucket_rw_adjust(&b, 16*KB, 96*KB);
+ tt_uint_op(b.cfg.rate, OP_EQ, rate_orig);
+ tt_uint_op(b.read_bucket.bucket, OP_EQ, 64*KB);
+ tt_uint_op(b.cfg.burst, OP_EQ, 96*KB);
+
+ // Decreasing burst below bucket,
+ token_bucket_rw_adjust(&b, 16*KB, 48*KB);
+ tt_uint_op(b.cfg.rate, OP_EQ, rate_orig);
+ tt_uint_op(b.read_bucket.bucket, OP_EQ, 48*KB);
+ tt_uint_op(b.cfg.burst, OP_EQ, 48*KB);
+
+ // Changing rate.
+ token_bucket_rw_adjust(&b, 32*KB, 48*KB);
+ tt_uint_op(b.cfg.rate, OP_GE, rate_orig*2 - 10);
+ tt_uint_op(b.cfg.rate, OP_LE, rate_orig*2 + 10);
+ tt_uint_op(b.read_bucket.bucket, OP_EQ, 48*KB);
+ tt_uint_op(b.cfg.burst, OP_EQ, 48*KB);
+
+ done:
+ ;
+}
+
+static void
+test_bwmgt_token_buf_dec(void *arg)
+{
+ (void)arg;
+ token_bucket_rw_t b;
+ token_bucket_rw_init(&b, 16*KB, 64*KB, START_TS);
+
+ // full-to-not-full.
+ tt_int_op(0, OP_EQ, token_bucket_rw_dec_read(&b, KB));
+ tt_int_op(b.read_bucket.bucket, OP_EQ, 63*KB);
+
+ // Full to almost-not-full
+ tt_int_op(0, OP_EQ, token_bucket_rw_dec_read(&b, 63*KB - 1));
+ tt_int_op(b.read_bucket.bucket, OP_EQ, 1);
+
+ // almost-not-full to empty.
+ tt_int_op(1, OP_EQ, token_bucket_rw_dec_read(&b, 1));
+ tt_int_op(b.read_bucket.bucket, OP_EQ, 0);
+
+ // reset bucket, try full-to-empty
+ token_bucket_rw_init(&b, 16*KB, 64*KB, START_TS);
+ tt_int_op(1, OP_EQ, token_bucket_rw_dec_read(&b, 64*KB));
+ tt_int_op(b.read_bucket.bucket, OP_EQ, 0);
+
+ // reset bucket, try underflow.
+ token_bucket_rw_init(&b, 16*KB, 64*KB, START_TS);
+ tt_int_op(1, OP_EQ, token_bucket_rw_dec_read(&b, 64*KB + 1));
+ tt_int_op(b.read_bucket.bucket, OP_EQ, -1);
+
+ // A second underflow does not make the bucket empty.
+ tt_int_op(0, OP_EQ, token_bucket_rw_dec_read(&b, 1000));
+ tt_int_op(b.read_bucket.bucket, OP_EQ, -1001);
+
+ done:
+ ;
+}
+
+static void
+test_bwmgt_token_buf_refill(void *arg)
+{
+ (void)arg;
+ token_bucket_rw_t b;
+ const uint32_t BW_SEC =
+ (uint32_t)monotime_msec_to_approx_coarse_stamp_units(1000);
+ token_bucket_rw_init(&b, 16*KB, 64*KB, START_TS);
+
+ /* Make the buffer much emptier, then let one second elapse. */
+ token_bucket_rw_dec_read(&b, 48*KB);
+ tt_int_op(b.read_bucket.bucket, OP_EQ, 16*KB);
+ tt_int_op(0, OP_EQ, token_bucket_rw_refill(&b, START_TS + BW_SEC));
+ tt_int_op(b.read_bucket.bucket, OP_GT, 32*KB - 300);
+ tt_int_op(b.read_bucket.bucket, OP_LT, 32*KB + 300);
+
+ /* Another half second. */
+ tt_int_op(0, OP_EQ, token_bucket_rw_refill(&b, START_TS + BW_SEC*3/2));
+ tt_int_op(b.read_bucket.bucket, OP_GT, 40*KB - 400);
+ tt_int_op(b.read_bucket.bucket, OP_LT, 40*KB + 400);
+ tt_uint_op(b.last_refilled_at_timestamp, OP_EQ, START_TS + BW_SEC*3/2);
+
+ /* No time: nothing happens. */
+ {
+ const uint32_t bucket_orig = b.read_bucket.bucket;
+ tt_int_op(0, OP_EQ, token_bucket_rw_refill(&b, START_TS + BW_SEC*3/2));
+ tt_int_op(b.read_bucket.bucket, OP_EQ, bucket_orig);
+ }
+
+ /* Another 30 seconds: fill the bucket. */
+ tt_int_op(0, OP_EQ, token_bucket_rw_refill(&b,
+ START_TS + BW_SEC*3/2 + BW_SEC*30));
+ tt_int_op(b.read_bucket.bucket, OP_EQ, b.cfg.burst);
+ tt_uint_op(b.last_refilled_at_timestamp, OP_EQ,
+ START_TS + BW_SEC*3/2 + BW_SEC*30);
+
+ /* Another 30 seconds: nothing happens. */
+ tt_int_op(0, OP_EQ, token_bucket_rw_refill(&b,
+ START_TS + BW_SEC*3/2 + BW_SEC*60));
+ tt_int_op(b.read_bucket.bucket, OP_EQ, b.cfg.burst);
+ tt_uint_op(b.last_refilled_at_timestamp, OP_EQ,
+ START_TS + BW_SEC*3/2 + BW_SEC*60);
+
+ /* Empty the bucket, let two seconds pass, and make sure that a refill is
+ * noticed. */
+ tt_int_op(1, OP_EQ, token_bucket_rw_dec_read(&b, b.cfg.burst));
+ tt_int_op(0, OP_EQ, b.read_bucket.bucket);
+ tt_int_op(1, OP_EQ, token_bucket_rw_refill(&b,
+ START_TS + BW_SEC*3/2 + BW_SEC*61));
+ tt_int_op(0, OP_EQ, token_bucket_rw_refill(&b,
+ START_TS + BW_SEC*3/2 + BW_SEC*62));
+ tt_int_op(b.read_bucket.bucket, OP_GT, 32*KB-400);
+ tt_int_op(b.read_bucket.bucket, OP_LT, 32*KB+400);
+
+ /* Underflow the bucket, make sure we detect when it has tokens again. */
+ tt_int_op(1, OP_EQ,
+ token_bucket_rw_dec_read(&b, b.read_bucket.bucket+16*KB));
+ tt_int_op(-16*KB, OP_EQ, b.read_bucket.bucket);
+ // half a second passes...
+ tt_int_op(0, OP_EQ, token_bucket_rw_refill(&b, START_TS + BW_SEC*64));
+ tt_int_op(b.read_bucket.bucket, OP_GT, -8*KB-300);
+ tt_int_op(b.read_bucket.bucket, OP_LT, -8*KB+300);
+ // a second passes
+ tt_int_op(1, OP_EQ, token_bucket_rw_refill(&b, START_TS + BW_SEC*65));
+ tt_int_op(b.read_bucket.bucket, OP_GT, 8*KB-400);
+ tt_int_op(b.read_bucket.bucket, OP_LT, 8*KB+400);
+
+ // We step a second backwards, and nothing happens.
+ tt_int_op(0, OP_EQ, token_bucket_rw_refill(&b, START_TS + BW_SEC*64));
+ tt_int_op(b.read_bucket.bucket, OP_GT, 8*KB-400);
+ tt_int_op(b.read_bucket.bucket, OP_LT, 8*KB+400);
+
+ // A ridiculous amount of time passes.
+ tt_int_op(0, OP_EQ, token_bucket_rw_refill(&b, INT32_MAX));
+ tt_int_op(b.read_bucket.bucket, OP_EQ, b.cfg.burst);
+
+ done:
+ ;
+}
+
+/* Test some helper functions we use within the token bucket interface. */
+static void
+test_bwmgt_token_buf_helpers(void *arg)
+{
+ uint32_t ret;
+
+ (void) arg;
+
+ /* The returned value will be OS specific but in any case, it should be
+ * greater than 1 since we are passing 1GB/sec rate. */
+ ret = rate_per_sec_to_rate_per_step(1 * GB);
+ tt_u64_op(ret, OP_GT, 1);
+
+ /* We default to 1 in case rate is 0. */
+ ret = rate_per_sec_to_rate_per_step(0);
+ tt_u64_op(ret, OP_EQ, 1);
+
+ done:
+ ;
+}
+
+#define BWMGT(name) \
+ { #name, test_bwmgt_ ## name , 0, NULL, NULL }
+
+struct testcase_t bwmgt_tests[] = {
+ BWMGT(token_buf_init),
+ BWMGT(token_buf_adjust),
+ BWMGT(token_buf_dec),
+ BWMGT(token_buf_refill),
+ BWMGT(token_buf_helpers),
+ END_OF_TESTCASES
+};
diff --git a/src/test/test_cell_formats.c b/src/test/test_cell_formats.c
index 88cdef383f..daf0296e2a 100644
--- a/src/test/test_cell_formats.c
+++ b/src/test/test_cell_formats.c
@@ -1,23 +1,29 @@
/* Copyright (c) 2001-2004, Roger Dingledine.
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2017, The Tor Project, Inc. */
+ * Copyright (c) 2007-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
#include "orconfig.h"
#define CONNECTION_EDGE_PRIVATE
#define RELAY_PRIVATE
-#include "or.h"
-#include "channel.h"
-#include "connection_edge.h"
-#include "connection_or.h"
-#include "config.h"
-#include "onion.h"
-#include "onion_tap.h"
-#include "onion_fast.h"
-#include "onion_ntor.h"
-#include "relay.h"
-#include "test.h"
+#include "core/or/or.h"
+#include "core/or/channel.h"
+#include "core/or/connection_edge.h"
+#include "core/or/connection_or.h"
+#include "app/config/config.h"
+#include "lib/crypt_ops/crypto_rand.h"
+#include "core/or/onion.h"
+#include "core/crypto/onion_tap.h"
+#include "core/crypto/onion_fast.h"
+#include "core/crypto/onion_ntor.h"
+#include "core/or/relay.h"
+
+#include "core/or/cell_st.h"
+#include "core/or/cell_queue_st.h"
+#include "core/or/var_cell_st.h"
+
+#include "test/test.h"
#include <stdlib.h>
#include <string.h>
@@ -1296,4 +1302,3 @@ struct testcase_t cell_format_tests[] = {
TEST(is_destroy, 0),
END_OF_TESTCASES
};
-
diff --git a/src/test/test_cell_queue.c b/src/test/test_cell_queue.c
index df987f82ce..d74bb9c622 100644
--- a/src/test/test_cell_queue.c
+++ b/src/test/test_cell_queue.c
@@ -1,12 +1,17 @@
-/* Copyright (c) 2013-2017, The Tor Project, Inc. */
+/* Copyright (c) 2013-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
#define CIRCUITLIST_PRIVATE
#define RELAY_PRIVATE
-#include "or.h"
-#include "circuitlist.h"
-#include "relay.h"
-#include "test.h"
+#include "core/or/or.h"
+#include "core/or/circuitlist.h"
+#include "core/or/relay.h"
+#include "test/test.h"
+
+#include "core/or/cell_st.h"
+#include "core/or/cell_queue_st.h"
+#include "core/or/or_circuit_st.h"
+#include "core/or/origin_circuit_st.h"
static void
test_cq_manip(void *arg)
diff --git a/src/test/test_channel.c b/src/test/test_channel.c
index bdc9d32f78..26af8de917 100644
--- a/src/test/test_channel.c
+++ b/src/test/test_channel.c
@@ -1,28 +1,35 @@
-/* Copyright (c) 2013-2017, The Tor Project, Inc. */
+/* Copyright (c) 2013-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
#define TOR_CHANNEL_INTERNAL_
#define CHANNEL_PRIVATE_
-#include "or.h"
-#include "channel.h"
+#include "core/or/or.h"
+#include "core/or/channel.h"
/* For channel_note_destroy_not_pending */
#define CIRCUITLIST_PRIVATE
-#include "circuitlist.h"
-#include "circuitmux.h"
-#include "circuitmux_ewma.h"
+#include "core/or/circuitlist.h"
+#include "core/or/circuitmux.h"
+#include "core/or/circuitmux_ewma.h"
/* For var_cell_free */
-#include "connection_or.h"
+#include "core/or/connection_or.h"
+#include "lib/crypt_ops/crypto_rand.h"
/* For packed_cell stuff */
#define RELAY_PRIVATE
-#include "relay.h"
+#include "core/or/relay.h"
/* For init/free stuff */
-#include "scheduler.h"
-#include "networkstatus.h"
+#include "core/or/scheduler.h"
+#include "feature/nodelist/networkstatus.h"
+
+#include "core/or/cell_st.h"
+#include "feature/nodelist/networkstatus_st.h"
+#include "core/or/origin_circuit_st.h"
+#include "feature/nodelist/routerstatus_st.h"
+#include "core/or/var_cell_st.h"
/* Test suite stuff */
-#include "log_test_helpers.h"
-#include "test.h"
-#include "fakechans.h"
+#include "test/log_test_helpers.h"
+#include "test/test.h"
+#include "test/fakechans.h"
static int test_chan_accept_cells = 0;
static int test_chan_fixed_cells_recved = 0;
@@ -281,6 +288,7 @@ new_fake_channel(void)
chan->state = CHANNEL_STATE_OPEN;
chan->cmux = circuitmux_alloc();
+ circuitmux_set_policy(chan->cmux, &ewma_policy);
return chan;
}
@@ -543,6 +551,13 @@ test_channel_outbound_cell(void *arg)
(void) arg;
+ /* Set the test time to be mocked, since this test assumes that no
+ * time will pass, ewma values will not need to be re-scaled, and so on */
+ monotime_enable_test_mocking();
+ monotime_set_mock_time_nsec(UINT64_C(1000000000) * 12345);
+
+ cmux_ewma_set_options(NULL,NULL);
+
/* The channel will be freed so we need to hijack this so the scheduler
* doesn't get confused. */
MOCK(scheduler_release_channel, scheduler_release_channel_mock);
@@ -575,15 +590,13 @@ test_channel_outbound_cell(void *arg)
channel_register(chan);
tt_int_op(chan->registered, OP_EQ, 1);
/* Set EWMA policy so we can pick it when flushing. */
- channel_set_cmux_policy_everywhere(&ewma_policy);
+ circuitmux_set_policy(chan->cmux, &ewma_policy);
tt_ptr_op(circuitmux_get_policy(chan->cmux), OP_EQ, &ewma_policy);
/* Register circuit to the channel circid map which will attach the circuit
* to the channel's cmux as well. */
circuit_set_n_circid_chan(TO_CIRCUIT(circ), 42, chan);
tt_int_op(channel_num_circuits(chan), OP_EQ, 1);
- tt_assert(!TO_CIRCUIT(circ)->next_active_on_n_chan);
- tt_assert(!TO_CIRCUIT(circ)->prev_active_on_n_chan);
/* Test the cmux state. */
tt_ptr_op(TO_CIRCUIT(circ)->n_mux, OP_EQ, chan->cmux);
tt_int_op(circuitmux_is_circuit_attached(chan->cmux, TO_CIRCUIT(circ)),
@@ -659,6 +672,7 @@ test_channel_outbound_cell(void *arg)
tor_free(p_cell);
channel_free_all();
UNMOCK(scheduler_release_channel);
+ monotime_disable_test_mocking();
}
/* Test inbound cell. The callstack is:
diff --git a/src/test/test_channelpadding.c b/src/test/test_channelpadding.c
index 90da2163a6..0fd60d0a92 100644
--- a/src/test/test_channelpadding.c
+++ b/src/test/test_channelpadding.c
@@ -1,25 +1,32 @@
-/* Copyright (c) 2016-2017, The Tor Project, Inc. */
+/* Copyright (c) 2016-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
#define TOR_CHANNEL_INTERNAL_
-#define MAIN_PRIVATE
+#define MAINLOOP_PRIVATE
#define NETWORKSTATUS_PRIVATE
#define TOR_TIMERS_PRIVATE
-#include "or.h"
-#include "test.h"
-#include "testsupport.h"
-#include "connection.h"
-#include "connection_or.h"
-#include "channel.h"
-#include "channeltls.h"
-#include "channelpadding.h"
-#include "compat_libevent.h"
-#include "config.h"
-#include <event2/event.h>
-#include "compat_time.h"
-#include "main.h"
-#include "networkstatus.h"
-#include "log_test_helpers.h"
+#include "core/or/or.h"
+#include "test/test.h"
+#include "lib/testsupport/testsupport.h"
+#include "core/mainloop/connection.h"
+#include "core/or/connection_or.h"
+#include "core/or/channel.h"
+#include "core/or/channeltls.h"
+#include "core/or/channelpadding.h"
+#include "lib/evloop/compat_libevent.h"
+#include "app/config/config.h"
+#include "lib/time/compat_time.h"
+#include "core/mainloop/mainloop.h"
+#include "feature/nodelist/networkstatus.h"
+#include "test/log_test_helpers.h"
+#include "lib/tls/tortls.h"
+#include "lib/evloop/timers.h"
+#include "lib/container/buffers.h"
+
+#include "core/or/cell_st.h"
+#include "feature/nodelist/networkstatus_st.h"
+#include "core/or/or_connection_st.h"
+#include "feature/nodelist/routerstatus_st.h"
int channelpadding_get_netflow_inactive_timeout_ms(channel_t *chan);
int64_t channelpadding_compute_time_until_pad_for_netflow(channel_t *chan);
@@ -65,7 +72,7 @@ mock_channel_write_cell_relay2(channel_t *chan, cell_t *cell)
(void)chan;
tried_to_write_cell++;
channel_tls_handle_cell(cell, ((channel_tls_t*)relay1_relay2)->conn);
- event_base_loopbreak(tor_libevent_get_base());
+ tor_libevent_exit_loop_after_callback(tor_libevent_get_base());
return 0;
}
@@ -75,7 +82,7 @@ mock_channel_write_cell_relay1(channel_t *chan, cell_t *cell)
(void)chan;
tried_to_write_cell++;
channel_tls_handle_cell(cell, ((channel_tls_t*)relay2_relay1)->conn);
- event_base_loopbreak(tor_libevent_get_base());
+ tor_libevent_exit_loop_after_callback(tor_libevent_get_base());
return 0;
}
@@ -85,7 +92,7 @@ mock_channel_write_cell_relay3(channel_t *chan, cell_t *cell)
(void)chan;
tried_to_write_cell++;
channel_tls_handle_cell(cell, ((channel_tls_t*)client_relay3)->conn);
- event_base_loopbreak(tor_libevent_get_base());
+ tor_libevent_exit_loop_after_callback(tor_libevent_get_base());
return 0;
}
@@ -95,7 +102,7 @@ mock_channel_write_cell_client(channel_t *chan, cell_t *cell)
(void)chan;
tried_to_write_cell++;
channel_tls_handle_cell(cell, ((channel_tls_t*)relay3_client)->conn);
- event_base_loopbreak(tor_libevent_get_base());
+ tor_libevent_exit_loop_after_callback(tor_libevent_get_base());
return 0;
}
@@ -105,7 +112,7 @@ mock_channel_write_cell(channel_t *chan, cell_t *cell)
tried_to_write_cell++;
channel_tls_handle_cell(cell, ((channel_tls_t*)chan)->conn);
if (!dont_stop_libevent)
- event_base_loopbreak(tor_libevent_get_base());
+ tor_libevent_exit_loop_after_callback(tor_libevent_get_base());
return 0;
}
@@ -246,7 +253,7 @@ static void
dummy_timer_cb(tor_timer_t *t, void *arg, const monotime_t *now_mono)
{
(void)t; (void)arg; (void)now_mono;
- event_base_loopbreak(tor_libevent_get_base());
+ tor_libevent_exit_loop_after_callback(tor_libevent_get_base());
return;
}
@@ -264,7 +271,8 @@ dummy_nop_timer(void)
timer_schedule(dummy_timer, &timeout);
- event_base_loop(tor_libevent_get_base(), 0);
+ tor_libevent_run_event_loop(tor_libevent_get_base(), 0);
+
timer_free(dummy_timer);
}
@@ -398,81 +406,12 @@ test_channelpadding_killonehop(void *arg)
setup_mock_consensus();
setup_mock_network();
- /* Do we disable padding if tor2webmode or rsos are enabled, and
- * the consensus says don't pad? */
-
- /* Ensure we can kill tor2web and rsos padding if we want. */
- // First, test that padding works if either is enabled
- smartlist_clear(current_md_consensus->net_params);
- channelpadding_new_consensus_params(current_md_consensus);
+ /* Do we disable padding if rsos is enabled, and the consensus says don't
+ * pad? */
monotime_coarse_t now;
monotime_coarse_get(&now);
- tried_to_write_cell = 0;
- get_options_mutable()->Tor2webMode = 1;
- monotime_coarse_add_msec(&client_relay3->next_padding_time, &now, 100);
- decision = channelpadding_decide_to_pad_channel(client_relay3);
- tt_int_op(decision, OP_EQ, CHANNELPADDING_PADDING_SCHEDULED);
- tt_assert(client_relay3->pending_padding_callback);
- tt_int_op(tried_to_write_cell, OP_EQ, 0);
-
- decision = channelpadding_decide_to_pad_channel(client_relay3);
- tt_int_op(decision, OP_EQ, CHANNELPADDING_PADDING_ALREADY_SCHEDULED);
-
- // Wait for the timer
- new_time += 101*NSEC_PER_MSEC;
- monotime_coarse_set_mock_time_nsec(new_time);
- monotime_set_mock_time_nsec(new_time);
- monotime_coarse_get(&now);
- timers_run_pending();
- tt_int_op(tried_to_write_cell, OP_EQ, 1);
- tt_assert(!client_relay3->pending_padding_callback);
-
- // Then test disabling each via consensus param
- smartlist_add(current_md_consensus->net_params,
- (void*)"nf_pad_tor2web=0");
- channelpadding_new_consensus_params(current_md_consensus);
-
- // Before the client tries to pad, the relay will still pad:
- tried_to_write_cell = 0;
- monotime_coarse_add_msec(&relay3_client->next_padding_time, &now, 100);
- get_options_mutable()->ORPort_set = 1;
- get_options_mutable()->Tor2webMode = 0;
- decision = channelpadding_decide_to_pad_channel(relay3_client);
- tt_int_op(decision, OP_EQ, CHANNELPADDING_PADDING_SCHEDULED);
- tt_assert(relay3_client->pending_padding_callback);
-
- // Wait for the timer
- new_time += 101*NSEC_PER_MSEC;
- monotime_coarse_set_mock_time_nsec(new_time);
- monotime_set_mock_time_nsec(new_time);
- monotime_coarse_get(&now);
- timers_run_pending();
- tt_int_op(tried_to_write_cell, OP_EQ, 1);
- tt_assert(!client_relay3->pending_padding_callback);
-
- // Test client side (it should stop immediately, but send a negotiate)
- tried_to_write_cell = 0;
- tt_assert(relay3_client->padding_enabled);
- tt_assert(client_relay3->padding_enabled);
- get_options_mutable()->Tor2webMode = 1;
- /* For the relay to receive the negotiate: */
- get_options_mutable()->ORPort_set = 1;
- decision = channelpadding_decide_to_pad_channel(client_relay3);
- tt_int_op(decision, OP_EQ, CHANNELPADDING_WONTPAD);
- tt_int_op(tried_to_write_cell, OP_EQ, 1);
- tt_assert(!client_relay3->pending_padding_callback);
- tt_assert(!relay3_client->padding_enabled);
-
- // Test relay side (it should have gotten the negotiation to disable)
- get_options_mutable()->ORPort_set = 1;
- get_options_mutable()->Tor2webMode = 0;
- tt_int_op(channelpadding_decide_to_pad_channel(relay3_client), OP_EQ,
- CHANNELPADDING_WONTPAD);
- tt_assert(!relay3_client->padding_enabled);
-
- /* Repeat for SOS */
// First, test that padding works if either is enabled
smartlist_clear(current_md_consensus->net_params);
channelpadding_new_consensus_params(current_md_consensus);
@@ -1163,4 +1102,3 @@ struct testcase_t channelpadding_tests[] = {
TEST_CHANNELPADDING(channelpadding_timers, TT_FORK),
END_OF_TESTCASES
};
-
diff --git a/src/test/test_channeltls.c b/src/test/test_channeltls.c
index 94f1893cae..787a30a85d 100644
--- a/src/test/test_channeltls.c
+++ b/src/test/test_channeltls.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014-2017, The Tor Project, Inc. */
+/* Copyright (c) 2014-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
#include "orconfig.h"
@@ -6,20 +6,23 @@
#include <math.h>
#define TOR_CHANNEL_INTERNAL_
-#include "or.h"
-#include "address.h"
-#include "buffers.h"
-#include "channel.h"
-#include "channeltls.h"
-#include "connection_or.h"
-#include "config.h"
+#include "core/or/or.h"
+#include "lib/net/address.h"
+#include "lib/container/buffers.h"
+#include "core/or/channel.h"
+#include "core/or/channeltls.h"
+#include "core/mainloop/connection.h"
+#include "core/or/connection_or.h"
+#include "app/config/config.h"
/* For init/free stuff */
-#include "scheduler.h"
-#include "tortls.h"
+#include "core/or/scheduler.h"
+#include "lib/tls/tortls.h"
+
+#include "core/or/or_connection_st.h"
/* Test suite stuff */
-#include "test.h"
-#include "fakechans.h"
+#include "test/test.h"
+#include "test/fakechans.h"
/* The channeltls unit tests */
static void test_channeltls_create(void *arg);
@@ -334,4 +337,3 @@ struct testcase_t channeltls_tests[] = {
TT_FORK, NULL, NULL },
END_OF_TESTCASES
};
-
diff --git a/src/test/test_checkdir.c b/src/test/test_checkdir.c
index bf6a8376b3..652e308ed8 100644
--- a/src/test/test_checkdir.c
+++ b/src/test/test_checkdir.c
@@ -1,8 +1,8 @@
-/* Copyright (c) 2014-2017, The Tor Project, Inc. */
+/* Copyright (c) 2014-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
#include "orconfig.h"
-#include "or.h"
+#include "core/or/or.h"
#ifdef _WIN32
#include <direct.h>
@@ -10,9 +10,12 @@
#include <dirent.h>
#endif
-#include "config.h"
-#include "test.h"
-#include "util.h"
+#include "app/config/config.h"
+#include "test/test.h"
+
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
#ifdef _WIN32
#define mkdir(a,b) mkdir(a)
@@ -146,4 +149,3 @@ struct testcase_t checkdir_tests[] = {
CHECKDIR(perms, TT_FORK),
END_OF_TESTCASES
};
-
diff --git a/src/test/test_circuitbuild.c b/src/test/test_circuitbuild.c
index a5282df69d..02eadecd98 100644
--- a/src/test/test_circuitbuild.c
+++ b/src/test/test_circuitbuild.c
@@ -1,16 +1,19 @@
/* Copyright (c) 2001-2004, Roger Dingledine.
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2016, The Tor Project, Inc. */
+ * Copyright (c) 2007-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
#define CIRCUITBUILD_PRIVATE
-#include "or.h"
-#include "test.h"
-#include "test_helpers.h"
-#include "log_test_helpers.h"
-#include "config.h"
-#include "circuitbuild.h"
+#include "core/or/or.h"
+#include "test/test.h"
+#include "test/test_helpers.h"
+#include "test/log_test_helpers.h"
+#include "app/config/config.h"
+#include "core/or/circuitbuild.h"
+#include "core/or/circuitlist.h"
+
+#include "core/or/extend_info_st.h"
/* Dummy nodes smartlist for testing */
static smartlist_t dummy_nodes;
@@ -130,4 +133,3 @@ struct testcase_t circuitbuild_tests[] = {
{ "unhandled_exit", test_new_route_len_unhandled_exit, 0, NULL, NULL },
END_OF_TESTCASES
};
-
diff --git a/src/test/test_circuitlist.c b/src/test/test_circuitlist.c
index d170009a9c..8dd7f5f5a9 100644
--- a/src/test/test_circuitlist.c
+++ b/src/test/test_circuitlist.c
@@ -1,17 +1,23 @@
-/* Copyright (c) 2013-2017, The Tor Project, Inc. */
+/* Copyright (c) 2013-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
#define TOR_CHANNEL_INTERNAL_
#define CIRCUITBUILD_PRIVATE
#define CIRCUITLIST_PRIVATE
#define HS_CIRCUITMAP_PRIVATE
-#include "or.h"
-#include "channel.h"
-#include "circuitbuild.h"
-#include "circuitlist.h"
-#include "hs_circuitmap.h"
-#include "test.h"
-#include "log_test_helpers.h"
+#include "core/or/or.h"
+#include "core/or/channel.h"
+#include "core/or/circuitbuild.h"
+#include "core/or/circuitlist.h"
+#include "core/or/circuitmux_ewma.h"
+#include "feature/hs/hs_circuitmap.h"
+#include "test/test.h"
+#include "test/log_test_helpers.h"
+
+#include "core/or/or_circuit_st.h"
+#include "core/or/origin_circuit_st.h"
+
+#include "lib/container/bitarray.h"
static channel_t *
new_fake_channel(void)
@@ -466,4 +472,3 @@ struct testcase_t circuitlist_tests[] = {
TT_FORK, NULL, NULL },
END_OF_TESTCASES
};
-
diff --git a/src/test/test_circuitmux.c b/src/test/test_circuitmux.c
index 854f725054..1be2ff5281 100644
--- a/src/test/test_circuitmux.c
+++ b/src/test/test_circuitmux.c
@@ -1,15 +1,21 @@
-/* Copyright (c) 2013-2017, The Tor Project, Inc. */
+/* Copyright (c) 2013-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
#define TOR_CHANNEL_INTERNAL_
#define CIRCUITMUX_PRIVATE
+#define CIRCUITMUX_EWMA_PRIVATE
#define RELAY_PRIVATE
-#include "or.h"
-#include "channel.h"
-#include "circuitmux.h"
-#include "relay.h"
-#include "scheduler.h"
-#include "test.h"
+#include "core/or/or.h"
+#include "core/or/channel.h"
+#include "core/or/circuitmux.h"
+#include "core/or/circuitmux_ewma.h"
+#include "core/or/relay.h"
+#include "core/or/scheduler.h"
+#include "test/test.h"
+
+#include "core/or/destroy_cell_queue_st.h"
+
+#include <math.h>
/* XXXX duplicated function from test_circuitlist.c */
static channel_t *
@@ -45,6 +51,7 @@ test_cmux_destroy_cell_queue(void *arg)
cmux = circuitmux_alloc();
tt_assert(cmux);
ch = new_fake_channel();
+ circuitmux_set_policy(cmux, &ewma_policy);
ch->has_queued_writes = has_queued_writes;
ch->wide_circ_ids = 1;
@@ -77,8 +84,50 @@ test_cmux_destroy_cell_queue(void *arg)
tor_free(dc);
}
+static void
+test_cmux_compute_ticks(void *arg)
+{
+ const int64_t NS_PER_S = 1000 * 1000 * 1000;
+ const int64_t START_NS = UINT64_C(1217709000)*NS_PER_S;
+ int64_t now;
+ double rem;
+ unsigned tick;
+ (void)arg;
+ circuitmux_ewma_free_all();
+ monotime_enable_test_mocking();
+
+ monotime_coarse_set_mock_time_nsec(START_NS);
+ cell_ewma_initialize_ticks();
+ const unsigned tick_zero = cell_ewma_get_current_tick_and_fraction(&rem);
+ tt_double_op(rem, OP_GT, -1e-9);
+ tt_double_op(rem, OP_LT, 1e-9);
+
+ /* 1.5 second later and we should still be in the same tick. */
+ now = START_NS + NS_PER_S + NS_PER_S/2;
+ monotime_coarse_set_mock_time_nsec(now);
+ tick = cell_ewma_get_current_tick_and_fraction(&rem);
+ tt_uint_op(tick, OP_EQ, tick_zero);
+#ifdef USING_32BIT_MSEC_HACK
+ const double tolerance = .0005;
+#else
+ const double tolerance = .00000001;
+#endif
+ tt_double_op(fabs(rem - .15), OP_LT, tolerance);
+
+ /* 25 second later and we should be in another tick. */
+ now = START_NS + NS_PER_S * 25;
+ monotime_coarse_set_mock_time_nsec(now);
+ tick = cell_ewma_get_current_tick_and_fraction(&rem);
+ tt_uint_op(tick, OP_EQ, tick_zero + 2);
+ tt_double_op(fabs(rem - .5), OP_LT, tolerance);
+
+ done:
+ ;
+}
+
struct testcase_t circuitmux_tests[] = {
{ "destroy_cell_queue", test_cmux_destroy_cell_queue, TT_FORK, NULL, NULL },
+ { "compute_ticks", test_cmux_compute_ticks, TT_FORK, NULL, NULL },
END_OF_TESTCASES
};
diff --git a/src/test/test_circuitstats.c b/src/test/test_circuitstats.c
index 8ebef659ca..c3cfad88da 100644
--- a/src/test/test_circuitstats.c
+++ b/src/test/test_circuitstats.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017, The Tor Project, Inc. */
+/* Copyright (c) 2017-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
#define CIRCUITBUILD_PRIVATE
@@ -6,16 +6,21 @@
#define CIRCUITLIST_PRIVATE
#define CHANNEL_PRIVATE_
-#include "or.h"
-#include "test.h"
-#include "test_helpers.h"
-#include "log_test_helpers.h"
-#include "config.h"
-#include "circuitlist.h"
-#include "circuitbuild.h"
-#include "circuitstats.h"
-#include "circuituse.h"
-#include "channel.h"
+#include "core/or/or.h"
+#include "test/test.h"
+#include "test/test_helpers.h"
+#include "test/log_test_helpers.h"
+#include "app/config/config.h"
+#include "core/or/circuitlist.h"
+#include "core/or/circuitbuild.h"
+#include "core/or/circuitstats.h"
+#include "core/or/circuituse.h"
+#include "core/or/channel.h"
+
+#include "core/or/cpath_build_state_st.h"
+#include "core/or/crypt_path_st.h"
+#include "core/or/extend_info_st.h"
+#include "core/or/origin_circuit_st.h"
void test_circuitstats_timeout(void *arg);
void test_circuitstats_hoplen(void *arg);
diff --git a/src/test/test_circuituse.c b/src/test/test_circuituse.c
index df1b43807f..720adeac84 100644
--- a/src/test/test_circuituse.c
+++ b/src/test/test_circuituse.c
@@ -1,18 +1,21 @@
/* Copyright (c) 2001-2004, Roger Dingledine.
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2017, The Tor Project, Inc. */
+ * Copyright (c) 2007-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
#define CIRCUITLIST_PRIVATE
-#include "or.h"
-#include "test.h"
-#include "test_helpers.h"
-#include "config.h"
-#include "circuitlist.h"
-#include "circuituse.h"
-#include "circuitbuild.h"
-#include "nodelist.h"
+#include "core/or/or.h"
+#include "test/test.h"
+#include "test/test_helpers.h"
+#include "app/config/config.h"
+#include "core/or/circuitlist.h"
+#include "core/or/circuituse.h"
+#include "core/or/circuitbuild.h"
+#include "feature/nodelist/nodelist.h"
+
+#include "core/or/cpath_build_state_st.h"
+#include "core/or/origin_circuit_st.h"
static void
test_circuit_is_available_for_use_ret_false_when_marked_for_close(void *arg)
diff --git a/src/test/test_compat_libevent.c b/src/test/test_compat_libevent.c
index 7dd8e65194..3f505d013b 100644
--- a/src/test/test_compat_libevent.c
+++ b/src/test/test_compat_libevent.c
@@ -1,18 +1,17 @@
-/* Copyright (c) 2010-2017, The Tor Project, Inc. */
+/* Copyright (c) 2010-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
#define COMPAT_LIBEVENT_PRIVATE
#include "orconfig.h"
-#include "or.h"
+#include "core/or/or.h"
-#include "test.h"
+#include "test/test.h"
-#include "compat_libevent.h"
+#include "lib/evloop/compat_libevent.h"
#include <event2/event.h>
-#include <event2/thread.h>
-#include "log_test_helpers.h"
+#include "test/log_test_helpers.h"
#define NS_MODULE compat_libevent
@@ -122,10 +121,70 @@ test_compat_libevent_header_version(void *ignored)
(void)0;
}
+/* Test for postloop events */
+
+/* Event callback to increment a counter. */
+static void
+increment_int_counter_cb(periodic_timer_t *timer, void *arg)
+{
+ (void)timer;
+ int *ctr = arg;
+ ++*ctr;
+}
+
+static int activated_counter = 0;
+
+/* Mainloop event callback to activate another mainloop event */
+static void
+activate_event_cb(mainloop_event_t *ev, void *arg)
+{
+ (void)ev;
+ mainloop_event_t **other_event = arg;
+ mainloop_event_activate(*other_event);
+ ++activated_counter;
+}
+
+static void
+test_compat_libevent_postloop_events(void *arg)
+{
+ (void)arg;
+ mainloop_event_t *a = NULL, *b = NULL;
+ periodic_timer_t *timed = NULL;
+
+ tor_libevent_postfork();
+
+ /* If postloop events don't work, then these events will activate one
+ * another ad infinitum and, and the periodic event will never occur. */
+ b = mainloop_event_postloop_new(activate_event_cb, &a);
+ a = mainloop_event_postloop_new(activate_event_cb, &b);
+
+ int counter = 0;
+ struct timeval fifty_ms = { 0, 10 * 1000 };
+ timed = periodic_timer_new(tor_libevent_get_base(), &fifty_ms,
+ increment_int_counter_cb, &counter);
+
+ mainloop_event_activate(a);
+ int r;
+ do {
+ r = tor_libevent_run_event_loop(tor_libevent_get_base(), 0);
+ if (r == -1)
+ break;
+ } while (counter < 5);
+
+ tt_int_op(activated_counter, OP_GE, 2);
+
+ done:
+ mainloop_event_free(a);
+ mainloop_event_free(b);
+ periodic_timer_free(timed);
+}
+
struct testcase_t compat_libevent_tests[] = {
{ "logging_callback", test_compat_libevent_logging_callback,
TT_FORK, NULL, NULL },
{ "header_version", test_compat_libevent_header_version, 0, NULL, NULL },
+ { "postloop_events", test_compat_libevent_postloop_events,
+ TT_FORK, NULL, NULL },
END_OF_TESTCASES
};
diff --git a/src/test/test_config.c b/src/test/test_config.c
index 2bcc0cad7b..dae4d83766 100644
--- a/src/test/test_config.c
+++ b/src/test/test_config.c
@@ -1,6 +1,6 @@
/* Copyright (c) 2001-2004, Roger Dingledine.
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2017, The Tor Project, Inc. */
+ * Copyright (c) 2007-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
#include "orconfig.h"
@@ -8,45 +8,59 @@
#define CONFIG_PRIVATE
#define PT_PRIVATE
#define ROUTERSET_PRIVATE
-#include "or.h"
-#include "address.h"
-#include "addressmap.h"
-#include "bridges.h"
-#include "circuitmux_ewma.h"
-#include "circuitbuild.h"
-#include "config.h"
-#include "confparse.h"
-#include "connection.h"
-#include "connection_edge.h"
-#include "test.h"
-#include "util.h"
-#include "address.h"
-#include "connection_or.h"
-#include "control.h"
-#include "cpuworker.h"
-#include "dirserv.h"
-#include "dirvote.h"
-#include "dns.h"
-#include "entrynodes.h"
-#include "transports.h"
-#include "ext_orport.h"
-#include "geoip.h"
-#include "hibernate.h"
-#include "main.h"
-#include "networkstatus.h"
-#include "nodelist.h"
-#include "policies.h"
-#include "rendclient.h"
-#include "rendservice.h"
-#include "router.h"
-#include "routerlist.h"
-#include "routerset.h"
-#include "statefile.h"
-#include "test.h"
-#include "transports.h"
-#include "util.h"
-
-#include "test_helpers.h"
+#include "core/or/or.h"
+#include "lib/net/address.h"
+#include "lib/net/resolve.h"
+#include "feature/client/addressmap.h"
+#include "feature/client/bridges.h"
+#include "core/or/circuitmux_ewma.h"
+#include "core/or/circuitbuild.h"
+#include "app/config/config.h"
+#include "app/config/confparse.h"
+#include "core/mainloop/connection.h"
+#include "core/or/connection_edge.h"
+#include "test/test.h"
+#include "core/or/connection_or.h"
+#include "feature/control/control.h"
+#include "core/mainloop/cpuworker.h"
+#include "feature/dircache/dirserv.h"
+#include "feature/dirauth/dirvote.h"
+#include "feature/relay/dns.h"
+#include "feature/client/entrynodes.h"
+#include "feature/client/transports.h"
+#include "feature/relay/ext_orport.h"
+#include "lib/geoip/geoip.h"
+#include "feature/hibernate/hibernate.h"
+#include "core/mainloop/mainloop.h"
+#include "feature/nodelist/networkstatus.h"
+#include "feature/nodelist/nodelist.h"
+#include "core/or/policies.h"
+#include "feature/rend/rendclient.h"
+#include "feature/rend/rendservice.h"
+#include "feature/relay/router.h"
+#include "feature/relay/routermode.h"
+#include "feature/nodelist/dirlist.h"
+#include "feature/nodelist/routerlist.h"
+#include "feature/nodelist/routerset.h"
+#include "app/config/statefile.h"
+
+#include "test/test_helpers.h"
+
+#include "feature/dirclient/dir_server_st.h"
+#include "core/or/port_cfg_st.h"
+#include "feature/nodelist/routerinfo_st.h"
+
+#include "lib/fs/conffile.h"
+#include "lib/meminfo/meminfo.h"
+#include "lib/net/gethostname.h"
+#include "lib/encoding/confline.h"
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
static void
test_config_addressmap(void *arg)
@@ -1623,6 +1637,40 @@ test_config_parsing_trusted_dir_server(void *arg)
#undef TEST_DIR_AUTH_LINE_END
#undef TEST_DIR_AUTH_IPV6_FLAG
+#define TEST_DIR_AUTH_LINE_START \
+ "foobar orport=12345 " \
+ "v3ident=14C131DFC5C6F93646BE72FA1401C02A8DF2E8B4 "
+#define TEST_DIR_AUTH_LINE_END_BAD_IP \
+ "0.256.3.4:54321 " \
+ "FDB2 FBD2 AAA5 25FA 2999 E617 5091 5A32 C777 3B17"
+#define TEST_DIR_AUTH_LINE_END_WITH_DNS_ADDR \
+ "torproject.org:54321 " \
+ "FDB2 FBD2 AAA5 25FA 2999 E617 5091 5A32 C777 3B17"
+
+static void
+test_config_parsing_invalid_dir_address(void *arg)
+{
+ (void)arg;
+ int rv;
+
+ rv = parse_dir_authority_line(TEST_DIR_AUTH_LINE_START
+ TEST_DIR_AUTH_LINE_END_BAD_IP,
+ V3_DIRINFO, 1);
+ tt_int_op(rv, OP_EQ, -1);
+
+ rv = parse_dir_authority_line(TEST_DIR_AUTH_LINE_START
+ TEST_DIR_AUTH_LINE_END_WITH_DNS_ADDR,
+ V3_DIRINFO, 1);
+ tt_int_op(rv, OP_EQ, -1);
+
+ done:
+ return;
+}
+
+#undef TEST_DIR_AUTH_LINE_START
+#undef TEST_DIR_AUTH_LINE_END_BAD_IP
+#undef TEST_DIR_AUTH_LINE_END_WITH_DNS_ADDR
+
/* No secrets here:
* id is `echo "syn-propanethial-S-oxide" | shasum | cut -d" " -f1`
*/
@@ -3728,7 +3776,7 @@ static void
test_config_default_fallback_dirs(void *arg)
{
const char *fallback[] = {
-#include "../or/fallback_dirs.inc"
+#include "app/config/fallback_dirs.inc"
NULL
};
@@ -4591,6 +4639,20 @@ test_config_parse_port_config__ports__ports_given(void *data)
tor_addr_parse(&addr, "127.0.0.46");
tt_assert(tor_addr_eq(&port_cfg->addr, &addr))
+ // Test success with a port of auto in mixed case
+ config_free_lines(config_port_valid); config_port_valid = NULL;
+ SMARTLIST_FOREACH(slout,port_cfg_t *,pf,port_cfg_free(pf));
+ smartlist_clear(slout);
+ config_port_valid = mock_config_line("DNSPort", "AuTo");
+ ret = parse_port_config(slout, config_port_valid, "DNS", 0,
+ "127.0.0.46", 0, 0);
+ tt_int_op(ret, OP_EQ, 0);
+ tt_int_op(smartlist_len(slout), OP_EQ, 1);
+ port_cfg = (port_cfg_t *)smartlist_get(slout, 0);
+ tt_int_op(port_cfg->port, OP_EQ, CFG_AUTO_PORT);
+ tor_addr_parse(&addr, "127.0.0.46");
+ tt_assert(tor_addr_eq(&port_cfg->addr, &addr))
+
// Test success with parsing both an address and an auto port
config_free_lines(config_port_valid); config_port_valid = NULL;
SMARTLIST_FOREACH(slout,port_cfg_t *,pf,port_cfg_free(pf));
@@ -5620,8 +5682,8 @@ test_config_include_opened_file_list(void *data)
static void
test_config_compute_max_mem_in_queues(void *data)
{
-#define GIGABYTE(x) (U64_LITERAL(x) << 30)
-#define MEGABYTE(x) (U64_LITERAL(x) << 20)
+#define GIGABYTE(x) (UINT64_C(x) << 30)
+#define MEGABYTE(x) (UINT64_C(x) << 20)
(void)data;
MOCK(get_total_system_memory, get_total_system_memory_mock);
@@ -5685,6 +5747,72 @@ test_config_compute_max_mem_in_queues(void *data)
#undef MEGABYTE
}
+static void
+test_config_extended_fmt(void *arg)
+{
+ (void)arg;
+ config_line_t *lines = NULL, *lp;
+ const char string1[] =
+ "thing1 is here\n"
+ "+thing2 is over here\n"
+ "/thing3\n"
+ "/thing4 is back here\n";
+
+ /* Try with the "extended" flag disabled. */
+ int r = config_get_lines(string1, &lines, 0);
+ tt_int_op(r, OP_EQ, 0);
+ lp = lines;
+ tt_ptr_op(lp, OP_NE, NULL);
+ tt_str_op(lp->key, OP_EQ, "thing1");
+ tt_str_op(lp->value, OP_EQ, "is here");
+ tt_int_op(lp->command, OP_EQ, CONFIG_LINE_NORMAL);
+ lp = lp->next;
+ tt_ptr_op(lp, OP_NE, NULL);
+ tt_str_op(lp->key, OP_EQ, "+thing2");
+ tt_str_op(lp->value, OP_EQ, "is over here");
+ tt_int_op(lp->command, OP_EQ, CONFIG_LINE_NORMAL);
+ lp = lp->next;
+ tt_ptr_op(lp, OP_NE, NULL);
+ tt_str_op(lp->key, OP_EQ, "/thing3");
+ tt_str_op(lp->value, OP_EQ, "");
+ tt_int_op(lp->command, OP_EQ, CONFIG_LINE_NORMAL);
+ lp = lp->next;
+ tt_ptr_op(lp, OP_NE, NULL);
+ tt_str_op(lp->key, OP_EQ, "/thing4");
+ tt_str_op(lp->value, OP_EQ, "is back here");
+ tt_int_op(lp->command, OP_EQ, CONFIG_LINE_NORMAL);
+ lp = lp->next;
+ config_free_lines(lines);
+
+ /* Try with the "extended" flag enabled. */
+ r = config_get_lines(string1, &lines, 1);
+ tt_int_op(r, OP_EQ, 0);
+ lp = lines;
+ tt_ptr_op(lp, OP_NE, NULL);
+ tt_str_op(lp->key, OP_EQ, "thing1");
+ tt_str_op(lp->value, OP_EQ, "is here");
+ tt_int_op(lp->command, OP_EQ, CONFIG_LINE_NORMAL);
+ lp = lp->next;
+ tt_ptr_op(lp, OP_NE, NULL);
+ tt_str_op(lp->key, OP_EQ, "thing2");
+ tt_str_op(lp->value, OP_EQ, "is over here");
+ tt_int_op(lp->command, OP_EQ, CONFIG_LINE_APPEND);
+ lp = lp->next;
+ tt_ptr_op(lp, OP_NE, NULL);
+ tt_str_op(lp->key, OP_EQ, "thing3");
+ tt_str_op(lp->value, OP_EQ, "");
+ tt_int_op(lp->command, OP_EQ, CONFIG_LINE_CLEAR);
+ lp = lp->next;
+ tt_ptr_op(lp, OP_NE, NULL);
+ tt_str_op(lp->key, OP_EQ, "thing4");
+ tt_str_op(lp->value, OP_EQ, "");
+ tt_int_op(lp->command, OP_EQ, CONFIG_LINE_CLEAR);
+ lp = lp->next;
+
+ done:
+ config_free_lines(lines);
+}
+
#define CONFIG_TEST(name, flags) \
{ #name, test_config_ ## name, flags, NULL, NULL }
@@ -5692,6 +5820,7 @@ struct testcase_t config_tests[] = {
CONFIG_TEST(adding_trusted_dir_server, TT_FORK),
CONFIG_TEST(adding_fallback_dir_server, TT_FORK),
CONFIG_TEST(parsing_trusted_dir_server, 0),
+ CONFIG_TEST(parsing_invalid_dir_address, 0),
CONFIG_TEST(parsing_fallback_dir_server, 0),
CONFIG_TEST(adding_default_trusted_dir_servers, TT_FORK),
CONFIG_TEST(adding_dir_servers, TT_FORK),
@@ -5734,6 +5863,6 @@ struct testcase_t config_tests[] = {
CONFIG_TEST(check_bridge_distribution_setting_unrecognised, 0),
CONFIG_TEST(include_opened_file_list, 0),
CONFIG_TEST(compute_max_mem_in_queues, 0),
+ CONFIG_TEST(extended_fmt, 0),
END_OF_TESTCASES
};
-
diff --git a/src/test/test_connection.c b/src/test/test_connection.c
index dc0f6860d9..0013f47fbc 100644
--- a/src/test/test_connection.c
+++ b/src/test/test_connection.c
@@ -1,27 +1,36 @@
-/* Copyright (c) 2015-2017, The Tor Project, Inc. */
+/* Copyright (c) 2015-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
#include "orconfig.h"
#define CONNECTION_PRIVATE
-#define MAIN_PRIVATE
+#define MAINLOOP_PRIVATE
#define CONNECTION_OR_PRIVATE
-#include "or.h"
-#include "test.h"
-
-#include "connection.h"
-#include "hs_common.h"
-#include "main.h"
-#include "microdesc.h"
-#include "nodelist.h"
-#include "networkstatus.h"
-#include "rendcache.h"
-#include "directory.h"
-#include "connection_or.h"
-
-#include "test_connection.h"
-#include "test_helpers.h"
+#include "core/or/or.h"
+#include "test/test.h"
+
+#include "core/mainloop/connection.h"
+#include "core/or/connection_edge.h"
+#include "feature/hs/hs_common.h"
+#include "core/mainloop/mainloop.h"
+#include "feature/nodelist/microdesc.h"
+#include "feature/nodelist/nodelist.h"
+#include "feature/nodelist/networkstatus.h"
+#include "feature/rend/rendcache.h"
+#include "feature/dircommon/directory.h"
+#include "core/or/connection_or.h"
+#include "lib/net/resolve.h"
+
+#include "test/test_connection.h"
+#include "test/test_helpers.h"
+
+#include "feature/dircommon/dir_connection_st.h"
+#include "core/or/entry_connection_st.h"
+#include "feature/nodelist/node_st.h"
+#include "core/or/or_connection_st.h"
+#include "feature/nodelist/routerinfo_st.h"
+#include "core/or/socks_request_st.h"
static void * test_conn_get_basic_setup(const struct testcase_t *tc);
static int test_conn_get_basic_teardown(const struct testcase_t *tc,
@@ -891,4 +900,3 @@ struct testcase_t connection_tests[] = {
{ "failed_orconn_tracker", test_failed_orconn_tracker, TT_FORK, NULL, NULL },
END_OF_TESTCASES
};
-
diff --git a/src/test/test_connection.h b/src/test/test_connection.h
index 392783b53b..27c296504a 100644
--- a/src/test/test_connection.h
+++ b/src/test/test_connection.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014-2017, The Tor Project, Inc. */
+/* Copyright (c) 2014-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
/** Some constants used by test_connection and helpers */
diff --git a/src/test/test_conscache.c b/src/test/test_conscache.c
index ffec3149b0..b5cbd72515 100644
--- a/src/test/test_conscache.c
+++ b/src/test/test_conscache.c
@@ -1,10 +1,11 @@
-/* Copyright (c) 2017, The Tor Project, Inc. */
+/* Copyright (c) 2017-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
-#include "or.h"
-#include "config.h"
-#include "conscache.h"
-#include "test.h"
+#include "core/or/or.h"
+#include "app/config/config.h"
+#include "feature/dircache/conscache.h"
+#include "lib/encoding/confline.h"
+#include "test/test.h"
#ifdef HAVE_UTIME_H
#include <utime.h>
@@ -337,4 +338,3 @@ struct testcase_t conscache_tests[] = {
ENT(filter),
END_OF_TESTCASES
};
-
diff --git a/src/test/test_consdiff.c b/src/test/test_consdiff.c
index fda3a7f186..b836befd22 100644
--- a/src/test/test_consdiff.c
+++ b/src/test/test_consdiff.c
@@ -1,15 +1,15 @@
/* Copyright (c) 2014, Daniel Martí
- * Copyright (c) 2014, The Tor Project, Inc. */
+ * Copyright (c) 2014-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
#define CONSDIFF_PRIVATE
-#include "or.h"
-#include "test.h"
+#include "core/or/or.h"
+#include "test/test.h"
-#include "consdiff.h"
-#include "memarea.h"
-#include "log_test_helpers.h"
+#include "feature/dircommon/consdiff.h"
+#include "lib/memarea/memarea.h"
+#include "test/log_test_helpers.h"
#define tt_str_eq_line(a,b) \
tt_assert(line_str_eq((b),(a)))
diff --git a/src/test/test_consdiffmgr.c b/src/test/test_consdiffmgr.c
index a9a4b6a98e..6c451da685 100644
--- a/src/test/test_consdiffmgr.c
+++ b/src/test/test_consdiffmgr.c
@@ -1,20 +1,25 @@
-/* Copyright (c) 2017, The Tor Project, Inc. */
+/* Copyright (c) 2017-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
#define CONSDIFFMGR_PRIVATE
-#include "or.h"
-#include "config.h"
-#include "conscache.h"
-#include "consdiff.h"
-#include "consdiffmgr.h"
-#include "cpuworker.h"
-#include "networkstatus.h"
-#include "routerparse.h"
-#include "workqueue.h"
+#include "core/or/or.h"
+#include "app/config/config.h"
+#include "feature/dircache/conscache.h"
+#include "feature/dircommon/consdiff.h"
+#include "feature/dircache/consdiffmgr.h"
+#include "core/mainloop/cpuworker.h"
+#include "lib/crypt_ops/crypto_rand.h"
+#include "feature/nodelist/networkstatus.h"
+#include "feature/dirparse/ns_parse.h"
+#include "lib/evloop/workqueue.h"
+#include "lib/compress/compress.h"
+#include "lib/encoding/confline.h"
-#include "test.h"
-#include "log_test_helpers.h"
+#include "feature/nodelist/networkstatus_st.h"
+
+#include "test/test.h"
+#include "test/log_test_helpers.h"
// ============================== Setup/teardown the consdiffmgr
// These functions get run before/after each test in this module
@@ -893,4 +898,3 @@ struct testcase_t consdiffmgr_tests[] = {
END_OF_TESTCASES
};
-
diff --git a/src/test/test_containers.c b/src/test/test_containers.c
index c4dba73750..717eb0892a 100644
--- a/src/test/test_containers.c
+++ b/src/test/test_containers.c
@@ -1,12 +1,17 @@
/* Copyright (c) 2001-2004, Roger Dingledine.
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2017, The Tor Project, Inc. */
+ * Copyright (c) 2007-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
#include "orconfig.h"
-#include "or.h"
-#include "fp_pair.h"
-#include "test.h"
+#include "core/or/or.h"
+#include "lib/crypt_ops/crypto_rand.h"
+#include "feature/dircommon/fp_pair.h"
+#include "test/test.h"
+
+#include "lib/container/bitarray.h"
+#include "lib/container/order.h"
+#include "lib/crypt_ops/digestset.h"
/** Helper: return a tristate based on comparing the strings in *<b>a</b> and
* *<b>b</b>. */
@@ -639,18 +644,18 @@ test_container_digestset(void *arg)
}
set = digestset_new(1000);
SMARTLIST_FOREACH(included, const char *, cp,
- if (digestset_contains(set, cp))
+ if (digestset_probably_contains(set, cp))
ok = 0);
tt_assert(ok);
SMARTLIST_FOREACH(included, const char *, cp,
digestset_add(set, cp));
SMARTLIST_FOREACH(included, const char *, cp,
- if (!digestset_contains(set, cp))
+ if (!digestset_probably_contains(set, cp))
ok = 0);
tt_assert(ok);
for (i = 0; i < 1000; ++i) {
crypto_rand(d, DIGEST_LEN);
- if (digestset_contains(set, d))
+ if (digestset_probably_contains(set, d))
++false_positives;
}
tt_int_op(50, OP_GT, false_positives); /* Should be far lower. */
@@ -1294,4 +1299,3 @@ struct testcase_t container_tests[] = {
CONTAINER(smartlist_strings_eq, 0),
END_OF_TESTCASES
};
-
diff --git a/src/test/test_controller.c b/src/test/test_controller.c
index 1c285bb3a2..4f5a9f58d5 100644
--- a/src/test/test_controller.c
+++ b/src/test/test_controller.c
@@ -1,17 +1,25 @@
-/* Copyright (c) 2015-2017, The Tor Project, Inc. */
+/* Copyright (c) 2015-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
#define CONTROL_PRIVATE
-#include "or.h"
-#include "bridges.h"
-#include "control.h"
-#include "entrynodes.h"
-#include "hs_common.h"
-#include "networkstatus.h"
-#include "rendservice.h"
-#include "routerlist.h"
-#include "test.h"
-#include "test_helpers.h"
+#include "core/or/or.h"
+#include "lib/crypt_ops/crypto_ed25519.h"
+#include "feature/client/bridges.h"
+#include "feature/control/control.h"
+#include "feature/client/entrynodes.h"
+#include "feature/hs/hs_common.h"
+#include "feature/nodelist/networkstatus.h"
+#include "feature/rend/rendservice.h"
+#include "feature/nodelist/authcert.h"
+#include "feature/nodelist/nodelist.h"
+#include "test/test.h"
+#include "test/test_helpers.h"
+#include "lib/net/resolve.h"
+
+#include "feature/control/control_connection_st.h"
+#include "feature/dirclient/download_status_st.h"
+#include "feature/nodelist/microdesc_st.h"
+#include "feature/nodelist/node_st.h"
static void
test_add_onion_helper_keyarg_v3(void *arg)
@@ -153,7 +161,7 @@ test_add_onion_helper_keyarg_v2(void *arg)
/* Test loading a RSA1024 key. */
tor_free(err_msg);
pk1 = pk_generate(0);
- tt_int_op(0, OP_EQ, crypto_pk_base64_encode(pk1, &encoded));
+ tt_int_op(0, OP_EQ, crypto_pk_base64_encode_private(pk1, &encoded));
tor_asprintf(&arg_str, "RSA1024:%s", encoded);
ret = add_onion_helper_keyarg(arg_str, 0, &key_new_alg, &key_new_blob,
&pk, &hs_version, &err_msg);
@@ -338,6 +346,13 @@ test_rend_service_parse_port_config(void *arg)
"in hidden service port configuration.");
tor_free(err_msg);
+ /* Wrong target address and port separation */
+ cfg = rend_service_parse_port_config("80,127.0.0.1 1234", sep,
+ &err_msg);
+ tt_ptr_op(cfg, OP_EQ, NULL);
+ tt_assert(err_msg);
+ tor_free(err_msg);
+
done:
rend_service_port_config_free(cfg);
tor_free(err_msg);
@@ -1470,6 +1485,135 @@ test_download_status_bridge(void *arg)
return;
}
+/** Set timeval to a mock date and time. This is necessary
+ * to make tor_gettimeofday() mockable. */
+static void
+mock_tor_gettimeofday(struct timeval *timeval)
+{
+ timeval->tv_sec = 1523405073;
+ timeval->tv_usec = 271645;
+}
+
+static void
+test_current_time(void *arg)
+{
+ /* We just need one of these to pass, it doesn't matter what's in it */
+ control_connection_t dummy;
+ /* Get results out */
+ char *answer = NULL;
+ const char *errmsg = NULL;
+
+ (void)arg;
+
+ /* We need these for storing the (mock) time. */
+ MOCK(tor_gettimeofday, mock_tor_gettimeofday);
+ struct timeval now;
+ tor_gettimeofday(&now);
+ char timebuf[ISO_TIME_LEN+1];
+
+ /* Case 1 - local time */
+ format_local_iso_time_nospace(timebuf, (time_t)now.tv_sec);
+ getinfo_helper_current_time(&dummy,
+ "current-time/local",
+ &answer, &errmsg);
+ tt_ptr_op(answer, OP_NE, NULL);
+ tt_ptr_op(errmsg, OP_EQ, NULL);
+ tt_str_op(answer, OP_EQ, timebuf);
+ tor_free(answer);
+ errmsg = NULL;
+
+ /* Case 2 - UTC time */
+ format_iso_time_nospace(timebuf, (time_t)now.tv_sec);
+ getinfo_helper_current_time(&dummy,
+ "current-time/utc",
+ &answer, &errmsg);
+ tt_ptr_op(answer, OP_NE, NULL);
+ tt_ptr_op(errmsg, OP_EQ, NULL);
+ tt_str_op(answer, OP_EQ, timebuf);
+ tor_free(answer);
+ errmsg = NULL;
+
+ done:
+ UNMOCK(tor_gettimeofday);
+ tor_free(answer);
+
+ return;
+}
+
+static size_t n_nodelist_get_list = 0;
+static smartlist_t *nodes = NULL;
+
+static smartlist_t *
+mock_nodelist_get_list(void)
+{
+ n_nodelist_get_list++;
+ tor_assert(nodes);
+
+ return nodes;
+}
+
+static void
+test_getinfo_md_all(void *arg)
+{
+ char *answer = NULL;
+ const char *errmsg = NULL;
+ int retval = 0;
+
+ (void)arg;
+
+ node_t *node1 = tor_malloc(sizeof(node_t));
+ memset(node1, 0, sizeof(node_t));
+ node1->md = tor_malloc(sizeof(microdesc_t));
+ memset(node1->md, 0, sizeof(microdesc_t));
+ node1->md->body = tor_strdup("md1\n");
+ node1->md->bodylen = 4;
+
+ node_t *node2 = tor_malloc(sizeof(node_t));
+ memset(node2, 0, sizeof(node_t));
+ node2->md = tor_malloc(sizeof(microdesc_t));
+ memset(node2->md, 0, sizeof(microdesc_t));
+ node2->md->body = tor_strdup("md2\n");
+ node2->md->bodylen = 4;
+
+ MOCK(nodelist_get_list, mock_nodelist_get_list);
+
+ nodes = smartlist_new();
+
+ retval = getinfo_helper_dir(NULL, "md/all", &answer, &errmsg);
+
+ tt_int_op(n_nodelist_get_list, OP_EQ, 1);
+ tt_int_op(retval, OP_EQ, 0);
+ tt_assert(answer != NULL);
+ tt_assert(errmsg == NULL);
+ tt_str_op(answer, OP_EQ, "");
+
+ tor_free(answer);
+
+ smartlist_add(nodes, node1);
+ smartlist_add(nodes, node2);
+
+ retval = getinfo_helper_dir(NULL, "md/all", &answer, &errmsg);
+
+ tt_int_op(n_nodelist_get_list, OP_EQ, 2);
+ tt_int_op(retval, OP_EQ, 0);
+ tt_assert(answer != NULL);
+ tt_assert(errmsg == NULL);
+
+ tt_str_op(answer, OP_EQ, "md1\nmd2\n");
+
+ done:
+ UNMOCK(nodelist_get_list);
+ tor_free(node1->md->body);
+ tor_free(node1->md);
+ tor_free(node1);
+ tor_free(node2->md->body);
+ tor_free(node2->md);
+ tor_free(node2);
+ tor_free(answer);
+ smartlist_free(nodes);
+ return;
+}
+
struct testcase_t controller_tests[] = {
{ "add_onion_helper_keyarg_v2", test_add_onion_helper_keyarg_v2, 0,
NULL, NULL },
@@ -1486,6 +1630,7 @@ struct testcase_t controller_tests[] = {
NULL },
{ "download_status_desc", test_download_status_desc, 0, NULL, NULL },
{ "download_status_bridge", test_download_status_bridge, 0, NULL, NULL },
+ { "current_time", test_current_time, 0, NULL, NULL },
+ { "getinfo_md_all", test_getinfo_md_all, 0, NULL, NULL },
END_OF_TESTCASES
};
-
diff --git a/src/test/test_controller_events.c b/src/test/test_controller_events.c
index 901ad7ab3d..4c404876b0 100644
--- a/src/test/test_controller_events.c
+++ b/src/test/test_controller_events.c
@@ -1,88 +1,19 @@
-/* Copyright (c) 2013-2017, The Tor Project, Inc. */
+/* Copyright (c) 2013-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
#define CONNECTION_PRIVATE
#define TOR_CHANNEL_INTERNAL_
#define CONTROL_PRIVATE
-#include "or.h"
-#include "channel.h"
-#include "channeltls.h"
-#include "connection.h"
-#include "control.h"
-#include "test.h"
+#include "core/or/or.h"
+#include "core/or/channel.h"
+#include "core/or/channeltls.h"
+#include "core/or/circuitlist.h"
+#include "core/mainloop/connection.h"
+#include "feature/control/control.h"
+#include "test/test.h"
-static void
-help_test_bucket_note_empty(uint32_t expected_msec_since_midnight,
- int tokens_before, size_t tokens_removed,
- uint32_t msec_since_epoch)
-{
- uint32_t timestamp_var = 0;
- struct timeval tvnow;
- tvnow.tv_sec = msec_since_epoch / 1000;
- tvnow.tv_usec = (msec_since_epoch % 1000) * 1000;
- connection_buckets_note_empty_ts(&timestamp_var, tokens_before,
- tokens_removed, &tvnow);
- tt_int_op(expected_msec_since_midnight, OP_EQ, timestamp_var);
-
- done:
- ;
-}
-
-static void
-test_cntev_bucket_note_empty(void *arg)
-{
- (void)arg;
-
- /* Two cases with nothing to note, because bucket was empty before;
- * 86442200 == 1970-01-02 00:00:42.200000 */
- help_test_bucket_note_empty(0, 0, 0, 86442200);
- help_test_bucket_note_empty(0, -100, 100, 86442200);
-
- /* Nothing to note, because bucket has not been emptied. */
- help_test_bucket_note_empty(0, 101, 100, 86442200);
-
- /* Bucket was emptied, note 42200 msec since midnight. */
- help_test_bucket_note_empty(42200, 101, 101, 86442200);
- help_test_bucket_note_empty(42200, 101, 102, 86442200);
-}
-
-static void
-test_cntev_bucket_millis_empty(void *arg)
-{
- struct timeval tvnow;
- (void)arg;
-
- /* 1970-01-02 00:00:42.200000 */
- tvnow.tv_sec = 86400 + 42;
- tvnow.tv_usec = 200000;
-
- /* Bucket has not been refilled. */
- tt_int_op(0, OP_EQ, bucket_millis_empty(0, 42120, 0, 100, &tvnow));
- tt_int_op(0, OP_EQ, bucket_millis_empty(-10, 42120, -10, 100, &tvnow));
-
- /* Bucket was not empty. */
- tt_int_op(0, OP_EQ, bucket_millis_empty(10, 42120, 20, 100, &tvnow));
-
- /* Bucket has been emptied 80 msec ago and has just been refilled. */
- tt_int_op(80, OP_EQ, bucket_millis_empty(-20, 42120, -10, 100, &tvnow));
- tt_int_op(80, OP_EQ, bucket_millis_empty(-10, 42120, 0, 100, &tvnow));
- tt_int_op(80, OP_EQ, bucket_millis_empty(0, 42120, 10, 100, &tvnow));
-
- /* Bucket has been emptied 180 msec ago, last refill was 100 msec ago
- * which was insufficient to make it positive, so cap msec at 100. */
- tt_int_op(100, OP_EQ, bucket_millis_empty(0, 42020, 1, 100, &tvnow));
-
- /* 1970-01-02 00:00:00:050000 */
- tvnow.tv_sec = 86400;
- tvnow.tv_usec = 50000;
-
- /* Last emptied 30 msec before midnight, tvnow is 50 msec after
- * midnight, that's 80 msec in total. */
- tt_int_op(80, OP_EQ, bucket_millis_empty(0, 86400000 - 30, 1, 100, &tvnow));
-
- done:
- ;
-}
+#include "core/or/or_circuit_st.h"
+#include "core/or/origin_circuit_st.h"
static void
add_testing_cell_stats_entry(circuit_t *circ, uint8_t command,
@@ -391,16 +322,81 @@ test_cntev_event_mask(void *arg)
;
}
+static char *saved_event_str = NULL;
+
+static void
+mock_queue_control_event_string(uint16_t event, char *msg)
+{
+ (void)event;
+
+ tor_free(saved_event_str);
+ saved_event_str = msg;
+}
+
+/* Helper macro for checking bootstrap control event strings */
+#define assert_bootmsg(s) \
+ tt_ptr_op(strstr(saved_event_str, "650 STATUS_CLIENT NOTICE " \
+ "BOOTSTRAP PROGRESS=" s), OP_EQ, saved_event_str)
+
+/* Test deferral of directory bootstrap messages (requesting_descriptors) */
+static void
+test_cntev_dirboot_defer_desc(void *arg)
+{
+ (void)arg;
+
+ MOCK(queue_control_event_string, mock_queue_control_event_string);
+ control_testing_set_global_event_mask(EVENT_MASK_(EVENT_STATUS_CLIENT));
+ control_event_bootstrap(BOOTSTRAP_STATUS_STARTING, 0);
+ assert_bootmsg("0 TAG=starting");
+ /* This event should get deferred */
+ control_event_boot_dir(BOOTSTRAP_STATUS_REQUESTING_DESCRIPTORS, 0);
+ assert_bootmsg("0 TAG=starting");
+ control_event_bootstrap(BOOTSTRAP_STATUS_CONN_DIR, 0);
+ assert_bootmsg("5 TAG=conn_dir");
+ control_event_bootstrap(BOOTSTRAP_STATUS_HANDSHAKE, 0);
+ assert_bootmsg("10 TAG=handshake_dir");
+ /* The deferred event should appear */
+ control_event_boot_first_orconn();
+ assert_bootmsg("45 TAG=requesting_descriptors");
+ done:
+ tor_free(saved_event_str);
+ UNMOCK(queue_control_event_string);
+}
+
+/* Test deferral of directory bootstrap messages (conn_or) */
+static void
+test_cntev_dirboot_defer_orconn(void *arg)
+{
+ (void)arg;
+
+ MOCK(queue_control_event_string, mock_queue_control_event_string);
+ control_testing_set_global_event_mask(EVENT_MASK_(EVENT_STATUS_CLIENT));
+ control_event_bootstrap(BOOTSTRAP_STATUS_STARTING, 0);
+ assert_bootmsg("0 TAG=starting");
+ /* This event should get deferred */
+ control_event_boot_dir(BOOTSTRAP_STATUS_CONN_OR, 0);
+ assert_bootmsg("0 TAG=starting");
+ control_event_bootstrap(BOOTSTRAP_STATUS_CONN_DIR, 0);
+ assert_bootmsg("5 TAG=conn_dir");
+ control_event_bootstrap(BOOTSTRAP_STATUS_HANDSHAKE, 0);
+ assert_bootmsg("10 TAG=handshake_dir");
+ /* The deferred event should appear */
+ control_event_boot_first_orconn();
+ assert_bootmsg("80 TAG=conn_or");
+ done:
+ tor_free(saved_event_str);
+ UNMOCK(queue_control_event_string);
+}
+
#define TEST(name, flags) \
{ #name, test_cntev_ ## name, flags, 0, NULL }
struct testcase_t controller_event_tests[] = {
- TEST(bucket_note_empty, TT_FORK),
- TEST(bucket_millis_empty, TT_FORK),
TEST(sum_up_cell_stats, TT_FORK),
TEST(append_cell_stats, TT_FORK),
TEST(format_cell_stats, TT_FORK),
TEST(event_mask, TT_FORK),
+ TEST(dirboot_defer_desc, TT_FORK),
+ TEST(dirboot_defer_orconn, TT_FORK),
END_OF_TESTCASES
};
-
diff --git a/src/test/test_crypto.c b/src/test/test_crypto.c
index 83d97f2867..81d2fa6f33 100644
--- a/src/test/test_crypto.c
+++ b/src/test/test_crypto.c
@@ -1,19 +1,38 @@
/* Copyright (c) 2001-2004, Roger Dingledine.
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2017, The Tor Project, Inc. */
+ * Copyright (c) 2007-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
#include "orconfig.h"
#define CRYPTO_CURVE25519_PRIVATE
-#define CRYPTO_PRIVATE
-#include "or.h"
-#include "test.h"
-#include "aes.h"
-#include "util.h"
+#define CRYPTO_RAND_PRIVATE
+#include "core/or/or.h"
+#include "test/test.h"
+#include "lib/crypt_ops/aes.h"
#include "siphash.h"
-#include "crypto_curve25519.h"
-#include "crypto_ed25519.h"
+#include "lib/crypt_ops/crypto_curve25519.h"
+#include "lib/crypt_ops/crypto_dh.h"
+#include "lib/crypt_ops/crypto_ed25519.h"
+#include "lib/crypt_ops/crypto_format.h"
+#include "lib/crypt_ops/crypto_hkdf.h"
+#include "lib/crypt_ops/crypto_rand.h"
+#include "lib/crypt_ops/crypto_init.h"
#include "ed25519_vectors.inc"
+#include "test/log_test_helpers.h"
+
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#if defined(ENABLE_OPENSSL)
+#include "lib/crypt_ops/compat_openssl.h"
+DISABLE_GCC_WARNING(redundant-decls)
+#include <openssl/dh.h>
+ENABLE_GCC_WARNING(redundant-decls)
+#endif
/** Run unit tests for Diffie-Hellman functionality. */
static void
@@ -22,38 +41,45 @@ test_crypto_dh(void *arg)
crypto_dh_t *dh1 = crypto_dh_new(DH_TYPE_CIRCUIT);
crypto_dh_t *dh1_dup = NULL;
crypto_dh_t *dh2 = crypto_dh_new(DH_TYPE_CIRCUIT);
- char p1[DH_BYTES];
- char p2[DH_BYTES];
- char s1[DH_BYTES];
- char s2[DH_BYTES];
+ char p1[DH1024_KEY_LEN];
+ char p2[DH1024_KEY_LEN];
+ char s1[DH1024_KEY_LEN];
+ char s2[DH1024_KEY_LEN];
ssize_t s1len, s2len;
+#ifdef ENABLE_OPENSSL
+ crypto_dh_t *dh3 = NULL;
+ DH *dh4 = NULL;
+ BIGNUM *pubkey_tmp = NULL;
+#endif
(void)arg;
- tt_int_op(crypto_dh_get_bytes(dh1),OP_EQ, DH_BYTES);
- tt_int_op(crypto_dh_get_bytes(dh2),OP_EQ, DH_BYTES);
+ tt_int_op(crypto_dh_get_bytes(dh1),OP_EQ, DH1024_KEY_LEN);
+ tt_int_op(crypto_dh_get_bytes(dh2),OP_EQ, DH1024_KEY_LEN);
- memset(p1, 0, DH_BYTES);
- memset(p2, 0, DH_BYTES);
- tt_mem_op(p1,OP_EQ, p2, DH_BYTES);
+ memset(p1, 0, DH1024_KEY_LEN);
+ memset(p2, 0, DH1024_KEY_LEN);
+ tt_mem_op(p1,OP_EQ, p2, DH1024_KEY_LEN);
tt_int_op(-1, OP_EQ, crypto_dh_get_public(dh1, p1, 6)); /* too short */
- tt_assert(! crypto_dh_get_public(dh1, p1, DH_BYTES));
- tt_mem_op(p1,OP_NE, p2, DH_BYTES);
- tt_assert(! crypto_dh_get_public(dh2, p2, DH_BYTES));
- tt_mem_op(p1,OP_NE, p2, DH_BYTES);
+ tt_assert(! crypto_dh_get_public(dh1, p1, DH1024_KEY_LEN));
+ tt_mem_op(p1,OP_NE, p2, DH1024_KEY_LEN);
+ tt_assert(! crypto_dh_get_public(dh2, p2, DH1024_KEY_LEN));
+ tt_mem_op(p1,OP_NE, p2, DH1024_KEY_LEN);
- memset(s1, 0, DH_BYTES);
- memset(s2, 0xFF, DH_BYTES);
- s1len = crypto_dh_compute_secret(LOG_WARN, dh1, p2, DH_BYTES, s1, 50);
- s2len = crypto_dh_compute_secret(LOG_WARN, dh2, p1, DH_BYTES, s2, 50);
+ memset(s1, 0, DH1024_KEY_LEN);
+ memset(s2, 0xFF, DH1024_KEY_LEN);
+ s1len = crypto_dh_compute_secret(LOG_WARN, dh1, p2, DH1024_KEY_LEN, s1, 50);
+ s2len = crypto_dh_compute_secret(LOG_WARN, dh2, p1, DH1024_KEY_LEN, s2, 50);
tt_assert(s1len > 0);
tt_int_op(s1len,OP_EQ, s2len);
tt_mem_op(s1,OP_EQ, s2, s1len);
/* test dh_dup; make sure it works the same. */
dh1_dup = crypto_dh_dup(dh1);
- s1len = crypto_dh_compute_secret(LOG_WARN, dh1_dup, p2, DH_BYTES, s1, 50);
+ s1len = crypto_dh_compute_secret(LOG_WARN, dh1_dup, p2, DH1024_KEY_LEN,
+ s1, 50);
+ tt_i64_op(s1len, OP_GE, 0);
tt_mem_op(s1,OP_EQ, s2, s1len);
{
@@ -66,18 +92,24 @@ test_crypto_dh(void *arg)
s1len = crypto_dh_compute_secret(LOG_WARN, dh1, "\x00", 1, s1, 50);
tt_int_op(-1, OP_EQ, s1len);
- memset(p1, 0, DH_BYTES); /* 0 with padding. */
- s1len = crypto_dh_compute_secret(LOG_WARN, dh1, p1, DH_BYTES, s1, 50);
+ memset(p1, 0, DH1024_KEY_LEN); /* 0 with padding. */
+ s1len = crypto_dh_compute_secret(LOG_WARN, dh1, p1, DH1024_KEY_LEN,
+ s1, 50);
tt_int_op(-1, OP_EQ, s1len);
- p1[DH_BYTES-1] = 1; /* 1 with padding*/
- s1len = crypto_dh_compute_secret(LOG_WARN, dh1, p1, DH_BYTES, s1, 50);
+ p1[DH1024_KEY_LEN-1] = 1; /* 1 with padding*/
+ s1len = crypto_dh_compute_secret(LOG_WARN, dh1, p1, DH1024_KEY_LEN,
+ s1, 50);
tt_int_op(-1, OP_EQ, s1len);
/* 2 is okay, though weird. */
s1len = crypto_dh_compute_secret(LOG_WARN, dh1, "\x02", 1, s1, 50);
tt_int_op(50, OP_EQ, s1len);
+ /* 2 a second time is still okay, though weird. */
+ s1len = crypto_dh_compute_secret(LOG_WARN, dh1, "\x02", 1, s1, 50);
+ tt_int_op(50, OP_EQ, s1len);
+
const char P[] =
"FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E08"
"8A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B"
@@ -88,15 +120,18 @@ test_crypto_dh(void *arg)
/* p-1, p, and so on are not okay. */
base16_decode(p1, sizeof(p1), P, strlen(P));
- s1len = crypto_dh_compute_secret(LOG_WARN, dh1, p1, DH_BYTES, s1, 50);
+ s1len = crypto_dh_compute_secret(LOG_WARN, dh1, p1, DH1024_KEY_LEN,
+ s1, 50);
tt_int_op(-1, OP_EQ, s1len);
- p1[DH_BYTES-1] = 0xFE; /* p-1 */
- s1len = crypto_dh_compute_secret(LOG_WARN, dh1, p1, DH_BYTES, s1, 50);
+ p1[DH1024_KEY_LEN-1] = 0xFE; /* p-1 */
+ s1len = crypto_dh_compute_secret(LOG_WARN, dh1, p1, DH1024_KEY_LEN,
+ s1, 50);
tt_int_op(-1, OP_EQ, s1len);
- p1[DH_BYTES-1] = 0xFD; /* p-2 works fine */
- s1len = crypto_dh_compute_secret(LOG_WARN, dh1, p1, DH_BYTES, s1, 50);
+ p1[DH1024_KEY_LEN-1] = 0xFD; /* p-2 works fine */
+ s1len = crypto_dh_compute_secret(LOG_WARN, dh1, p1, DH1024_KEY_LEN,
+ s1, 50);
tt_int_op(50, OP_EQ, s1len);
const char P_plus_one[] =
@@ -108,51 +143,103 @@ test_crypto_dh(void *arg)
base16_decode(p1, sizeof(p1), P_plus_one, strlen(P_plus_one));
- s1len = crypto_dh_compute_secret(LOG_WARN, dh1, p1, DH_BYTES, s1, 50);
+ s1len = crypto_dh_compute_secret(LOG_WARN, dh1, p1, DH1024_KEY_LEN,
+ s1, 50);
tt_int_op(-1, OP_EQ, s1len);
- p1[DH_BYTES-1] = 0x01; /* p+2 */
- s1len = crypto_dh_compute_secret(LOG_WARN, dh1, p1, DH_BYTES, s1, 50);
+ p1[DH1024_KEY_LEN-1] = 0x01; /* p+2 */
+ s1len = crypto_dh_compute_secret(LOG_WARN, dh1, p1, DH1024_KEY_LEN,
+ s1, 50);
tt_int_op(-1, OP_EQ, s1len);
- p1[DH_BYTES-1] = 0xff; /* p+256 */
- s1len = crypto_dh_compute_secret(LOG_WARN, dh1, p1, DH_BYTES, s1, 50);
+ p1[DH1024_KEY_LEN-1] = 0xff; /* p+256 */
+ s1len = crypto_dh_compute_secret(LOG_WARN, dh1, p1, DH1024_KEY_LEN,
+ s1, 50);
tt_int_op(-1, OP_EQ, s1len);
- memset(p1, 0xff, DH_BYTES), /* 2^1024-1 */
- s1len = crypto_dh_compute_secret(LOG_WARN, dh1, p1, DH_BYTES, s1, 50);
+ memset(p1, 0xff, DH1024_KEY_LEN), /* 2^1024-1 */
+ s1len = crypto_dh_compute_secret(LOG_WARN, dh1, p1, DH1024_KEY_LEN,
+ s1, 50);
tt_int_op(-1, OP_EQ, s1len);
}
{
/* provoke an error in the openssl DH_compute_key function; make sure we
* survive. */
- tt_assert(! crypto_dh_get_public(dh1, p1, DH_BYTES));
+ tt_assert(! crypto_dh_get_public(dh1, p1, DH1024_KEY_LEN));
crypto_dh_free(dh2);
dh2= crypto_dh_new(DH_TYPE_CIRCUIT); /* no private key set */
s1len = crypto_dh_compute_secret(LOG_WARN, dh2,
- p1, DH_BYTES,
+ p1, DH1024_KEY_LEN,
s1, 50);
tt_int_op(s1len, OP_EQ, -1);
}
+#if defined(ENABLE_OPENSSL)
+ {
+ /* Make sure that our crypto library can handshake with openssl. */
+ dh3 = crypto_dh_new(DH_TYPE_TLS);
+ tt_assert(!crypto_dh_get_public(dh3, p1, DH1024_KEY_LEN));
+
+ dh4 = crypto_dh_new_openssl_tls();
+ tt_assert(DH_generate_key(dh4));
+ const BIGNUM *pk=NULL;
+#ifdef OPENSSL_1_1_API
+ const BIGNUM *sk=NULL;
+ DH_get0_key(dh4, &pk, &sk);
+#else
+ pk = dh4->pub_key;
+#endif
+ tt_assert(pk);
+ tt_int_op(BN_num_bytes(pk), OP_LE, DH1024_KEY_LEN);
+ tt_int_op(BN_num_bytes(pk), OP_GT, 0);
+ memset(p2, 0, sizeof(p2));
+ /* right-pad. */
+ BN_bn2bin(pk, (unsigned char *)(p2+DH1024_KEY_LEN-BN_num_bytes(pk)));
+
+ s1len = crypto_dh_handshake(LOG_WARN, dh3, p2, DH1024_KEY_LEN,
+ (unsigned char *)s1, sizeof(s1));
+ pubkey_tmp = BN_bin2bn((unsigned char *)p1, DH1024_KEY_LEN, NULL);
+ s2len = DH_compute_key((unsigned char *)s2, pubkey_tmp, dh4);
+
+ tt_int_op(s1len, OP_EQ, s2len);
+ tt_int_op(s1len, OP_GT, 0);
+ tt_mem_op(s1, OP_EQ, s2, s1len);
+ }
+#endif
+
done:
crypto_dh_free(dh1);
crypto_dh_free(dh2);
crypto_dh_free(dh1_dup);
+#ifdef ENABLE_OPENSSL
+ crypto_dh_free(dh3);
+ if (dh4)
+ DH_free(dh4);
+ if (pubkey_tmp)
+ BN_free(pubkey_tmp);
+#endif
}
static void
test_crypto_openssl_version(void *arg)
{
(void)arg;
+#ifdef ENABLE_NSS
+ tt_skip();
+#else
const char *version = crypto_openssl_get_version_str();
const char *h_version = crypto_openssl_get_header_version_str();
tt_assert(version);
tt_assert(h_version);
- tt_assert(!strcmpstart(version, h_version)); /* "-fips" suffix, etc */
- tt_assert(!strstr(version, "OpenSSL"));
+ if (strcmpstart(version, h_version)) { /* "-fips" suffix, etc */
+ TT_DIE(("OpenSSL library version %s did not begin with header version %s.",
+ version, h_version));
+ }
+ if (strstr(version, "OpenSSL")) {
+ TT_DIE(("assertion failed: !strstr(\"%s\", \"OpenSSL\")", version));
+ }
int a=-1,b=-1,c=-1;
if (!strcmpstart(version, "LibreSSL") || !strcmpstart(version, "BoringSSL"))
return;
@@ -161,6 +248,7 @@ test_crypto_openssl_version(void *arg)
tt_int_op(a, OP_GE, 0);
tt_int_op(b, OP_GE, 0);
tt_int_op(c, OP_GE, 0);
+#endif
done:
;
@@ -189,10 +277,10 @@ test_crypto_rng(void *arg)
j = crypto_rand_int(100);
if (j < 0 || j >= 100)
allok = 0;
- big = crypto_rand_uint64(U64_LITERAL(1)<<40);
- if (big >= (U64_LITERAL(1)<<40))
+ big = crypto_rand_uint64(UINT64_C(1)<<40);
+ if (big >= (UINT64_C(1)<<40))
allok = 0;
- big = crypto_rand_uint64(U64_LITERAL(5));
+ big = crypto_rand_uint64(UINT64_C(5));
if (big >= 5)
allok = 0;
d = crypto_rand_double();
@@ -1338,22 +1426,22 @@ test_crypto_pk_base64(void *arg)
/* Test Base64 encoding a key. */
pk1 = pk_generate(0);
tt_assert(pk1);
- tt_int_op(0, OP_EQ, crypto_pk_base64_encode(pk1, &encoded));
+ tt_int_op(0, OP_EQ, crypto_pk_base64_encode_private(pk1, &encoded));
tt_assert(encoded);
/* Test decoding a valid key. */
- pk2 = crypto_pk_base64_decode(encoded, strlen(encoded));
+ pk2 = crypto_pk_base64_decode_private(encoded, strlen(encoded));
tt_assert(pk2);
tt_int_op(crypto_pk_cmp_keys(pk1, pk2), OP_EQ, 0);
crypto_pk_free(pk2);
/* Test decoding a invalid key (not Base64). */
static const char *invalid_b64 = "The key is in another castle!";
- pk2 = crypto_pk_base64_decode(invalid_b64, strlen(invalid_b64));
+ pk2 = crypto_pk_base64_decode_private(invalid_b64, strlen(invalid_b64));
tt_ptr_op(pk2, OP_EQ, NULL);
/* Test decoding a truncated Base64 blob. */
- pk2 = crypto_pk_base64_decode(encoded, strlen(encoded)/2);
+ pk2 = crypto_pk_base64_decode_private(encoded, strlen(encoded)/2);
tt_ptr_op(pk2, OP_EQ, NULL);
done:
@@ -1402,6 +1490,58 @@ test_crypto_pk_pem_encrypted(void *arg)
done:
crypto_pk_free(pk);
}
+
+static void
+test_crypto_pk_invalid_private_key(void *arg)
+{
+ (void)arg;
+ /* Here is a simple invalid private key: it was produced by making
+ * a regular private key, and then adding 2 to the modulus. */
+ const char pem[] =
+ "-----BEGIN RSA PRIVATE KEY-----\n"
+ "MIIEpQIBAAKCAQEAskRyZrs+YAukvBmZlgo6/rCxyKF2xyUk073ap+2CgRUnSfGG\n"
+ "mflHlzqVq7tpH50DafpS+fFAbaEaNV/ac20QG0rUZi38HTB4qURWOu6n0Bws6E4l\n"
+ "UX/AkvDlWnuYH0pHHi2c3DGNFjwoJpjKuUTk+cRffVR8X3Kjr62SUDUaBNW0Kecz\n"
+ "3SYLbmgmZI16dFZ+g9sNM3znXZbhvb33WwPqpZSSPs37cPgF7eS6mAw/gUMx6zfE\n"
+ "HRmUnOQSzUdS05rvc/hsiCLhiIZ8hgfkD07XnTT1Ds8DwE55k7BUWY2wvwWCNLsH\n"
+ "qtqAxTr615XdkMxVkYgImpqPybarpfNYhFqkOwIDAQABAoIBACPC3VxEdbfYvhxJ\n"
+ "2mih9sG++nswAN7kUaX0cRe86rAwaShJPmJHApiQ1ROVTfpciiHJaLnhLraPWe2Z\n"
+ "I/6Bw3hmI4O399p3Lc1u+wlpdNqnvE6B1rSptx0DHE9xecvVH70rE0uM2Su7t6Y+\n"
+ "gnR2IKUGQs2mlCilm7aTUEWs0WJkkl4CG1dyxItuOSdNBjOEzXimJyiB10jEBFsp\n"
+ "SZeCF2FZ7AJbck5CVC42+oTsiDbZrHTHOn7v26rFGdONeHD1wOI1v7JwHFpCB923\n"
+ "aEHBzsPbMeq7DWG1rjzCYpcXHhTDBDBWSia4SEhyr2Nl7m7qxWWWwR+x4dqAj3rD\n"
+ "HeTmos0CgYEA6uf1CLpjPpOs5IaW1DQI8dJA/xFEAC/6GVgq4nFOGHZrm8G3L5o+\n"
+ "qvtQNMpDs2naWuZpqROFqv24o01DykHygR72GlPIY6uvmmf5tvJLoGnbFUay33L4\n"
+ "7b9dkNhuEIBNPzVDie0pgS77WgaPbYkVv5fnDwgPuVnkqfakEt7Pz2MCgYEAwkZ5\n"
+ "R1wLuTQEA2Poo6Gf4L8Bg6yNYI46LHDqDIs818iYLjtcnEEvbPfaoKNpOn7s7s4O\n"
+ "Pc+4HnT1aIQs0IKVLRTp+5a/9wfOkPZnobWOUHZk9UzBL3Hc1uy/qhp93iE3tSzx\n"
+ "v0O1pvR+hr3guTCZx8wZnDvaMgG3hlyPnVlHdrMCgYEAzQQxGbMC1ySv6quEjCP2\n"
+ "AogMbhE1lixJTUFj/EoDbNo9xKznIkauly/Lqqc1OysRhfA/G2+MY9YZBX1zwtyX\n"
+ "uBW7mPKynDrFgi9pBECnvJNmwET57Ic9ttIj6Tzbos83nAjyrzgr1zGX8dRz7ZeN\n"
+ "QbBj2vygLJbGOYinXkjUeh0CgYEAhN5aF9n2EqZmkEMGWtMxWy6HRJ0A3Cap1rcq\n"
+ "+4VHCXWhzwy+XAeg/e/N0MuyLlWcif7XcqLcE8h+BwtO8xQ8HmcNWApUJAls12wO\n"
+ "mGRpftJaXgIupdpD5aJpu1b++qrRRNIGTH9sf1D8L/8w8LcylZkbcuTkaAsQj45C\n"
+ "kqT64U0CgYEAq47IKS6xc3CDc17BqExR6t+1yRe+4ml+z1zcVbfUKony4pGvl1yo\n"
+ "rk0IYDN5Vd8h5xtXrkPdX9h+ywmohnelDKsayEuE+opyqEpSU4/96Bb22RZUoucb\n"
+ "LWkV5gZx5hFnDFtEd4vadMIiY4jVv/3JqiZDKwMVBJKlHRXJEEmIEBk=\n"
+ "-----END RSA PRIVATE KEY-----\n";
+
+ crypto_pk_t *pk = NULL;
+
+ pk = crypto_pk_new();
+ setup_capture_of_logs(LOG_WARN);
+ tt_int_op(-1, OP_EQ,
+ crypto_pk_read_private_key_from_string(pk, pem, strlen(pem)));
+#ifdef ENABLE_NSS
+ expect_single_log_msg_containing("received bad data");
+#else
+ expect_single_log_msg_containing("while checking RSA key");
+#endif
+ done:
+ teardown_capture_of_logs();
+ crypto_pk_free(pk);
+}
+
#ifdef HAVE_TRUNCATE
#define do_truncate truncate
#else
@@ -1437,7 +1577,8 @@ test_crypto_digests(void *arg)
(void)arg;
k = crypto_pk_new();
tt_assert(k);
- r = crypto_pk_read_private_key_from_string(k, AUTHORITY_SIGNKEY_3, -1);
+ r = crypto_pk_read_private_key_from_string(k, AUTHORITY_SIGNKEY_3,
+ strlen(AUTHORITY_SIGNKEY_3));
tt_assert(!r);
r = crypto_pk_get_digest(k, digest);
@@ -1816,15 +1957,6 @@ test_crypto_hkdf_sha256(void *arg)
key_material, 100)
/* Test vectors generated with ntor_ref.py */
- memset(key_material, 0, sizeof(key_material));
- EXPAND("");
- tt_int_op(r, OP_EQ, 0);
- test_memeq_hex(key_material,
- "d3490ed48b12a48f9547861583573fe3f19aafe3f81dc7fc75"
- "eeed96d741b3290f941576c1f9f0b2d463d1ec7ab2c6bf71cd"
- "d7f826c6298c00dbfe6711635d7005f0269493edf6046cc7e7"
- "dcf6abe0d20c77cf363e8ffe358927817a3d3e73712cee28d8");
-
EXPAND("Tor");
tt_int_op(r, OP_EQ, 0);
test_memeq_hex(key_material,
@@ -2809,8 +2941,8 @@ test_crypto_siphash(void *arg)
{ 0x72, 0x45, 0x06, 0xeb, 0x4c, 0x32, 0x8a, 0x95, }
};
- const struct sipkey K = { U64_LITERAL(0x0706050403020100),
- U64_LITERAL(0x0f0e0d0c0b0a0908) };
+ const struct sipkey K = { UINT64_C(0x0706050403020100),
+ UINT64_C(0x0f0e0d0c0b0a0908) };
uint8_t input[64];
int i, j;
@@ -2865,12 +2997,12 @@ crypto_rand_check_failure_mode_identical(void)
{
/* just in case the buffer size isn't a multiple of sizeof(int64_t) */
#define FAILURE_MODE_BUFFER_SIZE_I64 \
- (FAILURE_MODE_BUFFER_SIZE/SIZEOF_INT64_T)
+ (FAILURE_MODE_BUFFER_SIZE/8)
#define FAILURE_MODE_BUFFER_SIZE_I64_BYTES \
- (FAILURE_MODE_BUFFER_SIZE_I64*SIZEOF_INT64_T)
+ (FAILURE_MODE_BUFFER_SIZE_I64*8)
#if FAILURE_MODE_BUFFER_SIZE_I64 < 2
-#error FAILURE_MODE_BUFFER_SIZE needs to be at least 2*SIZEOF_INT64_T
+#error FAILURE_MODE_BUFFER_SIZE needs to be at least 2*8
#endif
int64_t buf[FAILURE_MODE_BUFFER_SIZE_I64];
@@ -3031,6 +3163,8 @@ struct testcase_t crypto_tests[] = {
{ "pk_fingerprints", test_crypto_pk_fingerprints, TT_FORK, NULL, NULL },
{ "pk_base64", test_crypto_pk_base64, TT_FORK, NULL, NULL },
{ "pk_pem_encrypted", test_crypto_pk_pem_encrypted, TT_FORK, NULL, NULL },
+ { "pk_invalid_private_key", test_crypto_pk_invalid_private_key, 0,
+ NULL, NULL },
CRYPTO_LEGACY(digests),
{ "digest_names", test_crypto_digest_names, 0, NULL, NULL },
{ "sha3", test_crypto_sha3, TT_FORK, NULL, NULL},
@@ -3066,4 +3200,3 @@ struct testcase_t crypto_tests[] = {
{ "failure_modes", test_crypto_failure_modes, TT_FORK, NULL, NULL },
END_OF_TESTCASES
};
-
diff --git a/src/test/test_crypto_ope.c b/src/test/test_crypto_ope.c
new file mode 100644
index 0000000000..4e7b952327
--- /dev/null
+++ b/src/test/test_crypto_ope.c
@@ -0,0 +1,154 @@
+/* Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2017, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#include "orconfig.h"
+
+#define CRYPTO_OPE_PRIVATE
+
+#include "lib/cc/compat_compiler.h"
+#include "lib/crypt_ops/crypto_ope.h"
+#include "lib/crypt_ops/crypto_cipher.h"
+#include "lib/encoding/binascii.h"
+#include "lib/malloc/malloc.h"
+#include "test/test.h"
+#include "tinytest.h"
+
+#include <stddef.h>
+#include <string.h>
+
+static void
+test_crypto_ope_consistency(void *arg)
+{
+ (void)arg;
+
+ crypto_ope_t *ope = NULL;
+ crypto_cipher_t *aes = NULL;
+ const int TEST_VALS[] = { 5, 500, 1023, 1024, 1025, 2046, 2047, 2048, 2049,
+ 10000, OPE_INPUT_MAX };
+ unsigned i;
+ const uint8_t key[32] = "A fixed key, chosen arbitrarily.";
+
+ ope = crypto_ope_new(key);
+ tt_assert(ope);
+
+ uint64_t last_val = 0;
+ for (i = 0; i < ARRAY_LENGTH(TEST_VALS); ++i) {
+ aes = ope_get_cipher(ope, 0);
+ int val = TEST_VALS[i];
+ uint64_t v1 = crypto_ope_encrypt(ope, val);
+ uint64_t v2 = sum_values_from_cipher(aes, val);
+ tt_u64_op(v1, OP_EQ, v2);
+ tt_u64_op(v2, OP_GT, last_val);
+ last_val = v2;
+ crypto_cipher_free(aes);
+ }
+
+ done:
+ crypto_cipher_free(aes);
+ crypto_ope_free(ope);
+}
+
+static void
+test_crypto_ope_oob(void *arg)
+{
+ (void)arg;
+
+ crypto_ope_t *ope = NULL;
+ const uint8_t key[32] = "A fixed key, chosen arbitrarily.";
+ ope = crypto_ope_new(key);
+
+ tt_u64_op(UINT64_MAX, OP_EQ, crypto_ope_encrypt(ope,INT_MIN));
+ tt_u64_op(UINT64_MAX, OP_EQ, crypto_ope_encrypt(ope,-100));
+ tt_u64_op(UINT64_MAX, OP_EQ, crypto_ope_encrypt(ope,0));
+ tt_u64_op(UINT64_MAX, OP_NE, crypto_ope_encrypt(ope,1));
+ tt_u64_op(UINT64_MAX, OP_NE, crypto_ope_encrypt(ope,7000));
+ tt_u64_op(UINT64_MAX, OP_NE, crypto_ope_encrypt(ope,OPE_INPUT_MAX));
+ tt_u64_op(UINT64_MAX, OP_EQ, crypto_ope_encrypt(ope,OPE_INPUT_MAX+1));
+ tt_u64_op(UINT64_MAX, OP_EQ, crypto_ope_encrypt(ope,INT_MAX));
+ done:
+ crypto_ope_free(ope);
+}
+
+static const char OPE_TEST_KEY[] =
+ "19e05891d55232c08c2cad91d612fdb9cbd6691949a0742434a76c80bc6992fe";
+
+/* generated by a separate python implementation. */
+static const struct {
+ int v;
+ uint64_t r;
+} OPE_TEST_VECTORS[] = {
+ { 121132, UINT64_C(3971694514) },
+ { 82283, UINT64_C(2695743564) },
+ { 72661, UINT64_C(2381548866) },
+ { 72941, UINT64_C(2390408421) },
+ { 123122, UINT64_C(4036781069) },
+ { 12154, UINT64_C(402067100) },
+ { 121574, UINT64_C(3986197593) },
+ { 11391, UINT64_C(376696838) },
+ { 65845, UINT64_C(2161801517) },
+ { 86301, UINT64_C(2828270975) },
+ { 61284, UINT64_C(2013616892) },
+ { 70505, UINT64_C(2313368870) },
+ { 30438, UINT64_C(1001394664) },
+ { 60150, UINT64_C(1977329668) },
+ { 114800, UINT64_C(3764946628) },
+ { 109403, UINT64_C(3585352477) },
+ { 21893, UINT64_C(721388468) },
+ { 123569, UINT64_C(4051780471) },
+ { 95617, UINT64_C(3134921876) },
+ { 48561, UINT64_C(1597596985) },
+ { 53334, UINT64_C(1753691710) },
+ { 92746, UINT64_C(3040874493) },
+ { 7110, UINT64_C(234966492) },
+ { 9612, UINT64_C(318326551) },
+ { 106958, UINT64_C(3506124249) },
+ { 46889, UINT64_C(1542219146) },
+ { 87790, UINT64_C(2877361609) },
+ { 68878, UINT64_C(2260369112) },
+ { 47917, UINT64_C(1576681737) },
+ { 121128, UINT64_C(3971553290) },
+ { 108602, UINT64_C(3559176081) },
+ { 28217, UINT64_C(929692460) },
+ { 69498, UINT64_C(2280554161) },
+ { 63870, UINT64_C(2098322675) },
+ { 57542, UINT64_C(1891698992) },
+ { 122148, UINT64_C(4004515805) },
+ { 46254, UINT64_C(1521227949) },
+ { 42850, UINT64_C(1408996941) },
+ { 92661, UINT64_C(3037901517) },
+ { 57720, UINT64_C(1897369989) },
+};
+
+static void
+test_crypto_ope_vectors(void *arg)
+{
+ (void)arg;
+ uint8_t key[32];
+ crypto_ope_t *ope = NULL, *ope2 = NULL;
+
+ base16_decode((char*)key, 32, OPE_TEST_KEY, strlen(OPE_TEST_KEY));
+
+ ope = crypto_ope_new(key);
+ key[8] += 1;
+ ope2 = crypto_ope_new(key);
+ unsigned i;
+ for (i = 0; i < ARRAY_LENGTH(OPE_TEST_VECTORS); ++i) {
+ int val = OPE_TEST_VECTORS[i].v;
+ uint64_t res = OPE_TEST_VECTORS[i].r;
+
+ tt_u64_op(crypto_ope_encrypt(ope, val), OP_EQ, res);
+ tt_u64_op(crypto_ope_encrypt(ope2, val), OP_NE, res);
+ }
+ done:
+ crypto_ope_free(ope);
+ crypto_ope_free(ope2);
+}
+
+struct testcase_t crypto_ope_tests[] = {
+ { "consistency", test_crypto_ope_consistency, 0, NULL, NULL },
+ { "oob", test_crypto_ope_oob, 0, NULL, NULL },
+ { "vectors", test_crypto_ope_vectors, 0, NULL, NULL },
+ END_OF_TESTCASES
+};
diff --git a/src/test/test_crypto_openssl.c b/src/test/test_crypto_openssl.c
index 090cb4242b..92f9cbab2f 100644
--- a/src/test/test_crypto_openssl.c
+++ b/src/test/test_crypto_openssl.c
@@ -1,21 +1,21 @@
/* Copyright (c) 2001-2004, Roger Dingledine.
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2017, The Tor Project, Inc. */
+ * Copyright (c) 2007-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
#include "orconfig.h"
-#define CRYPTO_PRIVATE
+#define CRYPTO_RAND_PRIVATE
-#include "crypto.h"
-#include "util.h"
-#include "util_format.h"
-#include "compat.h"
-#include "test.h"
+#include "lib/crypt_ops/compat_openssl.h"
+#include "lib/crypt_ops/crypto_rand.h"
+#include "lib/encoding/binascii.h"
+#include "lib/malloc/malloc.h"
+#include "test/test.h"
#include <openssl/evp.h>
#include <openssl/rand.h>
-#include "compat_openssl.h"
+#include <string.h>
/* Test for rectifying openssl RAND engine. */
static void
@@ -104,4 +104,3 @@ struct testcase_t crypto_openssl_tests[] = {
TT_FORK, NULL, NULL },
END_OF_TESTCASES
};
-
diff --git a/src/test/test_crypto_slow.c b/src/test/test_crypto_slow.c
index 2afb71ff5a..ca6b7b8d4d 100644
--- a/src/test/test_crypto_slow.c
+++ b/src/test/test_crypto_slow.c
@@ -1,21 +1,26 @@
/* Copyright (c) 2001-2004, Roger Dingledine.
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2017, The Tor Project, Inc. */
+ * Copyright (c) 2007-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
#include "orconfig.h"
#define CRYPTO_S2K_PRIVATE
-#include "or.h"
-#include "test.h"
-#include "crypto_s2k.h"
-#include "crypto_pwbox.h"
+#include "core/or/or.h"
+#include "test/test.h"
+#include "lib/crypt_ops/crypto_curve25519.h"
+#include "lib/crypt_ops/crypto_ed25519.h"
+#include "lib/crypt_ops/crypto_s2k.h"
+#include "lib/crypt_ops/crypto_pwbox.h"
+#include "lib/crypt_ops/crypto_rand.h"
#if defined(HAVE_LIBSCRYPT_H) && defined(HAVE_LIBSCRYPT_SCRYPT)
#define HAVE_LIBSCRYPT
#include <libscrypt.h>
#endif
+#ifdef ENABLE_OPENSSL
#include <openssl/evp.h>
+#endif
/** Run unit tests for our secret-to-key passphrase hashing functionality. */
static void
@@ -614,4 +619,3 @@ struct testcase_t slow_crypto_tests[] = {
ED25519_TEST(fuzz_donna, TT_FORK),
END_OF_TESTCASES
};
-
diff --git a/src/test/test_data.c b/src/test/test_data.c
index ce6c3394f6..be8153258b 100644
--- a/src/test/test_data.c
+++ b/src/test/test_data.c
@@ -1,9 +1,9 @@
/* Copyright 2001-2004 Roger Dingledine.
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2017, The Tor Project, Inc. */
+ * Copyright (c) 2007-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
-#include "test.h"
+#include "test/test.h"
/* Our unit test expect that the AUTHORITY_CERT_* public keys will sort
* in this order. */
diff --git a/src/test/test_dir.c b/src/test/test_dir.c
index a33b23bcc9..c18aa99fea 100644
--- a/src/test/test_dir.c
+++ b/src/test/test_dir.c
@@ -1,46 +1,96 @@
/* Copyright (c) 2001-2004, Roger Dingledine.
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2017, The Tor Project, Inc. */
+ * Copyright (c) 2007-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
#include "orconfig.h"
#include <math.h>
+#define BWAUTH_PRIVATE
#define CONFIG_PRIVATE
#define CONTROL_PRIVATE
+#define DIRCACHE_PRIVATE
+#define DIRCLIENT_PRIVATE
#define DIRSERV_PRIVATE
#define DIRVOTE_PRIVATE
-#define ROUTER_PRIVATE
-#define ROUTERLIST_PRIVATE
-#define ROUTERPARSE_PRIVATE
+#define DLSTATUS_PRIVATE
#define HIBERNATE_PRIVATE
#define NETWORKSTATUS_PRIVATE
+#define NS_PARSE_PRIVATE
+#define NODE_SELECT_PRIVATE
#define RELAY_PRIVATE
-
-#include "or.h"
-#include "bridges.h"
-#include "confparse.h"
-#include "config.h"
-#include "control.h"
-#include "crypto_ed25519.h"
-#include "directory.h"
-#include "dirserv.h"
-#include "dirvote.h"
-#include "entrynodes.h"
-#include "hibernate.h"
-#include "memarea.h"
-#include "networkstatus.h"
-#include "router.h"
-#include "routerkeys.h"
-#include "routerlist.h"
-#include "routerparse.h"
-#include "routerset.h"
-#include "shared_random_state.h"
-#include "test.h"
-#include "test_dir_common.h"
-#include "torcert.h"
-#include "relay.h"
-#include "log_test_helpers.h"
+#define ROUTERLIST_PRIVATE
+#define ROUTER_PRIVATE
+#define UNPARSEABLE_PRIVATE
+#define VOTEFLAGS_PRIVATE
+
+#include "core/or/or.h"
+#include "app/config/config.h"
+#include "app/config/confparse.h"
+#include "core/mainloop/connection.h"
+#include "core/or/relay.h"
+#include "core/or/versions.h"
+#include "feature/client/bridges.h"
+#include "feature/client/entrynodes.h"
+#include "feature/control/control.h"
+#include "feature/dirauth/bwauth.h"
+#include "feature/dirauth/dirvote.h"
+#include "feature/dirauth/dsigs_parse.h"
+#include "feature/dirauth/process_descs.h"
+#include "feature/dirauth/recommend_pkg.h"
+#include "feature/dirauth/shared_random_state.h"
+#include "feature/dirauth/voteflags.h"
+#include "feature/dircache/dircache.h"
+#include "feature/dircache/dirserv.h"
+#include "feature/dirclient/dirclient.h"
+#include "feature/dirclient/dlstatus.h"
+#include "feature/dircommon/directory.h"
+#include "feature/dircommon/fp_pair.h"
+#include "feature/dircommon/voting_schedule.h"
+#include "feature/hibernate/hibernate.h"
+#include "feature/nodelist/authcert.h"
+#include "feature/nodelist/dirlist.h"
+#include "feature/nodelist/networkstatus.h"
+#include "feature/nodelist/nickname.h"
+#include "feature/nodelist/node_select.h"
+#include "feature/nodelist/routerlist.h"
+#include "feature/dirparse/authcert_parse.h"
+#include "feature/dirparse/ns_parse.h"
+#include "feature/dirparse/routerparse.h"
+#include "feature/dirparse/unparseable.h"
+#include "feature/nodelist/routerset.h"
+#include "feature/nodelist/torcert.h"
+#include "feature/relay/router.h"
+#include "feature/relay/routerkeys.h"
+#include "feature/relay/routermode.h"
+#include "lib/compress/compress.h"
+#include "lib/crypt_ops/crypto_ed25519.h"
+#include "lib/crypt_ops/crypto_format.h"
+#include "lib/crypt_ops/crypto_rand.h"
+#include "lib/encoding/confline.h"
+#include "lib/memarea/memarea.h"
+#include "lib/osinfo/uname.h"
+#include "test/log_test_helpers.h"
+#include "test/test.h"
+#include "test/test_dir_common.h"
+
+#include "core/or/addr_policy_st.h"
+#include "feature/nodelist/authority_cert_st.h"
+#include "feature/nodelist/document_signature_st.h"
+#include "feature/nodelist/extrainfo_st.h"
+#include "feature/nodelist/networkstatus_st.h"
+#include "feature/nodelist/networkstatus_voter_info_st.h"
+#include "feature/dirauth/ns_detached_signatures_st.h"
+#include "core/or/port_cfg_st.h"
+#include "feature/nodelist/routerinfo_st.h"
+#include "feature/nodelist/routerlist_st.h"
+#include "core/or/tor_version_st.h"
+#include "feature/dirauth/vote_microdesc_hash_st.h"
+#include "feature/nodelist/vote_routerstatus_st.h"
+
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
#define NS_MODULE dir
@@ -140,7 +190,7 @@ test_dir_formats(void *arg)
r1->supports_tunnelled_dir_requests = 1;
tor_addr_parse(&r1->ipv6_addr, "1:2:3:4::");
r1->ipv6_orport = 9999;
- r1->onion_pkey = crypto_pk_dup_key(pk1);
+ router_set_rsa_onion_pkey(pk1, &r1->onion_pkey, &r1->onion_pkey_len);
/* Fake just enough of an ntor key to get by */
curve25519_keypair_t r1_onion_keypair;
curve25519_keypair_generate(&r1_onion_keypair, 0);
@@ -183,7 +233,7 @@ test_dir_formats(void *arg)
r2->or_port = 9005;
r2->dir_port = 0;
r2->supports_tunnelled_dir_requests = 1;
- r2->onion_pkey = crypto_pk_dup_key(pk2);
+ router_set_rsa_onion_pkey(pk2, &r2->onion_pkey, &r2->onion_pkey_len);
curve25519_keypair_t r2_onion_keypair;
curve25519_keypair_generate(&r2_onion_keypair, 0);
r2->onion_curve25519_pkey = tor_memdup(&r2_onion_keypair.pubkey,
@@ -276,7 +326,10 @@ test_dir_formats(void *arg)
tt_int_op(rp1->bandwidthrate,OP_EQ, r1->bandwidthrate);
tt_int_op(rp1->bandwidthburst,OP_EQ, r1->bandwidthburst);
tt_int_op(rp1->bandwidthcapacity,OP_EQ, r1->bandwidthcapacity);
- tt_int_op(crypto_pk_cmp_keys(rp1->onion_pkey, pk1), OP_EQ, 0);
+ crypto_pk_t *onion_pkey = router_get_rsa_onion_pkey(rp1->onion_pkey,
+ rp1->onion_pkey_len);
+ tt_int_op(crypto_pk_cmp_keys(onion_pkey, pk1), OP_EQ, 0);
+ crypto_pk_free(onion_pkey);
tt_int_op(crypto_pk_cmp_keys(rp1->identity_pkey, pk2), OP_EQ, 0);
tt_assert(rp1->supports_tunnelled_dir_requests);
//tt_assert(rp1->exit_policy == NULL);
@@ -393,7 +446,10 @@ test_dir_formats(void *arg)
tt_mem_op(rp2->onion_curve25519_pkey->public_key,OP_EQ,
r2->onion_curve25519_pkey->public_key,
CURVE25519_PUBKEY_LEN);
- tt_int_op(crypto_pk_cmp_keys(rp2->onion_pkey, pk2), OP_EQ, 0);
+ onion_pkey = router_get_rsa_onion_pkey(rp2->onion_pkey,
+ rp2->onion_pkey_len);
+ tt_int_op(crypto_pk_cmp_keys(onion_pkey, pk2), OP_EQ, 0);
+ crypto_pk_free(onion_pkey);
tt_int_op(crypto_pk_cmp_keys(rp2->identity_pkey, pk1), OP_EQ, 0);
tt_assert(rp2->supports_tunnelled_dir_requests);
@@ -1499,6 +1555,13 @@ test_dir_measured_bw_kb(void *arg)
"bw=1024 junk=007\n",
"misc=junk node_id=$557365204145532d32353620696e73746561642e "
"bw=1024 junk=007\n",
+ /* check whether node_id can be at the end */
+ "bw=1024 node_id=$557365204145532d32353620696e73746561642e\n",
+ /* check whether node_id can be at the end and bw has something in front*/
+ "foo=bar bw=1024 node_id=$557365204145532d32353620696e73746561642e\n",
+ /* check whether node_id can be at the end and something in the
+ * in the middle of bw and node_id */
+ "bw=1024 foo=bar node_id=$557365204145532d32353620696e73746561642e\n",
"end"
};
const char *lines_fail[] = {
@@ -1538,12 +1601,18 @@ test_dir_measured_bw_kb(void *arg)
(void)arg;
for (i = 0; strcmp(lines_fail[i], "end"); i++) {
//fprintf(stderr, "Testing: %s\n", lines_fail[i]);
- tt_int_op(measured_bw_line_parse(&mbwl, lines_fail[i]), OP_EQ, -1);
+ /* Testing only with line_is_after_headers = 1. Tests with
+ * line_is_after_headers = 0 in
+ * test_dir_measured_bw_kb_line_is_after_headers */
+ tt_assert(measured_bw_line_parse(&mbwl, lines_fail[i], 1) == -1);
}
for (i = 0; strcmp(lines_pass[i], "end"); i++) {
//fprintf(stderr, "Testing: %s %d\n", lines_pass[i], TOR_ISSPACE('\n'));
- tt_int_op(measured_bw_line_parse(&mbwl, lines_pass[i]), OP_EQ, 0);
+ /* Testing only with line_is_after_headers = 1. Tests with
+ * line_is_after_headers = 0 in
+ * test_dir_measured_bw_kb_line_is_after_headers */
+ tt_assert(measured_bw_line_parse(&mbwl, lines_pass[i], 1) == 0);
tt_assert(mbwl.bw_kb == 1024);
tt_assert(strcmp(mbwl.node_hex,
"557365204145532d32353620696e73746561642e") == 0);
@@ -1553,23 +1622,372 @@ test_dir_measured_bw_kb(void *arg)
return;
}
-/* Test dirserv_read_measured_bandwidths */
+/* Unit tests for measured_bw_line_parse using line_is_after_headers flag.
+ * When the end of the header is detected (a first complete bw line is parsed),
+ * incomplete lines fail and give warnings, but do not give warnings if
+ * the header is not ended, allowing to ignore additional header lines. */
static void
-test_dir_dirserv_read_measured_bandwidths(void *arg)
+test_dir_measured_bw_kb_line_is_after_headers(void *arg)
{
- char *fname=NULL;
(void)arg;
+ measured_bw_line_t mbwl;
+ const char *line_pass = \
+ "node_id=$557365204145532d32353620696e73746561642e bw=1024\n";
+ int i;
+ const char *lines_fail[] = {
+ "node_id=$557365204145532d32353620696e73746561642e \n",
+ "bw=1024\n",
+ "rtt=300\n",
+ "end"
+ };
+
+ setup_capture_of_logs(LOG_DEBUG);
+
+ /* Test bw lines when header has ended */
+ for (i = 0; strcmp(lines_fail[i], "end"); i++) {
+ tt_assert(measured_bw_line_parse(&mbwl, lines_fail[i], 1) == -1);
+ expect_log_msg_containing("Incomplete line in bandwidth file:");
+ mock_clean_saved_logs();
+ }
- fname = tor_strdup(get_fname("V3BandwidthsFile"));
- /* Test an empty file */
+ tt_assert(measured_bw_line_parse(&mbwl, line_pass, 1) == 0);
+
+ /* Test bw lines when header has not ended */
+ for (i = 0; strcmp(lines_fail[i], "end"); i++) {
+ tt_assert(measured_bw_line_parse(&mbwl, lines_fail[i], 0) == -1);
+ expect_log_msg_containing("Missing bw or node_id in bandwidth file line:");
+ mock_clean_saved_logs();
+ }
+
+ tt_assert(measured_bw_line_parse(&mbwl, line_pass, 0) == 0);
+
+ done:
+ teardown_capture_of_logs();
+}
+
+/* Test dirserv_read_measured_bandwidths with headers and complete files. */
+static void
+test_dir_dirserv_read_measured_bandwidths(void *arg)
+{
+ (void)arg;
+ char *content = NULL;
+ time_t timestamp = time(NULL);
+ char *fname = tor_strdup(get_fname("V3BandwidthsFile"));
+ smartlist_t *bw_file_headers = smartlist_new();
+ /* bw file strings in vote */
+ char *bw_file_headers_str = NULL;
+ char *bw_file_headers_str_v100 = NULL;
+ char *bw_file_headers_str_v110 = NULL;
+ char *bw_file_headers_str_bad = NULL;
+ char *bw_file_headers_str_extra = NULL;
+ char bw_file_headers_str_long[MAX_BW_FILE_HEADER_COUNT_IN_VOTE * 8 + 1] = "";
+ /* string header lines in bw file */
+ char *header_lines_v100 = NULL;
+ char *header_lines_v110_no_terminator = NULL;
+ char *header_lines_v110 = NULL;
+ char header_lines_long[MAX_BW_FILE_HEADER_COUNT_IN_VOTE * 8 + 1] = "";
+ int i;
+ const char *header_lines_v110_no_terminator_no_timestamp =
+ "version=1.1.0\n"
+ "software=sbws\n"
+ "software_version=0.1.0\n"
+ "earliest_bandwidth=2018-05-08T16:13:26\n"
+ "file_created=2018-04-16T21:49:18\n"
+ "generator_started=2018-05-08T16:13:25\n"
+ "latest_bandwidth=2018-04-16T20:49:18\n";
+ const char *bw_file_headers_str_v110_no_timestamp =
+ "version=1.1.0 software=sbws "
+ "software_version=0.1.0 "
+ "earliest_bandwidth=2018-05-08T16:13:26 "
+ "file_created=2018-04-16T21:49:18 "
+ "generator_started=2018-05-08T16:13:25 "
+ "latest_bandwidth=2018-04-16T20:49:18";
+ const char *relay_lines_v100 =
+ "node_id=$557365204145532d32353620696e73746561642e bw=1024 "
+ "nick=Test measured_at=1523911725 updated_at=1523911725 "
+ "pid_error=4.11374090719 pid_error_sum=4.11374090719 "
+ "pid_bw=57136645 pid_delta=2.12168374577 circ_fail=0.2 "
+ "scanner=/filepath\n";
+ const char *relay_lines_v110 =
+ "node_id=$68A483E05A2ABDCA6DA5A3EF8DB5177638A27F80 "
+ "master_key_ed25519=YaqV4vbvPYKucElk297eVdNArDz9HtIwUoIeo0+cVIpQ "
+ "bw=760 nick=Test rtt=380 time=2018-05-08T16:13:26\n";
+ const char *relay_lines_bad =
+ "node_id=$68A483E05A2ABDCA6DA5A3EF8DB5177638A\n";
+
+ tor_asprintf(&header_lines_v100, "%ld\n", (long)timestamp);
+ tor_asprintf(&header_lines_v110_no_terminator, "%ld\n%s", (long)timestamp,
+ header_lines_v110_no_terminator_no_timestamp);
+ tor_asprintf(&header_lines_v110, "%s%s",
+ header_lines_v110_no_terminator, BW_FILE_HEADERS_TERMINATOR);
+
+ tor_asprintf(&bw_file_headers_str_v100, "timestamp=%ld",(long)timestamp);
+ tor_asprintf(&bw_file_headers_str_v110, "timestamp=%ld %s",
+ (long)timestamp, bw_file_headers_str_v110_no_timestamp);
+ tor_asprintf(&bw_file_headers_str_bad, "%s "
+ "node_id=$68A483E05A2ABDCA6DA5A3EF8DB5177638A",
+ bw_file_headers_str_v110);
+
+ for (i=0; i<MAX_BW_FILE_HEADER_COUNT_IN_VOTE; i++) {
+ strlcat(header_lines_long, "foo=bar\n",
+ sizeof(header_lines_long));
+ }
+ /* 8 is the number of v110 lines in header_lines_v110 */
+ for (i=0; i<MAX_BW_FILE_HEADER_COUNT_IN_VOTE - 8 - 1; i++) {
+ strlcat(bw_file_headers_str_long, "foo=bar ",
+ sizeof(bw_file_headers_str_long));
+ }
+ strlcat(bw_file_headers_str_long, "foo=bar",
+ sizeof(bw_file_headers_str_long));
+ tor_asprintf(&bw_file_headers_str_extra,
+ "%s %s",
+ bw_file_headers_str_v110,
+ bw_file_headers_str_long);
+
+ /* Test an empty bandwidth file. bw_file_headers will be empty string */
write_str_to_file(fname, "", 0);
setup_capture_of_logs(LOG_WARN);
- tt_int_op(-1, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL));
+ tt_int_op(-1, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL,
+ bw_file_headers));
expect_log_msg("Empty bandwidth file\n");
+ teardown_capture_of_logs();
+ bw_file_headers_str = smartlist_join_strings(bw_file_headers, " ", 0, NULL);
+ tt_str_op("", OP_EQ, bw_file_headers_str);
+ SMARTLIST_FOREACH(bw_file_headers, char *, c, tor_free(c));
+ smartlist_free(bw_file_headers);
+ tor_free(bw_file_headers_str);
+
+ /* Test bandwidth file with only timestamp.
+ * bw_file_headers will be empty string */
+ bw_file_headers = smartlist_new();
+ tor_asprintf(&content, "%ld", (long)timestamp);
+ write_str_to_file(fname, content, 0);
+ tor_free(content);
+ tt_int_op(-1, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL,
+ bw_file_headers));
+ bw_file_headers_str = smartlist_join_strings(bw_file_headers, " ", 0, NULL);
+ tt_str_op("", OP_EQ, bw_file_headers_str);
+ SMARTLIST_FOREACH(bw_file_headers, char *, c, tor_free(c));
+ smartlist_free(bw_file_headers);
+ tor_free(bw_file_headers_str);
+
+ /* Test v1.0.0 bandwidth file headers */
+ write_str_to_file(fname, header_lines_v100, 0);
+ bw_file_headers = smartlist_new();
+ tt_int_op(0, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL,
+ bw_file_headers));
+ bw_file_headers_str = smartlist_join_strings(bw_file_headers, " ", 0, NULL);
+ tt_str_op(bw_file_headers_str_v100, OP_EQ, bw_file_headers_str);
+ SMARTLIST_FOREACH(bw_file_headers, char *, c, tor_free(c));
+ smartlist_free(bw_file_headers);
+ tor_free(bw_file_headers_str);
+
+ /* Test v1.0.0 complete bandwidth file */
+ bw_file_headers = smartlist_new();
+ tor_asprintf(&content, "%s%s", header_lines_v100, relay_lines_v100);
+ write_str_to_file(fname, content, 0);
+ tor_free(content);
+ tt_int_op(0, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL,
+ bw_file_headers));
+ bw_file_headers_str = smartlist_join_strings(bw_file_headers, " ", 0, NULL);
+ tt_str_op(bw_file_headers_str_v100, OP_EQ, bw_file_headers_str);
+ SMARTLIST_FOREACH(bw_file_headers, char *, c, tor_free(c));
+ smartlist_free(bw_file_headers);
+ tor_free(bw_file_headers_str);
+
+ /* Test v1.0.0 complete bandwidth file with NULL bw_file_headers. */
+ tor_asprintf(&content, "%s%s", header_lines_v100, relay_lines_v100);
+ write_str_to_file(fname, content, 0);
+ tor_free(content);
+ tt_int_op(0, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL, NULL));
+
+ /* Test bandwidth file including v1.1.0 bandwidth headers and
+ * v1.0.0 relay lines. bw_file_headers will contain the v1.1.0 headers. */
+ bw_file_headers = smartlist_new();
+ tor_asprintf(&content, "%s%s%s", header_lines_v100, header_lines_v110,
+ relay_lines_v100);
+ write_str_to_file(fname, content, 0);
+ tor_free(content);
+ tt_int_op(0, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL,
+ bw_file_headers));
+ bw_file_headers_str = smartlist_join_strings(bw_file_headers, " ", 0, NULL);
+ tt_str_op(bw_file_headers_str_v110, OP_EQ, bw_file_headers_str);
+ SMARTLIST_FOREACH(bw_file_headers, char *, c, tor_free(c));
+ smartlist_free(bw_file_headers);
+ tor_free(bw_file_headers_str);
+
+ /* Test v1.0.0 complete bandwidth file with v1.1.0 headers at the end.
+ * bw_file_headers will contain only v1.0.0 headers and the additional
+ * headers will be interpreted as malformed relay lines. */
+ bw_file_headers = smartlist_new();
+ tor_asprintf(&content, "%s%s%s", header_lines_v100, relay_lines_v100,
+ header_lines_v110);
+ write_str_to_file(fname, content, 0);
+ tor_free(content);
+ tt_int_op(0, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL,
+ bw_file_headers));
+ bw_file_headers_str = smartlist_join_strings(bw_file_headers, " ", 0, NULL);
+ tt_str_op(bw_file_headers_str_v100, OP_EQ, bw_file_headers_str);
+ SMARTLIST_FOREACH(bw_file_headers, char *, c, tor_free(c));
+ smartlist_free(bw_file_headers);
+ tor_free(bw_file_headers_str);
+
+ /* Test v1.0.0 complete bandwidth file, the v1.1.0 headers and more relay
+ * lines. bw_file_headers will contain only v1.0.0 headers, the additional
+ * headers will be interpreted as malformed relay lines and the last relay
+ * lines will be correctly interpreted as relay lines. */
+ bw_file_headers = smartlist_new();
+ tor_asprintf(&content, "%s%s%s%s", header_lines_v100, relay_lines_v100,
+ header_lines_v110, relay_lines_v100);
+ write_str_to_file(fname, content, 0);
+ tor_free(content);
+ tt_int_op(0, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL,
+ bw_file_headers));
+ bw_file_headers_str = smartlist_join_strings(bw_file_headers, " ", 0, NULL);
+ tt_str_op(bw_file_headers_str_v100, OP_EQ, bw_file_headers_str);
+ SMARTLIST_FOREACH(bw_file_headers, char *, c, tor_free(c));
+ smartlist_free(bw_file_headers);
+ tor_free(bw_file_headers_str);
+
+ /* Test v1.1.0 bandwidth headers without terminator */
+ bw_file_headers = smartlist_new();
+ write_str_to_file(fname, header_lines_v110_no_terminator, 0);
+ tt_int_op(0, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL,
+ bw_file_headers));
+ bw_file_headers_str = smartlist_join_strings(bw_file_headers, " ", 0, NULL);
+ tt_str_op(bw_file_headers_str_v110, OP_EQ, bw_file_headers_str);
+ SMARTLIST_FOREACH(bw_file_headers, char *, c, tor_free(c));
+ smartlist_free(bw_file_headers);
+ tor_free(bw_file_headers_str);
+
+ /* Test v1.1.0 bandwidth headers with terminator */
+ bw_file_headers = smartlist_new();
+ write_str_to_file(fname, header_lines_v110, 0);
+ tt_int_op(0, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL,
+ bw_file_headers));
+ bw_file_headers_str = smartlist_join_strings(bw_file_headers, " ", 0, NULL);
+ tt_str_op(bw_file_headers_str_v110, OP_EQ, bw_file_headers_str);
+ SMARTLIST_FOREACH(bw_file_headers, char *, c, tor_free(c));
+ smartlist_free(bw_file_headers);
+ tor_free(bw_file_headers_str);
+
+ /* Test v1.1.0 bandwidth file without terminator, then relay lines.
+ * bw_file_headers will contain the v1.1.0 headers. */
+ bw_file_headers = smartlist_new();
+ tor_asprintf(&content, "%s%s",
+ header_lines_v110_no_terminator, relay_lines_v110);
+ write_str_to_file(fname, content, 0);
+ tor_free(content);
+ tt_int_op(0, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL,
+ bw_file_headers));
+ bw_file_headers_str = smartlist_join_strings(bw_file_headers, " ", 0, NULL);
+ tt_str_op(bw_file_headers_str_v110, OP_EQ, bw_file_headers_str);
+ SMARTLIST_FOREACH(bw_file_headers, char *, c, tor_free(c));
+ smartlist_free(bw_file_headers);
+ tor_free(bw_file_headers_str);
+
+ /* Test v1.1.0 bandwidth headers with terminator, then relay lines
+ * bw_file_headers will contain the v1.1.0 headers. */
+ bw_file_headers = smartlist_new();
+ tor_asprintf(&content, "%s%s",
+ header_lines_v110, relay_lines_v110);
+ write_str_to_file(fname, content, 0);
+ tor_free(content);
+ tt_int_op(0, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL,
+ bw_file_headers));
+ bw_file_headers_str = smartlist_join_strings(bw_file_headers, " ", 0, NULL);
+ tt_str_op(bw_file_headers_str_v110, OP_EQ, bw_file_headers_str);
+ SMARTLIST_FOREACH(bw_file_headers, char *, c, tor_free(c));
+ smartlist_free(bw_file_headers);
+ tor_free(bw_file_headers_str);
+
+ /* Test v1.1.0 bandwidth headers with terminator, then bad relay lines,
+ * then terminator, then relay_lines_bad.
+ * bw_file_headers will contain the v1.1.0 headers. */
+ bw_file_headers = smartlist_new();
+ tor_asprintf(&content, "%s%s%s%s", header_lines_v110, relay_lines_bad,
+ BW_FILE_HEADERS_TERMINATOR, relay_lines_bad);
+ write_str_to_file(fname, content, 0);
+ tor_free(content);
+ tt_int_op(0, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL,
+ bw_file_headers));
+ bw_file_headers_str = smartlist_join_strings(bw_file_headers, " ", 0, NULL);
+ tt_str_op(bw_file_headers_str_v110, OP_EQ, bw_file_headers_str);
+ SMARTLIST_FOREACH(bw_file_headers, char *, c, tor_free(c));
+ smartlist_free(bw_file_headers);
+ tor_free(bw_file_headers_str);
+
+ /* Test v1.1.0 bandwidth headers without terminator, then bad relay lines,
+ * then relay lines. bw_file_headers will contain the v1.1.0 headers and
+ * the bad relay lines. */
+ bw_file_headers = smartlist_new();
+ tor_asprintf(&content, "%s%s%s",
+ header_lines_v110_no_terminator, relay_lines_bad,
+ relay_lines_v110);
+ write_str_to_file(fname, content, 0);
+ tor_free(content);
+ tt_int_op(0, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL,
+ bw_file_headers));
+ bw_file_headers_str = smartlist_join_strings(bw_file_headers, " ", 0, NULL);
+ tt_str_op(bw_file_headers_str_bad, OP_EQ, bw_file_headers_str);
+ SMARTLIST_FOREACH(bw_file_headers, char *, c, tor_free(c));
+ smartlist_free(bw_file_headers);
+ tor_free(bw_file_headers_str);
+
+ /* Test v1.1.0 bandwidth headers without terminator,
+ * then many bad relay lines, then relay lines.
+ * bw_file_headers will contain the v1.1.0 headers and the bad relay lines
+ * to a maximum of MAX_BW_FILE_HEADER_COUNT_IN_VOTE header lines. */
+ bw_file_headers = smartlist_new();
+ tor_asprintf(&content, "%s%s%s",
+ header_lines_v110_no_terminator, header_lines_long,
+ relay_lines_v110);
+ write_str_to_file(fname, content, 0);
+ tor_free(content);
+ tt_int_op(0, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL,
+ bw_file_headers));
+ tt_int_op(MAX_BW_FILE_HEADER_COUNT_IN_VOTE, OP_EQ,
+ smartlist_len(bw_file_headers));
+ bw_file_headers_str = smartlist_join_strings(bw_file_headers, " ", 0, NULL);
+ tt_str_op(bw_file_headers_str_extra, OP_EQ, bw_file_headers_str);
+ SMARTLIST_FOREACH(bw_file_headers, char *, c, tor_free(c));
+ smartlist_free(bw_file_headers);
+ tor_free(bw_file_headers_str);
+
+ /* Test v1.1.0 bandwidth headers without terminator,
+ * then many bad relay lines, then relay lines.
+ * bw_file_headers will contain the v1.1.0 headers and the bad relay lines.
+ * Force bw_file_headers to have more than MAX_BW_FILE_HEADER_COUNT_IN_VOTE
+ * This test is needed while there is not dirvote test. */
+ bw_file_headers = smartlist_new();
+ tor_asprintf(&content, "%s%s%s",
+ header_lines_v110_no_terminator, header_lines_long,
+ relay_lines_v110);
+ write_str_to_file(fname, content, 0);
+ tor_free(content);
+ tt_int_op(0, OP_EQ, dirserv_read_measured_bandwidths(fname, NULL,
+ bw_file_headers));
+ tt_int_op(MAX_BW_FILE_HEADER_COUNT_IN_VOTE, OP_EQ,
+ smartlist_len(bw_file_headers));
+ /* force bw_file_headers to be bigger than
+ * MAX_BW_FILE_HEADER_COUNT_IN_VOTE */
+ char line[8] = "foo=bar\0";
+ smartlist_add_strdup(bw_file_headers, line);
+ tt_int_op(MAX_BW_FILE_HEADER_COUNT_IN_VOTE, OP_LT,
+ smartlist_len(bw_file_headers));
+ SMARTLIST_FOREACH(bw_file_headers, char *, c, tor_free(c));
+ smartlist_free(bw_file_headers);
+ tor_free(bw_file_headers_str);
done:
tor_free(fname);
- teardown_capture_of_logs();
+ tor_free(header_lines_v100);
+ tor_free(header_lines_v110_no_terminator);
+ tor_free(header_lines_v110);
+ tor_free(bw_file_headers_str_v100);
+ tor_free(bw_file_headers_str_v110);
+ tor_free(bw_file_headers_str_bad);
+ tor_free(bw_file_headers_str_extra);
}
#define MBWC_INIT_TIME 1000
@@ -1949,7 +2367,7 @@ test_vrs_for_v3ns(vote_routerstatus_t *vrs, int voter, time_t now)
tt_int_op(rs->or_port,OP_EQ, 443);
tt_int_op(rs->dir_port,OP_EQ, 8000);
/* no flags except "running" (16) and "v2dir" (64) and "valid" (128) */
- tt_u64_op(vrs->flags, OP_EQ, U64_LITERAL(0xd0));
+ tt_u64_op(vrs->flags, OP_EQ, UINT64_C(0xd0));
} else if (tor_memeq(rs->identity_digest,
"\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5"
"\x5\x5\x5\x5",
@@ -1975,10 +2393,10 @@ test_vrs_for_v3ns(vote_routerstatus_t *vrs, int voter, time_t now)
tt_int_op(rs->ipv6_orport,OP_EQ, 4711);
if (voter == 1) {
/* all except "authority" (1) */
- tt_u64_op(vrs->flags, OP_EQ, U64_LITERAL(254));
+ tt_u64_op(vrs->flags, OP_EQ, UINT64_C(254));
} else {
/* 1023 - authority(1) - madeofcheese(16) - madeoftin(32) */
- tt_u64_op(vrs->flags, OP_EQ, U64_LITERAL(974));
+ tt_u64_op(vrs->flags, OP_EQ, UINT64_C(974));
}
} else if (tor_memeq(rs->identity_digest,
"\x33\x33\x33\x33\x33\x33\x33\x33\x33\x33"
@@ -2398,7 +2816,7 @@ test_a_networkstatus(
sign_skey_2 = crypto_pk_new();
sign_skey_3 = crypto_pk_new();
sign_skey_leg1 = pk_generate(4);
- dirvote_recalculate_timing(get_options(), now);
+ voting_schedule_recalculate_timing(get_options(), now);
sr_state_init(0, 0);
tt_assert(!crypto_pk_read_private_key_from_string(sign_skey_1,
@@ -2788,8 +3206,8 @@ test_dir_scale_bw(void *testdata)
for (i=0; i<8; ++i) {
total += vals_u64[i];
}
- tt_assert(total >= (U64_LITERAL(1)<<60));
- tt_assert(total <= (U64_LITERAL(1)<<62));
+ tt_assert(total >= (UINT64_C(1)<<60));
+ tt_assert(total <= (UINT64_C(1)<<62));
for (i=0; i<8; ++i) {
/* vals[2].u64 is the scaled value of 1.0 */
@@ -2936,8 +3354,9 @@ gen_routerstatus_for_umbw(int idx, time_t now)
rs->addr = 0x99008801;
rs->or_port = 443;
rs->dir_port = 8000;
- /* all flags but running cleared */
+ /* all flags but running and valid cleared */
rs->is_flagged_running = 1;
+ rs->is_valid = 1;
/*
* This one has measured bandwidth below the clip cutoff, and
* so shouldn't be clipped; we'll have to test that it isn't
@@ -3010,8 +3429,9 @@ gen_routerstatus_for_umbw(int idx, time_t now)
rs->addr = 0xC0000203;
rs->or_port = 500;
rs->dir_port = 1999;
- /* all flags but running cleared */
+ /* all flags but running and valid cleared */
rs->is_flagged_running = 1;
+ rs->is_valid = 1;
/*
* This one has unmeasured bandwidth below the clip cutoff, and
* so shouldn't be clipped; we'll have to test that it isn't
@@ -3033,7 +3453,7 @@ gen_routerstatus_for_umbw(int idx, time_t now)
if (vrs) {
vrs->microdesc = tor_malloc_zero(sizeof(vote_microdesc_hash_t));
tor_asprintf(&vrs->microdesc->microdesc_hash_line,
- "m 9,10,11,12,13,14,15,16,17 "
+ "m 25,26,27,28 "
"sha256=xyzajkldsdsajdadlsdjaslsdksdjlsdjsdaskdaaa%d\n",
idx);
}
@@ -3059,7 +3479,7 @@ vote_tweaks_for_umbw(networkstatus_t *v, int voter, time_t now)
smartlist_clear(v->supported_methods);
/* Method 17 is MIN_METHOD_TO_CLIP_UNMEASURED_BW_KB */
smartlist_split_string(v->supported_methods,
- "1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17",
+ "25 26 27 28",
NULL, 0, -1);
/* If we're using a non-default clip bandwidth, add it to net_params */
if (alternate_clip_bw > 0) {
@@ -3221,9 +3641,9 @@ test_routerstatus_for_umbw(routerstatus_t *rs, time_t now)
tt_assert(!rs->is_fast);
tt_assert(!rs->is_possible_guard);
tt_assert(!rs->is_stable);
- /* (If it wasn't running it wouldn't be here) */
+ /* (If it wasn't running and valid it wouldn't be here) */
tt_assert(rs->is_flagged_running);
- tt_assert(!rs->is_valid);
+ tt_assert(rs->is_valid);
tt_assert(!rs->is_named);
/* This one should have measured bandwidth below the clip cutoff */
tt_assert(rs->has_bandwidth);
@@ -4082,34 +4502,19 @@ test_dir_download_status_increment(void *arg)
DL_WANT_ANY_DIRSERVER,
DL_SCHED_INCREMENT_ATTEMPT,
0, 0 };
- int no_delay = 0;
- int delay0 = -1;
- int delay1 = -1;
- int delay2 = -1;
- smartlist_t *schedule = smartlist_new();
- smartlist_t *schedule_no_initial_delay = smartlist_new();
or_options_t test_options;
time_t current_time = time(NULL);
- /* Provide some values for the schedules */
- delay0 = 10;
- delay1 = 99;
- delay2 = 20;
-
- /* Make the schedules */
- smartlist_add(schedule, (void *)&delay0);
- smartlist_add(schedule, (void *)&delay1);
- smartlist_add(schedule, (void *)&delay2);
-
- smartlist_add(schedule_no_initial_delay, (void *)&no_delay);
- smartlist_add(schedule_no_initial_delay, (void *)&delay1);
- smartlist_add(schedule_no_initial_delay, (void *)&delay2);
+ const int delay0 = 10;
+ const int no_delay = 0;
+ const int schedule = 10;
+ const int schedule_no_initial_delay = 0;
/* Put it in the options */
mock_options = &test_options;
reset_options(mock_options, &mock_get_options_calls);
- mock_options->TestingBridgeBootstrapDownloadSchedule = schedule;
- mock_options->TestingClientDownloadSchedule = schedule;
+ mock_options->TestingBridgeBootstrapDownloadInitialDelay = schedule;
+ mock_options->TestingClientDownloadInitialDelay = schedule;
MOCK(get_options, mock_get_options);
@@ -4117,13 +4522,13 @@ test_dir_download_status_increment(void *arg)
* whether or not it was reset before being used */
/* regression test for 17750: no initial delay */
- mock_options->TestingClientDownloadSchedule = schedule_no_initial_delay;
+ mock_options->TestingClientDownloadInitialDelay = schedule_no_initial_delay;
mock_get_options_calls = 0;
/* we really want to test that it's equal to time(NULL) + delay0, but that's
* an unrealiable test, because time(NULL) might change. */
/* regression test for 17750: exponential, no initial delay */
- mock_options->TestingClientDownloadSchedule = schedule_no_initial_delay;
+ mock_options->TestingClientDownloadInitialDelay = schedule_no_initial_delay;
mock_get_options_calls = 0;
/* we really want to test that it's equal to time(NULL) + delay0, but that's
* an unrealiable test, because time(NULL) might change. */
@@ -4136,7 +4541,7 @@ test_dir_download_status_increment(void *arg)
tt_int_op(mock_get_options_calls, OP_GE, 1);
/* regression test for 17750: exponential, initial delay */
- mock_options->TestingClientDownloadSchedule = schedule;
+ mock_options->TestingClientDownloadInitialDelay = schedule;
mock_get_options_calls = 0;
/* we really want to test that it's equal to time(NULL) + delay0, but that's
* an unrealiable test, because time(NULL) might change. */
@@ -4149,9 +4554,6 @@ test_dir_download_status_increment(void *arg)
tt_int_op(mock_get_options_calls, OP_GE, 1);
done:
- /* the pointers in schedule are allocated on the stack */
- smartlist_free(schedule);
- smartlist_free(schedule_no_initial_delay);
UNMOCK(get_options);
mock_options = NULL;
mock_get_options_calls = 0;
@@ -5469,7 +5871,7 @@ mock_num_bridges_usable(int use_maybe_reachable)
* fallbacks.
*/
static void
-test_dir_find_dl_schedule(void* data)
+test_dir_find_dl_min_delay(void* data)
{
const char *str = (const char *)data;
@@ -5502,44 +5904,45 @@ test_dir_find_dl_schedule(void* data)
mock_num_bridges_usable);
download_status_t dls;
- smartlist_t server, client, server_cons, client_cons;
- smartlist_t client_boot_auth_only_cons, client_boot_auth_cons;
- smartlist_t client_boot_fallback_cons, bridge, bridge_bootstrap;
+
+ const int server=10, client=20, server_cons=30, client_cons=40;
+ const int client_boot_auth_only_cons=50, client_boot_auth_cons=60;
+ const int client_boot_fallback_cons=70, bridge=80, bridge_bootstrap=90;
mock_options = tor_malloc(sizeof(or_options_t));
reset_options(mock_options, &mock_get_options_calls);
MOCK(get_options, mock_get_options);
- mock_options->TestingServerDownloadSchedule = &server;
- mock_options->TestingClientDownloadSchedule = &client;
- mock_options->TestingServerConsensusDownloadSchedule = &server_cons;
- mock_options->TestingClientConsensusDownloadSchedule = &client_cons;
- mock_options->ClientBootstrapConsensusAuthorityOnlyDownloadSchedule =
- &client_boot_auth_only_cons;
- mock_options->ClientBootstrapConsensusAuthorityDownloadSchedule =
- &client_boot_auth_cons;
- mock_options->ClientBootstrapConsensusFallbackDownloadSchedule =
- &client_boot_fallback_cons;
- mock_options->TestingBridgeDownloadSchedule = &bridge;
- mock_options->TestingBridgeBootstrapDownloadSchedule = &bridge_bootstrap;
+ mock_options->TestingServerDownloadInitialDelay = server;
+ mock_options->TestingClientDownloadInitialDelay = client;
+ mock_options->TestingServerConsensusDownloadInitialDelay = server_cons;
+ mock_options->TestingClientConsensusDownloadInitialDelay = client_cons;
+ mock_options->ClientBootstrapConsensusAuthorityOnlyDownloadInitialDelay =
+ client_boot_auth_only_cons;
+ mock_options->ClientBootstrapConsensusAuthorityDownloadInitialDelay =
+ client_boot_auth_cons;
+ mock_options->ClientBootstrapConsensusFallbackDownloadInitialDelay =
+ client_boot_fallback_cons;
+ mock_options->TestingBridgeDownloadInitialDelay = bridge;
+ mock_options->TestingBridgeBootstrapDownloadInitialDelay = bridge_bootstrap;
dls.schedule = DL_SCHED_GENERIC;
/* client */
mock_options->ClientOnly = 1;
- tt_ptr_op(find_dl_schedule(&dls, mock_options), OP_EQ, &client);
+ tt_int_op(find_dl_min_delay(&dls, mock_options), OP_EQ, client);
mock_options->ClientOnly = 0;
/* dir mode */
mock_options->DirPort_set = 1;
mock_options->DirCache = 1;
- tt_ptr_op(find_dl_schedule(&dls, mock_options), OP_EQ, &server);
+ tt_int_op(find_dl_min_delay(&dls, mock_options), OP_EQ, server);
mock_options->DirPort_set = 0;
mock_options->DirCache = 0;
dls.schedule = DL_SCHED_CONSENSUS;
/* public server mode */
mock_options->ORPort_set = 1;
- tt_ptr_op(find_dl_schedule(&dls, mock_options), OP_EQ, &server_cons);
+ tt_int_op(find_dl_min_delay(&dls, mock_options), OP_EQ, server_cons);
mock_options->ORPort_set = 0;
/* client and bridge modes */
@@ -5548,30 +5951,30 @@ test_dir_find_dl_schedule(void* data)
dls.want_authority = 1;
/* client */
mock_options->ClientOnly = 1;
- tt_ptr_op(find_dl_schedule(&dls, mock_options), OP_EQ,
- &client_boot_auth_cons);
+ tt_int_op(find_dl_min_delay(&dls, mock_options), OP_EQ,
+ client_boot_auth_cons);
mock_options->ClientOnly = 0;
/* bridge relay */
mock_options->ORPort_set = 1;
mock_options->BridgeRelay = 1;
- tt_ptr_op(find_dl_schedule(&dls, mock_options), OP_EQ,
- &client_boot_auth_cons);
+ tt_int_op(find_dl_min_delay(&dls, mock_options), OP_EQ,
+ client_boot_auth_cons);
mock_options->ORPort_set = 0;
mock_options->BridgeRelay = 0;
dls.want_authority = 0;
/* client */
mock_options->ClientOnly = 1;
- tt_ptr_op(find_dl_schedule(&dls, mock_options), OP_EQ,
- &client_boot_fallback_cons);
+ tt_int_op(find_dl_min_delay(&dls, mock_options), OP_EQ,
+ client_boot_fallback_cons);
mock_options->ClientOnly = 0;
/* bridge relay */
mock_options->ORPort_set = 1;
mock_options->BridgeRelay = 1;
- tt_ptr_op(find_dl_schedule(&dls, mock_options), OP_EQ,
- &client_boot_fallback_cons);
+ tt_int_op(find_dl_min_delay(&dls, mock_options), OP_EQ,
+ client_boot_fallback_cons);
mock_options->ORPort_set = 0;
mock_options->BridgeRelay = 0;
@@ -5579,30 +5982,30 @@ test_dir_find_dl_schedule(void* data)
/* dls.want_authority is ignored */
/* client */
mock_options->ClientOnly = 1;
- tt_ptr_op(find_dl_schedule(&dls, mock_options), OP_EQ,
- &client_boot_auth_only_cons);
+ tt_int_op(find_dl_min_delay(&dls, mock_options), OP_EQ,
+ client_boot_auth_only_cons);
mock_options->ClientOnly = 0;
/* bridge relay */
mock_options->ORPort_set = 1;
mock_options->BridgeRelay = 1;
- tt_ptr_op(find_dl_schedule(&dls, mock_options), OP_EQ,
- &client_boot_auth_only_cons);
+ tt_int_op(find_dl_min_delay(&dls, mock_options), OP_EQ,
+ client_boot_auth_only_cons);
mock_options->ORPort_set = 0;
mock_options->BridgeRelay = 0;
}
} else {
/* client */
mock_options->ClientOnly = 1;
- tt_ptr_op(find_dl_schedule(&dls, mock_options), OP_EQ,
- &client_cons);
+ tt_int_op(find_dl_min_delay(&dls, mock_options), OP_EQ,
+ client_cons);
mock_options->ClientOnly = 0;
/* bridge relay */
mock_options->ORPort_set = 1;
mock_options->BridgeRelay = 1;
- tt_ptr_op(find_dl_schedule(&dls, mock_options), OP_EQ,
- &client_cons);
+ tt_int_op(find_dl_min_delay(&dls, mock_options), OP_EQ,
+ client_cons);
mock_options->ORPort_set = 0;
mock_options->BridgeRelay = 0;
}
@@ -5612,9 +6015,9 @@ test_dir_find_dl_schedule(void* data)
mock_options->ClientOnly = 1;
mock_options->UseBridges = 1;
if (num_bridges_usable(0) > 0) {
- tt_ptr_op(find_dl_schedule(&dls, mock_options), OP_EQ, &bridge);
+ tt_int_op(find_dl_min_delay(&dls, mock_options), OP_EQ, bridge);
} else {
- tt_ptr_op(find_dl_schedule(&dls, mock_options), OP_EQ, &bridge_bootstrap);
+ tt_int_op(find_dl_min_delay(&dls, mock_options), OP_EQ, bridge_bootstrap);
}
done:
@@ -5634,9 +6037,8 @@ test_dir_assumed_flags(void *arg)
memarea_t *area = memarea_new();
routerstatus_t *rs = NULL;
- /* First, we should always assume that the Running flag is set, even
- * when it isn't listed, since the consensus method is always
- * higher than 4. */
+ /* We can assume that consensus method is higher than 24, so Running and
+ * Valid are always implicitly set */
const char *str1 =
"r example hereiswhereyouridentitygoes 2015-08-30 12:00:00 "
"192.168.0.1 9001 0\n"
@@ -5645,17 +6047,6 @@ test_dir_assumed_flags(void *arg)
const char *cp = str1;
rs = routerstatus_parse_entry_from_string(area, &cp, tokens, NULL, NULL,
- 23, FLAV_MICRODESC);
- tt_assert(rs);
- tt_assert(rs->is_flagged_running);
- tt_assert(! rs->is_valid);
- tt_assert(! rs->is_exit);
- tt_assert(rs->is_fast);
- routerstatus_free(rs);
-
- /* With method 24 or later, we can assume "valid" is set. */
- cp = str1;
- rs = routerstatus_parse_entry_from_string(area, &cp, tokens, NULL, NULL,
24, FLAV_MICRODESC);
tt_assert(rs);
tt_assert(rs->is_flagged_running);
@@ -5788,22 +6179,10 @@ test_dir_networkstatus_consensus_has_ipv6(void *arg)
/* Test the bounds for A lines in the NS consensus */
mock_options->UseMicrodescriptors = 0;
- mock_networkstatus->consensus_method = MIN_METHOD_FOR_A_LINES;
+ mock_networkstatus->consensus_method = MIN_SUPPORTED_CONSENSUS_METHOD;
has_ipv6 = networkstatus_consensus_has_ipv6(get_options());
tt_assert(has_ipv6);
- mock_networkstatus->consensus_method = MIN_METHOD_FOR_A_LINES + 1;
- has_ipv6 = networkstatus_consensus_has_ipv6(get_options());
- tt_assert(has_ipv6);
-
- mock_networkstatus->consensus_method = MIN_METHOD_FOR_A_LINES + 20;
- has_ipv6 = networkstatus_consensus_has_ipv6(get_options());
- tt_assert(has_ipv6);
-
- mock_networkstatus->consensus_method = MIN_METHOD_FOR_A_LINES - 1;
- has_ipv6 = networkstatus_consensus_has_ipv6(get_options());
- tt_assert(!has_ipv6);
-
/* Test the bounds for A lines in the microdesc consensus */
mock_options->UseMicrodescriptors = 1;
@@ -5812,6 +6191,10 @@ test_dir_networkstatus_consensus_has_ipv6(void *arg)
has_ipv6 = networkstatus_consensus_has_ipv6(get_options());
tt_assert(has_ipv6);
+ mock_networkstatus->consensus_method = MAX_SUPPORTED_CONSENSUS_METHOD + 20;
+ has_ipv6 = networkstatus_consensus_has_ipv6(get_options());
+ tt_assert(has_ipv6);
+
mock_networkstatus->consensus_method =
MIN_METHOD_FOR_A_LINES_IN_MICRODESC_CONSENSUS + 1;
has_ipv6 = networkstatus_consensus_has_ipv6(get_options());
@@ -5926,9 +6309,10 @@ struct testcase_t dir_tests[] = {
DIR_LEGACY(versions),
DIR_LEGACY(fp_pairs),
DIR(split_fps, 0),
- DIR_LEGACY(dirserv_read_measured_bandwidths),
DIR_LEGACY(measured_bw_kb),
+ DIR_LEGACY(measured_bw_kb_line_is_after_headers),
DIR_LEGACY(measured_bw_kb_cache),
+ DIR_LEGACY(dirserv_read_measured_bandwidths),
DIR_LEGACY(param_voting),
DIR(param_voting_lookup, 0),
DIR_LEGACY(v3_networkstatus),
@@ -5960,14 +6344,14 @@ struct testcase_t dir_tests[] = {
DIR(dump_unparseable_descriptors, 0),
DIR(populate_dump_desc_fifo, 0),
DIR(populate_dump_desc_fifo_2, 0),
- DIR_ARG(find_dl_schedule, TT_FORK, "bfd"),
- DIR_ARG(find_dl_schedule, TT_FORK, "bad"),
- DIR_ARG(find_dl_schedule, TT_FORK, "cfd"),
- DIR_ARG(find_dl_schedule, TT_FORK, "cad"),
- DIR_ARG(find_dl_schedule, TT_FORK, "bfr"),
- DIR_ARG(find_dl_schedule, TT_FORK, "bar"),
- DIR_ARG(find_dl_schedule, TT_FORK, "cfr"),
- DIR_ARG(find_dl_schedule, TT_FORK, "car"),
+ DIR_ARG(find_dl_min_delay, TT_FORK, "bfd"),
+ DIR_ARG(find_dl_min_delay, TT_FORK, "bad"),
+ DIR_ARG(find_dl_min_delay, TT_FORK, "cfd"),
+ DIR_ARG(find_dl_min_delay, TT_FORK, "cad"),
+ DIR_ARG(find_dl_min_delay, TT_FORK, "bfr"),
+ DIR_ARG(find_dl_min_delay, TT_FORK, "bar"),
+ DIR_ARG(find_dl_min_delay, TT_FORK, "cfr"),
+ DIR_ARG(find_dl_min_delay, TT_FORK, "car"),
DIR(assumed_flags, 0),
DIR(networkstatus_compute_bw_weights_v10, 0),
DIR(platform_str, 0),
diff --git a/src/test/test_dir_common.c b/src/test/test_dir_common.c
index fdf43533a8..86d2838944 100644
--- a/src/test/test_dir_common.c
+++ b/src/test/test_dir_common.c
@@ -1,18 +1,26 @@
/* Copyright (c) 2001-2004, Roger Dingledine.
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2017, The Tor Project, Inc. */
+ * Copyright (c) 2007-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
#include "orconfig.h"
#define DIRVOTE_PRIVATE
-#include "crypto.h"
-#include "test.h"
-#include "container.h"
-#include "or.h"
-#include "dirvote.h"
-#include "nodelist.h"
-#include "routerlist.h"
-#include "test_dir_common.h"
+#include "test/test.h"
+#include "core/or/or.h"
+#include "feature/dirauth/dirvote.h"
+#include "feature/nodelist/nodelist.h"
+#include "feature/nodelist/routerlist.h"
+#include "feature/dirparse/authcert_parse.h"
+#include "feature/dirparse/ns_parse.h"
+#include "test/test_dir_common.h"
+#include "feature/dircommon/voting_schedule.h"
+
+#include "feature/nodelist/authority_cert_st.h"
+#include "feature/nodelist/networkstatus_st.h"
+#include "feature/nodelist/networkstatus_voter_info_st.h"
+#include "feature/nodelist/routerinfo_st.h"
+#include "feature/dirauth/vote_microdesc_hash_st.h"
+#include "feature/nodelist/vote_routerstatus_st.h"
void dir_common_setup_vote(networkstatus_t **vote, time_t now);
networkstatus_t * dir_common_add_rs_and_parse(networkstatus_t *vote,
diff --git a/src/test/test_dir_common.h b/src/test/test_dir_common.h
index 65b9cf6436..1e958a21ff 100644
--- a/src/test/test_dir_common.h
+++ b/src/test/test_dir_common.h
@@ -1,11 +1,10 @@
/* Copyright (c) 2001-2004, Roger Dingledine.
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2017, The Tor Project, Inc. */
+ * Copyright (c) 2007-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
-#include "or.h"
-#include "networkstatus.h"
-#include "routerparse.h"
+#include "core/or/or.h"
+#include "feature/nodelist/networkstatus.h"
#define TEST_DIR_ROUTER_ID_1 3
#define TEST_DIR_ROUTER_ID_2 5
diff --git a/src/test/test_dir_handle_get.c b/src/test/test_dir_handle_get.c
index ca64dce5fe..1d4a36d7fc 100644
--- a/src/test/test_dir_handle_get.c
+++ b/src/test/test_dir_handle_get.c
@@ -1,6 +1,6 @@
/* Copyright (c) 2001-2004, Roger Dingledine.
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2017, The Tor Project, Inc. */
+ * Copyright (c) 2007-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
#define RENDCOMMON_PRIVATE
@@ -8,31 +8,43 @@
#define CONNECTION_PRIVATE
#define CONFIG_PRIVATE
#define RENDCACHE_PRIVATE
-
-#include "or.h"
-#include "config.h"
-#include "connection.h"
-#include "consdiffmgr.h"
-#include "directory.h"
-#include "test.h"
-#include "compress.h"
-#include "connection.h"
-#include "rendcommon.h"
-#include "rendcache.h"
-#include "router.h"
-#include "routerlist.h"
-#include "rend_test_helpers.h"
-#include "microdesc.h"
-#include "test_helpers.h"
-#include "nodelist.h"
-#include "entrynodes.h"
-#include "routerparse.h"
-#include "networkstatus.h"
-#include "proto_http.h"
-#include "geoip.h"
-#include "dirserv.h"
-#include "dirvote.h"
-#include "log_test_helpers.h"
+#define DIRCACHE_PRIVATE
+
+#include "core/or/or.h"
+#include "app/config/config.h"
+#include "core/mainloop/connection.h"
+#include "feature/dircache/consdiffmgr.h"
+#include "feature/dircommon/directory.h"
+#include "feature/dircache/dircache.h"
+#include "test/test.h"
+#include "lib/compress/compress.h"
+#include "feature/rend/rendcommon.h"
+#include "feature/rend/rendcache.h"
+#include "feature/relay/router.h"
+#include "feature/nodelist/authcert.h"
+#include "feature/nodelist/dirlist.h"
+#include "feature/nodelist/routerlist.h"
+#include "test/rend_test_helpers.h"
+#include "feature/nodelist/microdesc.h"
+#include "test/test_helpers.h"
+#include "feature/nodelist/nodelist.h"
+#include "feature/client/entrynodes.h"
+#include "feature/dirparse/authcert_parse.h"
+#include "feature/nodelist/networkstatus.h"
+#include "core/proto/proto_http.h"
+#include "lib/geoip/geoip.h"
+#include "feature/stats/geoip_stats.h"
+#include "feature/dircache/dirserv.h"
+#include "feature/dirauth/dirvote.h"
+#include "test/log_test_helpers.h"
+#include "feature/dircommon/voting_schedule.h"
+
+#include "feature/dircommon/dir_connection_st.h"
+#include "feature/dirclient/dir_server_st.h"
+#include "feature/nodelist/networkstatus_st.h"
+#include "feature/rend/rend_encoded_v2_service_descriptor_st.h"
+#include "feature/nodelist/routerinfo_st.h"
+#include "feature/nodelist/routerlist_st.h"
#ifdef _WIN32
/* For mkdir() */
@@ -2057,7 +2069,7 @@ test_dir_handle_get_status_vote_d(void* data)
mock_options->TestingV3AuthInitialDistDelay = 1;
time_t now = 1441223455 -1;
- dirvote_recalculate_timing(mock_options, now);
+ voting_schedule_recalculate_timing(mock_options, now);
const char *msg_out = NULL;
int status_out = 0;
@@ -2095,6 +2107,7 @@ test_dir_handle_get_status_vote_d(void* data)
clear_dir_servers();
dirvote_free_all();
+ routerlist_free_all();
}
static void
@@ -2403,7 +2416,7 @@ test_dir_handle_get_status_vote_next_authority(void* data)
mock_options->TestingV3AuthInitialDistDelay = 1;
time_t now = 1441223455 -1;
- dirvote_recalculate_timing(mock_options, now);
+ voting_schedule_recalculate_timing(mock_options, now);
struct pending_vote_t *vote = dirvote_add_vote(VOTE_BODY_V3, &msg_out,
&status_out);
@@ -2482,7 +2495,7 @@ test_dir_handle_get_status_vote_current_authority(void* data)
mock_options->TestingV3AuthInitialDistDelay = 1;
time_t now = 1441223455;
- dirvote_recalculate_timing(mock_options, now-1);
+ voting_schedule_recalculate_timing(mock_options, now-1);
struct pending_vote_t *vote = dirvote_add_vote(VOTE_BODY_V3, &msg_out,
&status_out);
@@ -2631,4 +2644,3 @@ struct testcase_t dir_handle_get_tests[] = {
DIR_HANDLE_CMD(parse_accept_encoding, 0),
END_OF_TESTCASES
};
-
diff --git a/src/test/test_dns.c b/src/test/test_dns.c
index 1fee01d2c0..8369f844f6 100644
--- a/src/test/test_dns.c
+++ b/src/test/test_dns.c
@@ -1,14 +1,18 @@
-/* Copyright (c) 2015-2017, The Tor Project, Inc. */
+/* Copyright (c) 2015-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
-#include "or.h"
-#include "test.h"
+#include "core/or/or.h"
+#include "test/test.h"
#define DNS_PRIVATE
-#include "dns.h"
-#include "connection.h"
-#include "router.h"
+#include "feature/relay/dns.h"
+#include "core/mainloop/connection.h"
+#include "core/or/connection_edge.h"
+#include "feature/relay/router.h"
+
+#include "core/or/edge_connection_st.h"
+#include "core/or/or_circuit_st.h"
#define NS_MODULE dns
@@ -745,4 +749,3 @@ struct testcase_t dns_tests[] = {
};
#undef NS_MODULE
-
diff --git a/src/test/test_dos.c b/src/test/test_dos.c
index cb9d9e559c..40a4c6ba29 100644
--- a/src/test/test_dos.c
+++ b/src/test/test_dos.c
@@ -5,17 +5,23 @@
#define TOR_CHANNEL_INTERNAL_
#define CIRCUITLIST_PRIVATE
-#include "or.h"
-#include "dos.h"
-#include "circuitlist.h"
-#include "geoip.h"
-#include "channel.h"
-#include "microdesc.h"
-#include "networkstatus.h"
-#include "nodelist.h"
-#include "routerlist.h"
-#include "test.h"
-#include "log_test_helpers.h"
+#include "core/or/or.h"
+#include "core/or/dos.h"
+#include "core/or/circuitlist.h"
+#include "lib/crypt_ops/crypto_rand.h"
+#include "feature/stats/geoip_stats.h"
+#include "core/or/channel.h"
+#include "feature/nodelist/microdesc.h"
+#include "feature/nodelist/networkstatus.h"
+#include "feature/nodelist/nodelist.h"
+#include "feature/nodelist/routerlist.h"
+
+#include "feature/nodelist/networkstatus_st.h"
+#include "core/or/or_connection_st.h"
+#include "feature/nodelist/routerstatus_st.h"
+
+#include "test/test.h"
+#include "test/log_test_helpers.h"
static networkstatus_t *dummy_ns = NULL;
static networkstatus_t *
@@ -494,4 +500,3 @@ struct testcase_t dos_tests[] = {
NULL, NULL },
END_OF_TESTCASES
};
-
diff --git a/src/test/test_entryconn.c b/src/test/test_entryconn.c
index 9d8a072c77..bec70090e6 100644
--- a/src/test/test_entryconn.c
+++ b/src/test/test_entryconn.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014-2017, The Tor Project, Inc. */
+/* Copyright (c) 2014-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
#include "orconfig.h"
@@ -6,18 +6,23 @@
#define CONNECTION_PRIVATE
#define CONNECTION_EDGE_PRIVATE
-#include "or.h"
-#include "test.h"
+#include "core/or/or.h"
+#include "test/test.h"
-#include "addressmap.h"
-#include "config.h"
-#include "confparse.h"
-#include "connection.h"
-#include "connection_edge.h"
-#include "nodelist.h"
+#include "feature/client/addressmap.h"
+#include "app/config/config.h"
+#include "app/config/confparse.h"
+#include "core/mainloop/connection.h"
+#include "core/or/connection_edge.h"
+#include "feature/nodelist/nodelist.h"
-#include "hs_cache.h"
-#include "rendcache.h"
+#include "feature/hs/hs_cache.h"
+#include "feature/rend/rendcache.h"
+
+#include "core/or/entry_connection_st.h"
+#include "core/or/socks_request_st.h"
+
+#include "lib/encoding/confline.h"
static void *
entryconn_rewrite_setup(const struct testcase_t *tc)
@@ -830,4 +835,3 @@ struct testcase_t entryconn_tests[] = {
END_OF_TESTCASES
};
-
diff --git a/src/test/test_entrynodes.c b/src/test/test_entrynodes.c
index 505e09e36f..b67c9fae53 100644
--- a/src/test/test_entrynodes.c
+++ b/src/test/test_entrynodes.c
@@ -1,34 +1,50 @@
-/* Copyright (c) 2014-2017, The Tor Project, Inc. */
+/* Copyright (c) 2014-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
#include "orconfig.h"
#define CIRCUITLIST_PRIVATE
+#define CIRCUITBUILD_PRIVATE
#define STATEFILE_PRIVATE
#define ENTRYNODES_PRIVATE
#define ROUTERLIST_PRIVATE
-#define DIRECTORY_PRIVATE
-
-#include "or.h"
-#include "test.h"
-
-#include "bridges.h"
-#include "circuitlist.h"
-#include "config.h"
-#include "confparse.h"
-#include "directory.h"
-#include "entrynodes.h"
-#include "nodelist.h"
-#include "networkstatus.h"
-#include "policies.h"
-#include "routerlist.h"
-#include "routerparse.h"
-#include "routerset.h"
-#include "statefile.h"
-#include "util.h"
-
-#include "test_helpers.h"
-#include "log_test_helpers.h"
+#define DIRCLIENT_PRIVATE
+
+#include "core/or/or.h"
+#include "test/test.h"
+
+#include "feature/client/bridges.h"
+#include "core/or/circuitlist.h"
+#include "core/or/circuitbuild.h"
+#include "app/config/config.h"
+#include "app/config/confparse.h"
+#include "lib/crypt_ops/crypto_rand.h"
+#include "feature/dircommon/directory.h"
+#include "feature/dirclient/dirclient.h"
+#include "feature/client/entrynodes.h"
+#include "feature/nodelist/nodelist.h"
+#include "feature/nodelist/networkstatus.h"
+#include "core/or/policies.h"
+#include "feature/nodelist/routerlist.h"
+#include "feature/nodelist/routerset.h"
+#include "app/config/statefile.h"
+
+#include "core/or/cpath_build_state_st.h"
+#include "core/or/crypt_path_st.h"
+#include "feature/dircommon/dir_connection_st.h"
+#include "feature/nodelist/microdesc_st.h"
+#include "feature/nodelist/networkstatus_st.h"
+#include "feature/nodelist/node_st.h"
+#include "core/or/origin_circuit_st.h"
+#include "app/config/or_state_st.h"
+#include "feature/nodelist/routerinfo_st.h"
+#include "feature/nodelist/routerstatus_st.h"
+
+#include "test/test_helpers.h"
+#include "test/log_test_helpers.h"
+
+#include "lib/container/bloomfilt.h"
+#include "lib/encoding/confline.h"
/* TODO:
* choose_random_entry() test with state set.
@@ -74,6 +90,17 @@ bfn_mock_node_get_by_id(const char *id)
return NULL;
}
+/* Helper function to free a test node. */
+static void
+test_node_free(node_t *n)
+{
+ tor_free(n->rs);
+ tor_free(n->md->onion_curve25519_pkey);
+ short_policy_free(n->md->exit_policy);
+ tor_free(n->md);
+ tor_free(n);
+}
+
/* Unittest cleanup function: Cleanup the fake network. */
static int
big_fake_network_cleanup(const struct testcase_t *testcase, void *ptr)
@@ -83,9 +110,7 @@ big_fake_network_cleanup(const struct testcase_t *testcase, void *ptr)
if (big_fake_net_nodes) {
SMARTLIST_FOREACH(big_fake_net_nodes, node_t *, n, {
- tor_free(n->rs);
- tor_free(n->md);
- tor_free(n);
+ test_node_free(n);
});
smartlist_free(big_fake_net_nodes);
}
@@ -113,9 +138,18 @@ big_fake_network_setup(const struct testcase_t *testcase)
big_fake_net_nodes = smartlist_new();
for (i = 0; i < N_NODES; ++i) {
+ curve25519_secret_key_t curve25519_secret_key;
+
node_t *n = tor_malloc_zero(sizeof(node_t));
n->md = tor_malloc_zero(sizeof(microdesc_t));
+ /* Generate curve25519 key for this node */
+ n->md->onion_curve25519_pkey =
+ tor_malloc_zero(sizeof(curve25519_public_key_t));
+ curve25519_secret_key_generate(&curve25519_secret_key, 0);
+ curve25519_public_key_generate(n->md->onion_curve25519_pkey,
+ &curve25519_secret_key);
+
crypto_rand(n->identity, sizeof(n->identity));
n->rs = tor_malloc_zero(sizeof(routerstatus_t));
@@ -135,8 +169,8 @@ big_fake_network_setup(const struct testcase_t *testcase)
{
char nickname_binary[8];
crypto_rand(nickname_binary, sizeof(nickname_binary));
- base64_encode(n->rs->nickname, sizeof(n->rs->nickname),
- nickname_binary, sizeof(nickname_binary), 0);
+ base32_encode(n->rs->nickname, sizeof(n->rs->nickname),
+ nickname_binary, sizeof(nickname_binary));
}
/* Call half of the nodes a possible guard. */
@@ -144,6 +178,12 @@ big_fake_network_setup(const struct testcase_t *testcase)
n->is_possible_guard = 1;
n->rs->guardfraction_percentage = 100;
n->rs->has_guardfraction = 1;
+ n->rs->is_possible_guard = 1;
+ }
+
+ /* Make some of these nodes a possible exit */
+ if (i % 7 == 0) {
+ n->md->exit_policy = parse_short_policy("accept 443");
}
smartlist_add(big_fake_net_nodes, n);
@@ -1075,9 +1115,7 @@ test_entry_guard_expand_sample_small_net(void *arg)
/* Fun corner case: not enough guards to make up our whole sample size. */
SMARTLIST_FOREACH(big_fake_net_nodes, node_t *, n, {
if (n_sl_idx >= 15) {
- tor_free(n->rs);
- tor_free(n->md);
- tor_free(n);
+ test_node_free(n);
SMARTLIST_DEL_CURRENT(big_fake_net_nodes, n);
} else {
n->rs->addr = 0; // make the filter reject this.
@@ -1174,9 +1212,7 @@ test_entry_guard_update_from_consensus_status(void *arg)
node_t *n = (node_t*) bfn_mock_node_get_by_id(g->identity);
tt_assert(n);
smartlist_remove(big_fake_net_nodes, n);
- tor_free(n->rs);
- tor_free(n->md);
- tor_free(n);
+ test_node_free(n);
}
update_approx_time(start + 300);
sampled_guards_update_from_consensus(gs);
@@ -2685,6 +2721,23 @@ test_enty_guard_should_expire_waiting(void *arg)
tor_free(fake_state);
}
+/** Test that the number of primary guards can be controlled using torrc */
+static void
+test_entry_guard_number_of_primaries(void *arg)
+{
+ (void) arg;
+
+ /* Get default value */
+ tt_int_op(get_n_primary_guards(), OP_EQ, DFLT_N_PRIMARY_GUARDS);
+
+ /* Set number of primaries using torrc */
+ get_options_mutable()->NumPrimaryGuards = 42;
+ tt_int_op(get_n_primary_guards(), OP_EQ, 42);
+
+ done:
+ ;
+}
+
static void
mock_directory_initiate_request(directory_request_t *req)
{
@@ -2793,6 +2846,161 @@ test_entry_guard_outdated_dirserver_exclusion(void *arg)
}
}
+/** Test helper to extend the <b>oc</b> circuit path <b>n</b> times and then
+ * ensure that the circuit is now complete. */
+static void
+helper_extend_circuit_path_n_times(origin_circuit_t *oc, int n)
+{
+ int retval;
+ int i;
+
+ /* Extend path n times */
+ for (i = 0 ; i < n ; i++) {
+ retval = onion_extend_cpath(oc);
+ tt_int_op(retval, OP_EQ, 0);
+ tt_int_op(circuit_get_cpath_len(oc), OP_EQ, i+1);
+ }
+
+ /* Now do it one last time and see that circ is complete */
+ retval = onion_extend_cpath(oc);
+ tt_int_op(retval, OP_EQ, 1);
+
+ done:
+ ;
+}
+
+/** Test for basic Tor path selection. Makes sure we build 3-hop circuits. */
+static void
+test_entry_guard_basic_path_selection(void *arg)
+{
+ (void) arg;
+
+ int retval;
+
+ /* Enable entry guards */
+ or_options_t *options = get_options_mutable();
+ options->UseEntryGuards = 1;
+
+ /* disables /16 check since all nodes have the same addr... */
+ options->EnforceDistinctSubnets = 0;
+
+ /* Create our circuit */
+ circuit_t *circ = dummy_origin_circuit_new(30);
+ origin_circuit_t *oc = TO_ORIGIN_CIRCUIT(circ);
+ oc->build_state = tor_malloc_zero(sizeof(cpath_build_state_t));
+
+ /* First pick the exit and pin it on the build_state */
+ retval = onion_pick_cpath_exit(oc, NULL, 0);
+ tt_int_op(retval, OP_EQ, 0);
+
+ /* Extend path 3 times. First we pick guard, then middle, then exit. */
+ helper_extend_circuit_path_n_times(oc, 3);
+
+ done:
+ circuit_free_(circ);
+}
+
+/** Test helper to build an L2 and L3 vanguard list. The vanguard lists
+ * produced should be completely disjoint. */
+static void
+helper_setup_vanguard_list(or_options_t *options)
+{
+ int i = 0;
+
+ /* Add some nodes to the vanguard L2 list */
+ options->HSLayer2Nodes = routerset_new();
+ for (i = 0; i < 10 ; i += 2) {
+ node_t *vanguard_node = smartlist_get(big_fake_net_nodes, i);
+ tt_assert(vanguard_node->is_possible_guard);
+ routerset_parse(options->HSLayer2Nodes, vanguard_node->rs->nickname, "l2");
+ }
+ /* also add some nodes to vanguard L3 list
+ * (L2 list and L3 list should be disjoint for this test to work) */
+ options->HSLayer3Nodes = routerset_new();
+ for (i = 10; i < 20 ; i += 2) {
+ node_t *vanguard_node = smartlist_get(big_fake_net_nodes, i);
+ tt_assert(vanguard_node->is_possible_guard);
+ routerset_parse(options->HSLayer3Nodes, vanguard_node->rs->nickname, "l3");
+ }
+
+ done:
+ ;
+}
+
+/** Test to ensure that vanguard path selection works properly. Ensures that
+ * default vanguard circuits are 4 hops, and that path selection works
+ * correctly given the vanguard settings. */
+static void
+test_entry_guard_vanguard_path_selection(void *arg)
+{
+ (void) arg;
+
+ int retval;
+
+ /* Enable entry guards */
+ or_options_t *options = get_options_mutable();
+ options->UseEntryGuards = 1;
+
+ /* XXX disables /16 check */
+ options->EnforceDistinctSubnets = 0;
+
+ /* Setup our vanguard list */
+ helper_setup_vanguard_list(options);
+
+ /* Create our circuit */
+ circuit_t *circ = dummy_origin_circuit_new(30);
+ origin_circuit_t *oc = TO_ORIGIN_CIRCUIT(circ);
+ oc->build_state = tor_malloc_zero(sizeof(cpath_build_state_t));
+ oc->build_state->is_internal = 1;
+
+ /* Switch circuit purpose to vanguards */
+ circ->purpose = CIRCUIT_PURPOSE_HS_VANGUARDS;
+
+ /* First pick the exit and pin it on the build_state */
+ tt_int_op(oc->build_state->desired_path_len, OP_EQ, 0);
+ retval = onion_pick_cpath_exit(oc, NULL, 0);
+ tt_int_op(retval, OP_EQ, 0);
+
+ /* Ensure that vanguards make 4-hop circuits by default */
+ tt_int_op(oc->build_state->desired_path_len, OP_EQ, 4);
+
+ /* Extend path as many times as needed to have complete circ. */
+ helper_extend_circuit_path_n_times(oc, oc->build_state->desired_path_len);
+
+ /* Test that the cpath linked list is set correctly. */
+ crypt_path_t *l1_node = oc->cpath;
+ crypt_path_t *l2_node = l1_node->next;
+ crypt_path_t *l3_node = l2_node->next;
+ crypt_path_t *l4_node = l3_node->next;
+ crypt_path_t *l1_node_again = l4_node->next;
+ tt_ptr_op(l1_node, OP_EQ, l1_node_again);
+
+ /* Test that L2 is indeed HSLayer2Node */
+ retval = routerset_contains_extendinfo(options->HSLayer2Nodes,
+ l2_node->extend_info);
+ tt_int_op(retval, OP_EQ, 4);
+ /* test that L3 node is _not_ contained in HSLayer2Node */
+ retval = routerset_contains_extendinfo(options->HSLayer2Nodes,
+ l3_node->extend_info);
+ tt_int_op(retval, OP_LT, 4);
+
+ /* Test that L3 is indeed HSLayer3Node */
+ retval = routerset_contains_extendinfo(options->HSLayer3Nodes,
+ l3_node->extend_info);
+ tt_int_op(retval, OP_EQ, 4);
+ /* test that L2 node is _not_ contained in HSLayer3Node */
+ retval = routerset_contains_extendinfo(options->HSLayer3Nodes,
+ l2_node->extend_info);
+ tt_int_op(retval, OP_LT, 4);
+
+ /* TODO: Test that L1 can be the same as exit. To test this we need start
+ enforcing EnforceDistinctSubnets again, which means that we need to give
+ each test node a different address which currently breaks some tests. */
+
+ done:
+ circuit_free_(circ);
+}
+
static const struct testcase_setup_t big_fake_network = {
big_fake_network_setup, big_fake_network_cleanup
};
@@ -2832,6 +3040,8 @@ struct testcase_t entrynodes_tests[] = {
test_entry_guard_parse_from_state_broken, TT_FORK, NULL, NULL },
{ "get_guard_selection_by_name",
test_entry_guard_get_guard_selection_by_name, TT_FORK, NULL, NULL },
+ { "number_of_primaries",
+ test_entry_guard_number_of_primaries, TT_FORK, NULL, NULL },
BFN_TEST(choose_selection_initial),
BFN_TEST(add_single_guard),
BFN_TEST(node_filter),
@@ -2854,6 +3064,8 @@ struct testcase_t entrynodes_tests[] = {
BFN_TEST(select_and_cancel),
BFN_TEST(drop_guards),
BFN_TEST(outdated_dirserver_exclusion),
+ BFN_TEST(basic_path_selection),
+ BFN_TEST(vanguard_path_selection),
UPGRADE_TEST(upgrade_a_circuit, "c1-done c2-done"),
UPGRADE_TEST(upgrade_blocked_by_live_primary_guards, "c1-done c2-done"),
@@ -2871,4 +3083,3 @@ struct testcase_t entrynodes_tests[] = {
END_OF_TESTCASES
};
-
diff --git a/src/test/test_extorport.c b/src/test/test_extorport.c
index cadef257f1..71be9131c7 100644
--- a/src/test/test_extorport.c
+++ b/src/test/test_extorport.c
@@ -1,18 +1,27 @@
-/* Copyright (c) 2013-2017, The Tor Project, Inc. */
+/* Copyright (c) 2013-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
#define CONNECTION_PRIVATE
#define EXT_ORPORT_PRIVATE
-#define MAIN_PRIVATE
-#include "or.h"
-#include "buffers.h"
-#include "connection.h"
-#include "connection_or.h"
-#include "config.h"
-#include "control.h"
-#include "ext_orport.h"
-#include "main.h"
-#include "test.h"
+#define MAINLOOP_PRIVATE
+#include "core/or/or.h"
+#include "lib/container/buffers.h"
+#include "core/mainloop/connection.h"
+#include "core/or/connection_or.h"
+#include "app/config/config.h"
+#include "feature/control/control.h"
+#include "lib/crypt_ops/crypto_rand.h"
+#include "feature/relay/ext_orport.h"
+#include "core/mainloop/mainloop.h"
+
+#include "core/or/or_connection_st.h"
+
+#include "test/test.h"
+#include "test/test_helpers.h"
+
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
/* Test connection_or_remove_from_ext_or_id_map and
* connection_or_set_ext_or_identifier */
@@ -81,22 +90,6 @@ connection_write_to_buf_impl_replacement(const char *string, size_t len,
buf_add(conn->outbuf, string, len);
}
-static char *
-buf_get_contents(buf_t *buf, size_t *sz_out)
-{
- char *out;
- *sz_out = buf_datalen(buf);
- if (*sz_out >= ULONG_MAX)
- return NULL; /* C'mon, really? */
- out = tor_malloc(*sz_out + 1);
- if (buf_get_bytes(buf, out, (unsigned long)*sz_out) != 0) {
- tor_free(out);
- return NULL;
- }
- out[*sz_out] = '\0'; /* Hopefully gratuitous. */
- return out;
-}
-
static void
test_ext_or_write_command(void *arg)
{
@@ -455,7 +448,7 @@ test_ext_or_handshake(void *arg)
memcpy(ext_or_auth_cookie, "Gliding wrapt in a brown mantle," , 32);
ext_or_auth_cookie_is_set = 1;
- init_connection_lists();
+ tor_init_connection_lists();
conn = or_connection_new(CONN_TYPE_EXT_OR, AF_INET);
tt_int_op(0, OP_EQ, connection_ext_or_start_auth(conn));
@@ -606,4 +599,3 @@ struct testcase_t extorport_tests[] = {
{ "handshake", test_ext_or_handshake, TT_FORK, NULL, NULL },
END_OF_TESTCASES
};
-
diff --git a/src/test/test_geoip.c b/src/test/test_geoip.c
new file mode 100644
index 0000000000..6f9c39063b
--- /dev/null
+++ b/src/test/test_geoip.c
@@ -0,0 +1,580 @@
+/* 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 "orconfig.h"
+
+/* These macros pull in declarations for some functions and structures that
+ * are typically file-private. */
+#define GEOIP_PRIVATE
+#include "core/or/or.h"
+#include "app/config/config.h"
+#include "lib/geoip/geoip.h"
+#include "feature/stats/geoip_stats.h"
+#include "test/test.h"
+
+ /* Record odd numbered fake-IPs using ipv6, even numbered fake-IPs
+ * using ipv4. Since our fake geoip database is the same between
+ * ipv4 and ipv6, we should get the same result no matter which
+ * address family we pick for each IP. */
+#define SET_TEST_ADDRESS(i) do { \
+ if ((i) & 1) { \
+ SET_TEST_IPV6(i); \
+ tor_addr_from_in6(&addr, &in6); \
+ } else { \
+ tor_addr_from_ipv4h(&addr, (uint32_t) i); \
+ } \
+ } while (0)
+
+ /* Make sure that country ID actually works. */
+#define SET_TEST_IPV6(i) \
+ do { \
+ set_uint32(in6.s6_addr + 12, htonl((uint32_t) (i))); \
+ } while (0)
+#define CHECK_COUNTRY(country, val) do { \
+ /* test ipv4 country lookup */ \
+ tt_str_op(country, OP_EQ, \
+ geoip_get_country_name(geoip_get_country_by_ipv4(val))); \
+ /* test ipv6 country lookup */ \
+ SET_TEST_IPV6(val); \
+ tt_str_op(country, OP_EQ, \
+ geoip_get_country_name(geoip_get_country_by_ipv6(&in6))); \
+ } while (0)
+
+/** Run unit tests for GeoIP code. */
+static void
+test_geoip(void *arg)
+{
+ int i, j;
+ time_t now = 1281533250; /* 2010-08-11 13:27:30 UTC */
+ char *s = NULL, *v = NULL;
+ const char *bridge_stats_1 =
+ "bridge-stats-end 2010-08-12 13:27:30 (86400 s)\n"
+ "bridge-ips zz=24,xy=8\n"
+ "bridge-ip-versions v4=16,v6=16\n"
+ "bridge-ip-transports <OR>=24\n",
+ *dirreq_stats_1 =
+ "dirreq-stats-end 2010-08-12 13:27:30 (86400 s)\n"
+ "dirreq-v3-ips ab=8\n"
+ "dirreq-v3-reqs ab=8\n"
+ "dirreq-v3-resp ok=0,not-enough-sigs=0,unavailable=0,not-found=0,"
+ "not-modified=0,busy=0\n"
+ "dirreq-v3-direct-dl complete=0,timeout=0,running=0\n"
+ "dirreq-v3-tunneled-dl complete=0,timeout=0,running=0\n",
+ *dirreq_stats_2 =
+ "dirreq-stats-end 2010-08-12 13:27:30 (86400 s)\n"
+ "dirreq-v3-ips \n"
+ "dirreq-v3-reqs \n"
+ "dirreq-v3-resp ok=0,not-enough-sigs=0,unavailable=0,not-found=0,"
+ "not-modified=0,busy=0\n"
+ "dirreq-v3-direct-dl complete=0,timeout=0,running=0\n"
+ "dirreq-v3-tunneled-dl complete=0,timeout=0,running=0\n",
+ *dirreq_stats_3 =
+ "dirreq-stats-end 2010-08-12 13:27:30 (86400 s)\n"
+ "dirreq-v3-ips \n"
+ "dirreq-v3-reqs \n"
+ "dirreq-v3-resp ok=8,not-enough-sigs=0,unavailable=0,not-found=0,"
+ "not-modified=0,busy=0\n"
+ "dirreq-v3-direct-dl complete=0,timeout=0,running=0\n"
+ "dirreq-v3-tunneled-dl complete=0,timeout=0,running=0\n",
+ *dirreq_stats_4 =
+ "dirreq-stats-end 2010-08-12 13:27:30 (86400 s)\n"
+ "dirreq-v3-ips \n"
+ "dirreq-v3-reqs \n"
+ "dirreq-v3-resp ok=8,not-enough-sigs=0,unavailable=0,not-found=0,"
+ "not-modified=0,busy=0\n"
+ "dirreq-v3-direct-dl complete=0,timeout=0,running=0\n"
+ "dirreq-v3-tunneled-dl complete=0,timeout=0,running=4\n",
+ *entry_stats_1 =
+ "entry-stats-end 2010-08-12 13:27:30 (86400 s)\n"
+ "entry-ips ab=8\n",
+ *entry_stats_2 =
+ "entry-stats-end 2010-08-12 13:27:30 (86400 s)\n"
+ "entry-ips \n";
+ tor_addr_t addr;
+ struct in6_addr in6;
+
+ /* Populate the DB a bit. Add these in order, since we can't do the final
+ * 'sort' step. These aren't very good IP addresses, but they're perfectly
+ * fine uint32_t values. */
+ (void)arg;
+ tt_int_op(0,OP_EQ, geoip_parse_entry("10,50,AB", AF_INET));
+ tt_int_op(0,OP_EQ, geoip_parse_entry("52,90,XY", AF_INET));
+ tt_int_op(0,OP_EQ, geoip_parse_entry("95,100,AB", AF_INET));
+ tt_int_op(0,OP_EQ, geoip_parse_entry("\"105\",\"140\",\"ZZ\"", AF_INET));
+ tt_int_op(0,OP_EQ, geoip_parse_entry("\"150\",\"190\",\"XY\"", AF_INET));
+ tt_int_op(0,OP_EQ, geoip_parse_entry("\"200\",\"250\",\"AB\"", AF_INET));
+
+ /* Populate the IPv6 DB equivalently with fake IPs in the same range */
+ tt_int_op(0,OP_EQ, geoip_parse_entry("::a,::32,AB", AF_INET6));
+ tt_int_op(0,OP_EQ, geoip_parse_entry("::34,::5a,XY", AF_INET6));
+ tt_int_op(0,OP_EQ, geoip_parse_entry("::5f,::64,AB", AF_INET6));
+ tt_int_op(0,OP_EQ, geoip_parse_entry("::69,::8c,ZZ", AF_INET6));
+ tt_int_op(0,OP_EQ, geoip_parse_entry("::96,::be,XY", AF_INET6));
+ tt_int_op(0,OP_EQ, geoip_parse_entry("::c8,::fa,AB", AF_INET6));
+
+ /* We should have 4 countries: ??, ab, xy, zz. */
+ tt_int_op(4,OP_EQ, geoip_get_n_countries());
+ memset(&in6, 0, sizeof(in6));
+
+ CHECK_COUNTRY("??", 3);
+ CHECK_COUNTRY("ab", 32);
+ CHECK_COUNTRY("??", 5);
+ CHECK_COUNTRY("??", 51);
+ CHECK_COUNTRY("xy", 150);
+ CHECK_COUNTRY("xy", 190);
+ CHECK_COUNTRY("??", 2000);
+
+ tt_int_op(0,OP_EQ, geoip_get_country_by_ipv4(3));
+ SET_TEST_IPV6(3);
+ tt_int_op(0,OP_EQ, geoip_get_country_by_ipv6(&in6));
+
+ get_options_mutable()->BridgeRelay = 1;
+ get_options_mutable()->BridgeRecordUsageByCountry = 1;
+ /* Put 9 observations in AB... */
+ for (i=32; i < 40; ++i) {
+ SET_TEST_ADDRESS(i);
+ geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &addr, NULL, now-7200);
+ }
+ SET_TEST_ADDRESS(225);
+ geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &addr, NULL, now-7200);
+ /* and 3 observations in XY, several times. */
+ for (j=0; j < 10; ++j)
+ for (i=52; i < 55; ++i) {
+ SET_TEST_ADDRESS(i);
+ geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &addr, NULL, now-3600);
+ }
+ /* and 17 observations in ZZ... */
+ for (i=110; i < 127; ++i) {
+ SET_TEST_ADDRESS(i);
+ geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &addr, NULL, now);
+ }
+ geoip_get_client_history(GEOIP_CLIENT_CONNECT, &s, &v);
+ tt_assert(s);
+ tt_assert(v);
+ tt_str_op("zz=24,ab=16,xy=8",OP_EQ, s);
+ tt_str_op("v4=16,v6=16",OP_EQ, v);
+ tor_free(s);
+ tor_free(v);
+
+ /* Now clear out all the AB observations. */
+ geoip_remove_old_clients(now-6000);
+ geoip_get_client_history(GEOIP_CLIENT_CONNECT, &s, &v);
+ tt_assert(s);
+ tt_assert(v);
+ tt_str_op("zz=24,xy=8",OP_EQ, s);
+ tt_str_op("v4=16,v6=16",OP_EQ, v);
+ tor_free(s);
+ tor_free(v);
+
+ /* Start testing bridge statistics by making sure that we don't output
+ * bridge stats without initializing them. */
+ s = geoip_format_bridge_stats(now + 86400);
+ tt_ptr_op(s, OP_EQ, NULL);
+
+ /* Initialize stats and generate the bridge-stats history string out of
+ * the connecting clients added above. */
+ geoip_bridge_stats_init(now);
+ s = geoip_format_bridge_stats(now + 86400);
+ tt_assert(s);
+ tt_str_op(bridge_stats_1,OP_EQ, s);
+ tor_free(s);
+
+ /* Stop collecting bridge stats and make sure we don't write a history
+ * string anymore. */
+ geoip_bridge_stats_term();
+ s = geoip_format_bridge_stats(now + 86400);
+ tt_ptr_op(s, OP_EQ, NULL);
+
+ /* Stop being a bridge and start being a directory mirror that gathers
+ * directory request statistics. */
+ geoip_bridge_stats_term();
+ get_options_mutable()->BridgeRelay = 0;
+ get_options_mutable()->BridgeRecordUsageByCountry = 0;
+ get_options_mutable()->DirReqStatistics = 1;
+
+ /* Start testing dirreq statistics by making sure that we don't collect
+ * dirreq stats without initializing them. */
+ SET_TEST_ADDRESS(100);
+ geoip_note_client_seen(GEOIP_CLIENT_NETWORKSTATUS, &addr, NULL, now);
+ s = geoip_format_dirreq_stats(now + 86400);
+ tt_ptr_op(s, OP_EQ, NULL);
+
+ /* Initialize stats, note one connecting client, and generate the
+ * dirreq-stats history string. */
+ geoip_dirreq_stats_init(now);
+ SET_TEST_ADDRESS(100);
+ geoip_note_client_seen(GEOIP_CLIENT_NETWORKSTATUS, &addr, NULL, now);
+ s = geoip_format_dirreq_stats(now + 86400);
+ tt_str_op(dirreq_stats_1,OP_EQ, s);
+ tor_free(s);
+
+ /* Stop collecting stats, add another connecting client, and ensure we
+ * don't generate a history string. */
+ geoip_dirreq_stats_term();
+ SET_TEST_ADDRESS(101);
+ geoip_note_client_seen(GEOIP_CLIENT_NETWORKSTATUS, &addr, NULL, now);
+ s = geoip_format_dirreq_stats(now + 86400);
+ tt_ptr_op(s, OP_EQ, NULL);
+
+ /* Re-start stats, add a connecting client, reset stats, and make sure
+ * that we get an all empty history string. */
+ geoip_dirreq_stats_init(now);
+ SET_TEST_ADDRESS(100);
+ geoip_note_client_seen(GEOIP_CLIENT_NETWORKSTATUS, &addr, NULL, now);
+ geoip_reset_dirreq_stats(now);
+ s = geoip_format_dirreq_stats(now + 86400);
+ tt_str_op(dirreq_stats_2,OP_EQ, s);
+ tor_free(s);
+
+ /* Note a successful network status response and make sure that it
+ * appears in the history string. */
+ geoip_note_ns_response(GEOIP_SUCCESS);
+ s = geoip_format_dirreq_stats(now + 86400);
+ tt_str_op(dirreq_stats_3,OP_EQ, s);
+ tor_free(s);
+
+ /* Start a tunneled directory request. */
+ geoip_start_dirreq((uint64_t) 1, 1024, DIRREQ_TUNNELED);
+ s = geoip_format_dirreq_stats(now + 86400);
+ tt_str_op(dirreq_stats_4,OP_EQ, s);
+ tor_free(s);
+
+ /* Stop collecting directory request statistics and start gathering
+ * entry stats. */
+ geoip_dirreq_stats_term();
+ get_options_mutable()->DirReqStatistics = 0;
+ get_options_mutable()->EntryStatistics = 1;
+
+ /* Start testing entry statistics by making sure that we don't collect
+ * anything without initializing entry stats. */
+ SET_TEST_ADDRESS(100);
+ geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &addr, NULL, now);
+ s = geoip_format_entry_stats(now + 86400);
+ tt_ptr_op(s, OP_EQ, NULL);
+
+ /* Initialize stats, note one connecting client, and generate the
+ * entry-stats history string. */
+ geoip_entry_stats_init(now);
+ SET_TEST_ADDRESS(100);
+ geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &addr, NULL, now);
+ s = geoip_format_entry_stats(now + 86400);
+ tt_str_op(entry_stats_1,OP_EQ, s);
+ tor_free(s);
+
+ /* Stop collecting stats, add another connecting client, and ensure we
+ * don't generate a history string. */
+ geoip_entry_stats_term();
+ SET_TEST_ADDRESS(101);
+ geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &addr, NULL, now);
+ s = geoip_format_entry_stats(now + 86400);
+ tt_ptr_op(s, OP_EQ, NULL);
+
+ /* Re-start stats, add a connecting client, reset stats, and make sure
+ * that we get an all empty history string. */
+ geoip_entry_stats_init(now);
+ SET_TEST_ADDRESS(100);
+ geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &addr, NULL, now);
+ geoip_reset_entry_stats(now);
+ s = geoip_format_entry_stats(now + 86400);
+ tt_str_op(entry_stats_2,OP_EQ, s);
+ tor_free(s);
+
+ /* Test the OOM handler. Add a client, run the OOM. */
+ geoip_entry_stats_init(now);
+ SET_TEST_ADDRESS(100);
+ geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &addr, NULL,
+ now - (12 * 60 * 60));
+ /* We've seen this 12 hours ago. Run the OOM, it should clean the entry
+ * because it is above the minimum cutoff of 4 hours. */
+ size_t bytes_removed = geoip_client_cache_handle_oom(now, 1000);
+ tt_size_op(bytes_removed, OP_GT, 0);
+
+ /* Do it again but this time with an entry with a lower cutoff. */
+ geoip_entry_stats_init(now);
+ SET_TEST_ADDRESS(100);
+ geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &addr, NULL,
+ now - (3 * 60 * 60));
+ bytes_removed = geoip_client_cache_handle_oom(now, 1000);
+ tt_size_op(bytes_removed, OP_EQ, 0);
+
+ /* Stop collecting entry statistics. */
+ geoip_entry_stats_term();
+ get_options_mutable()->EntryStatistics = 0;
+
+ done:
+ tor_free(s);
+ tor_free(v);
+}
+
+static void
+test_geoip_with_pt(void *arg)
+{
+ time_t now = 1281533250; /* 2010-08-11 13:27:30 UTC */
+ char *s = NULL;
+ int i;
+ tor_addr_t addr;
+ struct in6_addr in6;
+
+ (void)arg;
+ get_options_mutable()->BridgeRelay = 1;
+ get_options_mutable()->BridgeRecordUsageByCountry = 1;
+
+ memset(&in6, 0, sizeof(in6));
+
+ /* No clients seen yet. */
+ s = geoip_get_transport_history();
+ tor_assert(!s);
+
+ /* 4 connections without a pluggable transport */
+ for (i=0; i < 4; ++i) {
+ SET_TEST_ADDRESS(i);
+ geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &addr, NULL, now-7200);
+ }
+
+ /* 9 connections with "alpha" */
+ for (i=4; i < 13; ++i) {
+ SET_TEST_ADDRESS(i);
+ geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &addr, "alpha", now-7200);
+ }
+
+ /* one connection with "beta" */
+ SET_TEST_ADDRESS(13);
+ geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &addr, "beta", now-7200);
+
+ /* 14 connections with "charlie" */
+ for (i=14; i < 28; ++i) {
+ SET_TEST_ADDRESS(i);
+ geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &addr, "charlie", now-7200);
+ }
+
+ /* 131 connections with "ddr" */
+ for (i=28; i < 159; ++i) {
+ SET_TEST_ADDRESS(i);
+ geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &addr, "ddr", now-7200);
+ }
+
+ /* 8 connections with "entropy" */
+ for (i=159; i < 167; ++i) {
+ SET_TEST_ADDRESS(i);
+ geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &addr, "entropy", now-7200);
+ }
+
+ /* 2 connections from the same IP with two different transports. */
+ SET_TEST_ADDRESS(++i);
+ geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &addr, "fire", now-7200);
+ geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &addr, "google", now-7200);
+
+ /* Test the transport history string. */
+ s = geoip_get_transport_history();
+ tor_assert(s);
+ tt_str_op(s,OP_EQ, "<OR>=8,alpha=16,beta=8,charlie=16,ddr=136,"
+ "entropy=8,fire=8,google=8");
+
+ /* Stop collecting entry statistics. */
+ geoip_entry_stats_term();
+ get_options_mutable()->EntryStatistics = 0;
+
+ done:
+ tor_free(s);
+}
+
+#undef SET_TEST_ADDRESS
+#undef SET_TEST_IPV6
+#undef CHECK_COUNTRY
+
+static const char GEOIP_CONTENT[] =
+ "134445936,134445939,MP\n"
+ "134445940,134447103,GU\n"
+ "134447104,134738943,US\n"
+ "134738944,134739199,CA\n"
+ "134739200,135192575,US\n"
+ "135192576,135200767,MX\n"
+ "135200768,135430143,US\n"
+ "135430144,135430399,CA\n"
+ "135430400,135432191,US\n";
+
+static void
+test_geoip_load_file(void *arg)
+{
+ (void)arg;
+ char *contents = NULL;
+ char *dhex = NULL;
+
+ /* A nonexistant filename should fail. */
+ tt_int_op(-1, OP_EQ,
+ geoip_load_file(AF_INET, "/you/did/not/put/a/file/here/I/hope",
+ LOG_INFO));
+
+ /* We start out with only "Ningunpartia" in the database. */
+ tt_int_op(1, OP_EQ, geoip_get_n_countries());
+ tt_str_op("??", OP_EQ, geoip_get_country_name(0));
+ /* Any lookup attempt should say "-1" because we have no info */
+ tt_int_op(-1, OP_EQ, geoip_get_country_by_ipv4(0x01020304));
+ /* There should be no 'digest' for a nonexistant file */
+ tt_str_op("0000000000000000000000000000000000000000", OP_EQ,
+ geoip_db_digest(AF_INET));
+
+ const char *fname = get_fname("geoip");
+ tt_int_op(0, OP_EQ, write_str_to_file(fname, GEOIP_CONTENT, 1));
+
+ int rv = geoip_load_file(AF_INET, fname, LOG_WARN);
+ if (rv != 0) {
+ TT_GRIPE(("Unable to load geoip from %s", escaped(fname)));
+ }
+ tt_int_op(0, OP_EQ, rv);
+
+ /* Check that we loaded some countries; this will fail if there are ever
+ * fewer than 5 countries in our test above. */
+ tt_int_op(geoip_get_n_countries(), OP_GE, 5);
+
+ /* Let's see where 8.8.8.8 is. */
+ int country = geoip_get_country_by_ipv4(0x08080808);
+ tt_int_op(country, OP_GE, 1); /* It shouldn't be 'unknown' or 'nowhere' */
+ const char *cc = geoip_get_country_name(country);
+ tt_int_op(strlen(cc), OP_EQ, 2);
+
+ /* The digest should be set.... */
+ tt_str_op("0000000000000000000000000000000000000000", OP_NE,
+ geoip_db_digest(AF_INET));
+
+ /* And it should be set correctly */
+ contents = read_file_to_str(fname, RFTS_BIN, NULL);
+ uint8_t d[DIGEST_LEN];
+ crypto_digest((char*)d, contents, strlen(contents));
+ dhex = tor_strdup(hex_str((char*)d, DIGEST_LEN));
+ tt_str_op(dhex, OP_EQ, geoip_db_digest(AF_INET));
+
+ /* Make sure geoip_free_all() works. */
+ geoip_free_all();
+ tt_int_op(1, OP_EQ, geoip_get_n_countries());
+ tt_str_op("??", OP_EQ, geoip_get_country_name(0));
+ tt_int_op(-1, OP_EQ, geoip_get_country_by_ipv4(0x01020304));
+ tt_str_op("0000000000000000000000000000000000000000", OP_EQ,
+ geoip_db_digest(AF_INET)); // <--- nick bets this will fail.
+
+ done:
+ tor_free(contents);
+ tor_free(dhex);
+}
+
+static void
+test_geoip6_load_file(void *arg)
+{
+ (void)arg;
+ struct in6_addr iaddr6;
+ char *contents = NULL;
+ char *dhex = NULL;
+
+ /* A nonexistant filename should fail. */
+ tt_int_op(-1, OP_EQ,
+ geoip_load_file(AF_INET6, "/you/did/not/put/a/file/here/I/hope",
+ LOG_INFO));
+
+ /* Any lookup attempt should say "-1" because we have no info */
+ tor_inet_pton(AF_INET6, "2001:4860:4860::8888", &iaddr6);
+ tt_int_op(-1, OP_EQ, geoip_get_country_by_ipv6(&iaddr6));
+
+ /* Load geiop6 file */
+ const char *fname6 = get_fname("geoip6");
+ const char CONTENT[] =
+ "2001:4830:6010::,2001:4830:601f:ffff:ffff:ffff:ffff:ffff,GB\n"
+ "2001:4830:6020::,2001:4830:ffff:ffff:ffff:ffff:ffff:ffff,US\n"
+ "2001:4838::,2001:4838:ffff:ffff:ffff:ffff:ffff:ffff,US\n"
+ "2001:4840::,2001:4840:ffff:ffff:ffff:ffff:ffff:ffff,XY\n"
+ "2001:4848::,2001:4848:ffff:ffff:ffff:ffff:ffff:ffff,ZD\n"
+ "2001:4850::,2001:4850:ffff:ffff:ffff:ffff:ffff:ffff,RO\n"
+ "2001:4858::,2001:4858:ffff:ffff:ffff:ffff:ffff:ffff,TC\n"
+ "2001:4860::,2001:4860:ffff:ffff:ffff:ffff:ffff:ffff,US\n"
+ "2001:4868::,2001:4868:ffff:ffff:ffff:ffff:ffff:ffff,US\n"
+ "2001:4870::,2001:4871:ffff:ffff:ffff:ffff:ffff:ffff,NB\n"
+ "2001:4878::,2001:4878:128:ffff:ffff:ffff:ffff:ffff,US\n"
+ "2001:4878:129::,2001:4878:129:ffff:ffff:ffff:ffff:ffff,CR\n"
+ "2001:4878:12a::,2001:4878:203:ffff:ffff:ffff:ffff:ffff,US\n"
+ "2001:4878:204::,2001:4878:204:ffff:ffff:ffff:ffff:ffff,DE\n"
+ "2001:4878:205::,2001:4878:214:ffff:ffff:ffff:ffff:ffff,US\n";
+ tt_int_op(0, OP_EQ, write_str_to_file(fname6, CONTENT, 1));
+
+ tt_int_op(0, OP_EQ, geoip_load_file(AF_INET6, fname6, LOG_WARN));
+
+ /* Check that we loaded some countries; this will fail if there are ever
+ * fewer than 5 countries in our test data above. */
+ tt_int_op(geoip_get_n_countries(), OP_GE, 5);
+
+ /* Let's see where 2001:4860:4860::8888 (google dns) is. */
+ const char *caddr6 = "2001:4860:4860::8888";
+ tor_inet_pton(AF_INET6, caddr6, &iaddr6);
+ int country6 = geoip_get_country_by_ipv6(&iaddr6);
+ tt_int_op(country6, OP_GE, 1);
+
+ const char *cc6 = geoip_get_country_name(country6);
+ tt_int_op(strlen(cc6), OP_EQ, 2);
+
+ /* The digest should be set.... */
+ tt_str_op("0000000000000000000000000000000000000000", OP_NE,
+ geoip_db_digest(AF_INET6));
+
+ /* And it should be set correctly */
+ contents = read_file_to_str(fname6, RFTS_BIN, NULL);
+ uint8_t d[DIGEST_LEN];
+ crypto_digest((char*)d, contents, strlen(contents));
+ dhex = tor_strdup(hex_str((char*)d, DIGEST_LEN));
+ tt_str_op(dhex, OP_EQ, geoip_db_digest(AF_INET6));
+
+ /* Make sure geoip_free_all() works. */
+ geoip_free_all();
+ tt_int_op(1, OP_EQ, geoip_get_n_countries());
+ tt_str_op("??", OP_EQ, geoip_get_country_name(0));
+ tor_inet_pton(AF_INET6, "::1:2:3:4", &iaddr6);
+ tt_int_op(-1, OP_EQ, geoip_get_country_by_ipv6(&iaddr6));
+ tt_str_op("0000000000000000000000000000000000000000", OP_EQ,
+ geoip_db_digest(AF_INET6));
+
+ done:
+ tor_free(contents);
+ tor_free(dhex);
+}
+
+static void
+test_geoip_load_2nd_file(void *arg)
+{
+ (void)arg;
+
+ char *fname_geoip = tor_strdup(get_fname("geoip_data"));
+ char *fname_empty = tor_strdup(get_fname("geoip_empty"));
+
+ tt_int_op(0, OP_EQ, write_str_to_file(fname_geoip, GEOIP_CONTENT, 1));
+ tt_int_op(0, OP_EQ, write_str_to_file(fname_empty, "\n", 1));
+
+ /* Load 1st geoip file */
+ tt_int_op(0, OP_EQ, geoip_load_file(AF_INET, fname_geoip, LOG_WARN));
+
+ /* Load 2nd geoip (empty) file */
+ /* It has to be the same IP address family */
+ tt_int_op(0, OP_EQ, geoip_load_file(AF_INET, fname_empty, LOG_WARN));
+
+ /* Check that there is no geoip information for 8.8.8.8, */
+ /* since loading the empty 2nd file should have delete it. */
+ int country = geoip_get_country_by_ipv4(0x08080808);
+ tt_int_op(country, OP_EQ, 0);
+
+ done:
+ tor_free(fname_geoip);
+ tor_free(fname_empty);
+}
+
+#define ENT(name) \
+ { #name, test_ ## name , 0, NULL, NULL }
+#define FORK(name) \
+ { #name, test_ ## name , TT_FORK, NULL, NULL }
+
+struct testcase_t geoip_tests[] = {
+ { "geoip", test_geoip, TT_FORK, NULL, NULL },
+ { "geoip_with_pt", test_geoip_with_pt, TT_FORK, NULL, NULL },
+ { "load_file", test_geoip_load_file, TT_FORK, NULL, NULL },
+ { "load_file6", test_geoip6_load_file, TT_FORK, NULL, NULL },
+ { "load_2nd_file", test_geoip_load_2nd_file, TT_FORK, NULL, NULL },
+
+ END_OF_TESTCASES
+};
diff --git a/src/test/test_guardfraction.c b/src/test/test_guardfraction.c
index 51ca8f08ec..d6f4cd63f2 100644
--- a/src/test/test_guardfraction.c
+++ b/src/test/test_guardfraction.c
@@ -1,23 +1,25 @@
-/* Copyright (c) 2014-2017, The Tor Project, Inc. */
+/* Copyright (c) 2014-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
-#define DIRSERV_PRIVATE
-#define ROUTERPARSE_PRIVATE
+#define GUARDFRACTION_PRIVATE
#define NETWORKSTATUS_PRIVATE
+#define NS_PARSE_PRIVATE
#include "orconfig.h"
-#include "or.h"
-#include "config.h"
-#include "dirserv.h"
-#include "container.h"
-#include "entrynodes.h"
-#include "util.h"
-#include "routerparse.h"
-#include "networkstatus.h"
-
-#include "test.h"
-#include "test_helpers.h"
-#include "log_test_helpers.h"
+#include "core/or/or.h"
+#include "app/config/config.h"
+#include "feature/dirauth/guardfraction.h"
+#include "feature/client/entrynodes.h"
+#include "feature/dirparse/ns_parse.h"
+#include "feature/nodelist/networkstatus.h"
+
+#include "feature/nodelist/networkstatus_st.h"
+#include "feature/dirauth/vote_microdesc_hash_st.h"
+#include "feature/nodelist/vote_routerstatus_st.h"
+
+#include "test/test.h"
+#include "test/test_helpers.h"
+#include "test/log_test_helpers.h"
/** Generate a vote_routerstatus_t for a router with identity digest
* <b>digest_in_hex</b>. */
@@ -420,4 +422,3 @@ struct testcase_t guardfraction_tests[] = {
END_OF_TESTCASES
};
-
diff --git a/src/test/test_handles.c b/src/test/test_handles.c
index eb1e1f1bbe..2910d7e18f 100644
--- a/src/test/test_handles.c
+++ b/src/test/test_handles.c
@@ -1,11 +1,13 @@
-/* Copyright (c) 2016-2017, The Tor Project, Inc. */
+/* Copyright (c) 2016-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
#include "orconfig.h"
-#include "test.h"
+#include "test/test.h"
-#include "util.h"
-#include "handles.h"
+#include "lib/container/handles.h"
+#include "lib/log/util_bug.h"
+
+#include <stdio.h>
typedef struct demo_t {
HANDLE_ENTRY(demo, demo_t);
@@ -94,4 +96,3 @@ struct testcase_t handle_tests[] = {
HANDLE_TEST(basic, 0),
END_OF_TESTCASES
};
-
diff --git a/src/test/test_helpers.c b/src/test/test_helpers.c
index 0da9cf64d0..6ac73bff5c 100644
--- a/src/test/test_helpers.c
+++ b/src/test/test_helpers.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014-2017, The Tor Project, Inc. */
+/* Copyright (c) 2014-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
/**
@@ -9,23 +9,32 @@
#define ROUTERLIST_PRIVATE
#define CONFIG_PRIVATE
#define CONNECTION_PRIVATE
-#define MAIN_PRIVATE
+#define MAINLOOP_PRIVATE
#include "orconfig.h"
-#include "or.h"
-
-#include "buffers.h"
-#include "config.h"
-#include "confparse.h"
-#include "connection.h"
-#include "main.h"
-#include "nodelist.h"
-#include "relay.h"
-#include "routerlist.h"
-
-#include "test.h"
-#include "test_helpers.h"
-#include "test_connection.h"
+#include "core/or/or.h"
+
+#include "lib/container/buffers.h"
+#include "app/config/config.h"
+#include "app/config/confparse.h"
+#include "core/mainloop/connection.h"
+#include "lib/crypt_ops/crypto_rand.h"
+#include "core/mainloop/mainloop.h"
+#include "feature/nodelist/nodelist.h"
+#include "core/or/relay.h"
+#include "feature/nodelist/routerlist.h"
+#include "lib/encoding/confline.h"
+#include "lib/net/resolve.h"
+
+#include "core/or/cell_st.h"
+#include "core/or/connection_st.h"
+#include "feature/nodelist/node_st.h"
+#include "core/or/origin_circuit_st.h"
+#include "feature/nodelist/routerlist_st.h"
+
+#include "test/test.h"
+#include "test/test_helpers.h"
+#include "test/test_connection.h"
#ifdef HAVE_CFLAG_WOVERLENGTH_STRINGS
DISABLE_GCC_WARNING(overlength-strings)
@@ -33,8 +42,7 @@ DISABLE_GCC_WARNING(overlength-strings)
* at large. */
#endif
#include "test_descriptors.inc"
-#include "or.h"
-#include "circuitlist.h"
+#include "core/or/circuitlist.h"
#ifdef HAVE_CFLAG_WOVERLENGTH_STRINGS
ENABLE_GCC_WARNING(overlength-strings)
#endif
@@ -117,6 +125,25 @@ connection_write_to_buf_mock(const char *string, size_t len,
buf_add(conn->outbuf, string, len);
}
+char *
+buf_get_contents(buf_t *buf, size_t *sz_out)
+{
+ tor_assert(buf);
+ tor_assert(sz_out);
+
+ char *out;
+ *sz_out = buf_datalen(buf);
+ if (*sz_out >= ULONG_MAX)
+ return NULL; /* C'mon, really? */
+ out = tor_malloc(*sz_out + 1);
+ if (buf_get_bytes(buf, out, (unsigned long)*sz_out) != 0) {
+ tor_free(out);
+ return NULL;
+ }
+ out[*sz_out] = '\0'; /* Hopefully gratuitous. */
+ return out;
+}
+
/* Set up a fake origin circuit with the specified number of cells,
* Return a pointer to the newly-created dummy circuit */
circuit_t *
@@ -156,7 +183,7 @@ mock_tor_addr_lookup__fail_on_bad_addrs(const char *name,
/* Helper for test_conn_get_connection() */
static int
-fake_close_socket(evutil_socket_t sock)
+fake_close_socket(tor_socket_t sock)
{
(void)sock;
return 0;
@@ -209,7 +236,7 @@ test_conn_get_connection(uint8_t state, uint8_t type, uint8_t purpose)
mock_connection_connect_sockaddr);
MOCK(tor_close_socket, fake_close_socket);
- init_connection_lists();
+ tor_init_connection_lists();
conn = connection_new(type, TEST_CONN_FAMILY);
tt_assert(conn);
@@ -276,4 +303,3 @@ helper_parse_options(const char *conf)
}
return opt;
}
-
diff --git a/src/test/test_helpers.h b/src/test/test_helpers.h
index 9bc8553257..72bf7f2f71 100644
--- a/src/test/test_helpers.h
+++ b/src/test/test_helpers.h
@@ -1,10 +1,12 @@
-/* Copyright (c) 2017, The Tor Project, Inc. */
+/* Copyright (c) 2017-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
#ifndef TOR_TEST_HELPERS_H
#define TOR_TEST_HELPERS_H
-#include "or.h"
+#define BUFFERS_PRIVATE
+
+#include "core/or/or.h"
const char *get_yesterday_date_str(void);
@@ -18,6 +20,7 @@ void helper_setup_fake_routerlist(void);
#define GET(path) "GET " path " HTTP/1.0\r\n\r\n"
void connection_write_to_buf_mock(const char *string, size_t len,
connection_t *conn, int compressed);
+char *buf_get_contents(buf_t *buf, size_t *sz_out);
int mock_tor_addr_lookup__fail_on_bad_addrs(const char *name,
uint16_t family, tor_addr_t *out);
diff --git a/src/test/test_hs.c b/src/test/test_hs.c
index 07daebc164..e3599d5720 100644
--- a/src/test/test_hs.c
+++ b/src/test/test_hs.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2007-2017, The Tor Project, Inc. */
+/* Copyright (c) 2007-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
/**
@@ -12,16 +12,27 @@
#define RENDSERVICE_PRIVATE
#define HS_SERVICE_PRIVATE
-#include "or.h"
-#include "test.h"
-#include "control.h"
-#include "config.h"
-#include "hs_common.h"
-#include "rendcommon.h"
-#include "rendservice.h"
-#include "routerset.h"
-#include "circuitbuild.h"
-#include "test_helpers.h"
+#include "core/or/or.h"
+#include "test/test.h"
+#include "feature/control/control.h"
+#include "app/config/config.h"
+#include "feature/hs/hs_common.h"
+#include "feature/rend/rendcommon.h"
+#include "feature/rend/rendservice.h"
+#include "feature/nodelist/routerlist.h"
+#include "feature/nodelist/routerset.h"
+#include "core/or/circuitbuild.h"
+
+#include "feature/nodelist/node_st.h"
+#include "feature/rend/rend_encoded_v2_service_descriptor_st.h"
+#include "feature/rend/rend_intro_point_st.h"
+#include "feature/nodelist/routerinfo_st.h"
+
+#include "test/test_helpers.h"
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
/* mock ID digest and longname for node that's in nodelist */
#define HSDIR_EXIST_ID "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" \
@@ -343,76 +354,6 @@ test_hs_desc_event(void *arg)
tor_free(received_msg);
}
-/* Make sure we always pick the right RP, given a well formatted
- * Tor2webRendezvousPoints value. */
-static void
-test_pick_tor2web_rendezvous_node(void *arg)
-{
- or_options_t *options = get_options_mutable();
- const node_t *chosen_rp = NULL;
- router_crn_flags_t flags = CRN_NEED_DESC;
- int retval, i;
- const char *tor2web_rendezvous_str = "test003r";
-
- (void) arg;
-
- /* Setup fake routerlist. */
- helper_setup_fake_routerlist();
-
- /* Parse Tor2webRendezvousPoints as a routerset. */
- options->Tor2webRendezvousPoints = routerset_new();
- options->UseMicrodescriptors = 0;
- retval = routerset_parse(options->Tor2webRendezvousPoints,
- tor2web_rendezvous_str,
- "test_tor2web_rp");
- tt_int_op(retval, OP_GE, 0);
-
- /* Pick rendezvous point. Make sure the correct one is
- picked. Repeat many times to make sure it works properly. */
- for (i = 0; i < 50 ; i++) {
- chosen_rp = pick_tor2web_rendezvous_node(flags, options);
- tt_assert(chosen_rp);
- tt_str_op(chosen_rp->ri->nickname, OP_EQ, tor2web_rendezvous_str);
- }
-
- done:
- routerset_free(options->Tor2webRendezvousPoints);
-}
-
-/* Make sure we never pick an RP if Tor2webRendezvousPoints doesn't
- * correspond to an actual node. */
-static void
-test_pick_bad_tor2web_rendezvous_node(void *arg)
-{
- or_options_t *options = get_options_mutable();
- const node_t *chosen_rp = NULL;
- router_crn_flags_t flags = CRN_NEED_DESC;
- int retval, i;
- const char *tor2web_rendezvous_str = "dummy";
-
- (void) arg;
-
- /* Setup fake routerlist. */
- helper_setup_fake_routerlist();
-
- /* Parse Tor2webRendezvousPoints as a routerset. */
- options->Tor2webRendezvousPoints = routerset_new();
- retval = routerset_parse(options->Tor2webRendezvousPoints,
- tor2web_rendezvous_str,
- "test_tor2web_rp");
- tt_int_op(retval, OP_GE, 0);
-
- /* Pick rendezvous point. Since Tor2webRendezvousPoints was set to a
- dummy value, we shouldn't find any eligible RPs. */
- for (i = 0; i < 50 ; i++) {
- chosen_rp = pick_tor2web_rendezvous_node(flags, options);
- tt_ptr_op(chosen_rp, OP_EQ, NULL);
- }
-
- done:
- routerset_free(options->Tor2webRendezvousPoints);
-}
-
/* Make sure rend_data_t is valid at creation, destruction and when
* duplicated. */
static void
@@ -1035,11 +976,6 @@ struct testcase_t hs_tests[] = {
NULL, NULL },
{ "hs_desc_event", test_hs_desc_event, TT_FORK,
NULL, NULL },
- { "pick_tor2web_rendezvous_node", test_pick_tor2web_rendezvous_node, TT_FORK,
- NULL, NULL },
- { "pick_bad_tor2web_rendezvous_node",
- test_pick_bad_tor2web_rendezvous_node, TT_FORK,
- NULL, NULL },
{ "hs_auth_cookies", test_hs_auth_cookies, TT_FORK,
NULL, NULL },
{ "single_onion_poisoning_create_dir_none", test_single_onion_poisoning,
@@ -1055,4 +991,3 @@ struct testcase_t hs_tests[] = {
END_OF_TESTCASES
};
-
diff --git a/src/test/test_hs_cache.c b/src/test/test_hs_cache.c
index 458ce1a92e..203a1d7039 100644
--- a/src/test/test_hs_cache.c
+++ b/src/test/test_hs_cache.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016-2017, The Tor Project, Inc. */
+/* Copyright (c) 2016-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
/**
@@ -7,20 +7,26 @@
*/
#define CONNECTION_PRIVATE
-#define DIRECTORY_PRIVATE
+#define DIRCACHE_PRIVATE
+#define DIRCLIENT_PRIVATE
#define HS_CACHE_PRIVATE
-#include "ed25519_cert.h"
-#include "hs_cache.h"
-#include "rendcache.h"
-#include "directory.h"
-#include "networkstatus.h"
-#include "connection.h"
-#include "proto_http.h"
+#include "trunnel/ed25519_cert.h"
+#include "feature/hs/hs_cache.h"
+#include "feature/rend/rendcache.h"
+#include "feature/dircache/dircache.h"
+#include "feature/dirclient/dirclient.h"
+#include "feature/nodelist/networkstatus.h"
+#include "core/mainloop/connection.h"
+#include "core/proto/proto_http.h"
+#include "lib/crypt_ops/crypto_format.h"
-#include "hs_test_helpers.h"
-#include "test_helpers.h"
-#include "test.h"
+#include "feature/dircommon/dir_connection_st.h"
+#include "feature/nodelist/networkstatus_st.h"
+
+#include "test/hs_test_helpers.h"
+#include "test/test_helpers.h"
+#include "test/test.h"
/* Static variable used to encoded the HSDir query. */
static char query_b64[256];
@@ -60,7 +66,7 @@ test_directory(void *arg)
tt_int_op(ret, OP_EQ, 0);
desc1 = hs_helper_build_hs_desc_with_ip(&signing_kp1);
tt_assert(desc1);
- ret = hs_desc_encode_descriptor(desc1, &signing_kp1, &desc1_str);
+ ret = hs_desc_encode_descriptor(desc1, &signing_kp1, NULL, &desc1_str);
tt_int_op(ret, OP_EQ, 0);
/* Very first basic test, should be able to be stored, survive a
@@ -98,7 +104,7 @@ test_directory(void *arg)
desc_zero_lifetime->plaintext_data.lifetime_sec = 0;
char *desc_zero_lifetime_str;
ret = hs_desc_encode_descriptor(desc_zero_lifetime, &signing_kp_zero,
- &desc_zero_lifetime_str);
+ NULL, &desc_zero_lifetime_str);
tt_int_op(ret, OP_EQ, 0);
ret = hs_cache_store_as_dir(desc1_str);
@@ -149,7 +155,7 @@ test_directory(void *arg)
tt_int_op(ret, OP_EQ, 1);
/* Bump revision counter. */
desc1->plaintext_data.revision_counter++;
- ret = hs_desc_encode_descriptor(desc1, &signing_kp1, &new_desc_str);
+ ret = hs_desc_encode_descriptor(desc1, &signing_kp1, NULL, &new_desc_str);
tt_int_op(ret, OP_EQ, 0);
ret = hs_cache_store_as_dir(new_desc_str);
tt_int_op(ret, OP_EQ, 0);
@@ -183,7 +189,7 @@ test_clean_as_dir(void *arg)
tt_int_op(ret, OP_EQ, 0);
desc1 = hs_helper_build_hs_desc_with_ip(&signing_kp1);
tt_assert(desc1);
- ret = hs_desc_encode_descriptor(desc1, &signing_kp1, &desc1_str);
+ ret = hs_desc_encode_descriptor(desc1, &signing_kp1, NULL, &desc1_str);
tt_int_op(ret, OP_EQ, 0);
ret = hs_cache_store_as_dir(desc1_str);
tt_int_op(ret, OP_EQ, 0);
@@ -297,7 +303,7 @@ test_upload_and_download_hs_desc(void *arg)
published_desc = hs_helper_build_hs_desc_with_ip(&signing_kp);
tt_assert(published_desc);
retval = hs_desc_encode_descriptor(published_desc, &signing_kp,
- &published_desc_str);
+ NULL, &published_desc_str);
tt_int_op(retval, OP_EQ, 0);
}
@@ -361,7 +367,7 @@ test_hsdir_revision_counter_check(void *arg)
published_desc = hs_helper_build_hs_desc_with_ip(&signing_kp);
tt_assert(published_desc);
retval = hs_desc_encode_descriptor(published_desc, &signing_kp,
- &published_desc_str);
+ NULL, &published_desc_str);
tt_int_op(retval, OP_EQ, 0);
}
@@ -386,7 +392,7 @@ test_hsdir_revision_counter_check(void *arg)
received_desc_str = helper_fetch_desc_from_hsdir(blinded_key);
retval = hs_desc_decode_descriptor(received_desc_str,
- subcredential, &received_desc);
+ subcredential, NULL, &received_desc);
tt_int_op(retval, OP_EQ, 0);
tt_assert(received_desc);
@@ -403,7 +409,7 @@ test_hsdir_revision_counter_check(void *arg)
published_desc->plaintext_data.revision_counter = 1313;
tor_free(published_desc_str);
retval = hs_desc_encode_descriptor(published_desc, &signing_kp,
- &published_desc_str);
+ NULL, &published_desc_str);
tt_int_op(retval, OP_EQ, 0);
retval = handle_post_hs_descriptor("/tor/hs/3/publish",published_desc_str);
@@ -419,7 +425,7 @@ test_hsdir_revision_counter_check(void *arg)
received_desc_str = helper_fetch_desc_from_hsdir(blinded_key);
retval = hs_desc_decode_descriptor(received_desc_str,
- subcredential, &received_desc);
+ subcredential, NULL, &received_desc);
tt_int_op(retval, OP_EQ, 0);
tt_assert(received_desc);
@@ -478,7 +484,7 @@ test_client_cache(void *arg)
published_desc = hs_helper_build_hs_desc_with_ip(&signing_kp);
tt_assert(published_desc);
retval = hs_desc_encode_descriptor(published_desc, &signing_kp,
- &published_desc_str);
+ NULL, &published_desc_str);
tt_int_op(retval, OP_EQ, 0);
memcpy(wanted_subcredential, published_desc->subcredential, DIGEST256_LEN);
tt_assert(!tor_mem_is_zero((char*)wanted_subcredential, DIGEST256_LEN));
@@ -558,4 +564,3 @@ struct testcase_t hs_cache[] = {
END_OF_TESTCASES
};
-
diff --git a/src/test/test_hs_cell.c b/src/test/test_hs_cell.c
index aed28d3bd2..5b48dd3785 100644
--- a/src/test/test_hs_cell.c
+++ b/src/test/test_hs_cell.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017, The Tor Project, Inc. */
+/* Copyright (c) 2017-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
/**
@@ -9,17 +9,18 @@
#define HS_INTROPOINT_PRIVATE
#define HS_SERVICE_PRIVATE
-#include "test.h"
-#include "test_helpers.h"
-#include "log_test_helpers.h"
+#include "test/test.h"
+#include "test/test_helpers.h"
+#include "test/log_test_helpers.h"
-#include "crypto_ed25519.h"
-#include "hs_cell.h"
-#include "hs_intropoint.h"
-#include "hs_service.h"
+#include "lib/crypt_ops/crypto_ed25519.h"
+#include "lib/crypt_ops/crypto_rand.h"
+#include "feature/hs/hs_cell.h"
+#include "feature/hs/hs_intropoint.h"
+#include "feature/hs/hs_service.h"
/* Trunnel. */
-#include "hs/cell_establish_intro.h"
+#include "trunnel/hs/cell_establish_intro.h"
/** We simulate the creation of an outgoing ESTABLISH_INTRO cell, and then we
* parse it from the receiver side. */
diff --git a/src/test/test_hs_client.c b/src/test/test_hs_client.c
index 7ee7210bc9..25cb991a79 100644
--- a/src/test/test_hs_client.c
+++ b/src/test/test_hs_client.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016-2017, The Tor Project, Inc. */
+/* Copyright (c) 2016-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
/**
@@ -6,36 +6,50 @@
* \brief Test prop224 HS client functionality.
*/
+#define CONFIG_PRIVATE
#define CRYPTO_PRIVATE
-#define MAIN_PRIVATE
+#define MAINLOOP_PRIVATE
#define HS_CLIENT_PRIVATE
#define TOR_CHANNEL_INTERNAL_
#define CIRCUITBUILD_PRIVATE
#define CIRCUITLIST_PRIVATE
#define CONNECTION_PRIVATE
-#include "test.h"
-#include "test_helpers.h"
-#include "log_test_helpers.h"
-#include "rend_test_helpers.h"
-#include "hs_test_helpers.h"
-
-#include "config.h"
-#include "crypto.h"
-#include "channeltls.h"
-#include "main.h"
-#include "nodelist.h"
-#include "routerset.h"
-
-#include "hs_circuit.h"
-#include "hs_client.h"
-#include "hs_ident.h"
-#include "hs_cache.h"
-#include "circuitlist.h"
-#include "circuitbuild.h"
-#include "connection.h"
-#include "connection_edge.h"
-#include "networkstatus.h"
+#include "test/test.h"
+#include "test/test_helpers.h"
+#include "test/log_test_helpers.h"
+#include "test/rend_test_helpers.h"
+#include "test/hs_test_helpers.h"
+
+#include "app/config/config.h"
+#include "lib/crypt_ops/crypto_cipher.h"
+#include "lib/crypt_ops/crypto_dh.h"
+#include "core/or/channeltls.h"
+#include "feature/dircommon/directory.h"
+#include "core/mainloop/mainloop.h"
+#include "feature/nodelist/nodelist.h"
+#include "feature/nodelist/routerset.h"
+
+#include "feature/hs/hs_circuit.h"
+#include "feature/hs/hs_circuitmap.h"
+#include "feature/hs/hs_client.h"
+#include "feature/hs/hs_config.h"
+#include "feature/hs/hs_ident.h"
+#include "feature/hs/hs_cache.h"
+#include "core/or/circuitlist.h"
+#include "core/or/circuitbuild.h"
+#include "core/mainloop/connection.h"
+#include "core/or/connection_edge.h"
+#include "feature/nodelist/networkstatus.h"
+
+#include "core/or/cpath_build_state_st.h"
+#include "core/or/crypt_path_st.h"
+#include "feature/dircommon/dir_connection_st.h"
+#include "core/or/entry_connection_st.h"
+#include "core/or/extend_info_st.h"
+#include "feature/nodelist/networkstatus_st.h"
+#include "core/or/origin_circuit_st.h"
+#include "core/or/socks_request_st.h"
static int
mock_connection_ap_handshake_send_begin(entry_connection_t *ap_conn)
@@ -61,6 +75,20 @@ mock_networkstatus_get_live_consensus(time_t now)
return &mock_ns;
}
+static int
+helper_config_client(const char *conf, int validate_only)
+{
+ int ret = 0;
+ or_options_t *options = NULL;
+ tt_assert(conf);
+ options = helper_parse_options(conf);
+ tt_assert(options);
+ ret = hs_config_client_auth_all(options, validate_only);
+ done:
+ or_options_free(options);
+ return ret;
+}
+
/* Test helper function: Setup a circuit and a stream with the same hidden
* service destination, and put them in <b>circ_out</b> and
* <b>conn_out</b>. Make the stream wait for circuits to be established to the
@@ -188,17 +216,17 @@ test_e2e_rend_circuit_setup_legacy(void *arg)
/* Make a good RENDEZVOUS1 cell body because it needs to pass key exchange
* digest verification... */
- uint8_t rend_cell_body[DH_KEY_LEN+DIGEST_LEN] = {2};
+ uint8_t rend_cell_body[DH1024_KEY_LEN+DIGEST_LEN] = {2};
{
char keys[DIGEST_LEN+CPATH_KEY_MATERIAL_LEN];
crypto_dh_t *dh_state =
or_circ->build_state->pending_final_cpath->rend_dh_handshake_state;
/* compute and overwrite digest of cell body with the right value */
retval = crypto_dh_compute_secret(LOG_PROTOCOL_WARN, dh_state,
- (char*)rend_cell_body, DH_KEY_LEN,
+ (char*)rend_cell_body, DH1024_KEY_LEN,
keys, DIGEST_LEN+CPATH_KEY_MATERIAL_LEN);
tt_int_op(retval, OP_GT, 0);
- memcpy(rend_cell_body+DH_KEY_LEN, keys, DIGEST_LEN);
+ memcpy(rend_cell_body+DH1024_KEY_LEN, keys, DIGEST_LEN);
}
/* Setup the circuit */
@@ -213,12 +241,12 @@ test_e2e_rend_circuit_setup_legacy(void *arg)
tt_int_op(retval, OP_EQ, 1);
/* Check the digest algo */
- tt_int_op(crypto_digest_get_algorithm(or_circ->cpath->f_digest),
+ tt_int_op(crypto_digest_get_algorithm(or_circ->cpath->crypto.f_digest),
OP_EQ, DIGEST_SHA1);
- tt_int_op(crypto_digest_get_algorithm(or_circ->cpath->b_digest),
+ tt_int_op(crypto_digest_get_algorithm(or_circ->cpath->crypto.b_digest),
OP_EQ, DIGEST_SHA1);
- tt_assert(or_circ->cpath->f_crypto);
- tt_assert(or_circ->cpath->b_crypto);
+ tt_assert(or_circ->cpath->crypto.f_crypto);
+ tt_assert(or_circ->cpath->crypto.b_crypto);
/* Ensure that circ purpose was changed */
tt_int_op(or_circ->base_.purpose, OP_EQ, CIRCUIT_PURPOSE_C_REND_JOINED);
@@ -283,12 +311,12 @@ test_e2e_rend_circuit_setup(void *arg)
tt_int_op(retval, OP_EQ, 1);
/* Check that the crypt path has prop224 algorithm parameters */
- tt_int_op(crypto_digest_get_algorithm(or_circ->cpath->f_digest),
+ tt_int_op(crypto_digest_get_algorithm(or_circ->cpath->crypto.f_digest),
OP_EQ, DIGEST_SHA3_256);
- tt_int_op(crypto_digest_get_algorithm(or_circ->cpath->b_digest),
+ tt_int_op(crypto_digest_get_algorithm(or_circ->cpath->crypto.b_digest),
OP_EQ, DIGEST_SHA3_256);
- tt_assert(or_circ->cpath->f_crypto);
- tt_assert(or_circ->cpath->b_crypto);
+ tt_assert(or_circ->cpath->crypto.f_crypto);
+ tt_assert(or_circ->cpath->crypto.b_crypto);
/* Ensure that circ purpose was changed */
tt_int_op(or_circ->base_.purpose, OP_EQ, CIRCUIT_PURPOSE_C_REND_JOINED);
@@ -354,7 +382,7 @@ test_client_pick_intro(void *arg)
{
char *encoded = NULL;
desc = hs_helper_build_hs_desc_with_ip(&service_kp);
- ret = hs_desc_encode_descriptor(desc, &service_kp, &encoded);
+ ret = hs_desc_encode_descriptor(desc, &service_kp, NULL, &encoded);
tt_int_op(ret, OP_EQ, 0);
tt_assert(encoded);
@@ -397,21 +425,25 @@ test_client_pick_intro(void *arg)
} SMARTLIST_FOREACH_END(ip);
/* Try to get a random intro: Should return the chosen one! */
- extend_info_t *ip = client_get_random_intro(&service_kp.pubkey);
- tor_assert(ip);
- tt_assert(!tor_mem_is_zero((char*)ip->identity_digest, DIGEST_LEN));
- tt_mem_op(ip->identity_digest, OP_EQ, chosen_intro_ei->identity_digest,
- DIGEST_LEN);
+ /* (We try several times, to make sure this behavior is consistent, and to
+ * cover the different cases of client_get_random_intro().) */
+ for (int i = 0; i < 64; ++i) {
+ extend_info_t *ip = client_get_random_intro(&service_kp.pubkey);
+ tor_assert(ip);
+ tt_assert(!tor_mem_is_zero((char*)ip->identity_digest, DIGEST_LEN));
+ tt_mem_op(ip->identity_digest, OP_EQ, chosen_intro_ei->identity_digest,
+ DIGEST_LEN);
+ extend_info_free(ip);
+ }
extend_info_free(chosen_intro_ei);
- extend_info_free(ip);
/* Now also mark the chosen one as failed: See that we can't get any intro
points anymore. */
hs_cache_client_intro_state_note(&service_kp.pubkey,
&chosen_intro_point->auth_key_cert->signed_key,
INTRO_POINT_FAILURE_TIMEOUT);
- ip = client_get_random_intro(&service_kp.pubkey);
+ extend_info_t *ip = client_get_random_intro(&service_kp.pubkey);
tor_assert(!ip);
}
@@ -491,6 +523,9 @@ mock_connection_mark_unattached_ap_(entry_connection_t *conn, int endreason,
(void) line;
(void) file;
conn->edge_.end_reason = endreason;
+ /* This function ultimately will flag this so make sure we do also in the
+ * MOCK one so we can assess closed connections vs open ones. */
+ conn->edge_.base_.marked_for_close = 1;
}
static void
@@ -585,6 +620,271 @@ test_descriptor_fetch(void *arg)
hs_free_all();
}
+static void
+test_auth_key_filename_is_valid(void *arg)
+{
+ (void) arg;
+
+ /* Valid file name. */
+ tt_assert(auth_key_filename_is_valid("a.auth_private"));
+ /* Valid file name with special character. */
+ tt_assert(auth_key_filename_is_valid("a-.auth_private"));
+ /* Invalid extension. */
+ tt_assert(!auth_key_filename_is_valid("a.ath_private"));
+ /* Nothing before the extension. */
+ tt_assert(!auth_key_filename_is_valid(".auth_private"));
+
+ done:
+ ;
+}
+
+static void
+test_parse_auth_file_content(void *arg)
+{
+ hs_client_service_authorization_t *auth = NULL;
+
+ (void) arg;
+
+ /* Valid authorized client. */
+ auth = parse_auth_file_content(
+ "4acth47i6kxnvkewtm6q7ib2s3ufpo5sqbsnzjpbi7utijcltosqemad:descriptor:"
+ "x25519:zdsyvn2jq534ugyiuzgjy4267jbtzcjbsgedhshzx5mforyxtryq");
+ tt_assert(auth);
+
+ /* Wrong number of fields. */
+ tt_assert(!parse_auth_file_content("a:b"));
+ /* Wrong auth type. */
+ tt_assert(!parse_auth_file_content(
+ "4acth47i6kxnvkewtm6q7ib2s3ufpo5sqbsnzjpbi7utijcltosqemad:x:"
+ "x25519:zdsyvn2jq534ugyiuzgjy4267jbtzcjbsgedhshzx5mforyxtryq"));
+ /* Wrong key type. */
+ tt_assert(!parse_auth_file_content(
+ "4acth47i6kxnvkewtm6q7ib2s3ufpo5sqbsnzjpbi7utijcltosqemad:descriptor:"
+ "x:zdsyvn2jq534ugyiuzgjy4267jbtzcjbsgedhshzx5mforyxtryq"));
+ /* Some malformed string. */
+ tt_assert(!parse_auth_file_content("xx:descriptor:x25519:aa=="));
+ /* Bigger key than it should be */
+ tt_assert(!parse_auth_file_content("xx:descriptor:x25519:"
+ "vjqea4jbhwwc4hto7ekyvqfbeodghbaq6nxi45hz4wr3qvhqv3yqa"));
+ done:
+ tor_free(auth);
+}
+
+static char *
+mock_read_file_to_str(const char *filename, int flags, struct stat *stat_out)
+{
+ char *ret = NULL;
+
+ (void) flags;
+ (void) stat_out;
+
+ if (!strcmp(filename, get_fname("auth_keys" PATH_SEPARATOR
+ "client1.auth_private"))) {
+ ret = tor_strdup(
+ "4acth47i6kxnvkewtm6q7ib2s3ufpo5sqbsnzjpbi7utijcltosqemad:descriptor:"
+ "x25519:zdsyvn2jq534ugyiuzgjy4267jbtzcjbsgedhshzx5mforyxtryq");
+ goto done;
+ }
+
+ if (!strcmp(filename, get_fname("auth_keys" PATH_SEPARATOR "dummy.xxx"))) {
+ ret = tor_strdup(
+ "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx:descriptor:"
+ "x25519:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
+ goto done;
+ }
+
+ if (!strcmp(filename, get_fname("auth_keys" PATH_SEPARATOR
+ "client2.auth_private"))) {
+ ret = tor_strdup(
+ "25njqamcweflpvkl73j4szahhihoc4xt3ktcgjnpaingr5yhkenl5sid:descriptor:"
+ "x25519:fdreqzjqso7d2ac7qscrxfl5qfpamdvgy5d6cxejcgzc3hvhurmq");
+ goto done;
+ }
+
+ done:
+ return ret;
+}
+
+static int
+mock_check_private_dir(const char *dirname, cpd_check_t check,
+ const char *effective_user)
+{
+ (void) dirname;
+ (void) check;
+ (void) effective_user;
+
+ return 0;
+}
+
+static smartlist_t *
+mock_tor_listdir(const char *dirname)
+{
+ smartlist_t *file_list = smartlist_new();
+
+ (void) dirname;
+
+ smartlist_add(file_list, tor_strdup("client1.auth_private"));
+ smartlist_add(file_list, tor_strdup("dummy.xxx"));
+ smartlist_add(file_list, tor_strdup("client2.auth_private"));
+
+ return file_list;
+}
+
+static void
+test_config_client_authorization(void *arg)
+{
+ int ret;
+ char *conf = NULL;
+ ed25519_public_key_t pk1, pk2;
+ digest256map_t *global_map = NULL;
+ char *key_dir = tor_strdup(get_fname("auth_keys"));
+
+ (void) arg;
+
+ MOCK(read_file_to_str, mock_read_file_to_str);
+ MOCK(tor_listdir, mock_tor_listdir);
+ MOCK(check_private_dir, mock_check_private_dir);
+
+#define conf_fmt \
+ "ClientOnionAuthDir %s\n"
+
+ tor_asprintf(&conf, conf_fmt, key_dir);
+ ret = helper_config_client(conf, 0);
+ tor_free(conf);
+ tt_int_op(ret, OP_EQ, 0);
+
+#undef conf_fmt
+
+ global_map = get_hs_client_auths_map();
+ tt_int_op(digest256map_size(global_map), OP_EQ, 2);
+
+ hs_parse_address("4acth47i6kxnvkewtm6q7ib2s3ufpo5sqbsnzjpbi7utijcltosqemad",
+ &pk1, NULL, NULL);
+ hs_parse_address("25njqamcweflpvkl73j4szahhihoc4xt3ktcgjnpaingr5yhkenl5sid",
+ &pk2, NULL, NULL);
+
+ tt_assert(digest256map_get(global_map, pk1.pubkey));
+ tt_assert(digest256map_get(global_map, pk2.pubkey));
+
+ done:
+ tor_free(key_dir);
+ hs_free_all();
+ UNMOCK(read_file_to_str);
+ UNMOCK(tor_listdir);
+ UNMOCK(check_private_dir);
+}
+
+static entry_connection_t *
+helper_build_socks_connection(const ed25519_public_key_t *service_pk,
+ int conn_state)
+{
+ entry_connection_t *socks = entry_connection_new(CONN_TYPE_AP, AF_INET);
+ ENTRY_TO_EDGE_CONN(socks)->hs_ident = hs_ident_edge_conn_new(service_pk);
+ TO_CONN(ENTRY_TO_EDGE_CONN(socks))->state = conn_state;
+ smartlist_add(get_connection_array(), &socks->edge_.base_);
+ return socks;
+}
+
+static void
+test_desc_has_arrived_cleanup(void *arg)
+{
+ /* The goal of this test is to make sure we clean up everything in between
+ * two descriptors from the same .onion. Because intro points can change
+ * from one descriptor to another, once we received a new descriptor, we
+ * need to cleanup the remaining circuits so they aren't used or selected
+ * when establishing a connection with the newly stored descriptor.
+ *
+ * This test was created because of #27410. */
+
+ int ret;
+ char *desc_str = NULL;
+ hs_descriptor_t *desc = NULL;
+ const hs_descriptor_t *cached_desc;
+ ed25519_keypair_t signing_kp;
+ entry_connection_t *socks1 = NULL, *socks2 = NULL;
+ hs_ident_dir_conn_t hs_dir_ident;
+
+ (void) arg;
+
+ hs_init();
+
+ MOCK(networkstatus_get_live_consensus,
+ mock_networkstatus_get_live_consensus);
+ MOCK(connection_mark_unattached_ap_,
+ mock_connection_mark_unattached_ap_);
+ MOCK(router_have_minimum_dir_info,
+ mock_router_have_minimum_dir_info_true);
+
+ /* Set consensus time before our time so the cache lookup can always
+ * validate that the entry is not expired. */
+ parse_rfc1123_time("Sat, 26 Oct 1985 13:00:00 UTC", &mock_ns.valid_after);
+ parse_rfc1123_time("Sat, 26 Oct 1985 14:00:00 UTC", &mock_ns.fresh_until);
+ parse_rfc1123_time("Sat, 26 Oct 1985 16:00:00 UTC", &mock_ns.valid_until);
+
+ /* Build a descriptor for a specific .onion. */
+ ret = ed25519_keypair_generate(&signing_kp, 0);
+ tt_int_op(ret, OP_EQ, 0);
+ desc = hs_helper_build_hs_desc_with_ip(&signing_kp);
+ tt_assert(desc);
+ ret = hs_desc_encode_descriptor(desc, &signing_kp, NULL, &desc_str);
+ tt_int_op(ret, OP_EQ, 0);
+
+ /* Store in the client cache. */
+ ret = hs_cache_store_as_client(desc_str, &signing_kp.pubkey);
+ tt_int_op(ret, OP_EQ, 0);
+ cached_desc = hs_cache_lookup_as_client(&signing_kp.pubkey);
+ tt_assert(cached_desc);
+ hs_helper_desc_equal(desc, cached_desc);
+
+ /* Create two SOCKS connection for the same .onion both in the waiting for a
+ * descriptor state. */
+ socks1 = helper_build_socks_connection(&signing_kp.pubkey,
+ AP_CONN_STATE_RENDDESC_WAIT);
+ tt_assert(socks1);
+ socks2 = helper_build_socks_connection(&signing_kp.pubkey,
+ AP_CONN_STATE_RENDDESC_WAIT);
+ tt_assert(socks2);
+
+ /* Now, we'll make the intro points in the current descriptor unusable so
+ * the hs_client_desc_has_arrived() will take the right code path that we
+ * want to test that is the fetched descriptor has bad intro points. */
+ SMARTLIST_FOREACH_BEGIN(desc->encrypted_data.intro_points,
+ hs_desc_intro_point_t *, ip) {
+ hs_cache_client_intro_state_note(&signing_kp.pubkey,
+ &ip->auth_key_cert->signed_key,
+ INTRO_POINT_FAILURE_GENERIC);
+ } SMARTLIST_FOREACH_END(ip);
+
+ /* Simulate that a new descriptor just arrived. We should have both of our
+ * SOCKS connection to be ended with a resolved failed. */
+ hs_ident_dir_conn_init(&signing_kp.pubkey,
+ &desc->plaintext_data.blinded_pubkey, &hs_dir_ident);
+ hs_client_desc_has_arrived(&hs_dir_ident);
+ tt_int_op(socks1->edge_.end_reason, OP_EQ, END_STREAM_REASON_RESOLVEFAILED);
+ /* XXX: MUST work with OP_EQ. */
+ tt_int_op(socks2->edge_.end_reason, OP_EQ, END_STREAM_REASON_RESOLVEFAILED);
+
+ /* Now let say tor cleans up the intro state cache which resets all intro
+ * point failure count. */
+ hs_cache_client_intro_state_purge();
+
+ /* Retrying all SOCKS which should basically do nothing since we don't have
+ * any pending SOCKS connection in AP_CONN_STATE_RENDDESC_WAIT state. */
+ /* XXX: BUG() is triggered here, shouldn't if socks2 wasn't alive. */
+ retry_all_socks_conn_waiting_for_desc();
+
+ done:
+ connection_free_minimal(ENTRY_TO_CONN(socks1));
+ connection_free_minimal(ENTRY_TO_CONN(socks2));
+ hs_descriptor_free(desc);
+ tor_free(desc_str);
+ hs_free_all();
+
+ UNMOCK(networkstatus_get_live_consensus);
+ UNMOCK(connection_mark_unattached_ap_);
+ UNMOCK(router_have_minimum_dir_info);
+}
+
struct testcase_t hs_client_tests[] = {
{ "e2e_rend_circuit_setup_legacy", test_e2e_rend_circuit_setup_legacy,
TT_FORK, NULL, NULL },
@@ -594,6 +894,14 @@ struct testcase_t hs_client_tests[] = {
TT_FORK, NULL, NULL },
{ "descriptor_fetch", test_descriptor_fetch,
TT_FORK, NULL, NULL },
+ { "auth_key_filename_is_valid", test_auth_key_filename_is_valid, TT_FORK,
+ NULL, NULL },
+ { "parse_auth_file_content", test_parse_auth_file_content, TT_FORK,
+ NULL, NULL },
+ { "config_client_authorization", test_config_client_authorization,
+ TT_FORK, NULL, NULL },
+ { "desc_has_arrived_cleanup", test_desc_has_arrived_cleanup,
+ TT_FORK, NULL, NULL },
+
END_OF_TESTCASES
};
-
diff --git a/src/test/test_hs_common.c b/src/test/test_hs_common.c
index 16803dbd16..95f7ed14ba 100644
--- a/src/test/test_hs_common.c
+++ b/src/test/test_hs_common.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017, The Tor Project, Inc. */
+/* Copyright (c) 2017-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
/**
@@ -11,25 +11,34 @@
#define HS_SERVICE_PRIVATE
#define NODELIST_PRIVATE
-#include "test.h"
-#include "test_helpers.h"
-#include "log_test_helpers.h"
-#include "hs_test_helpers.h"
-
-#include "connection_edge.h"
-#include "hs_common.h"
-#include "hs_client.h"
-#include "hs_service.h"
-#include "config.h"
-#include "networkstatus.h"
-#include "directory.h"
-#include "dirvote.h"
-#include "nodelist.h"
-#include "routerlist.h"
-#include "statefile.h"
-#include "circuitlist.h"
-#include "shared_random.h"
-#include "util.h"
+#include "test/test.h"
+#include "test/test_helpers.h"
+#include "test/log_test_helpers.h"
+#include "test/hs_test_helpers.h"
+
+#include "core/or/connection_edge.h"
+#include "lib/crypt_ops/crypto_format.h"
+#include "lib/crypt_ops/crypto_rand.h"
+#include "feature/hs/hs_common.h"
+#include "feature/hs/hs_client.h"
+#include "feature/hs/hs_service.h"
+#include "app/config/config.h"
+#include "feature/nodelist/networkstatus.h"
+#include "feature/dirclient/dirclient.h"
+#include "feature/dirauth/dirvote.h"
+#include "feature/nodelist/nodelist.h"
+#include "feature/nodelist/routerlist.h"
+#include "app/config/statefile.h"
+#include "core/or/circuitlist.h"
+#include "feature/dirauth/shared_random.h"
+#include "feature/dircommon/voting_schedule.h"
+
+#include "feature/nodelist/microdesc_st.h"
+#include "feature/nodelist/networkstatus_st.h"
+#include "feature/nodelist/node_st.h"
+#include "app/config/or_state_st.h"
+#include "feature/nodelist/routerinfo_st.h"
+#include "feature/nodelist/routerstatus_st.h"
/** Test the validation of HS v3 addresses */
static void
@@ -364,11 +373,8 @@ mock_networkstatus_get_live_consensus(time_t now)
static void
test_responsible_hsdirs(void *arg)
{
- time_t now = approx_time();
smartlist_t *responsible_dirs = smartlist_new();
networkstatus_t *ns = NULL;
- int retval;
-
(void) arg;
hs_init();
@@ -390,12 +396,12 @@ test_responsible_hsdirs(void *arg)
helper_add_hsdir_to_networkstatus(ns, 3, "spyro", 0);
}
- ed25519_keypair_t kp;
- retval = ed25519_keypair_generate(&kp, 0);
- tt_int_op(retval, OP_EQ , 0);
+ /* Use a fixed time period and pub key so we always take the same path */
+ ed25519_public_key_t pubkey;
+ uint64_t time_period_num = 17653; // 2 May, 2018, 14:00.
+ memset(&pubkey, 42, sizeof(pubkey));
- uint64_t time_period_num = hs_get_time_period_num(now);
- hs_get_responsible_hsdirs(&kp.pubkey, time_period_num,
+ hs_get_responsible_hsdirs(&pubkey, time_period_num,
0, 0, responsible_dirs);
/* Make sure that we only found 2 responsible HSDirs.
@@ -422,11 +428,13 @@ mock_directory_initiate_request(directory_request_t *req)
static int
mock_hs_desc_encode_descriptor(const hs_descriptor_t *desc,
- const ed25519_keypair_t *signing_kp,
- char **encoded_out)
+ const ed25519_keypair_t *signing_kp,
+ const uint8_t *descriptor_cookie,
+ char **encoded_out)
{
(void)desc;
(void)signing_kp;
+ (void)descriptor_cookie;
tor_asprintf(encoded_out, "lulu");
return 0;
@@ -817,7 +825,7 @@ test_time_between_tp_and_srv(void *arg)
tt_int_op(ret, OP_EQ, 0);
ret = parse_rfc1123_time("Sat, 26 Oct 1985 01:00:00 UTC", &ns.fresh_until);
tt_int_op(ret, OP_EQ, 0);
- dirvote_recalculate_timing(get_options(), ns.valid_after);
+ voting_schedule_recalculate_timing(get_options(), ns.valid_after);
ret = hs_in_period_between_tp_and_srv(&ns, 0);
tt_int_op(ret, OP_EQ, 0);
@@ -825,7 +833,7 @@ test_time_between_tp_and_srv(void *arg)
tt_int_op(ret, OP_EQ, 0);
ret = parse_rfc1123_time("Sat, 26 Oct 1985 12:00:00 UTC", &ns.fresh_until);
tt_int_op(ret, OP_EQ, 0);
- dirvote_recalculate_timing(get_options(), ns.valid_after);
+ voting_schedule_recalculate_timing(get_options(), ns.valid_after);
ret = hs_in_period_between_tp_and_srv(&ns, 0);
tt_int_op(ret, OP_EQ, 0);
@@ -833,7 +841,7 @@ test_time_between_tp_and_srv(void *arg)
tt_int_op(ret, OP_EQ, 0);
ret = parse_rfc1123_time("Sat, 26 Oct 1985 13:00:00 UTC", &ns.fresh_until);
tt_int_op(ret, OP_EQ, 0);
- dirvote_recalculate_timing(get_options(), ns.valid_after);
+ voting_schedule_recalculate_timing(get_options(), ns.valid_after);
ret = hs_in_period_between_tp_and_srv(&ns, 0);
tt_int_op(ret, OP_EQ, 1);
@@ -841,7 +849,7 @@ test_time_between_tp_and_srv(void *arg)
tt_int_op(ret, OP_EQ, 0);
ret = parse_rfc1123_time("Sat, 27 Oct 1985 00:00:00 UTC", &ns.fresh_until);
tt_int_op(ret, OP_EQ, 0);
- dirvote_recalculate_timing(get_options(), ns.valid_after);
+ voting_schedule_recalculate_timing(get_options(), ns.valid_after);
ret = hs_in_period_between_tp_and_srv(&ns, 0);
tt_int_op(ret, OP_EQ, 1);
@@ -849,7 +857,7 @@ test_time_between_tp_and_srv(void *arg)
tt_int_op(ret, OP_EQ, 0);
ret = parse_rfc1123_time("Sat, 27 Oct 1985 01:00:00 UTC", &ns.fresh_until);
tt_int_op(ret, OP_EQ, 0);
- dirvote_recalculate_timing(get_options(), ns.valid_after);
+ voting_schedule_recalculate_timing(get_options(), ns.valid_after);
ret = hs_in_period_between_tp_and_srv(&ns, 0);
tt_int_op(ret, OP_EQ, 0);
@@ -1336,7 +1344,12 @@ run_reachability_scenario(const reachability_cfg_t *cfg, int num_scenario)
&mock_service_ns->valid_until);
set_consensus_times(cfg->service_valid_until,
&mock_service_ns->fresh_until);
- dirvote_recalculate_timing(get_options(), mock_service_ns->valid_after);
+ voting_schedule_recalculate_timing(get_options(),
+ mock_service_ns->valid_after);
+ /* Check that service is in the right time period point */
+ tt_int_op(hs_in_period_between_tp_and_srv(mock_service_ns, 0), OP_EQ,
+ cfg->service_in_new_tp);
+
/* Set client consensus time. */
set_consensus_times(cfg->client_valid_after,
&mock_client_ns->valid_after);
@@ -1344,11 +1357,9 @@ run_reachability_scenario(const reachability_cfg_t *cfg, int num_scenario)
&mock_client_ns->valid_until);
set_consensus_times(cfg->client_valid_until,
&mock_client_ns->fresh_until);
- dirvote_recalculate_timing(get_options(), mock_client_ns->valid_after);
-
- /* New time period checks for this scenario. */
- tt_int_op(hs_in_period_between_tp_and_srv(mock_service_ns, 0), OP_EQ,
- cfg->service_in_new_tp);
+ voting_schedule_recalculate_timing(get_options(),
+ mock_client_ns->valid_after);
+ /* Check that client is in the right time period point */
tt_int_op(hs_in_period_between_tp_and_srv(mock_client_ns, 0), OP_EQ,
cfg->client_in_new_tp);
@@ -1359,7 +1370,8 @@ run_reachability_scenario(const reachability_cfg_t *cfg, int num_scenario)
mock_service_ns->sr_info.previous_srv = cfg->service_previous_srv;
/* Initialize a service to get keys. */
- service = helper_init_service(time(NULL));
+ update_approx_time(mock_service_ns->valid_after);
+ service = helper_init_service(mock_service_ns->valid_after+1);
/*
* === Client setup ===
@@ -1568,7 +1580,7 @@ helper_set_consensus_and_system_time(networkstatus_t *ns, int position)
} else {
tt_assert(0);
}
- dirvote_recalculate_timing(get_options(), ns->valid_after);
+ voting_schedule_recalculate_timing(get_options(), ns->valid_after);
/* Set system time: pretend to be just 2 minutes before consensus expiry */
real_time = ns->valid_until - 120;
@@ -1825,4 +1837,3 @@ struct testcase_t hs_common_tests[] = {
END_OF_TESTCASES
};
-
diff --git a/src/test/test_hs_config.c b/src/test/test_hs_config.c
index a76be301d3..553b96758a 100644
--- a/src/test/test_hs_config.c
+++ b/src/test/test_hs_config.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016, The Tor Project, Inc. */
+/* Copyright (c) 2016-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
/**
@@ -9,15 +9,15 @@
#define CONFIG_PRIVATE
#define HS_SERVICE_PRIVATE
-#include "test.h"
-#include "test_helpers.h"
-#include "log_test_helpers.h"
+#include "test/test.h"
+#include "test/test_helpers.h"
+#include "test/log_test_helpers.h"
-#include "config.h"
-#include "hs_common.h"
-#include "hs_config.h"
-#include "hs_service.h"
-#include "rendservice.h"
+#include "app/config/config.h"
+#include "feature/hs/hs_common.h"
+#include "feature/hs/hs_config.h"
+#include "feature/hs/hs_service.h"
+#include "feature/rend/rendservice.h"
static int
helper_config_service(const char *conf, int validate_only)
@@ -139,6 +139,20 @@ test_invalid_service(void *arg)
teardown_capture_of_logs();
}
+ /* Bad target addr:port separation. */
+ {
+ const char *conf =
+ "HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs1\n"
+ "HiddenServiceVersion 2\n"
+ "HiddenServicePort 80 127.0.0.1 8000\n";
+ setup_full_capture_of_logs(LOG_WARN);
+ ret = helper_config_service(conf, 1);
+ tt_int_op(ret, OP_EQ, -1);
+ expect_log_msg_containing("HiddenServicePort parse error: "
+ "invalid port mapping");
+ teardown_capture_of_logs();
+ }
+
/* Out of order directives. */
{
const char *conf =
diff --git a/src/test/test_hs_control.c b/src/test/test_hs_control.c
index 207a55de6d..48402030bf 100644
--- a/src/test/test_hs_control.c
+++ b/src/test/test_hs_control.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017, The Tor Project, Inc. */
+/* Copyright (c) 2017-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
/**
@@ -7,23 +7,20 @@
**/
#define CONTROL_PRIVATE
-#define CIRCUITBUILD_PRIVATE
-#define RENDCOMMON_PRIVATE
-#define RENDSERVICE_PRIVATE
-#define HS_SERVICE_PRIVATE
-
-#include "or.h"
-#include "test.h"
-#include "control.h"
-#include "config.h"
-#include "hs_common.h"
-#include "hs_control.h"
-#include "nodelist.h"
-//#include "rendcommon.h"
-//#include "rendservice.h"
-//#include "routerset.h"
-//#include "circuitbuild.h"
-#include "test_helpers.h"
+
+#include "core/or/or.h"
+#include "test/test.h"
+#include "feature/control/control.h"
+#include "app/config/config.h"
+#include "feature/hs/hs_common.h"
+#include "feature/hs/hs_control.h"
+#include "feature/nodelist/nodelist.h"
+
+#include "feature/nodelist/node_st.h"
+#include "feature/nodelist/routerstatus_st.h"
+#include "lib/crypt_ops/crypto_format.h"
+
+#include "test/test_helpers.h"
/* mock ID digest and longname for node that's in nodelist */
#define HSDIR_EXIST_ID \
@@ -76,9 +73,8 @@ mock_node_get_by_id(const char *digest)
{
static node_t node;
memcpy(node.identity, digest, DIGEST_LEN);
- node.hsdir_index = tor_malloc_zero(sizeof(hsdir_index_t));
- memset(node.hsdir_index->fetch, 'C', DIGEST256_LEN);
- memset(node.hsdir_index->store_first, 'D', DIGEST256_LEN);
+ memset(node.hsdir_index.fetch, 'C', DIGEST256_LEN);
+ memset(node.hsdir_index.store_first, 'D', DIGEST256_LEN);
return &node;
}
@@ -196,4 +192,3 @@ struct testcase_t hs_control_tests[] = {
END_OF_TESTCASES
};
-
diff --git a/src/test/test_hs_descriptor.c b/src/test/test_hs_descriptor.c
index 8772461f90..428ca1024b 100644
--- a/src/test/test_hs_descriptor.c
+++ b/src/test/test_hs_descriptor.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016-2017, The Tor Project, Inc. */
+/* Copyright (c) 2016-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
/**
@@ -8,16 +8,19 @@
#define HS_DESCRIPTOR_PRIVATE
-#include "crypto_ed25519.h"
-#include "ed25519_cert.h"
-#include "or.h"
-#include "hs_descriptor.h"
-#include "test.h"
-#include "torcert.h"
+#include "lib/crypt_ops/crypto_ed25519.h"
+#include "lib/crypt_ops/crypto_format.h"
+#include "lib/crypt_ops/crypto_digest.h"
+#include "lib/crypt_ops/crypto_rand.h"
+#include "trunnel/ed25519_cert.h"
+#include "core/or/or.h"
+#include "feature/hs/hs_descriptor.h"
+#include "test/test.h"
+#include "feature/nodelist/torcert.h"
-#include "hs_test_helpers.h"
-#include "test_helpers.h"
-#include "log_test_helpers.h"
+#include "test/hs_test_helpers.h"
+#include "test/test_helpers.h"
+#include "test/log_test_helpers.h"
#ifdef HAVE_CFLAG_WOVERLENGTH_STRINGS
DISABLE_GCC_WARNING(overlength-strings)
@@ -27,6 +30,13 @@ DISABLE_GCC_WARNING(overlength-strings)
#include "test_hs_descriptor.inc"
ENABLE_GCC_WARNING(overlength-strings)
+/* Mock function to fill all bytes with 1 */
+static void
+mock_crypto_strongest_rand(uint8_t *out, size_t out_len)
+{
+ memset(out, 1, out_len);
+}
+
/* Test certificate encoding put in a descriptor. */
static void
test_cert_encoding(void *arg)
@@ -281,7 +291,6 @@ static void
test_encode_descriptor(void *arg)
{
int ret;
- char *encoded = NULL;
ed25519_keypair_t signing_kp;
hs_descriptor_t *desc = NULL;
@@ -290,19 +299,38 @@ test_encode_descriptor(void *arg)
ret = ed25519_keypair_generate(&signing_kp, 0);
tt_int_op(ret, OP_EQ, 0);
desc = hs_helper_build_hs_desc_with_ip(&signing_kp);
- ret = hs_desc_encode_descriptor(desc, &signing_kp, &encoded);
- tt_int_op(ret, OP_EQ, 0);
- tt_assert(encoded);
+ {
+ char *encoded = NULL;
+ ret = hs_desc_encode_descriptor(desc, &signing_kp, NULL, &encoded);
+ tt_int_op(ret, OP_EQ, 0);
+ tt_assert(encoded);
+
+ tor_free(encoded);
+ }
+
+ {
+ char *encoded = NULL;
+ uint8_t descriptor_cookie[HS_DESC_DESCRIPTOR_COOKIE_LEN];
+
+ crypto_strongest_rand(descriptor_cookie, sizeof(descriptor_cookie));
+
+ ret = hs_desc_encode_descriptor(desc, &signing_kp,
+ descriptor_cookie, &encoded);
+ tt_int_op(ret, OP_EQ, 0);
+ tt_assert(encoded);
+
+ tor_free(encoded);
+ }
done:
hs_descriptor_free(desc);
- tor_free(encoded);
}
static void
test_decode_descriptor(void *arg)
{
int ret;
+ int i;
char *encoded = NULL;
ed25519_keypair_t signing_kp;
hs_descriptor_t *desc = NULL;
@@ -320,14 +348,15 @@ test_decode_descriptor(void *arg)
subcredential);
/* Give some bad stuff to the decoding function. */
- ret = hs_desc_decode_descriptor("hladfjlkjadf", subcredential, &decoded);
+ ret = hs_desc_decode_descriptor("hladfjlkjadf", subcredential,
+ NULL, &decoded);
tt_int_op(ret, OP_EQ, -1);
- ret = hs_desc_encode_descriptor(desc, &signing_kp, &encoded);
+ ret = hs_desc_encode_descriptor(desc, &signing_kp, NULL, &encoded);
tt_int_op(ret, OP_EQ, 0);
tt_assert(encoded);
- ret = hs_desc_decode_descriptor(encoded, subcredential, &decoded);
+ ret = hs_desc_decode_descriptor(encoded, subcredential, NULL, &decoded);
tt_int_op(ret, OP_EQ, 0);
tt_assert(decoded);
@@ -343,13 +372,84 @@ test_decode_descriptor(void *arg)
desc_no_ip = hs_helper_build_hs_desc_no_ip(&signing_kp_no_ip);
tt_assert(desc_no_ip);
tor_free(encoded);
- ret = hs_desc_encode_descriptor(desc_no_ip, &signing_kp_no_ip, &encoded);
+ ret = hs_desc_encode_descriptor(desc_no_ip, &signing_kp_no_ip,
+ NULL, &encoded);
+ tt_int_op(ret, OP_EQ, 0);
+ tt_assert(encoded);
+ hs_descriptor_free(decoded);
+ ret = hs_desc_decode_descriptor(encoded, subcredential, NULL, &decoded);
+ tt_int_op(ret, OP_EQ, 0);
+ tt_assert(decoded);
+ }
+
+ /* Decode a descriptor with auth clients. */
+ {
+ uint8_t descriptor_cookie[HS_DESC_DESCRIPTOR_COOKIE_LEN];
+ curve25519_keypair_t auth_ephemeral_kp;
+ curve25519_keypair_t client_kp, invalid_client_kp;
+ smartlist_t *clients;
+ hs_desc_authorized_client_t *client, *fake_client;
+ client = tor_malloc_zero(sizeof(hs_desc_authorized_client_t));
+
+ /* Prepare all the keys needed to build the auth client. */
+ curve25519_keypair_generate(&auth_ephemeral_kp, 0);
+ curve25519_keypair_generate(&client_kp, 0);
+ curve25519_keypair_generate(&invalid_client_kp, 0);
+ crypto_strongest_rand(descriptor_cookie, HS_DESC_DESCRIPTOR_COOKIE_LEN);
+
+ memcpy(&desc->superencrypted_data.auth_ephemeral_pubkey,
+ &auth_ephemeral_kp.pubkey, CURVE25519_PUBKEY_LEN);
+
+ hs_helper_get_subcred_from_identity_keypair(&signing_kp,
+ subcredential);
+
+ /* Build and add the auth client to the descriptor. */
+ clients = desc->superencrypted_data.clients;
+ if (!clients) {
+ clients = smartlist_new();
+ }
+ hs_desc_build_authorized_client(subcredential,
+ &client_kp.pubkey,
+ &auth_ephemeral_kp.seckey,
+ descriptor_cookie, client);
+ smartlist_add(clients, client);
+
+ /* We need to add fake auth clients here. */
+ for (i=0; i < 15; ++i) {
+ fake_client = hs_desc_build_fake_authorized_client();
+ smartlist_add(clients, fake_client);
+ }
+ desc->superencrypted_data.clients = clients;
+
+ /* Test the encoding/decoding in the following lines. */
+ tor_free(encoded);
+ ret = hs_desc_encode_descriptor(desc, &signing_kp,
+ descriptor_cookie, &encoded);
tt_int_op(ret, OP_EQ, 0);
tt_assert(encoded);
+
+ /* If we do not have the client secret key, the decoding must fail. */
+ hs_descriptor_free(decoded);
+ ret = hs_desc_decode_descriptor(encoded, subcredential,
+ NULL, &decoded);
+ tt_int_op(ret, OP_LT, 0);
+ tt_assert(!decoded);
+
+ /* If we have an invalid client secret key, the decoding must fail. */
hs_descriptor_free(decoded);
- ret = hs_desc_decode_descriptor(encoded, subcredential, &decoded);
+ ret = hs_desc_decode_descriptor(encoded, subcredential,
+ &invalid_client_kp.seckey, &decoded);
+ tt_int_op(ret, OP_LT, 0);
+ tt_assert(!decoded);
+
+ /* If we have the client secret key, the decoding must succeed and the
+ * decoded descriptor must be correct. */
+ ret = hs_desc_decode_descriptor(encoded, subcredential,
+ &client_kp.seckey, &decoded);
tt_int_op(ret, OP_EQ, 0);
tt_assert(decoded);
+
+ hs_helper_desc_equal(desc, decoded);
}
done:
@@ -575,6 +675,8 @@ test_decode_bad_signature(void *arg)
(void) arg;
+ memset(&desc_plaintext, 0, sizeof(desc_plaintext));
+
/* Update approx time to dodge cert expiration */
update_approx_time(1502661599);
@@ -585,7 +687,7 @@ test_decode_bad_signature(void *arg)
teardown_capture_of_logs();
done:
- desc_plaintext_data_free_contents(&desc_plaintext);
+ hs_desc_plaintext_data_free_contents(&desc_plaintext);
}
static void
@@ -761,101 +863,69 @@ test_desc_signature(void *arg)
tor_free(data);
}
-/* bad desc auth type */
-static const char bad_superencrypted_text1[] = "desc-auth-type scoobysnack\n"
- "desc-auth-ephemeral-key A/O8DVtnUheb3r1JqoB8uJB7wxXL1XJX3eny4yB+eFA=\n"
- "auth-client oiNrQB8WwKo S5D02W7vKgiWIMygrBl8RQ FB//SfOBmLEx1kViEWWL1g\n"
- "encrypted\n"
- "-----BEGIN MESSAGE-----\n"
- "YmVpbmcgb24gbW91bnRhaW5zLCB0aGlua2luZyBhYm91dCBjb21wdXRlcnMsIGlzIG5vdC"
- "BiYWQgYXQgYWxs\n"
- "-----END MESSAGE-----\n";
-
-/* bad ephemeral key */
-static const char bad_superencrypted_text2[] = "desc-auth-type x25519\n"
- "desc-auth-ephemeral-key differentalphabet\n"
- "auth-client oiNrQB8WwKo S5D02W7vKgiWIMygrBl8RQ FB//SfOBmLEx1kViEWWL1g\n"
- "encrypted\n"
- "-----BEGIN MESSAGE-----\n"
- "YmVpbmcgb24gbW91bnRhaW5zLCB0aGlua2luZyBhYm91dCBjb21wdXRlcnMsIGlzIG5vdC"
- "BiYWQgYXQgYWxs\n"
- "-----END MESSAGE-----\n";
-
-/* bad encrypted msg */
-static const char bad_superencrypted_text3[] = "desc-auth-type x25519\n"
- "desc-auth-ephemeral-key A/O8DVtnUheb3r1JqoB8uJB7wxXL1XJX3eny4yB+eFA=\n"
- "auth-client oiNrQB8WwKo S5D02W7vKgiWIMygrBl8RQ FB//SfOBmLEx1kViEWWL1g\n"
- "encrypted\n"
- "-----BEGIN MESSAGE-----\n"
- "SO SMALL NOT GOOD\n"
- "-----END MESSAGE-----\n";
-
-static const char correct_superencrypted_text[] = "desc-auth-type x25519\n"
- "desc-auth-ephemeral-key A/O8DVtnUheb3r1JqoB8uJB7wxXL1XJX3eny4yB+eFA=\n"
- "auth-client oiNrQB8WwKo S5D02W7vKgiWIMygrBl8RQ FB//SfOBmLEx1kViEWWL1g\n"
- "auth-client Od09Qu636Qo /PKLzqewAdS/+0+vZC+MvQ dpw4NFo13zDnuPz45rxrOg\n"
- "auth-client JRr840iGYN0 8s8cxYqF7Lx23+NducC4Qg zAafl4wPLURkuEjJreZq1g\n"
- "encrypted\n"
- "-----BEGIN MESSAGE-----\n"
- "YmVpbmcgb24gbW91bnRhaW5zLCB0aGlua2luZyBhYm91dCBjb21wdXRlcnMsIGlzIG5vdC"
- "BiYWQgYXQgYWxs\n"
- "-----END MESSAGE-----\n";
-
-static const char correct_encrypted_plaintext[] = "being on mountains, "
- "thinking about computers, is not bad at all";
-
static void
-test_parse_hs_desc_superencrypted(void *arg)
+test_build_authorized_client(void *arg)
{
+ int ret;
+ hs_desc_authorized_client_t *desc_client = NULL;
+ uint8_t descriptor_cookie[HS_DESC_DESCRIPTOR_COOKIE_LEN];
+ curve25519_secret_key_t auth_ephemeral_sk;
+ curve25519_secret_key_t client_auth_sk;
+ curve25519_public_key_t client_auth_pk;
+ const char ephemeral_sk_b16[] =
+ "d023b674d993a5c8446bd2ca97e9961149b3c0e88c7dc14e8777744dd3468d6a";
+ const char descriptor_cookie_b16[] =
+ "07d087f1d8c68393721f6e70316d3b29";
+ const char client_pubkey_b16[] =
+ "8c1298fa6050e372f8598f6deca32e27b0ad457741422c2629ebb132cf7fae37";
+ uint8_t subcredential[DIGEST256_LEN];
+ char *mem_op_hex_tmp=NULL;
+
(void) arg;
- size_t retval;
- uint8_t *encrypted_out = NULL;
- {
- setup_full_capture_of_logs(LOG_WARN);
- retval = decode_superencrypted(bad_superencrypted_text1,
- strlen(bad_superencrypted_text1),
- &encrypted_out);
- tt_u64_op(retval, OP_EQ, 0);
- tt_ptr_op(encrypted_out, OP_EQ, NULL);
- expect_log_msg_containing("Unrecognized desc auth type");
- teardown_capture_of_logs();
- }
+ ret = curve25519_secret_key_generate(&auth_ephemeral_sk, 0);
+ tt_int_op(ret, OP_EQ, 0);
- {
- setup_full_capture_of_logs(LOG_WARN);
- retval = decode_superencrypted(bad_superencrypted_text2,
- strlen(bad_superencrypted_text2),
- &encrypted_out);
- tt_u64_op(retval, OP_EQ, 0);
- tt_ptr_op(encrypted_out, OP_EQ, NULL);
- expect_log_msg_containing("Bogus desc auth key in HS desc");
- teardown_capture_of_logs();
- }
+ ret = curve25519_secret_key_generate(&client_auth_sk, 0);
+ tt_int_op(ret, OP_EQ, 0);
+ curve25519_public_key_generate(&client_auth_pk, &client_auth_sk);
- {
- setup_full_capture_of_logs(LOG_WARN);
- retval = decode_superencrypted(bad_superencrypted_text3,
- strlen(bad_superencrypted_text3),
- &encrypted_out);
- tt_u64_op(retval, OP_EQ, 0);
- tt_ptr_op(encrypted_out, OP_EQ, NULL);
- expect_log_msg_containing("Length of descriptor\'s encrypted data "
- "is too small.");
- teardown_capture_of_logs();
- }
+ memset(subcredential, 42, sizeof(subcredential));
+
+ desc_client = tor_malloc_zero(sizeof(hs_desc_authorized_client_t));
- /* Now finally the good one */
- retval = decode_superencrypted(correct_superencrypted_text,
- strlen(correct_superencrypted_text),
- &encrypted_out);
+ base16_decode((char *) &auth_ephemeral_sk,
+ sizeof(auth_ephemeral_sk),
+ ephemeral_sk_b16,
+ strlen(ephemeral_sk_b16));
- tt_u64_op(retval, OP_EQ, strlen(correct_encrypted_plaintext));
- tt_mem_op(encrypted_out, OP_EQ, correct_encrypted_plaintext,
- strlen(correct_encrypted_plaintext));
+ base16_decode((char *) descriptor_cookie,
+ sizeof(descriptor_cookie),
+ descriptor_cookie_b16,
+ strlen(descriptor_cookie_b16));
+
+ base16_decode((char *) &client_auth_pk,
+ sizeof(client_auth_pk),
+ client_pubkey_b16,
+ strlen(client_pubkey_b16));
+
+ MOCK(crypto_strongest_rand_, mock_crypto_strongest_rand);
+
+ hs_desc_build_authorized_client(subcredential,
+ &client_auth_pk, &auth_ephemeral_sk,
+ descriptor_cookie, desc_client);
+
+ test_memeq_hex((char *) desc_client->client_id,
+ "EC19B7FF4D2DDA13");
+ test_memeq_hex((char *) desc_client->iv,
+ "01010101010101010101010101010101");
+ test_memeq_hex((char *) desc_client->encrypted_cookie,
+ "B21222BE13F385F355BD07B2381F9F29");
done:
- tor_free(encrypted_out);
+ tor_free(desc_client);
+ tor_free(mem_op_hex_tmp);
+ UNMOCK(crypto_strongest_rand_);
}
struct testcase_t hs_descriptor[] = {
@@ -888,10 +958,8 @@ struct testcase_t hs_descriptor[] = {
NULL, NULL },
{ "desc_signature", test_desc_signature, TT_FORK,
NULL, NULL },
-
- { "parse_hs_desc_superencrypted", test_parse_hs_desc_superencrypted,
- TT_FORK, NULL, NULL },
+ { "build_authorized_client", test_build_authorized_client, TT_FORK,
+ NULL, NULL },
END_OF_TESTCASES
};
-
diff --git a/src/test/test_hs_intropoint.c b/src/test/test_hs_intropoint.c
index ec4dcb4705..628d99bfde 100644
--- a/src/test/test_hs_intropoint.c
+++ b/src/test/test_hs_intropoint.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016-2017, The Tor Project, Inc. */
+/* Copyright (c) 2016-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
/**
@@ -11,28 +11,29 @@
#define RENDSERVICE_PRIVATE
#define CIRCUITLIST_PRIVATE
-#include "test.h"
-#include "log_test_helpers.h"
-#include "crypto.h"
-#include "log_test_helpers.h"
+#include "test/test.h"
+#include "test/log_test_helpers.h"
+#include "lib/crypt_ops/crypto_rand.h"
-#include "or.h"
-#include "circuitlist.h"
-#include "circuituse.h"
+#include "core/or/or.h"
+#include "core/or/circuitlist.h"
+#include "core/or/circuituse.h"
#include "ht.h"
-#include "relay.h"
-#include "rendservice.h"
+#include "core/or/relay.h"
+#include "feature/rend/rendservice.h"
-#include "hs_cell.h"
-#include "hs_circuitmap.h"
-#include "hs_common.h"
-#include "hs_intropoint.h"
-#include "hs_service.h"
+#include "feature/hs/hs_cell.h"
+#include "feature/hs/hs_circuitmap.h"
+#include "feature/hs/hs_common.h"
+#include "feature/hs/hs_intropoint.h"
+#include "feature/hs/hs_service.h"
+
+#include "core/or/or_circuit_st.h"
/* Trunnel. */
-#include "hs/cell_establish_intro.h"
-#include "hs/cell_introduce1.h"
-#include "hs/cell_common.h"
+#include "trunnel/hs/cell_establish_intro.h"
+#include "trunnel/hs/cell_introduce1.h"
+#include "trunnel/hs/cell_common.h"
static size_t
new_establish_intro_cell(const char *circ_nonce,
diff --git a/src/test/test_hs_ntor.c b/src/test/test_hs_ntor.c
index 8eee54d4b4..eeb0491657 100644
--- a/src/test/test_hs_ntor.c
+++ b/src/test/test_hs_ntor.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017, The Tor Project, Inc. */
+/* Copyright (c) 2017-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
/**
@@ -6,11 +6,13 @@
* \brief Test hidden service ntor functionality.
*/
-#include "test.h"
-#include "test_helpers.h"
-#include "log_test_helpers.h"
+#include "test/test.h"
+#include "test/test_helpers.h"
+#include "test/log_test_helpers.h"
+#include "lib/crypt_ops/crypto_curve25519.h"
+#include "lib/crypt_ops/crypto_ed25519.h"
-#include "hs_ntor.h"
+#include "core/crypto/hs_ntor.h"
/* Test the HS ntor handshake. Simulate the sending of an encrypted INTRODUCE1
* cell, and verify the proper derivation of decryption keys on the other end.
@@ -111,4 +113,3 @@ struct testcase_t hs_ntor_tests[] = {
END_OF_TESTCASES
};
-
diff --git a/src/test/test_hs_ntor_cl.c b/src/test/test_hs_ntor_cl.c
index ed1eda58ea..a4915c4f8a 100644
--- a/src/test/test_hs_ntor_cl.c
+++ b/src/test/test_hs_ntor_cl.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017, The Tor Project, Inc. */
+/* Copyright (c) 2017-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
/** This is a wrapper over the little-t-tor HS ntor functions. The wrapper is
@@ -13,13 +13,14 @@
#include <stdlib.h>
#define ONION_NTOR_PRIVATE
-#include "or.h"
-#include "util.h"
-#include "compat.h"
-#include "crypto.h"
-#include "crypto_curve25519.h"
-#include "hs_ntor.h"
-#include "onion_ntor.h"
+#include "core/or/or.h"
+#include "lib/crypt_ops/crypto_cipher.h"
+#include "lib/crypt_ops/crypto_curve25519.h"
+#include "lib/crypt_ops/crypto_ed25519.h"
+#include "lib/crypt_ops/crypto_format.h"
+#include "lib/crypt_ops/crypto_init.h"
+#include "core/crypto/hs_ntor.h"
+#include "core/crypto/onion_ntor.h"
#define N_ARGS(n) STMT_BEGIN { \
if (argc < (n)) { \
@@ -240,7 +241,11 @@ main(int argc, char **argv)
return 1;
}
+ init_logging(1);
curve25519_init();
+ if (crypto_global_init(0, NULL, NULL) < 0)
+ return 1;
+
if (!strcmp(argv[1], "client1")) {
return client1(argc, argv);
} else if (!strcmp(argv[1], "server1")) {
@@ -252,4 +257,3 @@ main(int argc, char **argv)
return 1;
}
}
-
diff --git a/src/test/test_hs_service.c b/src/test/test_hs_service.c
index c1e9f3ced6..bfe50eb3c6 100644
--- a/src/test/test_hs_service.c
+++ b/src/test/test_hs_service.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016-2017, The Tor Project, Inc. */
+/* Copyright (c) 2016-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
/**
@@ -10,51 +10,71 @@
#define CIRCUITLIST_PRIVATE
#define CONFIG_PRIVATE
#define CONNECTION_PRIVATE
+#define CONNECTION_EDGE_PRIVATE
#define CRYPTO_PRIVATE
#define HS_COMMON_PRIVATE
#define HS_SERVICE_PRIVATE
#define HS_INTROPOINT_PRIVATE
#define HS_CIRCUIT_PRIVATE
-#define MAIN_PRIVATE
+#define MAINLOOP_PRIVATE
#define NETWORKSTATUS_PRIVATE
#define STATEFILE_PRIVATE
#define TOR_CHANNEL_INTERNAL_
#define HS_CLIENT_PRIVATE
-#define ROUTERPARSE_PRIVATE
-
-#include "test.h"
-#include "test_helpers.h"
-#include "log_test_helpers.h"
-#include "rend_test_helpers.h"
-#include "hs_test_helpers.h"
-
-#include "or.h"
-#include "config.h"
-#include "circuitbuild.h"
-#include "circuitlist.h"
-#include "circuituse.h"
-#include "crypto.h"
-#include "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"
-#include "hs_intropoint.h"
-#include "hs_ntor.h"
-#include "hs_circuit.h"
-#include "hs_service.h"
-#include "hs_client.h"
-#include "main.h"
-#include "rendservice.h"
-#include "statefile.h"
-#include "shared_random_state.h"
+
+#include "test/test.h"
+#include "test/test_helpers.h"
+#include "test/log_test_helpers.h"
+#include "test/rend_test_helpers.h"
+#include "test/hs_test_helpers.h"
+
+#include "core/or/or.h"
+#include "app/config/config.h"
+#include "app/config/statefile.h"
+#include "core/crypto/hs_ntor.h"
+#include "core/mainloop/connection.h"
+#include "core/mainloop/mainloop.h"
+#include "core/or/circuitbuild.h"
+#include "core/or/circuitlist.h"
+#include "core/or/circuituse.h"
+#include "core/or/connection_edge.h"
+#include "core/or/edge_connection_st.h"
+#include "core/or/relay.h"
+#include "core/or/versions.h"
+#include "feature/dirauth/dirvote.h"
+#include "feature/dirauth/shared_random_state.h"
+#include "feature/dircommon/voting_schedule.h"
+#include "feature/hs/hs_circuit.h"
+#include "feature/hs/hs_circuitmap.h"
+#include "feature/hs/hs_client.h"
+#include "feature/hs/hs_common.h"
+#include "feature/hs/hs_config.h"
+#include "feature/hs/hs_ident.h"
+#include "feature/hs/hs_intropoint.h"
+#include "feature/hs/hs_service.h"
+#include "feature/nodelist/networkstatus.h"
+#include "feature/nodelist/nodelist.h"
+#include "feature/rend/rendservice.h"
+#include "lib/crypt_ops/crypto_rand.h"
+#include "lib/fs/dir.h"
+
+#include "core/or/cpath_build_state_st.h"
+#include "core/or/crypt_path_st.h"
+#include "feature/nodelist/networkstatus_st.h"
+#include "feature/nodelist/node_st.h"
+#include "core/or/origin_circuit_st.h"
+#include "app/config/or_state_st.h"
+#include "feature/nodelist/routerinfo_st.h"
/* Trunnel */
-#include "hs/cell_establish_intro.h"
+#include "trunnel/hs/cell_establish_intro.h"
+
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
static networkstatus_t mock_ns;
@@ -173,12 +193,12 @@ test_e2e_rend_circuit_setup(void *arg)
tt_int_op(retval, OP_EQ, 1);
/* Check the digest algo */
- tt_int_op(crypto_digest_get_algorithm(or_circ->cpath->f_digest),
+ tt_int_op(crypto_digest_get_algorithm(or_circ->cpath->crypto.f_digest),
OP_EQ, DIGEST_SHA3_256);
- tt_int_op(crypto_digest_get_algorithm(or_circ->cpath->b_digest),
+ tt_int_op(crypto_digest_get_algorithm(or_circ->cpath->crypto.b_digest),
OP_EQ, DIGEST_SHA3_256);
- tt_assert(or_circ->cpath->f_crypto);
- tt_assert(or_circ->cpath->b_crypto);
+ tt_assert(or_circ->cpath->crypto.f_crypto);
+ tt_assert(or_circ->cpath->crypto.b_crypto);
/* Ensure that circ purpose was changed */
tt_int_op(or_circ->base_.purpose, OP_EQ, CIRCUIT_PURPOSE_S_REND_JOINED);
@@ -211,6 +231,40 @@ helper_create_origin_circuit(int purpose, int flags)
return circ;
}
+/* Helper: Return a newly allocated authorized client object with
+ * and a newly generated public key. */
+static hs_service_authorized_client_t *
+helper_create_authorized_client(void)
+{
+ int ret;
+ hs_service_authorized_client_t *client;
+ curve25519_secret_key_t seckey;
+ client = tor_malloc_zero(sizeof(hs_service_authorized_client_t));
+
+ ret = curve25519_secret_key_generate(&seckey, 0);
+ tt_int_op(ret, OP_EQ, 0);
+ curve25519_public_key_generate(&client->client_pk, &seckey);
+
+ done:
+ return client;
+}
+
+/* Helper: Return a newly allocated authorized client object with the
+ * same client name and the same public key as the given client. */
+static hs_service_authorized_client_t *
+helper_clone_authorized_client(const hs_service_authorized_client_t *client)
+{
+ hs_service_authorized_client_t *client_out;
+
+ tor_assert(client);
+
+ client_out = tor_malloc_zero(sizeof(hs_service_authorized_client_t));
+ memcpy(client_out->client_pk.public_key,
+ client->client_pk.public_key, CURVE25519_PUBKEY_LEN);
+
+ return client_out;
+}
+
/* Helper: Return a newly allocated service object with the identity keypair
* sets and the current descriptor. Then register it to the global map.
* Caller should us hs_free_all() to free this service or remove it from the
@@ -235,6 +289,26 @@ helper_create_service(void)
return service;
}
+/* Helper: Return a newly allocated service object with clients. */
+static hs_service_t *
+helper_create_service_with_clients(int num_clients)
+{
+ int i;
+ hs_service_t *service = helper_create_service();
+ tt_assert(service);
+ service->config.is_client_auth_enabled = 1;
+ service->config.clients = smartlist_new();
+
+ for (i = 0; i < num_clients; i++) {
+ hs_service_authorized_client_t *client;
+ client = helper_create_authorized_client();
+ smartlist_add(service->config.clients, client);
+ }
+
+ done:
+ return service;
+}
+
/* Helper: Return a newly allocated service intro point with two link
* specifiers, one IPv4 and one legacy ID set to As. */
static hs_service_intro_point_t *
@@ -294,6 +368,8 @@ test_load_keys(void *arg)
/* It's in staging? */
tt_int_op(get_hs_service_staging_list_size(), OP_EQ, 1);
+#undef conf_fmt
+
/* Load the keys for these. After that, the v3 service should be registered
* in the global map. */
hs_service_load_all_keys();
@@ -313,6 +389,9 @@ test_load_keys(void *arg)
tt_int_op(hs_address_is_valid(addr), OP_EQ, 1);
tt_str_op(addr, OP_EQ, s->onion_address);
+ /* Check that the is_client_auth_enabled is not set. */
+ tt_assert(!s->config.is_client_auth_enabled);
+
done:
tor_free(hsdir_v2);
tor_free(hsdir_v3);
@@ -320,6 +399,183 @@ test_load_keys(void *arg)
}
static void
+test_client_filename_is_valid(void *arg)
+{
+ (void) arg;
+
+ /* Valid file name. */
+ tt_assert(client_filename_is_valid("a.auth"));
+ /* Valid file name with special character. */
+ tt_assert(client_filename_is_valid("a-.auth"));
+ /* Invalid extension. */
+ tt_assert(!client_filename_is_valid("a.ath"));
+ /* Nothing before the extension. */
+ tt_assert(!client_filename_is_valid(".auth"));
+
+ done:
+ ;
+}
+
+static void
+test_parse_authorized_client(void *arg)
+{
+ hs_service_authorized_client_t *client = NULL;
+
+ (void) arg;
+
+ /* Valid authorized client. */
+ client = parse_authorized_client(
+ "descriptor:x25519:dz4q5xqlb4ldnbs72iarrml4ephk3du4i7o2cgiva5lwr6wkquja");
+ tt_assert(client);
+
+ /* Wrong number of fields. */
+ tt_assert(!parse_authorized_client("a:b:c:d:e"));
+ /* Wrong auth type. */
+ tt_assert(!parse_authorized_client(
+ "x:x25519:dz4q5xqlb4ldnbs72iarrml4ephk3du4i7o2cgiva5lwr6wkquja"));
+ /* Wrong key type. */
+ tt_assert(!parse_authorized_client(
+ "descriptor:x:dz4q5xqlb4ldnbs72iarrml4ephk3du4i7o2cgiva5lwr6wkquja"));
+ /* Some malformed string. */
+ tt_assert(!parse_authorized_client("descriptor:x25519:aa=="));
+ tt_assert(!parse_authorized_client("descriptor:"));
+ tt_assert(!parse_authorized_client("descriptor:x25519"));
+ tt_assert(!parse_authorized_client("descriptor:x25519:"));
+ tt_assert(!parse_authorized_client(""));
+
+ done:
+ service_authorized_client_free(client);
+}
+
+static char *
+mock_read_file_to_str(const char *filename, int flags, struct stat *stat_out)
+{
+ char *ret = NULL;
+
+ (void) flags;
+ (void) stat_out;
+
+ if (!strcmp(filename, get_fname("hs3" PATH_SEPARATOR
+ "authorized_clients" PATH_SEPARATOR
+ "client1.auth"))) {
+ ret = tor_strdup("descriptor:x25519:"
+ "dz4q5xqlb4ldnbs72iarrml4ephk3du4i7o2cgiva5lwr6wkquja");
+ goto done;
+ }
+
+ if (!strcmp(filename, get_fname("hs3" PATH_SEPARATOR
+ "authorized_clients" PATH_SEPARATOR
+ "dummy.xxx"))) {
+ ret = tor_strdup("descriptor:x25519:"
+ "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
+ goto done;
+ }
+
+ if (!strcmp(filename, get_fname("hs3" PATH_SEPARATOR
+ "authorized_clients" PATH_SEPARATOR
+ "client2.auth"))) {
+ ret = tor_strdup("descriptor:x25519:"
+ "okoi2gml3wd6x7jganlk5d66xxyjgg24sxw4y7javx4giqr66zta");
+ goto done;
+ }
+
+ done:
+ return ret;
+}
+
+static smartlist_t *
+mock_tor_listdir(const char *dirname)
+{
+ smartlist_t *file_list = smartlist_new();
+
+ (void) dirname;
+
+ smartlist_add(file_list, tor_strdup("client1.auth"));
+ smartlist_add(file_list, tor_strdup("dummy.xxx"));
+ smartlist_add(file_list, tor_strdup("client2.auth"));
+
+ return file_list;
+}
+
+static void
+test_load_keys_with_client_auth(void *arg)
+{
+ int ret;
+ char *conf = NULL;
+ smartlist_t *pubkey_b32_list = smartlist_new();
+ char *hsdir_v3 = tor_strdup(get_fname("hs3"));
+ hs_service_t *service;
+
+ (void) arg;
+
+ hs_init();
+ smartlist_add(pubkey_b32_list, tor_strdup(
+ "dz4q5xqlb4ldnbs72iarrml4ephk3du4i7o2cgiva5lwr6wkquja"));
+ smartlist_add(pubkey_b32_list, tor_strdup(
+ "okoi2gml3wd6x7jganlk5d66xxyjgg24sxw4y7javx4giqr66zta"));
+
+#define conf_fmt \
+ "HiddenServiceDir %s\n" \
+ "HiddenServiceVersion %d\n" \
+ "HiddenServicePort 65534\n"
+
+ tor_asprintf(&conf, conf_fmt, hsdir_v3, HS_VERSION_THREE);
+ ret = helper_config_service(conf);
+ tor_free(conf);
+ tt_int_op(ret, OP_EQ, 0);
+ /* It's in staging? */
+ tt_int_op(get_hs_service_staging_list_size(), OP_EQ, 1);
+
+#undef conf_fmt
+
+ MOCK(read_file_to_str, mock_read_file_to_str);
+ MOCK(tor_listdir, mock_tor_listdir);
+
+ /* Load the keys for these. After that, the v3 service should be registered
+ * in the global map. */
+ hs_service_load_all_keys();
+ tt_int_op(get_hs_service_map_size(), OP_EQ, 1);
+
+ service = get_first_service();
+ tt_assert(service);
+ tt_assert(service->config.clients);
+ tt_int_op(smartlist_len(service->config.clients), OP_EQ,
+ smartlist_len(pubkey_b32_list));
+
+ /* Test that the is_client_auth_enabled flag is set. */
+ tt_assert(service->config.is_client_auth_enabled);
+
+ /* Test that the keys in clients are correct. */
+ SMARTLIST_FOREACH_BEGIN(pubkey_b32_list, char *, pubkey_b32) {
+
+ curve25519_public_key_t pubkey;
+ /* This flag will be set if the key is found in clients. */
+ int is_found = 0;
+ base32_decode((char *) pubkey.public_key, sizeof(pubkey.public_key),
+ pubkey_b32, strlen(pubkey_b32));
+
+ SMARTLIST_FOREACH_BEGIN(service->config.clients,
+ hs_service_authorized_client_t *, client) {
+ if (tor_memeq(&pubkey, &client->client_pk, sizeof(pubkey))) {
+ is_found = 1;
+ break;
+ }
+ } SMARTLIST_FOREACH_END(client);
+
+ tt_assert(is_found);
+
+ } SMARTLIST_FOREACH_END(pubkey_b32);
+
+ done:
+ SMARTLIST_FOREACH(pubkey_b32_list, char *, s, tor_free(s));
+ smartlist_free(pubkey_b32_list);
+ tor_free(hsdir_v3);
+ hs_free_all();
+ UNMOCK(read_file_to_str);
+ UNMOCK(tor_listdir);
+}
+
+static void
test_access_service(void *arg)
{
int ret;
@@ -492,6 +748,8 @@ test_helper_functions(void *arg)
MOCK(node_get_by_id, mock_node_get_by_id);
hs_service_init();
+ time_t now = time(NULL);
+ update_approx_time(now);
service = helper_create_service();
@@ -551,7 +809,6 @@ test_helper_functions(void *arg)
/* Testing can_service_launch_intro_circuit() */
{
- time_t now = time(NULL);
/* Put the start of the retry period back in time, we should be allowed.
* to launch intro circuit. */
service->state.num_intro_circ_launched = 2;
@@ -575,7 +832,6 @@ test_helper_functions(void *arg)
/* Testing intro_point_should_expire(). */
{
- time_t now = time(NULL);
/* Just some basic test of the current state. */
tt_u64_op(ip->introduce2_max, OP_GE,
INTRO_POINT_MIN_LIFETIME_INTRODUCTIONS);
@@ -1035,7 +1291,7 @@ static void
test_rotate_descriptors(void *arg)
{
int ret;
- time_t next_rotation_time, now = time(NULL);
+ time_t next_rotation_time, now;
hs_service_t *service;
hs_service_descriptor_t *desc_next;
@@ -1057,7 +1313,10 @@ test_rotate_descriptors(void *arg)
ret = parse_rfc1123_time("Sat, 26 Oct 1985 14:00:00 UTC",
&mock_ns.fresh_until);
tt_int_op(ret, OP_EQ, 0);
- dirvote_recalculate_timing(get_options(), mock_ns.valid_after);
+ voting_schedule_recalculate_timing(get_options(), mock_ns.valid_after);
+
+ update_approx_time(mock_ns.valid_after+1);
+ now = mock_ns.valid_after+1;
/* Create a service with a default descriptor and state. It's added to the
* global map. */
@@ -1095,7 +1354,10 @@ test_rotate_descriptors(void *arg)
ret = parse_rfc1123_time("Sat, 27 Oct 1985 02:00:00 UTC",
&mock_ns.fresh_until);
tt_int_op(ret, OP_EQ, 0);
- dirvote_recalculate_timing(get_options(), mock_ns.valid_after);
+ voting_schedule_recalculate_timing(get_options(), mock_ns.valid_after);
+
+ update_approx_time(mock_ns.valid_after+1);
+ now = mock_ns.valid_after+1;
/* Note down what to expect for the next rotation time which is 01:00 + 23h
* meaning 00:00:00. */
@@ -1157,7 +1419,10 @@ test_build_update_descriptors(void *arg)
ret = parse_rfc1123_time("Sat, 26 Oct 1985 04:00:00 UTC",
&mock_ns.fresh_until);
tt_int_op(ret, OP_EQ, 0);
- dirvote_recalculate_timing(get_options(), mock_ns.valid_after);
+ voting_schedule_recalculate_timing(get_options(), mock_ns.valid_after);
+
+ update_approx_time(mock_ns.valid_after+1);
+ now = mock_ns.valid_after+1;
/* Create a service without a current descriptor to trigger a build. */
service = helper_create_service();
@@ -1220,7 +1485,7 @@ test_build_update_descriptors(void *arg)
tt_int_op(ret, OP_EQ, 0);
ri.onion_curve25519_pkey =
tor_malloc_zero(sizeof(curve25519_public_key_t));
- ri.onion_pkey = crypto_pk_new();
+ ri.onion_pkey = tor_malloc_zero(140);
curve25519_public_key_generate(ri.onion_curve25519_pkey,
&curve25519_secret_key);
memset(ri.cache_info.identity_digest, 'A', DIGEST_LEN);
@@ -1237,7 +1502,7 @@ test_build_update_descriptors(void *arg)
node->is_running = node->is_valid = node->is_fast = node->is_stable = 1;
}
- /* We have to set thise, or the lack of microdescriptors for these
+ /* We have to set this, or the lack of microdescriptors for these
* nodes will make them unusable. */
get_options_mutable()->UseMicrodescriptors = 0;
@@ -1246,7 +1511,7 @@ test_build_update_descriptors(void *arg)
update_all_descriptors(now);
tor_free(node->ri->onion_curve25519_pkey); /* Avoid memleak. */
tor_free(node->ri->cache_info.signing_key_cert);
- crypto_pk_free(node->ri->onion_pkey);
+ tor_free(node->ri->onion_pkey);
expect_log_msg_containing("just picked 1 intro points and wanted 3 for next "
"descriptor. It currently has 0 intro points. "
"Launching ESTABLISH_INTRO circuit shortly.");
@@ -1300,6 +1565,9 @@ test_build_update_descriptors(void *arg)
&mock_ns.fresh_until);
tt_int_op(ret, OP_EQ, 0);
+ update_approx_time(mock_ns.valid_after+1);
+ now = mock_ns.valid_after+1;
+
/* Create a service without a current descriptor to trigger a build. */
service = helper_create_service();
tt_assert(service);
@@ -1350,11 +1618,95 @@ test_build_update_descriptors(void *arg)
nodelist_free_all();
}
+/** Test building descriptors. We use this separate function instead of
+ * using test_build_update_descriptors because that function is too complex
+ * and also too interactive. */
static void
-test_upload_descriptors(void *arg)
+test_build_descriptors(void *arg)
{
int ret;
time_t now = time(NULL);
+
+ (void) arg;
+
+ hs_init();
+
+ MOCK(get_or_state,
+ get_or_state_replacement);
+ MOCK(networkstatus_get_live_consensus,
+ mock_networkstatus_get_live_consensus);
+
+ dummy_state = tor_malloc_zero(sizeof(or_state_t));
+
+ ret = parse_rfc1123_time("Sat, 26 Oct 1985 03:00:00 UTC",
+ &mock_ns.valid_after);
+ tt_int_op(ret, OP_EQ, 0);
+ ret = parse_rfc1123_time("Sat, 26 Oct 1985 04:00:00 UTC",
+ &mock_ns.fresh_until);
+ tt_int_op(ret, OP_EQ, 0);
+ voting_schedule_recalculate_timing(get_options(), mock_ns.valid_after);
+
+ /* Generate a valid number of fake auth clients when a client authorization
+ * is disabled. */
+ {
+ hs_service_t *service = helper_create_service();
+ service_descriptor_free(service->desc_current);
+ service->desc_current = NULL;
+
+ build_all_descriptors(now);
+ hs_desc_superencrypted_data_t *superencrypted;
+ superencrypted = &service->desc_current->desc->superencrypted_data;
+ tt_int_op(smartlist_len(superencrypted->clients), OP_EQ, 16);
+ }
+
+ /* Generate a valid number of fake auth clients when the number of
+ * clients is zero. */
+ {
+ hs_service_t *service = helper_create_service_with_clients(0);
+ service_descriptor_free(service->desc_current);
+ service->desc_current = NULL;
+
+ build_all_descriptors(now);
+ hs_desc_superencrypted_data_t *superencrypted;
+ superencrypted = &service->desc_current->desc->superencrypted_data;
+ tt_int_op(smartlist_len(superencrypted->clients), OP_EQ, 16);
+ }
+
+ /* Generate a valid number of fake auth clients when the number of
+ * clients is not a multiple of 16. */
+ {
+ hs_service_t *service = helper_create_service_with_clients(20);
+ service_descriptor_free(service->desc_current);
+ service->desc_current = NULL;
+
+ build_all_descriptors(now);
+ hs_desc_superencrypted_data_t *superencrypted;
+ superencrypted = &service->desc_current->desc->superencrypted_data;
+ tt_int_op(smartlist_len(superencrypted->clients), OP_EQ, 32);
+ }
+
+ /* Do not generate any fake desc client when the number of clients is
+ * a multiple of 16 but not zero. */
+ {
+ hs_service_t *service = helper_create_service_with_clients(32);
+ service_descriptor_free(service->desc_current);
+ service->desc_current = NULL;
+
+ build_all_descriptors(now);
+ hs_desc_superencrypted_data_t *superencrypted;
+ superencrypted = &service->desc_current->desc->superencrypted_data;
+ tt_int_op(smartlist_len(superencrypted->clients), OP_EQ, 32);
+ }
+
+ done:
+ hs_free_all();
+}
+
+static void
+test_upload_descriptors(void *arg)
+{
+ int ret;
+ time_t now;
hs_service_t *service;
(void) arg;
@@ -1373,6 +1725,10 @@ test_upload_descriptors(void *arg)
ret = parse_rfc1123_time("Sat, 26 Oct 1985 14:00:00 UTC",
&mock_ns.fresh_until);
tt_int_op(ret, OP_EQ, 0);
+ voting_schedule_recalculate_timing(get_options(), mock_ns.valid_after);
+
+ update_approx_time(mock_ns.valid_after+1);
+ now = mock_ns.valid_after+1;
/* Create a service with no descriptor. It's added to the global map. */
service = hs_service_new(get_options());
@@ -1407,66 +1763,6 @@ test_upload_descriptors(void *arg)
UNMOCK(get_or_state);
}
-/** Test the functions that save and load HS revision counters to state. */
-static void
-test_revision_counter_state(void *arg)
-{
- char *state_line_one = NULL;
- char *state_line_two = NULL;
-
- hs_service_descriptor_t *desc_one = service_descriptor_new();
- hs_service_descriptor_t *desc_two = service_descriptor_new();
-
- (void) arg;
-
- /* Prepare both descriptors */
- desc_one->desc->plaintext_data.revision_counter = 42;
- desc_two->desc->plaintext_data.revision_counter = 240;
- memset(&desc_one->blinded_kp.pubkey.pubkey, 66,
- sizeof(desc_one->blinded_kp.pubkey.pubkey));
- memset(&desc_two->blinded_kp.pubkey.pubkey, 240,
- sizeof(desc_one->blinded_kp.pubkey.pubkey));
-
- /* Turn the descriptor rev counters into state lines */
- state_line_one = encode_desc_rev_counter_for_state(desc_one);
- tt_str_op(state_line_one, OP_EQ,
- "QkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkI 42");
-
- state_line_two = encode_desc_rev_counter_for_state(desc_two);
- tt_str_op(state_line_two, OP_EQ,
- "8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PA 240");
-
- /* Now let's test our state parsing function: */
- int service_found;
- uint64_t cached_rev_counter;
-
- /* First's try with wrong pubkey and check that no service was found */
- cached_rev_counter =check_state_line_for_service_rev_counter(state_line_one,
- &desc_two->blinded_kp.pubkey,
- &service_found);
- tt_int_op(service_found, OP_EQ, 0);
- tt_u64_op(cached_rev_counter, OP_EQ, 0);
-
- /* Now let's try with the right pubkeys */
- cached_rev_counter =check_state_line_for_service_rev_counter(state_line_one,
- &desc_one->blinded_kp.pubkey,
- &service_found);
- tt_int_op(service_found, OP_EQ, 1);
- tt_u64_op(cached_rev_counter, OP_EQ, 42);
-
- cached_rev_counter =check_state_line_for_service_rev_counter(state_line_two,
- &desc_two->blinded_kp.pubkey,
- &service_found);
- tt_int_op(service_found, OP_EQ, 1);
- tt_u64_op(cached_rev_counter, OP_EQ, 240);
-
- done:
- tor_free(state_line_one);
- tor_free(state_line_two);
- service_descriptor_free(desc_one);
- service_descriptor_free(desc_two);
-}
-
/** Global vars used by test_rendezvous1_parsing() */
static char rend1_payload[RELAY_PAYLOAD_SIZE];
static size_t rend1_payload_len = 0;
@@ -1591,11 +1887,227 @@ test_rendezvous1_parsing(void *arg)
UNMOCK(relay_send_command_from_edge_);
}
+static void
+test_authorized_client_config_equal(void *arg)
+{
+ int ret;
+ hs_service_config_t *config1, *config2;
+
+ (void) arg;
+
+ config1 = tor_malloc_zero(sizeof(*config1));
+ config2 = tor_malloc_zero(sizeof(*config2));
+
+ /* Both configs are empty. */
+ {
+ config1->clients = smartlist_new();
+ config2->clients = smartlist_new();
+
+ ret = service_authorized_client_config_equal(config1, config2);
+ tt_int_op(ret, OP_EQ, 1);
+
+ service_clear_config(config1);
+ service_clear_config(config2);
+ }
+
+ /* Both configs have exactly the same client config. */
+ {
+ config1->clients = smartlist_new();
+ config2->clients = smartlist_new();
+
+ hs_service_authorized_client_t *client1, *client2;
+ client1 = helper_create_authorized_client();
+ client2 = helper_create_authorized_client();
+
+ smartlist_add(config1->clients, client1);
+ smartlist_add(config1->clients, client2);
+
+ /* We should swap the order of clients here to test that the order
+ * does not matter. */
+ smartlist_add(config2->clients, helper_clone_authorized_client(client2));
+ smartlist_add(config2->clients, helper_clone_authorized_client(client1));
+
+ ret = service_authorized_client_config_equal(config1, config2);
+ tt_int_op(ret, OP_EQ, 1);
+
+ service_clear_config(config1);
+ service_clear_config(config2);
+ }
+
+ /* The numbers of clients in both configs are not equal. */
+ {
+ config1->clients = smartlist_new();
+ config2->clients = smartlist_new();
+
+ hs_service_authorized_client_t *client1, *client2;
+ client1 = helper_create_authorized_client();
+ client2 = helper_create_authorized_client();
+
+ smartlist_add(config1->clients, client1);
+ smartlist_add(config1->clients, client2);
+
+ smartlist_add(config2->clients, helper_clone_authorized_client(client1));
+
+ ret = service_authorized_client_config_equal(config1, config2);
+ tt_int_op(ret, OP_EQ, 0);
+
+ service_clear_config(config1);
+ service_clear_config(config2);
+ }
+
+ /* The first config has two distinct clients while the second config
+ * has two clients but they are duplicate. */
+ {
+ config1->clients = smartlist_new();
+ config2->clients = smartlist_new();
+
+ hs_service_authorized_client_t *client1, *client2;
+ client1 = helper_create_authorized_client();
+ client2 = helper_create_authorized_client();
+
+ smartlist_add(config1->clients, client1);
+ smartlist_add(config1->clients, client2);
+
+ smartlist_add(config2->clients, helper_clone_authorized_client(client1));
+ smartlist_add(config2->clients, helper_clone_authorized_client(client1));
+
+ ret = service_authorized_client_config_equal(config1, config2);
+ tt_int_op(ret, OP_EQ, 0);
+
+ service_clear_config(config1);
+ service_clear_config(config2);
+ }
+
+ /* Both configs have totally distinct clients. */
+ {
+ config1->clients = smartlist_new();
+ config2->clients = smartlist_new();
+
+ hs_service_authorized_client_t *client1, *client2, *client3, *client4;
+ client1 = helper_create_authorized_client();
+ client2 = helper_create_authorized_client();
+ client3 = helper_create_authorized_client();
+ client4 = helper_create_authorized_client();
+
+ smartlist_add(config1->clients, client1);
+ smartlist_add(config1->clients, client2);
+
+ smartlist_add(config2->clients, client3);
+ smartlist_add(config2->clients, client4);
+
+ ret = service_authorized_client_config_equal(config1, config2);
+ tt_int_op(ret, OP_EQ, 0);
+
+ service_clear_config(config1);
+ service_clear_config(config2);
+ }
+
+ done:
+ tor_free(config1);
+ tor_free(config2);
+}
+
+/** Test that client circuit ID gets correctly exported */
+static void
+test_export_client_circuit_id(void *arg)
+{
+ origin_circuit_t *or_circ = NULL;
+ size_t sz;
+ char *cp1=NULL, *cp2=NULL;
+ connection_t *conn = NULL;
+
+ (void) arg;
+
+ MOCK(connection_write_to_buf_impl_, connection_write_to_buf_mock);
+
+ hs_service_init();
+
+ /* Create service */
+ hs_service_t *service = helper_create_service();
+ /* Check that export circuit ID detection works */
+ service->config.circuit_id_protocol = HS_CIRCUIT_ID_PROTOCOL_NONE;
+ tt_int_op(0, OP_EQ,
+ hs_service_exports_circuit_id(&service->keys.identity_pk));
+ service->config.circuit_id_protocol = HS_CIRCUIT_ID_PROTOCOL_HAPROXY;
+ tt_int_op(1, OP_EQ,
+ hs_service_exports_circuit_id(&service->keys.identity_pk));
+
+ /* Create client connection */
+ conn = test_conn_get_connection(AP_CONN_STATE_CIRCUIT_WAIT, CONN_TYPE_AP, 0);
+
+ /* Create client edge conn hs_ident */
+ edge_connection_t *edge_conn = TO_EDGE_CONN(conn);
+ edge_conn->hs_ident = hs_ident_edge_conn_new(&service->keys.identity_pk);
+ edge_conn->hs_ident->orig_virtual_port = 42;
+
+ /* Create rend circuit */
+ or_circ = origin_circuit_new();
+ or_circ->base_.purpose = CIRCUIT_PURPOSE_C_REND_JOINED;
+ edge_conn->on_circuit = TO_CIRCUIT(or_circ);
+ or_circ->global_identifier = 666;
+
+ /* Export circuit ID */
+ export_hs_client_circuit_id(edge_conn, service->config.circuit_id_protocol);
+
+ /* Check contents */
+ cp1 = buf_get_contents(conn->outbuf, &sz);
+ tt_str_op(cp1, OP_EQ,
+ "PROXY TCP6 fc00:dead:beef:4dad::0:29a ::1 666 42\r\n");
+
+ /* Change circ GID and see that the reported circuit ID also changes */
+ or_circ->global_identifier = 22;
+
+ /* check changes */
+ export_hs_client_circuit_id(edge_conn, service->config.circuit_id_protocol);
+ cp2 = buf_get_contents(conn->outbuf, &sz);
+ tt_str_op(cp1, OP_NE, cp2);
+ tor_free(cp1);
+
+ /* Check that GID with UINT32_MAX works. */
+ or_circ->global_identifier = UINT32_MAX;
+
+ export_hs_client_circuit_id(edge_conn, service->config.circuit_id_protocol);
+ cp1 = buf_get_contents(conn->outbuf, &sz);
+ tt_str_op(cp1, OP_EQ,
+ "PROXY TCP6 fc00:dead:beef:4dad::ffff:ffff ::1 65535 42\r\n");
+ tor_free(cp1);
+
+ /* Check that GID with UINT16_MAX works. */
+ or_circ->global_identifier = UINT16_MAX;
+
+ export_hs_client_circuit_id(edge_conn, service->config.circuit_id_protocol);
+ cp1 = buf_get_contents(conn->outbuf, &sz);
+ tt_str_op(cp1, OP_EQ,
+ "PROXY TCP6 fc00:dead:beef:4dad::0:ffff ::1 65535 42\r\n");
+ tor_free(cp1);
+
+ /* Check that GID with UINT16_MAX + 7 works. */
+ or_circ->global_identifier = UINT16_MAX + 7;
+
+ export_hs_client_circuit_id(edge_conn, service->config.circuit_id_protocol);
+ cp1 = buf_get_contents(conn->outbuf, &sz);
+ tt_str_op(cp1, OP_EQ, "PROXY TCP6 fc00:dead:beef:4dad::1:6 ::1 6 42\r\n");
+
+ done:
+ UNMOCK(connection_write_to_buf_impl_);
+ circuit_free_(TO_CIRCUIT(or_circ));
+ connection_free_minimal(conn);
+ hs_service_free(service);
+ tor_free(cp1);
+ tor_free(cp2);
+}
+
struct testcase_t hs_service_tests[] = {
{ "e2e_rend_circuit_setup", test_e2e_rend_circuit_setup, TT_FORK,
NULL, NULL },
{ "load_keys", test_load_keys, TT_FORK,
NULL, NULL },
+ { "client_filename_is_valid", test_client_filename_is_valid, TT_FORK,
+ NULL, NULL },
+ { "parse_authorized_client", test_parse_authorized_client, TT_FORK,
+ NULL, NULL },
+ { "load_keys_with_client_auth", test_load_keys_with_client_auth, TT_FORK,
+ NULL, NULL },
{ "access_service", test_access_service, TT_FORK,
NULL, NULL },
{ "service_intro_point", test_service_intro_point, TT_FORK,
@@ -1618,13 +2130,16 @@ struct testcase_t hs_service_tests[] = {
NULL, NULL },
{ "build_update_descriptors", test_build_update_descriptors, TT_FORK,
NULL, NULL },
- { "upload_descriptors", test_upload_descriptors, TT_FORK,
+ { "build_descriptors", test_build_descriptors, TT_FORK,
NULL, NULL },
- { "revision_counter_state", test_revision_counter_state, TT_FORK,
+ { "upload_descriptors", test_upload_descriptors, TT_FORK,
NULL, NULL },
{ "rendezvous1_parsing", test_rendezvous1_parsing, TT_FORK,
NULL, NULL },
+ { "authorized_client_config_equal", test_authorized_client_config_equal,
+ TT_FORK, NULL, NULL },
+ { "export_client_circuit_id", test_export_client_circuit_id, TT_FORK,
+ NULL, NULL },
END_OF_TESTCASES
};
-
diff --git a/src/test/test_introduce.c b/src/test/test_introduce.c
index d502bdddb1..4d2d909945 100644
--- a/src/test/test_introduce.c
+++ b/src/test/test_introduce.c
@@ -1,13 +1,13 @@
-/* Copyright (c) 2012-2017, The Tor Project, Inc. */
+/* Copyright (c) 2012-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
#include "orconfig.h"
-#include "crypto.h"
-#include "or.h"
-#include "test.h"
+#include "lib/crypt_ops/crypto_cipher.h"
+#include "core/or/or.h"
+#include "test/test.h"
#define RENDSERVICE_PRIVATE
-#include "rendservice.h"
+#include "feature/rend/rendservice.h"
static uint8_t v0_test_plaintext[] =
/* 20 bytes of rendezvous point nickname */
diff --git a/src/test/test_keypin.c b/src/test/test_keypin.c
index 79d7bac902..9af12ff548 100644
--- a/src/test/test_keypin.c
+++ b/src/test/test_keypin.c
@@ -1,13 +1,12 @@
-/* Copyright (c) 2014-2017, The Tor Project, Inc. */
+/* Copyright (c) 2014-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
#include "orconfig.h"
#define KEYPIN_PRIVATE
-#include "or.h"
-#include "keypin.h"
-#include "util.h"
+#include "core/or/or.h"
+#include "feature/dirauth/keypin.h"
-#include "test.h"
+#include "test/test.h"
static void
test_keypin_parse_line(void *arg)
diff --git a/src/test/test_link_handshake.c b/src/test/test_link_handshake.c
index 6840072d76..82a91a9ae2 100644
--- a/src/test/test_link_handshake.c
+++ b/src/test/test_link_handshake.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014-2017, The Tor Project, Inc. */
+/* Copyright (c) 2014-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
#include "orconfig.h"
@@ -8,21 +8,28 @@
#define TOR_CHANNEL_INTERNAL_
#define TORTLS_PRIVATE
-#include "compat.h"
-
-#include "or.h"
-#include "config.h"
-#include "connection.h"
-#include "connection_or.h"
-#include "channeltls.h"
-#include "link_handshake.h"
-#include "router.h"
-#include "routerkeys.h"
-#include "scheduler.h"
-#include "torcert.h"
-
-#include "test.h"
-#include "log_test_helpers.h"
+#include "core/or/or.h"
+#include "app/config/config.h"
+#include "core/mainloop/connection.h"
+#include "core/or/connection_or.h"
+#include "core/or/channeltls.h"
+#include "trunnel/link_handshake.h"
+#include "feature/relay/router.h"
+#include "feature/relay/routerkeys.h"
+#include "core/or/scheduler.h"
+#include "feature/nodelist/torcert.h"
+
+#include "core/or/or_connection_st.h"
+#include "core/or/or_handshake_certs_st.h"
+#include "core/or/or_handshake_state_st.h"
+#include "core/or/var_cell_st.h"
+
+#define TOR_X509_PRIVATE
+#include "lib/tls/tortls.h"
+#include "lib/tls/x509.h"
+
+#include "test/test.h"
+#include "test/log_test_helpers.h"
static var_cell_t *mock_got_var_cell = NULL;
@@ -788,11 +795,26 @@ CERTS_FAIL(bad_rsa_id_cert, /*ed25519*/
{
require_failure_message = "legacy RSA ID certificate was not valid";
certs_cell_cert_t *cert = certs_cell_get_certs(d->ccell, 1);
- uint8_t *body = certs_cell_cert_getarray_body(cert);
- ssize_t body_len = certs_cell_cert_getlen_body(cert);
- /* Frob a byte in the signature */
- body[body_len - 13] ^= 7;
+ uint8_t *body;
+ /* Frob a byte in the signature, after making a new cert. (NSS won't let
+ * us just frob the old cert, since it will see that the issuer & serial
+ * number are the same, which will make it fail at an earlier stage than
+ * signature verification.) */
+ const tor_x509_cert_t *idc;
+ tor_x509_cert_t *newc;
+ tor_tls_get_my_certs(1, NULL, &idc);
+ time_t new_end = time(NULL) + 86400 * 10;
+ newc = tor_x509_cert_replace_expiration(idc, new_end, d->key2);
+ const uint8_t *encoded;
+ size_t encoded_len;
+ tor_x509_cert_get_der(newc, &encoded, &encoded_len);
+ certs_cell_cert_setlen_body(cert, encoded_len);
+ certs_cell_cert_set_cert_len(cert, encoded_len);
+ body = certs_cell_cert_getarray_body(cert);
+ memcpy(body, encoded, encoded_len);
+ body[encoded_len - 13] ^= 7;
REENCODE();
+ tor_x509_cert_free(newc);
})
CERTS_FAIL(expired_rsa_id, /* both */
{
@@ -804,9 +826,12 @@ CERTS_FAIL(expired_rsa_id, /* both */
tor_x509_cert_t *newc;
time_t new_end = time(NULL) - 86400 * 10;
newc = tor_x509_cert_replace_expiration(idc, new_end, d->key2);
- certs_cell_cert_setlen_body(cert, newc->encoded_len);
- memcpy(certs_cell_cert_getarray_body(cert),
- newc->encoded, newc->encoded_len);
+ const uint8_t *encoded;
+ size_t encoded_len;
+ tor_x509_cert_get_der(newc, &encoded, &encoded_len);
+ certs_cell_cert_setlen_body(cert, encoded_len);
+ certs_cell_cert_set_cert_len(cert, encoded_len);
+ memcpy(certs_cell_cert_getarray_body(cert), encoded, encoded_len);
REENCODE();
tor_x509_cert_free(newc);
})
@@ -917,15 +942,25 @@ test_link_handshake_send_authchallenge(void *arg)
cell1 = mock_got_var_cell;
tt_int_op(0, OP_EQ, connection_or_send_auth_challenge_cell(c1));
cell2 = mock_got_var_cell;
+#ifdef HAVE_WORKING_TOR_TLS_GET_TLSSECRETS
tt_int_op(38, OP_EQ, cell1->payload_len);
tt_int_op(38, OP_EQ, cell2->payload_len);
+#else
+ tt_int_op(36, OP_EQ, cell1->payload_len);
+ tt_int_op(36, OP_EQ, cell2->payload_len);
+#endif
tt_int_op(0, OP_EQ, cell1->circ_id);
tt_int_op(0, OP_EQ, cell2->circ_id);
tt_int_op(CELL_AUTH_CHALLENGE, OP_EQ, cell1->command);
tt_int_op(CELL_AUTH_CHALLENGE, OP_EQ, cell2->command);
+#ifdef HAVE_WORKING_TOR_TLS_GET_TLSSECRETS
tt_mem_op("\x00\x02\x00\x01\x00\x03", OP_EQ, cell1->payload + 32, 6);
tt_mem_op("\x00\x02\x00\x01\x00\x03", OP_EQ, cell2->payload + 32, 6);
+#else
+ tt_mem_op("\x00\x01\x00\x03", OP_EQ, cell1->payload + 32, 4);
+ tt_mem_op("\x00\x01\x00\x03", OP_EQ, cell2->payload + 32, 4);
+#endif
tt_mem_op(cell1->payload, OP_NE, cell2->payload, 32);
done:
@@ -967,6 +1002,8 @@ static void *
recv_authchallenge_setup(const struct testcase_t *test)
{
(void)test;
+
+ testing__connection_or_pretend_TLSSECRET_is_supported = 1;
authchallenge_data_t *d = tor_malloc_zero(sizeof(*d));
d->c = or_connection_new(CONN_TYPE_OR, AF_INET);
d->chan = tor_malloc_zero(sizeof(*d->chan));
@@ -1180,6 +1217,8 @@ authenticate_data_setup(const struct testcase_t *test)
authenticate_data_t *d = tor_malloc_zero(sizeof(*d));
int is_ed = d->is_ed = (test->setup_data == (void*)3);
+ testing__connection_or_pretend_TLSSECRET_is_supported = 1;
+
scheduler_init();
MOCK(connection_or_write_var_cell_to_buf, mock_write_var_cell);
@@ -1576,4 +1615,3 @@ struct testcase_t link_handshake_tests[] = {
END_OF_TESTCASES
};
-
diff --git a/src/test/test_logging.c b/src/test/test_logging.c
index e373158e34..cd685a4af7 100644
--- a/src/test/test_logging.c
+++ b/src/test/test_logging.c
@@ -1,10 +1,19 @@
-/* Copyright (c) 2013-2017, The Tor Project, Inc. */
+/* Copyright (c) 2013-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
+#define CONFIG_PRIVATE
+
#include "orconfig.h"
-#include "or.h"
-#include "torlog.h"
-#include "test.h"
+#include "core/or/or.h"
+#include "app/config/config.h"
+#include "lib/err/torerr.h"
+#include "lib/log/log.h"
+#include "test/test.h"
+#include "lib/process/subprocess.h"
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
static void
dummy_cb_fn(int severity, uint32_t domain, const char *msg)
@@ -89,7 +98,7 @@ test_sigsafe_err(void *arg)
init_logging(1);
mark_logs_temp();
- add_file_log(&include_bug, fn, 0);
+ open_and_add_file_log(&include_bug, fn, 0);
tor_log_update_sigsafe_err_fds();
close_temp_logs();
@@ -170,4 +179,3 @@ struct testcase_t logging_tests[] = {
{ "ratelim", test_ratelim, 0, NULL, NULL },
END_OF_TESTCASES
};
-
diff --git a/src/test/test_mainloop.c b/src/test/test_mainloop.c
new file mode 100644
index 0000000000..92ce2e9918
--- /dev/null
+++ b/src/test/test_mainloop.c
@@ -0,0 +1,142 @@
+/* Copyright (c) 2018, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+/**
+ * \file test_mainloop.c
+ * \brief Tests for functions closely related to the Tor main loop
+ */
+
+#include "test/test.h"
+#include "test/log_test_helpers.h"
+
+#include "core/or/or.h"
+#include "core/mainloop/mainloop.h"
+
+static const uint64_t BILLION = 1000000000;
+
+static void
+test_mainloop_update_time_normal(void *arg)
+{
+ (void)arg;
+
+ monotime_enable_test_mocking();
+ /* This is arbitrary */
+ uint64_t mt_now = UINT64_C(7493289274986);
+ /* This time is in the past as of when this test was written. */
+ time_t now = 1525272090;
+ monotime_coarse_set_mock_time_nsec(mt_now);
+ reset_uptime();
+ update_current_time(now);
+ tt_int_op(approx_time(), OP_EQ, now);
+ tt_int_op(get_uptime(), OP_EQ, 0);
+
+ update_current_time(now); // Same time as before is a no-op.
+ tt_int_op(get_uptime(), OP_EQ, 0);
+
+ now += 1;
+ mt_now += BILLION;
+ monotime_coarse_set_mock_time_nsec(mt_now);
+ update_current_time(now);
+ tt_int_op(approx_time(), OP_EQ, now);
+ tt_int_op(get_uptime(), OP_EQ, 1);
+
+ now += 2; // two-second jump is unremarkable.
+ mt_now += 2*BILLION;
+ update_current_time(now);
+ monotime_coarse_set_mock_time_nsec(mt_now);
+ tt_int_op(approx_time(), OP_EQ, now);
+ tt_int_op(get_uptime(), OP_EQ, 3);
+
+ now -= 1; // a one-second hop backwards is also unremarkable.
+ update_current_time(now);
+ tt_int_op(approx_time(), OP_EQ, now); // it changes the approx time...
+ tt_int_op(get_uptime(), OP_EQ, 3); // but it doesn't roll back our uptime
+
+ done:
+ monotime_disable_test_mocking();
+}
+
+static void
+test_mainloop_update_time_jumps(void *arg)
+{
+ (void)arg;
+
+ monotime_enable_test_mocking();
+ /* This is arbitrary */
+ uint64_t mt_now = UINT64_C(7493289274986);
+ /* This time is in the past as of when this test was written. */
+ time_t now = 220897152;
+ monotime_coarse_set_mock_time_nsec(mt_now);
+ reset_uptime();
+ update_current_time(now);
+ tt_int_op(approx_time(), OP_EQ, now);
+ tt_int_op(get_uptime(), OP_EQ, 0);
+
+ /* Put some uptime on the clock.. */
+ now += 3;
+ mt_now += 3*BILLION;
+ monotime_coarse_set_mock_time_nsec(mt_now);
+ update_current_time(now);
+ tt_int_op(approx_time(), OP_EQ, now);
+ tt_int_op(get_uptime(), OP_EQ, 3);
+
+ /* Now try jumping forward and backward, without updating the monotonic
+ * clock. */
+ setup_capture_of_logs(LOG_NOTICE);
+ now += 1800;
+ update_current_time(now);
+ expect_single_log_msg_containing(
+ "Your system clock just jumped 1800 seconds forward");
+ tt_int_op(approx_time(), OP_EQ, now);
+ tt_int_op(get_uptime(), OP_EQ, 3); // no uptime change.
+ mock_clean_saved_logs();
+
+ now -= 600;
+ update_current_time(now);
+ expect_single_log_msg_containing(
+ "Your system clock just jumped 600 seconds backward");
+ tt_int_op(approx_time(), OP_EQ, now);
+ tt_int_op(get_uptime(), OP_EQ, 3); // no uptime change.
+ mock_clean_saved_logs();
+
+ /* uptime tracking should go normally now if the clock moves sensibly. */
+ now += 2;
+ mt_now += 2*BILLION;
+ update_current_time(now);
+ tt_int_op(approx_time(), OP_EQ, now);
+ tt_int_op(get_uptime(), OP_EQ, 5);
+
+ /* If we skip forward by a few minutes but the monotonic clock agrees,
+ * we've just been idle: that counts as not worth warning about. */
+ now += 1800;
+ mt_now += 1800*BILLION;
+ monotime_coarse_set_mock_time_nsec(mt_now);
+ update_current_time(now);
+ expect_no_log_entry();
+ tt_int_op(approx_time(), OP_EQ, now);
+ tt_int_op(get_uptime(), OP_EQ, 5); // this doesn't count to uptime, though.
+
+ /* If we skip forward by a long time, even if the clock agrees, it's
+ * idnless that counts. */
+ now += 4000;
+ mt_now += 4000*BILLION;
+ monotime_coarse_set_mock_time_nsec(mt_now);
+ update_current_time(now);
+ expect_single_log_msg_containing("Tor has been idle for 4000 seconds");
+ tt_int_op(approx_time(), OP_EQ, now);
+ tt_int_op(get_uptime(), OP_EQ, 5);
+
+ done:
+ teardown_capture_of_logs();
+ monotime_disable_test_mocking();
+}
+
+#define MAINLOOP_TEST(name) \
+ { #name, test_mainloop_## name , TT_FORK, NULL, NULL }
+
+struct testcase_t mainloop_tests[] = {
+ MAINLOOP_TEST(update_time_normal),
+ MAINLOOP_TEST(update_time_jumps),
+ END_OF_TESTCASES
+};
+
diff --git a/src/test/test_microdesc.c b/src/test/test_microdesc.c
index 59b28f7580..8ede2690ec 100644
--- a/src/test/test_microdesc.c
+++ b/src/test/test_microdesc.c
@@ -1,18 +1,29 @@
-/* Copyright (c) 2010-2017, The Tor Project, Inc. */
+/* Copyright (c) 2010-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
#include "orconfig.h"
-#include "or.h"
-
-#include "config.h"
-#include "dirvote.h"
-#include "microdesc.h"
-#include "networkstatus.h"
-#include "routerlist.h"
-#include "routerparse.h"
-#include "torcert.h"
-
-#include "test.h"
+#include "core/or/or.h"
+
+#define DIRVOTE_PRIVATE
+#include "app/config/config.h"
+#include "feature/dirauth/dirvote.h"
+#include "feature/dirparse/microdesc_parse.h"
+#include "feature/dirparse/routerparse.h"
+#include "feature/nodelist/microdesc.h"
+#include "feature/nodelist/networkstatus.h"
+#include "feature/nodelist/routerlist.h"
+#include "feature/nodelist/torcert.h"
+
+#include "feature/nodelist/microdesc_st.h"
+#include "feature/nodelist/networkstatus_st.h"
+#include "feature/nodelist/routerinfo_st.h"
+#include "feature/nodelist/routerstatus_st.h"
+
+#include "test/test.h"
+
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
#ifdef _WIN32
/* For mkdir() */
@@ -385,25 +396,6 @@ static const char test_ri2[] =
"cf34GXHv61XReJF3AlzNHFpbrPOYmowmhrTULKyMqow=\n"
"-----END SIGNATURE-----\n";
-static const char test_md_8[] =
- "onion-key\n"
- "-----BEGIN RSA PUBLIC KEY-----\n"
- "MIGJAoGBANBJz8Vldl12aFeSMPLiA4nOetLDN0oxU8bB1SDhO7Uu2zdWYVYAF5J0\n"
- "st7WvrVy/jA9v/fsezNAPskBanecHRSkdMTpkcgRPMHE7CTGEwIy1Yp1X4bPgDlC\n"
- "VCnbs5Pcts5HnWEYNK7qHDAUn+IlmjOO+pTUY8uyq+GQVz6H9wFlAgMBAAE=\n"
- "-----END RSA PUBLIC KEY-----\n"
- "p reject 25,119,135-139,445,563,1214,4661-4666,6346-6429,6699,6881-6999\n";
-
-static const char test_md_16[] =
- "onion-key\n"
- "-----BEGIN RSA PUBLIC KEY-----\n"
- "MIGJAoGBANBJz8Vldl12aFeSMPLiA4nOetLDN0oxU8bB1SDhO7Uu2zdWYVYAF5J0\n"
- "st7WvrVy/jA9v/fsezNAPskBanecHRSkdMTpkcgRPMHE7CTGEwIy1Yp1X4bPgDlC\n"
- "VCnbs5Pcts5HnWEYNK7qHDAUn+IlmjOO+pTUY8uyq+GQVz6H9wFlAgMBAAE=\n"
- "-----END RSA PUBLIC KEY-----\n"
- "ntor-onion-key Gg73xH7+kTfT6bi1uNVx9gwQdQas9pROIfmc4NpAdC4=\n"
- "p reject 25,119,135-139,445,563,1214,4661-4666,6346-6429,6699,6881-6999\n";
-
static const char test_md_18[] =
"onion-key\n"
"-----BEGIN RSA PUBLIC KEY-----\n"
@@ -415,16 +407,6 @@ static const char test_md_18[] =
"p reject 25,119,135-139,445,563,1214,4661-4666,6346-6429,6699,6881-6999\n"
"id rsa1024 Cd47okjCHD83YGzThGBDptXs9Z4\n";
-static const char test_md2_18[] =
- "onion-key\n"
- "-----BEGIN RSA PUBLIC KEY-----\n"
- "MIGJAoGBAL2R8EfubUcahxha4u02P4VAR0llQIMwFAmrHPjzcK7apcQgDOf2ovOA\n"
- "+YQnJFxlpBmCoCZC6ssCi+9G0mqo650lFuTMP5I90BdtjotfzESfTykHLiChyvhd\n"
- "l0dlqclb2SU/GKem/fLRXH16aNi72CdSUu/1slKs/70ILi34QixRAgMBAAE=\n"
- "-----END RSA PUBLIC KEY-----\n"
- "ntor-onion-key hbxdRnfVUJJY7+KcT4E3Rs7/zuClbN3hJrjSBiEGMgI=\n"
- "id rsa1024 t+J/EEITw28T5+mCkYKEXklZl6A\n";
-
static const char test_md2_21[] =
"onion-key\n"
"-----BEGIN RSA PUBLIC KEY-----\n"
@@ -444,17 +426,6 @@ test_md_generate(void *arg)
ri = router_parse_entry_from_string(test_ri, NULL, 0, 0, NULL, NULL);
tt_assert(ri);
- md = dirvote_create_microdescriptor(ri, 8);
- tt_str_op(md->body, OP_EQ, test_md_8);
-
- /* XXXX test family lines. */
- /* XXXX test method 14 for A lines. */
- /* XXXX test method 15 for P6 lines. */
-
- microdesc_free(md);
- md = NULL;
- md = dirvote_create_microdescriptor(ri, 16);
- tt_str_op(md->body, OP_EQ, test_md_16);
microdesc_free(md);
md = NULL;
@@ -471,11 +442,6 @@ test_md_generate(void *arg)
microdesc_free(md);
md = NULL;
- md = dirvote_create_microdescriptor(ri, 18);
- tt_str_op(md->body, OP_EQ, test_md2_18);
-
- microdesc_free(md);
- md = NULL;
md = dirvote_create_microdescriptor(ri, 21);
tt_str_op(md->body, OP_EQ, test_md2_21);
tt_assert(ed25519_pubkey_eq(md->ed25519_identity_pkey,
@@ -854,4 +820,3 @@ struct testcase_t microdesc_tests[] = {
{ "corrupt_desc", test_md_corrupt_desc, TT_FORK, NULL, NULL },
END_OF_TESTCASES
};
-
diff --git a/src/test/test_nodelist.c b/src/test/test_nodelist.c
index a873003d72..1af6db68ec 100644
--- a/src/test/test_nodelist.c
+++ b/src/test/test_nodelist.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2007-2017, The Tor Project, Inc. */
+/* Copyright (c) 2007-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
/**
@@ -6,11 +6,20 @@
* \brief Unit tests for nodelist related functions.
**/
-#include "or.h"
-#include "networkstatus.h"
-#include "nodelist.h"
-#include "torcert.h"
-#include "test.h"
+#include "core/or/or.h"
+#include "lib/crypt_ops/crypto_rand.h"
+#include "feature/nodelist/networkstatus.h"
+#include "feature/nodelist/nodelist.h"
+#include "feature/nodelist/torcert.h"
+
+#include "feature/nodelist/microdesc_st.h"
+#include "feature/nodelist/networkstatus_st.h"
+#include "feature/nodelist/node_st.h"
+#include "feature/nodelist/routerinfo_st.h"
+#include "feature/nodelist/routerstatus_st.h"
+
+#include "test/test.h"
+#include "test/log_test_helpers.h"
/** Test the case when node_get_by_id() returns NULL,
* node_get_verbose_nickname_by_id should return the base 16 encoding
@@ -118,9 +127,10 @@ mock_networkstatus_get_latest_consensus_by_flavor(consensus_flavor_t f)
static void
test_nodelist_ed_id(void *arg)
{
- routerstatus_t *rs[4];
- microdesc_t *md[4];
- routerinfo_t *ri[4];
+#define N_NODES 5
+ routerstatus_t *rs[N_NODES];
+ microdesc_t *md[N_NODES];
+ routerinfo_t *ri[N_NODES];
networkstatus_t *ns;
int i;
(void)arg;
@@ -137,7 +147,7 @@ test_nodelist_ed_id(void *arg)
/* Make a bunch of dummy objects that we can play around with. Only set the
necessary fields */
- for (i = 0; i < 4; ++i) {
+ for (i = 0; i < N_NODES; ++i) {
rs[i] = tor_malloc_zero(sizeof(*rs[i]));
md[i] = tor_malloc_zero(sizeof(*md[i]));
ri[i] = tor_malloc_zero(sizeof(*ri[i]));
@@ -154,7 +164,7 @@ test_nodelist_ed_id(void *arg)
memcpy(&ri[i]->cache_info.signing_key_cert->signing_key,
md[i]->ed25519_identity_pkey, sizeof(ed25519_public_key_t));
- if (i != 3)
+ if (i < 3)
smartlist_add(ns->routerstatus_list, rs[i]);
}
@@ -184,13 +194,30 @@ test_nodelist_ed_id(void *arg)
/* Register the 4th by ri only -- we never put it into the networkstatus,
* so it has to be independent */
- n = nodelist_set_routerinfo(ri[3], &ri_old);
- tt_ptr_op(n, OP_EQ, node_get_by_ed25519_id(md[3]->ed25519_identity_pkey));
+ node_t *n3 = nodelist_set_routerinfo(ri[3], &ri_old);
+ tt_ptr_op(n3, OP_EQ, node_get_by_ed25519_id(md[3]->ed25519_identity_pkey));
tt_ptr_op(ri_old, OP_EQ, NULL);
tt_int_op(4, OP_EQ, smartlist_len(nodelist_get_list()));
+ /* Register the 5th by ri only, and rewrite its ed25519 pubkey to be
+ * the same as the 4th, to test the duplicate ed25519 key logging in
+ * nodelist.c */
+ memcpy(md[4]->ed25519_identity_pkey, md[3]->ed25519_identity_pkey,
+ sizeof(ed25519_public_key_t));
+ memcpy(&ri[4]->cache_info.signing_key_cert->signing_key,
+ md[3]->ed25519_identity_pkey, sizeof(ed25519_public_key_t));
+
+ setup_capture_of_logs(LOG_NOTICE);
+ node_t *n4 = nodelist_set_routerinfo(ri[4], &ri_old);
+ tt_ptr_op(ri_old, OP_EQ, NULL);
+ tt_int_op(5, OP_EQ, smartlist_len(nodelist_get_list()));
+ tt_ptr_op(n4, OP_NE, node_get_by_ed25519_id(md[3]->ed25519_identity_pkey));
+ tt_ptr_op(n3, OP_EQ, node_get_by_ed25519_id(md[3]->ed25519_identity_pkey));
+ expect_log_msg_containing("Reused ed25519_id");
+
done:
- for (i = 0; i < 4; ++i) {
+ teardown_capture_of_logs();
+ for (i = 0; i < N_NODES; ++i) {
tor_free(rs[i]);
tor_free(md[i]->ed25519_identity_pkey);
tor_free(md[i]);
@@ -201,6 +228,7 @@ test_nodelist_ed_id(void *arg)
networkstatus_vote_free(ns);
UNMOCK(networkstatus_get_latest_consensus);
UNMOCK(networkstatus_get_latest_consensus_by_flavor);
+#undef N_NODES
}
#define NODE(name, flags) \
diff --git a/src/test/test_ntor_cl.c b/src/test/test_ntor_cl.c
index d0eea85d6f..3f914523a3 100644
--- a/src/test/test_ntor_cl.c
+++ b/src/test/test_ntor_cl.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2017, The Tor Project, Inc. */
+/* Copyright (c) 2012-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
#include "orconfig.h"
@@ -6,12 +6,11 @@
#include <stdlib.h>
#define ONION_NTOR_PRIVATE
-#include "or.h"
-#include "util.h"
-#include "compat.h"
-#include "crypto.h"
-#include "crypto_curve25519.h"
-#include "onion_ntor.h"
+#include "core/or/or.h"
+#include "lib/crypt_ops/crypto_cipher.h"
+#include "lib/crypt_ops/crypto_curve25519.h"
+#include "lib/crypt_ops/crypto_init.h"
+#include "core/crypto/onion_ntor.h"
#define N_ARGS(n) STMT_BEGIN { \
if (argc < (n)) { \
@@ -155,7 +154,11 @@ main(int argc, char **argv)
return 1;
}
+ init_logging(1);
curve25519_init();
+ if (crypto_global_init(0, NULL, NULL) < 0)
+ return 1;
+
if (!strcmp(argv[1], "client1")) {
return client1(argc, argv);
} else if (!strcmp(argv[1], "server1")) {
@@ -167,4 +170,3 @@ main(int argc, char **argv)
return 1;
}
}
-
diff --git a/src/test/test_oom.c b/src/test/test_oom.c
index c172fe60c7..313a6b3114 100644
--- a/src/test/test_oom.c
+++ b/src/test/test_oom.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014-2017, The Tor Project, Inc. */
+/* Copyright (c) 2014-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
/* Unit tests for OOM handling logic */
@@ -7,15 +7,21 @@
#define BUFFERS_PRIVATE
#define CIRCUITLIST_PRIVATE
#define CONNECTION_PRIVATE
-#include "or.h"
-#include "buffers.h"
-#include "circuitlist.h"
-#include "compat_libevent.h"
-#include "connection.h"
-#include "config.h"
-#include "relay.h"
-#include "test.h"
-#include "test_helpers.h"
+#include "core/or/or.h"
+#include "lib/container/buffers.h"
+#include "core/or/circuitlist.h"
+#include "lib/evloop/compat_libevent.h"
+#include "core/mainloop/connection.h"
+#include "app/config/config.h"
+#include "lib/crypt_ops/crypto_rand.h"
+#include "core/or/relay.h"
+#include "test/test.h"
+#include "test/test_helpers.h"
+
+#include "core/or/cell_st.h"
+#include "core/or/entry_connection_st.h"
+#include "core/or/or_circuit_st.h"
+#include "core/or/origin_circuit_st.h"
/* small replacement mock for circuit_mark_for_close_ to avoid doing all
* the other bookkeeping that comes with marking circuits. */
diff --git a/src/test/test_oos.c b/src/test/test_oos.c
index e72fcf5de9..fb0daa7a8d 100644
--- a/src/test/test_oos.c
+++ b/src/test/test_oos.c
@@ -1,16 +1,20 @@
-/* Copyright (c) 2016-2017, The Tor Project, Inc. */
+/* Copyright (c) 2016-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
/* Unit tests for OOS handler */
#define CONNECTION_PRIVATE
-#include "or.h"
-#include "config.h"
-#include "connection.h"
-#include "connection_or.h"
-#include "main.h"
-#include "test.h"
+#include "core/or/or.h"
+#include "app/config/config.h"
+#include "core/mainloop/connection.h"
+#include "core/or/connection_or.h"
+#include "feature/dircommon/directory.h"
+#include "core/mainloop/mainloop.h"
+#include "test/test.h"
+
+#include "feature/dircommon/dir_connection_st.h"
+#include "core/or/or_connection_st.h"
static or_options_t mock_options;
@@ -453,4 +457,3 @@ struct testcase_t oos_tests[] = {
{ "pick_oos_victims", test_oos_pick_oos_victims, TT_FORK, NULL, NULL },
END_OF_TESTCASES
};
-
diff --git a/src/test/test_options.c b/src/test/test_options.c
index eaf5034397..f14e620eeb 100644
--- a/src/test/test_options.c
+++ b/src/test/test_options.c
@@ -1,24 +1,27 @@
/* Copyright (c) 2001-2004, Roger Dingledine.
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2017, The Tor Project, Inc. */
+ * Copyright (c) 2007-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
#define CONFIG_PRIVATE
-#include "or.h"
-#include "confparse.h"
-#include "config.h"
-#include "test.h"
-#include "geoip.h"
+#include "core/or/or.h"
+#include "app/config/confparse.h"
+#include "app/config/config.h"
+#include "test/test.h"
+#include "lib/geoip/geoip.h"
#define ROUTERSET_PRIVATE
-#include "routerset.h"
-#include "main.h"
-#include "log_test_helpers.h"
-
-#include "sandbox.h"
-#include "memarea.h"
-#include "policies.h"
-#include "test_helpers.h"
+#include "feature/nodelist/routerset.h"
+#include "core/mainloop/mainloop.h"
+#include "test/log_test_helpers.h"
+
+#include "lib/sandbox/sandbox.h"
+#include "lib/memarea/memarea.h"
+#include "lib/osinfo/uname.h"
+#include "lib/encoding/confline.h"
+#include "core/or/policies.h"
+#include "test/test_helpers.h"
+#include "lib/net/resolve.h"
#define NS_MODULE test_options
@@ -274,7 +277,7 @@ test_options_validate(void *arg)
return;
}
-#define MEGABYTEIFY(mb) (U64_LITERAL(mb) << 20)
+#define MEGABYTEIFY(mb) (UINT64_C(mb) << 20)
static void
test_have_enough_mem_for_dircache(void *arg)
{
@@ -470,6 +473,13 @@ test_options_validate__uname_for_server(void *ignored)
{
(void)ignored;
char *msg;
+
+#ifndef _WIN32
+ int unset_home_env = 0;
+ if (setenv("HOME", "/home/john", 0) == 0)
+ unset_home_env = 1;
+#endif
+
options_test_data_t *tdata = get_options_test_data(
"ORPort 127.0.0.1:5555");
setup_capture_of_logs(LOG_WARN);
@@ -509,6 +519,10 @@ test_options_validate__uname_for_server(void *ignored)
free_options_test_data(tdata);
tor_free(msg);
teardown_capture_of_logs();
+#ifndef _WIN32
+ if (unset_home_env)
+ unsetenv("HOME");
+#endif
}
static void
@@ -1410,6 +1424,13 @@ test_options_validate__paths_needed(void *ignored)
(void)ignored;
int ret;
char *msg;
+
+#ifndef _WIN32
+ int unset_home_env = 0;
+ if (setenv("HOME", "/home/john", 0) == 0)
+ unset_home_env = 1;
+#endif
+
setup_capture_of_logs(LOG_WARN);
options_test_data_t *tdata = get_options_test_data(
"PathsNeededToBuildCircuits 0.1\n"
@@ -1452,6 +1473,10 @@ test_options_validate__paths_needed(void *ignored)
teardown_capture_of_logs();
free_options_test_data(tdata);
tor_free(msg);
+#ifndef _WIN32
+ if (unset_home_env)
+ unsetenv("HOME");
+#endif
}
static void
@@ -1631,6 +1656,18 @@ test_options_validate__reachable_addresses(void *ignored)
tt_str_op(tdata->opt->ReachableAddresses->value, OP_EQ, "*:82");
tor_free(msg);
+ free_options_test_data(tdata);
+ mock_clean_saved_logs();
+ tdata = get_options_test_data("FascistFirewall 1\n"
+ "ReachableAddresses *:82\n"
+ "MaxClientCircuitsPending 1\n"
+ "ConnLimit 1\n");
+
+ ret = options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg);
+ tt_int_op(ret, OP_EQ, -1);
+ tt_ptr_op(tdata->opt->ReachableAddresses->next, OP_EQ, NULL);
+ tor_free(msg);
+
#define SERVERS_REACHABLE_MSG "Servers must be able to freely connect to" \
" the rest of the Internet, so they must not set Reachable*Addresses or" \
" FascistFirewall or FirewallPorts or ClientUseIPv4 0."
@@ -2067,12 +2104,12 @@ test_options_validate__testing(void *ignored)
ENSURE_DEFAULT(TestingV3AuthVotingStartOffset, 3000);
ENSURE_DEFAULT(TestingAuthDirTimeToLearnReachability, 3000);
ENSURE_DEFAULT(TestingEstimatedDescriptorPropagationTime, 3000);
- ENSURE_DEFAULT(TestingServerDownloadSchedule, 3000);
- ENSURE_DEFAULT(TestingClientDownloadSchedule, 3000);
- ENSURE_DEFAULT(TestingServerConsensusDownloadSchedule, 3000);
- ENSURE_DEFAULT(TestingClientConsensusDownloadSchedule, 3000);
- ENSURE_DEFAULT(TestingBridgeDownloadSchedule, 3000);
- ENSURE_DEFAULT(TestingBridgeBootstrapDownloadSchedule, 3000);
+ ENSURE_DEFAULT(TestingServerDownloadInitialDelay, 3000);
+ ENSURE_DEFAULT(TestingClientDownloadInitialDelay, 3000);
+ ENSURE_DEFAULT(TestingServerConsensusDownloadInitialDelay, 3000);
+ ENSURE_DEFAULT(TestingClientConsensusDownloadInitialDelay, 3000);
+ ENSURE_DEFAULT(TestingBridgeDownloadInitialDelay, 3000);
+ ENSURE_DEFAULT(TestingBridgeBootstrapDownloadInitialDelay, 3000);
ENSURE_DEFAULT(TestingClientMaxIntervalWithoutRequest, 3000);
ENSURE_DEFAULT(TestingDirConnectionMaxStall, 3000);
ENSURE_DEFAULT(TestingAuthKeyLifetime, 3000);
@@ -2422,67 +2459,6 @@ test_options_validate__circuits(void *ignored)
}
static void
-test_options_validate__port_forwarding(void *ignored)
-{
- (void)ignored;
- int ret;
- char *msg;
- options_test_data_t *tdata = NULL;
-
- free_options_test_data(tdata);
- tdata = get_options_test_data(TEST_OPTIONS_DEFAULT_VALUES
- "PortForwarding 1\nSandbox 1\n");
- ret = options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg);
- tt_int_op(ret, OP_EQ, -1);
- tt_str_op(msg, OP_EQ, "PortForwarding is not compatible with Sandbox;"
- " at most one can be set");
- tor_free(msg);
-
- free_options_test_data(tdata);
- tdata = get_options_test_data(TEST_OPTIONS_DEFAULT_VALUES
- "PortForwarding 1\nSandbox 0\n");
- ret = options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg);
- tt_int_op(ret, OP_EQ, 0);
- tt_assert(!msg);
- tor_free(msg);
-
- done:
- free_options_test_data(tdata);
- policies_free_all();
- tor_free(msg);
-}
-
-static void
-test_options_validate__tor2web(void *ignored)
-{
- (void)ignored;
- int ret;
- char *msg;
- options_test_data_t *tdata = NULL;
-
- free_options_test_data(tdata);
- tdata = get_options_test_data(TEST_OPTIONS_DEFAULT_VALUES
- "Tor2webRendezvousPoints 1\n");
- ret = options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg);
- tt_int_op(ret, OP_EQ, -1);
- tt_str_op(msg, OP_EQ,
- "Tor2webRendezvousPoints cannot be set without Tor2webMode.");
- tor_free(msg);
-
- free_options_test_data(tdata);
- tdata = get_options_test_data(TEST_OPTIONS_DEFAULT_VALUES
- "Tor2webRendezvousPoints 1\nTor2webMode 1\n");
- ret = options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg);
- tt_int_op(ret, OP_EQ, 0);
- tor_free(msg);
-
- done:
- policies_free_all();
- free_options_test_data(tdata);
- tor_free(msg);
-}
-
-static void
test_options_validate__rend(void *ignored)
{
(void)ignored;
@@ -2595,13 +2571,11 @@ test_options_validate__single_onion(void *ignored)
tt_ptr_op(msg, OP_EQ, NULL);
free_options_test_data(tdata);
- /* Test that SOCKSPort must come with Tor2webMode if
- * HiddenServiceSingleHopMode is 1 */
+ /* Test that SOCKSPort if HiddenServiceSingleHopMode is 1 */
tdata = get_options_test_data(TEST_OPTIONS_DEFAULT_VALUES
"SOCKSPort 5000\n"
"HiddenServiceSingleHopMode 1\n"
"HiddenServiceNonAnonymousMode 1\n"
- "Tor2webMode 0\n"
);
ret = options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg);
tt_int_op(ret, OP_EQ, -1);
@@ -2616,7 +2590,6 @@ test_options_validate__single_onion(void *ignored)
"SOCKSPort 0\n"
"HiddenServiceSingleHopMode 1\n"
"HiddenServiceNonAnonymousMode 1\n"
- "Tor2webMode 0\n"
);
ret = options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg);
tt_int_op(ret, OP_EQ, 0);
@@ -2626,27 +2599,13 @@ test_options_validate__single_onion(void *ignored)
tdata = get_options_test_data(TEST_OPTIONS_DEFAULT_VALUES
"SOCKSPort 5000\n"
"HiddenServiceSingleHopMode 0\n"
- "Tor2webMode 0\n"
);
ret = options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg);
tt_int_op(ret, OP_EQ, 0);
tt_ptr_op(msg, OP_EQ, NULL);
free_options_test_data(tdata);
- tdata = get_options_test_data(TEST_OPTIONS_DEFAULT_VALUES
- "SOCKSPort 5000\n"
- "HiddenServiceSingleHopMode 1\n"
- "HiddenServiceNonAnonymousMode 1\n"
- "Tor2webMode 1\n"
- );
- ret = options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg);
- tt_int_op(ret, OP_EQ, 0);
- tt_ptr_op(msg, OP_EQ, NULL);
- free_options_test_data(tdata);
-
- /* Test that a hidden service can't be run with Tor2web
- * Use HiddenServiceNonAnonymousMode instead of Tor2webMode, because
- * Tor2webMode requires a compilation #define */
+ /* Test that a hidden service can't be run in non anonymous mode. */
tdata = get_options_test_data(TEST_OPTIONS_DEFAULT_VALUES
"HiddenServiceNonAnonymousMode 1\n"
"HiddenServiceDir /Library/Tor/var/lib/tor/hidden_service/\n"
@@ -4135,16 +4094,6 @@ test_options_validate__testing_options(void *ignored)
free_options_test_data(tdata);
tdata = get_options_test_data(TEST_OPTIONS_DEFAULT_VALUES
"TestingEnableTbEmptyEvent 1\n"
- );
- ret = options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg);
- tt_int_op(ret, OP_EQ, -1);
- tt_str_op(msg, OP_EQ, "TestingEnableTbEmptyEvent may only be changed "
- "in testing Tor networks!");
- tor_free(msg);
-
- free_options_test_data(tdata);
- tdata = get_options_test_data(TEST_OPTIONS_DEFAULT_VALUES
- "TestingEnableTbEmptyEvent 1\n"
VALID_DIR_AUTH
"TestingTorNetwork 1\n"
"___UsingTestNetworkDefaults 0\n"
@@ -4261,8 +4210,6 @@ struct testcase_t options_tests[] = {
LOCAL_VALIDATE_TEST(path_bias),
LOCAL_VALIDATE_TEST(bandwidth),
LOCAL_VALIDATE_TEST(circuits),
- LOCAL_VALIDATE_TEST(port_forwarding),
- LOCAL_VALIDATE_TEST(tor2web),
LOCAL_VALIDATE_TEST(rend),
LOCAL_VALIDATE_TEST(single_onion),
LOCAL_VALIDATE_TEST(accounting),
@@ -4279,4 +4226,3 @@ struct testcase_t options_tests[] = {
LOCAL_VALIDATE_TEST(accel),
END_OF_TESTCASES /* */
};
-
diff --git a/src/test/test_pem.c b/src/test/test_pem.c
new file mode 100644
index 0000000000..2bae286e25
--- /dev/null
+++ b/src/test/test_pem.c
@@ -0,0 +1,122 @@
+/* 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 "orconfig.h"
+
+#include "lib/encoding/pem.h"
+#include "lib/cc/compat_compiler.h"
+#include "lib/malloc/malloc.h"
+
+#include "test/test.h"
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+static const char example_pre[] =
+ "Lest you get the wrong impression, we wombats "
+ "are not in the habit of tunneling madly about, without any supplies "
+ "or even a map."; /* -- Ursula Vernon, _Digger_ */
+static const char expected[] =
+ "-----BEGIN WOMBAT QUOTE-----\n"
+ "TGVzdCB5b3UgZ2V0IHRoZSB3cm9uZyBpbXByZXNzaW9uLCB3ZSB3b21iYXRzIGFy\n"
+ "ZSBub3QgaW4gdGhlIGhhYml0IG9mIHR1bm5lbGluZyBtYWRseSBhYm91dCwgd2l0\n"
+ "aG91dCBhbnkgc3VwcGxpZXMgb3IgZXZlbiBhIG1hcC4=\n"
+ "-----END WOMBAT QUOTE-----\n";
+
+static void
+test_crypto_pem_encode(void *arg)
+{
+ (void)arg;
+
+ char buf[4096];
+
+ int n = (int) pem_encoded_size(strlen(example_pre), "WOMBAT QUOTE");
+
+ int n2 = pem_encode(buf, sizeof(buf),
+ (const unsigned char *)example_pre, strlen(example_pre),
+ "WOMBAT QUOTE");
+ tt_int_op(strlen(buf)+1, OP_EQ, n);
+ tt_int_op(n2, OP_EQ, 0);
+ tt_str_op(buf, OP_EQ, expected);
+
+ /* Now make sure it succeeds if the buffer is exactly the length we want. */
+ memset(buf, 0, sizeof(buf));
+ n2 = pem_encode(buf, n, (const unsigned char *)example_pre,
+ strlen(example_pre), "WOMBAT QUOTE");
+ tt_int_op(n2, OP_EQ, 0);
+ tt_str_op(buf, OP_EQ, expected);
+
+ /* Make sure it fails if the buffer is too short. */
+ memset(buf, 0, sizeof(buf));
+ n2 = pem_encode(buf, n - 1, (const unsigned char *)example_pre,
+ strlen(example_pre), "WOMBAT QUOTE");
+ tt_int_op(n2, OP_EQ, -1);
+
+ done:
+ ;
+}
+
+static void
+test_crypto_pem_decode(void *arg)
+{
+ (void)arg;
+
+ unsigned char buf[4096];
+
+ /* Try a straightforward decoding. */
+ int n = pem_decode(buf, sizeof(buf),
+ expected, strlen(expected),
+ "WOMBAT QUOTE");
+ tt_int_op(n, OP_EQ, strlen(example_pre));
+ tt_mem_op(buf, OP_EQ, example_pre, n);
+
+ /* Succeed if the buffer is exactly the right size. */
+ memset(buf, 0xff, sizeof(buf));
+ n = pem_decode(buf, strlen(example_pre),
+ expected, strlen(expected),
+ "WOMBAT QUOTE");
+ tt_int_op(n, OP_EQ, strlen(example_pre));
+ tt_mem_op(buf, OP_EQ, example_pre, n);
+ tt_int_op(buf[n], OP_EQ, 0xff);
+
+ /* Verify that it fails if the buffer is too small. */
+ memset(buf, 0xff, sizeof(buf));
+ n = pem_decode(buf, strlen(example_pre) - 1,
+ expected, strlen(expected),
+ "WOMBAT QUOTE");
+ tt_int_op(n, OP_EQ, -1);
+
+ /* Verify that it fails with an incorrect tag. */
+ memset(buf, 0xff, sizeof(buf));
+ n = pem_decode(buf, sizeof(buf),
+ expected, strlen(expected),
+ "QUOKKA VOTE");
+ tt_int_op(n, OP_EQ, -1);
+
+ /* Try truncated buffers of different sizes. */
+ size_t i;
+ for (i = 0; i <= strlen(expected); ++i) {
+ char *truncated = tor_memdup(expected, i);
+ n = pem_decode(buf, sizeof(buf),
+ truncated, i,
+ "WOMBAT QUOTE");
+ tor_free(truncated);
+ if (i < strlen(expected) - 1) {
+ tt_int_op(n, OP_EQ, -1);
+ } else {
+ tt_int_op(n, OP_EQ, strlen(example_pre));
+ }
+ }
+
+ done:
+ ;
+}
+
+struct testcase_t pem_tests[] = {
+ { "encode", test_crypto_pem_encode, 0, NULL, NULL },
+ { "decode", test_crypto_pem_decode, 0, NULL, NULL },
+ END_OF_TESTCASES
+};
diff --git a/src/test/test_periodic_event.c b/src/test/test_periodic_event.c
new file mode 100644
index 0000000000..86dedd85d8
--- /dev/null
+++ b/src/test/test_periodic_event.c
@@ -0,0 +1,333 @@
+/* Copyright (c) 2018, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+/**
+ * \file test_periodic_event.c
+ * \brief Test the periodic events that Tor uses for different roles. They are
+ * part of the libevent mainloop
+ */
+
+#define CONFIG_PRIVATE
+#define HS_SERVICE_PRIVATE
+#define MAINLOOP_PRIVATE
+
+#include "test/test.h"
+#include "test/test_helpers.h"
+
+#include "core/or/or.h"
+#include "app/config/config.h"
+#include "feature/hibernate/hibernate.h"
+#include "feature/hs/hs_service.h"
+#include "core/mainloop/mainloop.h"
+#include "core/mainloop/periodic.h"
+
+/** Helper function: This is replaced in some tests for the event callbacks so
+ * we don't actually go into the code path of those callbacks. */
+static int
+dumb_event_fn(time_t now, const or_options_t *options)
+{
+ (void) now;
+ (void) options;
+
+ /* Will get rescheduled in 300 seconds. It just can't be 0. */
+ return 300;
+}
+
+static void
+register_dummy_hidden_service(hs_service_t *service)
+{
+ memset(service, 0, sizeof(hs_service_t));
+ memset(&service->keys.identity_pk, 'A', sizeof(service->keys.identity_pk));
+ (void) register_service(get_hs_service_map(), service);
+}
+
+static void
+test_pe_initialize(void *arg)
+{
+ (void) arg;
+
+ /* Initialize the events but the callback won't get called since we would
+ * need to run the main loop and then wait for a second delaying the unit
+ * tests. Instead, we'll test the callback work indepedently elsewhere. */
+ initialize_periodic_events();
+
+ /* Validate that all events have been set up. */
+ for (int i = 0; periodic_events[i].name; ++i) {
+ periodic_event_item_t *item = &periodic_events[i];
+ tt_assert(item->ev);
+ tt_assert(item->fn);
+ tt_u64_op(item->last_action_time, OP_EQ, 0);
+ /* Every event must have role(s) assign to it. This is done statically. */
+ tt_u64_op(item->roles, OP_NE, 0);
+ tt_uint_op(periodic_event_is_enabled(item), OP_EQ, 0);
+ }
+
+ done:
+ teardown_periodic_events();
+}
+
+static void
+test_pe_launch(void *arg)
+{
+ hs_service_t service, *to_remove = NULL;
+ or_options_t *options;
+
+ (void) arg;
+
+ hs_init();
+ /* We need to put tor in hibernation live state so the events requiring
+ * network gets enabled. */
+ consider_hibernation(time(NULL));
+
+ /* Hack: We'll set a dumb fn() of each events so they don't get called when
+ * dispatching them. We just want to test the state of the callbacks, not
+ * the whole code path. */
+ for (int i = 0; periodic_events[i].name; ++i) {
+ periodic_event_item_t *item = &periodic_events[i];
+ item->fn = dumb_event_fn;
+ }
+
+ options = get_options_mutable();
+ options->SocksPort_set = 1;
+ periodic_events_on_new_options(options);
+#if 0
+ /* Lets make sure that before intialization, we can't scan the periodic
+ * events list and launch them. Lets try by being a Client. */
+ /* XXXX We make sure these events are initialized now way earlier than we
+ * did before. */
+ for (int i = 0; periodic_events[i].name; ++i) {
+ periodic_event_item_t *item = &periodic_events[i];
+ tt_int_op(periodic_event_is_enabled(item), OP_EQ, 0);
+ }
+#endif
+
+ initialize_periodic_events();
+
+ /* Now that we've initialized, rescan the list to launch. */
+ periodic_events_on_new_options(options);
+
+ for (int i = 0; periodic_events[i].name; ++i) {
+ periodic_event_item_t *item = &periodic_events[i];
+ if (item->roles & PERIODIC_EVENT_ROLE_CLIENT) {
+ tt_int_op(periodic_event_is_enabled(item), OP_EQ, 1);
+ } else {
+ tt_int_op(periodic_event_is_enabled(item), OP_EQ, 0);
+ }
+ // enabled or not, the event has not yet been run.
+ tt_u64_op(item->last_action_time, OP_EQ, 0);
+ }
+
+ /* Remove Client but become a Relay. */
+ options->SocksPort_set = 0;
+ options->ORPort_set = 1;
+ periodic_events_on_new_options(options);
+
+ unsigned roles = get_my_roles(options);
+ tt_uint_op(roles, OP_EQ,
+ PERIODIC_EVENT_ROLE_RELAY|PERIODIC_EVENT_ROLE_DIRSERVER);
+
+ for (int i = 0; periodic_events[i].name; ++i) {
+ periodic_event_item_t *item = &periodic_events[i];
+ /* Only Client role should be disabled. */
+ if (item->roles == PERIODIC_EVENT_ROLE_CLIENT) {
+ tt_int_op(periodic_event_is_enabled(item), OP_EQ, 0);
+ }
+ if (item->roles & PERIODIC_EVENT_ROLE_RELAY) {
+ tt_int_op(periodic_event_is_enabled(item), OP_EQ, 1);
+ }
+ /* Non Relay role should be disabled, except for Dirserver. */
+ if (!(item->roles & roles)) {
+ tt_int_op(periodic_event_is_enabled(item), OP_EQ, 0);
+ }
+ }
+
+ /* Disable everything and we'll enable them ALL. */
+ options->SocksPort_set = 0;
+ options->ORPort_set = 0;
+ periodic_events_on_new_options(options);
+
+ for (int i = 0; periodic_events[i].name; ++i) {
+ periodic_event_item_t *item = &periodic_events[i];
+ tt_int_op(periodic_event_is_enabled(item), OP_EQ, 0);
+ }
+
+ /* Enable everything. */
+ options->SocksPort_set = 1; options->ORPort_set = 1;
+ options->BridgeRelay = 1; options->AuthoritativeDir = 1;
+ options->V3AuthoritativeDir = 1; options->BridgeAuthoritativeDir = 1;
+ register_dummy_hidden_service(&service);
+ periodic_events_on_new_options(options);
+ /* Note down the reference because we need to remove this service from the
+ * global list before the hs_free_all() call so it doesn't try to free
+ * memory on the stack. Furthermore, we can't remove it now else it will
+ * trigger a rescan of the event disabling the HS service event. */
+ to_remove = &service;
+
+ for (int i = 0; periodic_events[i].name; ++i) {
+ periodic_event_item_t *item = &periodic_events[i];
+ tt_int_op(periodic_event_is_enabled(item), OP_EQ, 1);
+ }
+
+ done:
+ if (to_remove) {
+ remove_service(get_hs_service_map(), to_remove);
+ }
+ hs_free_all();
+}
+
+static void
+test_pe_get_roles(void *arg)
+{
+ int roles;
+
+ (void) arg;
+
+ /* Just so the HS global map exists. */
+ hs_init();
+
+ or_options_t *options = get_options_mutable();
+ tt_assert(options);
+
+ /* Nothing configured, should be no roles. */
+ roles = get_my_roles(options);
+ tt_int_op(roles, OP_EQ, 0);
+
+ /* Indicate we have a SocksPort, roles should be come Client. */
+ options->SocksPort_set = 1;
+ roles = get_my_roles(options);
+ tt_int_op(roles, OP_EQ, PERIODIC_EVENT_ROLE_CLIENT);
+
+ /* Now, we'll add a ORPort so should now be a Relay + Client. */
+ options->ORPort_set = 1;
+ roles = get_my_roles(options);
+ tt_int_op(roles, OP_EQ,
+ (PERIODIC_EVENT_ROLE_CLIENT | PERIODIC_EVENT_ROLE_RELAY |
+ PERIODIC_EVENT_ROLE_DIRSERVER));
+
+ /* Now add a Bridge. */
+ options->BridgeRelay = 1;
+ roles = get_my_roles(options);
+ tt_int_op(roles, OP_EQ,
+ (PERIODIC_EVENT_ROLE_CLIENT | PERIODIC_EVENT_ROLE_RELAY |
+ PERIODIC_EVENT_ROLE_BRIDGE | PERIODIC_EVENT_ROLE_DIRSERVER));
+ tt_assert(roles & PERIODIC_EVENT_ROLE_ROUTER);
+ /* Unset client so we can solely test Router role. */
+ options->SocksPort_set = 0;
+ roles = get_my_roles(options);
+ tt_int_op(roles, OP_EQ,
+ PERIODIC_EVENT_ROLE_ROUTER | PERIODIC_EVENT_ROLE_DIRSERVER);
+
+ /* Reset options so we can test authorities. */
+ options->SocksPort_set = 0;
+ options->ORPort_set = 0;
+ options->BridgeRelay = 0;
+ roles = get_my_roles(options);
+ tt_int_op(roles, OP_EQ, 0);
+
+ /* Now upgrade to Dirauth. */
+ options->DirPort_set = 1;
+ options->AuthoritativeDir = 1;
+ options->V3AuthoritativeDir = 1;
+ roles = get_my_roles(options);
+ tt_int_op(roles, OP_EQ,
+ PERIODIC_EVENT_ROLE_DIRAUTH|PERIODIC_EVENT_ROLE_DIRSERVER);
+ tt_assert(roles & PERIODIC_EVENT_ROLE_AUTHORITIES);
+
+ /* Now Bridge Authority. */
+ options->V3AuthoritativeDir = 0;
+ options->BridgeAuthoritativeDir = 1;
+ roles = get_my_roles(options);
+ tt_int_op(roles, OP_EQ,
+ PERIODIC_EVENT_ROLE_BRIDGEAUTH|PERIODIC_EVENT_ROLE_DIRSERVER);
+ tt_assert(roles & PERIODIC_EVENT_ROLE_AUTHORITIES);
+
+ /* Move that bridge auth to become a relay. */
+ options->ORPort_set = 1;
+ roles = get_my_roles(options);
+ tt_int_op(roles, OP_EQ,
+ (PERIODIC_EVENT_ROLE_BRIDGEAUTH | PERIODIC_EVENT_ROLE_RELAY
+ | PERIODIC_EVENT_ROLE_DIRSERVER));
+ tt_assert(roles & PERIODIC_EVENT_ROLE_AUTHORITIES);
+
+ /* And now an Hidden service. */
+ hs_service_t service;
+ register_dummy_hidden_service(&service);
+ roles = get_my_roles(options);
+ /* Remove it now so the hs_free_all() doesn't try to free stack memory. */
+ remove_service(get_hs_service_map(), &service);
+ tt_int_op(roles, OP_EQ,
+ (PERIODIC_EVENT_ROLE_BRIDGEAUTH | PERIODIC_EVENT_ROLE_RELAY |
+ PERIODIC_EVENT_ROLE_HS_SERVICE | PERIODIC_EVENT_ROLE_DIRSERVER));
+ tt_assert(roles & PERIODIC_EVENT_ROLE_AUTHORITIES);
+
+ done:
+ hs_free_all();
+}
+
+static void
+test_pe_hs_service(void *arg)
+{
+ hs_service_t service, *to_remove = NULL;
+
+ (void) arg;
+
+ hs_init();
+ /* We need to put tor in hibernation live state so the events requiring
+ * network gets enabled. */
+ consider_hibernation(time(NULL));
+ /* Initialize the events so we can enable them */
+ initialize_periodic_events();
+
+ /* Hack: We'll set a dumb fn() of each events so they don't get called when
+ * dispatching them. We just want to test the state of the callbacks, not
+ * the whole code path. */
+ for (int i = 0; periodic_events[i].name; ++i) {
+ periodic_event_item_t *item = &periodic_events[i];
+ item->fn = dumb_event_fn;
+ }
+
+ /* This should trigger a rescan of the list and enable the HS service
+ * events. */
+ register_dummy_hidden_service(&service);
+ /* Note down the reference because we need to remove this service from the
+ * global list before the hs_free_all() call so it doesn't try to free
+ * memory on the stack. Furthermore, we can't remove it now else it will
+ * trigger a rescan of the event disabling the HS service event. */
+ to_remove = &service;
+
+ for (int i = 0; periodic_events[i].name; ++i) {
+ periodic_event_item_t *item = &periodic_events[i];
+ if (item->roles & PERIODIC_EVENT_ROLE_HS_SERVICE) {
+ tt_int_op(periodic_event_is_enabled(item), OP_EQ, 1);
+ }
+ }
+ to_remove = NULL;
+
+ /* Remove the service from the global map, it should trigger a rescan and
+ * disable the HS service events. */
+ remove_service(get_hs_service_map(), &service);
+ for (int i = 0; periodic_events[i].name; ++i) {
+ periodic_event_item_t *item = &periodic_events[i];
+ if (item->roles & PERIODIC_EVENT_ROLE_HS_SERVICE) {
+ tt_int_op(periodic_event_is_enabled(item), OP_EQ, 0);
+ }
+ }
+
+ done:
+ if (to_remove) {
+ remove_service(get_hs_service_map(), to_remove);
+ }
+ hs_free_all();
+}
+
+#define PE_TEST(name) \
+ { #name, test_pe_## name , TT_FORK, NULL, NULL }
+
+struct testcase_t periodic_event_tests[] = {
+ PE_TEST(initialize),
+ PE_TEST(launch),
+ PE_TEST(get_roles),
+ PE_TEST(hs_service),
+
+ END_OF_TESTCASES
+};
diff --git a/src/test/test_policy.c b/src/test/test_policy.c
index f8aa8ac40b..afe608f5f7 100644
--- a/src/test/test_policy.c
+++ b/src/test/test_policy.c
@@ -1,14 +1,22 @@
-/* Copyright (c) 2013-2017, The Tor Project, Inc. */
+/* Copyright (c) 2013-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
-#include "or.h"
#define CONFIG_PRIVATE
-#include "config.h"
-#include "router.h"
-#include "routerparse.h"
#define POLICIES_PRIVATE
-#include "policies.h"
-#include "test.h"
+
+#include "core/or/or.h"
+#include "app/config/config.h"
+#include "core/or/policies.h"
+#include "feature/dirparse/policy_parse.h"
+#include "feature/relay/router.h"
+#include "lib/encoding/confline.h"
+#include "test/test.h"
+
+#include "core/or/addr_policy_st.h"
+#include "core/or/port_cfg_st.h"
+#include "feature/nodelist/node_st.h"
+#include "feature/nodelist/routerinfo_st.h"
+#include "feature/nodelist/routerstatus_st.h"
/* Helper: assert that short_policy parses and writes back out as itself,
or as <b>expected</b> if that's provided. */
@@ -1496,9 +1504,21 @@ test_dump_exit_policy_to_string(void *arg)
}
static routerinfo_t *mock_desc_routerinfo = NULL;
+static int routerinfo_err;
+
static const routerinfo_t *
-mock_router_get_my_routerinfo(void)
+mock_router_get_my_routerinfo_with_err(int *err)
{
+ if (routerinfo_err) {
+ if (err)
+ *err = routerinfo_err;
+
+ return NULL;
+ }
+
+ if (err)
+ *err = 0;
+
return mock_desc_routerinfo;
}
@@ -1541,7 +1561,8 @@ test_policies_getinfo_helper_policies(void *arg)
tor_free(answer);
memset(&mock_my_routerinfo, 0, sizeof(routerinfo_t));
- MOCK(router_get_my_routerinfo, mock_router_get_my_routerinfo);
+ MOCK(router_get_my_routerinfo_with_err,
+ mock_router_get_my_routerinfo_with_err);
mock_my_routerinfo.exit_policy = smartlist_new();
mock_desc_routerinfo = &mock_my_routerinfo;
@@ -1658,6 +1679,55 @@ test_policies_getinfo_helper_policies(void *arg)
tt_assert(strlen(answer) == ipv4_len + ipv6_len + 1);
tor_free(answer);
+ routerinfo_err = TOR_ROUTERINFO_ERROR_NO_EXT_ADDR;
+ rv = getinfo_helper_policies(NULL, "exit-policy/full", &answer,
+ &errmsg);
+ tt_int_op(rv, OP_EQ, -1);
+ tt_ptr_op(answer, OP_EQ, NULL);
+ tt_ptr_op(errmsg, OP_NE, NULL);
+ tt_str_op(errmsg, OP_EQ, "No known exit address yet");
+
+ routerinfo_err = TOR_ROUTERINFO_ERROR_CANNOT_PARSE;
+ rv = getinfo_helper_policies(NULL, "exit-policy/full", &answer,
+ &errmsg);
+ tt_int_op(rv, OP_EQ, -1);
+ tt_ptr_op(answer, OP_EQ, NULL);
+ tt_ptr_op(errmsg, OP_NE, NULL);
+ tt_str_op(errmsg, OP_EQ, "Cannot parse descriptor");
+
+ routerinfo_err = TOR_ROUTERINFO_ERROR_NOT_A_SERVER;
+ rv = getinfo_helper_policies(NULL, "exit-policy/full", &answer,
+ &errmsg);
+ tt_int_op(rv, OP_EQ, 0);
+ tt_ptr_op(answer, OP_EQ, NULL);
+ tt_ptr_op(errmsg, OP_NE, NULL);
+ tt_str_op(errmsg, OP_EQ, "Not running in server mode");
+
+ routerinfo_err = TOR_ROUTERINFO_ERROR_DIGEST_FAILED;
+ rv = getinfo_helper_policies(NULL, "exit-policy/full", &answer,
+ &errmsg);
+
+ tt_int_op(rv, OP_EQ, -1);
+ tt_ptr_op(answer, OP_EQ, NULL);
+ tt_ptr_op(errmsg, OP_NE, NULL);
+ tt_str_op(errmsg, OP_EQ, "Key digest failed");
+
+ routerinfo_err = TOR_ROUTERINFO_ERROR_CANNOT_GENERATE;
+ rv = getinfo_helper_policies(NULL, "exit-policy/full", &answer,
+ &errmsg);
+ tt_int_op(rv, OP_EQ, -1);
+ tt_ptr_op(answer, OP_EQ, NULL);
+ tt_ptr_op(errmsg, OP_NE, NULL);
+ tt_str_op(errmsg, OP_EQ, "Cannot generate descriptor");
+
+ routerinfo_err = TOR_ROUTERINFO_ERROR_DESC_REBUILDING;
+ rv = getinfo_helper_policies(NULL, "exit-policy/full", &answer,
+ &errmsg);
+ tt_int_op(rv, OP_EQ, -1);
+ tt_ptr_op(answer, OP_EQ, NULL);
+ tt_ptr_op(errmsg, OP_NE, NULL);
+ tt_str_op(errmsg, OP_EQ, "Descriptor still rebuilding - not ready yet");
+
done:
tor_free(answer);
UNMOCK(get_options);
@@ -1923,11 +1993,8 @@ test_policies_fascist_firewall_allows_address(void *arg)
tor_addr_port_t chosen_rs_ap; \
tor_addr_make_null(&chosen_rs_ap.addr, AF_INET); \
chosen_rs_ap.port = 0; \
- tt_int_op(fascist_firewall_choose_address_rs(&(fake_rs), \
- (fw_connection), \
- (pref_only), \
- &chosen_rs_ap), \
- OP_EQ, (expect_rv)); \
+ fascist_firewall_choose_address_rs(&(fake_rs), (fw_connection), \
+ (pref_only), &chosen_rs_ap); \
tt_assert(tor_addr_eq(&(expect_ap).addr, &chosen_rs_ap.addr)); \
tt_int_op((expect_ap).port, OP_EQ, chosen_rs_ap.port); \
STMT_END
@@ -1940,11 +2007,8 @@ test_policies_fascist_firewall_allows_address(void *arg)
tor_addr_port_t chosen_node_ap; \
tor_addr_make_null(&chosen_node_ap.addr, AF_INET); \
chosen_node_ap.port = 0; \
- tt_int_op(fascist_firewall_choose_address_node(&(fake_node), \
- (fw_connection), \
- (pref_only), \
- &chosen_node_ap), \
- OP_EQ, (expect_rv)); \
+ fascist_firewall_choose_address_node(&(fake_node),(fw_connection), \
+ (pref_only), &chosen_node_ap); \
tt_assert(tor_addr_eq(&(expect_ap).addr, &chosen_node_ap.addr)); \
tt_int_op((expect_ap).port, OP_EQ, chosen_node_ap.port); \
STMT_END
@@ -2389,4 +2453,3 @@ struct testcase_t policy_tests[] = {
test_policies_fascist_firewall_choose_address, 0, NULL, NULL },
END_OF_TESTCASES
};
-
diff --git a/src/test/test_procmon.c b/src/test/test_procmon.c
index 5c52af8693..2c7918f580 100644
--- a/src/test/test_procmon.c
+++ b/src/test/test_procmon.c
@@ -1,14 +1,14 @@
-/* Copyright (c) 2010-2017, The Tor Project, Inc. */
+/* Copyright (c) 2010-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
#define PROCMON_PRIVATE
#include "orconfig.h"
-#include "or.h"
-#include "test.h"
+#include "core/or/or.h"
+#include "test/test.h"
-#include "procmon.h"
+#include "lib/evloop/procmon.h"
-#include "log_test_helpers.h"
+#include "test/log_test_helpers.h"
#define NS_MODULE procmon
diff --git a/src/test/test_proto_http.c b/src/test/test_proto_http.c
index 2f36fbccd7..1cfa0a752c 100644
--- a/src/test/test_proto_http.c
+++ b/src/test/test_proto_http.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017, The Tor Project, Inc. */
+/* Copyright (c) 2017-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
/**
@@ -6,11 +6,11 @@
* \brief Tests for our HTTP protocol parser code
*/
-#include "or.h"
-#include "test.h"
-#include "buffers.h"
-#include "proto_http.h"
-#include "log_test_helpers.h"
+#include "core/or/or.h"
+#include "test/test.h"
+#include "lib/container/buffers.h"
+#include "core/proto/proto_http.h"
+#include "test/log_test_helpers.h"
#define S(str) str, sizeof(str)-1
diff --git a/src/test/test_proto_misc.c b/src/test/test_proto_misc.c
index 263ca47447..1fcb763421 100644
--- a/src/test/test_proto_misc.c
+++ b/src/test/test_proto_misc.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017, The Tor Project, Inc. */
+/* Copyright (c) 2017-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
/**
@@ -6,14 +6,16 @@
* \brief Test our smaller buffer-based protocol functions
*/
-#include "or.h"
-#include "test.h"
-#include "buffers.h"
-#include "connection_or.h"
-#include "ext_orport.h"
-#include "proto_cell.h"
-#include "proto_control0.h"
-#include "proto_ext_or.h"
+#include "core/or/or.h"
+#include "test/test.h"
+#include "lib/container/buffers.h"
+#include "core/or/connection_or.h"
+#include "feature/relay/ext_orport.h"
+#include "core/proto/proto_cell.h"
+#include "core/proto/proto_control0.h"
+#include "core/proto/proto_ext_or.h"
+
+#include "core/or/var_cell_st.h"
static void
test_proto_var_cell(void *arg)
diff --git a/src/test/test_protover.c b/src/test/test_protover.c
index fb374c728b..b835e28ab5 100644
--- a/src/test/test_protover.c
+++ b/src/test/test_protover.c
@@ -1,15 +1,16 @@
-/* Copyright (c) 2016-2017, The Tor Project, Inc. */
+/* Copyright (c) 2016-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
#define PROTOVER_PRIVATE
#include "orconfig.h"
-#include "test.h"
+#include "test/test.h"
-#include "protover.h"
+#include "core/or/protover.h"
-#include "or.h"
-#include "connection_or.h"
+#include "core/or/or.h"
+#include "core/or/connection_or.h"
+#include "lib/tls/tortls.h"
static void
test_protover_parse(void *arg)
@@ -167,6 +168,14 @@ test_protover_vote(void *arg)
tt_str_op(result, OP_EQ, "");
tor_free(result);
+ /* Don't count double-voting. */
+ smartlist_clear(lst);
+ smartlist_add(lst, (void*) "Foo=1 Foo=1");
+ smartlist_add(lst, (void*) "Bar=1-2,2-3");
+ result = protover_compute_vote(lst, 2);
+ tt_str_op(result, OP_EQ, "");
+ tor_free(result);
+
/* Bad votes: the result must be empty */
smartlist_clear(lst);
smartlist_add(lst, (void*) "Faux=10-5");
@@ -229,8 +238,8 @@ test_protover_vote(void *arg)
/* Protocol name too long */
smartlist_clear(lst);
smartlist_add(lst, (void*) "DoSaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
- "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
- "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
result = protover_compute_vote(lst, 1);
tt_str_op(result, OP_EQ, "");
tor_free(result);
@@ -320,10 +329,10 @@ test_protover_all_supported(void *arg)
#ifndef HAVE_RUST // XXXXXX ?????
tor_capture_bugs_(1);
tt_assert(protover_all_supported(
- "DoSaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
- "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
- "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
- "aaaaaaaaaaaa=1-65536", &msg));
+ "DoSaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaa=1-65536", &msg));
tor_end_capture_bugs_();
#endif
@@ -444,10 +453,12 @@ test_protover_supported_protocols(void *arg)
}
}
+#ifdef HAVE_WORKING_TOR_TLS_GET_TLSSECRETS
/* Legacy LinkAuth does not appear anywhere in the code. */
tt_assert(protocol_list_supports_protocol(supported_protocols,
PRT_LINKAUTH,
PROTOVER_LINKAUTH_V1));
+#endif
/* Latest LinkAuth is not exposed in the headers. */
tt_assert(protocol_list_supports_protocol(supported_protocols,
PRT_LINKAUTH,
@@ -543,6 +554,10 @@ test_protover_vote_roundtrip(void *args)
const char *input;
const char *expected_output;
} examples[] = {
+ { "Risqu\u00e9=1", NULL },
+ { ",,,=1", NULL },
+ { "\xc1=1", NULL },
+ { "Foo_Bar=1", NULL },
{ "Fkrkljdsf", NULL },
{ "Zn=4294967295", NULL },
{ "Zn=4294967295-1", NULL },
@@ -575,6 +590,14 @@ test_protover_vote_roundtrip(void *args)
{ "Faux=-1", NULL },
{ "Faux=-1-3", NULL },
{ "Faux=1--1", NULL },
+ { "Link=1-2-", NULL },
+ { "Link=1-2-3", NULL },
+ { "Faux=1-2-", NULL },
+ { "Faux=1-2-3", NULL },
+ { "Link=\t1,3", NULL },
+ { "Link=1\n,3", NULL },
+ { "Faux=1,\r3", NULL },
+ { "Faux=1,3\f", NULL },
/* Large integers */
{ "Link=4294967296", NULL },
/* Large range */
@@ -625,4 +648,3 @@ struct testcase_t protover_tests[] = {
PV_TEST(vote_roundtrip, 0),
END_OF_TESTCASES
};
-
diff --git a/src/test/test_pt.c b/src/test/test_pt.c
index 07b6712ff9..d0160d1148 100644
--- a/src/test/test_pt.c
+++ b/src/test/test_pt.c
@@ -1,6 +1,6 @@
/* Copyright (c) 2001-2004, Roger Dingledine.
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2017, The Tor Project, Inc. */
+ * Copyright (c) 2007-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
#include "orconfig.h"
@@ -8,15 +8,20 @@
#define UTIL_PRIVATE
#define STATEFILE_PRIVATE
#define CONTROL_PRIVATE
-#include "or.h"
-#include "config.h"
-#include "confparse.h"
-#include "control.h"
-#include "transports.h"
-#include "circuitbuild.h"
-#include "util.h"
-#include "statefile.h"
-#include "test.h"
+#define SUBPROCESS_PRIVATE
+#include "core/or/or.h"
+#include "app/config/config.h"
+#include "app/config/confparse.h"
+#include "feature/control/control.h"
+#include "feature/client/transports.h"
+#include "core/or/circuitbuild.h"
+#include "app/config/statefile.h"
+#include "test/test.h"
+#include "lib/process/subprocess.h"
+#include "lib/encoding/confline.h"
+#include "lib/net/resolve.h"
+
+#include "app/config/or_state_st.h"
static void
reset_mp(managed_proxy_t *mp)
@@ -544,4 +549,3 @@ struct testcase_t pt_tests[] = {
NULL, NULL },
END_OF_TESTCASES
};
-
diff --git a/src/test/test_pubsub.c b/src/test/test_pubsub.c
deleted file mode 100644
index 2f047d9f2c..0000000000
--- a/src/test/test_pubsub.c
+++ /dev/null
@@ -1,85 +0,0 @@
-/* Copyright (c) 2016-2017, The Tor Project, Inc. */
-/* See LICENSE for licensing information */
-
-/**
- * \file test_pubsub.c
- * \brief Unit tests for publish-subscribe abstraction.
- **/
-
-#include "or.h"
-#include "test.h"
-#include "pubsub.h"
-
-DECLARE_PUBSUB_STRUCT_TYPES(foobar)
-DECLARE_PUBSUB_TOPIC(foobar)
-DECLARE_NOTIFY_PUBSUB_TOPIC(static, foobar)
-IMPLEMENT_PUBSUB_TOPIC(static, foobar)
-
-struct foobar_event_data_t {
- unsigned u;
- const char *s;
-};
-
-struct foobar_subscriber_data_t {
- const char *name;
- long l;
-};
-
-static int
-foobar_sub1(foobar_event_data_t *ev, foobar_subscriber_data_t *mine)
-{
- ev->u += 10;
- mine->l += 100;
- return 0;
-}
-
-static int
-foobar_sub2(foobar_event_data_t *ev, foobar_subscriber_data_t *mine)
-{
- ev->u += 5;
- mine->l += 50;
- return 0;
-}
-
-static void
-test_pubsub_basic(void *arg)
-{
- (void)arg;
- foobar_subscriber_data_t subdata1 = { "hi", 0 };
- foobar_subscriber_data_t subdata2 = { "wow", 0 };
- const foobar_subscriber_t *sub1;
- const foobar_subscriber_t *sub2;
- foobar_event_data_t ed = { 0, "x" };
- foobar_event_data_t ed2 = { 0, "y" };
- sub1 = foobar_subscribe(foobar_sub1, &subdata1, SUBSCRIBE_ATSTART, 100);
- tt_assert(sub1);
-
- foobar_notify(&ed, 0);
- tt_int_op(subdata1.l, OP_EQ, 100);
- tt_int_op(subdata2.l, OP_EQ, 0);
- tt_int_op(ed.u, OP_EQ, 10);
-
- sub2 = foobar_subscribe(foobar_sub2, &subdata2, 0, 5);
- tt_assert(sub2);
-
- foobar_notify(&ed2, 0);
- tt_int_op(subdata1.l, OP_EQ, 200);
- tt_int_op(subdata2.l, OP_EQ, 50);
- tt_int_op(ed2.u, OP_EQ, 15);
-
- foobar_unsubscribe(sub1);
-
- foobar_notify(&ed, 0);
- tt_int_op(subdata1.l, OP_EQ, 200);
- tt_int_op(subdata2.l, OP_EQ, 100);
- tt_int_op(ed.u, OP_EQ, 15);
-
- done:
- foobar_clear();
-}
-
-struct testcase_t pubsub_tests[] = {
- { "pubsub_basic", test_pubsub_basic, TT_FORK, NULL, NULL },
- END_OF_TESTCASES
-};
-
diff --git a/src/test/test_rebind.py b/src/test/test_rebind.py
new file mode 100644
index 0000000000..7ba3a5796d
--- /dev/null
+++ b/src/test/test_rebind.py
@@ -0,0 +1,93 @@
+from __future__ import print_function
+
+import sys
+import subprocess
+import socket
+import os
+import time
+import random
+
+def try_connecting_to_socksport():
+ socks_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ if socks_socket.connect_ex(('127.0.0.1', socks_port)):
+ tor_process.terminate()
+ print('FAIL')
+ sys.exit('Cannot connect to SOCKSPort')
+ socks_socket.close()
+
+def wait_for_log(s):
+ while True:
+ l = tor_process.stdout.readline()
+ if s in l.decode('utf8'):
+ return
+
+def pick_random_port():
+ port = 0
+ random.seed()
+
+ for i in range(8):
+ port = random.randint(10000, 60000)
+ s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ if s.connect_ex(('127.0.0.1', port)) == 0:
+ s.close()
+ else:
+ break
+
+ return port
+
+if sys.hexversion < 0x02070000:
+ sys.exit("ERROR: unsupported Python version (should be >= 2.7)")
+
+if sys.hexversion > 0x03000000 and sys.hexversion < 0x03010000:
+ sys.exit("ERROR: unsupported Python3 version (should be >= 3.1)")
+
+control_port = pick_random_port()
+socks_port = pick_random_port()
+
+assert control_port != 0
+assert socks_port != 0
+
+if not os.path.exists(sys.argv[1]):
+ sys.exit('ERROR: cannot find tor at %s' % sys.argv[1])
+
+tor_path = sys.argv[1]
+
+tor_process = subprocess.Popen([tor_path,
+ '-ControlPort', '127.0.0.1:{}'.format(control_port),
+ '-SOCKSPort', '127.0.0.1:{}'.format(socks_port),
+ '-FetchServerDescriptors', '0'],
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE)
+
+if tor_process == None:
+ sys.exit('ERROR: running tor failed')
+
+if len(sys.argv) < 2:
+ sys.exit('Usage: %s <path-to-tor>' % sys.argv[0])
+
+wait_for_log('Opened Control listener on')
+
+try_connecting_to_socksport()
+
+control_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+if control_socket.connect_ex(('127.0.0.1', control_port)):
+ tor_process.terminate()
+ print('FAIL')
+ sys.exit('Cannot connect to ControlPort')
+
+control_socket.sendall('AUTHENTICATE \r\n'.encode('utf8'))
+control_socket.sendall('SETCONF SOCKSPort=0.0.0.0:{}\r\n'.format(socks_port).encode('utf8'))
+wait_for_log('Opened Socks listener')
+
+try_connecting_to_socksport()
+
+control_socket.sendall('SETCONF SOCKSPort=127.0.0.1:{}\r\n'.format(socks_port).encode('utf8'))
+wait_for_log('Opened Socks listener')
+
+try_connecting_to_socksport()
+
+control_socket.sendall('SIGNAL HALT\r\n'.encode('utf8'))
+
+time.sleep(0.1)
+print('OK')
+tor_process.terminate()
diff --git a/src/test/test_rebind.sh b/src/test/test_rebind.sh
new file mode 100755
index 0000000000..76eb9f2e4d
--- /dev/null
+++ b/src/test/test_rebind.sh
@@ -0,0 +1,19 @@
+#!/bin/sh
+
+set -x
+
+UNAME_OS=$(uname -s | cut -d_ -f1)
+if test "$UNAME_OS" = 'CYGWIN' || \
+ test "$UNAME_OS" = 'MSYS' || \
+ test "$UNAME_OS" = 'MINGW'; then
+ if test "$APPVEYOR" = 'True'; then
+ echo "This test is disabled on Windows CI, as it requires firewall examptions. Skipping." >&2
+ exit 77
+ fi
+fi
+
+exitcode=0
+
+"${PYTHON:-python}" "${abs_top_srcdir:-.}/src/test/test_rebind.py" "${TESTING_TOR_BINARY}" || exitcode=1
+
+exit ${exitcode}
diff --git a/src/test/test_relay.c b/src/test/test_relay.c
index 73c0ed5586..4311392be8 100644
--- a/src/test/test_relay.c
+++ b/src/test/test_relay.c
@@ -1,17 +1,26 @@
-/* Copyright (c) 2014-2017, The Tor Project, Inc. */
+/* Copyright (c) 2014-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
-#include "or.h"
#define CIRCUITBUILD_PRIVATE
-#include "circuitbuild.h"
#define RELAY_PRIVATE
-#include "relay.h"
+#define REPHIST_PRIVATE
+#include "core/or/or.h"
+#include "core/or/circuitbuild.h"
+#include "core/or/circuitlist.h"
+#include "core/or/channeltls.h"
+#include "feature/stats/rephist.h"
+#include "core/or/relay.h"
+#include "feature/stats/rephist.h"
+#include "lib/container/order.h"
/* For init/free stuff */
-#include "scheduler.h"
+#include "core/or/scheduler.h"
+
+#include "core/or/cell_st.h"
+#include "core/or/or_circuit_st.h"
/* Test suite stuff */
-#include "test.h"
-#include "fakechans.h"
+#include "test/test.h"
+#include "test/fakechans.h"
static or_circuit_t * new_fake_orcirc(channel_t *nchan, channel_t *pchan);
@@ -27,10 +36,9 @@ new_fake_orcirc(channel_t *nchan, channel_t *pchan)
circ = &(orcirc->base_);
circ->magic = OR_CIRCUIT_MAGIC;
- circ->n_chan = nchan;
- circ->n_circ_id = get_unique_circ_id_by_chan(nchan);
- circ->n_mux = NULL; /* ?? */
+ circuit_set_n_circid_chan(circ, get_unique_circ_id_by_chan(nchan), nchan);
cell_queue_init(&(circ->n_chan_cells));
+
circ->n_hop = NULL;
circ->streams_blocked_on_n_chan = 0;
circ->streams_blocked_on_p_chan = 0;
@@ -43,14 +51,109 @@ new_fake_orcirc(channel_t *nchan, channel_t *pchan)
circ->deliver_window = CIRCWINDOW_START_MAX;
circ->n_chan_create_cell = NULL;
- orcirc->p_chan = pchan;
- orcirc->p_circ_id = get_unique_circ_id_by_chan(pchan);
+ circuit_set_p_circid_chan(orcirc, get_unique_circ_id_by_chan(pchan), pchan);
cell_queue_init(&(orcirc->p_chan_cells));
return orcirc;
}
static void
+assert_circuit_ok_mock(const circuit_t *c)
+{
+ (void) c;
+ return;
+}
+
+static void
+test_relay_close_circuit(void *arg)
+{
+ channel_t *nchan = NULL, *pchan = NULL;
+ or_circuit_t *orcirc = NULL;
+ cell_t *cell = NULL;
+ int old_count, new_count;
+
+ (void)arg;
+
+ /* Make fake channels to be nchan and pchan for the circuit */
+ nchan = new_fake_channel();
+ tt_assert(nchan);
+
+ pchan = new_fake_channel();
+ tt_assert(pchan);
+
+ /* Make a fake orcirc */
+ orcirc = new_fake_orcirc(nchan, pchan);
+ tt_assert(orcirc);
+ circuitmux_attach_circuit(nchan->cmux, TO_CIRCUIT(orcirc),
+ CELL_DIRECTION_OUT);
+ circuitmux_attach_circuit(pchan->cmux, TO_CIRCUIT(orcirc),
+ CELL_DIRECTION_IN);
+
+ /* Make a cell */
+ cell = tor_malloc_zero(sizeof(cell_t));
+ make_fake_cell(cell);
+
+ MOCK(scheduler_channel_has_waiting_cells,
+ scheduler_channel_has_waiting_cells_mock);
+ MOCK(assert_circuit_ok,
+ assert_circuit_ok_mock);
+
+ /* Append it */
+ old_count = get_mock_scheduler_has_waiting_cells_count();
+ append_cell_to_circuit_queue(TO_CIRCUIT(orcirc), nchan, cell,
+ CELL_DIRECTION_OUT, 0);
+ new_count = get_mock_scheduler_has_waiting_cells_count();
+ tt_int_op(new_count, OP_EQ, old_count + 1);
+
+ /* Now try the reverse direction */
+ old_count = get_mock_scheduler_has_waiting_cells_count();
+ append_cell_to_circuit_queue(TO_CIRCUIT(orcirc), pchan, cell,
+ CELL_DIRECTION_IN, 0);
+ new_count = get_mock_scheduler_has_waiting_cells_count();
+ tt_int_op(new_count, OP_EQ, old_count + 1);
+
+ /* Ensure our write totals are 0 */
+ tt_u64_op(find_largest_max(write_array), OP_EQ, 0);
+
+ /* Mark the circuit for close */
+ circuit_mark_for_close(TO_CIRCUIT(orcirc), 0);
+
+ /* Check our write totals. */
+ advance_obs(write_array);
+ commit_max(write_array);
+ /* Check for two cells plus overhead */
+ tt_u64_op(find_largest_max(write_array), OP_EQ,
+ 2*(get_cell_network_size(nchan->wide_circ_ids)
+ +TLS_PER_CELL_OVERHEAD));
+
+ UNMOCK(scheduler_channel_has_waiting_cells);
+
+ /* Get rid of the fake channels */
+ MOCK(scheduler_release_channel, scheduler_release_channel_mock);
+ channel_mark_for_close(nchan);
+ channel_mark_for_close(pchan);
+ UNMOCK(scheduler_release_channel);
+
+ /* Shut down channels */
+ channel_free_all();
+
+ done:
+ tor_free(cell);
+ if (orcirc) {
+ circuitmux_detach_circuit(nchan->cmux, TO_CIRCUIT(orcirc));
+ circuitmux_detach_circuit(pchan->cmux, TO_CIRCUIT(orcirc));
+ cell_queue_clear(&orcirc->base_.n_chan_cells);
+ cell_queue_clear(&orcirc->p_chan_cells);
+ }
+ tor_free(orcirc);
+ free_fake_channel(nchan);
+ free_fake_channel(pchan);
+ UNMOCK(assert_circuit_ok);
+
+ return;
+}
+
+static void
test_relay_append_cell_to_circuit_queue(void *arg)
{
channel_t *nchan = NULL, *pchan = NULL;
@@ -125,6 +228,7 @@ test_relay_append_cell_to_circuit_queue(void *arg)
struct testcase_t relay_tests[] = {
{ "append_cell_to_circuit_queue", test_relay_append_cell_to_circuit_queue,
TT_FORK, NULL, NULL },
+ { "close_circ_rephist", test_relay_close_circuit,
+ TT_FORK, NULL, NULL },
END_OF_TESTCASES
};
-
diff --git a/src/test/test_relaycell.c b/src/test/test_relaycell.c
index eea1f5dc80..3d3addfb9e 100644
--- a/src/test/test_relaycell.c
+++ b/src/test/test_relaycell.c
@@ -1,15 +1,35 @@
-/* Copyright (c) 2014-2017, The Tor Project, Inc. */
+/* Copyright (c) 2014-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
/* Unit tests for handling different kinds of relay cell */
#define RELAY_PRIVATE
-#include "or.h"
-#include "config.h"
-#include "connection.h"
-#include "connection_edge.h"
-#include "relay.h"
-#include "test.h"
+#define CIRCUITLIST_PRIVATE
+#define CONNECTION_EDGE_PRIVATE
+#define CONNECTION_PRIVATE
+
+#include "core/or/or.h"
+#include "core/mainloop/mainloop.h"
+#include "app/config/config.h"
+#include "core/mainloop/connection.h"
+#include "lib/crypt_ops/crypto_cipher.h"
+#include "lib/crypt_ops/crypto_rand.h"
+#include "core/or/circuitbuild.h"
+#include "core/or/circuitlist.h"
+#include "core/or/connection_edge.h"
+#include "core/or/relay.h"
+#include "test/test.h"
+#include "test/log_test_helpers.h"
+
+#include "core/or/cell_st.h"
+#include "core/or/crypt_path_st.h"
+#include "core/or/entry_connection_st.h"
+#include "core/or/origin_circuit_st.h"
+#include "core/or/socks_request_st.h"
+#include "core/or/half_edge_st.h"
+
+#include "feature/client/circpathbias.h"
+#include "core/or/connection_edge.h"
static int srm_ncalls;
static entry_connection_t *srm_conn;
@@ -60,6 +80,805 @@ mark_unattached_mock(entry_connection_t *conn, int endreason,
(void) file;
}
+/* Helper: Return a newly allocated and initialized origin circuit with
+ * purpose and flags. A default HS identifier is set to an ed25519
+ * authentication key for introduction point. */
+static origin_circuit_t *
+helper_create_origin_circuit(int purpose, int flags)
+{
+ origin_circuit_t *circ = NULL;
+
+ circ = origin_circuit_init(purpose, flags);
+ tor_assert(circ);
+ circ->cpath = tor_malloc_zero(sizeof(crypt_path_t));
+ circ->cpath->magic = CRYPT_PATH_MAGIC;
+ circ->cpath->state = CPATH_STATE_OPEN;
+ circ->cpath->package_window = circuit_initial_package_window();
+ circ->cpath->deliver_window = CIRCWINDOW_START;
+ circ->cpath->prev = circ->cpath;
+ /* Create a default HS identifier. */
+ circ->hs_ident = tor_malloc_zero(sizeof(hs_ident_circuit_t));
+
+ return circ;
+}
+
+static void
+mock_connection_mark_unattached_ap_(entry_connection_t *conn, int endreason,
+ int line, const char *file)
+{
+ (void) line;
+ (void) file;
+ conn->edge_.end_reason = endreason;
+}
+
+static void
+mock_mark_circ_for_close(circuit_t *circ, int reason, int line,
+ const char *file)
+{
+ (void)reason; (void)line; (void)file;
+
+ circ->marked_for_close = 1;
+ return;
+}
+
+static void
+mock_mark_for_close(connection_t *conn,
+ int line, const char *file)
+{
+ (void)line;
+ (void)file;
+
+ conn->marked_for_close = 1;
+ return;
+}
+
+static void
+mock_start_reading(connection_t *conn)
+{
+ (void)conn;
+ return;
+}
+
+static int
+mock_send_command(streamid_t stream_id, circuit_t *circ,
+ uint8_t relay_command, const char *payload,
+ size_t payload_len, crypt_path_t *cpath_layer,
+ const char *filename, int lineno)
+{
+ (void)stream_id; (void)circ;
+ (void)relay_command; (void)payload;
+ (void)payload_len; (void)cpath_layer;
+ (void)filename; (void)lineno;
+
+ return 0;
+}
+
+static entry_connection_t *
+fake_entry_conn(origin_circuit_t *oncirc, streamid_t id)
+{
+ edge_connection_t *edgeconn;
+ entry_connection_t *entryconn;
+
+ entryconn = entry_connection_new(CONN_TYPE_AP, AF_INET);
+ edgeconn = ENTRY_TO_EDGE_CONN(entryconn);
+ edgeconn->base_.state = AP_CONN_STATE_CONNECT_WAIT;
+ edgeconn->deliver_window = STREAMWINDOW_START;
+ edgeconn->package_window = STREAMWINDOW_START;
+
+ edgeconn->stream_id = id;
+ edgeconn->on_circuit = TO_CIRCUIT(oncirc);
+ edgeconn->cpath_layer = oncirc->cpath;
+
+ return entryconn;
+}
+
+#define PACK_CELL(id, cmd, body_s) do { \
+ memset(&cell, 0, sizeof(cell)); \
+ memset(&rh, 0, sizeof(rh)); \
+ memcpy(cell.payload+RELAY_HEADER_SIZE, (body_s), sizeof((body_s))-1); \
+ rh.length = sizeof((body_s))-1; \
+ rh.command = (cmd); \
+ rh.stream_id = (id); \
+ relay_header_pack((uint8_t*)&cell.payload, &rh); \
+ } while (0)
+#define ASSERT_COUNTED_BW() do { \
+ tt_int_op(circ->n_delivered_read_circ_bw, OP_EQ, delivered+rh.length); \
+ tt_int_op(circ->n_overhead_read_circ_bw, OP_EQ, \
+ overhead+RELAY_PAYLOAD_SIZE-rh.length); \
+ delivered = circ->n_delivered_read_circ_bw; \
+ overhead = circ->n_overhead_read_circ_bw; \
+ } while (0)
+#define ASSERT_UNCOUNTED_BW() do { \
+ tt_int_op(circ->n_delivered_read_circ_bw, OP_EQ, delivered); \
+ tt_int_op(circ->n_overhead_read_circ_bw, OP_EQ, overhead); \
+ } while (0)
+
+static int
+subtest_circbw_halfclosed(origin_circuit_t *circ, streamid_t init_id)
+{
+ cell_t cell;
+ relay_header_t rh;
+ edge_connection_t *edgeconn;
+ entry_connection_t *entryconn2=NULL;
+ entry_connection_t *entryconn3=NULL;
+ entry_connection_t *entryconn4=NULL;
+ int delivered = circ->n_delivered_read_circ_bw;
+ int overhead = circ->n_overhead_read_circ_bw;
+
+ /* Make new entryconns */
+ entryconn2 = fake_entry_conn(circ, init_id);
+ entryconn2->socks_request->has_finished = 1;
+ entryconn3 = fake_entry_conn(circ, init_id+1);
+ entryconn3->socks_request->has_finished = 1;
+ entryconn4 = fake_entry_conn(circ, init_id+2);
+ entryconn4->socks_request->has_finished = 1;
+ edgeconn = ENTRY_TO_EDGE_CONN(entryconn2);
+ edgeconn->package_window = 23;
+ edgeconn->base_.state = AP_CONN_STATE_OPEN;
+
+ int data_cells = edgeconn->deliver_window;
+ int sendme_cells = (STREAMWINDOW_START-edgeconn->package_window)
+ /STREAMWINDOW_INCREMENT;
+ ENTRY_TO_CONN(entryconn2)->marked_for_close = 0;
+ ENTRY_TO_CONN(entryconn2)->outbuf_flushlen = 0;
+ connection_edge_reached_eof(edgeconn);
+
+ /* Data cell not in the half-opened list */
+ PACK_CELL(4000, RELAY_COMMAND_DATA, "Data1234");
+ if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
+ pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
+ else
+ connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
+ circ->cpath);
+ ASSERT_UNCOUNTED_BW();
+
+ /* Sendme cell not in the half-opened list */
+ PACK_CELL(4000, RELAY_COMMAND_SENDME, "Data1234");
+ if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
+ pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
+ else
+ connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
+ circ->cpath);
+ ASSERT_UNCOUNTED_BW();
+
+ /* Connected cell not in the half-opened list */
+ PACK_CELL(4000, RELAY_COMMAND_CONNECTED, "Data1234");
+ if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
+ pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
+ else
+ connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
+ circ->cpath);
+ ASSERT_UNCOUNTED_BW();
+
+ /* Resolved cell not in the half-opened list */
+ PACK_CELL(4000, RELAY_COMMAND_RESOLVED, "Data1234");
+ if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
+ pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
+ else
+ connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
+ circ->cpath);
+ ASSERT_UNCOUNTED_BW();
+
+ /* Connected cell: not counted -- we were open */
+ edgeconn = ENTRY_TO_EDGE_CONN(entryconn2);
+ PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_CONNECTED, "Data1234");
+ if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
+ pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
+ else
+ connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
+ circ->cpath);
+ ASSERT_UNCOUNTED_BW();
+
+ /* DATA cells up to limit */
+ while (data_cells > 0) {
+ ENTRY_TO_CONN(entryconn2)->marked_for_close = 0;
+ ENTRY_TO_CONN(entryconn2)->outbuf_flushlen = 0;
+ PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_DATA, "Data1234");
+ if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
+ pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
+ else
+ connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
+ circ->cpath);
+ ASSERT_COUNTED_BW();
+ data_cells--;
+ }
+ ENTRY_TO_CONN(entryconn2)->marked_for_close = 0;
+ ENTRY_TO_CONN(entryconn2)->outbuf_flushlen = 0;
+ PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_DATA, "Data1234");
+ if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
+ pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
+ else
+ connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
+ circ->cpath);
+ ASSERT_UNCOUNTED_BW();
+
+ /* SENDME cells up to limit */
+ while (sendme_cells > 0) {
+ ENTRY_TO_CONN(entryconn2)->marked_for_close = 0;
+ ENTRY_TO_CONN(entryconn2)->outbuf_flushlen = 0;
+ PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_SENDME, "Data1234");
+ if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
+ pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
+ else
+ connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
+ circ->cpath);
+ ASSERT_COUNTED_BW();
+ sendme_cells--;
+ }
+ ENTRY_TO_CONN(entryconn2)->marked_for_close = 0;
+ ENTRY_TO_CONN(entryconn2)->outbuf_flushlen = 0;
+ PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_SENDME, "Data1234");
+ if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
+ pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
+ else
+ connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
+ circ->cpath);
+ ASSERT_UNCOUNTED_BW();
+
+ /* Only one END cell */
+ ENTRY_TO_CONN(entryconn2)->marked_for_close = 0;
+ ENTRY_TO_CONN(entryconn2)->outbuf_flushlen = 0;
+ PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_END, "Data1234");
+ if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
+ pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
+ else
+ connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
+ circ->cpath);
+ ASSERT_COUNTED_BW();
+
+ ENTRY_TO_CONN(entryconn2)->marked_for_close = 0;
+ ENTRY_TO_CONN(entryconn2)->outbuf_flushlen = 0;
+ PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_END, "Data1234");
+ if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
+ pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
+ else
+ connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
+ circ->cpath);
+ ASSERT_UNCOUNTED_BW();
+
+ edgeconn = ENTRY_TO_EDGE_CONN(entryconn3);
+ edgeconn->base_.state = AP_CONN_STATE_OPEN;
+ ENTRY_TO_CONN(entryconn3)->marked_for_close = 0;
+ ENTRY_TO_CONN(entryconn3)->outbuf_flushlen = 0;
+ /* sendme cell on open entryconn with full window */
+ PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_SENDME, "Data1234");
+ int ret =
+ connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn,
+ circ->cpath);
+ tt_int_op(ret, OP_EQ, -END_CIRC_REASON_TORPROTOCOL);
+ ASSERT_UNCOUNTED_BW();
+
+ /* connected cell on a after EOF */
+ ENTRY_TO_CONN(entryconn3)->marked_for_close = 0;
+ ENTRY_TO_CONN(entryconn3)->outbuf_flushlen = 0;
+ edgeconn->base_.state = AP_CONN_STATE_CONNECT_WAIT;
+ connection_edge_reached_eof(edgeconn);
+ PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_CONNECTED, "Data1234");
+ if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
+ pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
+ else
+ connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
+ circ->cpath);
+ ASSERT_COUNTED_BW();
+
+ ENTRY_TO_CONN(entryconn3)->marked_for_close = 0;
+ ENTRY_TO_CONN(entryconn3)->outbuf_flushlen = 0;
+ PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_CONNECTED, "Data1234");
+ if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
+ pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
+ else
+ connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
+ circ->cpath);
+ ASSERT_UNCOUNTED_BW();
+
+ /* DATA and SENDME after END cell */
+ ENTRY_TO_CONN(entryconn3)->marked_for_close = 0;
+ ENTRY_TO_CONN(entryconn3)->outbuf_flushlen = 0;
+ PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_END, "Data1234");
+ if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
+ pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
+ else
+ connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
+ circ->cpath);
+ ASSERT_COUNTED_BW();
+
+ ENTRY_TO_CONN(entryconn3)->marked_for_close = 0;
+ ENTRY_TO_CONN(entryconn3)->outbuf_flushlen = 0;
+ PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_SENDME, "Data1234");
+ ret =
+ connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
+ circ->cpath);
+ tt_int_op(ret, OP_NE, -END_CIRC_REASON_TORPROTOCOL);
+ ASSERT_UNCOUNTED_BW();
+
+ ENTRY_TO_CONN(entryconn3)->marked_for_close = 0;
+ ENTRY_TO_CONN(entryconn3)->outbuf_flushlen = 0;
+ PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_DATA, "Data1234");
+ if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
+ pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
+ else
+ connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
+ circ->cpath);
+ ASSERT_UNCOUNTED_BW();
+
+ /* Resolved: 1 counted, more not */
+ edgeconn = ENTRY_TO_EDGE_CONN(entryconn4);
+ entryconn4->socks_request->command = SOCKS_COMMAND_RESOLVE;
+ edgeconn->base_.state = AP_CONN_STATE_RESOLVE_WAIT;
+ edgeconn->on_circuit = TO_CIRCUIT(circ);
+ ENTRY_TO_CONN(entryconn4)->marked_for_close = 0;
+ ENTRY_TO_CONN(entryconn4)->outbuf_flushlen = 0;
+ connection_edge_reached_eof(edgeconn);
+
+ ENTRY_TO_CONN(entryconn4)->marked_for_close = 0;
+ ENTRY_TO_CONN(entryconn4)->outbuf_flushlen = 0;
+ PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_RESOLVED,
+ "\x04\x04\x12\x00\x00\x01\x00\x00\x02\x00");
+ if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
+ pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
+ else
+ connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
+ circ->cpath);
+ ASSERT_COUNTED_BW();
+
+ ENTRY_TO_CONN(entryconn4)->marked_for_close = 0;
+ ENTRY_TO_CONN(entryconn4)->outbuf_flushlen = 0;
+ PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_RESOLVED,
+ "\x04\x04\x12\x00\x00\x01\x00\x00\x02\x00");
+ connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
+ circ->cpath);
+ ASSERT_UNCOUNTED_BW();
+
+ /* Data not counted after resolved */
+ ENTRY_TO_CONN(entryconn4)->marked_for_close = 0;
+ ENTRY_TO_CONN(entryconn4)->outbuf_flushlen = 0;
+ PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_DATA, "Data1234");
+ if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
+ pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
+ else
+ connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
+ circ->cpath);
+ ASSERT_UNCOUNTED_BW();
+
+ /* End not counted after resolved */
+ ENTRY_TO_CONN(entryconn4)->marked_for_close = 0;
+ ENTRY_TO_CONN(entryconn4)->outbuf_flushlen = 0;
+ PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_END, "Data1234");
+ if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
+ pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
+ else
+ connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
+ circ->cpath);
+ ASSERT_UNCOUNTED_BW();
+
+ connection_free_minimal(ENTRY_TO_CONN(entryconn2));
+ connection_free_minimal(ENTRY_TO_CONN(entryconn3));
+ connection_free_minimal(ENTRY_TO_CONN(entryconn4));
+ return 1;
+ done:
+ connection_free_minimal(ENTRY_TO_CONN(entryconn2));
+ connection_free_minimal(ENTRY_TO_CONN(entryconn3));
+ connection_free_minimal(ENTRY_TO_CONN(entryconn4));
+ return 0;
+}
+
+static int
+halfstream_insert(origin_circuit_t *circ, edge_connection_t *edgeconn,
+ streamid_t *streams, int num, int random)
+{
+ int inserted = 0;
+
+ /* Insert num random elements */
+ while (inserted < num) {
+ streamid_t id;
+
+ if (random)
+ id = (streamid_t)crypto_rand_int(65535)+1;
+ else
+ id = get_unique_stream_id_by_circ(circ);
+
+ edgeconn->stream_id = id;
+
+ /* Ensure it isn't there */
+ if (connection_half_edge_find_stream_id(circ->half_streams, id)) {
+ continue;
+ }
+
+ connection_half_edge_add(edgeconn, circ);
+ if (streams)
+ streams[inserted] = id;
+ inserted++;
+ }
+
+ return inserted;
+}
+
+static void
+subtest_halfstream_insertremove(int num)
+{
+ origin_circuit_t *circ =
+ helper_create_origin_circuit(CIRCUIT_PURPOSE_C_GENERAL, 0);
+ edge_connection_t *edgeconn;
+ entry_connection_t *entryconn;
+ streamid_t *streams = tor_malloc_zero(num*sizeof(streamid_t));
+ int i = 0;
+
+ circ->cpath->state = CPATH_STATE_AWAITING_KEYS;
+ circ->cpath->deliver_window = CIRCWINDOW_START;
+
+ entryconn = fake_entry_conn(circ, 23);
+ edgeconn = ENTRY_TO_EDGE_CONN(entryconn);
+
+ /* Explicity test all operations on an absent stream list */
+ tt_int_op(connection_half_edge_is_valid_data(circ->half_streams,
+ 23), OP_EQ, 0);
+ tt_int_op(connection_half_edge_is_valid_connected(circ->half_streams,
+ 23), OP_EQ, 0);
+ tt_int_op(connection_half_edge_is_valid_sendme(circ->half_streams,
+ 23), OP_EQ, 0);
+ tt_int_op(connection_half_edge_is_valid_resolved(circ->half_streams,
+ 23), OP_EQ, 0);
+ tt_int_op(connection_half_edge_is_valid_end(circ->half_streams,
+ 23), OP_EQ, 0);
+
+ /* Insert a duplicate element; verify that other elements absent;
+ * ensure removing it once works */
+ edgeconn->stream_id = 23;
+ connection_half_edge_add(edgeconn, circ);
+ connection_half_edge_add(edgeconn, circ);
+ connection_half_edge_add(edgeconn, circ);
+
+ /* Verify that other elements absent */
+ tt_int_op(connection_half_edge_is_valid_data(circ->half_streams,
+ 22), OP_EQ, 0);
+ tt_int_op(connection_half_edge_is_valid_connected(circ->half_streams,
+ 22), OP_EQ, 0);
+ tt_int_op(connection_half_edge_is_valid_sendme(circ->half_streams,
+ 22), OP_EQ, 0);
+ tt_int_op(connection_half_edge_is_valid_resolved(circ->half_streams,
+ 22), OP_EQ, 0);
+ tt_int_op(connection_half_edge_is_valid_end(circ->half_streams,
+ 22), OP_EQ, 0);
+
+ tt_int_op(connection_half_edge_is_valid_data(circ->half_streams,
+ 24), OP_EQ, 0);
+ tt_int_op(connection_half_edge_is_valid_connected(circ->half_streams,
+ 24), OP_EQ, 0);
+ tt_int_op(connection_half_edge_is_valid_sendme(circ->half_streams,
+ 24), OP_EQ, 0);
+ tt_int_op(connection_half_edge_is_valid_resolved(circ->half_streams,
+ 24), OP_EQ, 0);
+ tt_int_op(connection_half_edge_is_valid_end(circ->half_streams,
+ 24), OP_EQ, 0);
+
+ /* Verify we only remove it once */
+ tt_int_op(connection_half_edge_is_valid_end(circ->half_streams,
+ 23), OP_EQ, 1);
+ tt_int_op(connection_half_edge_is_valid_end(circ->half_streams,
+ 23), OP_EQ, 0);
+
+ halfstream_insert(circ, edgeconn, streams, num, 1);
+
+ /* Remove half of them */
+ for (i = 0; i < num/2; i++) {
+ tt_int_op(connection_half_edge_is_valid_end(circ->half_streams,
+ streams[i]),
+ OP_EQ, 1);
+ }
+
+ /* Verify first half of list is gone */
+ for (i = 0; i < num/2; i++) {
+ tt_ptr_op(connection_half_edge_find_stream_id(circ->half_streams,
+ streams[i]),
+ OP_EQ, NULL);
+ }
+
+ /* Verify second half of list is present */
+ for (; i < num; i++) {
+ tt_ptr_op(connection_half_edge_find_stream_id(circ->half_streams,
+ streams[i]),
+ OP_NE, NULL);
+ }
+
+ /* Remove other half. Verify list is empty. */
+ for (i = num/2; i < num; i++) {
+ tt_int_op(connection_half_edge_is_valid_end(circ->half_streams,
+ streams[i]),
+ OP_EQ, 1);
+ }
+ tt_int_op(smartlist_len(circ->half_streams), OP_EQ, 0);
+
+ /* Explicity test all operations on an empty stream list */
+ tt_int_op(connection_half_edge_is_valid_data(circ->half_streams,
+ 23), OP_EQ, 0);
+ tt_int_op(connection_half_edge_is_valid_connected(circ->half_streams,
+ 23), OP_EQ, 0);
+ tt_int_op(connection_half_edge_is_valid_sendme(circ->half_streams,
+ 23), OP_EQ, 0);
+ tt_int_op(connection_half_edge_is_valid_resolved(circ->half_streams,
+ 23), OP_EQ, 0);
+ tt_int_op(connection_half_edge_is_valid_end(circ->half_streams,
+ 23), OP_EQ, 0);
+
+ /* For valgrind, leave some around then free the circ */
+ halfstream_insert(circ, edgeconn, NULL, 10, 0);
+
+ done:
+ tor_free(streams);
+ circuit_free_(TO_CIRCUIT(circ));
+ connection_free_minimal(ENTRY_TO_CONN(entryconn));
+}
+
+static void
+test_halfstream_insertremove(void *arg)
+{
+ (void)arg;
+
+ /* Suppress the WARN message we generate in this test */
+ setup_full_capture_of_logs(LOG_WARN);
+
+ /* Test insertion and removal with a few different sizes */
+ subtest_halfstream_insertremove(10);
+ subtest_halfstream_insertremove(100);
+ subtest_halfstream_insertremove(1000);
+}
+
+static void
+test_halfstream_wrap(void *arg)
+{
+ origin_circuit_t *circ =
+ helper_create_origin_circuit(CIRCUIT_PURPOSE_C_GENERAL, 0);
+ edge_connection_t *edgeconn;
+ entry_connection_t *entryconn;
+
+ circ->cpath->state = CPATH_STATE_AWAITING_KEYS;
+ circ->cpath->deliver_window = CIRCWINDOW_START;
+
+ entryconn = fake_entry_conn(circ, 23);
+ edgeconn = ENTRY_TO_EDGE_CONN(entryconn);
+
+ (void)arg;
+
+ /* Suppress the WARN message we generate in this test */
+ setup_full_capture_of_logs(LOG_WARN);
+ MOCK(connection_mark_for_close_internal_, mock_mark_for_close);
+
+ /* Verify that get_unique_stream_id_by_circ() can wrap uint16_t */
+ circ->next_stream_id = 65530;
+ halfstream_insert(circ, edgeconn, NULL, 7, 0);
+ tt_int_op(circ->next_stream_id, OP_EQ, 2);
+ tt_int_op(smartlist_len(circ->half_streams), OP_EQ, 7);
+
+ /* Insert full-1 */
+ halfstream_insert(circ, edgeconn, NULL,
+ 65534-smartlist_len(circ->half_streams), 0);
+ tt_int_op(smartlist_len(circ->half_streams), OP_EQ, 65534);
+
+ /* Verify that we can get_unique_stream_id_by_circ() successfully */
+ edgeconn->stream_id = get_unique_stream_id_by_circ(circ);
+ tt_int_op(edgeconn->stream_id, OP_NE, 0); /* 0 is failure */
+
+ /* Insert an opened stream on the circ with that id */
+ ENTRY_TO_CONN(entryconn)->marked_for_close = 0;
+ ENTRY_TO_CONN(entryconn)->outbuf_flushlen = 0;
+ edgeconn->base_.state = AP_CONN_STATE_CONNECT_WAIT;
+ circ->p_streams = edgeconn;
+
+ /* Verify that get_unique_stream_id_by_circ() fails */
+ tt_int_op(get_unique_stream_id_by_circ(circ), OP_EQ, 0); /* 0 is failure */
+
+ /* eof the one opened stream. Verify it is now in half-closed */
+ tt_int_op(smartlist_len(circ->half_streams), OP_EQ, 65534);
+ connection_edge_reached_eof(edgeconn);
+ tt_int_op(smartlist_len(circ->half_streams), OP_EQ, 65535);
+
+ /* Verify get_unique_stream_id_by_circ() fails due to full half-closed */
+ circ->p_streams = NULL;
+ tt_int_op(get_unique_stream_id_by_circ(circ), OP_EQ, 0); /* 0 is failure */
+
+ done:
+ circuit_free_(TO_CIRCUIT(circ));
+ connection_free_minimal(ENTRY_TO_CONN(entryconn));
+ UNMOCK(connection_mark_for_close_internal_);
+}
+
+static void
+test_circbw_relay(void *arg)
+{
+ cell_t cell;
+ relay_header_t rh;
+ tor_addr_t addr;
+ edge_connection_t *edgeconn;
+ entry_connection_t *entryconn1=NULL;
+ origin_circuit_t *circ;
+ int delivered = 0;
+ int overhead = 0;
+
+ (void)arg;
+
+ MOCK(connection_mark_unattached_ap_, mock_connection_mark_unattached_ap_);
+ MOCK(connection_start_reading, mock_start_reading);
+ MOCK(connection_mark_for_close_internal_, mock_mark_for_close);
+ MOCK(relay_send_command_from_edge_, mock_send_command);
+ MOCK(circuit_mark_for_close_, mock_mark_circ_for_close);
+
+ circ = helper_create_origin_circuit(CIRCUIT_PURPOSE_C_GENERAL, 0);
+ circ->cpath->state = CPATH_STATE_AWAITING_KEYS;
+ circ->cpath->deliver_window = CIRCWINDOW_START;
+
+ entryconn1 = fake_entry_conn(circ, 1);
+ edgeconn = ENTRY_TO_EDGE_CONN(entryconn1);
+
+ /* Stream id 0: Not counted */
+ PACK_CELL(0, RELAY_COMMAND_END, "Data1234");
+ connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn,
+ circ->cpath);
+ ASSERT_UNCOUNTED_BW();
+
+ /* Stream id 1: Counted */
+ PACK_CELL(1, RELAY_COMMAND_END, "Data1234");
+ connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn,
+ circ->cpath);
+ ASSERT_COUNTED_BW();
+
+ /* Properly formatted connect cell: counted */
+ PACK_CELL(1, RELAY_COMMAND_CONNECTED, "Data1234");
+ tor_addr_parse(&addr, "30.40.50.60");
+ rh.length = connected_cell_format_payload(cell.payload+RELAY_HEADER_SIZE,
+ &addr, 1024);
+ relay_header_pack((uint8_t*)&cell.payload, &rh); \
+ connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn,
+ circ->cpath);
+ ASSERT_COUNTED_BW();
+
+ /* Properly formatted resolved cell in correct state: counted */
+ edgeconn->base_.state = AP_CONN_STATE_RESOLVE_WAIT;
+ entryconn1->socks_request->command = SOCKS_COMMAND_RESOLVE;
+ edgeconn->on_circuit = TO_CIRCUIT(circ);
+ PACK_CELL(1, RELAY_COMMAND_RESOLVED,
+ "\x04\x04\x12\x00\x00\x01\x00\x00\x02\x00");
+ connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn,
+ circ->cpath);
+ ASSERT_COUNTED_BW();
+
+ edgeconn->base_.state = AP_CONN_STATE_OPEN;
+ entryconn1->socks_request->has_finished = 1;
+
+ /* Connected cell after open: not counted */
+ PACK_CELL(1, RELAY_COMMAND_CONNECTED, "Data1234");
+ connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn,
+ circ->cpath);
+ ASSERT_UNCOUNTED_BW();
+
+ /* Resolved cell after open: not counted */
+ PACK_CELL(1, RELAY_COMMAND_RESOLVED, "Data1234");
+ connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn,
+ circ->cpath);
+ ASSERT_UNCOUNTED_BW();
+
+ /* Drop cell: not counted */
+ PACK_CELL(1, RELAY_COMMAND_DROP, "Data1234");
+ connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn,
+ circ->cpath);
+ ASSERT_UNCOUNTED_BW();
+
+ /* Data cell on stream 0: not counted */
+ PACK_CELL(0, RELAY_COMMAND_DATA, "Data1234");
+ connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn,
+ circ->cpath);
+ ASSERT_UNCOUNTED_BW();
+
+ /* Data cell on open connection: counted */
+ ENTRY_TO_CONN(entryconn1)->marked_for_close = 0;
+ PACK_CELL(1, RELAY_COMMAND_DATA, "Data1234");
+ connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn,
+ circ->cpath);
+ ASSERT_COUNTED_BW();
+
+ /* Empty Data cell on open connection: not counted */
+ ENTRY_TO_CONN(entryconn1)->marked_for_close = 0;
+ PACK_CELL(1, RELAY_COMMAND_DATA, "");
+ connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn,
+ circ->cpath);
+ ASSERT_UNCOUNTED_BW();
+
+ /* Sendme on valid stream: counted */
+ edgeconn->package_window -= STREAMWINDOW_INCREMENT;
+ ENTRY_TO_CONN(entryconn1)->outbuf_flushlen = 0;
+ PACK_CELL(1, RELAY_COMMAND_SENDME, "Data1234");
+ connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn,
+ circ->cpath);
+ ASSERT_COUNTED_BW();
+
+ /* Sendme on valid stream with full window: not counted */
+ ENTRY_TO_CONN(entryconn1)->outbuf_flushlen = 0;
+ PACK_CELL(1, RELAY_COMMAND_SENDME, "Data1234");
+ edgeconn->package_window = STREAMWINDOW_START;
+ connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn,
+ circ->cpath);
+ ASSERT_UNCOUNTED_BW();
+
+ /* Sendme on unknown stream: not counted */
+ ENTRY_TO_CONN(entryconn1)->outbuf_flushlen = 0;
+ PACK_CELL(1, RELAY_COMMAND_SENDME, "Data1234");
+ connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
+ circ->cpath);
+ ASSERT_UNCOUNTED_BW();
+
+ /* Sendme on circuit with full window: not counted */
+ PACK_CELL(0, RELAY_COMMAND_SENDME, "Data1234");
+ connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn,
+ circ->cpath);
+ ASSERT_UNCOUNTED_BW();
+
+ /* Sendme on circuit with non-full window: counted */
+ PACK_CELL(0, RELAY_COMMAND_SENDME, "Data1234");
+ circ->cpath->package_window = 900;
+ connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn,
+ circ->cpath);
+ ASSERT_COUNTED_BW();
+
+ /* Invalid extended cell: not counted */
+ PACK_CELL(1, RELAY_COMMAND_EXTENDED2, "Data1234");
+ connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
+ circ->cpath);
+ ASSERT_UNCOUNTED_BW();
+
+ /* Invalid extended cell: not counted */
+ PACK_CELL(1, RELAY_COMMAND_EXTENDED, "Data1234");
+ connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
+ circ->cpath);
+ ASSERT_UNCOUNTED_BW();
+
+ /* Invalid HS cell: not counted */
+ PACK_CELL(1, RELAY_COMMAND_ESTABLISH_INTRO, "Data1234");
+ connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
+ circ->cpath);
+ ASSERT_UNCOUNTED_BW();
+
+ /* "Valid" HS cell in expected state: counted */
+ TO_CIRCUIT(circ)->purpose = CIRCUIT_PURPOSE_C_ESTABLISH_REND;
+ PACK_CELL(1, RELAY_COMMAND_RENDEZVOUS_ESTABLISHED, "Data1234");
+ connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
+ circ->cpath);
+ ASSERT_COUNTED_BW();
+
+ /* End cell on non-closed connection: counted */
+ PACK_CELL(1, RELAY_COMMAND_END, "Data1234");
+ connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn,
+ circ->cpath);
+ ASSERT_COUNTED_BW();
+
+ /* End cell on connection that already got one: not counted */
+ PACK_CELL(1, RELAY_COMMAND_END, "Data1234");
+ connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
+ circ->cpath);
+ ASSERT_UNCOUNTED_BW();
+
+ /* Simulate closed stream on entryconn, then test: */
+ if (!subtest_circbw_halfclosed(circ, 2))
+ goto done;
+
+ circ->base_.purpose = CIRCUIT_PURPOSE_PATH_BIAS_TESTING;
+ if (!subtest_circbw_halfclosed(circ, 6))
+ goto done;
+
+ /* Path bias: truncated */
+ tt_int_op(circ->base_.marked_for_close, OP_EQ, 0);
+ PACK_CELL(0, RELAY_COMMAND_TRUNCATED, "Data1234");
+ pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
+ tt_int_op(circ->base_.marked_for_close, OP_EQ, 1);
+
+ done:
+ UNMOCK(connection_start_reading);
+ UNMOCK(connection_mark_unattached_ap_);
+ UNMOCK(connection_mark_for_close_internal_);
+ UNMOCK(relay_send_command_from_edge_);
+ UNMOCK(circuit_mark_for_close_);
+ circuit_free_(TO_CIRCUIT(circ));
+ connection_free_minimal(ENTRY_TO_CONN(entryconn1));
+}
+
/* Tests for connection_edge_process_resolved_cell().
The point of ..process_resolved_cell() is to handle an incoming cell
@@ -244,6 +1063,8 @@ test_relaycell_resolved(void *arg)
struct testcase_t relaycell_tests[] = {
{ "resolved", test_relaycell_resolved, TT_FORK, NULL, NULL },
+ { "circbw", test_circbw_relay, TT_FORK, NULL, NULL },
+ { "halfstream", test_halfstream_insertremove, TT_FORK, NULL, NULL },
+ { "streamwrap", test_halfstream_wrap, TT_FORK, NULL, NULL },
END_OF_TESTCASES
};
-
diff --git a/src/test/test_relaycrypt.c b/src/test/test_relaycrypt.c
new file mode 100644
index 0000000000..c3cfb7d10b
--- /dev/null
+++ b/src/test/test_relaycrypt.c
@@ -0,0 +1,190 @@
+/* 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 "core/or/or.h"
+#include "core/or/circuitbuild.h"
+#define CIRCUITLIST_PRIVATE
+#include "core/or/circuitlist.h"
+#include "lib/crypt_ops/crypto_rand.h"
+#include "core/or/relay.h"
+#include "core/crypto/relay_crypto.h"
+
+#include "core/or/cell_st.h"
+#include "core/or/or_circuit_st.h"
+#include "core/or/origin_circuit_st.h"
+
+#include "test/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
+};
+
diff --git a/src/test/test_rendcache.c b/src/test/test_rendcache.c
index 9f6cfc4a22..394e28d785 100644
--- a/src/test/test_rendcache.c
+++ b/src/test/test_rendcache.c
@@ -1,18 +1,25 @@
-/* Copyright (c) 2010-2017, The Tor Project, Inc. */
+/* Copyright (c) 2010-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
#include "orconfig.h"
-#include "or.h"
+#include "core/or/or.h"
-#include "test.h"
+#include "test/test.h"
#define RENDCACHE_PRIVATE
-#include "rendcache.h"
-#include "router.h"
-#include "routerlist.h"
-#include "config.h"
-#include "hs_common.h"
-#include "rend_test_helpers.h"
-#include "log_test_helpers.h"
+#include "feature/rend/rendcache.h"
+#include "feature/relay/router.h"
+#include "feature/nodelist/routerlist.h"
+#include "app/config/config.h"
+#include "feature/hs/hs_common.h"
+
+#include "core/or/extend_info_st.h"
+#include "feature/rend/rend_encoded_v2_service_descriptor_st.h"
+#include "feature/rend/rend_intro_point_st.h"
+#include "feature/rend/rend_service_descriptor_st.h"
+#include "feature/nodelist/routerinfo_st.h"
+
+#include "test/rend_test_helpers.h"
+#include "test/log_test_helpers.h"
#define NS_MODULE rend_cache
diff --git a/src/test/test_replay.c b/src/test/test_replay.c
index d8dcc7370c..bca3a6660a 100644
--- a/src/test/test_replay.c
+++ b/src/test/test_replay.c
@@ -1,12 +1,12 @@
-/* Copyright (c) 2012-2017, The Tor Project, Inc. */
+/* Copyright (c) 2012-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
#define REPLAYCACHE_PRIVATE
#include "orconfig.h"
-#include "or.h"
-#include "replaycache.h"
-#include "test.h"
+#include "core/or/or.h"
+#include "feature/hs_common/replaycache.h"
+#include "test/test.h"
static const char *test_buffer =
"Lorem ipsum dolor sit amet, consectetur adipisici elit, sed do eiusmod"
diff --git a/src/test/test_router.c b/src/test/test_router.c
index 4e96e24534..921ec42904 100644
--- a/src/test/test_router.c
+++ b/src/test/test_router.c
@@ -1,21 +1,26 @@
-/* Copyright (c) 2017, The Tor Project, Inc. */
+/* Copyright (c) 2017-2018, The Tor Project, Inc. */
/* Copyright (c) 2017, isis agora lovecruft */
/* See LICENSE for licensing information */
/**
* \file test_router.c
- * \brief Unittests for code in src/or/router.c
+ * \brief Unittests for code in router.c
**/
-#include "or.h"
-#include "config.h"
-#include "crypto_curve25519.h"
-#include "crypto_ed25519.h"
-#include "router.h"
-#include "routerlist.h"
+#include "core/or/or.h"
+#include "app/config/config.h"
+#include "core/mainloop/mainloop.h"
+#include "feature/hibernate/hibernate.h"
+#include "feature/nodelist/routerinfo_st.h"
+#include "feature/nodelist/routerlist.h"
+#include "feature/relay/router.h"
+#include "feature/stats/rephist.h"
+#include "lib/crypt_ops/crypto_curve25519.h"
+#include "lib/crypt_ops/crypto_ed25519.h"
/* Test suite stuff */
-#include "test.h"
+#include "test/test.h"
+#include "test/log_test_helpers.h"
NS_DECL(const routerinfo_t *, router_get_my_routerinfo, (void));
@@ -47,9 +52,12 @@ NS(router_get_my_routerinfo)(void)
mock_routerinfo->platform = tor_strdup("unittest");
mock_routerinfo->cache_info.published_on = now;
mock_routerinfo->identity_pkey = crypto_pk_dup_key(ident_key);
- mock_routerinfo->onion_pkey = crypto_pk_dup_key(tap_key);
+ router_set_rsa_onion_pkey(tap_key, &mock_routerinfo->onion_pkey,
+ &mock_routerinfo->onion_pkey_len);
mock_routerinfo->bandwidthrate = 9001;
mock_routerinfo->bandwidthburst = 9002;
+ crypto_pk_free(ident_key);
+ crypto_pk_free(tap_key);
}
return mock_routerinfo;
@@ -87,11 +95,14 @@ test_router_dump_router_to_string_no_bridge_distribution_method(void *arg)
/* Generate our server descriptor and ensure that the substring
* "bridge-distribution-request any" occurs somewhere within it. */
+ crypto_pk_t *onion_pkey = router_get_rsa_onion_pkey(router->onion_pkey,
+ router->onion_pkey_len);
desc = router_dump_router_to_string(router,
router->identity_pkey,
- router->onion_pkey,
+ onion_pkey,
&ntor_keypair,
&signing_keypair);
+ crypto_pk_free(onion_pkey);
tt_ptr_op(desc, !=, NULL);
found = strstr(desc, needle);
tt_ptr_op(found, !=, NULL);
@@ -102,11 +113,129 @@ test_router_dump_router_to_string_no_bridge_distribution_method(void *arg)
tor_free(desc);
}
+static routerinfo_t *mock_router_get_my_routerinfo_result = NULL;
+
+static const routerinfo_t *
+mock_router_get_my_routerinfo(void)
+{
+ return mock_router_get_my_routerinfo_result;
+}
+
+static long
+mock_get_uptime_3h(void)
+{
+ return 3*60*60;
+}
+
+static long
+mock_get_uptime_1d(void)
+{
+ return 24*60*60;
+}
+
+static int
+mock_rep_hist_bandwidth_assess(void)
+{
+ return 20001;
+}
+
+static int
+mock_we_are_not_hibernating(void)
+{
+ return 0;
+}
+
+static int
+mock_we_are_hibernating(void)
+{
+ return 0;
+}
+
+static void
+test_router_check_descriptor_bandwidth_changed(void *arg)
+{
+ (void)arg;
+ routerinfo_t routerinfo;
+ memset(&routerinfo, 0, sizeof(routerinfo));
+ mock_router_get_my_routerinfo_result = NULL;
+
+ MOCK(we_are_hibernating, mock_we_are_not_hibernating);
+ MOCK(router_get_my_routerinfo, mock_router_get_my_routerinfo);
+ mock_router_get_my_routerinfo_result = &routerinfo;
+
+ /* When uptime is less than 24h, no previous bandwidth, no last_changed
+ * Uptime: 10800, last_changed: 0, Previous bw: 0, Current bw: 0 */
+ routerinfo.bandwidthcapacity = 0;
+ MOCK(get_uptime, mock_get_uptime_3h);
+ setup_full_capture_of_logs(LOG_INFO);
+ check_descriptor_bandwidth_changed(time(NULL));
+ expect_log_msg_not_containing(
+ "Measured bandwidth has changed; rebuilding descriptor.");
+ teardown_capture_of_logs();
+
+ /* When uptime is less than 24h, previous bandwidth,
+ * last_changed more than 3h ago
+ * Uptime: 10800, last_changed: 0, Previous bw: 10000, Current bw: 0 */
+ routerinfo.bandwidthcapacity = 10000;
+ setup_full_capture_of_logs(LOG_INFO);
+ check_descriptor_bandwidth_changed(time(NULL));
+ expect_log_msg_containing(
+ "Measured bandwidth has changed; rebuilding descriptor.");
+ teardown_capture_of_logs();
+
+ /* When uptime is less than 24h, previous bandwidth,
+ * last_changed more than 3h ago, and hibernating
+ * Uptime: 10800, last_changed: 0, Previous bw: 10000, Current bw: 0 */
+
+ UNMOCK(we_are_hibernating);
+ MOCK(we_are_hibernating, mock_we_are_hibernating);
+ routerinfo.bandwidthcapacity = 10000;
+ setup_full_capture_of_logs(LOG_INFO);
+ check_descriptor_bandwidth_changed(time(NULL));
+ expect_log_msg_not_containing(
+ "Measured bandwidth has changed; rebuilding descriptor.");
+ teardown_capture_of_logs();
+ UNMOCK(we_are_hibernating);
+ MOCK(we_are_hibernating, mock_we_are_not_hibernating);
+
+ /* When uptime is less than 24h, last_changed is not more than 3h ago
+ * Uptime: 10800, last_changed: x, Previous bw: 10000, Current bw: 0 */
+ setup_full_capture_of_logs(LOG_INFO);
+ check_descriptor_bandwidth_changed(time(NULL));
+ expect_log_msg_not_containing(
+ "Measured bandwidth has changed; rebuilding descriptor.");
+ teardown_capture_of_logs();
+
+ /* When uptime is less than 24h and bandwidthcapacity does not change
+ * Uptime: 10800, last_changed: x, Previous bw: 10000, Current bw: 20001 */
+ MOCK(rep_hist_bandwidth_assess, mock_rep_hist_bandwidth_assess);
+ setup_full_capture_of_logs(LOG_INFO);
+ check_descriptor_bandwidth_changed(time(NULL) + 6*60*60 + 1);
+ expect_log_msg_containing(
+ "Measured bandwidth has changed; rebuilding descriptor.");
+ UNMOCK(get_uptime);
+ UNMOCK(rep_hist_bandwidth_assess);
+ teardown_capture_of_logs();
+
+ /* When uptime is more than 24h */
+ MOCK(get_uptime, mock_get_uptime_1d);
+ setup_full_capture_of_logs(LOG_INFO);
+ check_descriptor_bandwidth_changed(time(NULL));
+ expect_log_msg_not_containing(
+ "Measured bandwidth has changed; rebuilding descriptor.");
+ teardown_capture_of_logs();
+
+ done:
+ UNMOCK(get_uptime);
+ UNMOCK(router_get_my_routerinfo);
+ UNMOCK(we_are_hibernating);
+}
+
#define ROUTER_TEST(name, flags) \
{ #name, test_router_ ## name, flags, NULL, NULL }
struct testcase_t router_tests[] = {
+ ROUTER_TEST(check_descriptor_bandwidth_changed, TT_FORK),
ROUTER_TEST(dump_router_to_string_no_bridge_distribution_method, TT_FORK),
END_OF_TESTCASES
};
-
diff --git a/src/test/test_routerkeys.c b/src/test/test_routerkeys.c
index e4abcdb92d..f05401ba0d 100644
--- a/src/test/test_routerkeys.c
+++ b/src/test/test_routerkeys.c
@@ -1,24 +1,32 @@
/* Copyright (c) 2001-2004, Roger Dingledine.
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2017, The Tor Project, Inc. */
+ * Copyright (c) 2007-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
#include "orconfig.h"
#define ROUTER_PRIVATE
-#include "or.h"
-#include "config.h"
-#include "router.h"
-#include "routerkeys.h"
-#include "util.h"
-#include "crypto.h"
-#include "torcert.h"
-#include "test.h"
+#include "core/or/or.h"
+#include "app/config/config.h"
+#include "feature/relay/router.h"
+#include "feature/relay/routerkeys.h"
+#include "lib/crypt_ops/crypto_cipher.h"
+#include "lib/crypt_ops/crypto_format.h"
+#include "feature/keymgt/loadkey.h"
+#include "feature/nodelist/torcert.h"
+#include "test/test.h"
#ifdef _WIN32
/* For mkdir() */
#include <direct.h>
#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+
static void
test_routerkeys_write_fingerprint(void *arg)
{
@@ -255,13 +263,14 @@ test_routerkeys_ed_key_init_basic(void *arg)
unlink(fname2);
/* Fail to load a key that isn't there. */
- kp1 = ed_key_init_from_file(fname1, 0, LOG_INFO, NULL, now, 0, 7, &cert);
+ kp1 = ed_key_init_from_file(fname1, 0, LOG_INFO, NULL, now, 0, 7, &cert,
+ NULL);
tt_assert(kp1 == NULL);
tt_assert(cert == NULL);
/* Create the key if requested to do so. */
kp1 = ed_key_init_from_file(fname1, INIT_ED_KEY_CREATE, LOG_INFO,
- NULL, now, 0, 7, &cert);
+ NULL, now, 0, 7, &cert, NULL);
tt_assert(kp1 != NULL);
tt_assert(cert == NULL);
tt_int_op(stat(get_fname("test_ed_key_1_cert"), &st), OP_LT, 0);
@@ -269,24 +278,24 @@ test_routerkeys_ed_key_init_basic(void *arg)
/* Fail to load if we say we need a cert */
kp2 = ed_key_init_from_file(fname1, INIT_ED_KEY_NEEDCERT, LOG_INFO,
- NULL, now, 0, 7, &cert);
+ NULL, now, 0, 7, &cert, NULL);
tt_assert(kp2 == NULL);
/* Fail to load if we say the wrong key type */
kp2 = ed_key_init_from_file(fname1, 0, LOG_INFO,
- NULL, now, 0, 6, &cert);
+ NULL, now, 0, 6, &cert, NULL);
tt_assert(kp2 == NULL);
/* Load successfully if we're not picky, whether we say "create" or not. */
kp2 = ed_key_init_from_file(fname1, INIT_ED_KEY_CREATE, LOG_INFO,
- NULL, now, 0, 7, &cert);
+ NULL, now, 0, 7, &cert, NULL);
tt_assert(kp2 != NULL);
tt_assert(cert == NULL);
tt_mem_op(kp1, OP_EQ, kp2, sizeof(*kp1));
ed25519_keypair_free(kp2); kp2 = NULL;
kp2 = ed_key_init_from_file(fname1, 0, LOG_INFO,
- NULL, now, 0, 7, &cert);
+ NULL, now, 0, 7, &cert, NULL);
tt_assert(kp2 != NULL);
tt_assert(cert == NULL);
tt_mem_op(kp1, OP_EQ, kp2, sizeof(*kp1));
@@ -295,7 +304,7 @@ test_routerkeys_ed_key_init_basic(void *arg)
/* Now create a key with a cert. */
kp2 = ed_key_init_from_file(fname2, (INIT_ED_KEY_CREATE|
INIT_ED_KEY_NEEDCERT),
- LOG_INFO, kp1, now, 7200, 7, &cert);
+ LOG_INFO, kp1, now, 7200, 7, &cert, NULL);
tt_assert(kp2 != NULL);
tt_assert(cert != NULL);
tt_mem_op(kp1, OP_NE, kp2, sizeof(*kp1));
@@ -308,7 +317,7 @@ test_routerkeys_ed_key_init_basic(void *arg)
/* Now verify we can load the cert... */
kp3 = ed_key_init_from_file(fname2, (INIT_ED_KEY_CREATE|
INIT_ED_KEY_NEEDCERT),
- LOG_INFO, kp1, now, 7200, 7, &cert2);
+ LOG_INFO, kp1, now, 7200, 7, &cert2, NULL);
tt_mem_op(kp2, OP_EQ, kp3, sizeof(*kp2));
tt_mem_op(cert2->encoded, OP_EQ, cert->encoded, cert->encoded_len);
ed25519_keypair_free(kp3); kp3 = NULL;
@@ -316,7 +325,7 @@ test_routerkeys_ed_key_init_basic(void *arg)
/* ... even without create... */
kp3 = ed_key_init_from_file(fname2, INIT_ED_KEY_NEEDCERT,
- LOG_INFO, kp1, now, 7200, 7, &cert2);
+ LOG_INFO, kp1, now, 7200, 7, &cert2, NULL);
tt_mem_op(kp2, OP_EQ, kp3, sizeof(*kp2));
tt_mem_op(cert2->encoded, OP_EQ, cert->encoded, cert->encoded_len);
ed25519_keypair_free(kp3); kp3 = NULL;
@@ -324,13 +333,13 @@ test_routerkeys_ed_key_init_basic(void *arg)
/* ... but that we don't crash or anything if we say we don't want it. */
kp3 = ed_key_init_from_file(fname2, INIT_ED_KEY_NEEDCERT,
- LOG_INFO, kp1, now, 7200, 7, NULL);
+ LOG_INFO, kp1, now, 7200, 7, NULL, NULL);
tt_mem_op(kp2, OP_EQ, kp3, sizeof(*kp2));
ed25519_keypair_free(kp3); kp3 = NULL;
/* Fail if we're told the wrong signing key */
kp3 = ed_key_init_from_file(fname2, INIT_ED_KEY_NEEDCERT,
- LOG_INFO, kp2, now, 7200, 7, &cert2);
+ LOG_INFO, kp2, now, 7200, 7, &cert2, NULL);
tt_assert(kp3 == NULL);
tt_assert(cert2 == NULL);
@@ -361,13 +370,14 @@ test_routerkeys_ed_key_init_split(void *arg)
unlink(fname2);
/* Can't load key that isn't there. */
- kp1 = ed_key_init_from_file(fname1, flags, LOG_INFO, NULL, now, 0, 7, &cert);
+ kp1 = ed_key_init_from_file(fname1, flags, LOG_INFO, NULL, now, 0, 7, &cert,
+ NULL);
tt_assert(kp1 == NULL);
tt_assert(cert == NULL);
/* Create a split key */
kp1 = ed_key_init_from_file(fname1, flags|INIT_ED_KEY_CREATE,
- LOG_INFO, NULL, now, 0, 7, &cert);
+ LOG_INFO, NULL, now, 0, 7, &cert, NULL);
tt_assert(kp1 != NULL);
tt_assert(cert == NULL);
tt_int_op(stat(get_fname("test_ed_key_3_cert"), &st), OP_LT, 0);
@@ -376,7 +386,7 @@ test_routerkeys_ed_key_init_split(void *arg)
/* Load it. */
kp2 = ed_key_init_from_file(fname1, flags|INIT_ED_KEY_CREATE,
- LOG_INFO, NULL, now, 0, 7, &cert);
+ LOG_INFO, NULL, now, 0, 7, &cert, NULL);
tt_assert(kp2 != NULL);
tt_assert(cert == NULL);
tt_mem_op(kp1, OP_EQ, kp2, sizeof(*kp2));
@@ -385,7 +395,7 @@ test_routerkeys_ed_key_init_split(void *arg)
/* Okay, try killing the secret key and loading it. */
unlink(get_fname("test_ed_key_3_secret_key"));
kp2 = ed_key_init_from_file(fname1, flags,
- LOG_INFO, NULL, now, 0, 7, &cert);
+ LOG_INFO, NULL, now, 0, 7, &cert, NULL);
tt_assert(kp2 != NULL);
tt_assert(cert == NULL);
tt_mem_op(&kp1->pubkey, OP_EQ, &kp2->pubkey, sizeof(kp2->pubkey));
@@ -395,7 +405,7 @@ test_routerkeys_ed_key_init_split(void *arg)
/* Even when we're told to "create", don't create if there's a public key */
kp2 = ed_key_init_from_file(fname1, flags|INIT_ED_KEY_CREATE,
- LOG_INFO, NULL, now, 0, 7, &cert);
+ LOG_INFO, NULL, now, 0, 7, &cert, NULL);
tt_assert(kp2 != NULL);
tt_assert(cert == NULL);
tt_mem_op(&kp1->pubkey, OP_EQ, &kp2->pubkey, sizeof(kp2->pubkey));
@@ -405,7 +415,7 @@ test_routerkeys_ed_key_init_split(void *arg)
/* Make sure we fail on a tag mismatch, though */
kp2 = ed_key_init_from_file(fname1, flags,
- LOG_INFO, NULL, now, 0, 99, &cert);
+ LOG_INFO, NULL, now, 0, 99, &cert, NULL);
tt_assert(kp2 == NULL);
done:
@@ -695,4 +705,3 @@ struct testcase_t routerkeys_tests[] = {
TEST(rsa_ed_crosscert, 0),
END_OF_TESTCASES
};
-
diff --git a/src/test/test_routerlist.c b/src/test/test_routerlist.c
index c19d66ef9d..67af2fd484 100644
--- a/src/test/test_routerlist.c
+++ b/src/test/test_routerlist.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014-2017, The Tor Project, Inc. */
+/* Copyright (c) 2014-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
#include "orconfig.h"
@@ -6,37 +6,53 @@
#include <time.h>
#define CONNECTION_PRIVATE
-#define DIRECTORY_PRIVATE
+#define DIRCLIENT_PRIVATE
#define DIRVOTE_PRIVATE
#define ENTRYNODES_PRIVATE
#define HIBERNATE_PRIVATE
#define NETWORKSTATUS_PRIVATE
#define ROUTERLIST_PRIVATE
+#define NODE_SELECT_PRIVATE
#define TOR_UNIT_TESTING
-#include "or.h"
-#include "config.h"
-#include "connection.h"
-#include "container.h"
-#include "control.h"
-#include "directory.h"
-#include "dirvote.h"
-#include "entrynodes.h"
-#include "hibernate.h"
-#include "microdesc.h"
-#include "networkstatus.h"
-#include "nodelist.h"
-#include "policies.h"
-#include "router.h"
-#include "routerlist.h"
-#include "routerset.h"
-#include "routerparse.h"
-#include "shared_random.h"
-#include "statefile.h"
-#include "test.h"
-#include "test_dir_common.h"
-#include "log_test_helpers.h"
-
-void construct_consensus(char **consensus_text_md);
+#include "core/or/or.h"
+#include "app/config/config.h"
+#include "core/mainloop/connection.h"
+#include "feature/control/control.h"
+#include "lib/crypt_ops/crypto_rand.h"
+#include "feature/dircommon/directory.h"
+#include "feature/dirclient/dirclient.h"
+#include "feature/dirauth/dirvote.h"
+#include "feature/client/entrynodes.h"
+#include "feature/hibernate/hibernate.h"
+#include "feature/nodelist/microdesc.h"
+#include "feature/nodelist/networkstatus.h"
+#include "feature/nodelist/nodelist.h"
+#include "core/or/policies.h"
+#include "feature/relay/router.h"
+#include "feature/nodelist/authcert.h"
+#include "feature/nodelist/node_select.h"
+#include "feature/nodelist/routerlist.h"
+#include "feature/nodelist/routerset.h"
+#include "feature/dirparse/authcert_parse.h"
+#include "feature/dirparse/ns_parse.h"
+#include "feature/dirauth/shared_random.h"
+#include "app/config/statefile.h"
+
+#include "feature/nodelist/authority_cert_st.h"
+#include "feature/dircommon/dir_connection_st.h"
+#include "feature/nodelist/networkstatus_st.h"
+#include "feature/nodelist/node_st.h"
+#include "app/config/or_state_st.h"
+#include "feature/nodelist/routerstatus_st.h"
+
+#include "lib/encoding/confline.h"
+#include "lib/container/buffers.h"
+
+#include "test/test.h"
+#include "test/test_dir_common.h"
+#include "test/log_test_helpers.h"
+
+void construct_consensus(char **consensus_text_md, time_t now);
static authority_cert_t *mock_cert;
@@ -135,7 +151,7 @@ test_routerlist_launch_descriptor_downloads(void *arg)
}
void
-construct_consensus(char **consensus_text_md)
+construct_consensus(char **consensus_text_md, time_t now)
{
networkstatus_t *vote = NULL;
networkstatus_t *v1 = NULL, *v2 = NULL, *v3 = NULL;
@@ -143,7 +159,6 @@ construct_consensus(char **consensus_text_md)
authority_cert_t *cert1=NULL, *cert2=NULL, *cert3=NULL;
crypto_pk_t *sign_skey_1=NULL, *sign_skey_2=NULL, *sign_skey_3=NULL;
crypto_pk_t *sign_skey_leg=NULL;
- time_t now = time(NULL);
smartlist_t *votes = NULL;
int n_vrs;
@@ -258,7 +273,7 @@ test_router_pick_directory_server_impl(void *arg)
rs = router_pick_directory_server_impl(V3_DIRINFO, (const int) 0, NULL);
tt_ptr_op(rs, OP_EQ, NULL);
- construct_consensus(&consensus_text_md);
+ construct_consensus(&consensus_text_md, now);
tt_assert(consensus_text_md);
con_md = networkstatus_parse_vote_from_string(consensus_text_md, NULL,
NS_TYPE_CONSENSUS);
@@ -452,6 +467,7 @@ test_directory_guard_fetch_with_no_dirinfo(void *arg)
int retval;
char *consensus_text_md = NULL;
or_options_t *options = get_options_mutable();
+ time_t now = time(NULL);
(void) arg;
@@ -495,7 +511,7 @@ test_directory_guard_fetch_with_no_dirinfo(void *arg)
conn->requested_resource = tor_strdup("ns");
/* Construct a consensus */
- construct_consensus(&consensus_text_md);
+ construct_consensus(&consensus_text_md, now);
tt_assert(consensus_text_md);
/* Place the consensus in the dirconn */
@@ -506,7 +522,7 @@ test_directory_guard_fetch_with_no_dirinfo(void *arg)
args.body_len = strlen(consensus_text_md);
/* Update approx time so that the consensus is considered live */
- update_approx_time(time(NULL)+1010);
+ update_approx_time(now+1010);
setup_capture_of_logs(LOG_DEBUG);
@@ -598,11 +614,167 @@ test_routerlist_router_is_already_dir_fetching(void *arg)
#undef TEST_ADDR_STR
#undef TEST_DIR_PORT
+static long mock_apparent_skew = 0;
+
+/** Store apparent_skew and assert that the other arguments are as
+ * expected. */
+static void
+mock_clock_skew_warning(const connection_t *conn, long apparent_skew,
+ int trusted, log_domain_mask_t domain,
+ const char *received, const char *source)
+{
+ (void)conn;
+ mock_apparent_skew = apparent_skew;
+ tt_int_op(trusted, OP_EQ, 1);
+ tt_int_op(domain, OP_EQ, LD_GENERAL);
+ tt_str_op(received, OP_EQ, "microdesc flavor consensus");
+ tt_str_op(source, OP_EQ, "CONSENSUS");
+ done:
+ ;
+}
+
+/** Do common setup for test_timely_consensus() and
+ * test_early_consensus(). Call networkstatus_set_current_consensus()
+ * on a constructed consensus and with an appropriately-modified
+ * approx_time. Callers expect presence or absence of appropriate log
+ * messages and control events. */
+static int
+test_skew_common(void *arg, time_t now, unsigned long *offset)
+{
+ char *consensus = NULL;
+ int retval = 0;
+
+ *offset = strtoul(arg, NULL, 10);
+
+ /* Initialize the SRV subsystem */
+ MOCK(get_my_v3_authority_cert, get_my_v3_authority_cert_m);
+ mock_cert = authority_cert_parse_from_string(AUTHORITY_CERT_1, NULL);
+ sr_init(0);
+ UNMOCK(get_my_v3_authority_cert);
+
+ construct_consensus(&consensus, now);
+ tt_assert(consensus);
+
+ update_approx_time(now + *offset);
+
+ mock_apparent_skew = 0;
+ /* Caller will call UNMOCK() */
+ MOCK(clock_skew_warning, mock_clock_skew_warning);
+ /* Caller will call teardown_capture_of_logs() */
+ setup_capture_of_logs(LOG_WARN);
+ retval = networkstatus_set_current_consensus(consensus, "microdesc", 0,
+ NULL);
+
+ done:
+ tor_free(consensus);
+ return retval;
+}
+
+/** Test non-early consensus */
+static void
+test_timely_consensus(void *arg)
+{
+ time_t now = time(NULL);
+ unsigned long offset = 0;
+ int retval = 0;
+
+ retval = test_skew_common(arg, now, &offset);
+ (void)offset;
+ expect_no_log_msg_containing("behind the time published in the consensus");
+ tt_int_op(retval, OP_EQ, 0);
+ tt_int_op(mock_apparent_skew, OP_EQ, 0);
+ done:
+ teardown_capture_of_logs();
+ UNMOCK(clock_skew_warning);
+}
+
+/** Test early consensus */
+static void
+test_early_consensus(void *arg)
+{
+ time_t now = time(NULL);
+ unsigned long offset = 0;
+ int retval = 0;
+
+ retval = test_skew_common(arg, now, &offset);
+ /* Can't use expect_single_log_msg() because of unrecognized authorities */
+ expect_log_msg_containing("behind the time published in the consensus");
+ tt_int_op(retval, OP_EQ, 0);
+ /* This depends on construct_consensus() setting valid_after=now+1000 */
+ tt_int_op(mock_apparent_skew, OP_EQ, offset - 1000);
+ done:
+ teardown_capture_of_logs();
+ UNMOCK(clock_skew_warning);
+}
+
+/** Test warn_early_consensus(), expecting no warning */
+static void
+test_warn_early_consensus_no(const networkstatus_t *c, time_t now,
+ long offset)
+{
+ mock_apparent_skew = 0;
+ setup_capture_of_logs(LOG_WARN);
+ warn_early_consensus(c, "microdesc", now + offset);
+ expect_no_log_msg_containing("behind the time published in the consensus");
+ tt_int_op(mock_apparent_skew, OP_EQ, 0);
+ done:
+ teardown_capture_of_logs();
+}
+
+/** Test warn_early_consensus(), expecting a warning */
+static void
+test_warn_early_consensus_yes(const networkstatus_t *c, time_t now,
+ long offset)
+{
+ mock_apparent_skew = 0;
+ setup_capture_of_logs(LOG_WARN);
+ warn_early_consensus(c, "microdesc", now + offset);
+ /* Can't use expect_single_log_msg() because of unrecognized authorities */
+ expect_log_msg_containing("behind the time published in the consensus");
+ tt_int_op(mock_apparent_skew, OP_EQ, offset);
+ done:
+ teardown_capture_of_logs();
+}
+
+/**
+ * Test warn_early_consensus() directly, checking both the non-warning
+ * case (consensus is not early) and the warning case (consensus is
+ * early). Depends on EARLY_CONSENSUS_NOTICE_SKEW=60.
+ */
+static void
+test_warn_early_consensus(void *arg)
+{
+ networkstatus_t *c = NULL;
+ time_t now = time(NULL);
+
+ (void)arg;
+ c = tor_malloc_zero(sizeof *c);
+ c->valid_after = now;
+ c->dist_seconds = 300;
+ mock_apparent_skew = 0;
+ MOCK(clock_skew_warning, mock_clock_skew_warning);
+ test_warn_early_consensus_no(c, now, 60);
+ test_warn_early_consensus_no(c, now, 0);
+ test_warn_early_consensus_no(c, now, -60);
+ test_warn_early_consensus_no(c, now, -360);
+ test_warn_early_consensus_yes(c, now, -361);
+ test_warn_early_consensus_yes(c, now, -600);
+ UNMOCK(clock_skew_warning);
+ tor_free(c);
+}
+
#define NODE(name, flags) \
{ #name, test_routerlist_##name, (flags), NULL, NULL }
#define ROUTER(name,flags) \
{ #name, test_router_##name, (flags), NULL, NULL }
+#define TIMELY(name, arg) \
+ { name, test_timely_consensus, TT_FORK, &passthrough_setup, \
+ (char *)(arg) }
+#define EARLY(name, arg) \
+ { name, test_early_consensus, TT_FORK, &passthrough_setup, \
+ (char *)(arg) }
+
struct testcase_t routerlist_tests[] = {
NODE(initiate_descriptor_downloads, 0),
NODE(launch_descriptor_downloads, 0),
@@ -610,6 +782,12 @@ struct testcase_t routerlist_tests[] = {
ROUTER(pick_directory_server_impl, TT_FORK),
{ "directory_guard_fetch_with_no_dirinfo",
test_directory_guard_fetch_with_no_dirinfo, TT_FORK, NULL, NULL },
+ /* These depend on construct_consensus() setting
+ * valid_after=now+1000 and dist_seconds=250 */
+ TIMELY("timely_consensus1", "1010"),
+ TIMELY("timely_consensus2", "1000"),
+ TIMELY("timely_consensus3", "690"),
+ EARLY("early_consensus1", "689"),
+ { "warn_early_consensus", test_warn_early_consensus, 0, NULL, NULL },
END_OF_TESTCASES
};
-
diff --git a/src/test/test_routerset.c b/src/test/test_routerset.c
index c541324674..86f9c0fa82 100644
--- a/src/test/test_routerset.c
+++ b/src/test/test_routerset.c
@@ -1,15 +1,22 @@
-/* Copyright (c) 2014-2017, The Tor Project, Inc. */
+/* Copyright (c) 2014-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
#define ROUTERSET_PRIVATE
-#include "or.h"
-#include "geoip.h"
-#include "routerset.h"
-#include "routerparse.h"
-#include "policies.h"
-#include "nodelist.h"
-#include "test.h"
+#include "core/or/or.h"
+#include "core/or/policies.h"
+#include "feature/dirparse/policy_parse.h"
+#include "feature/nodelist/nodelist.h"
+#include "feature/nodelist/routerset.h"
+#include "lib/geoip/geoip.h"
+
+#include "core/or/addr_policy_st.h"
+#include "core/or/extend_info_st.h"
+#include "feature/nodelist/node_st.h"
+#include "feature/nodelist/routerinfo_st.h"
+#include "feature/nodelist/routerstatus_st.h"
+
+#include "test/test.h"
#define NS_MODULE routerset
@@ -1489,6 +1496,7 @@ NS(test_main)(void *arg)
int r;
(void)arg;
+ memset(&NS(mock_node), 0, sizeof(NS(mock_node)));
NS(mock_node).ri = NULL;
NS(mock_node).rs = NULL;
@@ -1522,6 +1530,7 @@ NS(test_main)(void *arg)
strncpy(rs.nickname, nickname, sizeof(rs.nickname) - 1);
rs.nickname[sizeof(rs.nickname) - 1] = '\0';
+ memset(&NS(mock_node), 0, sizeof(NS(mock_node)));
NS(mock_node).ri = NULL;
NS(mock_node).rs = &rs;
@@ -1553,6 +1562,7 @@ NS(test_main)(void *arg)
strmap_set_lc(set->names, nickname, (void *)1);
ri.nickname = (char *)nickname;
+ memset(&mock_node, 0, sizeof(mock_node));
mock_node.ri = &ri;
mock_node.rs = NULL;
@@ -2221,4 +2231,3 @@ struct testcase_t routerset_tests[] = {
TEST_CASE(routerset_free),
END_OF_TESTCASES
};
-
diff --git a/src/test/test_rust.sh b/src/test/test_rust.sh
index 5405af436b..a1a56af480 100755
--- a/src/test/test_rust.sh
+++ b/src/test/test_rust.sh
@@ -9,7 +9,8 @@ for cargo_toml_dir in "${abs_top_srcdir:-../../..}"/src/rust/*; do
if [ -e "${cargo_toml_dir}/Cargo.toml" ]; then
cd "${abs_top_builddir:-../../..}/src/rust" && \
CARGO_TARGET_DIR="${abs_top_builddir:-../../..}/src/rust/target" \
- "${CARGO:-cargo}" test --all-features ${CARGO_ONLINE-"--frozen"} \
+ "${CARGO:-cargo}" test ${CARGO_ONLINE-"--frozen"} \
+ --features "test_linking_hack" \
${EXTRA_CARGO_OPTIONS} \
--manifest-path "${cargo_toml_dir}/Cargo.toml" || exitcode=1
fi
diff --git a/src/test/test_scheduler.c b/src/test/test_scheduler.c
index ebba71266c..2d562299ab 100644
--- a/src/test/test_scheduler.c
+++ b/src/test/test_scheduler.c
@@ -1,27 +1,26 @@
-/* Copyright (c) 2014-2017, The Tor Project, Inc. */
+/* Copyright (c) 2014-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
#include "orconfig.h"
#include <math.h>
-#include <event2/event.h>
#define SCHEDULER_KIST_PRIVATE
#define TOR_CHANNEL_INTERNAL_
#define CHANNEL_PRIVATE_
-#include "or.h"
-#include "config.h"
-#include "compat_libevent.h"
-#include "channel.h"
-#include "channeltls.h"
-#include "connection.h"
-#include "networkstatus.h"
+#include "core/or/or.h"
+#include "app/config/config.h"
+#include "lib/evloop/compat_libevent.h"
+#include "core/or/channel.h"
+#include "core/or/channeltls.h"
+#include "core/mainloop/connection.h"
+#include "feature/nodelist/networkstatus.h"
#define SCHEDULER_PRIVATE_
-#include "scheduler.h"
+#include "core/or/scheduler.h"
/* Test suite stuff */
-#include "test.h"
-#include "fakechans.h"
+#include "test/test.h"
+#include "test/fakechans.h"
/* Shamelessly stolen from compat_libevent.c */
#define V(major, minor, patch) \
@@ -101,62 +100,6 @@ mock_kist_networkstatus_get_param(
return 12;
}
-/* Event base for scheduelr tests */
-static struct event_base *mock_event_base = NULL;
-/* Setup for mock event stuff */
-static void mock_event_free_all(void);
-static void mock_event_init(void);
-static void
-mock_event_free_all(void)
-{
- tt_ptr_op(mock_event_base, OP_NE, NULL);
-
- if (mock_event_base) {
- event_base_free(mock_event_base);
- mock_event_base = NULL;
- }
-
- tt_ptr_op(mock_event_base, OP_EQ, NULL);
-
- done:
- return;
-}
-
-static void
-mock_event_init(void)
-{
- struct event_config *cfg = NULL;
-
- tt_ptr_op(mock_event_base, OP_EQ, NULL);
-
- /*
- * Really cut down from tor_libevent_initialize of
- * src/common/compat_libevent.c to kill config dependencies
- */
-
- if (!mock_event_base) {
- cfg = event_config_new();
-#if LIBEVENT_VERSION_NUMBER >= V(2,0,9)
- /* We can enable changelist support with epoll, since we don't give
- * Libevent any dup'd fds. This lets us avoid some syscalls. */
- event_config_set_flag(cfg, EVENT_BASE_FLAG_EPOLL_USE_CHANGELIST);
-#endif
- mock_event_base = event_base_new_with_config(cfg);
- event_config_free(cfg);
- }
-
- tt_ptr_op(mock_event_base, OP_NE, NULL);
-
- done:
- return;
-}
-
-static struct event_base *
-tor_libevent_get_base_mock(void)
-{
- return mock_event_base;
-}
-
static int
scheduler_compare_channels_mock(const void *c1_v,
const void *c2_v)
@@ -417,9 +360,7 @@ perform_channel_state_tests(int KISTSchedRunInterval, int sched_type)
mocked_options.KISTSchedRunInterval = KISTSchedRunInterval;
set_scheduler_options(sched_type);
- /* Set up libevent and scheduler */
- mock_event_init();
- MOCK(tor_libevent_get_base, tor_libevent_get_base_mock);
+ /* Set up scheduler */
scheduler_init();
/*
* Install the compare channels mock so we can test
@@ -523,14 +464,12 @@ perform_channel_state_tests(int KISTSchedRunInterval, int sched_type)
channel_free_all();
scheduler_free_all();
- mock_event_free_all();
done:
tor_free(ch1);
tor_free(ch2);
UNMOCK(scheduler_compare_channels);
- UNMOCK(tor_libevent_get_base);
UNMOCK(get_options);
cleanup_scheduler_options();
@@ -635,10 +574,7 @@ test_scheduler_loop_vanilla(void *arg)
set_scheduler_options(SCHEDULER_VANILLA);
mocked_options.KISTSchedRunInterval = 0;
- /* Set up libevent and scheduler */
-
- mock_event_init();
- MOCK(tor_libevent_get_base, tor_libevent_get_base_mock);
+ /* Set up scheduler */
scheduler_init();
/*
* Install the compare channels mock so we can test
@@ -786,7 +722,6 @@ test_scheduler_loop_vanilla(void *arg)
channel_flush_some_cells_mock_free_all();
channel_free_all();
scheduler_free_all();
- mock_event_free_all();
done:
tor_free(ch1);
@@ -795,7 +730,6 @@ test_scheduler_loop_vanilla(void *arg)
UNMOCK(channel_flush_some_cells);
UNMOCK(scheduler_compare_channels);
- UNMOCK(tor_libevent_get_base);
UNMOCK(get_options);
}
@@ -917,8 +851,6 @@ test_scheduler_initfree(void *arg)
tt_ptr_op(channels_pending, ==, NULL);
tt_ptr_op(run_sched_ev, ==, NULL);
- mock_event_init();
- MOCK(tor_libevent_get_base, tor_libevent_get_base_mock);
MOCK(get_options, mock_get_options);
set_scheduler_options(SCHEDULER_KIST);
set_scheduler_options(SCHEDULER_KIST_LITE);
@@ -935,9 +867,6 @@ test_scheduler_initfree(void *arg)
scheduler_free_all();
- UNMOCK(tor_libevent_get_base);
- mock_event_free_all();
-
tt_ptr_op(channels_pending, ==, NULL);
tt_ptr_op(run_sched_ev, ==, NULL);
diff --git a/src/test/test_shared_random.c b/src/test/test_shared_random.c
index 437fc38deb..8a7fb95cc1 100644
--- a/src/test/test_shared_random.c
+++ b/src/test/test_shared_random.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016-2017, The Tor Project, Inc. */
+/* Copyright (c) 2016-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
#define SHARED_RANDOM_PRIVATE
@@ -6,18 +6,35 @@
#define CONFIG_PRIVATE
#define DIRVOTE_PRIVATE
-#include "or.h"
-#include "test.h"
-#include "config.h"
-#include "dirvote.h"
-#include "shared_random.h"
-#include "shared_random_state.h"
-#include "routerkeys.h"
-#include "routerlist.h"
-#include "router.h"
-#include "routerparse.h"
-#include "networkstatus.h"
-#include "log_test_helpers.h"
+#include "core/or/or.h"
+#include "test/test.h"
+#include "app/config/config.h"
+#include "lib/crypt_ops/crypto_rand.h"
+#include "feature/dirauth/dirvote.h"
+#include "feature/dirauth/shared_random.h"
+#include "feature/dirauth/shared_random_state.h"
+#include "test/log_test_helpers.h"
+#include "feature/nodelist/networkstatus.h"
+#include "feature/relay/router.h"
+#include "feature/relay/routerkeys.h"
+#include "feature/nodelist/authcert.h"
+#include "feature/nodelist/dirlist.h"
+#include "feature/dirparse/authcert_parse.h"
+#include "feature/hs_common/shared_random_client.h"
+#include "feature/dircommon/voting_schedule.h"
+
+#include "feature/dirclient/dir_server_st.h"
+#include "feature/nodelist/networkstatus_st.h"
+#include "app/config/or_state_st.h"
+
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+
+#ifdef _WIN32
+/* For mkdir */
+#include <direct.h>
+#endif
static authority_cert_t *mock_cert;
@@ -170,7 +187,7 @@ test_get_state_valid_until_time(void *arg)
retval = parse_rfc1123_time("Mon, 20 Apr 2015 00:00:01 UTC",
&current_time);
tt_int_op(retval, OP_EQ, 0);
- dirvote_recalculate_timing(get_options(), current_time);
+ voting_schedule_recalculate_timing(get_options(), current_time);
valid_until_time = get_state_valid_until_time(current_time);
/* Compare it with the correct result */
@@ -182,7 +199,7 @@ test_get_state_valid_until_time(void *arg)
retval = parse_rfc1123_time("Mon, 20 Apr 2015 19:22:00 UTC",
&current_time);
tt_int_op(retval, OP_EQ, 0);
- dirvote_recalculate_timing(get_options(), current_time);
+ voting_schedule_recalculate_timing(get_options(), current_time);
valid_until_time = get_state_valid_until_time(current_time);
format_iso_time(tbuf, valid_until_time);
@@ -193,7 +210,7 @@ test_get_state_valid_until_time(void *arg)
retval = parse_rfc1123_time("Mon, 20 Apr 2015 23:59:00 UTC",
&current_time);
tt_int_op(retval, OP_EQ, 0);
- dirvote_recalculate_timing(get_options(), current_time);
+ voting_schedule_recalculate_timing(get_options(), current_time);
valid_until_time = get_state_valid_until_time(current_time);
format_iso_time(tbuf, valid_until_time);
@@ -204,7 +221,7 @@ test_get_state_valid_until_time(void *arg)
retval = parse_rfc1123_time("Mon, 20 Apr 2015 00:00:00 UTC",
&current_time);
tt_int_op(retval, OP_EQ, 0);
- dirvote_recalculate_timing(get_options(), current_time);
+ voting_schedule_recalculate_timing(get_options(), current_time);
valid_until_time = get_state_valid_until_time(current_time);
format_iso_time(tbuf, valid_until_time);
@@ -242,9 +259,8 @@ test_get_start_time_of_current_run(void *arg)
retval = parse_rfc1123_time("Mon, 20 Apr 2015 00:00:01 UTC",
&current_time);
tt_int_op(retval, OP_EQ, 0);
- dirvote_recalculate_timing(get_options(), current_time);
- run_start_time =
- sr_state_get_start_time_of_current_protocol_run(current_time);
+ voting_schedule_recalculate_timing(get_options(), current_time);
+ run_start_time = sr_state_get_start_time_of_current_protocol_run();
/* Compare it with the correct result */
format_iso_time(tbuf, run_start_time);
@@ -255,9 +271,8 @@ test_get_start_time_of_current_run(void *arg)
retval = parse_rfc1123_time("Mon, 20 Apr 2015 23:59:59 UTC",
&current_time);
tt_int_op(retval, OP_EQ, 0);
- dirvote_recalculate_timing(get_options(), current_time);
- run_start_time =
- sr_state_get_start_time_of_current_protocol_run(current_time);
+ voting_schedule_recalculate_timing(get_options(), current_time);
+ run_start_time = sr_state_get_start_time_of_current_protocol_run();
/* Compare it with the correct result */
format_iso_time(tbuf, run_start_time);
@@ -268,15 +283,48 @@ test_get_start_time_of_current_run(void *arg)
retval = parse_rfc1123_time("Mon, 20 Apr 2015 00:00:00 UTC",
&current_time);
tt_int_op(retval, OP_EQ, 0);
- dirvote_recalculate_timing(get_options(), current_time);
- run_start_time =
- sr_state_get_start_time_of_current_protocol_run(current_time);
+ voting_schedule_recalculate_timing(get_options(), current_time);
+ run_start_time = sr_state_get_start_time_of_current_protocol_run();
/* Compare it with the correct result */
format_iso_time(tbuf, run_start_time);
tt_str_op("2015-04-20 00:00:00", OP_EQ, tbuf);
}
+ {
+ /* We want the local time to be past midnight, but the current consensus to
+ * have valid-after 23:00 (e.g. this can happen if we fetch a new consensus
+ * at 00:08 before dircaches have a chance to get the midnight consensus).
+ *
+ * Basically, we want to cause a desynch between ns->valid_after (23:00)
+ * and the voting_schedule.interval_starts (01:00), to make sure that
+ * sr_state_get_start_time_of_current_protocol_run() handles it gracefully:
+ * It should actually follow the local consensus time and not the voting
+ * schedule (which is designed for authority voting purposes). */
+ retval = parse_rfc1123_time("Mon, 20 Apr 2015 00:00:00 UTC",
+ &mock_consensus.fresh_until);
+ tt_int_op(retval, OP_EQ, 0);
+
+ retval = parse_rfc1123_time("Mon, 19 Apr 2015 23:00:00 UTC",
+ &mock_consensus.valid_after);
+
+ retval = parse_rfc1123_time("Mon, 20 Apr 2015 00:08:00 UTC",
+ &current_time);
+ tt_int_op(retval, OP_EQ, 0);
+ update_approx_time(current_time);
+ voting_schedule_recalculate_timing(get_options(), current_time);
+
+ run_start_time = sr_state_get_start_time_of_current_protocol_run();
+
+ /* Compare it with the correct result */
+ format_iso_time(tbuf, run_start_time);
+ tt_str_op("2015-04-19 00:00:00", OP_EQ, tbuf);
+ /* Check that voting_schedule.interval_starts is at 01:00 (see above) */
+ time_t interval_starts = voting_schedule_get_next_valid_after_time();
+ format_iso_time(tbuf, interval_starts);
+ tt_str_op("2015-04-20 01:00:00", OP_EQ, tbuf);
+ }
+
/* Next test is testing it without a consensus to use the testing voting
* interval . */
UNMOCK(networkstatus_get_live_consensus);
@@ -291,9 +339,8 @@ test_get_start_time_of_current_run(void *arg)
retval = parse_rfc1123_time("Mon, 20 Apr 2015 00:15:32 UTC",
&current_time);
tt_int_op(retval, OP_EQ, 0);
- dirvote_recalculate_timing(get_options(), current_time);
- run_start_time =
- sr_state_get_start_time_of_current_protocol_run(current_time);
+ voting_schedule_recalculate_timing(get_options(), current_time);
+ run_start_time = sr_state_get_start_time_of_current_protocol_run();
/* Compare it with the correct result */
format_iso_time(tbuf, run_start_time);
@@ -324,9 +371,9 @@ test_get_start_time_functions(void *arg)
tt_int_op(retval, OP_EQ, 0);
time_t now = mock_consensus.valid_after;
- dirvote_recalculate_timing(get_options(), now);
+ voting_schedule_recalculate_timing(get_options(), now);
time_t start_time_of_protocol_run =
- sr_state_get_start_time_of_current_protocol_run(now);
+ sr_state_get_start_time_of_current_protocol_run();
tt_assert(start_time_of_protocol_run);
/* Check that the round start time of the beginning of the run, is itself */
@@ -1272,7 +1319,7 @@ test_keep_commit(void *arg)
expect_log_msg_containing("doesn't match the commit value.");
expect_log_msg_containing("has an invalid reveal value.");
assert_log_predicate(mock_saved_log_n_entries() == 2,
- "expected 2 log entries");
+ ("expected 2 log entries"));
teardown_capture_of_logs();
memcpy(commit->hashed_reveal, place_holder.hashed_reveal,
sizeof(commit->hashed_reveal));
@@ -1387,4 +1434,3 @@ struct testcase_t sr_tests[] = {
NULL, NULL },
END_OF_TESTCASES
};
-
diff --git a/src/test/test_slow.c b/src/test/test_slow.c
index e640702499..0b665363ab 100644
--- a/src/test/test_slow.c
+++ b/src/test/test_slow.c
@@ -1,6 +1,6 @@
/* Copyright (c) 2001-2004, Roger Dingledine.
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2017, The Tor Project, Inc. */
+ * Copyright (c) 2007-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
/**
@@ -15,8 +15,8 @@
#include <fcntl.h>
#endif
-#include "or.h"
-#include "test.h"
+#include "core/or/or.h"
+#include "test/test.h"
struct testgroup_t testgroups[] = {
{ "slow/crypto/", slow_crypto_tests },
diff --git a/src/test/test_socks.c b/src/test/test_socks.c
index 8da7191e82..7f6d8a48f1 100644
--- a/src/test/test_socks.c
+++ b/src/test/test_socks.c
@@ -1,14 +1,17 @@
/* Copyright (c) 2001-2004, Roger Dingledine.
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2017, The Tor Project, Inc. */
+ * Copyright (c) 2007-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
-#include "or.h"
-#include "buffers.h"
-#include "config.h"
-#include "proto_socks.h"
-#include "test.h"
-#include "log_test_helpers.h"
+#include "core/or/or.h"
+#include "lib/container/buffers.h"
+#include "app/config/config.h"
+#include "core/mainloop/connection.h"
+#include "core/proto/proto_socks.h"
+#include "test/test.h"
+#include "test/log_test_helpers.h"
+#include "core/or/socks_request_st.h"
+#include "lib/net/socks5_status.h"
typedef struct socks_test_data_t {
socks_request_t *req;
@@ -81,7 +84,7 @@ test_socks_4_supported_commands(void *ptr)
tt_int_op(0,OP_EQ, buf_datalen(buf));
- /* SOCKS 4 Send CONNECT [01] to IP address 2.2.2.2:4370 */
+ /* SOCKS 4 Send CONNECT [01] to IP address 2.2.2.3:4370 */
ADD_DATA(buf, "\x04\x01\x11\x12\x02\x02\x02\x03\x00");
tt_int_op(fetch_from_buf_socks(buf, socks, get_options()->TestSocks,
get_options()->SafeSocks),
@@ -97,7 +100,7 @@ test_socks_4_supported_commands(void *ptr)
tt_int_op(0,OP_EQ, buf_datalen(buf));
socks_request_clear(socks);
- /* SOCKS 4 Send CONNECT [01] to IP address 2.2.2.2:4369 with userid*/
+ /* SOCKS 4 Send CONNECT [01] to IP address 2.2.2.4:4369 with userid*/
ADD_DATA(buf, "\x04\x01\x11\x12\x02\x02\x02\x04me\x00");
tt_int_op(fetch_from_buf_socks(buf, socks, 1, 0),
OP_EQ, 1);
@@ -163,7 +166,7 @@ test_socks_4_bad_arguments(void *ptr)
tt_int_op(fetch_from_buf_socks(buf, socks, 1, 0),
OP_EQ, -1);
buf_clear(buf);
- expect_log_msg_containing("user name too long; rejecting.");
+ expect_log_msg_containing("socks4: parsing failed - invalid request.");
mock_clean_saved_logs();
/* Try with 2000-byte hostname */
@@ -191,7 +194,7 @@ test_socks_4_bad_arguments(void *ptr)
tt_int_op(fetch_from_buf_socks(buf, socks, 1, 0),
OP_EQ, -1);
buf_clear(buf);
- expect_log_msg_containing("Destaddr too long.");
+ expect_log_msg_containing("parsing failed - invalid request.");
mock_clean_saved_logs();
/* Socks4, bogus hostname */
@@ -645,7 +648,8 @@ test_socks_5_malformed_commands(void *ptr)
tt_int_op(5,OP_EQ,socks->socks_version);
tt_int_op(10,OP_EQ,socks->replylen);
tt_int_op(5,OP_EQ,socks->reply[0]);
- tt_int_op(SOCKS5_ADDRESS_TYPE_NOT_SUPPORTED,OP_EQ,socks->reply[1]);
+ /* trunnel parsing will fail with -1 */
+ tt_int_op(SOCKS5_GENERAL_ERROR,OP_EQ,socks->reply[1]);
tt_int_op(1,OP_EQ,socks->reply[3]);
done:
@@ -1046,4 +1050,3 @@ struct testcase_t socks_tests[] = {
END_OF_TESTCASES
};
-
diff --git a/src/test/test_status.c b/src/test/test_status.c
index b4ca17891b..3ceba77a84 100644
--- a/src/test/test_status.c
+++ b/src/test/test_status.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014-2017, The Tor Project, Inc. */
+/* Copyright (c) 2014-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
#define STATUS_PRIVATE
@@ -11,20 +11,27 @@
#include <float.h>
#include <math.h>
-#include "or.h"
-#include "torlog.h"
+#include "core/or/or.h"
+#include "lib/log/log.h"
#include "tor_queue.h"
-#include "status.h"
-#include "circuitlist.h"
-#include "config.h"
-#include "hibernate.h"
-#include "rephist.h"
-#include "relay.h"
-#include "router.h"
-#include "main.h"
-#include "nodelist.h"
-#include "statefile.h"
-#include "test.h"
+#include "core/or/status.h"
+#include "core/or/circuitlist.h"
+#include "app/config/config.h"
+#include "feature/hibernate/hibernate.h"
+#include "feature/stats/rephist.h"
+#include "core/or/relay.h"
+#include "feature/relay/router.h"
+#include "feature/relay/routermode.h"
+#include "core/mainloop/mainloop.h"
+#include "feature/nodelist/nodelist.h"
+#include "app/config/statefile.h"
+#include "lib/tls/tortls.h"
+
+#include "core/or/origin_circuit_st.h"
+#include "app/config/or_state_st.h"
+#include "feature/nodelist/routerinfo_st.h"
+
+#include "test/test.h"
#define NS_MODULE status
@@ -226,7 +233,7 @@ NS(test_main)(void *arg)
tor_free(actual);
expected = "10.00 GB";
- actual = bytes_to_usage((U64_LITERAL(1) << 30) * 10L);
+ actual = bytes_to_usage((UINT64_C(1) << 30) * 10L);
tt_str_op(actual, OP_EQ, expected);
tor_free(actual);
@@ -1093,4 +1100,3 @@ struct testcase_t status_tests[] = {
TEST_CASE_ASPECT(log_heartbeat, tls_write_overhead),
END_OF_TESTCASES
};
-
diff --git a/src/test/test_storagedir.c b/src/test/test_storagedir.c
index a27074c21f..76aae7e033 100644
--- a/src/test/test_storagedir.c
+++ b/src/test/test_storagedir.c
@@ -1,9 +1,11 @@
-/* Copyright (c) 2017, The Tor Project, Inc. */
+/* Copyright (c) 2017-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
-#include "or.h"
-#include "storagedir.h"
-#include "test.h"
+#include "core/or/or.h"
+#include "lib/crypt_ops/crypto_rand.h"
+#include "lib/fs/storagedir.h"
+#include "lib/encoding/confline.h"
+#include "test/test.h"
#ifdef HAVE_UTIME_H
#include <utime.h>
@@ -281,7 +283,7 @@ test_storagedir_save_labeled(void *arg)
int r = storage_dir_save_labeled_to_file(d, labels, inp, 8192, &fname);
tt_int_op(r, OP_EQ, 0);
- size_t n;
+ size_t n = 0;
saved = storage_dir_read(d, fname, 1, &n);
tt_assert(memchr(saved, '\0', n));
tt_str_op((char*)saved, OP_EQ, expected); /* NUL guarantees strcmp works */
@@ -372,4 +374,3 @@ struct testcase_t storagedir_tests[] = {
ENT(read_labeled),
END_OF_TESTCASES
};
-
diff --git a/src/test/test_switch_id.c b/src/test/test_switch_id.c
index fe36d8c6e6..d8a1d15e4e 100644
--- a/src/test/test_switch_id.c
+++ b/src/test/test_switch_id.c
@@ -1,11 +1,15 @@
-/* Copyright (c) 2015-2017, The Tor Project, Inc. */
+/* Copyright (c) 2015-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
-#include "or.h"
+#include "core/or/or.h"
+#include "lib/process/setuid.h"
#ifdef HAVE_SYS_CAPABILITY_H
#include <sys/capability.h>
#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
#define TEST_BUILT_WITH_CAPS 0
#define TEST_HAVE_CAPS 1
@@ -189,4 +193,3 @@ main(int argc, char **argv)
return (okay ? 0 : 1);
#endif /* defined(_WIN32) */
}
-
diff --git a/src/test/test_threads.c b/src/test/test_threads.c
index ed6d8f04aa..2bf5026061 100644
--- a/src/test/test_threads.c
+++ b/src/test/test_threads.c
@@ -1,12 +1,12 @@
/* Copyright (c) 2001-2004, Roger Dingledine.
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2017, The Tor Project, Inc. */
+ * Copyright (c) 2007-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
#include "orconfig.h"
-#include "or.h"
-#include "compat_threads.h"
-#include "test.h"
+#include "core/or/or.h"
+#include "lib/thread/threads.h"
+#include "test/test.h"
/** mutex for thread test to stop the threads hitting data at the same time. */
static tor_mutex_t *thread_test_mutex_ = NULL;
@@ -234,25 +234,33 @@ test_threads_conditionvar(void *arg)
if (timeout) {
ti->tv = &msec100;
}
+
+#define SPIN_UNTIL(condition,sleep_msec) \
+ while (1) { \
+ tor_mutex_acquire(ti->mutex); \
+ if (condition) { \
+ break; \
+ } \
+ tor_mutex_release(ti->mutex); \
+ tor_sleep_msec(sleep_msec); \
+ }
+
spawn_func(cv_test_thr_fn_, ti);
spawn_func(cv_test_thr_fn_, ti);
spawn_func(cv_test_thr_fn_, ti);
spawn_func(cv_test_thr_fn_, ti);
- tor_mutex_acquire(ti->mutex);
+ SPIN_UNTIL(ti->n_threads == 4, 10);
+
+ time_t started_at = time(NULL);
+
ti->addend = 7;
ti->shutdown = 1;
tor_cond_signal_one(ti->cond);
tor_mutex_release(ti->mutex);
#define SPIN() \
- while (1) { \
- tor_mutex_acquire(ti->mutex); \
- if (ti->addend == 0) { \
- break; \
- } \
- tor_mutex_release(ti->mutex); \
- }
+ SPIN_UNTIL(ti->addend == 0, 0)
SPIN();
@@ -279,8 +287,9 @@ test_threads_conditionvar(void *arg)
if (!timeout) {
tt_int_op(ti->n_shutdown, OP_EQ, 4);
} else {
- tor_sleep_msec(200);
- tor_mutex_acquire(ti->mutex);
+ const int GIVE_UP_AFTER_SEC = 30;
+ SPIN_UNTIL((ti->n_timeouts == 2 ||
+ time(NULL) >= started_at + GIVE_UP_AFTER_SEC), 10);
tt_int_op(ti->n_shutdown, OP_EQ, 2);
tt_int_op(ti->n_timeouts, OP_EQ, 2);
tor_mutex_release(ti->mutex);
@@ -301,4 +310,3 @@ struct testcase_t thread_tests[] = {
&passthrough_setup, (void*)"tv" },
END_OF_TESTCASES
};
-
diff --git a/src/test/test_tortls.c b/src/test/test_tortls.c
index a661eb5c5d..79b52437f8 100644
--- a/src/test/test_tortls.c
+++ b/src/test/test_tortls.c
@@ -1,8 +1,8 @@
-/* Copyright (c) 2010-2017, The Tor Project, Inc. */
+/* Copyright (c) 2010-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
#define TORTLS_PRIVATE
-#define TORTLS_OPENSSL_PRIVATE
+#define TOR_X509_PRIVATE
#define LOG_PRIVATE
#include "orconfig.h"
@@ -10,60 +10,138 @@
#include <winsock2.h>
#endif
#include <math.h>
+#include <stddef.h>
-#include "compat.h"
+#include "lib/cc/compat_compiler.h"
-/* Some versions of OpenSSL declare SSL_get_selected_srtp_profile twice in
- * srtp.h. Suppress the GCC warning so we can build with -Wredundant-decl. */
-DISABLE_GCC_WARNING(redundant-decls)
+#include "core/or/or.h"
+#include "lib/log/log.h"
+#include "app/config/config.h"
+#include "lib/crypt_ops/compat_openssl.h"
+#include "lib/tls/x509.h"
+#include "lib/tls/x509_internal.h"
+#include "lib/tls/tortls.h"
+#include "lib/tls/tortls_st.h"
+#include "lib/tls/tortls_internal.h"
+#include "lib/encoding/pem.h"
+#include "app/config/or_state_st.h"
-#include <openssl/opensslv.h>
+#include "test/test.h"
+#include "test/log_test_helpers.h"
+#include "test/test_tortls.h"
-#include <openssl/ssl.h>
-#include <openssl/ssl3.h>
-#include <openssl/err.h>
-#include <openssl/asn1t.h>
-#include <openssl/x509.h>
-#include <openssl/rsa.h>
-#include <openssl/evp.h>
-#include <openssl/bn.h>
+#include "tinytest.h"
-ENABLE_GCC_WARNING(redundant-decls)
-
-#include "or.h"
-#include "torlog.h"
-#include "config.h"
-#include "tortls.h"
-
-#include "test.h"
-#include "log_test_helpers.h"
-#define NS_MODULE tortls
+const char* notCompletelyValidCertString =
+ "-----BEGIN CERTIFICATE-----\n"
+ "MIICVjCCAb8CAg37MA0GCSqGSIb3DQEBBQUAMIGbMQswCQYDVQQGEwJKUDEOMAwG\n"
+ "A1UECBMFVG9reW8xEDAOBgNVBAcTB0NodW8ta3UxETAPBgNVBAoTCEZyYW5rNERE\n"
+ "MRgwFgYDVQQLEw9XZWJDZXJ0IFN1cHBvcnQxGDAWBgNVBAMTD0ZyYW5rNEREIFdl\n"
+ "YiBDQTEjMCEGCSqGSIb3DQEJARYUc3VwcG9ydEBmcmFuazRkZC5jb20wHhcNMTIw\n"
+ "ODIyMDUyNzIzWhcNMTcwODIxMDUyNzIzWjBKMQswCQYDVQQGEwJKUDEOMAwGA1UE\n"
+ "CAwFVG9reW8xETAPBgNVBAoMCEZyYW5rNEREMRgwFgYDVQQDDA93d3cuZXhhbXBs\n"
+ "ZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMYBBrx5PlP0WNI/ZdzD\n"
+ "+6Pktmurn+F2kQYbtc7XQh8/LTBvCo+P6iZoLEmUA9e7EXLRxgU1CVqeAi7QcAn9\n"
+ "MwBlc8ksFJHB0rtf9pmf8Oza9E0Bynlq/4/Kb1x+d+AyhL7oK9tQwB24uHOueHi1\n"
+ "C/iVv8CSWKiYe6hzN1txYe8rAgMBAAEwDQYJKoZIhvcNAQEFBQADgYEAASPdjigJ\n"
+ "kXCqKWpnZ/Oc75EUcMi6HztaW8abUMlYXPIgkV2F7YanHOB7K4f7OOLjiz8DTPFf\n"
+ "jC9UeuErhaA/zzWi8ewMTFZW/WshOrm3fNvcMrMLKtH534JKvcdMg6qIdjTFINIr\n"
+ "evnAhf0cwULaebn+lMs8Pdl7y37+sfluVok=\n"
+ "-----END CERTIFICATE-----\n";
-#ifndef HAVE_SSL_STATE
-#define OPENSSL_OPAQUE
-#endif
+const char* validCertString = "-----BEGIN CERTIFICATE-----\n"
+ "MIIDpTCCAY0CAg3+MA0GCSqGSIb3DQEBBQUAMF4xCzAJBgNVBAYTAlVTMREwDwYD\n"
+ "VQQIDAhJbGxpbm9pczEQMA4GA1UEBwwHQ2hpY2FnbzEUMBIGA1UECgwLVG9yIFRl\n"
+ "c3RpbmcxFDASBgNVBAMMC1RvciBUZXN0aW5nMB4XDTE1MDkwNjEzMzk1OVoXDTQz\n"
+ "MDEyMjEzMzk1OVowVjELMAkGA1UEBhMCVVMxEDAOBgNVBAcMB0NoaWNhZ28xFDAS\n"
+ "BgNVBAoMC1RvciBUZXN0aW5nMR8wHQYDVQQDDBZ0ZXN0aW5nLnRvcnByb2plY3Qu\n"
+ "b3JnMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDoT6uyVVhWyOF3wkHjjYbd\n"
+ "nKaykyRv4JVtKQdZ4OpEErmX1zw4MmyzpQNV6iR4bQnWiyLfzyVJMZDIC/WILBfX\n"
+ "w2Pza/yuLgUvDc3twMuhOACzOQVO8PrEF/aVv2+hbCCy2udXvKhnYn+CCXl3ozc8\n"
+ "XcKYvujTXDyvGWY3xwAjlQIDAQABMA0GCSqGSIb3DQEBBQUAA4ICAQCUvnhzQWuQ\n"
+ "MrN+pERkE+zcTI/9dGS90rUMMLgu8VDNqTa0TUQh8uO0EQ6uDvI8Js6e8tgwS0BR\n"
+ "UBahqb7ZHv+rejGCBr5OudqD+x4STiiuPNJVs86JTLN8SpM9CHjIBH5WCCN2KOy3\n"
+ "mevNoRcRRyYJzSFULCunIK6FGulszigMYGscrO4oiTkZiHPh9KvWT40IMiHfL+Lw\n"
+ "EtEWiLex6064LcA2YQ1AMuSZyCexks63lcfaFmQbkYOKqXa1oLkIRuDsOaSVjTfe\n"
+ "vec+X6jvf12cFTKS5WIeqkKF2Irt+dJoiHEGTe5RscUMN/f+gqHPzfFz5dR23sxo\n"
+ "g+HC6MZHlFkLAOx3wW6epPS8A/m1mw3zMPoTnb2U2YYt8T0dJMMlUn/7Y1sEAa+a\n"
+ "dSTMaeUf6VnJ//11m454EZl1to9Z7oJOgqmFffSrdD4BGIWe8f7hhW6L1Enmqe/J\n"
+ "BKL3wbzZh80O1W0bndAwhnEEhlzneFY84cbBo9pmVxpODHkUcStpr5Z7pBDrcL21\n"
+ "Ss/aB/1YrsVXhdvJdOGxl3Mnl9dUY57CympLGlT8f0pPS6GAKOelECOhFMHmJd8L\n"
+ "dj3XQSmKtYHevZ6IvuMXSlB/fJvSjSlkCuLo5+kJoaqPuRu+i/S1qxeRy3CBwmnE\n"
+ "LdSNdcX4N79GQJ996PA8+mUCQG7YRtK+WA==\n"
+ "-----END CERTIFICATE-----\n";
-#if defined(OPENSSL_OPAQUE) && !defined(LIBRESSL_VERSION_NUMBER)
-#define SSL_STATE_STR "before SSL initialization"
-#else
-#define SSL_STATE_STR "before/accept initialization"
-#endif
+const char* caCertString = "-----BEGIN CERTIFICATE-----\n"
+ "MIIFjzCCA3egAwIBAgIJAKd5WgyfPMYRMA0GCSqGSIb3DQEBCwUAMF4xCzAJBgNV\n"
+ "BAYTAlVTMREwDwYDVQQIDAhJbGxpbm9pczEQMA4GA1UEBwwHQ2hpY2FnbzEUMBIG\n"
+ "A1UECgwLVG9yIFRlc3RpbmcxFDASBgNVBAMMC1RvciBUZXN0aW5nMB4XDTE1MDkw\n"
+ "NjEzMzc0MVoXDTQzMDEyMjEzMzc0MVowXjELMAkGA1UEBhMCVVMxETAPBgNVBAgM\n"
+ "CElsbGlub2lzMRAwDgYDVQQHDAdDaGljYWdvMRQwEgYDVQQKDAtUb3IgVGVzdGlu\n"
+ "ZzEUMBIGA1UEAwwLVG9yIFRlc3RpbmcwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw\n"
+ "ggIKAoICAQCpLMUEiLW5leUgBZoEJms2V7lZRhIAjnJBhVMHD0e3UubNknmaQoxf\n"
+ "ARz3rvqOaRd0JlV+qM9qE0DjiYcCVP1cAfqAo9d83uS1vwY3YMVJzADlaIiHfyVW\n"
+ "uEgBy0vvkeUBqaua24dYlcwsemOiXYLu41yM1wkcGHW1AhBNHppY6cznb8TyLgNM\n"
+ "2x3SGUdzc5XMyAFx51faKGBA3wjs+Hg1PLY7d30nmCgEOBavpm5I1disM/0k+Mcy\n"
+ "YmAKEo/iHJX/rQzO4b9znP69juLlR8PDBUJEVIG/CYb6+uw8MjjUyiWXYoqfVmN2\n"
+ "hm/lH8b6rXw1a2Aa3VTeD0DxaWeacMYHY/i01fd5n7hCoDTRNdSw5KJ0L3Z0SKTu\n"
+ "0lzffKzDaIfyZGlpW5qdouACkWYzsaitQOePVE01PIdO30vUfzNTFDfy42ccx3Di\n"
+ "59UCu+IXB+eMtrBfsok0Qc63vtF1linJgjHW1z/8ujk8F7/qkOfODhk4l7wngc2A\n"
+ "EmwWFIFoGaiTEZHB9qteXr4unbXZ0AHpM02uGGwZEGohjFyebEb73M+J57WKKAFb\n"
+ "PqbLcGUksL1SHNBNAJcVLttX55sO4nbidOS/kA3m+F1R04MBTyQF9qA6YDDHqdI3\n"
+ "h/3pw0Z4fxVouTYT4/NfRnX4JTP4u+7Mpcoof28VME0qWqD1LnRhFQIDAQABo1Aw\n"
+ "TjAdBgNVHQ4EFgQUMoAgIXH7pZ3QMRwTjT+DM9Yo/v0wHwYDVR0jBBgwFoAUMoAg\n"
+ "IXH7pZ3QMRwTjT+DM9Yo/v0wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOC\n"
+ "AgEAUJxacjXR9sT+Xs6ISFiUsyd0T6WVKMnV46xrYJHirGfx+krWHrjxMY+ZtxYD\n"
+ "DBDGlo11Qc4v6QrclNf5QUBfIiGQsP9Cm6hHcQ+Tpg9HHCgSqG1YNPwCPReCR4br\n"
+ "BLvLfrfkcBL2IWM0PdQdCze+59DBfipsULD2mEn9fjYRXQEwb2QWtQ9qRc20Yb/x\n"
+ "Q4b/+CvUodLkaq7B8MHz0BV8HHcBoph6DYaRmO/N+hPauIuSp6XyaGYcEefGKVKj\n"
+ "G2+fcsdyXsoijNdL8vNKwm4j2gVwCBnw16J00yfFoV46YcbfqEdJB2je0XSvwXqt\n"
+ "14AOTngxso2h9k9HLtrfpO1ZG/B5AcCMs1lzbZ2fp5DPHtjvvmvA2RJqgo3yjw4W\n"
+ "4DHAuTglYFlC3mDHNfNtcGP20JvepcQNzNP2UzwcpOc94hfKikOFw+gf9Vf1qd0y\n"
+ "h/Sk6OZHn2+JVUPiWHIQV98Vtoh4RmUZDJD+b55ia3fQGTGzt4z1XFzQYSva5sfs\n"
+ "wocS/papthqWldQU7x+3wofNd5CNU1x6WKXG/yw30IT/4F8ADJD6GeygNT8QJYvt\n"
+ "u/8lAkbOy6B9xGmSvr0Kk1oq9P2NshA6kalxp1Oz/DTNDdL4AeBXV3JmM6WWCjGn\n"
+ "Yy1RT69d0rwYc5u/vnqODz1IjvT90smsrkBumGt791FAFeg=\n"
+ "-----END CERTIFICATE-----\n";
-#ifndef OPENSSL_OPAQUE
-static SSL_METHOD *
-give_me_a_test_method(void)
+tor_x509_cert_impl_t *
+read_cert_from(const char *str)
{
- SSL_METHOD *method = tor_malloc_zero(sizeof(SSL_METHOD));
- memcpy(method, TLSv1_method(), sizeof(SSL_METHOD));
- return method;
+ size_t len = strlen(str);
+ uint8_t *raw_cert = tor_malloc(len);
+ ssize_t true_len = pem_decode(raw_cert, len, str, len, "CERTIFICATE");
+ if (true_len < 0) {
+ tor_free(raw_cert);
+ return NULL;
+ }
+ tor_x509_cert_t *cert = tor_x509_cert_decode(raw_cert, true_len);
+ tor_free(raw_cert);
+ if (! cert) {
+ return NULL;
+ }
+ tor_x509_cert_impl_t *res = tor_x509_cert_impl_dup_(cert->cert);
+ tor_x509_cert_free(cert);
+ return res;
}
-static int
-fake_num_ciphers(void)
+static tor_x509_cert_impl_t *
+ fixed_try_to_extract_certs_from_tls_cert_out_result = NULL;
+static tor_x509_cert_impl_t *
+ fixed_try_to_extract_certs_from_tls_id_cert_out_result = NULL;
+
+static void
+fixed_try_to_extract_certs_from_tls(int severity, tor_tls_t *tls,
+ tor_x509_cert_impl_t **cert_out,
+ tor_x509_cert_impl_t **id_cert_out)
{
- return 0;
+ (void) severity;
+ (void) tls;
+ *cert_out = tor_x509_cert_impl_dup_(
+ fixed_try_to_extract_certs_from_tls_cert_out_result);
+ *id_cert_out = tor_x509_cert_impl_dup_(
+ fixed_try_to_extract_certs_from_tls_id_cert_out_result);
}
-#endif /* !defined(OPENSSL_OPAQUE) */
static void
test_tortls_errno_to_tls_error(void *data)
@@ -107,6 +185,7 @@ test_tortls_err_to_string(void *data)
(void)1;
}
+#ifdef ENABLE_OPENSSL
static int
mock_tls_cert_matches_key(const tor_tls_t *tls, const tor_x509_cert_t *cert)
{
@@ -116,66 +195,6 @@ mock_tls_cert_matches_key(const tor_tls_t *tls, const tor_x509_cert_t *cert)
}
static void
-test_tortls_tor_tls_new(void *data)
-{
- (void) data;
- MOCK(tor_tls_cert_matches_key, mock_tls_cert_matches_key);
- crypto_pk_t *key1 = NULL, *key2 = NULL;
- SSL_METHOD *method = NULL;
-
- key1 = pk_generate(2);
- key2 = pk_generate(3);
-
- tor_tls_t *tls = NULL;
- tt_int_op(tor_tls_context_init(TOR_TLS_CTX_IS_PUBLIC_SERVER,
- key1, key2, 86400), OP_EQ, 0);
- tls = tor_tls_new(-1, 0);
- tt_want(tls);
- tor_tls_free(tls); tls = NULL;
-
- SSL_CTX_free(client_tls_context->ctx);
- client_tls_context->ctx = NULL;
- tls = tor_tls_new(-1, 0);
- tt_ptr_op(tls, OP_EQ, NULL);
-
-#ifndef OPENSSL_OPAQUE
- method = give_me_a_test_method();
- SSL_CTX *ctx = SSL_CTX_new(method);
- method->num_ciphers = fake_num_ciphers;
- client_tls_context->ctx = ctx;
- tls = tor_tls_new(-1, 0);
- tt_ptr_op(tls, OP_EQ, NULL);
-#endif /* !defined(OPENSSL_OPAQUE) */
-
- done:
- UNMOCK(tor_tls_cert_matches_key);
- crypto_pk_free(key1);
- crypto_pk_free(key2);
- tor_tls_free(tls);
- tor_free(method);
- tor_tls_free_all();
-}
-
-#define NS_MODULE tortls
-NS_DECL(void, logv, (int severity, log_domain_mask_t domain,
- const char *funcname, const char *suffix,
- const char *format, va_list ap));
-
-static void
-NS(logv)(int severity, log_domain_mask_t domain,
- const char *funcname, const char *suffix, const char *format,
- va_list ap)
-{
- (void) severity;
- (void) domain;
- (void) funcname;
- (void) suffix;
- (void) format;
- (void) ap; // XXXX look at this.
- CALLED(logv)++;
-}
-
-static void
test_tortls_tor_tls_get_error(void *data)
{
(void) data;
@@ -188,11 +207,10 @@ test_tortls_tor_tls_get_error(void *data)
tt_int_op(tor_tls_context_init(TOR_TLS_CTX_IS_PUBLIC_SERVER,
key1, key2, 86400), OP_EQ, 0);
tls = tor_tls_new(-1, 0);
- NS_MOCK(logv);
- tt_int_op(CALLED(logv), OP_EQ, 0);
+ setup_capture_of_logs(LOG_WARN);
tor_tls_get_error(tls, 0, 0,
- (const char *)"test", 0, 0);
- tt_int_op(CALLED(logv), OP_EQ, 1);
+ (const char *)"in unit test", LOG_WARN, LD_GENERAL);
+ expect_single_log_msg_containing("unexpected close while in unit test");
done:
UNMOCK(tor_tls_cert_matches_key);
@@ -201,326 +219,7 @@ test_tortls_tor_tls_get_error(void *data)
crypto_pk_free(key2);
tor_tls_free(tls);
}
-
-static void
-test_tortls_get_state_description(void *ignored)
-{
- (void)ignored;
- tor_tls_t *tls;
- char *buf;
- SSL_CTX *ctx;
-
- SSL_library_init();
- SSL_load_error_strings();
-
- ctx = SSL_CTX_new(SSLv23_method());
-
- buf = tor_malloc_zero(1000);
- tls = tor_malloc_zero(sizeof(tor_tls_t));
-
- tor_tls_get_state_description(NULL, buf, 20);
- tt_str_op(buf, OP_EQ, "(No SSL object)");
-
- SSL_free(tls->ssl);
- tls->ssl = NULL;
- tor_tls_get_state_description(tls, buf, 20);
- tt_str_op(buf, OP_EQ, "(No SSL object)");
-
- tls->ssl = SSL_new(ctx);
- tor_tls_get_state_description(tls, buf, 200);
- tt_str_op(buf, OP_EQ, SSL_STATE_STR " in HANDSHAKE");
-
- tls->state = TOR_TLS_ST_OPEN;
- tor_tls_get_state_description(tls, buf, 200);
- tt_str_op(buf, OP_EQ, SSL_STATE_STR " in OPEN");
-
- tls->state = TOR_TLS_ST_GOTCLOSE;
- tor_tls_get_state_description(tls, buf, 200);
- tt_str_op(buf, OP_EQ, SSL_STATE_STR " in GOTCLOSE");
-
- tls->state = TOR_TLS_ST_SENTCLOSE;
- tor_tls_get_state_description(tls, buf, 200);
- tt_str_op(buf, OP_EQ, SSL_STATE_STR " in SENTCLOSE");
-
- tls->state = TOR_TLS_ST_CLOSED;
- tor_tls_get_state_description(tls, buf, 200);
- tt_str_op(buf, OP_EQ, SSL_STATE_STR " in CLOSED");
-
- tls->state = TOR_TLS_ST_RENEGOTIATE;
- tor_tls_get_state_description(tls, buf, 200);
- tt_str_op(buf, OP_EQ, SSL_STATE_STR " in RENEGOTIATE");
-
- tls->state = TOR_TLS_ST_BUFFEREVENT;
- tor_tls_get_state_description(tls, buf, 200);
- tt_str_op(buf, OP_EQ, SSL_STATE_STR);
-
- tls->state = 7;
- tor_tls_get_state_description(tls, buf, 200);
- tt_str_op(buf, OP_EQ, SSL_STATE_STR " in unknown TLS state");
-
- done:
- SSL_CTX_free(ctx);
- SSL_free(tls->ssl);
- tor_free(buf);
- tor_free(tls);
-}
-
-static void
-test_tortls_get_by_ssl(void *ignored)
-{
- (void)ignored;
- tor_tls_t *tls;
- tor_tls_t *res;
- SSL_CTX *ctx;
- SSL *ssl;
-
- SSL_library_init();
- SSL_load_error_strings();
- tor_tls_allocate_tor_tls_object_ex_data_index();
-
- ctx = SSL_CTX_new(SSLv23_method());
- tls = tor_malloc_zero(sizeof(tor_tls_t));
- tls->magic = TOR_TLS_MAGIC;
-
- ssl = SSL_new(ctx);
-
- res = tor_tls_get_by_ssl(ssl);
- tt_assert(!res);
-
- SSL_set_ex_data(ssl, tor_tls_object_ex_data_index, tls);
-
- res = tor_tls_get_by_ssl(ssl);
- tt_assert(res == tls);
-
- done:
- SSL_free(ssl);
- SSL_CTX_free(ctx);
- tor_free(tls);
-}
-
-static void
-test_tortls_allocate_tor_tls_object_ex_data_index(void *ignored)
-{
- (void)ignored;
- int first;
-
- tor_tls_allocate_tor_tls_object_ex_data_index();
-
- first = tor_tls_object_ex_data_index;
- tor_tls_allocate_tor_tls_object_ex_data_index();
- tt_int_op(first, OP_EQ, tor_tls_object_ex_data_index);
-
- done:
- (void)0;
-}
-
-static void
-test_tortls_log_one_error(void *ignored)
-{
- (void)ignored;
- tor_tls_t *tls;
- SSL_CTX *ctx;
- SSL *ssl = NULL;
-
- SSL_library_init();
- SSL_load_error_strings();
-
- ctx = SSL_CTX_new(SSLv23_method());
- tls = tor_malloc_zero(sizeof(tor_tls_t));
- setup_capture_of_logs(LOG_INFO);
-
- tor_tls_log_one_error(NULL, 0, LOG_WARN, 0, "something");
- expect_log_msg("TLS error while something: "
- "(null) (in (null):(null):---)\n");
-
- mock_clean_saved_logs();
- tor_tls_log_one_error(tls, 0, LOG_WARN, 0, NULL);
- expect_log_msg("TLS error: (null) "
- "(in (null):(null):---)\n");
-
- mock_clean_saved_logs();
- tls->address = tor_strdup("127.hello");
- tor_tls_log_one_error(tls, 0, LOG_WARN, 0, NULL);
- expect_log_msg("TLS error with 127.hello: "
- "(null) (in (null):(null):---)\n");
- tor_free(tls->address);
-
- mock_clean_saved_logs();
- tls->address = tor_strdup("127.hello");
- tor_tls_log_one_error(tls, 0, LOG_WARN, 0, "blarg");
- expect_log_msg("TLS error while blarg with "
- "127.hello: (null) (in (null):(null):---)\n");
-
- mock_clean_saved_logs();
- tor_tls_log_one_error(tls, ERR_PACK(1, 2, 3), LOG_WARN, 0, NULL);
- expect_log_msg("TLS error with 127.hello: "
- "BN lib (in unknown library:(null):---)\n");
-
- mock_clean_saved_logs();
- tor_tls_log_one_error(tls, ERR_PACK(1, 2, SSL_R_HTTP_REQUEST),
- LOG_WARN, 0, NULL);
- expect_log_severity(LOG_INFO);
-
- mock_clean_saved_logs();
- tor_tls_log_one_error(tls, ERR_PACK(1, 2, SSL_R_HTTPS_PROXY_REQUEST),
- LOG_WARN, 0, NULL);
- expect_log_severity(LOG_INFO);
-
- mock_clean_saved_logs();
- tor_tls_log_one_error(tls, ERR_PACK(1, 2, SSL_R_RECORD_LENGTH_MISMATCH),
- LOG_WARN, 0, NULL);
- expect_log_severity(LOG_INFO);
-
-#ifndef OPENSSL_1_1_API
- mock_clean_saved_logs();
- tor_tls_log_one_error(tls, ERR_PACK(1, 2, SSL_R_RECORD_TOO_LARGE),
- LOG_WARN, 0, NULL);
- expect_log_severity(LOG_INFO);
-#endif /* !defined(OPENSSL_1_1_API) */
-
- mock_clean_saved_logs();
- tor_tls_log_one_error(tls, ERR_PACK(1, 2, SSL_R_UNKNOWN_PROTOCOL),
- LOG_WARN, 0, NULL);
- expect_log_severity(LOG_INFO);
-
- mock_clean_saved_logs();
- tor_tls_log_one_error(tls, ERR_PACK(1, 2, SSL_R_UNSUPPORTED_PROTOCOL),
- LOG_WARN, 0, NULL);
- expect_log_severity(LOG_INFO);
-
- tls->ssl = SSL_new(ctx);
-
- mock_clean_saved_logs();
- tor_tls_log_one_error(tls, 0, LOG_WARN, 0, NULL);
- expect_log_msg("TLS error with 127.hello: (null)"
- " (in (null):(null):" SSL_STATE_STR ")\n");
-
- done:
- teardown_capture_of_logs();
- SSL_free(ssl);
- SSL_CTX_free(ctx);
- if (tls && tls->ssl)
- SSL_free(tls->ssl);
- if (tls)
- tor_free(tls->address);
- tor_free(tls);
-}
-
-#ifndef OPENSSL_OPAQUE
-static void
-test_tortls_get_error(void *ignored)
-{
- (void)ignored;
- tor_tls_t *tls;
- int ret;
- SSL_CTX *ctx;
-
- SSL_library_init();
- SSL_load_error_strings();
-
- ctx = SSL_CTX_new(SSLv23_method());
- setup_capture_of_logs(LOG_INFO);
- tls = tor_malloc_zero(sizeof(tor_tls_t));
- tls->ssl = SSL_new(ctx);
- SSL_set_bio(tls->ssl, BIO_new(BIO_s_mem()), NULL);
-
- ret = tor_tls_get_error(tls, 0, 0, "something", LOG_WARN, 0);
- tt_int_op(ret, OP_EQ, TOR_TLS_ERROR_IO);
- expect_log_msg("TLS error: unexpected close while"
- " something (before/accept initialization)\n");
-
- mock_clean_saved_logs();
- ret = tor_tls_get_error(tls, 2, 0, "something", LOG_WARN, 0);
- tt_int_op(ret, OP_EQ, 0);
- expect_no_log_entry();
-
- mock_clean_saved_logs();
- ret = tor_tls_get_error(tls, 0, 1, "something", LOG_WARN, 0);
- tt_int_op(ret, OP_EQ, -11);
- expect_no_log_entry();
-
- mock_clean_saved_logs();
- ERR_clear_error();
- ERR_put_error(ERR_LIB_BN, 2, -1, "somewhere.c", 99);
- ret = tor_tls_get_error(tls, 0, 0, "something", LOG_WARN, 0);
- tt_int_op(ret, OP_EQ, TOR_TLS_ERROR_MISC);
- expect_log_msg("TLS error while something: (null)"
- " (in bignum routines:(null):before/accept initialization)\n");
-
- mock_clean_saved_logs();
- ERR_clear_error();
- tls->ssl->rwstate = SSL_READING;
- SSL_get_rbio(tls->ssl)->flags = BIO_FLAGS_READ;
- ret = tor_tls_get_error(tls, -1, 0, "something", LOG_WARN, 0);
- tt_int_op(ret, OP_EQ, TOR_TLS_WANTREAD);
- expect_no_log_entry();
-
- mock_clean_saved_logs();
- ERR_clear_error();
- tls->ssl->rwstate = SSL_READING;
- SSL_get_rbio(tls->ssl)->flags = BIO_FLAGS_WRITE;
- ret = tor_tls_get_error(tls, -1, 0, "something", LOG_WARN, 0);
- tt_int_op(ret, OP_EQ, TOR_TLS_WANTWRITE);
- expect_no_log_entry();
-
- mock_clean_saved_logs();
- ERR_clear_error();
- tls->ssl->rwstate = 0;
- tls->ssl->shutdown = SSL_RECEIVED_SHUTDOWN;
- tls->ssl->s3->warn_alert =SSL_AD_CLOSE_NOTIFY;
- ret = tor_tls_get_error(tls, 0, 0, "something", LOG_WARN, 0);
- tt_int_op(ret, OP_EQ, TOR_TLS_CLOSE);
- expect_log_entry();
-
- mock_clean_saved_logs();
- ret = tor_tls_get_error(tls, 0, 2, "something", LOG_WARN, 0);
- tt_int_op(ret, OP_EQ, -10);
- expect_no_log_entry();
-
- mock_clean_saved_logs();
- ERR_put_error(ERR_LIB_SYS, 2, -1, "somewhere.c", 99);
- ret = tor_tls_get_error(tls, -1, 0, "something", LOG_WARN, 0);
- tt_int_op(ret, OP_EQ, -9);
- expect_log_msg("TLS error while something: (null) (in system library:"
- "connect:before/accept initialization)\n");
-
- done:
- teardown_capture_of_logs();
- SSL_free(tls->ssl);
- tor_free(tls);
- SSL_CTX_free(ctx);
-}
-#endif /* !defined(OPENSSL_OPAQUE) */
-
-static void
-test_tortls_always_accept_verify_cb(void *ignored)
-{
- (void)ignored;
- int ret;
-
- ret = always_accept_verify_cb(0, NULL);
- tt_int_op(ret, OP_EQ, 1);
-
- done:
- (void)0;
-}
-
-#ifndef OPENSSL_OPAQUE
-static void
-test_tortls_x509_cert_free(void *ignored)
-{
- (void)ignored;
- tor_x509_cert_t *cert;
-
- cert = tor_malloc_zero(sizeof(tor_x509_cert_t));
- tor_x509_cert_free(cert);
-
- cert = tor_malloc_zero(sizeof(tor_x509_cert_t));
- cert->cert = tor_malloc_zero(sizeof(X509));
- cert->encoded = tor_malloc_zero(1);
- tor_x509_cert_free(cert);
-}
-#endif /* !defined(OPENSSL_OPAQUE) */
+#endif
static void
test_tortls_x509_cert_get_id_digests(void *ignored)
@@ -539,6 +238,7 @@ test_tortls_x509_cert_get_id_digests(void *ignored)
cert->pkey_digests_set = 1;
cert->pkey_digests = *d;
res = tor_x509_cert_get_id_digests(cert);
+ tt_assert(res);
tt_int_op(res->d[0][0], OP_EQ, 42);
done:
@@ -546,152 +246,6 @@ test_tortls_x509_cert_get_id_digests(void *ignored)
tor_free(d);
}
-#ifndef OPENSSL_OPAQUE
-static void
-fake_x509_free(X509 *cert)
-{
- if (cert) {
- if (cert->cert_info) {
- if (cert->cert_info->key) {
- if (cert->cert_info->key->pkey) {
- tor_free(cert->cert_info->key->pkey);
- }
- tor_free(cert->cert_info->key);
- }
- tor_free(cert->cert_info);
- }
- tor_free(cert);
- }
-}
-#endif
-
-static tor_x509_cert_t *fixed_x509_cert = NULL;
-static tor_x509_cert_t *
-get_peer_cert_mock_return_fixed(tor_tls_t *tls)
-{
- (void)tls;
- if (fixed_x509_cert)
- return tor_x509_cert_dup(fixed_x509_cert);
- else
- return NULL;
-}
-
-static void
-test_tortls_cert_matches_key(void *ignored)
-{
- (void)ignored;
-
- X509 *cert1 = NULL, *cert2 = NULL, *cert3 = NULL, *cert4 = NULL;
- tor_x509_cert_t *c1 = NULL, *c2 = NULL, *c3 = NULL, *c4 = NULL;
- crypto_pk_t *k1 = NULL, *k2 = NULL, *k3 = NULL;
-
- k1 = pk_generate(1);
- k2 = pk_generate(2);
- k3 = pk_generate(3);
-
- cert1 = tor_tls_create_certificate(k1, k2, "A", "B", 1000);
- cert2 = tor_tls_create_certificate(k1, k3, "C", "D", 1000);
- cert3 = tor_tls_create_certificate(k2, k3, "C", "D", 1000);
- cert4 = tor_tls_create_certificate(k3, k2, "E", "F", 1000);
-
- tt_assert(cert1 && cert2 && cert3 && cert4);
-
- c1 = tor_x509_cert_new(cert1); cert1 = NULL;
- c2 = tor_x509_cert_new(cert2); cert2 = NULL;
- c3 = tor_x509_cert_new(cert3); cert3 = NULL;
- c4 = tor_x509_cert_new(cert4); cert4 = NULL;
-
- tt_assert(c1 && c2 && c3 && c4);
-
- MOCK(tor_tls_get_peer_cert, get_peer_cert_mock_return_fixed);
-
- fixed_x509_cert = NULL;
- /* If the peer has no certificate, it shouldn't match anything. */
- tt_assert(! tor_tls_cert_matches_key(NULL, c1));
- tt_assert(! tor_tls_cert_matches_key(NULL, c2));
- tt_assert(! tor_tls_cert_matches_key(NULL, c3));
- tt_assert(! tor_tls_cert_matches_key(NULL, c4));
- fixed_x509_cert = c1;
- /* If the peer has a certificate, it should match every cert with the same
- * subject key. */
- tt_assert(tor_tls_cert_matches_key(NULL, c1));
- tt_assert(tor_tls_cert_matches_key(NULL, c2));
- tt_assert(! tor_tls_cert_matches_key(NULL, c3));
- tt_assert(! tor_tls_cert_matches_key(NULL, c4));
-
- done:
- tor_x509_cert_free(c1);
- tor_x509_cert_free(c2);
- tor_x509_cert_free(c3);
- tor_x509_cert_free(c4);
- if (cert1) X509_free(cert1);
- if (cert2) X509_free(cert2);
- if (cert3) X509_free(cert3);
- if (cert4) X509_free(cert4);
- crypto_pk_free(k1);
- crypto_pk_free(k2);
- crypto_pk_free(k3);
- UNMOCK(tor_tls_get_peer_cert);
-}
-
-#ifndef OPENSSL_OPAQUE
-static void
-test_tortls_cert_get_key(void *ignored)
-{
- (void)ignored;
- tor_x509_cert_t *cert = NULL;
- crypto_pk_t *res = NULL;
- cert = tor_malloc_zero(sizeof(tor_x509_cert_t));
- X509 *key = NULL;
- key = tor_malloc_zero(sizeof(X509));
- key->references = 1;
-
- res = tor_tls_cert_get_key(cert);
- tt_assert(!res);
-
- cert->cert = key;
- key->cert_info = tor_malloc_zero(sizeof(X509_CINF));
- key->cert_info->key = tor_malloc_zero(sizeof(X509_PUBKEY));
- key->cert_info->key->pkey = tor_malloc_zero(sizeof(EVP_PKEY));
- key->cert_info->key->pkey->references = 1;
- key->cert_info->key->pkey->type = 2;
- res = tor_tls_cert_get_key(cert);
- tt_assert(!res);
-
- done:
- fake_x509_free(key);
- tor_free(cert);
- crypto_pk_free(res);
-}
-#endif /* !defined(OPENSSL_OPAQUE) */
-
-static void
-test_tortls_get_my_client_auth_key(void *ignored)
-{
- (void)ignored;
- crypto_pk_t *ret;
- crypto_pk_t *expected;
- tor_tls_context_t *ctx;
- RSA *k = RSA_new();
-
- ctx = tor_malloc_zero(sizeof(tor_tls_context_t));
- expected = crypto_new_pk_from_rsa_(k);
- ctx->auth_key = expected;
-
- client_tls_context = NULL;
- ret = tor_tls_get_my_client_auth_key();
- tt_assert(!ret);
-
- client_tls_context = ctx;
- ret = tor_tls_get_my_client_auth_key();
- tt_assert(ret == expected);
-
- done:
- RSA_free(k);
- tor_free(expected);
- tor_free(ctx);
-}
-
static void
test_tortls_get_my_certs(void *ignored)
{
@@ -727,438 +281,7 @@ test_tortls_get_my_certs(void *ignored)
(void)1;
}
-#ifndef HAVE_SSL_GET_CLIENT_CIPHERS
-static SSL_CIPHER *
-get_cipher_by_name(const char *name)
-{
- int i;
- const SSL_METHOD *method = SSLv23_method();
- int num = method->num_ciphers();
-
- for (i = 0; i < num; ++i) {
- const SSL_CIPHER *cipher = method->get_cipher(i);
- const char *ciphername = SSL_CIPHER_get_name(cipher);
- if (!strcmp(ciphername, name)) {
- return (SSL_CIPHER *)cipher;
- }
- }
-
- return NULL;
-}
-#endif /* !defined(HAVE_SSL_GET_CLIENT_CIPHERS) */
-
-#ifndef OPENSSL_OPAQUE
-static void
-test_tortls_get_ciphersuite_name(void *ignored)
-{
- (void)ignored;
- const char *ret;
- tor_tls_t *ctx;
- ctx = tor_malloc_zero(sizeof(tor_tls_t));
- ctx->ssl = tor_malloc_zero(sizeof(SSL));
-
- ret = tor_tls_get_ciphersuite_name(ctx);
- tt_str_op(ret, OP_EQ, "(NONE)");
-
- done:
- tor_free(ctx->ssl);
- tor_free(ctx);
-}
-
-static SSL_CIPHER *
-get_cipher_by_id(uint16_t id)
-{
- int i;
- const SSL_METHOD *method = SSLv23_method();
- int num = method->num_ciphers();
- for (i = 0; i < num; ++i) {
- const SSL_CIPHER *cipher = method->get_cipher(i);
- if (id == (SSL_CIPHER_get_id(cipher) & 0xffff)) {
- return (SSL_CIPHER *)cipher;
- }
- }
-
- return NULL;
-}
-
-static void
-test_tortls_classify_client_ciphers(void *ignored)
-{
- (void)ignored;
- int i;
- int ret;
- SSL_CTX *ctx;
- SSL *ssl;
- tor_tls_t *tls;
- STACK_OF(SSL_CIPHER) *ciphers;
- SSL_CIPHER *tmp_cipher;
-
- SSL_library_init();
- SSL_load_error_strings();
- tor_tls_allocate_tor_tls_object_ex_data_index();
-
- tls = tor_malloc_zero(sizeof(tor_tls_t));
- tls->magic = TOR_TLS_MAGIC;
-
- ctx = SSL_CTX_new(TLSv1_method());
- ssl = SSL_new(ctx);
- tls->ssl = ssl;
-
- ciphers = sk_SSL_CIPHER_new_null();
-
- ret = tor_tls_classify_client_ciphers(ssl, NULL);
- tt_int_op(ret, OP_EQ, -1);
-
- SSL_set_ex_data(ssl, tor_tls_object_ex_data_index, tls);
- tls->client_cipher_list_type = 42;
-
- ret = tor_tls_classify_client_ciphers(ssl, NULL);
- tt_int_op(ret, OP_EQ, 42);
-
- tls->client_cipher_list_type = 0;
- ret = tor_tls_classify_client_ciphers(ssl, ciphers);
- tt_int_op(ret, OP_EQ, 1);
- tt_int_op(tls->client_cipher_list_type, OP_EQ, 1);
-
- tls->client_cipher_list_type = 0;
- ret = tor_tls_classify_client_ciphers(ssl, SSL_get_ciphers(ssl));
- tt_int_op(ret, OP_EQ, 3);
- tt_int_op(tls->client_cipher_list_type, OP_EQ, 3);
-
- SSL_CIPHER *one = get_cipher_by_name(TLS1_TXT_DHE_RSA_WITH_AES_128_SHA),
- *two = get_cipher_by_name(TLS1_TXT_DHE_RSA_WITH_AES_256_SHA),
- *three = get_cipher_by_name(SSL3_TXT_EDH_RSA_DES_192_CBC3_SHA),
- *four = NULL;
- sk_SSL_CIPHER_push(ciphers, one);
- sk_SSL_CIPHER_push(ciphers, two);
- sk_SSL_CIPHER_push(ciphers, three);
- sk_SSL_CIPHER_push(ciphers, four);
-
- tls->client_cipher_list_type = 0;
- ret = tor_tls_classify_client_ciphers(ssl, ciphers);
- tt_int_op(ret, OP_EQ, 1);
- tt_int_op(tls->client_cipher_list_type, OP_EQ, 1);
-
- sk_SSL_CIPHER_zero(ciphers);
-
- one = get_cipher_by_name("ECDHE-RSA-AES256-GCM-SHA384");
- tt_assert(one);
- one->id = 0x00ff;
- two = get_cipher_by_name("ECDHE-RSA-AES128-GCM-SHA256");
- tt_assert(two);
- two->id = 0x0000;
- sk_SSL_CIPHER_push(ciphers, one);
- tls->client_cipher_list_type = 0;
- ret = tor_tls_classify_client_ciphers(ssl, ciphers);
- tt_int_op(ret, OP_EQ, 3);
- tt_int_op(tls->client_cipher_list_type, OP_EQ, 3);
-
- sk_SSL_CIPHER_push(ciphers, two);
- tls->client_cipher_list_type = 0;
- ret = tor_tls_classify_client_ciphers(ssl, ciphers);
- tt_int_op(ret, OP_EQ, 3);
- tt_int_op(tls->client_cipher_list_type, OP_EQ, 3);
-
- one->id = 0xC00A;
- tls->client_cipher_list_type = 0;
- ret = tor_tls_classify_client_ciphers(ssl, ciphers);
- tt_int_op(ret, OP_EQ, 3);
- tt_int_op(tls->client_cipher_list_type, OP_EQ, 3);
-
- sk_SSL_CIPHER_zero(ciphers);
- for (i=0; v2_cipher_list[i]; i++) {
- tmp_cipher = get_cipher_by_id(v2_cipher_list[i]);
- tt_assert(tmp_cipher);
- sk_SSL_CIPHER_push(ciphers, tmp_cipher);
- }
- tls->client_cipher_list_type = 0;
- ret = tor_tls_classify_client_ciphers(ssl, ciphers);
- tt_int_op(ret, OP_EQ, 2);
- tt_int_op(tls->client_cipher_list_type, OP_EQ, 2);
-
- done:
- sk_SSL_CIPHER_free(ciphers);
- SSL_free(tls->ssl);
- tor_free(tls);
- SSL_CTX_free(ctx);
-}
-#endif /* !defined(OPENSSL_OPAQUE) */
-
-static void
-test_tortls_client_is_using_v2_ciphers(void *ignored)
-{
- (void)ignored;
-
-#ifdef HAVE_SSL_GET_CLIENT_CIPHERS
- tt_skip();
- done:
- (void)1;
-#else
- int ret;
- SSL_CTX *ctx;
- SSL *ssl;
- SSL_SESSION *sess;
- STACK_OF(SSL_CIPHER) *ciphers;
-
- SSL_library_init();
- SSL_load_error_strings();
-
- ctx = SSL_CTX_new(TLSv1_method());
- ssl = SSL_new(ctx);
- sess = SSL_SESSION_new();
-
- ret = tor_tls_client_is_using_v2_ciphers(ssl);
- tt_int_op(ret, OP_EQ, -1);
-
- ssl->session = sess;
- ret = tor_tls_client_is_using_v2_ciphers(ssl);
- tt_int_op(ret, OP_EQ, 0);
-
- ciphers = sk_SSL_CIPHER_new_null();
- SSL_CIPHER *one = get_cipher_by_name("ECDHE-RSA-AES256-GCM-SHA384");
- tt_assert(one);
- one->id = 0x00ff;
- sk_SSL_CIPHER_push(ciphers, one);
- sess->ciphers = ciphers;
- ret = tor_tls_client_is_using_v2_ciphers(ssl);
- tt_int_op(ret, OP_EQ, 1);
- done:
- SSL_free(ssl);
- SSL_CTX_free(ctx);
-#endif /* defined(HAVE_SSL_GET_CLIENT_CIPHERS) */
-}
-
-#ifndef OPENSSL_OPAQUE
-static X509 *fixed_try_to_extract_certs_from_tls_cert_out_result = NULL;
-static X509 *fixed_try_to_extract_certs_from_tls_id_cert_out_result = NULL;
-
-static void
-fixed_try_to_extract_certs_from_tls(int severity, tor_tls_t *tls,
- X509 **cert_out, X509 **id_cert_out)
-{
- (void) severity;
- (void) tls;
- *cert_out = fixed_try_to_extract_certs_from_tls_cert_out_result;
- *id_cert_out = fixed_try_to_extract_certs_from_tls_id_cert_out_result;
-}
-#endif /* !defined(OPENSSL_OPAQUE) */
-
-#ifndef OPENSSL_OPAQUE
-static const char* notCompletelyValidCertString =
- "-----BEGIN CERTIFICATE-----\n"
- "MIICVjCCAb8CAg37MA0GCSqGSIb3DQEBBQUAMIGbMQswCQYDVQQGEwJKUDEOMAwG\n"
- "A1UECBMFVG9reW8xEDAOBgNVBAcTB0NodW8ta3UxETAPBgNVBAoTCEZyYW5rNERE\n"
- "MRgwFgYDVQQLEw9XZWJDZXJ0IFN1cHBvcnQxGDAWBgNVBAMTD0ZyYW5rNEREIFdl\n"
- "YiBDQTEjMCEGCSqGSIb3DQEJARYUc3VwcG9ydEBmcmFuazRkZC5jb20wHhcNMTIw\n"
- "ODIyMDUyNzIzWhcNMTcwODIxMDUyNzIzWjBKMQswCQYDVQQGEwJKUDEOMAwGA1UE\n"
- "CAwFVG9reW8xETAPBgNVBAoMCEZyYW5rNEREMRgwFgYDVQQDDA93d3cuZXhhbXBs\n"
- "ZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMYBBrx5PlP0WNI/ZdzD\n"
- "+6Pktmurn+F2kQYbtc7XQh8/LTBvCo+P6iZoLEmUA9e7EXLRxgU1CVqeAi7QcAn9\n"
- "MwBlc8ksFJHB0rtf9pmf8Oza9E0Bynlq/4/Kb1x+d+AyhL7oK9tQwB24uHOueHi1\n"
- "C/iVv8CSWKiYe6hzN1txYe8rAgMBAAEwDQYJKoZIhvcNAQEFBQADgYEAASPdjigJ\n"
- "kXCqKWpnZ/Oc75EUcMi6HztaW8abUMlYXPIgkV2F7YanHOB7K4f7OOLjiz8DTPFf\n"
- "jC9UeuErhaA/zzWi8ewMTFZW/WshOrm3fNvcMrMLKtH534JKvcdMg6qIdjTFINIr\n"
- "evnAhf0cwULaebn+lMs8Pdl7y37+sfluVok=\n"
- "-----END CERTIFICATE-----\n";
-#endif /* !defined(OPENSSL_OPAQUE) */
-
-static const char* validCertString = "-----BEGIN CERTIFICATE-----\n"
- "MIIDpTCCAY0CAg3+MA0GCSqGSIb3DQEBBQUAMF4xCzAJBgNVBAYTAlVTMREwDwYD\n"
- "VQQIDAhJbGxpbm9pczEQMA4GA1UEBwwHQ2hpY2FnbzEUMBIGA1UECgwLVG9yIFRl\n"
- "c3RpbmcxFDASBgNVBAMMC1RvciBUZXN0aW5nMB4XDTE1MDkwNjEzMzk1OVoXDTQz\n"
- "MDEyMjEzMzk1OVowVjELMAkGA1UEBhMCVVMxEDAOBgNVBAcMB0NoaWNhZ28xFDAS\n"
- "BgNVBAoMC1RvciBUZXN0aW5nMR8wHQYDVQQDDBZ0ZXN0aW5nLnRvcnByb2plY3Qu\n"
- "b3JnMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDoT6uyVVhWyOF3wkHjjYbd\n"
- "nKaykyRv4JVtKQdZ4OpEErmX1zw4MmyzpQNV6iR4bQnWiyLfzyVJMZDIC/WILBfX\n"
- "w2Pza/yuLgUvDc3twMuhOACzOQVO8PrEF/aVv2+hbCCy2udXvKhnYn+CCXl3ozc8\n"
- "XcKYvujTXDyvGWY3xwAjlQIDAQABMA0GCSqGSIb3DQEBBQUAA4ICAQCUvnhzQWuQ\n"
- "MrN+pERkE+zcTI/9dGS90rUMMLgu8VDNqTa0TUQh8uO0EQ6uDvI8Js6e8tgwS0BR\n"
- "UBahqb7ZHv+rejGCBr5OudqD+x4STiiuPNJVs86JTLN8SpM9CHjIBH5WCCN2KOy3\n"
- "mevNoRcRRyYJzSFULCunIK6FGulszigMYGscrO4oiTkZiHPh9KvWT40IMiHfL+Lw\n"
- "EtEWiLex6064LcA2YQ1AMuSZyCexks63lcfaFmQbkYOKqXa1oLkIRuDsOaSVjTfe\n"
- "vec+X6jvf12cFTKS5WIeqkKF2Irt+dJoiHEGTe5RscUMN/f+gqHPzfFz5dR23sxo\n"
- "g+HC6MZHlFkLAOx3wW6epPS8A/m1mw3zMPoTnb2U2YYt8T0dJMMlUn/7Y1sEAa+a\n"
- "dSTMaeUf6VnJ//11m454EZl1to9Z7oJOgqmFffSrdD4BGIWe8f7hhW6L1Enmqe/J\n"
- "BKL3wbzZh80O1W0bndAwhnEEhlzneFY84cbBo9pmVxpODHkUcStpr5Z7pBDrcL21\n"
- "Ss/aB/1YrsVXhdvJdOGxl3Mnl9dUY57CympLGlT8f0pPS6GAKOelECOhFMHmJd8L\n"
- "dj3XQSmKtYHevZ6IvuMXSlB/fJvSjSlkCuLo5+kJoaqPuRu+i/S1qxeRy3CBwmnE\n"
- "LdSNdcX4N79GQJ996PA8+mUCQG7YRtK+WA==\n"
- "-----END CERTIFICATE-----\n";
-
-static const char* caCertString = "-----BEGIN CERTIFICATE-----\n"
- "MIIFjzCCA3egAwIBAgIJAKd5WgyfPMYRMA0GCSqGSIb3DQEBCwUAMF4xCzAJBgNV\n"
- "BAYTAlVTMREwDwYDVQQIDAhJbGxpbm9pczEQMA4GA1UEBwwHQ2hpY2FnbzEUMBIG\n"
- "A1UECgwLVG9yIFRlc3RpbmcxFDASBgNVBAMMC1RvciBUZXN0aW5nMB4XDTE1MDkw\n"
- "NjEzMzc0MVoXDTQzMDEyMjEzMzc0MVowXjELMAkGA1UEBhMCVVMxETAPBgNVBAgM\n"
- "CElsbGlub2lzMRAwDgYDVQQHDAdDaGljYWdvMRQwEgYDVQQKDAtUb3IgVGVzdGlu\n"
- "ZzEUMBIGA1UEAwwLVG9yIFRlc3RpbmcwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw\n"
- "ggIKAoICAQCpLMUEiLW5leUgBZoEJms2V7lZRhIAjnJBhVMHD0e3UubNknmaQoxf\n"
- "ARz3rvqOaRd0JlV+qM9qE0DjiYcCVP1cAfqAo9d83uS1vwY3YMVJzADlaIiHfyVW\n"
- "uEgBy0vvkeUBqaua24dYlcwsemOiXYLu41yM1wkcGHW1AhBNHppY6cznb8TyLgNM\n"
- "2x3SGUdzc5XMyAFx51faKGBA3wjs+Hg1PLY7d30nmCgEOBavpm5I1disM/0k+Mcy\n"
- "YmAKEo/iHJX/rQzO4b9znP69juLlR8PDBUJEVIG/CYb6+uw8MjjUyiWXYoqfVmN2\n"
- "hm/lH8b6rXw1a2Aa3VTeD0DxaWeacMYHY/i01fd5n7hCoDTRNdSw5KJ0L3Z0SKTu\n"
- "0lzffKzDaIfyZGlpW5qdouACkWYzsaitQOePVE01PIdO30vUfzNTFDfy42ccx3Di\n"
- "59UCu+IXB+eMtrBfsok0Qc63vtF1linJgjHW1z/8ujk8F7/qkOfODhk4l7wngc2A\n"
- "EmwWFIFoGaiTEZHB9qteXr4unbXZ0AHpM02uGGwZEGohjFyebEb73M+J57WKKAFb\n"
- "PqbLcGUksL1SHNBNAJcVLttX55sO4nbidOS/kA3m+F1R04MBTyQF9qA6YDDHqdI3\n"
- "h/3pw0Z4fxVouTYT4/NfRnX4JTP4u+7Mpcoof28VME0qWqD1LnRhFQIDAQABo1Aw\n"
- "TjAdBgNVHQ4EFgQUMoAgIXH7pZ3QMRwTjT+DM9Yo/v0wHwYDVR0jBBgwFoAUMoAg\n"
- "IXH7pZ3QMRwTjT+DM9Yo/v0wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOC\n"
- "AgEAUJxacjXR9sT+Xs6ISFiUsyd0T6WVKMnV46xrYJHirGfx+krWHrjxMY+ZtxYD\n"
- "DBDGlo11Qc4v6QrclNf5QUBfIiGQsP9Cm6hHcQ+Tpg9HHCgSqG1YNPwCPReCR4br\n"
- "BLvLfrfkcBL2IWM0PdQdCze+59DBfipsULD2mEn9fjYRXQEwb2QWtQ9qRc20Yb/x\n"
- "Q4b/+CvUodLkaq7B8MHz0BV8HHcBoph6DYaRmO/N+hPauIuSp6XyaGYcEefGKVKj\n"
- "G2+fcsdyXsoijNdL8vNKwm4j2gVwCBnw16J00yfFoV46YcbfqEdJB2je0XSvwXqt\n"
- "14AOTngxso2h9k9HLtrfpO1ZG/B5AcCMs1lzbZ2fp5DPHtjvvmvA2RJqgo3yjw4W\n"
- "4DHAuTglYFlC3mDHNfNtcGP20JvepcQNzNP2UzwcpOc94hfKikOFw+gf9Vf1qd0y\n"
- "h/Sk6OZHn2+JVUPiWHIQV98Vtoh4RmUZDJD+b55ia3fQGTGzt4z1XFzQYSva5sfs\n"
- "wocS/papthqWldQU7x+3wofNd5CNU1x6WKXG/yw30IT/4F8ADJD6GeygNT8QJYvt\n"
- "u/8lAkbOy6B9xGmSvr0Kk1oq9P2NshA6kalxp1Oz/DTNDdL4AeBXV3JmM6WWCjGn\n"
- "Yy1RT69d0rwYc5u/vnqODz1IjvT90smsrkBumGt791FAFeg=\n"
- "-----END CERTIFICATE-----\n";
-
-static X509 *
-read_cert_from(const char *str)
-{
- BIO *bio = BIO_new(BIO_s_mem());
- BIO_write(bio, str, (int) strlen(str));
- X509 *res = PEM_read_bio_X509(bio, NULL, NULL, NULL);
- BIO_free(bio);
- return res;
-}
-
-#ifndef OPENSSL_OPAQUE
-static void
-test_tortls_verify(void *ignored)
-{
- (void)ignored;
- int ret;
- tor_tls_t *tls;
- crypto_pk_t *k = NULL;
- X509 *cert1 = NULL, *cert2 = NULL, *invalidCert = NULL,
- *validCert = NULL, *caCert = NULL;
-
- cert1 = tor_malloc_zero(sizeof(X509));
- cert1->references = 10;
-
- cert2 = tor_malloc_zero(sizeof(X509));
- cert2->references = 10;
-
- validCert = read_cert_from(validCertString);
- caCert = read_cert_from(caCertString);
- invalidCert = read_cert_from(notCompletelyValidCertString);
-
- tls = tor_malloc_zero(sizeof(tor_tls_t));
- ret = tor_tls_verify(LOG_WARN, tls, &k);
- tt_int_op(ret, OP_EQ, -1);
-
- MOCK(try_to_extract_certs_from_tls, fixed_try_to_extract_certs_from_tls);
-
- fixed_try_to_extract_certs_from_tls_cert_out_result = cert1;
- ret = tor_tls_verify(LOG_WARN, tls, &k);
- tt_int_op(ret, OP_EQ, -1);
-
- fixed_try_to_extract_certs_from_tls_id_cert_out_result = cert2;
- ret = tor_tls_verify(LOG_WARN, tls, &k);
- tt_int_op(ret, OP_EQ, -1);
-
- fixed_try_to_extract_certs_from_tls_cert_out_result = invalidCert;
- fixed_try_to_extract_certs_from_tls_id_cert_out_result = invalidCert;
-
- ret = tor_tls_verify(LOG_WARN, tls, &k);
- tt_int_op(ret, OP_EQ, -1);
-
- fixed_try_to_extract_certs_from_tls_cert_out_result = validCert;
- fixed_try_to_extract_certs_from_tls_id_cert_out_result = caCert;
-
- ret = tor_tls_verify(LOG_WARN, tls, &k);
- tt_int_op(ret, OP_EQ, 0);
- tt_assert(k);
-
- done:
- UNMOCK(try_to_extract_certs_from_tls);
- tor_free(cert1);
- tor_free(cert2);
- tor_free(tls);
- tor_free(k);
-}
-#endif /* !defined(OPENSSL_OPAQUE) */
-
-#ifndef OPENSSL_OPAQUE
-static void
-test_tortls_check_lifetime(void *ignored)
-{
- (void)ignored;
- int ret;
- tor_tls_t *tls;
- X509 *validCert = read_cert_from(validCertString);
- time_t now = time(NULL);
-
- tls = tor_malloc_zero(sizeof(tor_tls_t));
- ret = tor_tls_check_lifetime(LOG_WARN, tls, time(NULL), 0, 0);
- tt_int_op(ret, OP_EQ, -1);
-
- tls->ssl = tor_malloc_zero(sizeof(SSL));
- tls->ssl->session = tor_malloc_zero(sizeof(SSL_SESSION));
- tls->ssl->session->peer = validCert;
- ret = tor_tls_check_lifetime(LOG_WARN, tls, time(NULL), 0, 0);
- tt_int_op(ret, OP_EQ, 0);
-
- ASN1_STRING_free(validCert->cert_info->validity->notBefore);
- validCert->cert_info->validity->notBefore = ASN1_TIME_set(NULL, now-10);
- ASN1_STRING_free(validCert->cert_info->validity->notAfter);
- validCert->cert_info->validity->notAfter = ASN1_TIME_set(NULL, now+60);
-
- ret = tor_tls_check_lifetime(LOG_WARN, tls, time(NULL), 0, -1000);
- tt_int_op(ret, OP_EQ, -1);
-
- ret = tor_tls_check_lifetime(LOG_WARN, tls, time(NULL), -1000, 0);
- tt_int_op(ret, OP_EQ, -1);
-
- done:
- tor_free(tls->ssl->session);
- tor_free(tls->ssl);
- tor_free(tls);
- X509_free(validCert);
-}
-#endif /* !defined(OPENSSL_OPAQUE) */
-
-#ifndef OPENSSL_OPAQUE
-static int fixed_ssl_pending_result = 0;
-
-static int
-fixed_ssl_pending(const SSL *ignored)
-{
- (void)ignored;
- return fixed_ssl_pending_result;
-}
-
-static void
-test_tortls_get_pending_bytes(void *ignored)
-{
- (void)ignored;
- int ret;
- tor_tls_t *tls;
- SSL_METHOD *method;
-
- tls = tor_malloc_zero(sizeof(tor_tls_t));
- tls->ssl = tor_malloc_zero(sizeof(SSL));
- method = tor_malloc_zero(sizeof(SSL_METHOD));
- method->ssl_pending = fixed_ssl_pending;
- tls->ssl->method = method;
-
- fixed_ssl_pending_result = 42;
- ret = tor_tls_get_pending_bytes(tls);
- tt_int_op(ret, OP_EQ, 42);
-
- done:
- tor_free(method);
- tor_free(tls->ssl);
- tor_free(tls);
-}
-#endif /* !defined(OPENSSL_OPAQUE) */
-
+#ifdef ENABLE_OPENSSL
static void
test_tortls_get_forced_write_size(void *ignored)
{
@@ -1177,30 +300,6 @@ test_tortls_get_forced_write_size(void *ignored)
}
static void
-test_tortls_get_write_overhead_ratio(void *ignored)
-{
- (void)ignored;
- double ret;
-
- total_bytes_written_over_tls = 0;
- ret = tls_get_write_overhead_ratio();
- tt_double_op(fabs(ret - 1.0), OP_LT, 1E-12);
-
- total_bytes_written_by_tls = 10;
- total_bytes_written_over_tls = 1;
- ret = tls_get_write_overhead_ratio();
- tt_double_op(fabs(ret - 10.0), OP_LT, 1E-12);
-
- total_bytes_written_by_tls = 10;
- total_bytes_written_over_tls = 2;
- ret = tls_get_write_overhead_ratio();
- tt_double_op(fabs(ret - 5.0), OP_LT, 1E-12);
-
- done:
- (void)0;
-}
-
-static void
test_tortls_used_v1_handshake(void *ignored)
{
(void)ignored;
@@ -1222,23 +321,6 @@ test_tortls_used_v1_handshake(void *ignored)
}
static void
-test_tortls_get_num_server_handshakes(void *ignored)
-{
- (void)ignored;
- int ret;
- tor_tls_t *tls;
-
- tls = tor_malloc_zero(sizeof(tor_tls_t));
-
- tls->server_handshake_count = 3;
- ret = tor_tls_get_num_server_handshakes(tls);
- tt_int_op(ret, OP_EQ, 3);
-
- done:
- tor_free(tls);
-}
-
-static void
test_tortls_server_got_renegotiate(void *ignored)
{
(void)ignored;
@@ -1254,116 +336,7 @@ test_tortls_server_got_renegotiate(void *ignored)
done:
tor_free(tls);
}
-
-#ifndef OPENSSL_OPAQUE
-static void
-test_tortls_SSL_SESSION_get_master_key(void *ignored)
-{
- (void)ignored;
- size_t ret;
- tor_tls_t *tls;
- uint8_t *out;
- out = tor_malloc_zero(1);
- tls = tor_malloc_zero(sizeof(tor_tls_t));
- tls->ssl = tor_malloc_zero(sizeof(SSL));
- tls->ssl->session = tor_malloc_zero(sizeof(SSL_SESSION));
- tls->ssl->session->master_key_length = 1;
-
-#ifndef HAVE_SSL_SESSION_GET_MASTER_KEY
- tls->ssl->session->master_key[0] = 43;
- ret = SSL_SESSION_get_master_key(tls->ssl->session, out, 0);
- tt_int_op(ret, OP_EQ, 1);
- tt_int_op(out[0], OP_EQ, 0);
-
- ret = SSL_SESSION_get_master_key(tls->ssl->session, out, 1);
- tt_int_op(ret, OP_EQ, 1);
- tt_int_op(out[0], OP_EQ, 43);
-
- done:
-#endif /* !defined(HAVE_SSL_SESSION_GET_MASTER_KEY) */
- tor_free(tls->ssl->session);
- tor_free(tls->ssl);
- tor_free(tls);
- tor_free(out);
-}
-#endif /* !defined(OPENSSL_OPAQUE) */
-
-#ifndef OPENSSL_OPAQUE
-static void
-test_tortls_get_tlssecrets(void *ignored)
-{
- (void)ignored;
- int ret;
- uint8_t *secret_out = tor_malloc_zero(DIGEST256_LEN);
- tor_tls_t *tls;
- tls = tor_malloc_zero(sizeof(tor_tls_t));
- tls->ssl = tor_malloc_zero(sizeof(SSL));
- tls->ssl->session = tor_malloc_zero(sizeof(SSL_SESSION));
- tls->ssl->session->master_key_length = 1;
- tls->ssl->s3 = tor_malloc_zero(sizeof(SSL3_STATE));
-
- ret = tor_tls_get_tlssecrets(tls, secret_out);
- tt_int_op(ret, OP_EQ, 0);
-
- done:
- tor_free(secret_out);
- tor_free(tls->ssl->s3);
- tor_free(tls->ssl->session);
- tor_free(tls->ssl);
- tor_free(tls);
-}
-#endif /* !defined(OPENSSL_OPAQUE) */
-
-#ifndef OPENSSL_OPAQUE
-static void
-test_tortls_get_buffer_sizes(void *ignored)
-{
- (void)ignored;
- int ret;
- tor_tls_t *tls;
- size_t rbuf_c=-1, rbuf_b=-1, wbuf_c=-1, wbuf_b=-1;
-
- tls = tor_malloc_zero(sizeof(tor_tls_t));
- tls->ssl = tor_malloc_zero(sizeof(SSL));
- tls->ssl->s3 = tor_malloc_zero(sizeof(SSL3_STATE));
-
- tls->ssl->s3->rbuf.buf = NULL;
- tls->ssl->s3->rbuf.len = 1;
- tls->ssl->s3->rbuf.offset = 0;
- tls->ssl->s3->rbuf.left = 42;
-
- tls->ssl->s3->wbuf.buf = NULL;
- tls->ssl->s3->wbuf.len = 2;
- tls->ssl->s3->wbuf.offset = 0;
- tls->ssl->s3->wbuf.left = 43;
-
- ret = tor_tls_get_buffer_sizes(tls, &rbuf_c, &rbuf_b, &wbuf_c, &wbuf_b);
-#if OPENSSL_VERSION_NUMBER >= OPENSSL_V_SERIES(1,1,0)
- tt_int_op(ret, OP_EQ, -1);
-#else
- tt_int_op(ret, OP_EQ, 0);
- tt_int_op(rbuf_c, OP_EQ, 0);
- tt_int_op(wbuf_c, OP_EQ, 0);
- tt_int_op(rbuf_b, OP_EQ, 42);
- tt_int_op(wbuf_b, OP_EQ, 43);
-
- tls->ssl->s3->rbuf.buf = tor_malloc_zero(1);
- tls->ssl->s3->wbuf.buf = tor_malloc_zero(1);
- ret = tor_tls_get_buffer_sizes(tls, &rbuf_c, &rbuf_b, &wbuf_c, &wbuf_b);
- tt_int_op(ret, OP_EQ, 0);
- tt_int_op(rbuf_c, OP_EQ, 1);
- tt_int_op(wbuf_c, OP_EQ, 2);
-
-#endif /* OPENSSL_VERSION_NUMBER >= OPENSSL_V_SERIES(1,1,0) */
-
- done:
- tor_free(tls->ssl->s3->rbuf.buf);
- tor_free(tls->ssl->s3->wbuf.buf);
- tor_free(tls->ssl->s3);
- tor_free(tls->ssl);
- tor_free(tls);
-}
-#endif /* !defined(OPENSSL_OPAQUE) */
+#endif
static void
test_tortls_evaluate_ecgroup_for_tls(void *ignored)
@@ -1388,1443 +361,177 @@ test_tortls_evaluate_ecgroup_for_tls(void *ignored)
(void)0;
}
-#ifndef OPENSSL_OPAQUE
-typedef struct cert_pkey_st_local
-{
- X509 *x509;
- EVP_PKEY *privatekey;
- const EVP_MD *digest;
-} CERT_PKEY_local;
-
-typedef struct sess_cert_st_local
-{
- STACK_OF(X509) *cert_chain;
- int peer_cert_type;
- CERT_PKEY_local *peer_key;
- CERT_PKEY_local peer_pkeys[8];
- int references;
-} SESS_CERT_local;
-
-static void
-test_tortls_try_to_extract_certs_from_tls(void *ignored)
-{
- (void)ignored;
- tor_tls_t *tls;
- X509 *cert = NULL, *id_cert = NULL, *c1 = NULL, *c2 = NULL;
- SESS_CERT_local *sess = NULL;
-
- c1 = read_cert_from(validCertString);
- c2 = read_cert_from(caCertString);
-
- tls = tor_malloc_zero(sizeof(tor_tls_t));
- tls->ssl = tor_malloc_zero(sizeof(SSL));
- tls->ssl->session = tor_malloc_zero(sizeof(SSL_SESSION));
- sess = tor_malloc_zero(sizeof(SESS_CERT_local));
- tls->ssl->session->sess_cert = (void *)sess;
-
- try_to_extract_certs_from_tls(LOG_WARN, tls, &cert, &id_cert);
- tt_assert(!cert);
- tt_assert(!id_cert);
-
- tls->ssl->session->peer = c1;
- try_to_extract_certs_from_tls(LOG_WARN, tls, &cert, &id_cert);
- tt_assert(cert == c1);
- tt_assert(!id_cert);
- X509_free(cert); /* decrease refcnt */
-
- sess->cert_chain = sk_X509_new_null();
- try_to_extract_certs_from_tls(LOG_WARN, tls, &cert, &id_cert);
- tt_assert(cert == c1);
- tt_assert(!id_cert);
- X509_free(cert); /* decrease refcnt */
-
- sk_X509_push(sess->cert_chain, c1);
- sk_X509_push(sess->cert_chain, c2);
-
- try_to_extract_certs_from_tls(LOG_WARN, tls, &cert, &id_cert);
- tt_assert(cert == c1);
- tt_assert(id_cert);
- X509_free(cert); /* decrease refcnt */
-
- done:
- sk_X509_free(sess->cert_chain);
- tor_free(sess);
- tor_free(tls->ssl->session);
- tor_free(tls->ssl);
- tor_free(tls);
- X509_free(c1);
- X509_free(c2);
-}
-#endif /* !defined(OPENSSL_OPAQUE) */
-
-#ifndef OPENSSL_OPAQUE
-static void
-test_tortls_get_peer_cert(void *ignored)
-{
- (void)ignored;
- tor_x509_cert_t *ret;
- tor_tls_t *tls;
- X509 *cert = NULL;
-
- cert = read_cert_from(validCertString);
-
- tls = tor_malloc_zero(sizeof(tor_tls_t));
- tls->ssl = tor_malloc_zero(sizeof(SSL));
- tls->ssl->session = tor_malloc_zero(sizeof(SSL_SESSION));
-
- ret = tor_tls_get_peer_cert(tls);
- tt_assert(!ret);
-
- tls->ssl->session->peer = cert;
- ret = tor_tls_get_peer_cert(tls);
- tt_assert(ret);
- tt_assert(ret->cert == cert);
-
- done:
- tor_x509_cert_free(ret);
- tor_free(tls->ssl->session);
- tor_free(tls->ssl);
- tor_free(tls);
- X509_free(cert);
-}
-#endif /* !defined(OPENSSL_OPAQUE) */
-
-#ifndef OPENSSL_OPAQUE
static void
-test_tortls_peer_has_cert(void *ignored)
+test_tortls_double_init(void *arg)
{
- (void)ignored;
- int ret;
- tor_tls_t *tls;
- X509 *cert = NULL;
-
- cert = read_cert_from(validCertString);
-
- tls = tor_malloc_zero(sizeof(tor_tls_t));
- tls->ssl = tor_malloc_zero(sizeof(SSL));
- tls->ssl->session = tor_malloc_zero(sizeof(SSL_SESSION));
-
- ret = tor_tls_peer_has_cert(tls);
- tt_assert(!ret);
-
- tls->ssl->session->peer = cert;
- ret = tor_tls_peer_has_cert(tls);
- tt_assert(ret);
-
- done:
- tor_free(tls->ssl->session);
- tor_free(tls->ssl);
- tor_free(tls);
- X509_free(cert);
-}
-#endif /* !defined(OPENSSL_OPAQUE) */
+ (void) arg;
+ /* If we call tor_tls_context_init() a second time, nothing should go
+ * wrong.
+ */
+ crypto_pk_t *pk1 = NULL, *pk2 = NULL;
+ pk1 = pk_generate(2);
+ pk2 = pk_generate(0);
-static void
-test_tortls_is_server(void *ignored)
-{
- (void)ignored;
- tor_tls_t *tls;
- int ret;
+ int r = tor_tls_context_init(TOR_TLS_CTX_IS_PUBLIC_SERVER,
+ pk1, pk2, 86400);
+ tt_int_op(r, OP_EQ, 0);
- tls = tor_malloc_zero(sizeof(tor_tls_t));
- tls->isServer = 1;
- ret = tor_tls_is_server(tls);
- tt_int_op(ret, OP_EQ, 1);
+ r = tor_tls_context_init(TOR_TLS_CTX_IS_PUBLIC_SERVER,
+ pk2, pk1, 86400);
+ tt_int_op(r, OP_EQ, 0);
+ /* For a public server context, these are the same */
+ tt_ptr_op(tor_tls_context_get(0), OP_EQ, tor_tls_context_get(1));
done:
- tor_free(tls);
-}
-
-#ifndef OPENSSL_OPAQUE
-static void
-test_tortls_session_secret_cb(void *ignored)
-{
- (void)ignored;
- tor_tls_t *tls;
- SSL_CTX *ctx;
- STACK_OF(SSL_CIPHER) *ciphers = NULL;
- SSL_CIPHER *one;
-
- SSL_library_init();
- SSL_load_error_strings();
- tor_tls_allocate_tor_tls_object_ex_data_index();
-
- tls = tor_malloc_zero(sizeof(tor_tls_t));
-
- tls->magic = TOR_TLS_MAGIC;
-
- ctx = SSL_CTX_new(TLSv1_method());
- tls->ssl = SSL_new(ctx);
- SSL_set_ex_data(tls->ssl, tor_tls_object_ex_data_index, tls);
-
- SSL_set_session_secret_cb(tls->ssl, tor_tls_session_secret_cb, NULL);
-
- tor_tls_session_secret_cb(tls->ssl, NULL, NULL, NULL, NULL, NULL);
- tt_assert(!tls->ssl->tls_session_secret_cb);
-
- one = get_cipher_by_name("ECDHE-RSA-AES256-GCM-SHA384");
- one->id = 0x00ff;
- ciphers = sk_SSL_CIPHER_new_null();
- sk_SSL_CIPHER_push(ciphers, one);
-
- tls->client_cipher_list_type = 0;
- tor_tls_session_secret_cb(tls->ssl, NULL, NULL, ciphers, NULL, NULL);
- tt_assert(!tls->ssl->tls_session_secret_cb);
-
- done:
- sk_SSL_CIPHER_free(ciphers);
- SSL_free(tls->ssl);
- SSL_CTX_free(ctx);
- tor_free(tls);
-}
-#endif /* !defined(OPENSSL_OPAQUE) */
-
-#ifndef OPENSSL_OPAQUE
-/* TODO: It seems block_renegotiation and unblock_renegotiation and
- * using different blags. This might not be correct */
-static void
-test_tortls_block_renegotiation(void *ignored)
-{
- (void)ignored;
- tor_tls_t *tls;
-
- tls = tor_malloc_zero(sizeof(tor_tls_t));
- tls->ssl = tor_malloc_zero(sizeof(SSL));
- tls->ssl->s3 = tor_malloc_zero(sizeof(SSL3_STATE));
-#ifndef SUPPORT_UNSAFE_RENEGOTIATION_FLAG
-#define SSL3_FLAGS_ALLOW_UNSAFE_LEGACY_RENEGOTIATION 0
-#endif
-
- tls->ssl->s3->flags = SSL3_FLAGS_ALLOW_UNSAFE_LEGACY_RENEGOTIATION;
-
- tor_tls_block_renegotiation(tls);
-
-#ifndef OPENSSL_1_1_API
- tt_assert(!(tls->ssl->s3->flags &
- SSL3_FLAGS_ALLOW_UNSAFE_LEGACY_RENEGOTIATION));
-#endif
-
- done:
- tor_free(tls->ssl->s3);
- tor_free(tls->ssl);
- tor_free(tls);
-}
-
-static void
-test_tortls_unblock_renegotiation(void *ignored)
-{
- (void)ignored;
- tor_tls_t *tls;
-
- tls = tor_malloc_zero(sizeof(tor_tls_t));
- tls->ssl = tor_malloc_zero(sizeof(SSL));
- tor_tls_unblock_renegotiation(tls);
-
- tt_uint_op(SSL_get_options(tls->ssl) &
- SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION, OP_EQ,
- SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION);
-
- done:
- tor_free(tls->ssl);
- tor_free(tls);
-}
-#endif /* !defined(OPENSSL_OPAQUE) */
-
-#ifndef OPENSSL_OPAQUE
-static void
-test_tortls_assert_renegotiation_unblocked(void *ignored)
-{
- (void)ignored;
- tor_tls_t *tls;
-
- tls = tor_malloc_zero(sizeof(tor_tls_t));
- tls->ssl = tor_malloc_zero(sizeof(SSL));
- tor_tls_unblock_renegotiation(tls);
- tor_tls_assert_renegotiation_unblocked(tls);
- /* No assertion here - this test will fail if tor_assert is turned on
- * and things are bad. */
-
- tor_free(tls->ssl);
- tor_free(tls);
-}
-#endif /* !defined(OPENSSL_OPAQUE) */
-
-static void
-test_tortls_set_logged_address(void *ignored)
-{
- (void)ignored;
- tor_tls_t *tls;
-
- tls = tor_malloc_zero(sizeof(tor_tls_t));
-
- tor_tls_set_logged_address(tls, "foo bar");
-
- tt_str_op(tls->address, OP_EQ, "foo bar");
-
- tor_tls_set_logged_address(tls, "foo bar 2");
- tt_str_op(tls->address, OP_EQ, "foo bar 2");
-
- done:
- tor_free(tls->address);
- tor_free(tls);
+ crypto_pk_free(pk1);
+ crypto_pk_free(pk2);
}
-#ifndef OPENSSL_OPAQUE
static void
-example_cb(tor_tls_t *t, void *arg)
+test_tortls_bridge_init(void *arg)
{
- (void)t;
(void)arg;
-}
+ crypto_pk_t *pk1 = NULL, *pk2 = NULL;
+ pk1 = pk_generate(2);
+ pk2 = pk_generate(0);
-static void
-test_tortls_set_renegotiate_callback(void *ignored)
-{
- (void)ignored;
- tor_tls_t *tls;
- const char *arg = "hello";
-
- tls = tor_malloc_zero(sizeof(tor_tls_t));
- tls->ssl = tor_malloc_zero(sizeof(SSL));
-
- tor_tls_set_renegotiate_callback(tls, example_cb, (void*)arg);
- tt_assert(tls->negotiated_callback == example_cb);
- tt_assert(tls->callback_arg == arg);
- tt_assert(!tls->got_renegotiate);
-
- /* Assumes V2_HANDSHAKE_SERVER */
- tt_assert(tls->ssl->info_callback == tor_tls_server_info_callback);
-
- tor_tls_set_renegotiate_callback(tls, NULL, (void*)arg);
- tt_assert(tls->ssl->info_callback == tor_tls_debug_state_callback);
+ /* If we pass in a server identity key but not the
+ TOR_TLS_CTX_IS_PUBLIC_SERVER flag, we should get a bridge-style
+ configuration, with two distinct contexts. */
+ int r = tor_tls_context_init(0 /* flags */, pk1, pk2, 86400);
+ tt_int_op(r, OP_EQ, 0);
+ tt_ptr_op(tor_tls_context_get(0), OP_NE, tor_tls_context_get(1));
done:
- tor_free(tls->ssl);
- tor_free(tls);
-}
-#endif /* !defined(OPENSSL_OPAQUE) */
-
-#ifndef OPENSSL_OPAQUE
-static SSL_CIPHER *fixed_cipher1 = NULL;
-static SSL_CIPHER *fixed_cipher2 = NULL;
-static const SSL_CIPHER *
-fake_get_cipher(unsigned ncipher)
-{
-
- switch (ncipher) {
- case 1:
- return fixed_cipher1;
- case 2:
- return fixed_cipher2;
- default:
- return NULL;
- }
-}
-#endif /* !defined(OPENSSL_OPAQUE) */
-
-#ifndef OPENSSL_OPAQUE
-static void
-test_tortls_find_cipher_by_id(void *ignored)
-{
- (void)ignored;
- int ret;
- SSL *ssl;
- SSL_CTX *ctx;
- const SSL_METHOD *m = TLSv1_method();
- SSL_METHOD *empty_method = tor_malloc_zero(sizeof(SSL_METHOD));
-
- fixed_cipher1 = tor_malloc_zero(sizeof(SSL_CIPHER));
- fixed_cipher2 = tor_malloc_zero(sizeof(SSL_CIPHER));
- fixed_cipher2->id = 0xC00A;
-
- SSL_library_init();
- SSL_load_error_strings();
-
- ctx = SSL_CTX_new(m);
- ssl = SSL_new(ctx);
-
- ret = find_cipher_by_id(ssl, NULL, 0xC00A);
- tt_int_op(ret, OP_EQ, 1);
-
- ret = find_cipher_by_id(ssl, m, 0xC00A);
- tt_int_op(ret, OP_EQ, 1);
-
- ret = find_cipher_by_id(ssl, m, 0xFFFF);
- tt_int_op(ret, OP_EQ, 0);
-
- ret = find_cipher_by_id(ssl, empty_method, 0xC00A);
- tt_int_op(ret, OP_EQ, 1);
-
- ret = find_cipher_by_id(ssl, empty_method, 0xFFFF);
-#ifdef HAVE_SSL_CIPHER_FIND
- tt_int_op(ret, OP_EQ, 0);
-#else
- tt_int_op(ret, OP_EQ, 1);
-#endif
-
- empty_method->get_cipher = fake_get_cipher;
- ret = find_cipher_by_id(ssl, empty_method, 0xC00A);
- tt_int_op(ret, OP_EQ, 1);
-
- empty_method->get_cipher = m->get_cipher;
- empty_method->num_ciphers = m->num_ciphers;
- ret = find_cipher_by_id(ssl, empty_method, 0xC00A);
- tt_int_op(ret, OP_EQ, 1);
-
- empty_method->get_cipher = fake_get_cipher;
- empty_method->num_ciphers = m->num_ciphers;
- ret = find_cipher_by_id(ssl, empty_method, 0xC00A);
- tt_int_op(ret, OP_EQ, 1);
-
- empty_method->num_ciphers = fake_num_ciphers;
- ret = find_cipher_by_id(ssl, empty_method, 0xC00A);
-#ifdef HAVE_SSL_CIPHER_FIND
- tt_int_op(ret, OP_EQ, 1);
-#else
- tt_int_op(ret, OP_EQ, 0);
-#endif
-
- done:
- tor_free(empty_method);
- SSL_free(ssl);
- SSL_CTX_free(ctx);
- tor_free(fixed_cipher1);
-}
-#endif /* !defined(OPENSSL_OPAQUE) */
-
-#ifndef OPENSSL_OPAQUE
-static void
-test_tortls_debug_state_callback(void *ignored)
-{
- (void)ignored;
- SSL *ssl;
- char *buf = tor_malloc_zero(1000);
- int n;
-
- setup_capture_of_logs(LOG_DEBUG);
-
- ssl = tor_malloc_zero(sizeof(SSL));
-
- tor_tls_debug_state_callback(ssl, 32, 45);
-
- n = tor_snprintf(buf, 1000, "SSL %p is now in state unknown"
- " state [type=32,val=45].\n", ssl);
- /* tor's snprintf returns -1 on error */
- tt_int_op(n, OP_NE, -1);
- expect_log_msg(buf);
-
- done:
- teardown_capture_of_logs();
- tor_free(buf);
- tor_free(ssl);
-}
-#endif /* !defined(OPENSSL_OPAQUE) */
-
-#ifndef OPENSSL_OPAQUE
-static void
-test_tortls_server_info_callback(void *ignored)
-{
- (void)ignored;
- tor_tls_t *tls;
- SSL_CTX *ctx;
- SSL *ssl;
-
- SSL_library_init();
- SSL_load_error_strings();
-
- ctx = SSL_CTX_new(TLSv1_method());
- ssl = SSL_new(ctx);
-
- tor_tls_allocate_tor_tls_object_ex_data_index();
-
- tls = tor_malloc_zero(sizeof(tor_tls_t));
- tls->magic = TOR_TLS_MAGIC;
- tls->ssl = ssl;
-
- setup_full_capture_of_logs(LOG_WARN);
- SSL_set_state(ssl, SSL3_ST_SW_SRVR_HELLO_A);
- mock_clean_saved_logs();
- tor_tls_server_info_callback(ssl, SSL_CB_ACCEPT_LOOP, 0);
- expect_single_log_msg("Couldn't look up the tls for an SSL*. How odd!\n");
-
- SSL_set_state(ssl, SSL3_ST_SW_SRVR_HELLO_B);
- mock_clean_saved_logs();
- tor_tls_server_info_callback(ssl, SSL_CB_ACCEPT_LOOP, 0);
- expect_single_log_msg("Couldn't look up the tls for an SSL*. How odd!\n");
-
- SSL_set_state(ssl, 99);
- mock_clean_saved_logs();
- tor_tls_server_info_callback(ssl, SSL_CB_ACCEPT_LOOP, 0);
- expect_no_log_entry();
- teardown_capture_of_logs();
-
- SSL_set_ex_data(tls->ssl, tor_tls_object_ex_data_index, tls);
- SSL_set_state(ssl, SSL3_ST_SW_SRVR_HELLO_B);
- tls->negotiated_callback = 0;
- tls->server_handshake_count = 120;
- tor_tls_server_info_callback(ssl, SSL_CB_ACCEPT_LOOP, 0);
- tt_int_op(tls->server_handshake_count, OP_EQ, 121);
-
- tls->server_handshake_count = 127;
- tls->negotiated_callback = (void *)1;
- tor_tls_server_info_callback(ssl, SSL_CB_ACCEPT_LOOP, 0);
- tt_int_op(tls->server_handshake_count, OP_EQ, 127);
- tt_int_op(tls->got_renegotiate, OP_EQ, 1);
-
- tls->ssl->session = SSL_SESSION_new();
- tls->wasV2Handshake = 0;
- tor_tls_server_info_callback(ssl, SSL_CB_ACCEPT_LOOP, 0);
- tt_int_op(tls->wasV2Handshake, OP_EQ, 0);
-
- done:
- teardown_capture_of_logs();
- SSL_free(ssl);
- SSL_CTX_free(ctx);
- tor_free(tls);
-}
-#endif /* !defined(OPENSSL_OPAQUE) */
-
-#ifndef OPENSSL_OPAQUE
-static int fixed_ssl_read_result_index;
-static int fixed_ssl_read_result[5];
-static int fixed_ssl_shutdown_result;
-
-static int
-fixed_ssl_read(SSL *s, void *buf, int len)
-{
- (void)s;
- (void)buf;
- (void)len;
- return fixed_ssl_read_result[fixed_ssl_read_result_index++];
-}
-
-static int
-fixed_ssl_shutdown(SSL *s)
-{
- (void)s;
- return fixed_ssl_shutdown_result;
-}
-
-#ifndef LIBRESSL_VERSION_NUMBER
-static int fixed_ssl_state_to_set;
-static tor_tls_t *fixed_tls;
-
-static int
-setting_version_ssl_shutdown(SSL *s)
-{
- s->version = SSL2_VERSION;
- return fixed_ssl_shutdown_result;
-}
-
-static int
-setting_version_and_state_ssl_shutdown(SSL *s)
-{
- fixed_tls->state = fixed_ssl_state_to_set;
- s->version = SSL2_VERSION;
- return fixed_ssl_shutdown_result;
-}
-#endif /* !defined(LIBRESSL_VERSION_NUMBER) */
-
-static int
-dummy_handshake_func(SSL *s)
-{
- (void)s;
- return 1;
-}
-
-static void
-test_tortls_shutdown(void *ignored)
-{
- (void)ignored;
- int ret;
- tor_tls_t *tls;
- SSL_METHOD *method = give_me_a_test_method();
- setup_capture_of_logs(LOG_WARN);
-
- tls = tor_malloc_zero(sizeof(tor_tls_t));
- tls->ssl = tor_malloc_zero(sizeof(SSL));
- tls->ssl->method = method;
- method->ssl_read = fixed_ssl_read;
- method->ssl_shutdown = fixed_ssl_shutdown;
-
- ret = tor_tls_shutdown(tls);
- tt_int_op(ret, OP_EQ, -9);
-
- tls->state = TOR_TLS_ST_SENTCLOSE;
- fixed_ssl_read_result_index = 0;
- fixed_ssl_read_result[0] = 10;
- fixed_ssl_read_result[1] = -1;
- ret = tor_tls_shutdown(tls);
- tt_int_op(ret, OP_EQ, -9);
-
-#ifndef LIBRESSL_VERSION_NUMBER
- tls->ssl->handshake_func = dummy_handshake_func;
-
- fixed_ssl_read_result_index = 0;
- fixed_ssl_read_result[0] = 10;
- fixed_ssl_read_result[1] = 42;
- fixed_ssl_read_result[2] = 0;
- fixed_ssl_shutdown_result = 1;
- ERR_clear_error();
- tls->ssl->version = SSL2_VERSION;
- ret = tor_tls_shutdown(tls);
- tt_int_op(ret, OP_EQ, TOR_TLS_DONE);
- tt_int_op(tls->state, OP_EQ, TOR_TLS_ST_CLOSED);
-
- fixed_ssl_read_result_index = 0;
- fixed_ssl_read_result[0] = 10;
- fixed_ssl_read_result[1] = 42;
- fixed_ssl_read_result[2] = 0;
- fixed_ssl_shutdown_result = 0;
- ERR_clear_error();
- tls->ssl->version = 0;
- ret = tor_tls_shutdown(tls);
- tt_int_op(ret, OP_EQ, TOR_TLS_DONE);
- tt_int_op(tls->state, OP_EQ, TOR_TLS_ST_CLOSED);
-
- fixed_ssl_read_result_index = 0;
- fixed_ssl_read_result[0] = 10;
- fixed_ssl_read_result[1] = 42;
- fixed_ssl_read_result[2] = 0;
- fixed_ssl_shutdown_result = 0;
- ERR_clear_error();
- tls->ssl->version = 0;
- method->ssl_shutdown = setting_version_ssl_shutdown;
- ret = tor_tls_shutdown(tls);
- tt_int_op(ret, OP_EQ, TOR_TLS_ERROR_MISC);
-
- fixed_ssl_read_result_index = 0;
- fixed_ssl_read_result[0] = 10;
- fixed_ssl_read_result[1] = 42;
- fixed_ssl_read_result[2] = 0;
- fixed_ssl_shutdown_result = 0;
- fixed_tls = tls;
- fixed_ssl_state_to_set = TOR_TLS_ST_GOTCLOSE;
- ERR_clear_error();
- tls->ssl->version = 0;
- method->ssl_shutdown = setting_version_and_state_ssl_shutdown;
- ret = tor_tls_shutdown(tls);
- tt_int_op(ret, OP_EQ, TOR_TLS_ERROR_MISC);
-
- fixed_ssl_read_result_index = 0;
- fixed_ssl_read_result[0] = 10;
- fixed_ssl_read_result[1] = 42;
- fixed_ssl_read_result[2] = 0;
- fixed_ssl_read_result[3] = -1;
- fixed_ssl_shutdown_result = 0;
- fixed_tls = tls;
- fixed_ssl_state_to_set = 0;
- ERR_clear_error();
- tls->ssl->version = 0;
- method->ssl_shutdown = setting_version_and_state_ssl_shutdown;
- ret = tor_tls_shutdown(tls);
- tt_int_op(ret, OP_EQ, TOR_TLS_ERROR_MISC);
-#endif /* !defined(LIBRESSL_VERSION_NUMBER) */
-
- done:
- teardown_capture_of_logs();
- tor_free(method);
- tor_free(tls->ssl);
- tor_free(tls);
+ crypto_pk_free(pk1);
+ crypto_pk_free(pk2);
}
-static int negotiated_callback_called;
-
static void
-negotiated_callback_setter(tor_tls_t *t, void *arg)
+test_tortls_address(void *arg)
{
- (void)t;
(void)arg;
- negotiated_callback_called++;
-}
-
-static void
-test_tortls_read(void *ignored)
-{
- (void)ignored;
- int ret;
- tor_tls_t *tls;
- char buf[100];
- SSL_METHOD *method = give_me_a_test_method();
- setup_capture_of_logs(LOG_WARN);
-
- tls = tor_malloc_zero(sizeof(tor_tls_t));
- tls->ssl = tor_malloc_zero(sizeof(SSL));
- tls->state = TOR_TLS_ST_OPEN;
-
- ret = tor_tls_read(tls, buf, 10);
- tt_int_op(ret, OP_EQ, -9);
-
- /* These tests assume that V2_HANDSHAKE_SERVER is set */
- tls->ssl->handshake_func = dummy_handshake_func;
- tls->ssl->method = method;
- method->ssl_read = fixed_ssl_read;
- fixed_ssl_read_result_index = 0;
- fixed_ssl_read_result[0] = 42;
- tls->state = TOR_TLS_ST_OPEN;
- ERR_clear_error();
- ret = tor_tls_read(tls, buf, 10);
- tt_int_op(ret, OP_EQ, 42);
-
- tls->state = TOR_TLS_ST_OPEN;
- tls->got_renegotiate = 1;
- fixed_ssl_read_result_index = 0;
- ERR_clear_error();
- ret = tor_tls_read(tls, buf, 10);
- tt_int_op(tls->got_renegotiate, OP_EQ, 0);
-
- tls->state = TOR_TLS_ST_OPEN;
- tls->got_renegotiate = 1;
- negotiated_callback_called = 0;
- tls->negotiated_callback = negotiated_callback_setter;
- fixed_ssl_read_result_index = 0;
- ERR_clear_error();
- ret = tor_tls_read(tls, buf, 10);
- tt_int_op(negotiated_callback_called, OP_EQ, 1);
-
-#ifndef LIBRESSL_VERSION_NUMBER
- fixed_ssl_read_result_index = 0;
- fixed_ssl_read_result[0] = 0;
- tls->ssl->version = SSL2_VERSION;
- ERR_clear_error();
- ret = tor_tls_read(tls, buf, 10);
- tt_int_op(ret, OP_EQ, TOR_TLS_CLOSE);
- tt_int_op(tls->state, OP_EQ, TOR_TLS_ST_CLOSED);
-#endif /* !defined(LIBRESSL_VERSION_NUMBER) */
- // TODO: fill up
-
- done:
- teardown_capture_of_logs();
- tor_free(tls->ssl);
- tor_free(tls);
- tor_free(method);
-}
-
-static int fixed_ssl_write_result;
-
-static int
-fixed_ssl_write(SSL *s, const void *buf, int len)
-{
- (void)s;
- (void)buf;
- (void)len;
- return fixed_ssl_write_result;
-}
+ tor_tls_t *tls = NULL;
+ crypto_pk_t *pk1=NULL, *pk2=NULL;
+ pk1 = pk_generate(2);
+ pk2 = pk_generate(0);
-static void
-test_tortls_write(void *ignored)
-{
- (void)ignored;
- int ret;
- tor_tls_t *tls;
- SSL_METHOD *method = give_me_a_test_method();
- char buf[100];
- setup_capture_of_logs(LOG_WARN);
+ int r = tor_tls_context_init(TOR_TLS_CTX_IS_PUBLIC_SERVER,
+ pk1, pk2, 86400);
+ tt_int_op(r, OP_EQ, 0);
- tls = tor_malloc_zero(sizeof(tor_tls_t));
- tls->ssl = tor_malloc_zero(sizeof(SSL));
+ tls = tor_tls_new(-1, 0);
tls->state = TOR_TLS_ST_OPEN;
+ tor_tls_set_logged_address(tls, "zombo.com");
- ret = tor_tls_write(tls, buf, 0);
- tt_int_op(ret, OP_EQ, 0);
-
- ret = tor_tls_write(tls, buf, 10);
- tt_int_op(ret, OP_EQ, -9);
-
- tls->ssl->method = method;
- tls->wantwrite_n = 1;
- ret = tor_tls_write(tls, buf, 10);
- tt_int_op(tls->wantwrite_n, OP_EQ, 0);
-
- method->ssl_write = fixed_ssl_write;
- tls->ssl->handshake_func = dummy_handshake_func;
- fixed_ssl_write_result = 1;
- ERR_clear_error();
- ret = tor_tls_write(tls, buf, 10);
- tt_int_op(ret, OP_EQ, 1);
-
- fixed_ssl_write_result = -1;
- ERR_clear_error();
- tls->ssl->rwstate = SSL_READING;
- SSL_set_bio(tls->ssl, BIO_new(BIO_s_mem()), NULL);
- SSL_get_rbio(tls->ssl)->flags = BIO_FLAGS_READ;
- ret = tor_tls_write(tls, buf, 10);
- tt_int_op(ret, OP_EQ, TOR_TLS_WANTREAD);
-
- ERR_clear_error();
- tls->ssl->rwstate = SSL_READING;
- SSL_set_bio(tls->ssl, BIO_new(BIO_s_mem()), NULL);
- SSL_get_rbio(tls->ssl)->flags = BIO_FLAGS_WRITE;
- ret = tor_tls_write(tls, buf, 10);
- tt_int_op(ret, OP_EQ, TOR_TLS_WANTWRITE);
-
- done:
- teardown_capture_of_logs();
- BIO_free(tls->ssl->rbio);
- tor_free(tls->ssl);
- tor_free(tls);
- tor_free(method);
-}
-#endif /* !defined(OPENSSL_OPAQUE) */
-
-#ifndef OPENSSL_OPAQUE
-static int fixed_ssl_accept_result;
-static int fixed_ssl_connect_result;
-
-static int
-setting_error_ssl_accept(SSL *ssl)
-{
- (void)ssl;
- ERR_put_error(ERR_LIB_BN, 2, -1, "somewhere.c", 99);
- ERR_put_error(ERR_LIB_SYS, 2, -1, "somewhere.c", 99);
- return fixed_ssl_accept_result;
-}
-
-static int
-setting_error_ssl_connect(SSL *ssl)
-{
- (void)ssl;
- ERR_put_error(ERR_LIB_BN, 2, -1, "somewhere.c", 99);
- ERR_put_error(ERR_LIB_SYS, 2, -1, "somewhere.c", 99);
- return fixed_ssl_connect_result;
-}
-
-static int
-fixed_ssl_accept(SSL *ssl)
-{
- (void) ssl;
- return fixed_ssl_accept_result;
-}
-
-static void
-test_tortls_handshake(void *ignored)
-{
- (void)ignored;
- int ret;
- tor_tls_t *tls;
- SSL_CTX *ctx;
- SSL_METHOD *method = give_me_a_test_method();
+ /* This write should fail, since the fd is -1. */
setup_capture_of_logs(LOG_INFO);
-
- SSL_library_init();
- SSL_load_error_strings();
-
- ctx = SSL_CTX_new(TLSv1_method());
-
- tls = tor_malloc_zero(sizeof(tor_tls_t));
- tls->ssl = SSL_new(ctx);
- tls->state = TOR_TLS_ST_HANDSHAKE;
-
- ret = tor_tls_handshake(tls);
- tt_int_op(ret, OP_EQ, -9);
-
- tls->isServer = 1;
- tls->state = TOR_TLS_ST_HANDSHAKE;
- ret = tor_tls_handshake(tls);
- tt_int_op(ret, OP_EQ, -9);
-
- tls->ssl->method = method;
- method->ssl_accept = fixed_ssl_accept;
- fixed_ssl_accept_result = 2;
- ERR_clear_error();
- tls->state = TOR_TLS_ST_HANDSHAKE;
- ret = tor_tls_handshake(tls);
- tt_int_op(tls->state, OP_EQ, TOR_TLS_ST_OPEN);
-
- method->ssl_accept = setting_error_ssl_accept;
- fixed_ssl_accept_result = 1;
- ERR_clear_error();
- mock_clean_saved_logs();
- tls->state = TOR_TLS_ST_HANDSHAKE;
- ret = tor_tls_handshake(tls);
- tt_int_op(ret, OP_EQ, TOR_TLS_ERROR_MISC);
- expect_log_entry();
- /* This fails on jessie. Investigate why! */
-#if 0
- expect_log_msg("TLS error while handshaking: (null) (in bignum routines:"
- "(null):SSLv3 write client hello B)\n");
- expect_log_msg("TLS error while handshaking: (null) (in system library:"
- "connect:SSLv3 write client hello B)\n");
-#endif /* 0 */
- expect_log_severity(LOG_INFO);
-
- tls->isServer = 0;
- method->ssl_connect = setting_error_ssl_connect;
- fixed_ssl_connect_result = 1;
- ERR_clear_error();
- mock_clean_saved_logs();
- tls->state = TOR_TLS_ST_HANDSHAKE;
- ret = tor_tls_handshake(tls);
- tt_int_op(ret, OP_EQ, TOR_TLS_ERROR_MISC);
- expect_log_entry();
-#if 0
- /* See above */
- expect_log_msg("TLS error while handshaking: "
- "(null) (in bignum routines:(null):SSLv3 write client hello B)\n");
- expect_log_msg("TLS error while handshaking: "
- "(null) (in system library:connect:SSLv3 write client hello B)\n");
-#endif /* 0 */
- expect_log_severity(LOG_WARN);
+ int n = tor_tls_write(tls, "welcome", 7);
+ tt_int_op(n, OP_LT, 0);
+ expect_log_msg_containing("with zombo.com");
done:
teardown_capture_of_logs();
- SSL_free(tls->ssl);
- SSL_CTX_free(ctx);
- tor_free(tls);
- tor_free(method);
-}
-#endif /* !defined(OPENSSL_OPAQUE) */
-
-#ifndef OPENSSL_OPAQUE
-static void
-test_tortls_finish_handshake(void *ignored)
-{
- (void)ignored;
- int ret;
- tor_tls_t *tls;
- SSL_CTX *ctx;
- SSL_METHOD *method = give_me_a_test_method();
- SSL_library_init();
- SSL_load_error_strings();
-
- X509 *c1 = read_cert_from(validCertString);
- SESS_CERT_local *sess = NULL;
-
- ctx = SSL_CTX_new(method);
-
- tls = tor_malloc_zero(sizeof(tor_tls_t));
- tls->ssl = SSL_new(ctx);
- tls->state = TOR_TLS_ST_OPEN;
-
- ret = tor_tls_finish_handshake(tls);
- tt_int_op(ret, OP_EQ, 0);
-
- tls->isServer = 1;
- tls->wasV2Handshake = 0;
- setup_full_capture_of_logs(LOG_WARN);
- ret = tor_tls_finish_handshake(tls);
- tt_int_op(ret, OP_EQ, 0);
- tt_int_op(tls->wasV2Handshake, OP_EQ, 1);
- expect_single_log_msg_containing("For some reason, wasV2Handshake didn't "
- "get set.");
- teardown_capture_of_logs();
-
- tls->wasV2Handshake = 1;
- ret = tor_tls_finish_handshake(tls);
- tt_int_op(ret, OP_EQ, 0);
- tt_int_op(tls->wasV2Handshake, OP_EQ, 1);
-
- tls->wasV2Handshake = 1;
- tls->ssl->session = SSL_SESSION_new();
- ret = tor_tls_finish_handshake(tls);
- tt_int_op(ret, OP_EQ, 0);
- tt_int_op(tls->wasV2Handshake, OP_EQ, 0);
-
- tls->isServer = 0;
-
- sess = tor_malloc_zero(sizeof(SESS_CERT_local));
- tls->ssl->session->sess_cert = (void *)sess;
- sess->cert_chain = sk_X509_new_null();
- sk_X509_push(sess->cert_chain, c1);
- tls->ssl->session->peer = c1;
- tls->wasV2Handshake = 0;
- ret = tor_tls_finish_handshake(tls);
- tt_int_op(ret, OP_EQ, 0);
- tt_int_op(tls->wasV2Handshake, OP_EQ, 1);
-
- method->num_ciphers = fake_num_ciphers;
- ret = tor_tls_finish_handshake(tls);
- tt_int_op(ret, OP_EQ, -9);
-
- done:
- if (sess)
- sk_X509_free(sess->cert_chain);
- if (tls->ssl && tls->ssl->session) {
- tor_free(tls->ssl->session->sess_cert);
- }
- SSL_free(tls->ssl);
- tor_free(tls);
- SSL_CTX_free(ctx);
- tor_free(method);
- teardown_capture_of_logs();
-}
-#endif /* !defined(OPENSSL_OPAQUE) */
-
-static int fixed_crypto_pk_new_result_index;
-static crypto_pk_t *fixed_crypto_pk_new_result[5];
-
-static crypto_pk_t *
-fixed_crypto_pk_new(void)
-{
- return fixed_crypto_pk_new_result[fixed_crypto_pk_new_result_index++];
-}
-
-#ifndef OPENSSL_OPAQUE
-static int fixed_crypto_pk_generate_key_with_bits_result_index;
-static int fixed_crypto_pk_generate_key_with_bits_result[5];
-static int fixed_tor_tls_create_certificate_result_index;
-static X509 *fixed_tor_tls_create_certificate_result[5];
-static int fixed_tor_x509_cert_new_result_index;
-static tor_x509_cert_t *fixed_tor_x509_cert_new_result[5];
-
-static int
-fixed_crypto_pk_generate_key_with_bits(crypto_pk_t *env, int bits)
-{
- (void)env;
- (void)bits;
- return fixed_crypto_pk_generate_key_with_bits_result[
- fixed_crypto_pk_generate_key_with_bits_result_index++];
-}
-
-static X509 *
-fixed_tor_tls_create_certificate(crypto_pk_t *rsa,
- crypto_pk_t *rsa_sign,
- const char *cname,
- const char *cname_sign,
- unsigned int cert_lifetime)
-{
- (void)rsa;
- (void)rsa_sign;
- (void)cname;
- (void)cname_sign;
- (void)cert_lifetime;
- return fixed_tor_tls_create_certificate_result[
- fixed_tor_tls_create_certificate_result_index++];
-}
-
-static tor_x509_cert_t *
-fixed_tor_x509_cert_new(X509 *x509_cert)
-{
- (void) x509_cert;
- return fixed_tor_x509_cert_new_result[
- fixed_tor_x509_cert_new_result_index++];
+ tor_tls_free(tls);
+ crypto_pk_free(pk1);
+ crypto_pk_free(pk2);
}
static void
-test_tortls_context_new(void *ignored)
+test_tortls_is_server(void *arg)
{
- (void)ignored;
- tor_tls_context_t *ret;
- crypto_pk_t *pk1, *pk2, *pk3, *pk4, *pk5, *pk6, *pk7, *pk8, *pk9, *pk10,
- *pk11, *pk12, *pk13, *pk14, *pk15, *pk16, *pk17, *pk18;
-
- pk1 = crypto_pk_new();
- pk2 = crypto_pk_new();
- pk3 = crypto_pk_new();
- pk4 = crypto_pk_new();
- pk5 = crypto_pk_new();
- pk6 = crypto_pk_new();
- pk7 = crypto_pk_new();
- pk8 = crypto_pk_new();
- pk9 = crypto_pk_new();
- pk10 = crypto_pk_new();
- pk11 = crypto_pk_new();
- pk12 = crypto_pk_new();
- pk13 = crypto_pk_new();
- pk14 = crypto_pk_new();
- pk15 = crypto_pk_new();
- pk16 = crypto_pk_new();
- pk17 = crypto_pk_new();
- pk18 = crypto_pk_new();
-
- fixed_crypto_pk_new_result_index = 0;
- fixed_crypto_pk_new_result[0] = NULL;
- MOCK(crypto_pk_new, fixed_crypto_pk_new);
- ret = tor_tls_context_new(NULL, 0, 0, 0);
- tt_assert(!ret);
-
- /* note: we already override this in testing_common.c, so we
- * run this unit test in a subprocess. */
- MOCK(crypto_pk_generate_key_with_bits,
- fixed_crypto_pk_generate_key_with_bits);
- fixed_crypto_pk_new_result_index = 0;
- fixed_crypto_pk_new_result[0] = pk1;
- fixed_crypto_pk_new_result[1] = NULL;
- fixed_crypto_pk_generate_key_with_bits_result[0] = -1;
- fixed_crypto_pk_generate_key_with_bits_result_index = 0;
- ret = tor_tls_context_new(NULL, 0, 0, 0);
- tt_assert(!ret);
-
- fixed_crypto_pk_new_result_index = 0;
- fixed_crypto_pk_new_result[0] = pk2;
- fixed_crypto_pk_new_result[1] = NULL;
- fixed_crypto_pk_generate_key_with_bits_result[0] = 0;
- fixed_crypto_pk_generate_key_with_bits_result_index = 0;
- ret = tor_tls_context_new(NULL, 0, 0, 0);
- tt_assert(!ret);
-
- fixed_crypto_pk_new_result_index = 0;
- fixed_crypto_pk_new_result[0] = pk3;
- fixed_crypto_pk_new_result[1] = pk4;
- fixed_crypto_pk_new_result[2] = NULL;
- fixed_crypto_pk_generate_key_with_bits_result[0] = 0;
- fixed_crypto_pk_generate_key_with_bits_result[1] = -1;
- fixed_crypto_pk_generate_key_with_bits_result_index = 0;
- ret = tor_tls_context_new(NULL, 0, 0, 0);
- tt_assert(!ret);
-
- MOCK(tor_tls_create_certificate, fixed_tor_tls_create_certificate);
-
- fixed_crypto_pk_new_result_index = 0;
- fixed_crypto_pk_new_result[0] = pk5;
- fixed_crypto_pk_new_result[1] = pk6;
- fixed_crypto_pk_new_result[2] = NULL;
- fixed_crypto_pk_generate_key_with_bits_result_index = 0;
- fixed_crypto_pk_generate_key_with_bits_result[1] = 0;
- fixed_tor_tls_create_certificate_result_index = 0;
- fixed_tor_tls_create_certificate_result[0] = NULL;
- fixed_tor_tls_create_certificate_result[1] = tor_malloc_zero(sizeof(X509));
- fixed_tor_tls_create_certificate_result[2] = tor_malloc_zero(sizeof(X509));
- ret = tor_tls_context_new(NULL, 0, 0, 0);
- tt_assert(!ret);
-
- fixed_crypto_pk_new_result_index = 0;
- fixed_crypto_pk_new_result[0] = pk7;
- fixed_crypto_pk_new_result[1] = pk8;
- fixed_crypto_pk_new_result[2] = NULL;
- fixed_crypto_pk_generate_key_with_bits_result_index = 0;
- fixed_tor_tls_create_certificate_result_index = 0;
- fixed_tor_tls_create_certificate_result[0] = tor_malloc_zero(sizeof(X509));
- fixed_tor_tls_create_certificate_result[1] = NULL;
- fixed_tor_tls_create_certificate_result[2] = tor_malloc_zero(sizeof(X509));
- ret = tor_tls_context_new(NULL, 0, 0, 0);
- tt_assert(!ret);
-
- fixed_crypto_pk_new_result_index = 0;
- fixed_crypto_pk_new_result[0] = pk9;
- fixed_crypto_pk_new_result[1] = pk10;
- fixed_crypto_pk_new_result[2] = NULL;
- fixed_crypto_pk_generate_key_with_bits_result_index = 0;
- fixed_tor_tls_create_certificate_result_index = 0;
- fixed_tor_tls_create_certificate_result[0] = tor_malloc_zero(sizeof(X509));
- fixed_tor_tls_create_certificate_result[1] = tor_malloc_zero(sizeof(X509));
- fixed_tor_tls_create_certificate_result[2] = NULL;
- ret = tor_tls_context_new(NULL, 0, 0, 0);
- tt_assert(!ret);
-
- MOCK(tor_x509_cert_new, fixed_tor_x509_cert_new);
- fixed_crypto_pk_new_result_index = 0;
- fixed_crypto_pk_new_result[0] = pk11;
- fixed_crypto_pk_new_result[1] = pk12;
- fixed_crypto_pk_new_result[2] = NULL;
- fixed_crypto_pk_generate_key_with_bits_result_index = 0;
- fixed_tor_tls_create_certificate_result_index = 0;
- fixed_tor_tls_create_certificate_result[0] = tor_malloc_zero(sizeof(X509));
- fixed_tor_tls_create_certificate_result[1] = tor_malloc_zero(sizeof(X509));
- fixed_tor_tls_create_certificate_result[2] = tor_malloc_zero(sizeof(X509));
- fixed_tor_x509_cert_new_result_index = 0;
- fixed_tor_x509_cert_new_result[0] = NULL;
- fixed_tor_x509_cert_new_result[1] = NULL;
- fixed_tor_x509_cert_new_result[2] = NULL;
- ret = tor_tls_context_new(NULL, 0, 0, 0);
- tt_assert(!ret);
-
- fixed_crypto_pk_new_result_index = 0;
- fixed_crypto_pk_new_result[0] = pk13;
- fixed_crypto_pk_new_result[1] = pk14;
- fixed_crypto_pk_new_result[2] = NULL;
- fixed_crypto_pk_generate_key_with_bits_result_index = 0;
- fixed_tor_tls_create_certificate_result_index = 0;
- fixed_tor_tls_create_certificate_result[0] = tor_malloc_zero(sizeof(X509));
- fixed_tor_tls_create_certificate_result[1] = tor_malloc_zero(sizeof(X509));
- fixed_tor_tls_create_certificate_result[2] = tor_malloc_zero(sizeof(X509));
- fixed_tor_x509_cert_new_result_index = 0;
- fixed_tor_x509_cert_new_result[0] = tor_malloc_zero(sizeof(tor_x509_cert_t));
- fixed_tor_x509_cert_new_result[1] = NULL;
- fixed_tor_x509_cert_new_result[2] = NULL;
- ret = tor_tls_context_new(NULL, 0, 0, 0);
- tt_assert(!ret);
-
- fixed_crypto_pk_new_result_index = 0;
- fixed_crypto_pk_new_result[0] = pk15;
- fixed_crypto_pk_new_result[1] = pk16;
- fixed_crypto_pk_new_result[2] = NULL;
- fixed_crypto_pk_generate_key_with_bits_result_index = 0;
- fixed_tor_tls_create_certificate_result_index = 0;
- fixed_tor_tls_create_certificate_result[0] = tor_malloc_zero(sizeof(X509));
- fixed_tor_tls_create_certificate_result[1] = tor_malloc_zero(sizeof(X509));
- fixed_tor_tls_create_certificate_result[2] = tor_malloc_zero(sizeof(X509));
- fixed_tor_x509_cert_new_result_index = 0;
- fixed_tor_x509_cert_new_result[0] = tor_malloc_zero(sizeof(tor_x509_cert_t));
- fixed_tor_x509_cert_new_result[1] = tor_malloc_zero(sizeof(tor_x509_cert_t));
- fixed_tor_x509_cert_new_result[2] = NULL;
- ret = tor_tls_context_new(NULL, 0, 0, 0);
- tt_assert(!ret);
-
- fixed_crypto_pk_new_result_index = 0;
- fixed_crypto_pk_new_result[0] = pk17;
- fixed_crypto_pk_new_result[1] = pk18;
- fixed_crypto_pk_new_result[2] = NULL;
- fixed_crypto_pk_generate_key_with_bits_result_index = 0;
- fixed_tor_tls_create_certificate_result_index = 0;
- fixed_tor_tls_create_certificate_result[0] = tor_malloc_zero(sizeof(X509));
- fixed_tor_tls_create_certificate_result[1] = tor_malloc_zero(sizeof(X509));
- fixed_tor_tls_create_certificate_result[2] = tor_malloc_zero(sizeof(X509));
- fixed_tor_x509_cert_new_result_index = 0;
- fixed_tor_x509_cert_new_result[0] = tor_malloc_zero(sizeof(tor_x509_cert_t));
- fixed_tor_x509_cert_new_result[1] = tor_malloc_zero(sizeof(tor_x509_cert_t));
- fixed_tor_x509_cert_new_result[2] = tor_malloc_zero(sizeof(tor_x509_cert_t));
- ret = tor_tls_context_new(NULL, 0, 0, 0);
- tt_assert(!ret);
-
- done:
- UNMOCK(tor_x509_cert_new);
- UNMOCK(tor_tls_create_certificate);
- UNMOCK(crypto_pk_generate_key_with_bits);
- UNMOCK(crypto_pk_new);
-}
-#endif /* !defined(OPENSSL_OPAQUE) */
-
-static int fixed_crypto_pk_get_evp_pkey_result_index = 0;
-static EVP_PKEY *fixed_crypto_pk_get_evp_pkey_result[5];
+ (void)arg;
+ crypto_pk_t *pk1=NULL, *pk2=NULL;
+ tor_tls_t *tls1=NULL, *tls2=NULL;
+ pk1 = pk_generate(2);
+ pk2 = pk_generate(0);
-static EVP_PKEY *
-fixed_crypto_pk_get_evp_pkey_(crypto_pk_t *env, int private)
-{
- (void) env;
- (void) private;
- return fixed_crypto_pk_get_evp_pkey_result[
- fixed_crypto_pk_get_evp_pkey_result_index++];
-}
+ int r = tor_tls_context_init(TOR_TLS_CTX_IS_PUBLIC_SERVER,
+ pk1, pk2, 86400);
+ tt_int_op(r, OP_EQ, 0);
+ tls1 = tor_tls_new(-1, 0);
+ tls2 = tor_tls_new(-1, 1);
-static void
-test_tortls_create_certificate(void *ignored)
-{
- (void)ignored;
- X509 *ret;
- crypto_pk_t *pk1, *pk2;
-
- pk1 = crypto_pk_new();
- pk2 = crypto_pk_new();
-
- MOCK(crypto_pk_get_evp_pkey_, fixed_crypto_pk_get_evp_pkey_);
- fixed_crypto_pk_get_evp_pkey_result_index = 0;
- fixed_crypto_pk_get_evp_pkey_result[0] = NULL;
- ret = tor_tls_create_certificate(pk1, pk2, "hello", "hello2", 1);
- tt_assert(!ret);
-
- fixed_crypto_pk_get_evp_pkey_result_index = 0;
- fixed_crypto_pk_get_evp_pkey_result[0] = EVP_PKEY_new();
- fixed_crypto_pk_get_evp_pkey_result[1] = NULL;
- ret = tor_tls_create_certificate(pk1, pk2, "hello", "hello2", 1);
- tt_assert(!ret);
-
- fixed_crypto_pk_get_evp_pkey_result_index = 0;
- fixed_crypto_pk_get_evp_pkey_result[0] = EVP_PKEY_new();
- fixed_crypto_pk_get_evp_pkey_result[1] = EVP_PKEY_new();
- ret = tor_tls_create_certificate(pk1, pk2, "hello", "hello2", 1);
- tt_assert(!ret);
+ tt_assert(! tor_tls_is_server(tls1));
+ tt_assert(tor_tls_is_server(tls2));
done:
- UNMOCK(crypto_pk_get_evp_pkey_);
+ tor_tls_free(tls1);
+ tor_tls_free(tls2);
crypto_pk_free(pk1);
crypto_pk_free(pk2);
}
static void
-test_tortls_cert_new(void *ignored)
-{
- (void)ignored;
- tor_x509_cert_t *ret;
- X509 *cert = read_cert_from(validCertString);
-
- ret = tor_x509_cert_new(NULL);
- tt_assert(!ret);
-
- ret = tor_x509_cert_new(cert);
- tt_assert(ret);
- tor_x509_cert_free(ret);
- ret = NULL;
-
-#if 0
- cert = read_cert_from(validCertString);
- /* XXX this doesn't do what you think: it alters a copy of the pubkey. */
- X509_get_pubkey(cert)->type = EVP_PKEY_DSA;
- ret = tor_x509_cert_new(cert);
- tt_assert(ret);
-#endif /* 0 */
-
-#ifndef OPENSSL_OPAQUE
- cert = read_cert_from(validCertString);
- X509_CINF_free(cert->cert_info);
- cert->cert_info = NULL;
- ret = tor_x509_cert_new(cert);
- tt_assert(ret);
-#endif /* !defined(OPENSSL_OPAQUE) */
-
- done:
- tor_x509_cert_free(ret);
-}
-
-static void
-test_tortls_cert_is_valid(void *ignored)
+test_tortls_verify(void *ignored)
{
(void)ignored;
int ret;
- tor_x509_cert_t *cert = NULL, *scert = NULL;
+ tor_tls_t *tls;
+ crypto_pk_t *k = NULL;
+ tor_x509_cert_impl_t *cert1 = NULL, *cert2 = NULL, *invalidCert = NULL,
+ *validCert = NULL, *caCert = NULL;
- scert = tor_malloc_zero(sizeof(tor_x509_cert_t));
- ret = tor_tls_cert_is_valid(LOG_WARN, cert, scert, time(NULL), 0);
- tt_int_op(ret, OP_EQ, 0);
+ validCert = read_cert_from(validCertString);
+ caCert = read_cert_from(caCertString);
+ invalidCert = read_cert_from(notCompletelyValidCertString);
- cert = tor_malloc_zero(sizeof(tor_x509_cert_t));
- ret = tor_tls_cert_is_valid(LOG_WARN, cert, scert, time(NULL), 0);
- tt_int_op(ret, OP_EQ, 0);
- tor_free(scert);
- tor_free(cert);
+ tls = tor_malloc_zero(sizeof(tor_tls_t));
- cert = tor_x509_cert_new(read_cert_from(validCertString));
- scert = tor_x509_cert_new(read_cert_from(caCertString));
- ret = tor_tls_cert_is_valid(LOG_WARN, cert, scert, time(NULL), 0);
- tt_int_op(ret, OP_EQ, 1);
+ MOCK(try_to_extract_certs_from_tls, fixed_try_to_extract_certs_from_tls);
-#ifndef OPENSSL_OPAQUE
- tor_x509_cert_free(cert);
- tor_x509_cert_free(scert);
- cert = tor_x509_cert_new(read_cert_from(validCertString));
- scert = tor_x509_cert_new(read_cert_from(caCertString));
- ASN1_TIME_free(cert->cert->cert_info->validity->notAfter);
- cert->cert->cert_info->validity->notAfter =
- ASN1_TIME_set(NULL, time(NULL)-1000000);
- ret = tor_tls_cert_is_valid(LOG_WARN, cert, scert, time(NULL), 0);
- tt_int_op(ret, OP_EQ, 0);
+ fixed_try_to_extract_certs_from_tls_cert_out_result = cert1;
+ ret = tor_tls_verify(LOG_WARN, tls, &k);
+ tt_int_op(ret, OP_EQ, -1);
- tor_x509_cert_free(cert);
- tor_x509_cert_free(scert);
- cert = tor_x509_cert_new(read_cert_from(validCertString));
- scert = tor_x509_cert_new(read_cert_from(caCertString));
- X509_PUBKEY_free(cert->cert->cert_info->key);
- cert->cert->cert_info->key = NULL;
- ret = tor_tls_cert_is_valid(LOG_WARN, cert, scert, time(NULL), 1);
- tt_int_op(ret, OP_EQ, 0);
-#endif /* !defined(OPENSSL_OPAQUE) */
+ fixed_try_to_extract_certs_from_tls_id_cert_out_result = cert2;
+ ret = tor_tls_verify(LOG_WARN, tls, &k);
+ tt_int_op(ret, OP_EQ, -1);
-#if 0
- tor_x509_cert_free(cert);
- tor_x509_cert_free(scert);
- cert = tor_x509_cert_new(read_cert_from(validCertString));
- scert = tor_x509_cert_new(read_cert_from(caCertString));
- /* This doesn't actually change the key in the cert. XXXXXX */
- BN_one(EVP_PKEY_get1_RSA(X509_get_pubkey(cert->cert))->n);
- ret = tor_tls_cert_is_valid(LOG_WARN, cert, scert, time(NULL), 1);
- tt_int_op(ret, OP_EQ, 0);
+ fixed_try_to_extract_certs_from_tls_cert_out_result = invalidCert;
+ fixed_try_to_extract_certs_from_tls_id_cert_out_result = invalidCert;
- tor_x509_cert_free(cert);
- tor_x509_cert_free(scert);
- cert = tor_x509_cert_new(read_cert_from(validCertString));
- scert = tor_x509_cert_new(read_cert_from(caCertString));
- /* This doesn't actually change the key in the cert. XXXXXX */
- X509_get_pubkey(cert->cert)->type = EVP_PKEY_EC;
- ret = tor_tls_cert_is_valid(LOG_WARN, cert, scert, time(NULL), 1);
- tt_int_op(ret, OP_EQ, 0);
+ ret = tor_tls_verify(LOG_WARN, tls, &k);
+ tt_int_op(ret, OP_EQ, -1);
- tor_x509_cert_free(cert);
- tor_x509_cert_free(scert);
- cert = tor_x509_cert_new(read_cert_from(validCertString));
- scert = tor_x509_cert_new(read_cert_from(caCertString));
- /* This doesn't actually change the key in the cert. XXXXXX */
- X509_get_pubkey(cert->cert)->type = EVP_PKEY_EC;
- ret = tor_tls_cert_is_valid(LOG_WARN, cert, scert, time(NULL), 0);
- tt_int_op(ret, OP_EQ, 1);
+ fixed_try_to_extract_certs_from_tls_cert_out_result = validCert;
+ fixed_try_to_extract_certs_from_tls_id_cert_out_result = caCert;
- tor_x509_cert_free(cert);
- tor_x509_cert_free(scert);
- cert = tor_x509_cert_new(read_cert_from(validCertString));
- scert = tor_x509_cert_new(read_cert_from(caCertString));
- /* This doesn't actually change the key in the cert. XXXXXX */
- X509_get_pubkey(cert->cert)->type = EVP_PKEY_EC;
- X509_get_pubkey(cert->cert)->ameth = NULL;
- ret = tor_tls_cert_is_valid(LOG_WARN, cert, scert, time(NULL), 0);
+ ret = tor_tls_verify(LOG_WARN, tls, &k);
tt_int_op(ret, OP_EQ, 0);
-#endif /* 0 */
+ tt_assert(k);
done:
- tor_x509_cert_free(cert);
- tor_x509_cert_free(scert);
-}
-
-static void
-test_tortls_context_init_one(void *ignored)
-{
- (void)ignored;
- int ret;
- tor_tls_context_t *old = NULL;
-
- MOCK(crypto_pk_new, fixed_crypto_pk_new);
-
- fixed_crypto_pk_new_result_index = 0;
- fixed_crypto_pk_new_result[0] = NULL;
- ret = tor_tls_context_init_one(&old, NULL, 0, 0, 0);
- tt_int_op(ret, OP_EQ, -1);
+ UNMOCK(try_to_extract_certs_from_tls);
+ tor_x509_cert_impl_free(cert1);
+ tor_x509_cert_impl_free(cert2);
+ tor_x509_cert_impl_free(validCert);
+ tor_x509_cert_impl_free(invalidCert);
+ tor_x509_cert_impl_free(caCert);
- done:
- UNMOCK(crypto_pk_new);
+ tor_free(tls);
+ crypto_pk_free(k);
}
-#define LOCAL_TEST_CASE(name, flags) \
+#define LOCAL_TEST_CASE(name, flags) \
{ #name, test_tortls_##name, (flags|TT_FORK), NULL, NULL }
-#ifdef OPENSSL_OPAQUE
-#define INTRUSIVE_TEST_CASE(name, flags) \
- { #name, NULL, TT_SKIP, NULL, NULL }
-#else
-#define INTRUSIVE_TEST_CASE(name, flags) LOCAL_TEST_CASE(name, flags)
-#endif /* defined(OPENSSL_OPAQUE) */
-
struct testcase_t tortls_tests[] = {
LOCAL_TEST_CASE(errno_to_tls_error, 0),
LOCAL_TEST_CASE(err_to_string, 0),
- LOCAL_TEST_CASE(tor_tls_new, TT_FORK),
- LOCAL_TEST_CASE(tor_tls_get_error, 0),
- LOCAL_TEST_CASE(get_state_description, TT_FORK),
- LOCAL_TEST_CASE(get_by_ssl, TT_FORK),
- LOCAL_TEST_CASE(allocate_tor_tls_object_ex_data_index, TT_FORK),
- LOCAL_TEST_CASE(log_one_error, TT_FORK),
- INTRUSIVE_TEST_CASE(get_error, TT_FORK),
- LOCAL_TEST_CASE(always_accept_verify_cb, 0),
- INTRUSIVE_TEST_CASE(x509_cert_free, 0),
LOCAL_TEST_CASE(x509_cert_get_id_digests, 0),
- LOCAL_TEST_CASE(cert_matches_key, 0),
- INTRUSIVE_TEST_CASE(cert_get_key, 0),
- LOCAL_TEST_CASE(get_my_client_auth_key, TT_FORK),
LOCAL_TEST_CASE(get_my_certs, TT_FORK),
- INTRUSIVE_TEST_CASE(get_ciphersuite_name, 0),
- INTRUSIVE_TEST_CASE(classify_client_ciphers, 0),
- LOCAL_TEST_CASE(client_is_using_v2_ciphers, 0),
- INTRUSIVE_TEST_CASE(verify, 0),
- INTRUSIVE_TEST_CASE(check_lifetime, 0),
- INTRUSIVE_TEST_CASE(get_pending_bytes, 0),
+#ifdef ENABLE_OPENSSL
+ LOCAL_TEST_CASE(tor_tls_get_error, 0),
LOCAL_TEST_CASE(get_forced_write_size, 0),
- LOCAL_TEST_CASE(get_write_overhead_ratio, TT_FORK),
LOCAL_TEST_CASE(used_v1_handshake, TT_FORK),
- LOCAL_TEST_CASE(get_num_server_handshakes, 0),
LOCAL_TEST_CASE(server_got_renegotiate, 0),
- INTRUSIVE_TEST_CASE(SSL_SESSION_get_master_key, 0),
- INTRUSIVE_TEST_CASE(get_tlssecrets, 0),
- INTRUSIVE_TEST_CASE(get_buffer_sizes, 0),
+#endif
LOCAL_TEST_CASE(evaluate_ecgroup_for_tls, 0),
- INTRUSIVE_TEST_CASE(try_to_extract_certs_from_tls, 0),
- INTRUSIVE_TEST_CASE(get_peer_cert, 0),
- INTRUSIVE_TEST_CASE(peer_has_cert, 0),
- INTRUSIVE_TEST_CASE(shutdown, 0),
- INTRUSIVE_TEST_CASE(finish_handshake, 0),
- INTRUSIVE_TEST_CASE(handshake, 0),
- INTRUSIVE_TEST_CASE(write, 0),
- INTRUSIVE_TEST_CASE(read, 0),
- INTRUSIVE_TEST_CASE(server_info_callback, 0),
+ LOCAL_TEST_CASE(double_init, TT_FORK),
+ LOCAL_TEST_CASE(address, TT_FORK),
LOCAL_TEST_CASE(is_server, 0),
- INTRUSIVE_TEST_CASE(assert_renegotiation_unblocked, 0),
- INTRUSIVE_TEST_CASE(block_renegotiation, 0),
- INTRUSIVE_TEST_CASE(unblock_renegotiation, 0),
- INTRUSIVE_TEST_CASE(set_renegotiate_callback, 0),
- LOCAL_TEST_CASE(set_logged_address, 0),
- INTRUSIVE_TEST_CASE(find_cipher_by_id, 0),
- INTRUSIVE_TEST_CASE(session_secret_cb, 0),
- INTRUSIVE_TEST_CASE(debug_state_callback, 0),
- INTRUSIVE_TEST_CASE(context_new, TT_FORK /* redundant */),
- LOCAL_TEST_CASE(create_certificate, 0),
- LOCAL_TEST_CASE(cert_new, 0),
- LOCAL_TEST_CASE(cert_is_valid, 0),
- LOCAL_TEST_CASE(context_init_one, 0),
+ LOCAL_TEST_CASE(bridge_init, TT_FORK),
+ LOCAL_TEST_CASE(verify, TT_FORK),
END_OF_TESTCASES
};
diff --git a/src/test/test_tortls.h b/src/test/test_tortls.h
new file mode 100644
index 0000000000..c997934ebc
--- /dev/null
+++ b/src/test/test_tortls.h
@@ -0,0 +1,13 @@
+/* Copyright (c) 2010-2018, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#ifndef TEST_TORTLS_H
+#define TEST_TORTLS_H
+
+tor_x509_cert_impl_t *read_cert_from(const char *str);
+
+extern const char *notCompletelyValidCertString;
+extern const char *validCertString;
+extern const char *caCertString;
+
+#endif
diff --git a/src/test/test_tortls_openssl.c b/src/test/test_tortls_openssl.c
new file mode 100644
index 0000000000..abe1fb7889
--- /dev/null
+++ b/src/test/test_tortls_openssl.c
@@ -0,0 +1,2316 @@
+/* Copyright (c) 2010-2018, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#define TORTLS_PRIVATE
+#define TORTLS_OPENSSL_PRIVATE
+#define TOR_X509_PRIVATE
+#define LOG_PRIVATE
+#include "orconfig.h"
+
+#ifdef _WIN32
+#include <winsock2.h>
+#endif
+#include <math.h>
+
+#include "lib/cc/compat_compiler.h"
+
+/* Some versions of OpenSSL declare SSL_get_selected_srtp_profile twice in
+ * srtp.h. Suppress the GCC warning so we can build with -Wredundant-decl. */
+DISABLE_GCC_WARNING(redundant-decls)
+
+#include <openssl/opensslv.h>
+
+#include <openssl/ssl.h>
+#include <openssl/ssl3.h>
+#include <openssl/err.h>
+#include <openssl/asn1t.h>
+#include <openssl/x509.h>
+#include <openssl/rsa.h>
+#include <openssl/evp.h>
+#include <openssl/bn.h>
+
+ENABLE_GCC_WARNING(redundant-decls)
+
+#include "core/or/or.h"
+#include "lib/log/log.h"
+#include "app/config/config.h"
+#include "lib/crypt_ops/compat_openssl.h"
+#include "lib/tls/x509.h"
+#include "lib/tls/x509_internal.h"
+#include "lib/tls/tortls.h"
+#include "lib/tls/tortls_st.h"
+#include "lib/tls/tortls_internal.h"
+#include "app/config/or_state_st.h"
+
+#include "test/test.h"
+#include "test/log_test_helpers.h"
+#include "test/test_tortls.h"
+
+#define NS_MODULE tortls
+
+#ifndef HAVE_SSL_STATE
+#define OPENSSL_OPAQUE
+#endif
+
+#if defined(OPENSSL_OPAQUE) && !defined(LIBRESSL_VERSION_NUMBER)
+#define SSL_STATE_STR "before SSL initialization"
+#else
+#define SSL_STATE_STR "before/accept initialization"
+#endif
+
+#ifndef OPENSSL_OPAQUE
+static SSL_METHOD *
+give_me_a_test_method(void)
+{
+ SSL_METHOD *method = tor_malloc_zero(sizeof(SSL_METHOD));
+ memcpy(method, TLSv1_method(), sizeof(SSL_METHOD));
+ return method;
+}
+
+static int
+fake_num_ciphers(void)
+{
+ return 0;
+}
+#endif /* !defined(OPENSSL_OPAQUE) */
+
+static int
+mock_tls_cert_matches_key(const tor_tls_t *tls, const tor_x509_cert_t *cert)
+{
+ (void) tls;
+ (void) cert; // XXXX look at this.
+ return 1;
+}
+
+static void
+test_tortls_tor_tls_new(void *data)
+{
+ (void) data;
+ MOCK(tor_tls_cert_matches_key, mock_tls_cert_matches_key);
+ crypto_pk_t *key1 = NULL, *key2 = NULL;
+ SSL_METHOD *method = NULL;
+
+ key1 = pk_generate(2);
+ key2 = pk_generate(3);
+
+ tor_tls_t *tls = NULL;
+ tt_int_op(tor_tls_context_init(TOR_TLS_CTX_IS_PUBLIC_SERVER,
+ key1, key2, 86400), OP_EQ, 0);
+ tls = tor_tls_new(-1, 0);
+ tt_want(tls);
+ tor_tls_free(tls); tls = NULL;
+
+ SSL_CTX_free(client_tls_context->ctx);
+ client_tls_context->ctx = NULL;
+ tls = tor_tls_new(-1, 0);
+ tt_ptr_op(tls, OP_EQ, NULL);
+
+#ifndef OPENSSL_OPAQUE
+ method = give_me_a_test_method();
+ SSL_CTX *ctx = SSL_CTX_new(method);
+ method->num_ciphers = fake_num_ciphers;
+ client_tls_context->ctx = ctx;
+ tls = tor_tls_new(-1, 0);
+ tt_ptr_op(tls, OP_EQ, NULL);
+#endif /* !defined(OPENSSL_OPAQUE) */
+
+ done:
+ UNMOCK(tor_tls_cert_matches_key);
+ crypto_pk_free(key1);
+ crypto_pk_free(key2);
+ tor_tls_free(tls);
+ tor_free(method);
+ tor_tls_free_all();
+}
+
+#define NS_MODULE tortls
+
+static void
+library_init(void)
+{
+#ifdef OPENSSL_1_1_API
+ OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS, NULL);
+#else
+ SSL_library_init();
+ SSL_load_error_strings();
+#endif
+}
+
+static void
+test_tortls_get_state_description(void *ignored)
+{
+ (void)ignored;
+ tor_tls_t *tls;
+ char *buf;
+ SSL_CTX *ctx;
+
+ library_init();
+ ctx = SSL_CTX_new(SSLv23_method());
+
+ buf = tor_malloc_zero(1000);
+ tls = tor_malloc_zero(sizeof(tor_tls_t));
+
+ tor_tls_get_state_description(NULL, buf, 20);
+ tt_str_op(buf, OP_EQ, "(No SSL object)");
+
+ SSL_free(tls->ssl);
+ tls->ssl = NULL;
+ tor_tls_get_state_description(tls, buf, 20);
+ tt_str_op(buf, OP_EQ, "(No SSL object)");
+
+ tls->ssl = SSL_new(ctx);
+ tor_tls_get_state_description(tls, buf, 200);
+ tt_str_op(buf, OP_EQ, SSL_STATE_STR " in HANDSHAKE");
+
+ tls->state = TOR_TLS_ST_OPEN;
+ tor_tls_get_state_description(tls, buf, 200);
+ tt_str_op(buf, OP_EQ, SSL_STATE_STR " in OPEN");
+
+ tls->state = TOR_TLS_ST_GOTCLOSE;
+ tor_tls_get_state_description(tls, buf, 200);
+ tt_str_op(buf, OP_EQ, SSL_STATE_STR " in GOTCLOSE");
+
+ tls->state = TOR_TLS_ST_SENTCLOSE;
+ tor_tls_get_state_description(tls, buf, 200);
+ tt_str_op(buf, OP_EQ, SSL_STATE_STR " in SENTCLOSE");
+
+ tls->state = TOR_TLS_ST_CLOSED;
+ tor_tls_get_state_description(tls, buf, 200);
+ tt_str_op(buf, OP_EQ, SSL_STATE_STR " in CLOSED");
+
+ tls->state = TOR_TLS_ST_RENEGOTIATE;
+ tor_tls_get_state_description(tls, buf, 200);
+ tt_str_op(buf, OP_EQ, SSL_STATE_STR " in RENEGOTIATE");
+
+ tls->state = TOR_TLS_ST_BUFFEREVENT;
+ tor_tls_get_state_description(tls, buf, 200);
+ tt_str_op(buf, OP_EQ, SSL_STATE_STR);
+
+ tls->state = 7;
+ tor_tls_get_state_description(tls, buf, 200);
+ tt_str_op(buf, OP_EQ, SSL_STATE_STR " in unknown TLS state");
+
+ done:
+ SSL_CTX_free(ctx);
+ SSL_free(tls->ssl);
+ tor_free(buf);
+ tor_free(tls);
+}
+
+static void
+test_tortls_get_by_ssl(void *ignored)
+{
+ (void)ignored;
+ tor_tls_t *tls;
+ tor_tls_t *res;
+ SSL_CTX *ctx;
+ SSL *ssl;
+
+ library_init();
+ tor_tls_allocate_tor_tls_object_ex_data_index();
+
+ ctx = SSL_CTX_new(SSLv23_method());
+ tls = tor_malloc_zero(sizeof(tor_tls_t));
+ tls->magic = TOR_TLS_MAGIC;
+
+ ssl = SSL_new(ctx);
+
+ res = tor_tls_get_by_ssl(ssl);
+ tt_assert(!res);
+
+ SSL_set_ex_data(ssl, tor_tls_object_ex_data_index, tls);
+
+ res = tor_tls_get_by_ssl(ssl);
+ tt_assert(res == tls);
+
+ done:
+ SSL_free(ssl);
+ SSL_CTX_free(ctx);
+ tor_free(tls);
+}
+
+static void
+test_tortls_allocate_tor_tls_object_ex_data_index(void *ignored)
+{
+ (void)ignored;
+ int first;
+
+ tor_tls_allocate_tor_tls_object_ex_data_index();
+
+ first = tor_tls_object_ex_data_index;
+ tor_tls_allocate_tor_tls_object_ex_data_index();
+ tt_int_op(first, OP_EQ, tor_tls_object_ex_data_index);
+
+ done:
+ (void)0;
+}
+
+static void
+test_tortls_log_one_error(void *ignored)
+{
+ (void)ignored;
+ tor_tls_t *tls;
+ SSL_CTX *ctx;
+ SSL *ssl = NULL;
+
+ library_init();
+
+ ctx = SSL_CTX_new(SSLv23_method());
+ tls = tor_malloc_zero(sizeof(tor_tls_t));
+ setup_capture_of_logs(LOG_INFO);
+
+ tor_tls_log_one_error(NULL, 0, LOG_WARN, 0, "something");
+ expect_log_msg("TLS error while something: "
+ "(null) (in (null):(null):---)\n");
+
+ mock_clean_saved_logs();
+ tor_tls_log_one_error(tls, 0, LOG_WARN, 0, NULL);
+ expect_log_msg("TLS error: (null) "
+ "(in (null):(null):---)\n");
+
+ mock_clean_saved_logs();
+ tls->address = tor_strdup("127.hello");
+ tor_tls_log_one_error(tls, 0, LOG_WARN, 0, NULL);
+ expect_log_msg("TLS error with 127.hello: "
+ "(null) (in (null):(null):---)\n");
+ tor_free(tls->address);
+
+ mock_clean_saved_logs();
+ tls->address = tor_strdup("127.hello");
+ tor_tls_log_one_error(tls, 0, LOG_WARN, 0, "blarg");
+ expect_log_msg("TLS error while blarg with "
+ "127.hello: (null) (in (null):(null):---)\n");
+
+ mock_clean_saved_logs();
+ tor_tls_log_one_error(tls, ERR_PACK(1, 2, 3), LOG_WARN, 0, NULL);
+ expect_log_msg("TLS error with 127.hello: "
+ "BN lib (in unknown library:(null):---)\n");
+
+ mock_clean_saved_logs();
+ tor_tls_log_one_error(tls, ERR_PACK(1, 2, SSL_R_HTTP_REQUEST),
+ LOG_WARN, 0, NULL);
+ expect_log_severity(LOG_INFO);
+
+ mock_clean_saved_logs();
+ tor_tls_log_one_error(tls, ERR_PACK(1, 2, SSL_R_HTTPS_PROXY_REQUEST),
+ LOG_WARN, 0, NULL);
+ expect_log_severity(LOG_INFO);
+
+ mock_clean_saved_logs();
+ tor_tls_log_one_error(tls, ERR_PACK(1, 2, SSL_R_RECORD_LENGTH_MISMATCH),
+ LOG_WARN, 0, NULL);
+ expect_log_severity(LOG_INFO);
+
+#ifndef OPENSSL_1_1_API
+ mock_clean_saved_logs();
+ tor_tls_log_one_error(tls, ERR_PACK(1, 2, SSL_R_RECORD_TOO_LARGE),
+ LOG_WARN, 0, NULL);
+ expect_log_severity(LOG_INFO);
+#endif /* !defined(OPENSSL_1_1_API) */
+
+ mock_clean_saved_logs();
+ tor_tls_log_one_error(tls, ERR_PACK(1, 2, SSL_R_UNKNOWN_PROTOCOL),
+ LOG_WARN, 0, NULL);
+ expect_log_severity(LOG_INFO);
+
+ mock_clean_saved_logs();
+ tor_tls_log_one_error(tls, ERR_PACK(1, 2, SSL_R_UNSUPPORTED_PROTOCOL),
+ LOG_WARN, 0, NULL);
+ expect_log_severity(LOG_INFO);
+
+ tls->ssl = SSL_new(ctx);
+
+ mock_clean_saved_logs();
+ tor_tls_log_one_error(tls, 0, LOG_WARN, 0, NULL);
+ expect_log_msg("TLS error with 127.hello: (null)"
+ " (in (null):(null):" SSL_STATE_STR ")\n");
+
+ done:
+ teardown_capture_of_logs();
+ SSL_free(ssl);
+ SSL_CTX_free(ctx);
+ if (tls && tls->ssl)
+ SSL_free(tls->ssl);
+ if (tls)
+ tor_free(tls->address);
+ tor_free(tls);
+}
+
+#ifndef OPENSSL_OPAQUE
+static void
+test_tortls_get_error(void *ignored)
+{
+ (void)ignored;
+ tor_tls_t *tls;
+ int ret;
+ SSL_CTX *ctx;
+
+ library_init();
+
+ ctx = SSL_CTX_new(SSLv23_method());
+ setup_capture_of_logs(LOG_INFO);
+ tls = tor_malloc_zero(sizeof(tor_tls_t));
+ tls->ssl = SSL_new(ctx);
+ SSL_set_bio(tls->ssl, BIO_new(BIO_s_mem()), NULL);
+
+ ret = tor_tls_get_error(tls, 0, 0, "something", LOG_WARN, 0);
+ tt_int_op(ret, OP_EQ, TOR_TLS_ERROR_IO);
+ expect_log_msg("TLS error: unexpected close while"
+ " something (before/accept initialization)\n");
+
+ mock_clean_saved_logs();
+ ret = tor_tls_get_error(tls, 2, 0, "something", LOG_WARN, 0);
+ tt_int_op(ret, OP_EQ, 0);
+ expect_no_log_entry();
+
+ mock_clean_saved_logs();
+ ret = tor_tls_get_error(tls, 0, 1, "something", LOG_WARN, 0);
+ tt_int_op(ret, OP_EQ, -11);
+ expect_no_log_entry();
+
+ mock_clean_saved_logs();
+ ERR_clear_error();
+ ERR_put_error(ERR_LIB_BN, 2, -1, "somewhere.c", 99);
+ ret = tor_tls_get_error(tls, 0, 0, "something", LOG_WARN, 0);
+ tt_int_op(ret, OP_EQ, TOR_TLS_ERROR_MISC);
+ expect_log_msg("TLS error while something: (null)"
+ " (in bignum routines:(null):before/accept initialization)\n");
+
+ mock_clean_saved_logs();
+ ERR_clear_error();
+ tls->ssl->rwstate = SSL_READING;
+ SSL_get_rbio(tls->ssl)->flags = BIO_FLAGS_READ;
+ ret = tor_tls_get_error(tls, -1, 0, "something", LOG_WARN, 0);
+ tt_int_op(ret, OP_EQ, TOR_TLS_WANTREAD);
+ expect_no_log_entry();
+
+ mock_clean_saved_logs();
+ ERR_clear_error();
+ tls->ssl->rwstate = SSL_READING;
+ SSL_get_rbio(tls->ssl)->flags = BIO_FLAGS_WRITE;
+ ret = tor_tls_get_error(tls, -1, 0, "something", LOG_WARN, 0);
+ tt_int_op(ret, OP_EQ, TOR_TLS_WANTWRITE);
+ expect_no_log_entry();
+
+ mock_clean_saved_logs();
+ ERR_clear_error();
+ tls->ssl->rwstate = 0;
+ tls->ssl->shutdown = SSL_RECEIVED_SHUTDOWN;
+ tls->ssl->s3->warn_alert =SSL_AD_CLOSE_NOTIFY;
+ ret = tor_tls_get_error(tls, 0, 0, "something", LOG_WARN, 0);
+ tt_int_op(ret, OP_EQ, TOR_TLS_CLOSE);
+ expect_log_entry();
+
+ mock_clean_saved_logs();
+ ret = tor_tls_get_error(tls, 0, 2, "something", LOG_WARN, 0);
+ tt_int_op(ret, OP_EQ, -10);
+ expect_no_log_entry();
+
+ mock_clean_saved_logs();
+ ERR_put_error(ERR_LIB_SYS, 2, -1, "somewhere.c", 99);
+ ret = tor_tls_get_error(tls, -1, 0, "something", LOG_WARN, 0);
+ tt_int_op(ret, OP_EQ, -9);
+ expect_log_msg("TLS error while something: (null) (in system library:"
+ "connect:before/accept initialization)\n");
+
+ done:
+ teardown_capture_of_logs();
+ SSL_free(tls->ssl);
+ tor_free(tls);
+ SSL_CTX_free(ctx);
+}
+#endif /* !defined(OPENSSL_OPAQUE) */
+
+static void
+test_tortls_always_accept_verify_cb(void *ignored)
+{
+ (void)ignored;
+ int ret;
+
+ ret = always_accept_verify_cb(0, NULL);
+ tt_int_op(ret, OP_EQ, 1);
+
+ done:
+ (void)0;
+}
+
+#ifndef OPENSSL_OPAQUE
+static void
+test_tortls_x509_cert_free(void *ignored)
+{
+ (void)ignored;
+ tor_x509_cert_t *cert;
+
+ cert = tor_malloc_zero(sizeof(tor_x509_cert_t));
+ tor_x509_cert_free(cert);
+
+ cert = tor_malloc_zero(sizeof(tor_x509_cert_t));
+ cert->cert = X509_new();
+ cert->encoded = tor_malloc_zero(1);
+ tor_x509_cert_free(cert);
+}
+#endif /* !defined(OPENSSL_OPAQUE) */
+
+#ifndef OPENSSL_OPAQUE
+/*
+ * Use only for the matching fake_x509_free() call
+ */
+static X509 *
+fake_x509_malloc(void)
+{
+ return tor_malloc_zero(sizeof(X509));
+}
+
+static void
+fake_x509_free(X509 *cert)
+{
+ if (cert) {
+ if (cert->cert_info) {
+ if (cert->cert_info->key) {
+ if (cert->cert_info->key->pkey) {
+ tor_free(cert->cert_info->key->pkey);
+ }
+ tor_free(cert->cert_info->key);
+ }
+ tor_free(cert->cert_info);
+ }
+ tor_free(cert);
+ }
+}
+#endif
+
+static tor_x509_cert_t *fixed_x509_cert = NULL;
+static tor_x509_cert_t *
+get_peer_cert_mock_return_fixed(tor_tls_t *tls)
+{
+ (void)tls;
+ if (fixed_x509_cert)
+ return tor_x509_cert_dup(fixed_x509_cert);
+ else
+ return NULL;
+}
+
+static void
+test_tortls_cert_matches_key(void *ignored)
+{
+ (void)ignored;
+
+ X509 *cert1 = NULL, *cert2 = NULL, *cert3 = NULL, *cert4 = NULL;
+ tor_x509_cert_t *c1 = NULL, *c2 = NULL, *c3 = NULL, *c4 = NULL;
+ crypto_pk_t *k1 = NULL, *k2 = NULL, *k3 = NULL;
+
+ k1 = pk_generate(1);
+ k2 = pk_generate(2);
+ k3 = pk_generate(3);
+
+ cert1 = tor_tls_create_certificate(k1, k2, "A", "B", 1000);
+ cert2 = tor_tls_create_certificate(k1, k3, "C", "D", 1000);
+ cert3 = tor_tls_create_certificate(k2, k3, "C", "D", 1000);
+ cert4 = tor_tls_create_certificate(k3, k2, "E", "F", 1000);
+
+ tt_assert(cert1 && cert2 && cert3 && cert4);
+
+ c1 = tor_x509_cert_new(cert1); cert1 = NULL;
+ c2 = tor_x509_cert_new(cert2); cert2 = NULL;
+ c3 = tor_x509_cert_new(cert3); cert3 = NULL;
+ c4 = tor_x509_cert_new(cert4); cert4 = NULL;
+
+ tt_assert(c1 && c2 && c3 && c4);
+
+ MOCK(tor_tls_get_peer_cert, get_peer_cert_mock_return_fixed);
+
+ fixed_x509_cert = NULL;
+ /* If the peer has no certificate, it shouldn't match anything. */
+ tt_assert(! tor_tls_cert_matches_key(NULL, c1));
+ tt_assert(! tor_tls_cert_matches_key(NULL, c2));
+ tt_assert(! tor_tls_cert_matches_key(NULL, c3));
+ tt_assert(! tor_tls_cert_matches_key(NULL, c4));
+ fixed_x509_cert = c1;
+ /* If the peer has a certificate, it should match every cert with the same
+ * subject key. */
+ tt_assert(tor_tls_cert_matches_key(NULL, c1));
+ tt_assert(tor_tls_cert_matches_key(NULL, c2));
+ tt_assert(! tor_tls_cert_matches_key(NULL, c3));
+ tt_assert(! tor_tls_cert_matches_key(NULL, c4));
+
+ done:
+ tor_x509_cert_free(c1);
+ tor_x509_cert_free(c2);
+ tor_x509_cert_free(c3);
+ tor_x509_cert_free(c4);
+ if (cert1) X509_free(cert1);
+ if (cert2) X509_free(cert2);
+ if (cert3) X509_free(cert3);
+ if (cert4) X509_free(cert4);
+ crypto_pk_free(k1);
+ crypto_pk_free(k2);
+ crypto_pk_free(k3);
+ UNMOCK(tor_tls_get_peer_cert);
+}
+
+#ifndef OPENSSL_OPAQUE
+static void
+test_tortls_cert_get_key(void *ignored)
+{
+ (void)ignored;
+ tor_x509_cert_t *cert = NULL;
+ crypto_pk_t *res = NULL;
+ cert = tor_malloc_zero(sizeof(tor_x509_cert_t));
+ X509 *key = NULL;
+ key = fake_x509_malloc();
+ key->references = 1;
+
+ res = tor_tls_cert_get_key(cert);
+ tt_assert(!res);
+
+ cert->cert = key;
+ key->cert_info = tor_malloc_zero(sizeof(X509_CINF));
+ key->cert_info->key = tor_malloc_zero(sizeof(X509_PUBKEY));
+ key->cert_info->key->pkey = tor_malloc_zero(sizeof(EVP_PKEY));
+ key->cert_info->key->pkey->references = 1;
+ key->cert_info->key->pkey->type = 2;
+ res = tor_tls_cert_get_key(cert);
+ tt_assert(!res);
+
+ done:
+ fake_x509_free(key);
+ tor_free(cert);
+ crypto_pk_free(res);
+}
+#endif /* !defined(OPENSSL_OPAQUE) */
+
+static void
+test_tortls_get_my_client_auth_key(void *ignored)
+{
+ (void)ignored;
+ crypto_pk_t *ret;
+ crypto_pk_t *expected;
+ tor_tls_context_t *ctx;
+ RSA *k = RSA_new();
+
+ ctx = tor_malloc_zero(sizeof(tor_tls_context_t));
+ expected = crypto_new_pk_from_openssl_rsa_(k);
+ ctx->auth_key = expected;
+
+ client_tls_context = NULL;
+ ret = tor_tls_get_my_client_auth_key();
+ tt_assert(!ret);
+
+ client_tls_context = ctx;
+ ret = tor_tls_get_my_client_auth_key();
+ tt_assert(ret == expected);
+
+ done:
+ crypto_pk_free(expected);
+ tor_free(ctx);
+}
+
+#ifndef HAVE_SSL_GET_CLIENT_CIPHERS
+static SSL_CIPHER *
+get_cipher_by_name(const char *name)
+{
+ int i;
+ const SSL_METHOD *method = SSLv23_method();
+ int num = method->num_ciphers();
+
+ for (i = 0; i < num; ++i) {
+ const SSL_CIPHER *cipher = method->get_cipher(i);
+ const char *ciphername = SSL_CIPHER_get_name(cipher);
+ if (!strcmp(ciphername, name)) {
+ return (SSL_CIPHER *)cipher;
+ }
+ }
+
+ return NULL;
+}
+#endif /* !defined(HAVE_SSL_GET_CLIENT_CIPHERS) */
+
+#ifndef OPENSSL_OPAQUE
+static void
+test_tortls_get_ciphersuite_name(void *ignored)
+{
+ (void)ignored;
+ const char *ret;
+ tor_tls_t *ctx;
+ ctx = tor_malloc_zero(sizeof(tor_tls_t));
+ ctx->ssl = tor_malloc_zero(sizeof(SSL));
+
+ ret = tor_tls_get_ciphersuite_name(ctx);
+ tt_str_op(ret, OP_EQ, "(NONE)");
+
+ done:
+ tor_free(ctx->ssl);
+ tor_free(ctx);
+}
+
+static SSL_CIPHER *
+get_cipher_by_id(uint16_t id)
+{
+ int i;
+ const SSL_METHOD *method = SSLv23_method();
+ int num = method->num_ciphers();
+ for (i = 0; i < num; ++i) {
+ const SSL_CIPHER *cipher = method->get_cipher(i);
+ if (id == (SSL_CIPHER_get_id(cipher) & 0xffff)) {
+ return (SSL_CIPHER *)cipher;
+ }
+ }
+
+ return NULL;
+}
+
+static void
+test_tortls_classify_client_ciphers(void *ignored)
+{
+ (void)ignored;
+ int i;
+ int ret;
+ SSL_CTX *ctx;
+ SSL *ssl;
+ tor_tls_t *tls;
+ STACK_OF(SSL_CIPHER) *ciphers;
+ SSL_CIPHER *tmp_cipher;
+
+ library_init();
+
+ tor_tls_allocate_tor_tls_object_ex_data_index();
+
+ tls = tor_malloc_zero(sizeof(tor_tls_t));
+ tls->magic = TOR_TLS_MAGIC;
+
+ ctx = SSL_CTX_new(TLSv1_method());
+ ssl = SSL_new(ctx);
+ tls->ssl = ssl;
+
+ ciphers = sk_SSL_CIPHER_new_null();
+
+ ret = tor_tls_classify_client_ciphers(ssl, NULL);
+ tt_int_op(ret, OP_EQ, -1);
+
+ SSL_set_ex_data(ssl, tor_tls_object_ex_data_index, tls);
+ tls->client_cipher_list_type = 42;
+
+ ret = tor_tls_classify_client_ciphers(ssl, NULL);
+ tt_int_op(ret, OP_EQ, 42);
+
+ tls->client_cipher_list_type = 0;
+ ret = tor_tls_classify_client_ciphers(ssl, ciphers);
+ tt_int_op(ret, OP_EQ, 1);
+ tt_int_op(tls->client_cipher_list_type, OP_EQ, 1);
+
+ tls->client_cipher_list_type = 0;
+ ret = tor_tls_classify_client_ciphers(ssl, SSL_get_ciphers(ssl));
+ tt_int_op(ret, OP_EQ, 3);
+ tt_int_op(tls->client_cipher_list_type, OP_EQ, 3);
+
+ SSL_CIPHER *one = get_cipher_by_name(TLS1_TXT_DHE_RSA_WITH_AES_128_SHA),
+ *two = get_cipher_by_name(TLS1_TXT_DHE_RSA_WITH_AES_256_SHA),
+ *three = get_cipher_by_name(SSL3_TXT_EDH_RSA_DES_192_CBC3_SHA),
+ *four = NULL;
+ sk_SSL_CIPHER_push(ciphers, one);
+ sk_SSL_CIPHER_push(ciphers, two);
+ sk_SSL_CIPHER_push(ciphers, three);
+ sk_SSL_CIPHER_push(ciphers, four);
+
+ tls->client_cipher_list_type = 0;
+ ret = tor_tls_classify_client_ciphers(ssl, ciphers);
+ tt_int_op(ret, OP_EQ, 1);
+ tt_int_op(tls->client_cipher_list_type, OP_EQ, 1);
+
+ sk_SSL_CIPHER_zero(ciphers);
+
+ one = get_cipher_by_name("ECDHE-RSA-AES256-GCM-SHA384");
+ tt_assert(one);
+ one->id = 0x00ff;
+ two = get_cipher_by_name("ECDHE-RSA-AES128-GCM-SHA256");
+ tt_assert(two);
+ two->id = 0x0000;
+ sk_SSL_CIPHER_push(ciphers, one);
+ tls->client_cipher_list_type = 0;
+ ret = tor_tls_classify_client_ciphers(ssl, ciphers);
+ tt_int_op(ret, OP_EQ, 3);
+ tt_int_op(tls->client_cipher_list_type, OP_EQ, 3);
+
+ sk_SSL_CIPHER_push(ciphers, two);
+ tls->client_cipher_list_type = 0;
+ ret = tor_tls_classify_client_ciphers(ssl, ciphers);
+ tt_int_op(ret, OP_EQ, 3);
+ tt_int_op(tls->client_cipher_list_type, OP_EQ, 3);
+
+ one->id = 0xC00A;
+ tls->client_cipher_list_type = 0;
+ ret = tor_tls_classify_client_ciphers(ssl, ciphers);
+ tt_int_op(ret, OP_EQ, 3);
+ tt_int_op(tls->client_cipher_list_type, OP_EQ, 3);
+
+ sk_SSL_CIPHER_zero(ciphers);
+ for (i=0; v2_cipher_list[i]; i++) {
+ tmp_cipher = get_cipher_by_id(v2_cipher_list[i]);
+ tt_assert(tmp_cipher);
+ sk_SSL_CIPHER_push(ciphers, tmp_cipher);
+ }
+ tls->client_cipher_list_type = 0;
+ ret = tor_tls_classify_client_ciphers(ssl, ciphers);
+ tt_int_op(ret, OP_EQ, 2);
+ tt_int_op(tls->client_cipher_list_type, OP_EQ, 2);
+
+ done:
+ sk_SSL_CIPHER_free(ciphers);
+ SSL_free(tls->ssl);
+ tor_free(tls);
+ SSL_CTX_free(ctx);
+}
+#endif /* !defined(OPENSSL_OPAQUE) */
+
+static void
+test_tortls_client_is_using_v2_ciphers(void *ignored)
+{
+ (void)ignored;
+
+#ifdef HAVE_SSL_GET_CLIENT_CIPHERS
+ tt_skip();
+ done:
+ (void)1;
+#else
+ int ret;
+ SSL_CTX *ctx;
+ SSL *ssl;
+ SSL_SESSION *sess;
+ STACK_OF(SSL_CIPHER) *ciphers;
+
+ library_init();
+
+ ctx = SSL_CTX_new(TLSv1_method());
+ ssl = SSL_new(ctx);
+ sess = SSL_SESSION_new();
+
+ ret = tor_tls_client_is_using_v2_ciphers(ssl);
+ tt_int_op(ret, OP_EQ, -1);
+
+ ssl->session = sess;
+ ret = tor_tls_client_is_using_v2_ciphers(ssl);
+ tt_int_op(ret, OP_EQ, 0);
+
+ ciphers = sk_SSL_CIPHER_new_null();
+ SSL_CIPHER *one = get_cipher_by_name("ECDHE-RSA-AES256-GCM-SHA384");
+ tt_assert(one);
+ one->id = 0x00ff;
+ sk_SSL_CIPHER_push(ciphers, one);
+ sess->ciphers = ciphers;
+ ret = tor_tls_client_is_using_v2_ciphers(ssl);
+ tt_int_op(ret, OP_EQ, 1);
+ done:
+ SSL_free(ssl);
+ SSL_CTX_free(ctx);
+#endif /* defined(HAVE_SSL_GET_CLIENT_CIPHERS) */
+}
+
+#ifndef OPENSSL_OPAQUE
+static int fixed_ssl_pending_result = 0;
+
+static int
+fixed_ssl_pending(const SSL *ignored)
+{
+ (void)ignored;
+ return fixed_ssl_pending_result;
+}
+
+static void
+test_tortls_get_pending_bytes(void *ignored)
+{
+ (void)ignored;
+ int ret;
+ tor_tls_t *tls;
+ SSL_METHOD *method;
+
+ tls = tor_malloc_zero(sizeof(tor_tls_t));
+ tls->ssl = tor_malloc_zero(sizeof(SSL));
+ method = tor_malloc_zero(sizeof(SSL_METHOD));
+ method->ssl_pending = fixed_ssl_pending;
+ tls->ssl->method = method;
+
+ fixed_ssl_pending_result = 42;
+ ret = tor_tls_get_pending_bytes(tls);
+ tt_int_op(ret, OP_EQ, 42);
+
+ done:
+ tor_free(method);
+ tor_free(tls->ssl);
+ tor_free(tls);
+}
+#endif /* !defined(OPENSSL_OPAQUE) */
+
+#ifndef OPENSSL_OPAQUE
+static void
+test_tortls_SSL_SESSION_get_master_key(void *ignored)
+{
+ (void)ignored;
+ size_t ret;
+ tor_tls_t *tls;
+ uint8_t *out;
+ out = tor_malloc_zero(1);
+ tls = tor_malloc_zero(sizeof(tor_tls_t));
+ tls->ssl = tor_malloc_zero(sizeof(SSL));
+ tls->ssl->session = tor_malloc_zero(sizeof(SSL_SESSION));
+ tls->ssl->session->master_key_length = 1;
+
+#ifndef HAVE_SSL_SESSION_GET_MASTER_KEY
+ tls->ssl->session->master_key[0] = 43;
+ ret = SSL_SESSION_get_master_key(tls->ssl->session, out, 0);
+ tt_int_op(ret, OP_EQ, 1);
+ tt_int_op(out[0], OP_EQ, 0);
+
+ ret = SSL_SESSION_get_master_key(tls->ssl->session, out, 1);
+ tt_int_op(ret, OP_EQ, 1);
+ tt_int_op(out[0], OP_EQ, 43);
+
+ done:
+#endif /* !defined(HAVE_SSL_SESSION_GET_MASTER_KEY) */
+ tor_free(tls->ssl->session);
+ tor_free(tls->ssl);
+ tor_free(tls);
+ tor_free(out);
+}
+#endif /* !defined(OPENSSL_OPAQUE) */
+
+#ifndef OPENSSL_OPAQUE
+static void
+test_tortls_get_tlssecrets(void *ignored)
+{
+ (void)ignored;
+ int ret;
+ uint8_t *secret_out = tor_malloc_zero(DIGEST256_LEN);
+ tor_tls_t *tls;
+ tls = tor_malloc_zero(sizeof(tor_tls_t));
+ tls->ssl = tor_malloc_zero(sizeof(SSL));
+ tls->ssl->session = tor_malloc_zero(sizeof(SSL_SESSION));
+ tls->ssl->session->master_key_length = 1;
+ tls->ssl->s3 = tor_malloc_zero(sizeof(SSL3_STATE));
+
+ ret = tor_tls_get_tlssecrets(tls, secret_out);
+ tt_int_op(ret, OP_EQ, 0);
+
+ done:
+ tor_free(secret_out);
+ tor_free(tls->ssl->s3);
+ tor_free(tls->ssl->session);
+ tor_free(tls->ssl);
+ tor_free(tls);
+}
+#endif /* !defined(OPENSSL_OPAQUE) */
+
+#ifndef OPENSSL_OPAQUE
+static void
+test_tortls_get_buffer_sizes(void *ignored)
+{
+ (void)ignored;
+ int ret;
+ tor_tls_t *tls;
+ size_t rbuf_c=-1, rbuf_b=-1, wbuf_c=-1, wbuf_b=-1;
+
+ tls = tor_malloc_zero(sizeof(tor_tls_t));
+ tls->ssl = tor_malloc_zero(sizeof(SSL));
+ tls->ssl->s3 = tor_malloc_zero(sizeof(SSL3_STATE));
+
+ tls->ssl->s3->rbuf.buf = NULL;
+ tls->ssl->s3->rbuf.len = 1;
+ tls->ssl->s3->rbuf.offset = 0;
+ tls->ssl->s3->rbuf.left = 42;
+
+ tls->ssl->s3->wbuf.buf = NULL;
+ tls->ssl->s3->wbuf.len = 2;
+ tls->ssl->s3->wbuf.offset = 0;
+ tls->ssl->s3->wbuf.left = 43;
+
+ ret = tor_tls_get_buffer_sizes(tls, &rbuf_c, &rbuf_b, &wbuf_c, &wbuf_b);
+#if OPENSSL_VERSION_NUMBER >= OPENSSL_V_SERIES(1,1,0)
+ tt_int_op(ret, OP_EQ, -1);
+#else
+ tt_int_op(ret, OP_EQ, 0);
+ tt_int_op(rbuf_c, OP_EQ, 0);
+ tt_int_op(wbuf_c, OP_EQ, 0);
+ tt_int_op(rbuf_b, OP_EQ, 42);
+ tt_int_op(wbuf_b, OP_EQ, 43);
+
+ tls->ssl->s3->rbuf.buf = tor_malloc_zero(1);
+ tls->ssl->s3->wbuf.buf = tor_malloc_zero(1);
+ ret = tor_tls_get_buffer_sizes(tls, &rbuf_c, &rbuf_b, &wbuf_c, &wbuf_b);
+ tt_int_op(ret, OP_EQ, 0);
+ tt_int_op(rbuf_c, OP_EQ, 1);
+ tt_int_op(wbuf_c, OP_EQ, 2);
+
+#endif /* OPENSSL_VERSION_NUMBER >= OPENSSL_V_SERIES(1,1,0) */
+
+ done:
+ tor_free(tls->ssl->s3->rbuf.buf);
+ tor_free(tls->ssl->s3->wbuf.buf);
+ tor_free(tls->ssl->s3);
+ tor_free(tls->ssl);
+ tor_free(tls);
+}
+#endif /* !defined(OPENSSL_OPAQUE) */
+
+#ifndef OPENSSL_OPAQUE
+typedef struct cert_pkey_st_local
+{
+ X509 *x509;
+ EVP_PKEY *privatekey;
+ const EVP_MD *digest;
+} CERT_PKEY_local;
+
+typedef struct sess_cert_st_local
+{
+ STACK_OF(X509) *cert_chain;
+ int peer_cert_type;
+ CERT_PKEY_local *peer_key;
+ CERT_PKEY_local peer_pkeys[8];
+ int references;
+} SESS_CERT_local;
+
+static void
+test_tortls_try_to_extract_certs_from_tls(void *ignored)
+{
+ (void)ignored;
+ tor_tls_t *tls;
+ X509 *cert = NULL, *id_cert = NULL, *c1 = NULL, *c2 = NULL;
+ SESS_CERT_local *sess = NULL;
+
+ c1 = read_cert_from(validCertString);
+ c2 = read_cert_from(caCertString);
+
+ tls = tor_malloc_zero(sizeof(tor_tls_t));
+ tls->ssl = tor_malloc_zero(sizeof(SSL));
+ tls->ssl->session = tor_malloc_zero(sizeof(SSL_SESSION));
+ sess = tor_malloc_zero(sizeof(SESS_CERT_local));
+ tls->ssl->session->sess_cert = (void *)sess;
+
+ try_to_extract_certs_from_tls(LOG_WARN, tls, &cert, &id_cert);
+ tt_assert(!cert);
+ tt_assert(!id_cert);
+
+ tls->ssl->session->peer = c1;
+ try_to_extract_certs_from_tls(LOG_WARN, tls, &cert, &id_cert);
+ tt_assert(cert == c1);
+ tt_assert(!id_cert);
+ X509_free(cert); /* decrease refcnt */
+
+ sess->cert_chain = sk_X509_new_null();
+ try_to_extract_certs_from_tls(LOG_WARN, tls, &cert, &id_cert);
+ tt_assert(cert == c1);
+ tt_assert(!id_cert);
+ X509_free(cert); /* decrease refcnt */
+
+ sk_X509_push(sess->cert_chain, c1);
+ sk_X509_push(sess->cert_chain, c2);
+
+ try_to_extract_certs_from_tls(LOG_WARN, tls, &cert, &id_cert);
+ tt_assert(cert == c1);
+ tt_assert(id_cert);
+ X509_free(cert); /* decrease refcnt */
+ X509_free(id_cert); /* decrease refcnt */
+
+ done:
+ sk_X509_free(sess->cert_chain);
+ tor_free(sess);
+ tor_free(tls->ssl->session);
+ tor_free(tls->ssl);
+ tor_free(tls);
+ X509_free(c1);
+ X509_free(c2);
+}
+#endif /* !defined(OPENSSL_OPAQUE) */
+
+#ifndef OPENSSL_OPAQUE
+static void
+test_tortls_get_peer_cert(void *ignored)
+{
+ (void)ignored;
+ tor_x509_cert_t *ret;
+ tor_tls_t *tls;
+ X509 *cert = NULL;
+
+ cert = read_cert_from(validCertString);
+
+ tls = tor_malloc_zero(sizeof(tor_tls_t));
+ tls->ssl = tor_malloc_zero(sizeof(SSL));
+ tls->ssl->session = tor_malloc_zero(sizeof(SSL_SESSION));
+
+ ret = tor_tls_get_peer_cert(tls);
+ tt_assert(!ret);
+
+ tls->ssl->session->peer = cert;
+ ret = tor_tls_get_peer_cert(tls);
+ tt_assert(ret);
+ tt_assert(ret->cert == cert);
+
+ done:
+ tor_x509_cert_free(ret);
+ tor_free(tls->ssl->session);
+ tor_free(tls->ssl);
+ tor_free(tls);
+ X509_free(cert);
+}
+#endif /* !defined(OPENSSL_OPAQUE) */
+
+#ifndef OPENSSL_OPAQUE
+static void
+test_tortls_peer_has_cert(void *ignored)
+{
+ (void)ignored;
+ int ret;
+ tor_tls_t *tls;
+ X509 *cert = NULL;
+
+ cert = read_cert_from(validCertString);
+
+ tls = tor_malloc_zero(sizeof(tor_tls_t));
+ tls->ssl = tor_malloc_zero(sizeof(SSL));
+ tls->ssl->session = tor_malloc_zero(sizeof(SSL_SESSION));
+
+ ret = tor_tls_peer_has_cert(tls);
+ tt_assert(!ret);
+
+ tls->ssl->session->peer = cert;
+ ret = tor_tls_peer_has_cert(tls);
+ tt_assert(ret);
+
+ done:
+ tor_free(tls->ssl->session);
+ tor_free(tls->ssl);
+ tor_free(tls);
+ X509_free(cert);
+}
+#endif /* !defined(OPENSSL_OPAQUE) */
+
+static void
+test_tortls_get_write_overhead_ratio(void *ignored)
+{
+ (void)ignored;
+ double ret;
+
+ total_bytes_written_over_tls = 0;
+ ret = tls_get_write_overhead_ratio();
+ tt_double_op(fabs(ret - 1.0), OP_LT, 1E-12);
+
+ total_bytes_written_by_tls = 10;
+ total_bytes_written_over_tls = 1;
+ ret = tls_get_write_overhead_ratio();
+ tt_double_op(fabs(ret - 10.0), OP_LT, 1E-12);
+
+ total_bytes_written_by_tls = 10;
+ total_bytes_written_over_tls = 2;
+ ret = tls_get_write_overhead_ratio();
+ tt_double_op(fabs(ret - 5.0), OP_LT, 1E-12);
+
+ done:
+ (void)0;
+}
+
+static void
+test_tortls_is_server(void *ignored)
+{
+ (void)ignored;
+ tor_tls_t *tls;
+ int ret;
+
+ tls = tor_malloc_zero(sizeof(tor_tls_t));
+ tls->isServer = 1;
+ ret = tor_tls_is_server(tls);
+ tt_int_op(ret, OP_EQ, 1);
+
+ done:
+ tor_free(tls);
+}
+
+#ifndef OPENSSL_OPAQUE
+static void
+test_tortls_session_secret_cb(void *ignored)
+{
+ (void)ignored;
+ tor_tls_t *tls;
+ SSL_CTX *ctx;
+ STACK_OF(SSL_CIPHER) *ciphers = NULL;
+ SSL_CIPHER *one;
+
+ library_init();
+
+ tor_tls_allocate_tor_tls_object_ex_data_index();
+
+ tls = tor_malloc_zero(sizeof(tor_tls_t));
+
+ tls->magic = TOR_TLS_MAGIC;
+
+ ctx = SSL_CTX_new(TLSv1_method());
+ tls->ssl = SSL_new(ctx);
+ SSL_set_ex_data(tls->ssl, tor_tls_object_ex_data_index, tls);
+
+ SSL_set_session_secret_cb(tls->ssl, tor_tls_session_secret_cb, NULL);
+
+ tor_tls_session_secret_cb(tls->ssl, NULL, NULL, NULL, NULL, NULL);
+ tt_assert(!tls->ssl->tls_session_secret_cb);
+
+ one = get_cipher_by_name("ECDHE-RSA-AES256-GCM-SHA384");
+ one->id = 0x00ff;
+ ciphers = sk_SSL_CIPHER_new_null();
+ sk_SSL_CIPHER_push(ciphers, one);
+
+ tls->client_cipher_list_type = 0;
+ tor_tls_session_secret_cb(tls->ssl, NULL, NULL, ciphers, NULL, NULL);
+ tt_assert(!tls->ssl->tls_session_secret_cb);
+
+ done:
+ sk_SSL_CIPHER_free(ciphers);
+ SSL_free(tls->ssl);
+ SSL_CTX_free(ctx);
+ tor_free(tls);
+}
+#endif /* !defined(OPENSSL_OPAQUE) */
+
+#ifndef OPENSSL_OPAQUE
+/* TODO: It seems block_renegotiation and unblock_renegotiation and
+ * using different blags. This might not be correct */
+static void
+test_tortls_block_renegotiation(void *ignored)
+{
+ (void)ignored;
+ tor_tls_t *tls;
+
+ tls = tor_malloc_zero(sizeof(tor_tls_t));
+ tls->ssl = tor_malloc_zero(sizeof(SSL));
+ tls->ssl->s3 = tor_malloc_zero(sizeof(SSL3_STATE));
+#ifndef SUPPORT_UNSAFE_RENEGOTIATION_FLAG
+#define SSL3_FLAGS_ALLOW_UNSAFE_LEGACY_RENEGOTIATION 0
+#endif
+
+ tls->ssl->s3->flags = SSL3_FLAGS_ALLOW_UNSAFE_LEGACY_RENEGOTIATION;
+
+ tor_tls_block_renegotiation(tls);
+
+#ifndef OPENSSL_1_1_API
+ tt_assert(!(tls->ssl->s3->flags &
+ SSL3_FLAGS_ALLOW_UNSAFE_LEGACY_RENEGOTIATION));
+#endif
+
+ done:
+ tor_free(tls->ssl->s3);
+ tor_free(tls->ssl);
+ tor_free(tls);
+}
+
+static void
+test_tortls_unblock_renegotiation(void *ignored)
+{
+ (void)ignored;
+ tor_tls_t *tls;
+
+ tls = tor_malloc_zero(sizeof(tor_tls_t));
+ tls->ssl = tor_malloc_zero(sizeof(SSL));
+ tor_tls_unblock_renegotiation(tls);
+
+ tt_uint_op(SSL_get_options(tls->ssl) &
+ SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION, OP_EQ,
+ SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION);
+
+ done:
+ tor_free(tls->ssl);
+ tor_free(tls);
+}
+#endif /* !defined(OPENSSL_OPAQUE) */
+
+#ifndef OPENSSL_OPAQUE
+static void
+test_tortls_assert_renegotiation_unblocked(void *ignored)
+{
+ (void)ignored;
+ tor_tls_t *tls;
+
+ tls = tor_malloc_zero(sizeof(tor_tls_t));
+ tls->ssl = tor_malloc_zero(sizeof(SSL));
+ tor_tls_unblock_renegotiation(tls);
+ tor_tls_assert_renegotiation_unblocked(tls);
+ /* No assertion here - this test will fail if tor_assert is turned on
+ * and things are bad. */
+
+ tor_free(tls->ssl);
+ tor_free(tls);
+}
+#endif /* !defined(OPENSSL_OPAQUE) */
+
+static void
+test_tortls_set_logged_address(void *ignored)
+{
+ (void)ignored;
+ tor_tls_t *tls;
+
+ tls = tor_malloc_zero(sizeof(tor_tls_t));
+
+ tor_tls_set_logged_address(tls, "foo bar");
+
+ tt_str_op(tls->address, OP_EQ, "foo bar");
+
+ tor_tls_set_logged_address(tls, "foo bar 2");
+ tt_str_op(tls->address, OP_EQ, "foo bar 2");
+
+ done:
+ tor_free(tls->address);
+ tor_free(tls);
+}
+
+#ifndef OPENSSL_OPAQUE
+static void
+example_cb(tor_tls_t *t, void *arg)
+{
+ (void)t;
+ (void)arg;
+}
+
+static void
+test_tortls_set_renegotiate_callback(void *ignored)
+{
+ (void)ignored;
+ tor_tls_t *tls;
+ const char *arg = "hello";
+
+ tls = tor_malloc_zero(sizeof(tor_tls_t));
+ tls->ssl = tor_malloc_zero(sizeof(SSL));
+
+ tor_tls_set_renegotiate_callback(tls, example_cb, (void*)arg);
+ tt_assert(tls->negotiated_callback == example_cb);
+ tt_assert(tls->callback_arg == arg);
+ tt_assert(!tls->got_renegotiate);
+
+ /* Assumes V2_HANDSHAKE_SERVER */
+ tt_assert(tls->ssl->info_callback == tor_tls_server_info_callback);
+
+ tor_tls_set_renegotiate_callback(tls, NULL, (void*)arg);
+ tt_assert(tls->ssl->info_callback == tor_tls_debug_state_callback);
+
+ done:
+ tor_free(tls->ssl);
+ tor_free(tls);
+}
+#endif /* !defined(OPENSSL_OPAQUE) */
+
+#ifndef OPENSSL_OPAQUE
+static SSL_CIPHER *fixed_cipher1 = NULL;
+static SSL_CIPHER *fixed_cipher2 = NULL;
+static const SSL_CIPHER *
+fake_get_cipher(unsigned ncipher)
+{
+
+ switch (ncipher) {
+ case 1:
+ return fixed_cipher1;
+ case 2:
+ return fixed_cipher2;
+ default:
+ return NULL;
+ }
+}
+#endif /* !defined(OPENSSL_OPAQUE) */
+
+#ifndef OPENSSL_OPAQUE
+static void
+test_tortls_find_cipher_by_id(void *ignored)
+{
+ (void)ignored;
+ int ret;
+ SSL *ssl;
+ SSL_CTX *ctx;
+ const SSL_METHOD *m = TLSv1_method();
+ SSL_METHOD *empty_method = tor_malloc_zero(sizeof(SSL_METHOD));
+
+ fixed_cipher1 = tor_malloc_zero(sizeof(SSL_CIPHER));
+ fixed_cipher2 = tor_malloc_zero(sizeof(SSL_CIPHER));
+ fixed_cipher2->id = 0xC00A;
+
+ library_init();
+
+ ctx = SSL_CTX_new(m);
+ ssl = SSL_new(ctx);
+
+ ret = find_cipher_by_id(ssl, NULL, 0xC00A);
+ tt_int_op(ret, OP_EQ, 1);
+
+ ret = find_cipher_by_id(ssl, m, 0xC00A);
+ tt_int_op(ret, OP_EQ, 1);
+
+ ret = find_cipher_by_id(ssl, m, 0xFFFF);
+ tt_int_op(ret, OP_EQ, 0);
+
+ ret = find_cipher_by_id(ssl, empty_method, 0xC00A);
+ tt_int_op(ret, OP_EQ, 1);
+
+ ret = find_cipher_by_id(ssl, empty_method, 0xFFFF);
+#ifdef HAVE_SSL_CIPHER_FIND
+ tt_int_op(ret, OP_EQ, 0);
+#else
+ tt_int_op(ret, OP_EQ, 1);
+#endif
+
+ empty_method->get_cipher = fake_get_cipher;
+ ret = find_cipher_by_id(ssl, empty_method, 0xC00A);
+ tt_int_op(ret, OP_EQ, 1);
+
+ empty_method->get_cipher = m->get_cipher;
+ empty_method->num_ciphers = m->num_ciphers;
+ ret = find_cipher_by_id(ssl, empty_method, 0xC00A);
+ tt_int_op(ret, OP_EQ, 1);
+
+ empty_method->get_cipher = fake_get_cipher;
+ empty_method->num_ciphers = m->num_ciphers;
+ ret = find_cipher_by_id(ssl, empty_method, 0xC00A);
+ tt_int_op(ret, OP_EQ, 1);
+
+ empty_method->num_ciphers = fake_num_ciphers;
+ ret = find_cipher_by_id(ssl, empty_method, 0xC00A);
+#ifdef HAVE_SSL_CIPHER_FIND
+ tt_int_op(ret, OP_EQ, 1);
+#else
+ tt_int_op(ret, OP_EQ, 0);
+#endif
+
+ done:
+ tor_free(empty_method);
+ SSL_free(ssl);
+ SSL_CTX_free(ctx);
+ tor_free(fixed_cipher1);
+}
+#endif /* !defined(OPENSSL_OPAQUE) */
+
+#ifndef OPENSSL_OPAQUE
+static void
+test_tortls_debug_state_callback(void *ignored)
+{
+ (void)ignored;
+ SSL *ssl;
+ char *buf = tor_malloc_zero(1000);
+ int n;
+
+ setup_capture_of_logs(LOG_DEBUG);
+
+ ssl = tor_malloc_zero(sizeof(SSL));
+
+ tor_tls_debug_state_callback(ssl, 32, 45);
+
+ n = tor_snprintf(buf, 1000, "SSL %p is now in state unknown"
+ " state [type=32,val=45].\n", ssl);
+ /* tor's snprintf returns -1 on error */
+ tt_int_op(n, OP_NE, -1);
+ expect_log_msg(buf);
+
+ done:
+ teardown_capture_of_logs();
+ tor_free(buf);
+ tor_free(ssl);
+}
+#endif /* !defined(OPENSSL_OPAQUE) */
+
+#ifndef OPENSSL_OPAQUE
+static void
+test_tortls_server_info_callback(void *ignored)
+{
+ (void)ignored;
+ tor_tls_t *tls;
+ SSL_CTX *ctx;
+ SSL *ssl;
+
+ library_init();
+
+ ctx = SSL_CTX_new(TLSv1_method());
+ ssl = SSL_new(ctx);
+
+ tor_tls_allocate_tor_tls_object_ex_data_index();
+
+ tls = tor_malloc_zero(sizeof(tor_tls_t));
+ tls->magic = TOR_TLS_MAGIC;
+ tls->ssl = ssl;
+
+ setup_full_capture_of_logs(LOG_WARN);
+ SSL_set_state(ssl, SSL3_ST_SW_SRVR_HELLO_A);
+ mock_clean_saved_logs();
+ tor_tls_server_info_callback(ssl, SSL_CB_ACCEPT_LOOP, 0);
+ expect_single_log_msg("Couldn't look up the tls for an SSL*. How odd!\n");
+
+ SSL_set_state(ssl, SSL3_ST_SW_SRVR_HELLO_B);
+ mock_clean_saved_logs();
+ tor_tls_server_info_callback(ssl, SSL_CB_ACCEPT_LOOP, 0);
+ expect_single_log_msg("Couldn't look up the tls for an SSL*. How odd!\n");
+
+ SSL_set_state(ssl, 99);
+ mock_clean_saved_logs();
+ tor_tls_server_info_callback(ssl, SSL_CB_ACCEPT_LOOP, 0);
+ expect_no_log_entry();
+ teardown_capture_of_logs();
+
+ SSL_set_ex_data(tls->ssl, tor_tls_object_ex_data_index, tls);
+ SSL_set_state(ssl, SSL3_ST_SW_SRVR_HELLO_B);
+ tls->negotiated_callback = 0;
+ //tls->server_handshake_count = 120;
+ tor_tls_server_info_callback(ssl, SSL_CB_ACCEPT_LOOP, 0);
+ //tt_int_op(tls->server_handshake_count, OP_EQ, 121);
+
+ //tls->server_handshake_count = 127;
+ tls->negotiated_callback = (void *)1;
+ tor_tls_server_info_callback(ssl, SSL_CB_ACCEPT_LOOP, 0);
+ //tt_int_op(tls->server_handshake_count, OP_EQ, 127);
+ tt_int_op(tls->got_renegotiate, OP_EQ, 1);
+
+ tls->ssl->session = SSL_SESSION_new();
+ tls->wasV2Handshake = 0;
+ tor_tls_server_info_callback(ssl, SSL_CB_ACCEPT_LOOP, 0);
+ tt_int_op(tls->wasV2Handshake, OP_EQ, 0);
+
+ done:
+ teardown_capture_of_logs();
+ SSL_free(ssl);
+ SSL_CTX_free(ctx);
+ tor_free(tls);
+}
+#endif /* !defined(OPENSSL_OPAQUE) */
+
+#ifndef OPENSSL_OPAQUE
+static int fixed_ssl_read_result_index;
+static int fixed_ssl_read_result[5];
+
+static int
+fixed_ssl_read(SSL *s, void *buf, int len)
+{
+ (void)s;
+ (void)buf;
+ (void)len;
+ return fixed_ssl_read_result[fixed_ssl_read_result_index++];
+}
+
+static int
+dummy_handshake_func(SSL *s)
+{
+ (void)s;
+ return 1;
+}
+
+static int negotiated_callback_called;
+
+static void
+negotiated_callback_setter(tor_tls_t *t, void *arg)
+{
+ (void)t;
+ (void)arg;
+ negotiated_callback_called++;
+}
+
+static void
+test_tortls_read(void *ignored)
+{
+ (void)ignored;
+ int ret;
+ tor_tls_t *tls;
+ char buf[100];
+ SSL_METHOD *method = give_me_a_test_method();
+ setup_capture_of_logs(LOG_WARN);
+
+ tls = tor_malloc_zero(sizeof(tor_tls_t));
+ tls->ssl = tor_malloc_zero(sizeof(SSL));
+ tls->state = TOR_TLS_ST_OPEN;
+
+ ret = tor_tls_read(tls, buf, 10);
+ tt_int_op(ret, OP_EQ, -9);
+
+ /* These tests assume that V2_HANDSHAKE_SERVER is set */
+ tls->ssl->handshake_func = dummy_handshake_func;
+ tls->ssl->method = method;
+ method->ssl_read = fixed_ssl_read;
+ fixed_ssl_read_result_index = 0;
+ fixed_ssl_read_result[0] = 42;
+ tls->state = TOR_TLS_ST_OPEN;
+ ERR_clear_error();
+ ret = tor_tls_read(tls, buf, 10);
+ tt_int_op(ret, OP_EQ, 42);
+
+ tls->state = TOR_TLS_ST_OPEN;
+ tls->got_renegotiate = 1;
+ fixed_ssl_read_result_index = 0;
+ ERR_clear_error();
+ ret = tor_tls_read(tls, buf, 10);
+ tt_int_op(tls->got_renegotiate, OP_EQ, 0);
+
+ tls->state = TOR_TLS_ST_OPEN;
+ tls->got_renegotiate = 1;
+ negotiated_callback_called = 0;
+ tls->negotiated_callback = negotiated_callback_setter;
+ fixed_ssl_read_result_index = 0;
+ ERR_clear_error();
+ ret = tor_tls_read(tls, buf, 10);
+ tt_int_op(negotiated_callback_called, OP_EQ, 1);
+
+#ifndef LIBRESSL_VERSION_NUMBER
+ fixed_ssl_read_result_index = 0;
+ fixed_ssl_read_result[0] = 0;
+ tls->ssl->version = SSL2_VERSION;
+ ERR_clear_error();
+ ret = tor_tls_read(tls, buf, 10);
+ tt_int_op(ret, OP_EQ, TOR_TLS_CLOSE);
+ tt_int_op(tls->state, OP_EQ, TOR_TLS_ST_CLOSED);
+#endif /* !defined(LIBRESSL_VERSION_NUMBER) */
+ // TODO: fill up
+
+ done:
+ teardown_capture_of_logs();
+ tor_free(tls->ssl);
+ tor_free(tls);
+ tor_free(method);
+}
+
+static int fixed_ssl_write_result;
+
+static int
+fixed_ssl_write(SSL *s, const void *buf, int len)
+{
+ (void)s;
+ (void)buf;
+ (void)len;
+ return fixed_ssl_write_result;
+}
+
+static void
+test_tortls_write(void *ignored)
+{
+ (void)ignored;
+ int ret;
+ tor_tls_t *tls;
+ SSL_METHOD *method = give_me_a_test_method();
+ char buf[100];
+ setup_capture_of_logs(LOG_WARN);
+
+ tls = tor_malloc_zero(sizeof(tor_tls_t));
+ tls->ssl = tor_malloc_zero(sizeof(SSL));
+ tls->state = TOR_TLS_ST_OPEN;
+
+ ret = tor_tls_write(tls, buf, 0);
+ tt_int_op(ret, OP_EQ, 0);
+
+ ret = tor_tls_write(tls, buf, 10);
+ tt_int_op(ret, OP_EQ, -9);
+
+ tls->ssl->method = method;
+ tls->wantwrite_n = 1;
+ ret = tor_tls_write(tls, buf, 10);
+ tt_int_op(tls->wantwrite_n, OP_EQ, 0);
+
+ method->ssl_write = fixed_ssl_write;
+ tls->ssl->handshake_func = dummy_handshake_func;
+ fixed_ssl_write_result = 1;
+ ERR_clear_error();
+ ret = tor_tls_write(tls, buf, 10);
+ tt_int_op(ret, OP_EQ, 1);
+
+ fixed_ssl_write_result = -1;
+ ERR_clear_error();
+ tls->ssl->rwstate = SSL_READING;
+ SSL_set_bio(tls->ssl, BIO_new(BIO_s_mem()), NULL);
+ SSL_get_rbio(tls->ssl)->flags = BIO_FLAGS_READ;
+ ret = tor_tls_write(tls, buf, 10);
+ tt_int_op(ret, OP_EQ, TOR_TLS_WANTREAD);
+
+ ERR_clear_error();
+ tls->ssl->rwstate = SSL_READING;
+ SSL_set_bio(tls->ssl, BIO_new(BIO_s_mem()), NULL);
+ SSL_get_rbio(tls->ssl)->flags = BIO_FLAGS_WRITE;
+ ret = tor_tls_write(tls, buf, 10);
+ tt_int_op(ret, OP_EQ, TOR_TLS_WANTWRITE);
+
+ done:
+ teardown_capture_of_logs();
+ BIO_free(tls->ssl->rbio);
+ tor_free(tls->ssl);
+ tor_free(tls);
+ tor_free(method);
+}
+#endif /* !defined(OPENSSL_OPAQUE) */
+
+#ifndef OPENSSL_OPAQUE
+static int fixed_ssl_accept_result;
+static int fixed_ssl_connect_result;
+
+static int
+setting_error_ssl_accept(SSL *ssl)
+{
+ (void)ssl;
+ ERR_put_error(ERR_LIB_BN, 2, -1, "somewhere.c", 99);
+ ERR_put_error(ERR_LIB_SYS, 2, -1, "somewhere.c", 99);
+ return fixed_ssl_accept_result;
+}
+
+static int
+setting_error_ssl_connect(SSL *ssl)
+{
+ (void)ssl;
+ ERR_put_error(ERR_LIB_BN, 2, -1, "somewhere.c", 99);
+ ERR_put_error(ERR_LIB_SYS, 2, -1, "somewhere.c", 99);
+ return fixed_ssl_connect_result;
+}
+
+static int
+fixed_ssl_accept(SSL *ssl)
+{
+ (void) ssl;
+ return fixed_ssl_accept_result;
+}
+
+static void
+test_tortls_handshake(void *ignored)
+{
+ (void)ignored;
+ int ret;
+ tor_tls_t *tls;
+ SSL_CTX *ctx;
+ SSL_METHOD *method = give_me_a_test_method();
+ setup_capture_of_logs(LOG_INFO);
+
+ SSL_library_init();
+ SSL_load_error_strings();
+
+ ctx = SSL_CTX_new(TLSv1_method());
+
+ tls = tor_malloc_zero(sizeof(tor_tls_t));
+ tls->ssl = SSL_new(ctx);
+ tls->state = TOR_TLS_ST_HANDSHAKE;
+
+ ret = tor_tls_handshake(tls);
+ tt_int_op(ret, OP_EQ, -9);
+
+ tls->isServer = 1;
+ tls->state = TOR_TLS_ST_HANDSHAKE;
+ ret = tor_tls_handshake(tls);
+ tt_int_op(ret, OP_EQ, -9);
+
+ tls->ssl->method = method;
+ method->ssl_accept = fixed_ssl_accept;
+ fixed_ssl_accept_result = 2;
+ ERR_clear_error();
+ tls->state = TOR_TLS_ST_HANDSHAKE;
+ ret = tor_tls_handshake(tls);
+ tt_int_op(tls->state, OP_EQ, TOR_TLS_ST_OPEN);
+
+ method->ssl_accept = setting_error_ssl_accept;
+ fixed_ssl_accept_result = 1;
+ ERR_clear_error();
+ mock_clean_saved_logs();
+ tls->state = TOR_TLS_ST_HANDSHAKE;
+ ret = tor_tls_handshake(tls);
+ tt_int_op(ret, OP_EQ, TOR_TLS_ERROR_MISC);
+ expect_log_entry();
+ /* This fails on jessie. Investigate why! */
+#if 0
+ expect_log_msg("TLS error while handshaking: (null) (in bignum routines:"
+ "(null):SSLv3 write client hello B)\n");
+ expect_log_msg("TLS error while handshaking: (null) (in system library:"
+ "connect:SSLv3 write client hello B)\n");
+#endif /* 0 */
+ expect_log_severity(LOG_INFO);
+
+ tls->isServer = 0;
+ method->ssl_connect = setting_error_ssl_connect;
+ fixed_ssl_connect_result = 1;
+ ERR_clear_error();
+ mock_clean_saved_logs();
+ tls->state = TOR_TLS_ST_HANDSHAKE;
+ ret = tor_tls_handshake(tls);
+ tt_int_op(ret, OP_EQ, TOR_TLS_ERROR_MISC);
+ expect_log_entry();
+#if 0
+ /* See above */
+ expect_log_msg("TLS error while handshaking: "
+ "(null) (in bignum routines:(null):SSLv3 write client hello B)\n");
+ expect_log_msg("TLS error while handshaking: "
+ "(null) (in system library:connect:SSLv3 write client hello B)\n");
+#endif /* 0 */
+ expect_log_severity(LOG_WARN);
+
+ done:
+ teardown_capture_of_logs();
+ SSL_free(tls->ssl);
+ SSL_CTX_free(ctx);
+ tor_free(tls);
+ tor_free(method);
+}
+#endif /* !defined(OPENSSL_OPAQUE) */
+
+#ifndef OPENSSL_OPAQUE
+static void
+test_tortls_finish_handshake(void *ignored)
+{
+ (void)ignored;
+ int ret;
+ tor_tls_t *tls;
+ SSL_CTX *ctx;
+ SSL_METHOD *method = give_me_a_test_method();
+ SSL_library_init();
+ SSL_load_error_strings();
+
+ X509 *c1 = read_cert_from(validCertString);
+ SESS_CERT_local *sess = NULL;
+
+ ctx = SSL_CTX_new(method);
+
+ tls = tor_malloc_zero(sizeof(tor_tls_t));
+ tls->ssl = SSL_new(ctx);
+ tls->state = TOR_TLS_ST_OPEN;
+
+ ret = tor_tls_finish_handshake(tls);
+ tt_int_op(ret, OP_EQ, 0);
+
+ tls->isServer = 1;
+ tls->wasV2Handshake = 0;
+ setup_full_capture_of_logs(LOG_WARN);
+ ret = tor_tls_finish_handshake(tls);
+ tt_int_op(ret, OP_EQ, 0);
+ tt_int_op(tls->wasV2Handshake, OP_EQ, 1);
+ expect_single_log_msg_containing("For some reason, wasV2Handshake didn't "
+ "get set.");
+ teardown_capture_of_logs();
+
+ tls->wasV2Handshake = 1;
+ ret = tor_tls_finish_handshake(tls);
+ tt_int_op(ret, OP_EQ, 0);
+ tt_int_op(tls->wasV2Handshake, OP_EQ, 1);
+
+ tls->wasV2Handshake = 1;
+ tls->ssl->session = SSL_SESSION_new();
+ ret = tor_tls_finish_handshake(tls);
+ tt_int_op(ret, OP_EQ, 0);
+ tt_int_op(tls->wasV2Handshake, OP_EQ, 0);
+
+ tls->isServer = 0;
+
+ sess = tor_malloc_zero(sizeof(SESS_CERT_local));
+ tls->ssl->session->sess_cert = (void *)sess;
+ sess->cert_chain = sk_X509_new_null();
+ sk_X509_push(sess->cert_chain, c1);
+ tls->ssl->session->peer = c1;
+ tls->wasV2Handshake = 0;
+ ret = tor_tls_finish_handshake(tls);
+ tt_int_op(ret, OP_EQ, 0);
+ tt_int_op(tls->wasV2Handshake, OP_EQ, 1);
+
+ method->num_ciphers = fake_num_ciphers;
+ ret = tor_tls_finish_handshake(tls);
+ tt_int_op(ret, OP_EQ, -9);
+
+ done:
+ if (sess)
+ sk_X509_free(sess->cert_chain);
+ if (tls->ssl && tls->ssl->session) {
+ tor_free(tls->ssl->session->sess_cert);
+ }
+ SSL_free(tls->ssl);
+ tor_free(tls);
+ SSL_CTX_free(ctx);
+ tor_free(method);
+ teardown_capture_of_logs();
+}
+#endif /* !defined(OPENSSL_OPAQUE) */
+
+static int fixed_crypto_pk_new_result_index;
+static crypto_pk_t *fixed_crypto_pk_new_result[5];
+
+static crypto_pk_t *
+fixed_crypto_pk_new(void)
+{
+ return fixed_crypto_pk_new_result[fixed_crypto_pk_new_result_index++];
+}
+
+#ifndef OPENSSL_OPAQUE
+static int fixed_crypto_pk_generate_key_with_bits_result_index;
+static int fixed_crypto_pk_generate_key_with_bits_result[5];
+static int fixed_tor_tls_create_certificate_result_index;
+static X509 *fixed_tor_tls_create_certificate_result[5];
+static int fixed_tor_x509_cert_new_result_index;
+static tor_x509_cert_t *fixed_tor_x509_cert_new_result[5];
+
+static int
+fixed_crypto_pk_generate_key_with_bits(crypto_pk_t *env, int bits)
+{
+ (void)env;
+ (void)bits;
+ return fixed_crypto_pk_generate_key_with_bits_result[
+ fixed_crypto_pk_generate_key_with_bits_result_index++];
+}
+
+static X509 *
+fixed_tor_tls_create_certificate(crypto_pk_t *rsa,
+ crypto_pk_t *rsa_sign,
+ const char *cname,
+ const char *cname_sign,
+ unsigned int cert_lifetime)
+{
+ (void)rsa;
+ (void)rsa_sign;
+ (void)cname;
+ (void)cname_sign;
+ (void)cert_lifetime;
+ X509 *result = fixed_tor_tls_create_certificate_result[
+ fixed_tor_tls_create_certificate_result_index++];
+ if (result)
+ return X509_dup(result);
+ else
+ return NULL;
+}
+
+static void
+fixed_tor_tls_create_certificate_results_free(void)
+{
+ unsigned i;
+ for (i = 0; i < ARRAY_LENGTH(fixed_tor_tls_create_certificate_result); ++i) {
+ X509 *cert = fixed_tor_tls_create_certificate_result[i];
+ if (cert)
+ X509_free(cert);
+ fixed_tor_tls_create_certificate_result[i] = NULL;
+ }
+}
+
+static void
+fixed_tor_x509_cert_new_results_free(void)
+{
+ unsigned i;
+ for (i = 0; i < ARRAY_LENGTH(fixed_tor_x509_cert_new_result); ++i) {
+ tor_x509_cert_free(fixed_tor_x509_cert_new_result[i]);
+ }
+}
+
+static tor_x509_cert_t *
+fixed_tor_x509_cert_new(tor_x509_cert_impl_t *x509_cert)
+{
+ (void) x509_cert;
+ tor_x509_cert_t **certp =
+ &fixed_tor_x509_cert_new_result[fixed_tor_x509_cert_new_result_index++];
+ tor_x509_cert_t *cert = *certp;
+ *certp = NULL;
+ return cert;
+}
+
+static void
+test_tortls_context_new(void *ignored)
+{
+ (void)ignored;
+ tor_tls_context_t *ret;
+ crypto_pk_t *pk1, *pk2, *pk3, *pk4, *pk5, *pk6, *pk7, *pk8, *pk9, *pk10,
+ *pk11, *pk12, *pk13, *pk14, *pk15, *pk16, *pk17, *pk18;
+
+ pk1 = crypto_pk_new();
+ pk2 = crypto_pk_new();
+ pk3 = crypto_pk_new();
+ pk4 = crypto_pk_new();
+ pk5 = crypto_pk_new();
+ pk6 = crypto_pk_new();
+ pk7 = crypto_pk_new();
+ pk8 = crypto_pk_new();
+ pk9 = crypto_pk_new();
+ pk10 = crypto_pk_new();
+ pk11 = crypto_pk_new();
+ pk12 = crypto_pk_new();
+ pk13 = crypto_pk_new();
+ pk14 = crypto_pk_new();
+ pk15 = crypto_pk_new();
+ pk16 = crypto_pk_new();
+ pk17 = crypto_pk_new();
+ pk18 = crypto_pk_new();
+
+ fixed_crypto_pk_new_result_index = 0;
+ fixed_crypto_pk_new_result[0] = NULL;
+ MOCK(crypto_pk_new, fixed_crypto_pk_new);
+ ret = tor_tls_context_new(NULL, 0, 0, 0);
+ tt_assert(!ret);
+
+ /* note: we already override this in testing_common.c, so we
+ * run this unit test in a subprocess. */
+ MOCK(crypto_pk_generate_key_with_bits,
+ fixed_crypto_pk_generate_key_with_bits);
+ fixed_crypto_pk_new_result_index = 0;
+ fixed_crypto_pk_new_result[0] = pk1;
+ fixed_crypto_pk_new_result[1] = NULL;
+ fixed_crypto_pk_generate_key_with_bits_result[0] = -1;
+ fixed_crypto_pk_generate_key_with_bits_result_index = 0;
+ ret = tor_tls_context_new(NULL, 0, 0, 0);
+ tt_assert(!ret);
+
+ fixed_crypto_pk_new_result_index = 0;
+ fixed_crypto_pk_new_result[0] = pk2;
+ fixed_crypto_pk_new_result[1] = NULL;
+ fixed_crypto_pk_generate_key_with_bits_result[0] = 0;
+ fixed_crypto_pk_generate_key_with_bits_result_index = 0;
+ ret = tor_tls_context_new(NULL, 0, 0, 0);
+ tt_assert(!ret);
+
+ fixed_crypto_pk_new_result_index = 0;
+ fixed_crypto_pk_new_result[0] = pk3;
+ fixed_crypto_pk_new_result[1] = pk4;
+ fixed_crypto_pk_new_result[2] = NULL;
+ fixed_crypto_pk_generate_key_with_bits_result[0] = 0;
+ fixed_crypto_pk_generate_key_with_bits_result[1] = -1;
+ fixed_crypto_pk_generate_key_with_bits_result_index = 0;
+ ret = tor_tls_context_new(NULL, 0, 0, 0);
+ tt_assert(!ret);
+
+ MOCK(tor_tls_create_certificate, fixed_tor_tls_create_certificate);
+
+ fixed_crypto_pk_new_result_index = 0;
+ fixed_crypto_pk_new_result[0] = pk5;
+ fixed_crypto_pk_new_result[1] = pk6;
+ fixed_crypto_pk_new_result[2] = NULL;
+ fixed_crypto_pk_generate_key_with_bits_result_index = 0;
+ fixed_crypto_pk_generate_key_with_bits_result[1] = 0;
+ fixed_tor_tls_create_certificate_result_index = 0;
+ fixed_tor_tls_create_certificate_result[0] = NULL;
+ fixed_tor_tls_create_certificate_result[1] = X509_new();
+ fixed_tor_tls_create_certificate_result[2] = X509_new();
+ ret = tor_tls_context_new(NULL, 0, 0, 0);
+ tt_assert(!ret);
+ fixed_tor_tls_create_certificate_results_free();
+
+ fixed_crypto_pk_new_result_index = 0;
+ fixed_crypto_pk_new_result[0] = pk7;
+ fixed_crypto_pk_new_result[1] = pk8;
+ fixed_crypto_pk_new_result[2] = NULL;
+ fixed_crypto_pk_generate_key_with_bits_result_index = 0;
+ fixed_tor_tls_create_certificate_result_index = 0;
+ fixed_tor_tls_create_certificate_result[0] = X509_new();
+ fixed_tor_tls_create_certificate_result[1] = NULL;
+ fixed_tor_tls_create_certificate_result[2] = X509_new();
+ ret = tor_tls_context_new(NULL, 0, 0, 0);
+ tt_assert(!ret);
+ fixed_tor_tls_create_certificate_results_free();
+
+ fixed_crypto_pk_new_result_index = 0;
+ fixed_crypto_pk_new_result[0] = pk9;
+ fixed_crypto_pk_new_result[1] = pk10;
+ fixed_crypto_pk_new_result[2] = NULL;
+ fixed_crypto_pk_generate_key_with_bits_result_index = 0;
+ fixed_tor_tls_create_certificate_result_index = 0;
+ fixed_tor_tls_create_certificate_result[0] = X509_new();
+ fixed_tor_tls_create_certificate_result[1] = X509_new();
+ fixed_tor_tls_create_certificate_result[2] = NULL;
+ ret = tor_tls_context_new(NULL, 0, 0, 0);
+ tt_assert(!ret);
+ fixed_tor_tls_create_certificate_results_free();
+
+ MOCK(tor_x509_cert_new, fixed_tor_x509_cert_new);
+ fixed_crypto_pk_new_result_index = 0;
+ fixed_crypto_pk_new_result[0] = pk11;
+ fixed_crypto_pk_new_result[1] = pk12;
+ fixed_crypto_pk_new_result[2] = NULL;
+ fixed_crypto_pk_generate_key_with_bits_result_index = 0;
+ fixed_tor_tls_create_certificate_result_index = 0;
+ fixed_tor_tls_create_certificate_result[0] = X509_new();
+ fixed_tor_tls_create_certificate_result[1] = X509_new();
+ fixed_tor_tls_create_certificate_result[2] = X509_new();
+ fixed_tor_x509_cert_new_result_index = 0;
+ fixed_tor_x509_cert_new_result[0] = NULL;
+ fixed_tor_x509_cert_new_result[1] = NULL;
+ fixed_tor_x509_cert_new_result[2] = NULL;
+ ret = tor_tls_context_new(NULL, 0, 0, 0);
+ tt_assert(!ret);
+ fixed_tor_tls_create_certificate_results_free();
+
+ fixed_crypto_pk_new_result_index = 0;
+ fixed_crypto_pk_new_result[0] = pk13;
+ fixed_crypto_pk_new_result[1] = pk14;
+ fixed_crypto_pk_new_result[2] = NULL;
+ fixed_crypto_pk_generate_key_with_bits_result_index = 0;
+ fixed_tor_tls_create_certificate_result_index = 0;
+ fixed_tor_tls_create_certificate_result[0] = X509_new();
+ fixed_tor_tls_create_certificate_result[1] = X509_new();
+ fixed_tor_tls_create_certificate_result[2] = X509_new();
+ fixed_tor_x509_cert_new_result_index = 0;
+ fixed_tor_x509_cert_new_result[0] = tor_malloc_zero(sizeof(tor_x509_cert_t));
+ fixed_tor_x509_cert_new_result[1] = NULL;
+ fixed_tor_x509_cert_new_result[2] = NULL;
+ ret = tor_tls_context_new(NULL, 0, 0, 0);
+ tt_assert(!ret);
+ fixed_tor_tls_create_certificate_results_free();
+ fixed_tor_x509_cert_new_results_free();
+
+ fixed_crypto_pk_new_result_index = 0;
+ fixed_crypto_pk_new_result[0] = pk15;
+ fixed_crypto_pk_new_result[1] = pk16;
+ fixed_crypto_pk_new_result[2] = NULL;
+ fixed_crypto_pk_generate_key_with_bits_result_index = 0;
+ fixed_tor_tls_create_certificate_result_index = 0;
+ fixed_tor_tls_create_certificate_result[0] = X509_new();
+ fixed_tor_tls_create_certificate_result[1] = X509_new();
+ fixed_tor_tls_create_certificate_result[2] = X509_new();
+ fixed_tor_x509_cert_new_result_index = 0;
+ fixed_tor_x509_cert_new_result[0] = tor_malloc_zero(sizeof(tor_x509_cert_t));
+ fixed_tor_x509_cert_new_result[1] = tor_malloc_zero(sizeof(tor_x509_cert_t));
+ fixed_tor_x509_cert_new_result[2] = NULL;
+ ret = tor_tls_context_new(NULL, 0, 0, 0);
+ tt_assert(!ret);
+ fixed_tor_tls_create_certificate_results_free();
+ fixed_tor_x509_cert_new_results_free();
+
+ fixed_crypto_pk_new_result_index = 0;
+ fixed_crypto_pk_new_result[0] = pk17;
+ fixed_crypto_pk_new_result[1] = pk18;
+ fixed_crypto_pk_new_result[2] = NULL;
+ fixed_crypto_pk_generate_key_with_bits_result_index = 0;
+ fixed_tor_tls_create_certificate_result_index = 0;
+ fixed_tor_tls_create_certificate_result[0] = X509_new();
+ fixed_tor_tls_create_certificate_result[1] = X509_new();
+ fixed_tor_tls_create_certificate_result[2] = X509_new();
+ fixed_tor_x509_cert_new_result_index = 0;
+ fixed_tor_x509_cert_new_result[0] = tor_malloc_zero(sizeof(tor_x509_cert_t));
+ fixed_tor_x509_cert_new_result[1] = tor_malloc_zero(sizeof(tor_x509_cert_t));
+ fixed_tor_x509_cert_new_result[2] = tor_malloc_zero(sizeof(tor_x509_cert_t));
+ ret = tor_tls_context_new(NULL, 0, 0, 0);
+ tt_assert(!ret);
+
+ done:
+ fixed_tor_tls_create_certificate_results_free();
+ fixed_tor_x509_cert_new_results_free();
+ UNMOCK(tor_x509_cert_new);
+ UNMOCK(tor_tls_create_certificate);
+ UNMOCK(crypto_pk_generate_key_with_bits);
+ UNMOCK(crypto_pk_new);
+}
+#endif /* !defined(OPENSSL_OPAQUE) */
+
+static int fixed_crypto_pk_get_evp_pkey_result_index = 0;
+static EVP_PKEY *fixed_crypto_pk_get_evp_pkey_result[5];
+
+static EVP_PKEY *
+fixed_crypto_pk_get_evp_pkey_(crypto_pk_t *env, int private)
+{
+ (void) env;
+ (void) private;
+ return fixed_crypto_pk_get_evp_pkey_result[
+ fixed_crypto_pk_get_evp_pkey_result_index++];
+}
+
+static void
+test_tortls_create_certificate(void *ignored)
+{
+ (void)ignored;
+ X509 *ret;
+ crypto_pk_t *pk1, *pk2;
+
+ pk1 = crypto_pk_new();
+ pk2 = crypto_pk_new();
+
+ MOCK(crypto_pk_get_openssl_evp_pkey_, fixed_crypto_pk_get_evp_pkey_);
+ fixed_crypto_pk_get_evp_pkey_result_index = 0;
+ fixed_crypto_pk_get_evp_pkey_result[0] = NULL;
+ ret = tor_tls_create_certificate(pk1, pk2, "hello", "hello2", 1);
+ tt_assert(!ret);
+
+ fixed_crypto_pk_get_evp_pkey_result_index = 0;
+ fixed_crypto_pk_get_evp_pkey_result[0] = EVP_PKEY_new();
+ fixed_crypto_pk_get_evp_pkey_result[1] = NULL;
+ ret = tor_tls_create_certificate(pk1, pk2, "hello", "hello2", 1);
+ tt_assert(!ret);
+
+ fixed_crypto_pk_get_evp_pkey_result_index = 0;
+ fixed_crypto_pk_get_evp_pkey_result[0] = EVP_PKEY_new();
+ fixed_crypto_pk_get_evp_pkey_result[1] = EVP_PKEY_new();
+ ret = tor_tls_create_certificate(pk1, pk2, "hello", "hello2", 1);
+ tt_assert(!ret);
+
+ done:
+ UNMOCK(crypto_pk_get_openssl_evp_pkey_);
+ crypto_pk_free(pk1);
+ crypto_pk_free(pk2);
+}
+
+static void
+test_tortls_cert_new(void *ignored)
+{
+ (void)ignored;
+ tor_x509_cert_t *ret;
+ X509 *cert = read_cert_from(validCertString);
+
+ ret = tor_x509_cert_new(NULL);
+ tt_assert(!ret);
+
+ ret = tor_x509_cert_new(cert);
+ tt_assert(ret);
+ tor_x509_cert_free(ret);
+ ret = NULL;
+
+#if 0
+ cert = read_cert_from(validCertString);
+ /* XXX this doesn't do what you think: it alters a copy of the pubkey. */
+ X509_get_pubkey(cert)->type = EVP_PKEY_DSA;
+ ret = tor_x509_cert_new(cert);
+ tt_assert(ret);
+#endif /* 0 */
+
+#ifndef OPENSSL_OPAQUE
+ cert = read_cert_from(validCertString);
+ X509_CINF_free(cert->cert_info);
+ cert->cert_info = NULL;
+ ret = tor_x509_cert_new(cert);
+ tt_assert(ret);
+#endif /* !defined(OPENSSL_OPAQUE) */
+
+ done:
+ tor_x509_cert_free(ret);
+}
+
+static void
+test_tortls_cert_is_valid(void *ignored)
+{
+ (void)ignored;
+ int ret;
+ tor_x509_cert_t *cert = NULL, *scert = NULL;
+
+ scert = tor_malloc_zero(sizeof(tor_x509_cert_t));
+ ret = tor_tls_cert_is_valid(LOG_WARN, cert, scert, time(NULL), 0);
+ tt_int_op(ret, OP_EQ, 0);
+
+ cert = tor_malloc_zero(sizeof(tor_x509_cert_t));
+ ret = tor_tls_cert_is_valid(LOG_WARN, cert, scert, time(NULL), 0);
+ tt_int_op(ret, OP_EQ, 0);
+ tor_free(scert);
+ tor_free(cert);
+
+ cert = tor_x509_cert_new(read_cert_from(validCertString));
+ scert = tor_x509_cert_new(read_cert_from(caCertString));
+ ret = tor_tls_cert_is_valid(LOG_WARN, cert, scert, time(NULL), 0);
+ tt_int_op(ret, OP_EQ, 1);
+
+#ifndef OPENSSL_OPAQUE
+ tor_x509_cert_free(cert);
+ tor_x509_cert_free(scert);
+ cert = tor_x509_cert_new(read_cert_from(validCertString));
+ scert = tor_x509_cert_new(read_cert_from(caCertString));
+ ASN1_TIME_free(cert->cert->cert_info->validity->notAfter);
+ cert->cert->cert_info->validity->notAfter =
+ ASN1_TIME_set(NULL, time(NULL)-1000000);
+ ret = tor_tls_cert_is_valid(LOG_WARN, cert, scert, time(NULL), 0);
+ tt_int_op(ret, OP_EQ, 0);
+
+ tor_x509_cert_free(cert);
+ tor_x509_cert_free(scert);
+ cert = tor_x509_cert_new(read_cert_from(validCertString));
+ scert = tor_x509_cert_new(read_cert_from(caCertString));
+ X509_PUBKEY_free(cert->cert->cert_info->key);
+ cert->cert->cert_info->key = NULL;
+ ret = tor_tls_cert_is_valid(LOG_WARN, cert, scert, time(NULL), 1);
+ tt_int_op(ret, OP_EQ, 0);
+#endif /* !defined(OPENSSL_OPAQUE) */
+
+#if 0
+ tor_x509_cert_free(cert);
+ tor_x509_cert_free(scert);
+ cert = tor_x509_cert_new(read_cert_from(validCertString));
+ scert = tor_x509_cert_new(read_cert_from(caCertString));
+ /* This doesn't actually change the key in the cert. XXXXXX */
+ BN_one(EVP_PKEY_get1_RSA(X509_get_pubkey(cert->cert))->n);
+ ret = tor_tls_cert_is_valid(LOG_WARN, cert, scert, time(NULL), 1);
+ tt_int_op(ret, OP_EQ, 0);
+
+ tor_x509_cert_free(cert);
+ tor_x509_cert_free(scert);
+ cert = tor_x509_cert_new(read_cert_from(validCertString));
+ scert = tor_x509_cert_new(read_cert_from(caCertString));
+ /* This doesn't actually change the key in the cert. XXXXXX */
+ X509_get_pubkey(cert->cert)->type = EVP_PKEY_EC;
+ ret = tor_tls_cert_is_valid(LOG_WARN, cert, scert, time(NULL), 1);
+ tt_int_op(ret, OP_EQ, 0);
+
+ tor_x509_cert_free(cert);
+ tor_x509_cert_free(scert);
+ cert = tor_x509_cert_new(read_cert_from(validCertString));
+ scert = tor_x509_cert_new(read_cert_from(caCertString));
+ /* This doesn't actually change the key in the cert. XXXXXX */
+ X509_get_pubkey(cert->cert)->type = EVP_PKEY_EC;
+ ret = tor_tls_cert_is_valid(LOG_WARN, cert, scert, time(NULL), 0);
+ tt_int_op(ret, OP_EQ, 1);
+
+ tor_x509_cert_free(cert);
+ tor_x509_cert_free(scert);
+ cert = tor_x509_cert_new(read_cert_from(validCertString));
+ scert = tor_x509_cert_new(read_cert_from(caCertString));
+ /* This doesn't actually change the key in the cert. XXXXXX */
+ X509_get_pubkey(cert->cert)->type = EVP_PKEY_EC;
+ X509_get_pubkey(cert->cert)->ameth = NULL;
+ ret = tor_tls_cert_is_valid(LOG_WARN, cert, scert, time(NULL), 0);
+ tt_int_op(ret, OP_EQ, 0);
+#endif /* 0 */
+
+ done:
+ tor_x509_cert_free(cert);
+ tor_x509_cert_free(scert);
+}
+
+static void
+test_tortls_context_init_one(void *ignored)
+{
+ (void)ignored;
+ int ret;
+ tor_tls_context_t *old = NULL;
+
+ MOCK(crypto_pk_new, fixed_crypto_pk_new);
+
+ fixed_crypto_pk_new_result_index = 0;
+ fixed_crypto_pk_new_result[0] = NULL;
+ ret = tor_tls_context_init_one(&old, NULL, 0, 0, 0);
+ tt_int_op(ret, OP_EQ, -1);
+
+ done:
+ UNMOCK(crypto_pk_new);
+}
+
+#define LOCAL_TEST_CASE(name, flags) \
+ { #name, test_tortls_##name, (flags|TT_FORK), NULL, NULL }
+
+#ifdef OPENSSL_OPAQUE
+#define INTRUSIVE_TEST_CASE(name, flags) \
+ { #name, NULL, TT_SKIP, NULL, NULL }
+#else
+#define INTRUSIVE_TEST_CASE(name, flags) LOCAL_TEST_CASE(name, flags)
+#endif /* defined(OPENSSL_OPAQUE) */
+
+struct testcase_t tortls_openssl_tests[] = {
+ LOCAL_TEST_CASE(tor_tls_new, TT_FORK),
+ LOCAL_TEST_CASE(get_state_description, TT_FORK),
+ LOCAL_TEST_CASE(get_by_ssl, TT_FORK),
+ LOCAL_TEST_CASE(allocate_tor_tls_object_ex_data_index, TT_FORK),
+ LOCAL_TEST_CASE(log_one_error, TT_FORK),
+ INTRUSIVE_TEST_CASE(get_error, TT_FORK),
+ LOCAL_TEST_CASE(always_accept_verify_cb, 0),
+ INTRUSIVE_TEST_CASE(x509_cert_free, 0),
+ LOCAL_TEST_CASE(cert_matches_key, 0),
+ INTRUSIVE_TEST_CASE(cert_get_key, 0),
+ LOCAL_TEST_CASE(get_my_client_auth_key, TT_FORK),
+ INTRUSIVE_TEST_CASE(get_ciphersuite_name, 0),
+ INTRUSIVE_TEST_CASE(classify_client_ciphers, 0),
+ LOCAL_TEST_CASE(client_is_using_v2_ciphers, 0),
+ INTRUSIVE_TEST_CASE(get_pending_bytes, 0),
+ INTRUSIVE_TEST_CASE(SSL_SESSION_get_master_key, 0),
+ INTRUSIVE_TEST_CASE(get_tlssecrets, 0),
+ INTRUSIVE_TEST_CASE(get_buffer_sizes, 0),
+ INTRUSIVE_TEST_CASE(try_to_extract_certs_from_tls, 0),
+ INTRUSIVE_TEST_CASE(get_peer_cert, 0),
+ INTRUSIVE_TEST_CASE(peer_has_cert, 0),
+ INTRUSIVE_TEST_CASE(finish_handshake, 0),
+ INTRUSIVE_TEST_CASE(handshake, 0),
+ INTRUSIVE_TEST_CASE(write, 0),
+ INTRUSIVE_TEST_CASE(read, 0),
+ INTRUSIVE_TEST_CASE(server_info_callback, 0),
+ LOCAL_TEST_CASE(get_write_overhead_ratio, TT_FORK),
+ LOCAL_TEST_CASE(is_server, 0),
+ INTRUSIVE_TEST_CASE(assert_renegotiation_unblocked, 0),
+ INTRUSIVE_TEST_CASE(block_renegotiation, 0),
+ INTRUSIVE_TEST_CASE(unblock_renegotiation, 0),
+ INTRUSIVE_TEST_CASE(set_renegotiate_callback, 0),
+ LOCAL_TEST_CASE(set_logged_address, 0),
+ INTRUSIVE_TEST_CASE(find_cipher_by_id, 0),
+ INTRUSIVE_TEST_CASE(session_secret_cb, 0),
+ INTRUSIVE_TEST_CASE(debug_state_callback, 0),
+ INTRUSIVE_TEST_CASE(context_new, TT_FORK /* redundant */),
+ LOCAL_TEST_CASE(create_certificate, 0),
+ LOCAL_TEST_CASE(cert_new, 0),
+ LOCAL_TEST_CASE(cert_is_valid, 0),
+ LOCAL_TEST_CASE(context_init_one, 0),
+ END_OF_TESTCASES
+};
diff --git a/src/test/test_util.c b/src/test/test_util.c
index 036f739b89..7bc1b7921a 100644
--- a/src/test/test_util.c
+++ b/src/test/test_util.c
@@ -1,6 +1,6 @@
/* Copyright (c) 2001-2004, Roger Dingledine.
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2017, The Tor Project, Inc. */
+ * Copyright (c) 2007-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
#include "orconfig.h"
@@ -8,14 +8,37 @@
#define COMPAT_TIME_PRIVATE
#define CONTROL_PRIVATE
#define UTIL_PRIVATE
-#include "or.h"
-#include "buffers.h"
-#include "config.h"
-#include "control.h"
-#include "test.h"
-#include "memarea.h"
-#include "util_process.h"
-#include "log_test_helpers.h"
+#define UTIL_MALLOC_PRIVATE
+#define SOCKET_PRIVATE
+#define SUBPROCESS_PRIVATE
+#include "lib/testsupport/testsupport.h"
+#include "core/or/or.h"
+#include "lib/container/buffers.h"
+#include "app/config/config.h"
+#include "feature/control/control.h"
+#include "feature/client/transports.h"
+#include "lib/crypt_ops/crypto_format.h"
+#include "lib/crypt_ops/crypto_rand.h"
+#include "test/test.h"
+#include "lib/memarea/memarea.h"
+#include "lib/process/waitpid.h"
+#include "test/log_test_helpers.h"
+#include "lib/compress/compress.h"
+#include "lib/compress/compress_zstd.h"
+#include "lib/encoding/keyval.h"
+#include "lib/fdio/fdio.h"
+#include "lib/fs/winlib.h"
+#include "lib/process/env.h"
+#include "lib/process/pidfile.h"
+#include "lib/process/subprocess.h"
+#include "lib/intmath/weakrng.h"
+#include "lib/thread/numcpus.h"
+#include "lib/math/fp.h"
+#include "lib/math/laplace.h"
+#include "lib/meminfo/meminfo.h"
+#include "lib/time/tvdiff.h"
+#include "lib/encoding/confline.h"
+#include "lib/net/socketpair.h"
#ifdef HAVE_PWD_H
#include <pwd.h>
@@ -26,6 +49,16 @@
#ifdef HAVE_UTIME_H
#include <utime.h>
#endif
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
#ifdef _WIN32
#include <tchar.h>
#endif
@@ -890,6 +923,32 @@ test_util_time(void *arg)
teardown_capture_of_logs();
}
}
+ {
+ /* As above, but with localtime. */
+ t_res = -9223372036854775LL;
+ tor_localtime_r(&t_res, &b_time);
+ tt_assert(b_time.tm_year == (1970-1900) ||
+ b_time.tm_year == (1-1900));
+
+ /* while unlikely, the system's gmtime(_r) could return
+ * a "correct" retrospective gregorian negative year value,
+ * which I'm pretty sure is:
+ * -1*(2^63)/60/60/24*2000/730485 + 1970 = -292277022657
+ * 730485 is the number of days in two millennia, including leap days
+ * (int64_t)b_time.tm_year == (-292277022657LL-1900LL) without clamping */
+ t_res = INT64_MIN;
+ CAPTURE();
+ tor_localtime_r(&t_res, &b_time);
+ if (! (b_time.tm_year == (1970-1900) ||
+ b_time.tm_year == (1-1900))) {
+ tt_int_op(b_time.tm_year, OP_EQ, 1970-1900);
+ }
+ if (b_time.tm_year != 1970-1900) {
+ CHECK_TIMEGM_WARNING("Rounding up to ");
+ } else {
+ teardown_capture_of_logs();
+ }
+ }
#endif /* SIZEOF_TIME_T == 8 */
/* time_t >= INT_MAX yields a year clamped to 2037 or 9999,
@@ -906,6 +965,17 @@ test_util_time(void *arg)
tt_assert(b_time.tm_year == (2037-1900) ||
b_time.tm_year == (2038-1900));
}
+ {
+ /* as above but with localtime. */
+ t_res = 3*(1 << 29);
+ tor_localtime_r(&t_res, &b_time);
+ tt_assert(b_time.tm_year == (2021-1900));
+
+ t_res = INT32_MAX;
+ tor_localtime_r(&t_res, &b_time);
+ tt_assert(b_time.tm_year == (2037-1900) ||
+ b_time.tm_year == (2038-1900));
+ }
#endif /* SIZEOF_TIME_T == 4 || SIZEOF_TIME_T == 8 */
#if SIZEOF_TIME_T == 8
@@ -931,6 +1001,27 @@ test_util_time(void *arg)
tt_assert(b_time.tm_year == (2037-1900) ||
b_time.tm_year == (9999-1900));
}
+ {
+ /* As above but with localtime. */
+ t_res = 9223372036854775LL;
+ tor_localtime_r(&t_res, &b_time);
+ tt_assert(b_time.tm_year == (2037-1900) ||
+ b_time.tm_year == (9999-1900));
+
+ /* while unlikely, the system's gmtime(_r) could return
+ * a "correct" proleptic gregorian year value,
+ * which I'm pretty sure is:
+ * (2^63-1)/60/60/24*2000/730485 + 1970 = 292277026596
+ * 730485 is the number of days in two millennia, including leap days
+ * (int64_t)b_time.tm_year == (292277026596L-1900L) without clamping */
+ t_res = INT64_MAX;
+ CAPTURE();
+ tor_localtime_r(&t_res, &b_time);
+ CHECK_TIMEGM_WARNING("Rounding down to ");
+
+ tt_assert(b_time.tm_year == (2037-1900) ||
+ b_time.tm_year == (9999-1900));
+ }
#endif /* SIZEOF_TIME_T == 8 */
/* Test {format,parse}_rfc1123_time */
@@ -1899,8 +1990,8 @@ test_util_strmisc(void *arg)
tor_snprintf(buf, 10, "abcdef");
tt_int_op(0,OP_EQ, buf[6]);
/* uint64 */
- tor_snprintf(buf, sizeof(buf), "x!"U64_FORMAT"!x",
- U64_PRINTF_ARG(U64_LITERAL(12345678901)));
+ tor_snprintf(buf, sizeof(buf), "x!%"PRIu64"!x",
+ (UINT64_C(12345678901)));
tt_str_op("x!12345678901!x",OP_EQ, buf);
/* Test str{,case}cmpstart */
@@ -2113,20 +2204,10 @@ test_util_parse_integer(void *arg)
tt_int_op(1,OP_EQ, i);
tt_str_op(cp,OP_EQ, " plus garbage");
/* Illogical min max */
- tor_capture_bugs_(1);
tt_int_op(0L,OP_EQ, tor_parse_long("10",10,50,4,&i,NULL));
tt_int_op(0,OP_EQ, i);
- tt_int_op(1, OP_EQ, smartlist_len(tor_get_captured_bug_log_()));
- tt_str_op("!(max < min)", OP_EQ,
- smartlist_get(tor_get_captured_bug_log_(), 0));
- tor_end_capture_bugs_();
- tor_capture_bugs_(1);
tt_int_op(0L,OP_EQ, tor_parse_long("-50",10,100,-100,&i,NULL));
tt_int_op(0,OP_EQ, i);
- tt_int_op(1, OP_EQ, smartlist_len(tor_get_captured_bug_log_()));
- tt_str_op("!(max < min)", OP_EQ,
- smartlist_get(tor_get_captured_bug_log_(), 0));
- tor_end_capture_bugs_();
/* Out of bounds */
tt_int_op(0L,OP_EQ, tor_parse_long("10",10,50,100,&i,NULL));
tt_int_op(0,OP_EQ, i);
@@ -2137,11 +2218,8 @@ test_util_parse_integer(void *arg)
tt_int_op(0L,OP_EQ, tor_parse_long("2",2,0,100,NULL,NULL));
tt_int_op(68284L,OP_EQ, tor_parse_long("10abc",16,0,70000,NULL,NULL));
tt_int_op(68284L,OP_EQ, tor_parse_long("10ABC",16,0,70000,NULL,NULL));
- tor_capture_bugs_(2);
tt_int_op(0L,OP_EQ, tor_parse_long("10",-2,0,100,NULL,NULL));
tt_int_op(0,OP_EQ, tor_parse_long("10ABC",-1,0,70000,&i,NULL));
- tt_int_op(2, OP_EQ, smartlist_len(tor_get_captured_bug_log_()));
- tor_end_capture_bugs_();
tt_int_op(i,OP_EQ, 0);
/* Test parse_ulong */
@@ -2154,40 +2232,34 @@ test_util_parse_integer(void *arg)
tt_int_op(0UL,OP_EQ, tor_parse_ulong("8",8,0,100,NULL,NULL));
tt_int_op(50UL,OP_EQ, tor_parse_ulong("50",10,50,100,NULL,NULL));
tt_int_op(0UL,OP_EQ, tor_parse_ulong("-50",10,0,100,NULL,NULL));
- tor_capture_bugs_(1);
tt_int_op(0UL,OP_EQ, tor_parse_ulong("50",-1,50,100,&i,NULL));
- tt_int_op(1, OP_EQ, smartlist_len(tor_get_captured_bug_log_()));
- tor_end_capture_bugs_();
tt_int_op(0,OP_EQ, i);
tt_int_op(0UL,OP_EQ, tor_parse_ulong("-50",10,0,100,&i,NULL));
tt_int_op(0,OP_EQ, i);
/* Test parse_uint64 */
- tt_assert(U64_LITERAL(10) == tor_parse_uint64("10 x",10,0,100, &i, &cp));
+ tt_assert(UINT64_C(10) == tor_parse_uint64("10 x",10,0,100, &i, &cp));
tt_int_op(1,OP_EQ, i);
tt_str_op(cp,OP_EQ, " x");
- tt_assert(U64_LITERAL(12345678901) ==
+ tt_assert(UINT64_C(12345678901) ==
tor_parse_uint64("12345678901",10,0,UINT64_MAX, &i, &cp));
tt_int_op(1,OP_EQ, i);
tt_str_op(cp,OP_EQ, "");
- tt_assert(U64_LITERAL(0) ==
+ tt_assert(UINT64_C(0) ==
tor_parse_uint64("12345678901",10,500,INT32_MAX, &i, &cp));
tt_int_op(0,OP_EQ, i);
- tor_capture_bugs_(1);
- tt_assert(U64_LITERAL(0) ==
+ tt_assert(UINT64_C(0) ==
tor_parse_uint64("123",-1,0,INT32_MAX, &i, &cp));
- tt_int_op(1, OP_EQ, smartlist_len(tor_get_captured_bug_log_()));
- tor_end_capture_bugs_();
tt_int_op(0,OP_EQ, i);
{
/* Test parse_double */
double d = tor_parse_double("10", 0, (double)UINT64_MAX,&i,NULL);
tt_int_op(1,OP_EQ, i);
- tt_assert(DBL_TO_U64(d) == 10);
+ tt_assert(((uint64_t)d) == 10);
d = tor_parse_double("0", 0, (double)UINT64_MAX,&i,NULL);
tt_int_op(1,OP_EQ, i);
- tt_assert(DBL_TO_U64(d) == 0);
+ tt_assert(((uint64_t)d) == 0);
d = tor_parse_double(" ", 0, (double)UINT64_MAX,&i,NULL);
tt_double_op(fabs(d), OP_LT, 1e-10);
tt_int_op(0,OP_EQ, i);
@@ -2199,7 +2271,7 @@ test_util_parse_integer(void *arg)
tt_int_op(1,OP_EQ, i);
d = tor_parse_double("-.0", 0, (double)UINT64_MAX,&i,NULL);
tt_int_op(1,OP_EQ, i);
- tt_assert(DBL_TO_U64(d) == 0);
+ tt_assert(((uint64_t)d) == 0);
d = tor_parse_double("-10", -100.0, 100.0,&i,NULL);
tt_int_op(1,OP_EQ, i);
tt_double_op(fabs(d - -10.0),OP_LT, 1E-12);
@@ -2217,12 +2289,12 @@ test_util_parse_integer(void *arg)
tt_int_op(i,OP_EQ, 0);
tt_int_op(0UL,OP_EQ, tor_parse_ulong(TOOBIG, 10, 0, ULONG_MAX, &i, NULL));
tt_int_op(i,OP_EQ, 0);
- tt_u64_op(U64_LITERAL(0), OP_EQ, tor_parse_uint64(TOOBIG, 10,
+ tt_u64_op(UINT64_C(0), OP_EQ, tor_parse_uint64(TOOBIG, 10,
0, UINT64_MAX, &i, NULL));
tt_int_op(i,OP_EQ, 0);
}
done:
- tor_end_capture_bugs_();
+ ;
}
static void
@@ -2240,17 +2312,17 @@ test_util_pow2(void *arg)
tt_int_op(tor_log2(3),OP_EQ, 1);
tt_int_op(tor_log2(4),OP_EQ, 2);
tt_int_op(tor_log2(5),OP_EQ, 2);
- tt_int_op(tor_log2(U64_LITERAL(40000000000000000)),OP_EQ, 55);
+ tt_int_op(tor_log2(UINT64_C(40000000000000000)),OP_EQ, 55);
tt_int_op(tor_log2(UINT64_MAX),OP_EQ, 63);
/* Test round_to_power_of_2 */
tt_u64_op(round_to_power_of_2(120), OP_EQ, 128);
tt_u64_op(round_to_power_of_2(128), OP_EQ, 128);
tt_u64_op(round_to_power_of_2(130), OP_EQ, 128);
- tt_u64_op(round_to_power_of_2(U64_LITERAL(40000000000000000)), OP_EQ,
- U64_LITERAL(1)<<55);
- tt_u64_op(round_to_power_of_2(U64_LITERAL(0xffffffffffffffff)), OP_EQ,
- U64_LITERAL(1)<<63);
+ tt_u64_op(round_to_power_of_2(UINT64_C(40000000000000000)), OP_EQ,
+ UINT64_C(1)<<55);
+ tt_u64_op(round_to_power_of_2(UINT64_C(0xffffffffffffffff)), OP_EQ,
+ UINT64_C(1)<<63);
tt_u64_op(round_to_power_of_2(0), OP_EQ, 1);
tt_u64_op(round_to_power_of_2(1), OP_EQ, 1);
tt_u64_op(round_to_power_of_2(2), OP_EQ, 2);
@@ -2396,6 +2468,37 @@ test_util_compress_stream_impl(compress_method_t method,
tor_free(buf3);
}
+/** Setup function for compression tests: handles x-zstd:nostatic
+ */
+static void *
+compression_test_setup(const struct testcase_t *testcase)
+{
+ tor_assert(testcase->setup_data);
+ tor_assert(testcase->setup_data != (void*)TT_SKIP);
+ const char *methodname = testcase->setup_data;
+
+ if (!strcmp(methodname, "x-zstd:nostatic")) {
+ methodname = "x-zstd";
+ tor_zstd_set_static_apis_disabled_for_testing(1);
+ }
+
+ return (void *)methodname;
+}
+
+/** Cleanup for compression tests: disables nostatic */
+static int
+compression_test_cleanup(const struct testcase_t *testcase, void *ptr)
+{
+ (void)testcase;
+ (void)ptr;
+ tor_zstd_set_static_apis_disabled_for_testing(0);
+ return 1;
+}
+
+static const struct testcase_setup_t compress_setup = {
+ compression_test_setup, compression_test_cleanup
+};
+
/** Run unit tests for compression functions */
static void
test_util_compress(void *arg)
@@ -3119,6 +3222,21 @@ test_util_sscanf(void *arg)
test_feq(d3, -900123123.2000787);
test_feq(d4, 3.2);
+ /* missing float */
+ r = tor_sscanf("3 ", "%d %lf", &int1, &d1);
+ tt_int_op(r, OP_EQ, 1);
+ tt_int_op(int1, OP_EQ, 3);
+
+ /* not a float */
+ r = tor_sscanf("999 notafloat", "%d %lf", &int1, &d1);
+ tt_int_op(r, OP_EQ, 1);
+ tt_int_op(int1, OP_EQ, 999);
+
+ /* %s but no buffer. */
+ char *nullbuf = NULL;
+ r = tor_sscanf("hello", "%3s", nullbuf);
+ tt_int_op(r, OP_EQ, 0);
+
done:
tor_free(huge);
}
@@ -3895,6 +4013,53 @@ test_util_string_is_C_identifier(void *ptr)
}
static void
+test_util_string_is_utf8(void *ptr)
+{
+ (void)ptr;
+
+ tt_int_op(1, OP_EQ, string_is_utf8(NULL, 0));
+ tt_int_op(1, OP_EQ, string_is_utf8("", 1));
+ tt_int_op(1, OP_EQ, string_is_utf8("\uFEFF", 3));
+ tt_int_op(1, OP_EQ, string_is_utf8("\uFFFE", 3));
+ tt_int_op(1, OP_EQ, string_is_utf8("ascii\x7f\n", 7));
+ tt_int_op(1, OP_EQ, string_is_utf8("Risqu\u00e9=1", 9));
+
+ // Validate exactly 'len' bytes.
+ tt_int_op(0, OP_EQ, string_is_utf8("\0\x80", 2));
+ tt_int_op(0, OP_EQ, string_is_utf8("Risqu\u00e9=1", 6));
+
+ // Reject sequences with missing bytes.
+ tt_int_op(0, OP_EQ, string_is_utf8("\x80", 1));
+ tt_int_op(0, OP_EQ, string_is_utf8("\xc2", 1));
+ tt_int_op(0, OP_EQ, string_is_utf8("\xc2 ", 2));
+ tt_int_op(0, OP_EQ, string_is_utf8("\xe1\x80", 2));
+ tt_int_op(0, OP_EQ, string_is_utf8("\xe1\x80 ", 3));
+ tt_int_op(0, OP_EQ, string_is_utf8("\xf1\x80\x80", 3));
+ tt_int_op(0, OP_EQ, string_is_utf8("\xf1\x80\x80 ", 4));
+
+ // Reject encodings that are overly long.
+ tt_int_op(0, OP_EQ, string_is_utf8("\xc1\xbf", 2));
+ tt_int_op(1, OP_EQ, string_is_utf8("\xc2\x80", 2));
+ tt_int_op(0, OP_EQ, string_is_utf8("\xe0\x9f\xbf", 3));
+ tt_int_op(1, OP_EQ, string_is_utf8("\xe0\xa0\x80", 3));
+ tt_int_op(0, OP_EQ, string_is_utf8("\xf0\x8f\xbf\xbf", 4));
+ tt_int_op(1, OP_EQ, string_is_utf8("\xf0\x90\x80\x80", 4));
+
+ // Reject UTF-16 surrogate halves.
+ tt_int_op(1, OP_EQ, string_is_utf8("\xed\x9f\xbf", 3));
+ tt_int_op(0, OP_EQ, string_is_utf8("\xed\xa0\x80", 3));
+ tt_int_op(0, OP_EQ, string_is_utf8("\xed\xbf\xbf", 3));
+ tt_int_op(1, OP_EQ, string_is_utf8("\xee\x80\x80", 3));
+
+ // The maximum legal codepoint, 10FFFF.
+ tt_int_op(1, OP_EQ, string_is_utf8("\xf4\x8f\xbf\xbf", 4));
+ tt_int_op(0, OP_EQ, string_is_utf8("\xf4\x90\x80\x80", 4));
+
+ done:
+ ;
+}
+
+static void
test_util_asprintf(void *ptr)
{
#define LOREMIPSUM \
@@ -4069,7 +4234,8 @@ test_util_ftruncate(void *ptr)
tt_int_op(fd, OP_GE, 0);
/* Make the file be there. */
- tt_int_op(strlen(message), OP_EQ, write_all(fd, message, strlen(message),0));
+ tt_int_op(strlen(message), OP_EQ,
+ write_all_to_fd(fd, message, strlen(message)));
tt_int_op((int)tor_fd_getpos(fd), OP_EQ, strlen(message));
tt_int_op(0, OP_EQ, fstat(fd, &st));
tt_int_op((int)st.st_size, OP_EQ, strlen(message));
@@ -4082,7 +4248,7 @@ test_util_ftruncate(void *ptr)
/* Replace, and see if it got replaced */
tt_int_op(strlen(message2), OP_EQ,
- write_all(fd, message2, strlen(message2), 0));
+ write_all_to_fd(fd, message2, strlen(message2)));
tt_int_op((int)tor_fd_getpos(fd), OP_EQ, strlen(message2));
tt_int_op(0, OP_EQ, fstat(fd, &st));
tt_int_op((int)st.st_size, OP_EQ, strlen(message2));
@@ -5494,10 +5660,13 @@ test_util_socketpair(void *arg)
tt_assert(SOCKET_OK(fds[0]));
tt_assert(SOCKET_OK(fds[1]));
- tt_int_op(get_n_open_sockets(), OP_EQ, n + 2);
+ if (ersatz)
+ tt_int_op(get_n_open_sockets(), OP_EQ, n);
+ else
+ tt_int_op(get_n_open_sockets(), OP_EQ, n + 2);
#ifdef CAN_CHECK_CLOEXEC
- tt_int_op(fd_is_cloexec(fds[0]), OP_EQ, 1);
- tt_int_op(fd_is_cloexec(fds[1]), OP_EQ, 1);
+ tt_int_op(fd_is_cloexec(fds[0]), OP_EQ, !ersatz);
+ tt_int_op(fd_is_cloexec(fds[1]), OP_EQ, !ersatz);
#endif
#ifdef CAN_CHECK_NONBLOCK
tt_int_op(fd_is_nonblocking(fds[0]), OP_EQ, 0);
@@ -5505,10 +5674,17 @@ test_util_socketpair(void *arg)
#endif
done:
- if (SOCKET_OK(fds[0]))
- tor_close_socket(fds[0]);
- if (SOCKET_OK(fds[1]))
- tor_close_socket(fds[1]);
+ if (ersatz) {
+ if (SOCKET_OK(fds[0]))
+ tor_close_socket_simple(fds[0]);
+ if (SOCKET_OK(fds[1]))
+ tor_close_socket_simple(fds[1]);
+ } else {
+ if (SOCKET_OK(fds[0]))
+ tor_close_socket(fds[0]);
+ if (SOCKET_OK(fds[1]))
+ tor_close_socket(fds[1]);
+ }
}
#undef SOCKET_EPROTO
@@ -5525,15 +5701,15 @@ test_util_max_mem(void *arg)
tt_int_op(r, OP_EQ, r2);
tt_uint_op(memory2, OP_EQ, memory1);
- TT_BLATHER(("System memory: "U64_FORMAT, U64_PRINTF_ARG(memory1)));
+ TT_BLATHER(("System memory: %"TOR_PRIuSZ, (memory1)));
if (r==0) {
/* You have at least a megabyte. */
tt_uint_op(memory1, OP_GT, (1<<20));
} else {
/* You do not have a petabyte. */
-#if SIZEOF_SIZE_T == SIZEOF_UINT64_T
- tt_u64_op(memory1, OP_LT, (U64_LITERAL(1)<<50));
+#if SIZEOF_SIZE_T >= 8
+ tt_u64_op(memory1, OP_LT, (UINT64_C(1)<<50));
#endif
}
@@ -5875,6 +6051,13 @@ test_util_monotonic_time(void *arg)
tt_u64_op(coarse_stamp_diff, OP_GE, 120);
tt_u64_op(coarse_stamp_diff, OP_LE, 1200);
+ {
+ uint64_t units = monotime_msec_to_approx_coarse_stamp_units(5000);
+ uint64_t ms = monotime_coarse_stamp_units_to_approx_msec(units);
+ tt_u64_op(ms, OP_GE, 4950);
+ tt_u64_op(ms, OP_LT, 5050);
+ }
+
done:
;
}
@@ -5996,6 +6179,9 @@ test_util_monotonic_time_add_msec(void *arg)
monotime_coarse_add_msec(&ct2, &ct1, 1337);
tt_i64_op(monotime_diff_msec(&t1, &t2), OP_EQ, 1337);
tt_i64_op(monotime_coarse_diff_msec(&ct1, &ct2), OP_EQ, 1337);
+ // The 32-bit variant must be within 1% of the regular one.
+ tt_int_op(monotime_coarse_diff_msec32_(&ct1, &ct2), OP_GT, 1323);
+ tt_int_op(monotime_coarse_diff_msec32_(&ct1, &ct2), OP_LT, 1350);
/* Add 1337 msec twice more; make sure that any second rollover issues
* worked. */
@@ -6005,6 +6191,25 @@ test_util_monotonic_time_add_msec(void *arg)
monotime_coarse_add_msec(&ct2, &ct2, 1337);
tt_i64_op(monotime_diff_msec(&t1, &t2), OP_EQ, 1337*3);
tt_i64_op(monotime_coarse_diff_msec(&ct1, &ct2), OP_EQ, 1337*3);
+ tt_int_op(monotime_coarse_diff_msec32_(&ct1, &ct2), OP_GT, 3970);
+ tt_int_op(monotime_coarse_diff_msec32_(&ct1, &ct2), OP_LT, 4051);
+
+ done:
+ ;
+}
+
+static void
+test_util_nowrap_math(void *arg)
+{
+ (void)arg;
+
+ tt_u64_op(0, OP_EQ, tor_add_u32_nowrap(0, 0));
+ tt_u64_op(1, OP_EQ, tor_add_u32_nowrap(0, 1));
+ tt_u64_op(1, OP_EQ, tor_add_u32_nowrap(1, 0));
+ tt_u64_op(4, OP_EQ, tor_add_u32_nowrap(2, 2));
+ tt_u64_op(UINT32_MAX, OP_EQ, tor_add_u32_nowrap(UINT32_MAX-1, 2));
+ tt_u64_op(UINT32_MAX, OP_EQ, tor_add_u32_nowrap(2, UINT32_MAX-1));
+ tt_u64_op(UINT32_MAX, OP_EQ, tor_add_u32_nowrap(UINT32_MAX, UINT32_MAX));
done:
;
@@ -6115,6 +6320,57 @@ test_util_get_unquoted_path(void *arg)
tor_free(r);
}
+static void
+test_util_log_mallinfo(void *arg)
+{
+ (void)arg;
+ char *log1 = NULL, *log2 = NULL, *mem = NULL;
+#ifdef HAVE_MALLINFO
+ setup_capture_of_logs(LOG_INFO);
+ tor_log_mallinfo(LOG_INFO);
+ expect_single_log_msg_containing("mallinfo() said: ");
+ mock_saved_log_entry_t *lg = smartlist_get(mock_saved_logs(), 0);
+ log1 = tor_strdup(lg->generated_msg);
+
+ mock_clean_saved_logs();
+ mem = tor_malloc(8192);
+ tor_log_mallinfo(LOG_INFO);
+ expect_single_log_msg_containing("mallinfo() said: ");
+ lg = smartlist_get(mock_saved_logs(), 0);
+ log2 = tor_strdup(lg->generated_msg);
+
+ /* Make sure that the amount of used memory increased. */
+ const char *used1 = strstr(log1, "uordblks=");
+ const char *used2 = strstr(log2, "uordblks=");
+ tt_assert(used1);
+ tt_assert(used2);
+ used1 += strlen("uordblks=");
+ used2 += strlen("uordblks=");
+
+ int ok1, ok2;
+ char *next1 = NULL, *next2 = NULL;
+ uint64_t mem1 = tor_parse_uint64(used1, 10, 0, UINT64_MAX, &ok1, &next1);
+ uint64_t mem2 = tor_parse_uint64(used2, 10, 0, UINT64_MAX, &ok2, &next2);
+ tt_assert(ok1);
+ tt_assert(ok2);
+ tt_assert(next1);
+ tt_assert(next2);
+ if (mem2 == 0) {
+ /* This is a fake mallinfo that doesn't actually fill in its outputs. */
+ tt_u64_op(mem1, OP_EQ, 0);
+ } else {
+ tt_u64_op(mem1, OP_LT, mem2);
+ }
+#else
+ tt_skip();
+#endif
+ done:
+ teardown_capture_of_logs();
+ tor_free(log1);
+ tor_free(log2);
+ tor_free(mem);
+}
+
#define UTIL_LEGACY(name) \
{ #name, test_util_ ## name , 0, NULL, NULL }
@@ -6122,22 +6378,22 @@ test_util_get_unquoted_path(void *arg)
{ #name, test_util_ ## name, flags, NULL, NULL }
#define COMPRESS(name, identifier) \
- { "compress/" #name, test_util_compress, 0, &passthrough_setup, \
+ { "compress/" #name, test_util_compress, 0, &compress_setup, \
(char*)(identifier) }
#define COMPRESS_CONCAT(name, identifier) \
{ "compress_concat/" #name, test_util_decompress_concatenated, 0, \
- &passthrough_setup, \
+ &compress_setup, \
(char*)(identifier) }
#define COMPRESS_JUNK(name, identifier) \
{ "compress_junk/" #name, test_util_decompress_junk, 0, \
- &passthrough_setup, \
+ &compress_setup, \
(char*)(identifier) }
#define COMPRESS_DOS(name, identifier) \
{ "compress_dos/" #name, test_util_decompress_dos, 0, \
- &passthrough_setup, \
+ &compress_setup, \
(char*)(identifier) }
#ifdef _WIN32
@@ -6168,11 +6424,13 @@ struct testcase_t util_tests[] = {
COMPRESS(gzip, "gzip"),
COMPRESS(lzma, "x-tor-lzma"),
COMPRESS(zstd, "x-zstd"),
+ COMPRESS(zstd_nostatic, "x-zstd:nostatic"),
COMPRESS(none, "identity"),
COMPRESS_CONCAT(zlib, "deflate"),
COMPRESS_CONCAT(gzip, "gzip"),
COMPRESS_CONCAT(lzma, "x-tor-lzma"),
COMPRESS_CONCAT(zstd, "x-zstd"),
+ COMPRESS_CONCAT(zstd_nostatic, "x-zstd:nostatic"),
COMPRESS_CONCAT(none, "identity"),
COMPRESS_JUNK(zlib, "deflate"),
COMPRESS_JUNK(gzip, "gzip"),
@@ -6181,6 +6439,7 @@ struct testcase_t util_tests[] = {
COMPRESS_DOS(gzip, "gzip"),
COMPRESS_DOS(lzma, "x-tor-lzma"),
COMPRESS_DOS(zstd, "x-zstd"),
+ COMPRESS_DOS(zstd_nostatic, "x-zstd:nostatic"),
UTIL_TEST(gzip_compression_bomb, TT_FORK),
UTIL_LEGACY(datadir),
UTIL_LEGACY(memarea),
@@ -6197,10 +6456,12 @@ struct testcase_t util_tests[] = {
UTIL_TEST(clamp_double_to_int64, 0),
UTIL_TEST(find_str_at_start_of_line, 0),
UTIL_TEST(string_is_C_identifier, 0),
+ UTIL_TEST(string_is_utf8, 0),
UTIL_TEST(asprintf, 0),
UTIL_TEST(listdir, 0),
UTIL_TEST(parent_dir, 0),
UTIL_TEST(ftruncate, 0),
+ UTIL_TEST(nowrap_math, 0),
UTIL_TEST(num_cpus, 0),
UTIL_TEST_WIN_ONLY(load_win_lib, 0),
UTIL_TEST_NO_WIN(exit_status, 0),
@@ -6248,6 +6509,6 @@ struct testcase_t util_tests[] = {
UTIL_TEST(monotonic_time_add_msec, 0),
UTIL_TEST(htonll, 0),
UTIL_TEST(get_unquoted_path, 0),
+ UTIL_TEST(log_mallinfo, 0),
END_OF_TESTCASES
};
-
diff --git a/src/test/test_util_format.c b/src/test/test_util_format.c
index 683d5fdac1..85d8a8e62e 100644
--- a/src/test/test_util_format.c
+++ b/src/test/test_util_format.c
@@ -1,13 +1,14 @@
-/* Copyright (c) 2010-2017, The Tor Project, Inc. */
+/* Copyright (c) 2010-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
#include "orconfig.h"
-#include "or.h"
+#include "core/or/or.h"
-#include "test.h"
+#include "test/test.h"
+#include "lib/crypt_ops/crypto_rand.h"
#define UTIL_FORMAT_PRIVATE
-#include "util_format.h"
+#include "lib/encoding/binascii.h"
#define NS_MODULE util_format
@@ -18,7 +19,7 @@ test_util_format_unaligned_accessors(void *ignored)
char buf[9] = "onionsoup"; // 6f6e696f6e736f7570
tt_u64_op(get_uint64(buf+1), OP_EQ,
- tor_htonll(U64_LITERAL(0x6e696f6e736f7570)));
+ tor_htonll(UINT64_C(0x6e696f6e736f7570)));
tt_uint_op(get_uint32(buf+1), OP_EQ, htonl(0x6e696f6e));
tt_uint_op(get_uint16(buf+1), OP_EQ, htons(0x6e69));
tt_uint_op(get_uint8(buf+1), OP_EQ, 0x6e);
@@ -32,7 +33,7 @@ test_util_format_unaligned_accessors(void *ignored)
set_uint32(buf+1, htonl(0x78696465));
tt_mem_op(buf, OP_EQ, "oxidestop", 9);
- set_uint64(buf+1, tor_htonll(U64_LITERAL(0x6266757363617465)));
+ set_uint64(buf+1, tor_htonll(UINT64_C(0x6266757363617465)));
tt_mem_op(buf, OP_EQ, "obfuscate", 9);
done:
;
diff --git a/src/test/test_util_process.c b/src/test/test_util_process.c
index 68ce6cfd40..44c4da9169 100644
--- a/src/test/test_util_process.c
+++ b/src/test/test_util_process.c
@@ -1,15 +1,15 @@
-/* Copyright (c) 2010-2017, The Tor Project, Inc. */
+/* Copyright (c) 2010-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
#define UTIL_PROCESS_PRIVATE
#include "orconfig.h"
-#include "or.h"
+#include "core/or/or.h"
-#include "test.h"
+#include "test/test.h"
-#include "util_process.h"
+#include "lib/process/waitpid.h"
-#include "log_test_helpers.h"
+#include "test/log_test_helpers.h"
#ifndef _WIN32
#define NS_MODULE util_process
diff --git a/src/test/test_util_slow.c b/src/test/test_util_slow.c
index 2cd68cf118..c7b3e3e2a4 100644
--- a/src/test/test_util_slow.c
+++ b/src/test/test_util_slow.c
@@ -1,15 +1,21 @@
/* Copyright (c) 2001-2004, Roger Dingledine.
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2017, The Tor Project, Inc. */
+ * Copyright (c) 2007-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
#include "orconfig.h"
#define UTIL_PRIVATE
-#include "util.h"
-#include "util_process.h"
-#include "crypto.h"
-#include "torlog.h"
-#include "test.h"
+#define SUBPROCESS_PRIVATE
+#include "lib/crypt_ops/crypto_cipher.h"
+#include "lib/log/log.h"
+#include "lib/process/subprocess.h"
+#include "lib/process/waitpid.h"
+#include "lib/string/printf.h"
+#include "lib/time/compat_time.h"
+#include "test/test.h"
+
+#include <errno.h>
+#include <string.h>
#ifndef BUILDDIR
#define BUILDDIR "."
@@ -388,4 +394,3 @@ struct testcase_t slow_util_tests[] = {
UTIL_TEST(spawn_background_waitpid_notify, 0),
END_OF_TESTCASES
};
-
diff --git a/src/test/test_voting_schedule.c b/src/test/test_voting_schedule.c
new file mode 100644
index 0000000000..c3a581cf21
--- /dev/null
+++ b/src/test/test_voting_schedule.c
@@ -0,0 +1,64 @@
+/* Copyright (c) 2018, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#include "orconfig.h"
+
+#include "core/or/or.h"
+#include "feature/dircommon/voting_schedule.h"
+
+#include "test/test.h"
+
+static void
+test_voting_schedule_interval_start(void *arg)
+{
+#define next_interval voting_schedule_get_start_of_next_interval
+ (void)arg;
+ char buf[ISO_TIME_LEN+1];
+
+ // Midnight UTC tonight (as I am writing this test)
+ const time_t midnight = 1525651200;
+ format_iso_time(buf, midnight);
+ tt_str_op(buf, OP_EQ, "2018-05-07 00:00:00");
+
+ /* Some simple tests with a 50-minute voting interval */
+
+ tt_i64_op(next_interval(midnight, 3000, 0), OP_EQ,
+ midnight+3000);
+
+ tt_i64_op(next_interval(midnight+100, 3000, 0), OP_EQ,
+ midnight+3000);
+
+ tt_i64_op(next_interval(midnight+3000, 3000, 0), OP_EQ,
+ midnight+6000);
+
+ tt_i64_op(next_interval(midnight+3001, 3000, 0), OP_EQ,
+ midnight+6000);
+
+ /* Make sure that we roll around properly at midnight */
+ tt_i64_op(next_interval(midnight+83000, 3000, 0), OP_EQ,
+ midnight+84000);
+
+ /* We start fresh at midnight UTC, even if there are leftover seconds. */
+ tt_i64_op(next_interval(midnight+84005, 3000, 0), OP_EQ,
+ midnight+86400);
+
+ /* Now try with offsets. (These are only used for test networks.) */
+ tt_i64_op(next_interval(midnight, 3000, 99), OP_EQ,
+ midnight+99);
+
+ tt_i64_op(next_interval(midnight+100, 3000, 99), OP_EQ,
+ midnight+3099);
+
+ done:
+ ;
+#undef next_interval
+}
+
+#define VS(name,flags) \
+ { #name, test_voting_schedule_##name, (flags), NULL, NULL }
+
+struct testcase_t voting_schedule_tests[] = {
+ VS(interval_start, 0),
+ END_OF_TESTCASES
+};
+
diff --git a/src/test/test_workqueue.c b/src/test/test_workqueue.c
index 2b03173717..28fbd6fb9f 100644
--- a/src/test/test_workqueue.c
+++ b/src/test/test_workqueue.c
@@ -1,18 +1,20 @@
/* Copyright (c) 2001-2004, Roger Dingledine.
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2017, The Tor Project, Inc. */
+ * Copyright (c) 2007-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
-#include "or.h"
-#include "compat_threads.h"
-#include "onion.h"
-#include "workqueue.h"
-#include "crypto.h"
-#include "crypto_curve25519.h"
-#include "compat_libevent.h"
+#include "core/or/or.h"
+#include "lib/thread/threads.h"
+#include "core/or/onion.h"
+#include "lib/evloop/workqueue.h"
+#include "lib/crypt_ops/crypto_curve25519.h"
+#include "lib/crypt_ops/crypto_rand.h"
+#include "lib/net/alertsock.h"
+#include "lib/evloop/compat_libevent.h"
+#include "lib/intmath/weakrng.h"
+#include "lib/crypt_ops/crypto_init.h"
#include <stdio.h>
-#include <event2/event.h>
#define MAX_INFLIGHT (1<<16)
@@ -159,6 +161,7 @@ static tor_weak_rng_t weak_rng;
static int n_sent = 0;
static int rsa_sent = 0;
static int ecdh_sent = 0;
+static int n_received_previously = 0;
static int n_received = 0;
static int no_shutdown = 0;
@@ -224,18 +227,24 @@ add_n_work_items(threadpool_t *tp, int n)
workqueue_entry_t **to_cancel;
workqueue_entry_t *ent;
- to_cancel = tor_malloc(sizeof(workqueue_entry_t*) * opt_n_cancel);
+ // We'll choose randomly which entries to cancel.
+ to_cancel = tor_calloc(opt_n_cancel, sizeof(workqueue_entry_t*));
while (n_queued++ < n) {
ent = add_work(tp);
if (! ent) {
puts("Z");
- tor_event_base_loopexit(tor_libevent_get_base(), NULL);
+ tor_libevent_exit_loop_after_delay(tor_libevent_get_base(), NULL);
return -1;
}
- if (n_try_cancel < opt_n_cancel &&
- tor_weak_random_range(&weak_rng, n) < opt_n_cancel) {
+
+ if (n_try_cancel < opt_n_cancel) {
to_cancel[n_try_cancel++] = ent;
+ } else {
+ int p = tor_weak_random_range(&weak_rng, n_queued);
+ if (p < n_try_cancel) {
+ to_cancel[p] = ent;
+ }
}
}
@@ -256,19 +265,13 @@ add_n_work_items(threadpool_t *tp, int n)
static int shutting_down = 0;
static void
-replysock_readable_cb(tor_socket_t sock, short what, void *arg)
+replysock_readable_cb(threadpool_t *tp)
{
- threadpool_t *tp = arg;
- replyqueue_t *rq = threadpool_get_replyqueue(tp);
-
- int old_r = n_received;
- (void) sock;
- (void) what;
-
- replyqueue_process(rq);
- if (old_r == n_received)
+ if (n_received_previously == n_received)
return;
+ n_received_previously = n_received;
+
if (opt_verbose) {
printf("%d / %d", n_received, n_sent);
if (opt_n_cancel)
@@ -308,7 +311,7 @@ replysock_readable_cb(tor_socket_t sock, short what, void *arg)
handle_reply_shutdown, NULL);
{
struct timeval limit = { 2, 0 };
- tor_event_base_loopexit(tor_libevent_get_base(), &limit);
+ tor_libevent_exit_loop_after_delay(tor_libevent_get_base(), &limit);
}
}
}
@@ -337,7 +340,6 @@ main(int argc, char **argv)
threadpool_t *tp;
int i;
tor_libevent_cfg evcfg;
- struct event *ev;
uint32_t as_flags = 0;
for (i = 1; i < argc; ++i) {
@@ -411,11 +413,11 @@ main(int argc, char **argv)
memset(&evcfg, 0, sizeof(evcfg));
tor_libevent_initialize(&evcfg);
- ev = tor_event_new(tor_libevent_get_base(),
- replyqueue_get_socket(rq), EV_READ|EV_PERSIST,
- replysock_readable_cb, tp);
-
- event_add(ev, NULL);
+ {
+ int r = threadpool_register_reply_event(tp,
+ replysock_readable_cb);
+ tor_assert(r == 0);
+ }
#ifdef TRACK_RESPONSES
handled = bitarray_init_zero(opt_n_items);
@@ -433,10 +435,10 @@ main(int argc, char **argv)
{
struct timeval limit = { 180, 0 };
- tor_event_base_loopexit(tor_libevent_get_base(), &limit);
+ tor_libevent_exit_loop_after_delay(tor_libevent_get_base(), &limit);
}
- event_base_loop(tor_libevent_get_base(), 0);
+ tor_libevent_run_event_loop(tor_libevent_get_base(), 0);
if (n_sent != opt_n_items || n_received+n_successful_cancel != n_sent) {
printf("%d vs %d\n", n_sent, opt_n_items);
@@ -451,4 +453,3 @@ main(int argc, char **argv)
return 0;
}
}
-
diff --git a/src/test/test_x509.c b/src/test/test_x509.c
new file mode 100644
index 0000000000..9128958492
--- /dev/null
+++ b/src/test/test_x509.c
@@ -0,0 +1,205 @@
+/* Copyright (c) 2010-2018, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#define TOR_X509_PRIVATE
+#include "orconfig.h"
+
+#ifdef _WIN32
+#include <winsock2.h>
+#endif
+#include <math.h>
+#include <stddef.h>
+
+#include "lib/cc/compat_compiler.h"
+
+#include "core/or/or.h"
+#include "lib/log/log.h"
+#include "app/config/config.h"
+#include "lib/tls/x509.h"
+#include "lib/tls/x509_internal.h"
+#include "app/config/or_state_st.h"
+
+#include "test/test.h"
+#include "test/log_test_helpers.h"
+
+#include "tinytest.h"
+
+/* A mock replacement for crypto_digest that always fails. */
+static int
+mock_failing_digest(char *digest, const char *m, size_t len)
+{
+ (void)digest;
+ (void)m;
+ (void)len;
+ return -1;
+}
+
+static void
+test_x509_cert_new_failing_digest(void *arg)
+{
+ (void)arg;
+ crypto_pk_t *pk1=NULL, *pk2=NULL;
+ tor_x509_cert_impl_t *impl = NULL;
+ tor_x509_cert_t *cert = NULL;
+ pk1 = pk_generate(0);
+ pk2 = pk_generate(1);
+
+ impl = tor_tls_create_certificate(pk1, pk2, "hello", "world", 86400*100);
+ tt_assert(impl);
+ MOCK(crypto_digest, mock_failing_digest);
+
+ setup_full_capture_of_logs(LOG_WARN);
+ cert = tor_x509_cert_new(impl);
+ tt_assert(!cert);
+ expect_log_msg_containing("Couldn't wrap encoded X509 certificate");
+ expect_log_msg_containing("unable to compute digests of certificate key");
+
+ done:
+ crypto_pk_free(pk1);
+ crypto_pk_free(pk2);
+ UNMOCK(crypto_digest);
+ teardown_capture_of_logs();
+}
+
+static tor_x509_cert_t *
+cert_from_der64(const char *der64)
+{
+ size_t der64len = strlen(der64);
+ unsigned char *der = tor_malloc_zero(der64len);
+ int derlen;
+ tor_x509_cert_t *cert = NULL;
+
+ derlen = base64_decode((char*)der, der64len,
+ der64, der64len);
+ if (derlen >= 0)
+ cert = tor_x509_cert_decode(der, derlen);
+ tor_free(der);
+ return cert;
+}
+
+static void
+test_x509_consume_ec_cert(void *arg)
+{
+ (void)arg;
+ /* This is a small self-signed EC certificate. */
+ const char certificate[] =
+ "MIIBEzCBugIJAIdl5svgOZ0OMAoGCCqGSM49BAMCMBIxEDAOBgNVBAMMB1Rlc3Rp\n"
+ "bmcwHhcNMTgwODIzMTcyMzI1WhcNMTkwODIzMTcyMzI1WjASMRAwDgYDVQQDDAdU\n"
+ "ZXN0aW5nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAExMDpnRc0Btic3tIyCKNE\n"
+ "iNY4j4gzcaYzS2sTYRoVK3RAukG29Qg6/c8e8XcnsSquU4fItYxDRbi/3nhYk4CP\n"
+ "GDAKBggqhkjOPQQDAgNIADBFAiA0h1q03C2xlONUgAOonJLrlV1SUtMeKDxNsxsU\n"
+ "+FSPvQIhAM7kY9Tlt0ELmyMnORPp1VJieXn/qhL5VoxGxSedTbny\n";
+ const time_t now = 1535045321; /* when I'm writing this test. */
+ tor_x509_cert_t *cert = cert_from_der64(certificate);
+ crypto_pk_t *key = NULL;
+ tt_assert(cert);
+
+ key = tor_tls_cert_get_key(cert);
+ tt_ptr_op(NULL, OP_EQ, key); // Can't get an RSA key out of an EC cert.
+
+ /* It's a self-signed cert -- make sure it signed itself. */
+ tt_assert(tor_tls_cert_is_valid(LOG_ERR, cert, cert, now, 0));
+
+ /* Make sure we detect its key as non-RSA1024 */
+ setup_capture_of_logs(LOG_INFO);
+ tt_assert(! tor_tls_cert_is_valid(LOG_INFO, cert, cert, now, 1));
+ expect_log_msg_containing("Key is not RSA1024");
+
+ done:
+ tor_x509_cert_free(cert);
+ crypto_pk_free(key);
+ teardown_capture_of_logs();
+}
+
+static void
+test_x509_reject_tiny_keys(void *arg)
+{
+ (void)arg;
+ const char *certificates[] = {
+ /* Self-signed RSA512 */
+ "MIIBXDCCAQYCCQDKikjJYZI5uDANBgkqhkiG9w0BAQsFADA1MRUwEwYDVQQHDAxE\n"
+ "ZWZhdWx0IENpdHkxHDAaBgNVBAoME0RlZmF1bHQgQ29tcGFueSBMdGQwHhcNMTgw\n"
+ "ODIzMTczNjQ4WhcNMTkwODIzMTczNjQ4WjA1MRUwEwYDVQQHDAxEZWZhdWx0IENp\n"
+ "dHkxHDAaBgNVBAoME0RlZmF1bHQgQ29tcGFueSBMdGQwXDANBgkqhkiG9w0BAQEF\n"
+ "AANLADBIAkEAqOvVKzrSpmKOTNqDzBG/iZrUdhCrMRsymFXyIScJcdsyn7jB8RMy\n"
+ "fbHqG8EqB8HHLU/eqt/+zhh2w08Lx3+5QwIDAQABMA0GCSqGSIb3DQEBCwUAA0EA\n"
+ "RSCq0sNbD9uWfcBqF0U4MtfFjU5x+RQQCeBVtAzwC9bggSILKZfB9XUvtGh6vqig\n",
+ /* Self-signed secp112r2 */
+ "MIIBLTCB+QIJAI0LtN9uWxy3MAoGCCqGSM49BAMCMEUxCzAJBgNVBAYTAkFVMRMw\n"
+ "EQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0\n"
+ "eSBMdGQwHhcNMTgwODIzMTc0MTQ4WhcNMTkwODIzMTc0MTQ4WjBFMQswCQYDVQQG\n"
+ "EwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lk\n"
+ "Z2l0cyBQdHkgTHRkMDIwEAYHKoZIzj0CAQYFK4EEAAcDHgAEf7dFHo7xhCtIcgyo\n"
+ "Px+IDcUUlntZCtar6V4O0zAKBggqhkjOPQQDAgMjADAgAg4yhBJMEmpkNbZU95Zf\n"
+ "uwIOJAan4J1ETxUII1RrGmw=\n"
+ };
+ const time_t now = 1535046182;
+ tor_x509_cert_t *cert = NULL;
+
+ unsigned i;
+ for (i = 0; i < ARRAY_LENGTH(certificates); ++i) {
+ cert = cert_from_der64(certificates[i]);
+ /* It might parse okay, depending on our version of NSS or OpenSSL. */
+ if (cert == NULL)
+ continue;
+ /* But it should not validate. */
+ tt_assert(! tor_tls_cert_is_valid(LOG_INFO, cert, cert, now, 0));
+ tor_x509_cert_free(cert);
+ }
+
+ done:
+ tor_x509_cert_free(cert);
+}
+
+static void
+test_x509_expiration(void *arg)
+{
+ (void)arg;
+ /* a 365-day RSA2048 cert, created between 0 and 60 minutes before "now" */
+ const char certificate[] =
+ "MIICzjCCAbYCCQDxIONWIQ9OGDANBgkqhkiG9w0BAQsFADApMQswCQYDVQQGEwJV\n"
+ "UzEaMBgGA1UEAwwRSW50ZXJlc3RpbmcgdGltZXMwHhcNMTgwODIzMTc1NTE4WhcN\n"
+ "MTkwODIzMTc1NTE4WjApMQswCQYDVQQGEwJVUzEaMBgGA1UEAwwRSW50ZXJlc3Rp\n"
+ "bmcgdGltZXMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQD0Blz1fBii\n"
+ "OffpFlzMrmfPah/vkPcNrwoyx5YiosbHErYUpqdCtfNb7rbBM5xcac1LmF9kjnOQ\n"
+ "uAw1jsCNE82QHwWMlXOqaZCEJsnttNo0Y7yaSR/ChbGJ54XCp+Lx2acyTeH9cBWU\n"
+ "de8/sKAQ4NqpbEP01pBH4+1mPu2MYWjVWVicUxmw0mJ3cfkJCWUzt0nC4ls8+Itk\n"
+ "7XliKb216Z9uQXu/zD/JGkxAljnFs1jXCX4NyWz46xnJFzXbYCeyQnBz0tUbAvgg\n"
+ "uRdryYtHzD46hd8LTXH6oK2gV64ILAhDnRb1aBjnCXxbex24XoW3hjSrKGTdNsXA\n"
+ "RMWU/8QZaoiBAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAFIYDBcbit2kOMrHECZK\n"
+ "ctem40A3s+0ZifzZ2KLhW8dTr/2Zb6DnlqVm2iUOV4cG/o1RAn/HzkQQuWEq+oBG\n"
+ "yOPVHudvCyGs+2ZQWudgAv9xq8N7KtZwJhnn42c2YSoreqRXDQgJqGFatyr+XdR7\n"
+ "gdQapLI4BFbZToeXp49Nl+q9330hKaSmIYmWEZ7R/33R64PU2el7X9/apYEcuZQT\n"
+ "+FjEqcO1lJ8/dTwM/2C1BJZqUeFTAu+ac1M+4//qyJRUUc6xSJLhiens8atWaxwL\n"
+ "eBCT8fCY8oPOwA1eImc/yWWmWXpv8bBWVe8OeLCMKM/OZoIdFqQpqSdcyGoh/kIW\n"
+ "Dws=\n";
+ const time_t now = 1535046996;
+
+ tor_x509_cert_t *cert = cert_from_der64(certificate);
+ tt_assert(cert);
+
+ tt_assert(tor_tls_cert_is_valid(LOG_ERR, cert, cert, now, 0));
+
+ tt_assert(tor_tls_cert_is_valid(LOG_ERR, cert, cert,
+ now-TOR_X509_FUTURE_SLOP, 0));
+ tt_assert(tor_tls_cert_is_valid(LOG_ERR, cert, cert,
+ now+365*86400+TOR_X509_PAST_SLOP - 3600, 0));
+
+ tt_assert(! tor_tls_cert_is_valid(LOG_INFO, cert, cert,
+ now-TOR_X509_FUTURE_SLOP - 3600, 0));
+ tt_assert(! tor_tls_cert_is_valid(LOG_INFO, cert, cert,
+ now+365*86400+TOR_X509_FUTURE_SLOP, 0));
+
+ done:
+ tor_x509_cert_free(cert);
+}
+
+#define TEST(name) { #name, test_x509_ ## name, TT_FORK, 0, NULL }
+
+struct testcase_t x509_tests[] = {
+ TEST(cert_new_failing_digest),
+ TEST(consume_ec_cert),
+ TEST(reject_tiny_keys),
+ TEST(expiration),
+ END_OF_TESTCASES
+};
diff --git a/src/test/test_zero_length_keys.sh b/src/test/test_zero_length_keys.sh
index f85edb68db..84ca513b0a 100755
--- a/src/test/test_zero_length_keys.sh
+++ b/src/test/test_zero_length_keys.sh
@@ -3,8 +3,8 @@
exitcode=0
-"${SHELL:-sh}" "${abs_top_srcdir:-.}/src/test/zero_length_keys.sh" "${builddir:-.}/src/or/tor" -z || exitcode=1
-"${SHELL:-sh}" "${abs_top_srcdir:-.}/src/test/zero_length_keys.sh" "${builddir:-.}/src/or/tor" -d || exitcode=1
-"${SHELL:-sh}" "${abs_top_srcdir:-.}/src/test/zero_length_keys.sh" "${builddir:-.}/src/or/tor" -e || exitcode=1
+"${SHELL:-sh}" "${abs_top_srcdir:-.}/src/test/zero_length_keys.sh" "${builddir:-.}/src/app/tor" -z || exitcode=1
+"${SHELL:-sh}" "${abs_top_srcdir:-.}/src/test/zero_length_keys.sh" "${builddir:-.}/src/app/tor" -d || exitcode=1
+"${SHELL:-sh}" "${abs_top_srcdir:-.}/src/test/zero_length_keys.sh" "${builddir:-.}/src/app/tor" -e || exitcode=1
exit ${exitcode}
diff --git a/src/test/testing_common.c b/src/test/testing_common.c
index 52729147b2..c52683afca 100644
--- a/src/test/testing_common.c
+++ b/src/test/testing_common.c
@@ -1,6 +1,6 @@
/* Copyright (c) 2001-2004, Roger Dingledine.
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2017, The Tor Project, Inc. */
+ * Copyright (c) 2007-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
/**
@@ -8,19 +8,34 @@
* \brief Common pieces to implement unit tests.
**/
+#define MAINLOOP_PRIVATE
#include "orconfig.h"
-#include "or.h"
-#include "control.h"
-#include "config.h"
-#include "rephist.h"
-#include "backtrace.h"
-#include "test.h"
-#include "channelpadding.h"
+#include "core/or/or.h"
+#include "feature/control/control.h"
+#include "app/config/config.h"
+#include "lib/crypt_ops/crypto_dh.h"
+#include "lib/crypt_ops/crypto_ed25519.h"
+#include "lib/crypt_ops/crypto_rand.h"
+#include "feature/stats/predict_ports.h"
+#include "feature/stats/rephist.h"
+#include "lib/err/backtrace.h"
+#include "test/test.h"
+#include "core/or/channelpadding.h"
+#include "core/mainloop/mainloop.h"
+#include "lib/compress/compress.h"
+#include "lib/evloop/compat_libevent.h"
+#include "lib/crypt_ops/crypto_init.h"
#include <stdio.h>
#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
#ifdef _WIN32
/* For mkdir() */
@@ -29,13 +44,6 @@
#include <dirent.h>
#endif /* defined(_WIN32) */
-#include "or.h"
-
-#ifdef USE_DMALLOC
-#include <dmalloc.h>
-#include "main.h"
-#endif
-
/** Temporary directory (set up by setup_directory) under which we store all
* our files during testing. */
static char temp_dir[256];
@@ -106,8 +114,8 @@ get_fname_suffix(const char *name, const char *suffix)
setup_directory();
if (!name)
return temp_dir;
- tor_snprintf(buf,sizeof(buf),"%s/%s%s%s",temp_dir,name,suffix ? "_" : "",
- suffix ? suffix : "");
+ tor_snprintf(buf,sizeof(buf),"%s%s%s%s%s", temp_dir, PATH_SEPARATOR, name,
+ suffix ? "_" : "", suffix ? suffix : "");
return buf;
}
@@ -216,6 +224,21 @@ an_assertion_failed(void)
tinytest_set_test_failed_();
}
+void tinytest_prefork(void);
+void tinytest_postfork(void);
+void
+tinytest_prefork(void)
+{
+ free_pregenerated_keys();
+ crypto_prefork();
+}
+void
+tinytest_postfork(void)
+{
+ crypto_postfork();
+ init_pregenerated_keys();
+}
+
/** Main entry point for unit test code: parse the command line, and run
* some unit tests. */
int
@@ -230,13 +253,6 @@ main(int c, const char **v)
/* We must initialise logs before we call tor_assert() */
init_logging(1);
-#ifdef USE_DMALLOC
- {
- int r = crypto_use_tor_alloc_functions();
- tor_assert(r == 0);
- }
-#endif /* defined(USE_DMALLOC) */
-
update_approx_time(time(NULL));
options = options_new();
tor_threads_init();
@@ -285,13 +301,13 @@ main(int c, const char **v)
printf("Can't initialize crypto subsystem; exiting.\n");
return 1;
}
- crypto_set_tls_dh_prime();
if (crypto_seed_rng() < 0) {
printf("Couldn't seed RNG; exiting.\n");
return 1;
}
rep_hist_init();
setup_directory();
+ initialize_mainloop_events();
options_init(options);
options->DataDirectory = tor_strdup(temp_dir);
tor_asprintf(&options->KeyDirectory, "%s"PATH_SEPARATOR"keys",
@@ -317,10 +333,7 @@ main(int c, const char **v)
int have_failed = (tinytest_main(c, v, testgroups) != 0);
free_pregenerated_keys();
-#ifdef USE_DMALLOC
- tor_free_all(0);
- dmalloc_log_unfreed();
-#endif
+
crypto_global_cleanup();
if (have_failed)
@@ -328,4 +341,3 @@ main(int c, const char **v)
else
return 0;
}
-
diff --git a/src/test/testing_rsakeys.c b/src/test/testing_rsakeys.c
index 7a24c0ed14..c8062b82d5 100644
--- a/src/test/testing_rsakeys.c
+++ b/src/test/testing_rsakeys.c
@@ -1,11 +1,12 @@
/* Copyright (c) 2001-2004, Roger Dingledine.
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2017, The Tor Project, Inc. */
+ * Copyright (c) 2007-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
+#include "lib/crypt_ops/crypto_rand.h"
#include "orconfig.h"
-#include "or.h"
-#include "test.h"
+#include "core/or/or.h"
+#include "test/test.h"
/** Define this if unit tests spend too much time generating public keys.
* This module is meant to save time by using a bunch of pregenerated RSA
@@ -489,7 +490,7 @@ crypto_pk_generate_key_with_bits__get_cached(crypto_pk_t *env, int bits)
{
if (bits == 1024 || bits == 2048) {
crypto_pk_t *newkey = pk_generate_internal(bits);
- crypto_pk_assign_(env, newkey);
+ crypto_pk_assign_private(env, newkey);
crypto_pk_free(newkey);
} else {
return crypto_pk_generate_key_with_bits__real(env, bits);
@@ -543,4 +544,3 @@ init_pregenerated_keys(void)
crypto_pk_generate_key_with_bits__get_cached);
#endif /* defined(USE_PREGENERATED_RSA_KEYS) */
}
-