aboutsummaryrefslogtreecommitdiff
path: root/src/test
diff options
context:
space:
mode:
Diffstat (limited to 'src/test')
-rw-r--r--src/test/bench.c20
-rw-r--r--src/test/include.am8
-rw-r--r--src/test/log_test_helpers.c157
-rw-r--r--src/test/log_test_helpers.h62
-rw-r--r--src/test/sr_commit_calc_ref.py51
-rw-r--r--src/test/test-child.c2
-rw-r--r--src/test/test-memwipe.c20
-rw-r--r--src/test/test.c1
-rw-r--r--src/test/test.h4
-rw-r--r--src/test/test_addr.c12
-rw-r--r--src/test/test_address.c29
-rw-r--r--src/test/test_buffers.c22
-rw-r--r--src/test/test_channel.c4
-rw-r--r--src/test/test_channeltls.c11
-rw-r--r--src/test/test_circuitlist.c22
-rw-r--r--src/test/test_compat_libevent.c14
-rw-r--r--src/test/test_config.c315
-rw-r--r--src/test/test_connection.c36
-rw-r--r--src/test/test_containers.c16
-rw-r--r--src/test/test_controller.c48
-rw-r--r--src/test/test_crypto.c167
-rw-r--r--src/test/test_crypto_slow.c84
-rw-r--r--src/test/test_dir.c497
-rw-r--r--src/test/test_dir_common.c1
-rw-r--r--src/test/test_dir_handle_get.c102
-rw-r--r--src/test/test_entryconn.c20
-rw-r--r--src/test/test_entrynodes.c18
-rw-r--r--src/test/test_guardfraction.c7
-rw-r--r--src/test/test_hs.c210
-rw-r--r--src/test/test_link_handshake.c790
-rw-r--r--src/test/test_options.c264
-rw-r--r--src/test/test_policy.c8
-rw-r--r--src/test/test_protover.c195
-rw-r--r--src/test/test_pt.c8
-rw-r--r--src/test/test_relay.c12
-rw-r--r--src/test/test_rendcache.c13
-rw-r--r--src/test/test_routerkeys.c61
-rw-r--r--src/test/test_routerlist.c68
-rw-r--r--src/test/test_routerset.c28
-rw-r--r--src/test/test_scheduler.c3
-rw-r--r--src/test/test_shared_random.c73
-rw-r--r--src/test/test_status.c2
-rw-r--r--src/test/test_threads.c20
-rw-r--r--src/test/test_tortls.c74
-rw-r--r--src/test/test_util.c487
-rw-r--r--src/test/test_util_format.c17
-rw-r--r--src/test/test_util_process.c11
-rw-r--r--src/test/testing_common.c70
-rw-r--r--src/test/testing_rsakeys.c546
49 files changed, 3931 insertions, 779 deletions
diff --git a/src/test/bench.c b/src/test/bench.c
index f1cf715f30..30984fda70 100644
--- a/src/test/bench.c
+++ b/src/test/bench.c
@@ -90,7 +90,9 @@ bench_aes(void)
uint64_t start, end;
const int bytes_per_iter = (1<<24);
reset_perftime();
- c = crypto_cipher_new(NULL);
+ char key[CIPHER_KEY_LEN];
+ crypto_rand(key, sizeof(key));
+ c = crypto_cipher_new(key);
for (len = 1; len <= 8192; len *= 2) {
int iters = bytes_per_iter / len;
@@ -328,8 +330,9 @@ bench_cell_aes(void)
char *b = tor_malloc(len+max_misalign);
crypto_cipher_t *c;
int i, misalign;
-
- c = crypto_cipher_new(NULL);
+ char key[CIPHER_KEY_LEN];
+ crypto_rand(key, sizeof(key));
+ c = crypto_cipher_new(key);
reset_perftime();
for (misalign = 0; misalign <= max_misalign; ++misalign) {
@@ -501,8 +504,11 @@ bench_cell_ops(void)
or_circ->base_.purpose = CIRCUIT_PURPOSE_OR;
/* Initialize crypto */
- or_circ->p_crypto = crypto_cipher_new(NULL);
- or_circ->n_crypto = crypto_cipher_new(NULL);
+ 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();
@@ -557,7 +563,7 @@ bench_dh(void)
dh_b, dh_pubkey_a, sizeof(dh_pubkey_a),
secret_b, sizeof(secret_b));
tor_assert(slen_a == slen_b);
- tor_assert(!memcmp(secret_a, secret_b, slen_a));
+ tor_assert(fast_memeq(secret_a, secret_b, slen_a));
crypto_dh_free(dh_a);
crypto_dh_free(dh_b);
}
@@ -595,7 +601,7 @@ bench_ecdh_impl(int nid, const char *name)
NULL);
tor_assert(slen_a == slen_b);
- tor_assert(!memcmp(secret_a, secret_b, slen_a));
+ tor_assert(fast_memeq(secret_a, secret_b, slen_a));
EC_KEY_free(dh_a);
EC_KEY_free(dh_b);
}
diff --git a/src/test/include.am b/src/test/include.am
index f3d0015499..f6e43148f0 100644
--- a/src/test/include.am
+++ b/src/test/include.am
@@ -28,9 +28,10 @@ TESTS += src/test/test src/test/test-slow src/test/test-memwipe \
$(TESTSCRIPTS)
# These flavors are run using automake's test-driver and test-network.sh
-TEST_CHUTNEY_FLAVORS = basic-min bridges-min hs-min bridges+hs
+TEST_CHUTNEY_FLAVORS = basic-min bridges-min hs-min single-onion
# only run if we can ping6 ::1 (localhost)
-TEST_CHUTNEY_FLAVORS_IPV6 = bridges+ipv6-min ipv6-exit-min
+TEST_CHUTNEY_FLAVORS_IPV6 = bridges+ipv6-min ipv6-exit-min hs-ipv6 \
+ single-onion-ipv6
# only run if we can find a stable (or simply another) version of tor
TEST_CHUTNEY_FLAVORS_MIXED = mixed
@@ -109,6 +110,7 @@ src_test_test_SOURCES = \
src/test/test_options.c \
src/test/test_policy.c \
src/test/test_procmon.c \
+ src/test/test_protover.c \
src/test/test_pt.c \
src/test/test_pubsub.c \
src/test/test_relay.c \
@@ -130,6 +132,7 @@ src_test_test_SOURCES = \
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 = \
@@ -137,6 +140,7 @@ src_test_test_slow_SOURCES = \
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
src_test_test_memwipe_SOURCES = \
diff --git a/src/test/log_test_helpers.c b/src/test/log_test_helpers.c
index 166a777747..c788a33c17 100644
--- a/src/test/log_test_helpers.c
+++ b/src/test/log_test_helpers.c
@@ -4,27 +4,92 @@
#include "torlog.h"
#include "log_test_helpers.h"
+/**
+ * \file log_test_helpers.c
+ * \brief Code to check for expected log messages during testing.
+ */
+
+static void mock_saving_logv(int severity, log_domain_mask_t domain,
+ const char *funcname, const char *suffix,
+ const char *format, va_list ap)
+ CHECK_PRINTF(5, 0);
+
+/**
+ * Smartlist of all the logs we've received since we last set up
+ * log capture.
+ */
static smartlist_t *saved_logs = NULL;
-int
+/** Boolean: should we also send messages to the test-runner? */
+static int echo_to_real_logs = 1;
+
+/** Record logs at this level or more severe */
+static int record_logs_at_level = LOG_ERR;
+
+static int saved_log_level = 0;
+
+/**
+ * As setup_capture_of_logs, but do not relay log messages into the main
+ * logging system.
+ *
+ * Avoid using this function; use setup_capture_of_logs() instead if you
+ * can. If you must use this function, then make sure you detect any
+ * unexpected log messages, and treat them as test failures. */
+void
+setup_full_capture_of_logs(int new_level)
+{
+ setup_capture_of_logs(new_level);
+ echo_to_real_logs = 0;
+}
+
+/**
+ * Temporarily capture all the messages logged at severity <b>new_level</b> or
+ * higher.
+ *
+ * This function does not prevent messages from being sent to the main
+ * logging system.
+ */
+void
setup_capture_of_logs(int new_level)
{
- int previous_log = log_global_min_severity_;
- log_global_min_severity_ = new_level;
+ if (saved_log_level == 0) {
+ saved_log_level = log_global_min_severity_;
+ } else {
+ tor_assert(0);
+ }
+
+ /* Only change the log_global_min_severity_ if we're making things _more_
+ * verbose. Otherwise we could prevent real log messages that the test-
+ * runner wanted.
+ */
+ if (log_global_min_severity_ < new_level)
+ log_global_min_severity_ = new_level;
+
+ record_logs_at_level = new_level;
mock_clean_saved_logs();
saved_logs = smartlist_new();
MOCK(logv, mock_saving_logv);
- return previous_log;
+ echo_to_real_logs = 1;
}
+/**
+ * Undo setup_capture_of_logs().
+ *
+ * This function is safe to call more than once.
+ */
void
-teardown_capture_of_logs(int prev)
+teardown_capture_of_logs(void)
{
UNMOCK(logv);
- log_global_min_severity_ = prev;
+ if (saved_log_level)
+ log_global_min_severity_ = saved_log_level;
+ saved_log_level = 0;
mock_clean_saved_logs();
}
+/**
+ * Clear all messages in mock_saved_logs()
+ */
void
mock_clean_saved_logs(void)
{
@@ -36,6 +101,11 @@ mock_clean_saved_logs(void)
saved_logs = NULL;
}
+/**
+ * Return a list of all the messages captured since the last
+ * setup_[full_]capture_of_logs() call. Each log call is recorded as a
+ * mock_saved_log_entry_t.
+ */
const smartlist_t *
mock_saved_logs(void)
{
@@ -43,23 +113,52 @@ mock_saved_logs(void)
}
int
+mock_saved_log_n_entries(void)
+{
+ return saved_logs ? smartlist_len(saved_logs) : 0;
+}
+
+/**
+ * Return true iff there is a message recorded by log capture
+ * that is exactly equal to <b>msg</b>
+ */
+int
mock_saved_log_has_message(const char *msg)
{
- int has_msg = 0;
if (saved_logs) {
SMARTLIST_FOREACH(saved_logs, mock_saved_log_entry_t *, m,
{
if (msg && m->generated_msg &&
!strcmp(msg, m->generated_msg)) {
- has_msg = 1;
+ return 1;
+ }
+ });
+ }
+
+ return 0;
+}
+
+/**
+ * Return true iff there is a message recorded by log capture
+ * that contains <b>msg</b> as a substring.
+ */
+int
+mock_saved_log_has_message_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 1;
}
});
}
- return has_msg;
+ return 0;
}
-/* Do the saved logs have any messages with severity? */
+/** Return true iff the saved logs have any messages with <b>severity</b> */
int
mock_saved_log_has_severity(int severity)
{
@@ -76,7 +175,7 @@ mock_saved_log_has_severity(int severity)
return has_sev;
}
-/* Do the saved logs have any messages? */
+/** Return true iff the the saved logs have at lease one message */
int
mock_saved_log_has_entry(void)
{
@@ -86,12 +185,14 @@ mock_saved_log_has_entry(void)
return 0;
}
-void
+/* Replacement for logv: record the log message, and (maybe) send it
+ * into the logging system again.
+ */
+static void
mock_saving_logv(int severity, log_domain_mask_t domain,
const char *funcname, const char *suffix,
const char *format, va_list ap)
{
- (void)domain;
char *buf = tor_malloc_zero(10240);
int n;
n = tor_vsnprintf(buf,10240,format,ap);
@@ -99,6 +200,18 @@ mock_saving_logv(int severity, log_domain_mask_t domain,
buf[n]='\n';
buf[n+1]='\0';
+ if (echo_to_real_logs) {
+ tor_log(severity, domain|LD_NO_MOCK, "%s", buf);
+ }
+
+ if (severity > record_logs_at_level) {
+ tor_free(buf);
+ return;
+ }
+
+ if (!saved_logs)
+ saved_logs = smartlist_new();
+
mock_saved_log_entry_t *e = tor_malloc_zero(sizeof(mock_saved_log_entry_t));
e->severity = severity;
e->funcname = funcname;
@@ -107,8 +220,22 @@ mock_saving_logv(int severity, log_domain_mask_t domain,
e->generated_msg = tor_strdup(buf);
tor_free(buf);
- if (!saved_logs)
- saved_logs = smartlist_new();
smartlist_add(saved_logs, e);
}
+void
+mock_dump_saved_logs(void)
+{
+ if (saved_logs == NULL) {
+ puts(" Captured logs: NULL");
+ return;
+ }
+
+ puts(" Captured logs:");
+ SMARTLIST_FOREACH_BEGIN(saved_logs, const mock_saved_log_entry_t *, m) {
+ printf("% 5d. %s: %s\n", m_sl_idx + 1,
+ log_level_to_string(m->severity),
+ escaped(m->generated_msg));
+ } SMARTLIST_FOREACH_END(m);
+}
+
diff --git a/src/test/log_test_helpers.h b/src/test/log_test_helpers.h
index 1966f170fb..4c020c7ec3 100644
--- a/src/test/log_test_helpers.h
+++ b/src/test/log_test_helpers.h
@@ -6,50 +6,84 @@
#ifndef TOR_LOG_TEST_HELPERS_H
#define TOR_LOG_TEST_HELPERS_H
+/** An element of mock_saved_logs(); records the log element that we
+ * received. */
typedef struct mock_saved_log_entry_t {
int severity;
const char *funcname;
const char *suffix;
const char *format;
char *generated_msg;
- struct mock_saved_log_entry_t *next;
} mock_saved_log_entry_t;
-void mock_saving_logv(int severity, log_domain_mask_t domain,
- const char *funcname, const char *suffix,
- const char *format, va_list ap)
- CHECK_PRINTF(5, 0);
void mock_clean_saved_logs(void);
const smartlist_t *mock_saved_logs(void);
-int setup_capture_of_logs(int new_level);
-void teardown_capture_of_logs(int prev);
+void setup_capture_of_logs(int new_level);
+void setup_full_capture_of_logs(int new_level);
+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_severity(int severity);
int mock_saved_log_has_entry(void);
+int mock_saved_log_n_entries(void);
+void mock_dump_saved_logs(void);
-#define expect_log_msg(str) \
- tt_assert_msg(mock_saved_log_has_message(str), \
+#define assert_log_predicate(predicate, failure_msg) \
+ do { \
+ if (!(predicate)) { \
+ tt_fail_msg((failure_msg)); \
+ mock_dump_saved_logs(); \
+ TT_EXIT_TEST_FUNCTION; \
+ } \
+ } while (0)
+
+#define expect_log_msg(str) \
+ assert_log_predicate(mock_saved_log_has_message(str), \
+ "expected log to contain " # str);
+
+#define expect_log_msg_containing(str) \
+ assert_log_predicate(mock_saved_log_has_message_containing(str), \
"expected log to contain " # 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);
+
+#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); \
+ } 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); \
+ } while (0);
+
#define expect_no_log_msg(str) \
- tt_assert_msg(!mock_saved_log_has_message(str), \
+ assert_log_predicate(!mock_saved_log_has_message(str), \
"expected log to not contain " # str);
#define expect_log_severity(severity) \
- tt_assert_msg(mock_saved_log_has_severity(severity), \
+ assert_log_predicate(mock_saved_log_has_severity(severity), \
"expected log to contain severity " # severity);
#define expect_no_log_severity(severity) \
- tt_assert_msg(!mock_saved_log_has_severity(severity), \
+ assert_log_predicate(!mock_saved_log_has_severity(severity), \
"expected log to not contain severity " # severity);
#define expect_log_entry() \
- tt_assert_msg(mock_saved_log_has_entry(), \
+ assert_log_predicate(mock_saved_log_has_entry(), \
"expected log to contain entries");
#define expect_no_log_entry() \
- tt_assert_msg(!mock_saved_log_has_entry(), \
+ assert_log_predicate(!mock_saved_log_has_entry(), \
"expected log to not contain entries");
#endif
diff --git a/src/test/sr_commit_calc_ref.py b/src/test/sr_commit_calc_ref.py
new file mode 100644
index 0000000000..45e629cfb0
--- /dev/null
+++ b/src/test/sr_commit_calc_ref.py
@@ -0,0 +1,51 @@
+# This is a reference implementation of the COMMIT/REVEAL calculation for
+# prop250. We use it to generate a test vector for the test_encoding()
+# unittest.
+#
+# Here is the computation formula:
+#
+# H = SHA3-256
+# TIMESTAMP = 8 bytes network-endian value
+# RAND = H(32 bytes of random)
+#
+# REVEAL = base64-encode( TIMESTAMP || RAND )
+# COMMIT = base64-encode( TIMESTAMP || H(REVEAL) )
+#
+
+import sys
+import hashlib
+import struct
+import base64
+
+# Python 3.6+, the SHA3 is available in hashlib natively. Else this requires
+# the pysha3 package (pip install pysha3).
+if sys.version_info < (3, 6):
+ import sha3
+
+# Test vector to make sure the right sha3 version will be used. pysha3 < 1.0
+# used the old Keccak implementation. During the finalization of SHA3, NIST
+# changed the delimiter suffix from 0x01 to 0x06. The Keccak sponge function
+# stayed the same. pysha3 1.0 provides the previous Keccak hash, too.
+TEST_VALUE = "e167f68d6563d75bb25f3aa49c29ef612d41352dc00606de7cbd630bb2665f51"
+if TEST_VALUE != sha3.sha3_256(b"Hello World").hexdigest():
+ print("pysha3 version is < 1.0. Please install from:")
+ print("https://github.com/tiran/pysha3https://github.com/tiran/pysha3")
+ sys.exit(1)
+
+# TIMESTAMP
+ts = 1454333590
+# RAND
+data = 'A' * 32 # Yes very very random, NIST grade :).
+rand = hashlib.sha3_256(data)
+
+reveal = struct.pack('!Q', ts) + rand.digest()
+b64_reveal = base64.b64encode(reveal)
+print("REVEAL: %s" % (b64_reveal))
+
+# Yes we do hash the _encoded_ reveal here that is H(REVEAL)
+hashed_reveal = hashlib.sha3_256(b64_reveal)
+commit = struct.pack('!Q', ts) + hashed_reveal.digest()
+print("COMMIT: %s" % (base64.b64encode(commit)))
+
+# REVEAL: AAAAAFavXpZJxbwTupvaJCTeIUCQmOPxAMblc7ChL5H2nZKuGchdaA==
+# COMMIT: AAAAAFavXpbkBMzMQG7aNoaGLFNpm2Wkk1ozXhuWWqL//GynltxVAg==
diff --git a/src/test/test-child.c b/src/test/test-child.c
index e2552a499d..fdf3ccec0a 100644
--- a/src/test/test-child.c
+++ b/src/test/test-child.c
@@ -1,8 +1,8 @@
/* Copyright (c) 2011-2016, The Tor Project, Inc. */
/* See LICENSE for licensing information */
-#include <stdio.h>
#include "orconfig.h"
+#include <stdio.h>
#ifdef _WIN32
#define WINDOWS_LEAN_AND_MEAN
#include <windows.h>
diff --git a/src/test/test-memwipe.c b/src/test/test-memwipe.c
index c28d5054a2..21882448c3 100644
--- a/src/test/test-memwipe.c
+++ b/src/test/test-memwipe.c
@@ -1,3 +1,4 @@
+#include "orconfig.h"
#include <string.h>
#include <stdio.h>
#include <sys/types.h>
@@ -5,6 +6,7 @@
#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));
@@ -34,6 +36,12 @@ const char *s = NULL;
sum += (unsigned char)buf[i]; \
}
+#ifdef __OpenBSD__
+/* Disable some of OpenBSD's malloc protections for this test. This helps
+ * us do bad things, such as access freed buffers, without crashing. */
+const char *malloc_options="sufjj";
+#endif
+
static unsigned
fill_a_buffer_memset(void)
{
@@ -98,29 +106,29 @@ static char *heap_buf = NULL;
static unsigned
fill_heap_buffer_memset(void)
{
- char *buf = heap_buf = malloc(BUF_LEN);
+ char *buf = heap_buf = raw_malloc(BUF_LEN);
FILL_BUFFER_IMPL()
memset(buf, 0, BUF_LEN);
- free(buf);
+ raw_free(buf);
return sum;
}
static unsigned
fill_heap_buffer_memwipe(void)
{
- char *buf = heap_buf = malloc(BUF_LEN);
+ char *buf = heap_buf = raw_malloc(BUF_LEN);
FILL_BUFFER_IMPL()
memwipe(buf, 0, BUF_LEN);
- free(buf);
+ raw_free(buf);
return sum;
}
static unsigned
fill_heap_buffer_nothing(void)
{
- char *buf = heap_buf = malloc(BUF_LEN);
+ char *buf = heap_buf = raw_malloc(BUF_LEN);
FILL_BUFFER_IMPL()
- free(buf);
+ raw_free(buf);
return sum;
}
diff --git a/src/test/test.c b/src/test/test.c
index 2d3f07e03c..b02ecb922d 100644
--- a/src/test/test.c
+++ b/src/test/test.c
@@ -1216,6 +1216,7 @@ struct testgroup_t testgroups[] = {
{ "options/", options_tests },
{ "policy/" , policy_tests },
{ "procmon/", procmon_tests },
+ { "protover/", protover_tests },
{ "pt/", pt_tests },
{ "relay/" , relay_tests },
{ "relaycell/", relaycell_tests },
diff --git a/src/test/test.h b/src/test/test.h
index 764b8b638c..15ccf5c379 100644
--- a/src/test/test.h
+++ b/src/test/test.h
@@ -74,6 +74,8 @@
const char *get_fname(const char *name);
struct crypto_pk_t *pk_generate(int idx);
+void init_pregenerated_keys(void);
+void free_pregenerated_keys(void);
#define US2_CONCAT_2__(a, b) a ## __ ## b
#define US_CONCAT_2__(a, b) a ## _ ## b
@@ -169,6 +171,7 @@ struct crypto_pk_t *pk_generate(int idx);
#define NS_UNMOCK(name) UNMOCK(name)
extern const struct testcase_setup_t passthrough_setup;
+extern const struct testcase_setup_t ed25519_test_setup;
extern struct testcase_t accounting_tests[];
extern struct testcase_t addr_tests[];
@@ -208,6 +211,7 @@ extern struct testcase_t oos_tests[];
extern struct testcase_t options_tests[];
extern struct testcase_t policy_tests[];
extern struct testcase_t procmon_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[];
diff --git a/src/test/test_addr.c b/src/test/test_addr.c
index dcecb0b7dc..49e248014f 100644
--- a/src/test/test_addr.c
+++ b/src/test/test_addr.c
@@ -81,12 +81,12 @@ test_addr_basic(void *arg)
#define test_op_ip6_(a,op,b,e1,e2) \
STMT_BEGIN \
tt_assert_test_fmt_type(a,b,e1" "#op" "e2,struct in6_addr*, \
- (memcmp(val1_->s6_addr, val2_->s6_addr, 16) op 0), \
+ (fast_memcmp(val1_->s6_addr, val2_->s6_addr, 16) op 0), \
char *, "%s", \
{ char *cp; \
cp = print_ = tor_malloc(64); \
- for (int ii_=0;i<16;++i) { \
- tor_snprintf(cp, 3,"%02x", (unsigned)value_->s6_addr[i]);\
+ for (int ii_=0;ii_<16;++ii_) { \
+ tor_snprintf(cp, 3,"%02x", (unsigned)value_->s6_addr[ii_]); \
cp += 2; \
if (ii_ != 15) *cp++ = ':'; \
} \
@@ -1037,17 +1037,17 @@ test_addr_make_null(void *data)
(void) data;
/* Ensure that before tor_addr_make_null, addr != 0's */
memset(addr, 1, sizeof(*addr));
- tt_int_op(memcmp(addr, zeros, sizeof(*addr)), OP_NE, 0);
+ tt_int_op(fast_memcmp(addr, zeros, sizeof(*addr)), OP_NE, 0);
/* Test with AF == AF_INET */
zeros->family = AF_INET;
tor_addr_make_null(addr, AF_INET);
- tt_int_op(memcmp(addr, zeros, sizeof(*addr)), OP_EQ, 0);
+ tt_int_op(fast_memcmp(addr, zeros, sizeof(*addr)), OP_EQ, 0);
tt_str_op(tor_addr_to_str(buf, addr, sizeof(buf), 0), OP_EQ, "0.0.0.0");
/* Test with AF == AF_INET6 */
memset(addr, 1, sizeof(*addr));
zeros->family = AF_INET6;
tor_addr_make_null(addr, AF_INET6);
- tt_int_op(memcmp(addr, zeros, sizeof(*addr)), OP_EQ, 0);
+ tt_int_op(fast_memcmp(addr, zeros, sizeof(*addr)), OP_EQ, 0);
tt_str_op(tor_addr_to_str(buf, addr, sizeof(buf), 0), OP_EQ, "::");
done:
tor_free(addr);
diff --git a/src/test/test_address.c b/src/test/test_address.c
index b4638f0702..e52779cb64 100644
--- a/src/test/test_address.c
+++ b/src/test/test_address.c
@@ -557,6 +557,13 @@ fake_open_socket(int domain, int type, int protocol)
return FAKE_SOCKET_FD;
}
+static int
+fake_close_socket(tor_socket_t s)
+{
+ (void)s;
+ return 0;
+}
+
static int last_connected_socket_fd = 0;
static int connect_retval = 0;
@@ -617,6 +624,7 @@ test_address_udp_socket_trick_whitebox(void *arg)
MOCK(tor_open_socket,fake_open_socket);
MOCK(tor_connect_socket,pretend_to_connect);
MOCK(tor_getsockname,fake_getsockname);
+ MOCK(tor_close_socket,fake_close_socket);
mock_addr = tor_malloc_zero(sizeof(struct sockaddr_storage));
sockaddr_in_from_string("23.32.246.118",(struct sockaddr_in *)mock_addr);
@@ -647,11 +655,12 @@ test_address_udp_socket_trick_whitebox(void *arg)
tt_assert(sockaddr_in6_are_equal(mock_addr6,ipv6_to_check));
+ done:
UNMOCK(tor_open_socket);
UNMOCK(tor_connect_socket);
UNMOCK(tor_getsockname);
+ UNMOCK(tor_close_socket);
- done:
tor_free(ipv6_to_check);
tor_free(mock_addr);
tor_free(addr_from_hack);
@@ -794,7 +803,15 @@ test_address_get_if_addrs6_list_internal(void *arg)
(void)arg;
+ /* We might drop a log_err */
+ setup_full_capture_of_logs(LOG_ERR);
results = get_interface_address6_list(LOG_ERR, AF_INET6, 1);
+ tt_int_op(smartlist_len(mock_saved_logs()), OP_LE, 1);
+ if (smartlist_len(mock_saved_logs()) == 1) {
+ expect_log_msg_containing_either("connect() failed",
+ "unable to create socket");
+ }
+ teardown_capture_of_logs();
tt_assert(results != NULL);
/* Work even on systems without IPv6 interfaces */
@@ -813,6 +830,7 @@ test_address_get_if_addrs6_list_internal(void *arg)
done:
free_interface_address6_list(results);
+ teardown_capture_of_logs();
return;
}
@@ -824,10 +842,14 @@ test_address_get_if_addrs6_list_no_internal(void *arg)
(void)arg;
/* We might drop a log_err */
- int prev_level = setup_capture_of_logs(LOG_ERR);
+ setup_full_capture_of_logs(LOG_ERR);
results = get_interface_address6_list(LOG_ERR, AF_INET6, 0);
tt_int_op(smartlist_len(mock_saved_logs()), OP_LE, 1);
- teardown_capture_of_logs(prev_level);
+ if (smartlist_len(mock_saved_logs()) == 1) {
+ expect_log_msg_containing_either("connect() failed",
+ "unable to create socket");
+ }
+ teardown_capture_of_logs();
tt_assert(results != NULL);
/* Work even on systems without IPv6 interfaces */
@@ -845,6 +867,7 @@ test_address_get_if_addrs6_list_no_internal(void *arg)
}
done:
+ teardown_capture_of_logs();
free_interface_address6_list(results);
return;
}
diff --git a/src/test/test_buffers.c b/src/test/test_buffers.c
index 971dd1d889..3408da3aa9 100644
--- a/src/test/test_buffers.c
+++ b/src/test/test_buffers.c
@@ -744,6 +744,27 @@ test_buffers_tls_read_mocked(void *arg)
buf_free(buf);
}
+static void
+test_buffers_chunk_size(void *arg)
+{
+ (void)arg;
+ const int min = 256;
+ const int max = 65536;
+ tt_uint_op(preferred_chunk_size(3), OP_EQ, min);
+ tt_uint_op(preferred_chunk_size(25), OP_EQ, min);
+ tt_uint_op(preferred_chunk_size(0), OP_EQ, min);
+ tt_uint_op(preferred_chunk_size(256), OP_EQ, 512);
+ tt_uint_op(preferred_chunk_size(65400), OP_EQ, max);
+ /* Here, we're implicitly saying that the chunk header overhead is
+ * between 1 and 100 bytes. 24..48 would probably be more accurate. */
+ tt_uint_op(preferred_chunk_size(65536), OP_GT, 65536);
+ tt_uint_op(preferred_chunk_size(65536), OP_LT, 65536+100);
+ tt_uint_op(preferred_chunk_size(165536), OP_GT, 165536);
+ tt_uint_op(preferred_chunk_size(165536), OP_LT, 165536+100);
+ done:
+ ;
+}
+
struct testcase_t buffer_tests[] = {
{ "basic", test_buffers_basic, TT_FORK, NULL, NULL },
{ "copy", test_buffer_copy, TT_FORK, NULL, NULL },
@@ -758,6 +779,7 @@ struct testcase_t buffer_tests[] = {
NULL, NULL},
{ "tls_read_mocked", test_buffers_tls_read_mocked, 0,
NULL, NULL },
+ { "chunk_size", test_buffers_chunk_size, 0, NULL, NULL },
END_OF_TESTCASES
};
diff --git a/src/test/test_channel.c b/src/test/test_channel.c
index a9e0634d9e..e87f99ef50 100644
--- a/src/test/test_channel.c
+++ b/src/test/test_channel.c
@@ -1405,10 +1405,14 @@ test_channel_queue_impossible(void *arg)
/* Let it drain and check that the bad entry is discarded */
test_chan_accept_cells = 1;
+ tor_capture_bugs_(1);
channel_change_state(ch, CHANNEL_STATE_OPEN);
tt_assert(test_cells_written == old_count);
tt_int_op(chan_cell_queue_len(&(ch->outgoing_queue)), ==, 0);
+ tt_int_op(smartlist_len(tor_get_captured_bug_log_()), ==, 1);
+ tor_end_capture_bugs_();
+
done:
free_fake_channel(ch);
diff --git a/src/test/test_channeltls.c b/src/test/test_channeltls.c
index bde46a2998..fd98ee40fb 100644
--- a/src/test/test_channeltls.c
+++ b/src/test/test_channeltls.c
@@ -1,6 +1,8 @@
/* Copyright (c) 2014-2016, The Tor Project, Inc. */
/* See LICENSE for licensing information */
+#include "orconfig.h"
+
#include <math.h>
#define TOR_CHANNEL_INTERNAL_
@@ -30,6 +32,7 @@ static or_connection_t * tlschan_connection_or_connect_mock(
const tor_addr_t *addr,
uint16_t port,
const char *digest,
+ const ed25519_public_key_t *ed_id,
channel_tls_t *tlschan);
static int tlschan_is_local_addr_mock(const tor_addr_t *addr);
@@ -68,7 +71,7 @@ test_channeltls_create(void *arg)
MOCK(connection_or_connect, tlschan_connection_or_connect_mock);
/* Try connecting */
- ch = channel_tls_connect(&test_addr, 567, test_digest);
+ ch = channel_tls_connect(&test_addr, 567, test_digest, NULL);
tt_assert(ch != NULL);
done:
@@ -117,7 +120,7 @@ test_channeltls_num_bytes_queued(void *arg)
MOCK(connection_or_connect, tlschan_connection_or_connect_mock);
/* Try connecting */
- ch = channel_tls_connect(&test_addr, 567, test_digest);
+ ch = channel_tls_connect(&test_addr, 567, test_digest, NULL);
tt_assert(ch != NULL);
/*
@@ -202,7 +205,7 @@ test_channeltls_overhead_estimate(void *arg)
MOCK(connection_or_connect, tlschan_connection_or_connect_mock);
/* Try connecting */
- ch = channel_tls_connect(&test_addr, 567, test_digest);
+ ch = channel_tls_connect(&test_addr, 567, test_digest, NULL);
tt_assert(ch != NULL);
/* First case: silly low ratios should get clamped to 1.0 */
@@ -264,9 +267,11 @@ static or_connection_t *
tlschan_connection_or_connect_mock(const tor_addr_t *addr,
uint16_t port,
const char *digest,
+ const ed25519_public_key_t *ed_id,
channel_tls_t *tlschan)
{
or_connection_t *result = NULL;
+ (void) ed_id; // XXXX Not yet used.
tt_assert(addr != NULL);
tt_assert(port != 0);
diff --git a/src/test/test_circuitlist.c b/src/test/test_circuitlist.c
index 1e640b5709..e996c42115 100644
--- a/src/test/test_circuitlist.c
+++ b/src/test/test_circuitlist.c
@@ -9,6 +9,7 @@
#include "circuitbuild.h"
#include "circuitlist.h"
#include "test.h"
+#include "log_test_helpers.h"
static channel_t *
new_fake_channel(void)
@@ -270,6 +271,13 @@ test_rend_token_maps(void *arg)
}
static void
+mock_channel_dump_statistics(channel_t *chan, int severity)
+{
+ (void)chan;
+ (void)severity;
+}
+
+static void
test_pick_circid(void *arg)
{
bitarray_t *ba = NULL;
@@ -278,12 +286,22 @@ test_pick_circid(void *arg)
int i;
(void) arg;
+ MOCK(channel_dump_statistics, mock_channel_dump_statistics);
+
chan1 = tor_malloc_zero(sizeof(channel_t));
chan2 = tor_malloc_zero(sizeof(channel_t));
chan2->wide_circ_ids = 1;
+ chan1->cmux = circuitmux_alloc();
+ chan2->cmux = circuitmux_alloc();
+
+ /* CIRC_ID_TYPE_NEITHER is supposed to create a warning. */
chan1->circ_id_type = CIRC_ID_TYPE_NEITHER;
+ setup_full_capture_of_logs(LOG_WARN);
tt_int_op(0, OP_EQ, get_unique_circ_id_by_chan(chan1));
+ expect_single_log_msg_containing("Trying to pick a circuit ID for a "
+ "connection from a client with no identity.");
+ teardown_capture_of_logs();
/* Basic tests, with no collisions */
chan1->circ_id_type = CIRC_ID_TYPE_LOWER;
@@ -337,10 +355,14 @@ test_pick_circid(void *arg)
}
done:
+ circuitmux_free(chan1->cmux);
+ circuitmux_free(chan2->cmux);
tor_free(chan1);
tor_free(chan2);
bitarray_free(ba);
circuit_free_all();
+ teardown_capture_of_logs();
+ UNMOCK(channel_dump_statistics);
}
struct testcase_t circuitlist_tests[] = {
diff --git a/src/test/test_compat_libevent.c b/src/test/test_compat_libevent.c
index f13eb81124..0443cc0b1c 100644
--- a/src/test/test_compat_libevent.c
+++ b/src/test/test_compat_libevent.c
@@ -20,31 +20,36 @@ static void
test_compat_libevent_logging_callback(void *ignored)
{
(void)ignored;
- int previous_log = setup_capture_of_logs(LOG_DEBUG);
+ setup_full_capture_of_logs(LOG_DEBUG);
libevent_logging_callback(_EVENT_LOG_DEBUG, "hello world");
expect_log_msg("Message from libevent: hello world\n");
expect_log_severity(LOG_DEBUG);
+ tt_int_op(smartlist_len(mock_saved_logs()), OP_EQ, 1);
mock_clean_saved_logs();
libevent_logging_callback(_EVENT_LOG_MSG, "hello world another time");
expect_log_msg("Message from libevent: hello world another time\n");
expect_log_severity(LOG_INFO);
+ tt_int_op(smartlist_len(mock_saved_logs()), OP_EQ, 1);
mock_clean_saved_logs();
libevent_logging_callback(_EVENT_LOG_WARN, "hello world a third time");
expect_log_msg("Warning from libevent: hello world a third time\n");
expect_log_severity(LOG_WARN);
+ tt_int_op(smartlist_len(mock_saved_logs()), OP_EQ, 1);
mock_clean_saved_logs();
libevent_logging_callback(_EVENT_LOG_ERR, "hello world a fourth time");
expect_log_msg("Error from libevent: hello world a fourth time\n");
expect_log_severity(LOG_ERR);
+ tt_int_op(smartlist_len(mock_saved_logs()), OP_EQ, 1);
mock_clean_saved_logs();
libevent_logging_callback(42, "hello world a fifth time");
expect_log_msg("Message [42] from libevent: hello world a fifth time\n");
expect_log_severity(LOG_WARN);
+ tt_int_op(smartlist_len(mock_saved_logs()), OP_EQ, 1);
mock_clean_saved_logs();
libevent_logging_callback(_EVENT_LOG_DEBUG,
@@ -75,28 +80,33 @@ test_compat_libevent_logging_callback(void *ignored)
"012345678901234567890123456789"
"012345678901234567890123456789\n");
expect_log_severity(LOG_DEBUG);
+ tt_int_op(smartlist_len(mock_saved_logs()), OP_EQ, 1);
mock_clean_saved_logs();
libevent_logging_callback(42, "xxx\n");
expect_log_msg("Message [42] from libevent: xxx\n");
expect_log_severity(LOG_WARN);
+ tt_int_op(smartlist_len(mock_saved_logs()), OP_EQ, 1);
suppress_libevent_log_msg("something");
mock_clean_saved_logs();
libevent_logging_callback(_EVENT_LOG_MSG, "hello there");
expect_log_msg("Message from libevent: hello there\n");
expect_log_severity(LOG_INFO);
+ tt_int_op(smartlist_len(mock_saved_logs()), OP_EQ, 1);
mock_clean_saved_logs();
libevent_logging_callback(_EVENT_LOG_MSG, "hello there something else");
expect_no_log_msg("hello there something else");
+ if (mock_saved_logs())
+ tt_int_op(smartlist_len(mock_saved_logs()), OP_EQ, 0);
// No way of verifying the result of this, it seems =/
configure_libevent_logging();
done:
suppress_libevent_log_msg(NULL);
- teardown_capture_of_logs(previous_log);
+ teardown_capture_of_logs();
}
static void
diff --git a/src/test/test_config.c b/src/test/test_config.c
index 90ea4da87d..384bff410f 100644
--- a/src/test/test_config.c
+++ b/src/test/test_config.c
@@ -3710,6 +3710,144 @@ test_config_default_fallback_dirs(void *arg)
clear_dir_servers();
}
+static void
+test_config_port_cfg_line_extract_addrport(void *arg)
+{
+ (void)arg;
+ int unixy = 0;
+ const char *rest = NULL;
+ char *a = NULL;
+
+ tt_int_op(port_cfg_line_extract_addrport("", &a, &unixy, &rest), OP_EQ, 0);
+ tt_int_op(unixy, OP_EQ, 0);
+ tt_str_op(a, OP_EQ, "");;
+ tt_str_op(rest, OP_EQ, "");
+ tor_free(a);
+
+ tt_int_op(port_cfg_line_extract_addrport("hello", &a, &unixy, &rest),
+ OP_EQ, 0);
+ tt_int_op(unixy, OP_EQ, 0);
+ tt_str_op(a, OP_EQ, "hello");;
+ tt_str_op(rest, OP_EQ, "");
+ tor_free(a);
+
+ tt_int_op(port_cfg_line_extract_addrport(" flipperwalt gersplut",
+ &a, &unixy, &rest), OP_EQ, 0);
+ tt_int_op(unixy, OP_EQ, 0);
+ tt_str_op(a, OP_EQ, "flipperwalt");;
+ tt_str_op(rest, OP_EQ, "gersplut");
+ tor_free(a);
+
+ tt_int_op(port_cfg_line_extract_addrport(" flipperwalt \t gersplut",
+ &a, &unixy, &rest), OP_EQ, 0);
+ tt_int_op(unixy, OP_EQ, 0);
+ tt_str_op(a, OP_EQ, "flipperwalt");;
+ tt_str_op(rest, OP_EQ, "gersplut");
+ tor_free(a);
+
+ tt_int_op(port_cfg_line_extract_addrport("flipperwalt \t gersplut",
+ &a, &unixy, &rest), OP_EQ, 0);
+ tt_int_op(unixy, OP_EQ, 0);
+ tt_str_op(a, OP_EQ, "flipperwalt");;
+ tt_str_op(rest, OP_EQ, "gersplut");
+ tor_free(a);
+
+ tt_int_op(port_cfg_line_extract_addrport("unix:flipperwalt \t gersplut",
+ &a, &unixy, &rest), OP_EQ, 0);
+ tt_int_op(unixy, OP_EQ, 1);
+ tt_str_op(a, OP_EQ, "flipperwalt");;
+ tt_str_op(rest, OP_EQ, "gersplut");
+ tor_free(a);
+
+ tt_int_op(port_cfg_line_extract_addrport("lolol",
+ &a, &unixy, &rest), OP_EQ, 0);
+ tt_int_op(unixy, OP_EQ, 0);
+ tt_str_op(a, OP_EQ, "lolol");;
+ tt_str_op(rest, OP_EQ, "");
+ tor_free(a);
+
+ tt_int_op(port_cfg_line_extract_addrport("unix:lolol",
+ &a, &unixy, &rest), OP_EQ, 0);
+ tt_int_op(unixy, OP_EQ, 1);
+ tt_str_op(a, OP_EQ, "lolol");;
+ tt_str_op(rest, OP_EQ, "");
+ tor_free(a);
+
+ tt_int_op(port_cfg_line_extract_addrport("unix:lolol ",
+ &a, &unixy, &rest), OP_EQ, 0);
+ tt_int_op(unixy, OP_EQ, 1);
+ tt_str_op(a, OP_EQ, "lolol");;
+ tt_str_op(rest, OP_EQ, "");
+ tor_free(a);
+
+ tt_int_op(port_cfg_line_extract_addrport(" unix:lolol",
+ &a, &unixy, &rest), OP_EQ, 0);
+ tt_int_op(unixy, OP_EQ, 1);
+ tt_str_op(a, OP_EQ, "lolol");;
+ tt_str_op(rest, OP_EQ, "");
+ tor_free(a);
+
+ tt_int_op(port_cfg_line_extract_addrport("foobar:lolol",
+ &a, &unixy, &rest), OP_EQ, 0);
+ tt_int_op(unixy, OP_EQ, 0);
+ tt_str_op(a, OP_EQ, "foobar:lolol");;
+ tt_str_op(rest, OP_EQ, "");
+ tor_free(a);
+
+ tt_int_op(port_cfg_line_extract_addrport(":lolol",
+ &a, &unixy, &rest), OP_EQ, 0);
+ tt_int_op(unixy, OP_EQ, 0);
+ tt_str_op(a, OP_EQ, ":lolol");;
+ tt_str_op(rest, OP_EQ, "");
+ tor_free(a);
+
+ tt_int_op(port_cfg_line_extract_addrport("unix:\"lolol\"",
+ &a, &unixy, &rest), OP_EQ, 0);
+ tt_int_op(unixy, OP_EQ, 1);
+ tt_str_op(a, OP_EQ, "lolol");;
+ tt_str_op(rest, OP_EQ, "");
+ tor_free(a);
+
+ tt_int_op(port_cfg_line_extract_addrport("unix:\"lolol\" ",
+ &a, &unixy, &rest), OP_EQ, 0);
+ tt_int_op(unixy, OP_EQ, 1);
+ tt_str_op(a, OP_EQ, "lolol");;
+ tt_str_op(rest, OP_EQ, "");
+ tor_free(a);
+
+ tt_int_op(port_cfg_line_extract_addrport("unix:\"lolol\" foo ",
+ &a, &unixy, &rest), OP_EQ, 0);
+ tt_int_op(unixy, OP_EQ, 1);
+ tt_str_op(a, OP_EQ, "lolol");;
+ tt_str_op(rest, OP_EQ, "foo ");
+ tor_free(a);
+
+ tt_int_op(port_cfg_line_extract_addrport("unix:\"lol ol\" foo ",
+ &a, &unixy, &rest), OP_EQ, 0);
+ tt_int_op(unixy, OP_EQ, 1);
+ tt_str_op(a, OP_EQ, "lol ol");;
+ tt_str_op(rest, OP_EQ, "foo ");
+ tor_free(a);
+
+ tt_int_op(port_cfg_line_extract_addrport("unix:\"lol\\\" ol\" foo ",
+ &a, &unixy, &rest), OP_EQ, 0);
+ tt_int_op(unixy, OP_EQ, 1);
+ tt_str_op(a, OP_EQ, "lol\" ol");;
+ tt_str_op(rest, OP_EQ, "foo ");
+ tor_free(a);
+
+ tt_int_op(port_cfg_line_extract_addrport("unix:\"lol\\\" ol foo ",
+ &a, &unixy, &rest), OP_EQ, -1);
+ tor_free(a);
+
+ tt_int_op(port_cfg_line_extract_addrport("unix:\"lol\\0\" ol foo ",
+ &a, &unixy, &rest), OP_EQ, -1);
+ tor_free(a);
+
+ done:
+ tor_free(a);
+}
+
static config_line_t *
mock_config_line(const char *key, const char *val)
{
@@ -3832,6 +3970,8 @@ test_config_parse_port_config__listenaddress(void *data)
tt_int_op(ret, OP_EQ, 0);
// Test warning nonlocal other
+ SMARTLIST_FOREACH(slout,port_cfg_t *,pf,port_cfg_free(pf));
+ smartlist_clear(slout);
ret = parse_port_config(slout, config_port2, config_listen_address, "DNS",
0, NULL, 0, CL_PORT_WARN_NONLOCAL);
tt_int_op(ret, OP_EQ, 0);
@@ -3952,7 +4092,7 @@ test_config_parse_port_config__ports__ports_given(void *data)
tt_int_op(ret, OP_EQ, -1);
// Test error when encounters a unix domain specification but the listener
- // doesnt support domain sockets
+ // doesn't support domain sockets
config_port_valid = mock_config_line("DNSPort", "unix:/tmp/foo/bar");
ret = parse_port_config(NULL, config_port_valid, NULL, "DNS",
CONN_TYPE_AP_DNS_LISTENER, NULL, 0, 0);
@@ -3961,7 +4101,7 @@ test_config_parse_port_config__ports__ports_given(void *data)
// Test valid unix domain
SMARTLIST_FOREACH(slout,port_cfg_t *,pf,port_cfg_free(pf));
smartlist_clear(slout);
- ret = parse_port_config(slout, config_port_valid, NULL, "DNS",
+ ret = parse_port_config(slout, config_port_valid, NULL, "SOCKS",
CONN_TYPE_AP_LISTENER, NULL, 0, 0);
#ifdef _WIN32
tt_int_op(ret, OP_EQ, -1);
@@ -3972,26 +4112,153 @@ test_config_parse_port_config__ports__ports_given(void *data)
tt_int_op(port_cfg->port, OP_EQ, 0);
tt_int_op(port_cfg->is_unix_addr, OP_EQ, 1);
tt_str_op(port_cfg->unix_addr, OP_EQ, "/tmp/foo/bar");
+ /* Test entry port defaults as initialised in parse_port_config */
+ tt_int_op(port_cfg->entry_cfg.dns_request, OP_EQ, 1);
+ tt_int_op(port_cfg->entry_cfg.ipv4_traffic, OP_EQ, 1);
+ tt_int_op(port_cfg->entry_cfg.onion_traffic, OP_EQ, 1);
+ tt_int_op(port_cfg->entry_cfg.cache_ipv4_answers, OP_EQ, 1);
+ tt_int_op(port_cfg->entry_cfg.prefer_ipv6_virtaddr, OP_EQ, 1);
#endif
- // Test failure if we have no ipv4 and no ipv6 (for unix domain sockets,
- // this makes no sense - it should be fixed)
+ // Test failure if we have no ipv4 and no ipv6 and no onion (DNS only)
+ config_free_lines(config_port_invalid); config_port_invalid = NULL;
+ config_port_invalid = mock_config_line("SOCKSPort",
+ "unix:/tmp/foo/bar NoIPv4Traffic "
+ "NoOnionTraffic");
+ ret = parse_port_config(NULL, config_port_invalid, NULL, "SOCKS",
+ CONN_TYPE_AP_LISTENER, NULL, 0,
+ CL_PORT_TAKES_HOSTNAMES);
+ tt_int_op(ret, OP_EQ, -1);
+
+ // Test failure if we have no DNS and we're a DNSPort
config_free_lines(config_port_invalid); config_port_invalid = NULL;
config_port_invalid = mock_config_line("DNSPort",
- "unix:/tmp/foo/bar NoIPv4Traffic");
+ "127.0.0.1:80 NoDNSRequest");
ret = parse_port_config(NULL, config_port_invalid, NULL, "DNS",
+ CONN_TYPE_AP_DNS_LISTENER, NULL, 0,
+ CL_PORT_TAKES_HOSTNAMES);
+ tt_int_op(ret, OP_EQ, -1);
+
+ // If we're a DNSPort, DNS only is ok
+ // Use a port because DNSPort doesn't support sockets
+ 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", "127.0.0.1:80 "
+ "NoIPv4Traffic NoOnionTraffic");
+ ret = parse_port_config(slout, config_port_valid, NULL, "DNS",
+ CONN_TYPE_AP_DNS_LISTENER, NULL, 0,
+ CL_PORT_TAKES_HOSTNAMES);
+ 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->entry_cfg.dns_request, OP_EQ, 1);
+ tt_int_op(port_cfg->entry_cfg.ipv4_traffic, OP_EQ, 0);
+ tt_int_op(port_cfg->entry_cfg.ipv6_traffic, OP_EQ, 0);
+ tt_int_op(port_cfg->entry_cfg.onion_traffic, OP_EQ, 0);
+
+ // Test failure if we have DNS but no ipv4 and no ipv6
+ config_free_lines(config_port_invalid); config_port_invalid = NULL;
+ config_port_invalid = mock_config_line("SOCKSPort",
+ "unix:/tmp/foo/bar NoIPv4Traffic");
+ ret = parse_port_config(NULL, config_port_invalid, NULL, "SOCKS",
+ CONN_TYPE_AP_LISTENER, NULL, 0,
+ CL_PORT_TAKES_HOSTNAMES);
+ tt_int_op(ret, OP_EQ, -1);
+
+ // Test success with no DNS, no ipv4, no ipv6 (only onion, using separate
+ // options)
+ 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("SOCKSPort", "unix:/tmp/foo/bar "
+ "NoDNSRequest NoIPv4Traffic");
+ ret = parse_port_config(slout, config_port_valid, NULL, "SOCKS",
CONN_TYPE_AP_LISTENER, NULL, 0,
CL_PORT_TAKES_HOSTNAMES);
+#ifdef _WIN32
tt_int_op(ret, OP_EQ, -1);
+#else
+ 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->entry_cfg.dns_request, OP_EQ, 0);
+ tt_int_op(port_cfg->entry_cfg.ipv4_traffic, OP_EQ, 0);
+ tt_int_op(port_cfg->entry_cfg.ipv6_traffic, OP_EQ, 0);
+ tt_int_op(port_cfg->entry_cfg.onion_traffic, OP_EQ, 1);
+#endif
- // Test success with no ipv4 but take ipv6 (for unix domain sockets, this
- // makes no sense - it should be fixed)
+ // Test success with quoted unix: address.
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", "unix:/tmp/foo/bar "
+ config_port_valid = mock_config_line("SOCKSPort", "unix:\"/tmp/foo/ bar\" "
+ "NoDNSRequest NoIPv4Traffic");
+ ret = parse_port_config(slout, config_port_valid, NULL, "SOCKS",
+ CONN_TYPE_AP_LISTENER, NULL, 0,
+ CL_PORT_TAKES_HOSTNAMES);
+#ifdef _WIN32
+ tt_int_op(ret, OP_EQ, -1);
+#else
+ 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->entry_cfg.dns_request, OP_EQ, 0);
+ tt_int_op(port_cfg->entry_cfg.ipv4_traffic, OP_EQ, 0);
+ tt_int_op(port_cfg->entry_cfg.ipv6_traffic, OP_EQ, 0);
+ tt_int_op(port_cfg->entry_cfg.onion_traffic, OP_EQ, 1);
+#endif
+
+ // Test failure with broken quoted unix: address.
+ 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("SOCKSPort", "unix:\"/tmp/foo/ bar "
+ "NoDNSRequest NoIPv4Traffic");
+ ret = parse_port_config(slout, config_port_valid, NULL, "SOCKS",
+ CONN_TYPE_AP_LISTENER, NULL, 0,
+ CL_PORT_TAKES_HOSTNAMES);
+ tt_int_op(ret, OP_EQ, -1);
+
+ // Test failure with empty quoted unix: address.
+ 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("SOCKSPort", "unix:\"\" "
+ "NoDNSRequest NoIPv4Traffic");
+ ret = parse_port_config(slout, config_port_valid, NULL, "SOCKS",
+ CONN_TYPE_AP_LISTENER, NULL, 0,
+ CL_PORT_TAKES_HOSTNAMES);
+ tt_int_op(ret, OP_EQ, -1);
+
+ // Test success with OnionTrafficOnly (no DNS, no ipv4, no ipv6)
+ 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("SOCKSPort", "unix:/tmp/foo/bar "
+ "OnionTrafficOnly");
+ ret = parse_port_config(slout, config_port_valid, NULL, "SOCKS",
+ CONN_TYPE_AP_LISTENER, NULL, 0,
+ CL_PORT_TAKES_HOSTNAMES);
+#ifdef _WIN32
+ tt_int_op(ret, OP_EQ, -1);
+#else
+ 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->entry_cfg.dns_request, OP_EQ, 0);
+ tt_int_op(port_cfg->entry_cfg.ipv4_traffic, OP_EQ, 0);
+ tt_int_op(port_cfg->entry_cfg.ipv6_traffic, OP_EQ, 0);
+ tt_int_op(port_cfg->entry_cfg.onion_traffic, OP_EQ, 1);
+#endif
+
+ // Test success with no ipv4 but take ipv6
+ 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("SOCKSPort", "unix:/tmp/foo/bar "
"NoIPv4Traffic IPv6Traffic");
- ret = parse_port_config(slout, config_port_valid, NULL, "DNS",
+ ret = parse_port_config(slout, config_port_valid, NULL, "SOCKS",
CONN_TYPE_AP_LISTENER, NULL, 0,
CL_PORT_TAKES_HOSTNAMES);
#ifdef _WIN32
@@ -4004,14 +4271,13 @@ test_config_parse_port_config__ports__ports_given(void *data)
tt_int_op(port_cfg->entry_cfg.ipv6_traffic, OP_EQ, 1);
#endif
- // Test success with both ipv4 and ipv6 (for unix domain sockets,
- // this makes no sense - it should be fixed)
+ // Test success with both ipv4 and ipv6
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", "unix:/tmp/foo/bar "
+ config_port_valid = mock_config_line("SOCKSPort", "unix:/tmp/foo/bar "
"IPv4Traffic IPv6Traffic");
- ret = parse_port_config(slout, config_port_valid, NULL, "DNS",
+ ret = parse_port_config(slout, config_port_valid, NULL, "SOCKS",
CONN_TYPE_AP_LISTENER, NULL, 0,
CL_PORT_TAKES_HOSTNAMES);
#ifdef _WIN32
@@ -4153,8 +4419,9 @@ test_config_parse_port_config__ports__ports_given(void *data)
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", "42 IPv6Traffic PreferIPv6");
- ret = parse_port_config(slout, config_port_valid, NULL, "DNS",
+ config_port_valid = mock_config_line("SOCKSPort",
+ "42 IPv6Traffic PreferIPv6");
+ ret = parse_port_config(slout, config_port_valid, NULL, "SOCKS",
CONN_TYPE_AP_LISTENER, "127.0.0.42", 0,
CL_PORT_TAKES_HOSTNAMES);
tt_int_op(ret, OP_EQ, 0);
@@ -4292,7 +4559,7 @@ test_config_parse_port_config__ports__ports_given(void *data)
// Test success with warn non-local control
SMARTLIST_FOREACH(slout,port_cfg_t *,pf,port_cfg_free(pf));
smartlist_clear(slout);
- ret = parse_port_config(slout, config_port_valid, NULL, "DNS",
+ ret = parse_port_config(slout, config_port_valid, NULL, "Control",
CONN_TYPE_CONTROL_LISTENER, "127.0.0.42", 0,
CL_PORT_WARN_NONLOCAL);
tt_int_op(ret, OP_EQ, 0);
@@ -4300,7 +4567,7 @@ test_config_parse_port_config__ports__ports_given(void *data)
// Test success with warn non-local listener
SMARTLIST_FOREACH(slout,port_cfg_t *,pf,port_cfg_free(pf));
smartlist_clear(slout);
- ret = parse_port_config(slout, config_port_valid, NULL, "DNS",
+ ret = parse_port_config(slout, config_port_valid, NULL, "ExtOR",
CONN_TYPE_EXT_OR_LISTENER, "127.0.0.42", 0,
CL_PORT_WARN_NONLOCAL);
tt_int_op(ret, OP_EQ, 0);
@@ -4472,8 +4739,8 @@ test_config_parse_port_config__ports__ports_given(void *data)
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", "unix:/tmp/somewhere");
- ret = parse_port_config(slout, config_port_valid, NULL, "DNS",
+ config_port_valid = mock_config_line("SOCKSPort", "unix:/tmp/somewhere");
+ ret = parse_port_config(slout, config_port_valid, NULL, "SOCKS",
CONN_TYPE_AP_LISTENER, "127.0.0.46", 0,
CL_PORT_DFLT_GROUP_WRITABLE);
#ifdef _WIN32
@@ -4604,6 +4871,15 @@ test_config_parse_port_config__ports__server_options(void *data)
0, CL_PORT_SERVER_OPTIONS);
tt_int_op(ret, OP_EQ, -1);
+ // Check for failure with empty unix: address.
+ config_free_lines(config_port_invalid); config_port_invalid = NULL;
+ SMARTLIST_FOREACH(slout,port_cfg_t *,pf,port_cfg_free(pf));
+ smartlist_clear(slout);
+ config_port_invalid = mock_config_line("ORPort", "unix:\"\"");
+ ret = parse_port_config(slout, config_port_invalid, NULL, "ORPort", 0, NULL,
+ 0, CL_PORT_SERVER_OPTIONS);
+ tt_int_op(ret, OP_EQ, -1);
+
done:
if (slout)
SMARTLIST_FOREACH(slout,port_cfg_t *,pf,port_cfg_free(pf));
@@ -4633,6 +4909,7 @@ struct testcase_t config_tests[] = {
CONFIG_TEST(write_to_data_subdir, TT_FORK),
CONFIG_TEST(fix_my_family, 0),
CONFIG_TEST(directory_fetch, 0),
+ CONFIG_TEST(port_cfg_line_extract_addrport, 0),
CONFIG_TEST(parse_port_config__listenaddress, 0),
CONFIG_TEST(parse_port_config__ports__no_ports_given, 0),
CONFIG_TEST(parse_port_config__ports__server_options, 0),
diff --git a/src/test/test_connection.c b/src/test/test_connection.c
index d7342e3948..5cda4f3175 100644
--- a/src/test/test_connection.c
+++ b/src/test/test_connection.c
@@ -96,6 +96,13 @@ mock_connection_connect_sockaddr(connection_t *conn,
return 1;
}
+static int
+fake_close_socket(evutil_socket_t sock)
+{
+ (void)sock;
+ return 0;
+}
+
static void
test_conn_lookup_addr_helper(const char *address, int family, tor_addr_t *addr)
{
@@ -125,6 +132,7 @@ test_conn_get_connection(uint8_t state, uint8_t type, uint8_t purpose)
MOCK(connection_connect_sockaddr,
mock_connection_connect_sockaddr);
+ MOCK(tor_close_socket, fake_close_socket);
init_connection_lists();
@@ -149,12 +157,13 @@ test_conn_get_connection(uint8_t state, uint8_t type, uint8_t purpose)
assert_connection_ok(conn, time(NULL));
UNMOCK(connection_connect_sockaddr);
-
+ UNMOCK(tor_close_socket);
return conn;
/* On failure */
done:
UNMOCK(connection_connect_sockaddr);
+ UNMOCK(tor_close_socket);
return NULL;
}
@@ -193,6 +202,15 @@ test_conn_get_basic_teardown(const struct testcase_t *tc, void *arg)
if (!conn->linked_conn->marked_for_close) {
connection_close_immediate(conn->linked_conn);
+ if (CONN_IS_EDGE(conn->linked_conn)) {
+ /* Suppress warnings about all the stuff we didn't do */
+ TO_EDGE_CONN(conn->linked_conn)->edge_has_sent_end = 1;
+ TO_EDGE_CONN(conn->linked_conn)->end_reason =
+ END_STREAM_REASON_INTERNAL;
+ if (conn->linked_conn->type == CONN_TYPE_AP) {
+ TO_ENTRY_CONN(conn->linked_conn)->socks_request->has_finished = 1;
+ }
+ }
connection_mark_for_close(conn->linked_conn);
}
@@ -213,6 +231,14 @@ test_conn_get_basic_teardown(const struct testcase_t *tc, void *arg)
if (!conn->marked_for_close) {
connection_close_immediate(conn);
+ if (CONN_IS_EDGE(conn)) {
+ /* Suppress warnings about all the stuff we didn't do */
+ TO_EDGE_CONN(conn)->edge_has_sent_end = 1;
+ TO_EDGE_CONN(conn)->end_reason = END_STREAM_REASON_INTERNAL;
+ if (conn->type == CONN_TYPE_AP) {
+ TO_ENTRY_CONN(conn)->socks_request->has_finished = 1;
+ }
+ }
connection_mark_for_close(conn);
}
@@ -337,10 +363,7 @@ test_conn_get_rsrc_teardown(const struct testcase_t *tc, void *arg)
static void *
test_conn_download_status_setup(const struct testcase_t *tc)
{
- (void)tc;
-
- /* Don't return NULL, that causes the test to fail */
- return (void*)"ok";
+ return (void*)tc;
}
static int
@@ -653,7 +676,8 @@ test_conn_download_status(void *arg)
dir_connection_t *conn4 = NULL;
connection_t *ap_conn = NULL;
- consensus_flavor_t usable_flavor = (consensus_flavor_t)arg;
+ const struct testcase_t *tc = arg;
+ consensus_flavor_t usable_flavor = (consensus_flavor_t)tc->setup_data;
/* The "other flavor" trick only works if there are two flavors */
tor_assert(N_CONSENSUS_FLAVORS == 2);
diff --git a/src/test/test_containers.c b/src/test/test_containers.c
index d8b82e0661..d7291a2ce2 100644
--- a/src/test/test_containers.c
+++ b/src/test/test_containers.c
@@ -501,13 +501,13 @@ test_container_smartlist_pos(void *arg)
(void) arg;
smartlist_t *sl = smartlist_new();
- smartlist_add(sl, tor_strdup("This"));
- smartlist_add(sl, tor_strdup("is"));
- smartlist_add(sl, tor_strdup("a"));
- smartlist_add(sl, tor_strdup("test"));
- smartlist_add(sl, tor_strdup("for"));
- smartlist_add(sl, tor_strdup("a"));
- smartlist_add(sl, tor_strdup("function"));
+ smartlist_add_strdup(sl, "This");
+ smartlist_add_strdup(sl, "is");
+ smartlist_add_strdup(sl, "a");
+ smartlist_add_strdup(sl, "test");
+ smartlist_add_strdup(sl, "for");
+ smartlist_add_strdup(sl, "a");
+ smartlist_add_strdup(sl, "function");
/* Test string_pos */
tt_int_op(smartlist_string_pos(NULL, "Fred"), ==, -1);
@@ -830,7 +830,7 @@ test_container_strmap(void *arg)
found_keys = smartlist_new();
while (!strmap_iter_done(iter)) {
strmap_iter_get(iter,&k,&v);
- smartlist_add(found_keys, tor_strdup(k));
+ smartlist_add_strdup(found_keys, k);
tt_ptr_op(v,OP_EQ, strmap_get(map, k));
if (!strcmp(k, "K2")) {
diff --git a/src/test/test_controller.c b/src/test/test_controller.c
index 0dea8473b9..f19c846144 100644
--- a/src/test/test_controller.c
+++ b/src/test/test_controller.c
@@ -137,6 +137,8 @@ test_rend_service_parse_port_config(void *arg)
cfg = rend_service_parse_port_config("80,[2001:db8::1]:8080", sep, &err_msg);
tt_assert(cfg);
tt_assert(!err_msg);
+ rend_service_port_config_free(cfg);
+ cfg = NULL;
/* XXX: Someone should add tests for AF_UNIX targets if supported. */
@@ -151,6 +153,52 @@ test_rend_service_parse_port_config(void *arg)
cfg = rend_service_parse_port_config("90001", sep, &err_msg);
tt_assert(!cfg);
tt_assert(err_msg);
+ tor_free(err_msg);
+
+ /* unix port */
+ cfg = NULL;
+
+ /* quoted unix port */
+ tor_free(err_msg);
+ cfg = rend_service_parse_port_config("100 unix:\"/tmp/foo bar\"",
+ " ", &err_msg);
+ tt_assert(cfg);
+ tt_assert(!err_msg);
+ rend_service_port_config_free(cfg);
+ cfg = NULL;
+
+ /* quoted unix port */
+ tor_free(err_msg);
+ cfg = rend_service_parse_port_config("100 unix:\"/tmp/foo bar\"",
+ " ", &err_msg);
+ tt_assert(cfg);
+ tt_assert(!err_msg);
+ rend_service_port_config_free(cfg);
+ cfg = NULL;
+
+ /* quoted unix port, missing end quote */
+ cfg = rend_service_parse_port_config("100 unix:\"/tmp/foo bar",
+ " ", &err_msg);
+ tt_assert(!cfg);
+ tt_str_op(err_msg, OP_EQ, "Couldn't process address <unix:\"/tmp/foo bar> "
+ "from hidden service configuration");
+ tor_free(err_msg);
+
+ /* bogus IP address */
+ cfg = rend_service_parse_port_config("100 1.2.3.4.5:9000",
+ " ", &err_msg);
+ tt_assert(!cfg);
+ tt_str_op(err_msg, OP_EQ, "Unparseable address in hidden service port "
+ "configuration.");
+ tor_free(err_msg);
+
+ /* bogus port port */
+ cfg = rend_service_parse_port_config("100 99999",
+ " ", &err_msg);
+ tt_assert(!cfg);
+ tt_str_op(err_msg, OP_EQ, "Unparseable or out-of-range port \"99999\" "
+ "in hidden service port configuration.");
+ tor_free(err_msg);
done:
rend_service_port_config_free(cfg);
diff --git a/src/test/test_crypto.c b/src/test/test_crypto.c
index 542512bd44..64a46f7914 100644
--- a/src/test/test_crypto.c
+++ b/src/test/test_crypto.c
@@ -363,15 +363,15 @@ test_crypto_rng_engine(void *arg)
;
}
-/** Run unit tests for our AES functionality */
+/** Run unit tests for our AES128 functionality */
static void
-test_crypto_aes(void *arg)
+test_crypto_aes128(void *arg)
{
char *data1 = NULL, *data2 = NULL, *data3 = NULL;
crypto_cipher_t *env1 = NULL, *env2 = NULL;
int i, j;
char *mem_op_hex_tmp=NULL;
-
+ char key[CIPHER_KEY_LEN];
int use_evp = !strcmp(arg,"evp");
evaluate_evp_for_aes(use_evp);
evaluate_ctr_for_aes();
@@ -387,9 +387,10 @@ test_crypto_aes(void *arg)
memset(data2, 0, 1024);
memset(data3, 0, 1024);
- env1 = crypto_cipher_new(NULL);
+ crypto_rand(key, sizeof(key));
+ env1 = crypto_cipher_new(key);
tt_ptr_op(env1, OP_NE, NULL);
- env2 = crypto_cipher_new(crypto_cipher_get_key(env1));
+ env2 = crypto_cipher_new(key);
tt_ptr_op(env2, OP_NE, NULL);
/* Try encrypting 512 chars. */
@@ -420,7 +421,7 @@ test_crypto_aes(void *arg)
env2 = NULL;
memset(data3, 0, 1024);
- env2 = crypto_cipher_new(crypto_cipher_get_key(env1));
+ env2 = crypto_cipher_new(key);
tt_ptr_op(env2, OP_NE, NULL);
for (j = 0; j < 1024-16; j += 17) {
crypto_cipher_encrypt(env2, data3+j, data1+j, 17);
@@ -513,32 +514,61 @@ test_crypto_aes(void *arg)
static void
test_crypto_aes_ctr_testvec(void *arg)
{
- (void)arg;
+ const char *bitstr = arg;
char *mem_op_hex_tmp=NULL;
+ crypto_cipher_t *c=NULL;
/* from NIST SP800-38a, section F.5 */
- const char key16[] = "2b7e151628aed2a6abf7158809cf4f3c";
const char ctr16[] = "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff";
const char plaintext16[] =
"6bc1bee22e409f96e93d7e117393172a"
"ae2d8a571e03ac9c9eb76fac45af8e51"
"30c81c46a35ce411e5fbc1191a0a52ef"
"f69f2445df4f9b17ad2b417be66c3710";
- const char ciphertext16[] =
- "874d6191b620e3261bef6864990db6ce"
- "9806f66b7970fdff8617187bb9fffdff"
- "5ae4df3edbd5d35e5b4f09020db03eab"
- "1e031dda2fbe03d1792170a0f3009cee";
+ const char *ciphertext16;
+ const char *key16;
+ int bits;
+
+ if (!strcmp(bitstr, "128")) {
+ ciphertext16 = /* section F.5.1 */
+ "874d6191b620e3261bef6864990db6ce"
+ "9806f66b7970fdff8617187bb9fffdff"
+ "5ae4df3edbd5d35e5b4f09020db03eab"
+ "1e031dda2fbe03d1792170a0f3009cee";
+ key16 = "2b7e151628aed2a6abf7158809cf4f3c";
+ bits = 128;
+ } else if (!strcmp(bitstr, "192")) {
+ ciphertext16 = /* section F.5.3 */
+ "1abc932417521ca24f2b0459fe7e6e0b"
+ "090339ec0aa6faefd5ccc2c6f4ce8e94"
+ "1e36b26bd1ebc670d1bd1d665620abf7"
+ "4f78a7f6d29809585a97daec58c6b050";
+ key16 = "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b";
+ bits = 192;
+ } else if (!strcmp(bitstr, "256")) {
+ ciphertext16 = /* section F.5.5 */
+ "601ec313775789a5b7a7f504bbf3d228"
+ "f443e3ca4d62b59aca84e990cacaf5c5"
+ "2b0930daa23de94ce87017ba2d84988d"
+ "dfc9c58db67aada613c2dd08457941a6";
+ key16 =
+ "603deb1015ca71be2b73aef0857d7781"
+ "1f352c073b6108d72d9810a30914dff4";
+ bits = 256;
+ } else {
+ tt_abort_msg("AES doesn't support this number of bits.");
+ }
- char key[16];
+ char key[32];
char iv[16];
char plaintext[16*4];
+ memset(key, 0xf9, sizeof(key)); /* poison extra bytes */
base16_decode(key, sizeof(key), key16, strlen(key16));
base16_decode(iv, sizeof(iv), ctr16, strlen(ctr16));
base16_decode(plaintext, sizeof(plaintext),
plaintext16, strlen(plaintext16));
- crypto_cipher_t *c = crypto_cipher_new_with_iv(key, iv);
+ c = crypto_cipher_new_with_iv_and_bits((uint8_t*)key, (uint8_t*)iv, bits);
crypto_cipher_crypt_inplace(c, plaintext, sizeof(plaintext));
test_memeq_hex(plaintext, ciphertext16);
@@ -999,11 +1029,11 @@ test_crypto_sha3(void *arg)
crypto_digest_free(d1);
/* Attempt to exercise the incremental hashing code by creating a randomized
- * 100 KiB buffer, and hashing rand[1, 5 * Rate] bytes at a time. SHA3-512
+ * 30 KiB buffer, and hashing rand[1, 5 * Rate] bytes at a time. SHA3-512
* is used because it has a lowest rate of the family (the code is common,
* but the slower rate exercises more of it).
*/
- const size_t bufsz = 100 * 1024;
+ const size_t bufsz = 30 * 1024;
size_t j = 0;
large = tor_malloc(bufsz);
crypto_rand(large, bufsz);
@@ -2139,24 +2169,6 @@ test_crypto_curve25519_persist(void *arg)
tor_free(tag);
}
-static void *
-ed25519_testcase_setup(const struct testcase_t *testcase)
-{
- crypto_ed25519_testing_force_impl(testcase->setup_data);
- return testcase->setup_data;
-}
-static int
-ed25519_testcase_cleanup(const struct testcase_t *testcase, void *ptr)
-{
- (void)testcase;
- (void)ptr;
- crypto_ed25519_testing_restore_impl();
- return 1;
-}
-static const struct testcase_setup_t ed25519_test_setup = {
- ed25519_testcase_setup, ed25519_testcase_cleanup
-};
-
static void
test_crypto_ed25519_simple(void *arg)
{
@@ -2258,7 +2270,7 @@ test_crypto_ed25519_simple(void *arg)
tt_int_op(0, OP_EQ, ed25519_sign(&manual_sig, (uint8_t *)prefixed_msg,
strlen(prefixed_msg), &kp1));
tor_free(prefixed_msg);
- tt_assert(!memcmp(sig1.sig, manual_sig.sig, sizeof(sig1.sig)));
+ tt_assert(fast_memeq(sig1.sig, manual_sig.sig, sizeof(sig1.sig)));
/* Test that prefixed checksig verifies it properly. */
tt_int_op(0, OP_EQ, ed25519_checksig_prefixed(&sig1, msg, msg_len,
@@ -2619,77 +2631,6 @@ test_crypto_ed25519_testvectors(void *arg)
}
static void
-test_crypto_ed25519_fuzz_donna(void *arg)
-{
- const unsigned iters = 1024;
- uint8_t msg[1024];
- unsigned i;
- (void)arg;
-
- tt_assert(sizeof(msg) == iters);
- crypto_rand((char*) msg, sizeof(msg));
-
- /* Fuzz Ed25519-donna vs ref10, alternating the implementation used to
- * generate keys/sign per iteration.
- */
- for (i = 0; i < iters; ++i) {
- const int use_donna = i & 1;
- uint8_t blinding[32];
- curve25519_keypair_t ckp;
- ed25519_keypair_t kp, kp_blind, kp_curve25519;
- ed25519_public_key_t pk, pk_blind, pk_curve25519;
- ed25519_signature_t sig, sig_blind;
- int bit = 0;
-
- crypto_rand((char*) blinding, sizeof(blinding));
-
- /* Impl. A:
- * 1. Generate a keypair.
- * 2. Blinded the keypair.
- * 3. Sign a message (unblinded).
- * 4. Sign a message (blinded).
- * 5. Generate a curve25519 keypair, and convert it to Ed25519.
- */
- ed25519_set_impl_params(use_donna);
- tt_int_op(0, OP_EQ, ed25519_keypair_generate(&kp, i&1));
- tt_int_op(0, OP_EQ, ed25519_keypair_blind(&kp_blind, &kp, blinding));
- tt_int_op(0, OP_EQ, ed25519_sign(&sig, msg, i, &kp));
- tt_int_op(0, OP_EQ, ed25519_sign(&sig_blind, msg, i, &kp_blind));
-
- tt_int_op(0, OP_EQ, curve25519_keypair_generate(&ckp, i&1));
- tt_int_op(0, OP_EQ, ed25519_keypair_from_curve25519_keypair(
- &kp_curve25519, &bit, &ckp));
-
- /* Impl. B:
- * 1. Validate the public key by rederiving it.
- * 2. Validate the blinded public key by rederiving it.
- * 3. Validate the unblinded signature (and test a invalid signature).
- * 4. Validate the blinded signature.
- * 5. Validate the public key (from Curve25519) by rederiving it.
- */
- ed25519_set_impl_params(!use_donna);
- tt_int_op(0, OP_EQ, ed25519_public_key_generate(&pk, &kp.seckey));
- tt_mem_op(pk.pubkey, OP_EQ, kp.pubkey.pubkey, 32);
-
- tt_int_op(0, OP_EQ, ed25519_public_blind(&pk_blind, &kp.pubkey, blinding));
- tt_mem_op(pk_blind.pubkey, OP_EQ, kp_blind.pubkey.pubkey, 32);
-
- tt_int_op(0, OP_EQ, ed25519_checksig(&sig, msg, i, &pk));
- sig.sig[0] ^= 15;
- tt_int_op(-1, OP_EQ, ed25519_checksig(&sig, msg, sizeof(msg), &pk));
-
- tt_int_op(0, OP_EQ, ed25519_checksig(&sig_blind, msg, i, &pk_blind));
-
- tt_int_op(0, OP_EQ, ed25519_public_key_from_curve25519_public_key(
- &pk_curve25519, &ckp.pubkey, bit));
- tt_mem_op(pk_curve25519.pubkey, OP_EQ, kp_curve25519.pubkey.pubkey, 32);
- }
-
- done:
- ;
-}
-
-static void
test_crypto_ed25519_storage(void *arg)
{
(void)arg;
@@ -2961,9 +2902,14 @@ struct testcase_t crypto_tests[] = {
{ "rng_strongest_broken", test_crypto_rng_strongest, TT_FORK,
&passthrough_setup, (void*)"broken" },
{ "openssl_version", test_crypto_openssl_version, TT_FORK, NULL, NULL },
- { "aes_AES", test_crypto_aes, TT_FORK, &passthrough_setup, (void*)"aes" },
- { "aes_EVP", test_crypto_aes, TT_FORK, &passthrough_setup, (void*)"evp" },
- { "aes_ctr_testvec", test_crypto_aes_ctr_testvec, 0, NULL, NULL },
+ { "aes_AES", test_crypto_aes128, TT_FORK, &passthrough_setup, (void*)"aes" },
+ { "aes_EVP", test_crypto_aes128, TT_FORK, &passthrough_setup, (void*)"evp" },
+ { "aes128_ctr_testvec", test_crypto_aes_ctr_testvec, 0,
+ &passthrough_setup, (void*)"128" },
+ { "aes192_ctr_testvec", test_crypto_aes_ctr_testvec, 0,
+ &passthrough_setup, (void*)"192" },
+ { "aes256_ctr_testvec", test_crypto_aes_ctr_testvec, 0,
+ &passthrough_setup, (void*)"256" },
CRYPTO_LEGACY(sha),
CRYPTO_LEGACY(pk),
{ "pk_fingerprints", test_crypto_pk_fingerprints, TT_FORK, NULL, NULL },
@@ -2995,7 +2941,6 @@ struct testcase_t crypto_tests[] = {
ED25519_TEST(convert, 0),
ED25519_TEST(blinding, 0),
ED25519_TEST(testvectors, 0),
- ED25519_TEST(fuzz_donna, TT_FORK),
{ "ed25519_storage", test_crypto_ed25519_storage, 0, NULL, NULL },
{ "siphash", test_crypto_siphash, 0, NULL, NULL },
{ "failure_modes", test_crypto_failure_modes, TT_FORK, NULL, NULL },
diff --git a/src/test/test_crypto_slow.c b/src/test/test_crypto_slow.c
index 6f3e40e0ab..0d7d65ac73 100644
--- a/src/test/test_crypto_slow.c
+++ b/src/test/test_crypto_slow.c
@@ -421,12 +421,16 @@ test_crypto_pbkdf2_vectors(void *arg)
secret_to_key_compute_key(out, 20, spec, 5, "password", 8, 1));
test_memeq_hex(out, "4b007901b765489abead49d926f721d065a429c1");
+ /* This is the very slow one here. When enabled, it accounts for roughly
+ * half the time spent in test-slow. */
+ /*
base16_decode((char*)spec, sizeof(spec),
"73616c74" "18" , 10);
memset(out, 0x00, sizeof(out));
tt_int_op(20, OP_EQ,
secret_to_key_compute_key(out, 20, spec, 5, "password", 8, 1));
test_memeq_hex(out, "eefe3d61cd4da4e4e9945b3d6ba2158c2634e984");
+ */
base16_decode((char*)spec, sizeof(spec),
"73616c7453414c5473616c7453414c5473616c745"
@@ -503,9 +507,88 @@ test_crypto_pwbox(void *arg)
tor_free(decoded);
}
+static void
+test_crypto_ed25519_fuzz_donna(void *arg)
+{
+ const unsigned iters = 1024;
+ uint8_t msg[1024];
+ unsigned i;
+ (void)arg;
+
+ tt_assert(sizeof(msg) == iters);
+ crypto_rand((char*) msg, sizeof(msg));
+
+ /* Fuzz Ed25519-donna vs ref10, alternating the implementation used to
+ * generate keys/sign per iteration.
+ */
+ for (i = 0; i < iters; ++i) {
+ const int use_donna = i & 1;
+ uint8_t blinding[32];
+ curve25519_keypair_t ckp;
+ ed25519_keypair_t kp, kp_blind, kp_curve25519;
+ ed25519_public_key_t pk, pk_blind, pk_curve25519;
+ ed25519_signature_t sig, sig_blind;
+ int bit = 0;
+
+ crypto_rand((char*) blinding, sizeof(blinding));
+
+ /* Impl. A:
+ * 1. Generate a keypair.
+ * 2. Blinded the keypair.
+ * 3. Sign a message (unblinded).
+ * 4. Sign a message (blinded).
+ * 5. Generate a curve25519 keypair, and convert it to Ed25519.
+ */
+ ed25519_set_impl_params(use_donna);
+ tt_int_op(0, OP_EQ, ed25519_keypair_generate(&kp, i&1));
+ tt_int_op(0, OP_EQ, ed25519_keypair_blind(&kp_blind, &kp, blinding));
+ tt_int_op(0, OP_EQ, ed25519_sign(&sig, msg, i, &kp));
+ tt_int_op(0, OP_EQ, ed25519_sign(&sig_blind, msg, i, &kp_blind));
+
+ tt_int_op(0, OP_EQ, curve25519_keypair_generate(&ckp, i&1));
+ tt_int_op(0, OP_EQ, ed25519_keypair_from_curve25519_keypair(
+ &kp_curve25519, &bit, &ckp));
+
+ /* Impl. B:
+ * 1. Validate the public key by rederiving it.
+ * 2. Validate the blinded public key by rederiving it.
+ * 3. Validate the unblinded signature (and test a invalid signature).
+ * 4. Validate the blinded signature.
+ * 5. Validate the public key (from Curve25519) by rederiving it.
+ */
+ ed25519_set_impl_params(!use_donna);
+ tt_int_op(0, OP_EQ, ed25519_public_key_generate(&pk, &kp.seckey));
+ tt_mem_op(pk.pubkey, OP_EQ, kp.pubkey.pubkey, 32);
+
+ tt_int_op(0, OP_EQ, ed25519_public_blind(&pk_blind, &kp.pubkey, blinding));
+ tt_mem_op(pk_blind.pubkey, OP_EQ, kp_blind.pubkey.pubkey, 32);
+
+ tt_int_op(0, OP_EQ, ed25519_checksig(&sig, msg, i, &pk));
+ sig.sig[0] ^= 15;
+ tt_int_op(-1, OP_EQ, ed25519_checksig(&sig, msg, sizeof(msg), &pk));
+
+ tt_int_op(0, OP_EQ, ed25519_checksig(&sig_blind, msg, i, &pk_blind));
+
+ tt_int_op(0, OP_EQ, ed25519_public_key_from_curve25519_public_key(
+ &pk_curve25519, &ckp.pubkey, bit));
+ tt_mem_op(pk_curve25519.pubkey, OP_EQ, kp_curve25519.pubkey.pubkey, 32);
+ }
+
+ done:
+ ;
+}
+
#define CRYPTO_LEGACY(name) \
{ #name, test_crypto_ ## name , 0, NULL, NULL }
+#define ED25519_TEST_ONE(name, fl, which) \
+ { #name "/ed25519_" which, test_crypto_ed25519_ ## name, (fl), \
+ &ed25519_test_setup, (void*)which }
+
+#define ED25519_TEST(name, fl) \
+ ED25519_TEST_ONE(name, (fl), "donna"), \
+ ED25519_TEST_ONE(name, (fl), "ref10")
+
struct testcase_t slow_crypto_tests[] = {
CRYPTO_LEGACY(s2k_rfc2440),
#ifdef HAVE_LIBSCRYPT
@@ -527,6 +610,7 @@ struct testcase_t slow_crypto_tests[] = {
{ "scrypt_vectors", test_crypto_scrypt_vectors, 0, NULL, NULL },
{ "pbkdf2_vectors", test_crypto_pbkdf2_vectors, 0, NULL, NULL },
{ "pwbox", test_crypto_pwbox, 0, NULL, NULL },
+ ED25519_TEST(fuzz_donna, TT_FORK),
END_OF_TESTCASES
};
diff --git a/src/test/test_dir.c b/src/test/test_dir.c
index 4a2538b5dc..c8daa18653 100644
--- a/src/test/test_dir.c
+++ b/src/test/test_dir.c
@@ -36,6 +36,7 @@
#include "test_dir_common.h"
#include "torcert.h"
#include "relay.h"
+#include "log_test_helpers.h"
#define NS_MODULE dir
@@ -116,6 +117,7 @@ test_dir_formats(void *arg)
const addr_policy_t *p;
time_t now = time(NULL);
port_cfg_t orport, dirport;
+ char cert_buf[256];
(void)arg;
pk1 = pk_generate(0);
@@ -135,6 +137,11 @@ test_dir_formats(void *arg)
tor_addr_parse(&r1->ipv6_addr, "1:2:3:4::");
r1->ipv6_orport = 9999;
r1->onion_pkey = crypto_pk_dup_key(pk1);
+ /* Fake just enough of an ntor key to get by */
+ curve25519_keypair_t r1_onion_keypair;
+ curve25519_keypair_generate(&r1_onion_keypair, 0);
+ r1->onion_curve25519_pkey = tor_memdup(&r1_onion_keypair.pubkey,
+ sizeof(curve25519_public_key_t));
r1->identity_pkey = crypto_pk_dup_key(pk2);
r1->bandwidthrate = 1000;
r1->bandwidthburst = 5000;
@@ -167,11 +174,6 @@ test_dir_formats(void *arg)
&kp2.pubkey,
now, 86400,
CERT_FLAG_INCLUDE_SIGNING_KEY);
- char cert_buf[256];
- base64_encode(cert_buf, sizeof(cert_buf),
- (const char*)r2->cache_info.signing_key_cert->encoded,
- r2->cache_info.signing_key_cert->encoded_len,
- BASE64_ENCODE_MULTILINE);
r2->platform = tor_strdup(platform);
r2->cache_info.published_on = 5;
r2->or_port = 9005;
@@ -230,7 +232,6 @@ test_dir_formats(void *arg)
"platform Tor "VERSION" on ", sizeof(buf2));
strlcat(buf2, get_uname(), sizeof(buf2));
strlcat(buf2, "\n"
- "protocols Link 1 2 Circuit 1\n"
"published 1970-01-01 00:00:00\n"
"fingerprint ", sizeof(buf2));
tt_assert(!crypto_pk_get_fingerprint(pk2, fingerprint, 1));
@@ -247,6 +248,11 @@ test_dir_formats(void *arg)
strlcat(buf2, "hidden-service-dir\n", sizeof(buf2));
strlcat(buf2, "contact Magri White <magri@elsewhere.example.com>\n",
sizeof(buf2));
+ strlcat(buf2, "ntor-onion-key ", sizeof(buf2));
+ base64_encode(cert_buf, sizeof(cert_buf),
+ (const char*)r1_onion_keypair.pubkey.public_key, 32,
+ BASE64_ENCODE_MULTILINE);
+ strlcat(buf2, cert_buf, sizeof(buf2));
strlcat(buf2, "reject *:*\n", sizeof(buf2));
strlcat(buf2, "tunnelled-dir-server\nrouter-signature\n", sizeof(buf2));
buf[strlen(buf2)] = '\0'; /* Don't compare the sig; it's never the same
@@ -276,6 +282,10 @@ test_dir_formats(void *arg)
"router Fred 10.3.2.1 9005 0 0\n"
"identity-ed25519\n"
"-----BEGIN ED25519 CERT-----\n", sizeof(buf2));
+ base64_encode(cert_buf, sizeof(cert_buf),
+ (const char*)r2->cache_info.signing_key_cert->encoded,
+ r2->cache_info.signing_key_cert->encoded_len,
+ BASE64_ENCODE_MULTILINE);
strlcat(buf2, cert_buf, sizeof(buf2));
strlcat(buf2, "-----END ED25519 CERT-----\n", sizeof(buf2));
strlcat(buf2, "master-key-ed25519 ", sizeof(buf2));
@@ -290,7 +300,6 @@ test_dir_formats(void *arg)
strlcat(buf2, "platform Tor "VERSION" on ", sizeof(buf2));
strlcat(buf2, get_uname(), sizeof(buf2));
strlcat(buf2, "\n"
- "protocols Link 1 2 Circuit 1\n"
"published 1970-01-01 00:00:05\n"
"fingerprint ", sizeof(buf2));
tt_assert(!crypto_pk_get_fingerprint(pk1, fingerprint, 1));
@@ -669,16 +678,16 @@ test_dir_parse_router_list(void *arg)
routerinfo_t *ri = NULL;
char d[DIGEST_LEN];
- smartlist_add(chunks, tor_strdup(EX_RI_MINIMAL)); // ri 0
- smartlist_add(chunks, tor_strdup(EX_RI_BAD_PORTS)); // bad ri 0
- smartlist_add(chunks, tor_strdup(EX_EI_MAXIMAL)); // ei 0
- smartlist_add(chunks, tor_strdup(EX_EI_BAD_SIG2)); // bad ei --
- smartlist_add(chunks, tor_strdup(EX_EI_BAD_NICKNAME));// bad ei 0
- smartlist_add(chunks, tor_strdup(EX_RI_BAD_SIG1)); // bad ri --
- smartlist_add(chunks, tor_strdup(EX_EI_BAD_PUBLISHED)); // bad ei 1
- smartlist_add(chunks, tor_strdup(EX_RI_MAXIMAL)); // ri 1
- smartlist_add(chunks, tor_strdup(EX_RI_BAD_FAMILY)); // bad ri 1
- smartlist_add(chunks, tor_strdup(EX_EI_MINIMAL)); // ei 1
+ smartlist_add_strdup(chunks, EX_RI_MINIMAL); // ri 0
+ smartlist_add_strdup(chunks, EX_RI_BAD_PORTS); // bad ri 0
+ smartlist_add_strdup(chunks, EX_EI_MAXIMAL); // ei 0
+ smartlist_add_strdup(chunks, EX_EI_BAD_SIG2); // bad ei --
+ smartlist_add_strdup(chunks, EX_EI_BAD_NICKNAME);// bad ei 0
+ smartlist_add_strdup(chunks, EX_RI_BAD_SIG1); // bad ri --
+ smartlist_add_strdup(chunks, EX_EI_BAD_PUBLISHED); // bad ei 1
+ smartlist_add_strdup(chunks, EX_RI_MAXIMAL); // ri 1
+ smartlist_add_strdup(chunks, EX_RI_BAD_FAMILY); // bad ri 1
+ smartlist_add_strdup(chunks, EX_EI_MINIMAL); // ei 1
list = smartlist_join_strings(chunks, "", 0, NULL);
@@ -803,19 +812,19 @@ test_dir_load_routers(void *arg)
#define ADD(str) \
do { \
tt_int_op(0,OP_EQ,router_get_router_hash(str, strlen(str), buf)); \
- smartlist_add(wanted, tor_strdup(hex_str(buf, DIGEST_LEN))); \
+ smartlist_add_strdup(wanted, hex_str(buf, DIGEST_LEN)); \
} while (0)
MOCK(router_get_dl_status_by_descriptor_digest, mock_router_get_dl_status);
update_approx_time(1412510400);
- smartlist_add(chunks, tor_strdup(EX_RI_MINIMAL));
- smartlist_add(chunks, tor_strdup(EX_RI_BAD_FINGERPRINT));
- smartlist_add(chunks, tor_strdup(EX_RI_BAD_SIG2));
- smartlist_add(chunks, tor_strdup(EX_RI_MAXIMAL));
- smartlist_add(chunks, tor_strdup(EX_RI_BAD_PORTS));
- smartlist_add(chunks, tor_strdup(EX_RI_BAD_TOKENS));
+ smartlist_add_strdup(chunks, EX_RI_MINIMAL);
+ smartlist_add_strdup(chunks, EX_RI_BAD_FINGERPRINT);
+ smartlist_add_strdup(chunks, EX_RI_BAD_SIG2);
+ smartlist_add_strdup(chunks, EX_RI_MAXIMAL);
+ smartlist_add_strdup(chunks, EX_RI_BAD_PORTS);
+ smartlist_add_strdup(chunks, EX_RI_BAD_TOKENS);
/* not ADDing MINIMIAL */
ADD(EX_RI_MAXIMAL);
@@ -923,18 +932,18 @@ test_dir_load_extrainfo(void *arg)
#define ADD(str) \
do { \
tt_int_op(0,OP_EQ,router_get_extrainfo_hash(str, strlen(str), buf)); \
- smartlist_add(wanted, tor_strdup(hex_str(buf, DIGEST_LEN))); \
+ smartlist_add_strdup(wanted, hex_str(buf, DIGEST_LEN)); \
} while (0)
mock_ei_insert_list = smartlist_new();
MOCK(router_get_by_extrainfo_digest, mock_get_by_ei_desc_digest);
MOCK(extrainfo_insert, mock_ei_insert);
- smartlist_add(chunks, tor_strdup(EX_EI_MINIMAL));
- smartlist_add(chunks, tor_strdup(EX_EI_BAD_NICKNAME));
- smartlist_add(chunks, tor_strdup(EX_EI_MAXIMAL));
- smartlist_add(chunks, tor_strdup(EX_EI_BAD_PUBLISHED));
- smartlist_add(chunks, tor_strdup(EX_EI_BAD_TOKENS));
+ smartlist_add_strdup(chunks, EX_EI_MINIMAL);
+ smartlist_add_strdup(chunks, EX_EI_BAD_NICKNAME);
+ smartlist_add_strdup(chunks, EX_EI_MAXIMAL);
+ smartlist_add_strdup(chunks, EX_EI_BAD_PUBLISHED);
+ smartlist_add_strdup(chunks, EX_EI_BAD_TOKENS);
/* not ADDing MINIMIAL */
ADD(EX_EI_MAXIMAL);
@@ -1577,23 +1586,46 @@ test_dir_param_voting_lookup(void *arg)
tt_int_op(99, OP_EQ,
dirvote_get_intermediate_param_value(lst, "abcd", 1000));
- /* moomin appears twice. */
+ /* moomin appears twice. That's a bug. */
+ tor_capture_bugs_(1);
tt_int_op(-100, OP_EQ,
dirvote_get_intermediate_param_value(lst, "moomin", -100));
- /* fred and jack are truncated */
+ tt_int_op(smartlist_len(tor_get_captured_bug_log_()), OP_EQ, 1);
+ tt_str_op(smartlist_get(tor_get_captured_bug_log_(), 0), OP_EQ,
+ "!(n_found > 1)");
+ tor_end_capture_bugs_();
+ /* There is no 'fred=', so that is treated as not existing. */
tt_int_op(-100, OP_EQ,
dirvote_get_intermediate_param_value(lst, "fred", -100));
+ /* jack is truncated */
+ tor_capture_bugs_(1);
tt_int_op(-100, OP_EQ,
dirvote_get_intermediate_param_value(lst, "jack", -100));
+ tt_int_op(smartlist_len(tor_get_captured_bug_log_()), OP_EQ, 1);
+ tt_str_op(smartlist_get(tor_get_captured_bug_log_(), 0), OP_EQ,
+ "!(! ok)");
+ tor_end_capture_bugs_();
/* electricity and opa aren't integers. */
+ tor_capture_bugs_(1);
tt_int_op(-100, OP_EQ,
dirvote_get_intermediate_param_value(lst, "electricity", -100));
+ tt_int_op(smartlist_len(tor_get_captured_bug_log_()), OP_EQ, 1);
+ tt_str_op(smartlist_get(tor_get_captured_bug_log_(), 0), OP_EQ,
+ "!(! ok)");
+ tor_end_capture_bugs_();
+
+ tor_capture_bugs_(1);
tt_int_op(-100, OP_EQ,
dirvote_get_intermediate_param_value(lst, "opa", -100));
+ tt_int_op(smartlist_len(tor_get_captured_bug_log_()), OP_EQ, 1);
+ tt_str_op(smartlist_get(tor_get_captured_bug_log_(), 0), OP_EQ,
+ "!(! ok)");
+ tor_end_capture_bugs_();
done:
SMARTLIST_FOREACH(lst, char *, cp, tor_free(cp));
smartlist_free(lst);
+ tor_end_capture_bugs_();
}
#undef dirvote_compute_params
@@ -1704,8 +1736,8 @@ test_vrs_for_v3ns(vote_routerstatus_t *vrs, int voter, time_t now)
tt_int_op(rs->addr,OP_EQ, 0x99008801);
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) */
- tt_u64_op(vrs->flags, OP_EQ, U64_LITERAL(80));
+ /* no flags except "running" (16) and "v2dir" (64) and "valid" (128) */
+ tt_u64_op(vrs->flags, OP_EQ, U64_LITERAL(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",
@@ -1802,7 +1834,7 @@ test_routerstatus_for_v3ns(routerstatus_t *rs, time_t now)
tt_assert(!rs->is_stable);
/* (If it wasn't running 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);
tt_assert(rs->is_v2_dir);
/* XXXX check version */
@@ -1842,6 +1874,249 @@ test_routerstatus_for_v3ns(routerstatus_t *rs, time_t now)
return;
}
+static void
+test_dir_networkstatus_compute_bw_weights_v10(void *arg)
+{
+ (void) arg;
+ smartlist_t *chunks = smartlist_new();
+ int64_t G, M, E, D, T, weight_scale;
+ int ret;
+ weight_scale = 10000;
+
+ /* no case. one or more of the values is 0 */
+ G = M = E = D = 0;
+ T = G + M + E + D;
+ ret = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D, T,
+ weight_scale);
+ tt_int_op(ret, OP_EQ, 0);
+ tt_int_op(smartlist_len(chunks), OP_EQ, 0);
+
+ /* case 1 */
+ /* XXX dir-spec not followed? See #20272. If it isn't closed, then this is
+ * testing current behavior, not spec. */
+ G = E = 10;
+ M = D = 1;
+ T = G + M + E + D;
+ ret = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D, T,
+ weight_scale);
+ tt_int_op(ret, OP_EQ, 1);
+ tt_int_op(smartlist_len(chunks), OP_EQ, 1);
+ tt_str_op(smartlist_get(chunks, 0), OP_EQ, "bandwidth-weights Wbd=3333 "
+ "Wbe=3000 Wbg=3000 Wbm=10000 Wdb=10000 Web=10000 Wed=3333 Wee=7000 "
+ "Weg=3333 Wem=7000 Wgb=10000 Wgd=3333 Wgg=7000 Wgm=7000 Wmb=10000 "
+ "Wmd=3333 Wme=3000 Wmg=3000 Wmm=10000\n");
+ SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
+ smartlist_clear(chunks);
+
+ /* case 2a E scarce */
+ M = 100;
+ G = 20;
+ E = D = 5;
+ T = G + M + E + D;
+ ret = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D, T,
+ weight_scale);
+ tt_int_op(ret, OP_EQ, 1);
+ tt_str_op(smartlist_get(chunks, 0), OP_EQ, "bandwidth-weights Wbd=0 Wbe=0 "
+ "Wbg=0 Wbm=10000 Wdb=10000 Web=10000 Wed=10000 Wee=10000 Weg=10000 "
+ "Wem=10000 Wgb=10000 Wgd=0 Wgg=10000 Wgm=10000 Wmb=10000 Wmd=0 Wme=0 "
+ "Wmg=0 Wmm=10000\n");
+ SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
+ smartlist_clear(chunks);
+
+ /* case 2a G scarce */
+ M = 100;
+ E = 20;
+ G = D = 5;
+ T = G + M + E + D;
+ ret = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D, T,
+ weight_scale);
+ tt_int_op(ret, OP_EQ, 1);
+ tt_str_op(smartlist_get(chunks, 0), OP_EQ, "bandwidth-weights Wbd=0 Wbe=0 "
+ "Wbg=0 Wbm=10000 Wdb=10000 Web=10000 Wed=0 Wee=10000 Weg=0 Wem=10000 "
+ "Wgb=10000 Wgd=10000 Wgg=10000 Wgm=10000 Wmb=10000 Wmd=0 Wme=0 Wmg=0 "
+ "Wmm=10000\n");
+ SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
+ smartlist_clear(chunks);
+
+ /* case 2b1 (Wgg=1, Wmd=Wgd) */
+ M = 10;
+ E = 30;
+ G = 10;
+ D = 100;
+ T = G + M + E + D;
+ ret = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D, T,
+ weight_scale);
+ tt_int_op(ret, OP_EQ, 1);
+ tt_str_op(smartlist_get(chunks, 0), OP_EQ, "bandwidth-weights Wbd=4000 "
+ "Wbe=0 Wbg=0 Wbm=10000 Wdb=10000 Web=10000 Wed=2000 Wee=10000 Weg=2000 "
+ "Wem=10000 Wgb=10000 Wgd=4000 Wgg=10000 Wgm=10000 Wmb=10000 Wmd=4000 "
+ "Wme=0 Wmg=0 Wmm=10000\n");
+ SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
+ smartlist_clear(chunks);
+
+ /* case 2b2 */
+ M = 60;
+ E = 30;
+ G = 10;
+ D = 100;
+ T = G + M + E + D;
+ ret = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D, T,
+ weight_scale);
+ tt_int_op(ret, OP_EQ, 1);
+ tt_str_op(smartlist_get(chunks, 0), OP_EQ, "bandwidth-weights Wbd=666 Wbe=0 "
+ "Wbg=0 Wbm=10000 Wdb=10000 Web=10000 Wed=3666 Wee=10000 Weg=3666 "
+ "Wem=10000 Wgb=10000 Wgd=5668 Wgg=10000 Wgm=10000 Wmb=10000 Wmd=666 "
+ "Wme=0 Wmg=0 Wmm=10000\n");
+ SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
+ smartlist_clear(chunks);
+
+ /* case 2b3 */
+ /* XXX I can't get a combination of values that hits this case without error,
+ * so this just tests that it fails. See #20285. Also see #20284 as 2b3 does
+ * not follow dir-spec. */
+ /* (E < T/3 && G < T/3) && (E+D>=G || G+D>=E) && (M > T/3) */
+ M = 80;
+ E = 30;
+ G = 30;
+ D = 30;
+ T = G + M + E + D;
+ ret = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D, T,
+ weight_scale);
+ tt_int_op(ret, OP_EQ, 0);
+ SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
+ smartlist_clear(chunks);
+
+ /* case 3a G scarce */
+ M = 10;
+ E = 30;
+ G = 10;
+ D = 5;
+ T = G + M + E + D;
+ ret = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D, T,
+ weight_scale);
+ tt_int_op(ret, OP_EQ, 1);
+ tt_str_op(smartlist_get(chunks, 0), OP_EQ, "bandwidth-weights Wbd=0 "
+ "Wbe=3333 Wbg=0 Wbm=10000 Wdb=10000 Web=10000 Wed=0 Wee=6667 Weg=0 "
+ "Wem=6667 Wgb=10000 Wgd=10000 Wgg=10000 Wgm=10000 Wmb=10000 Wmd=0 "
+ "Wme=3333 Wmg=0 Wmm=10000\n");
+ SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
+ smartlist_clear(chunks);
+
+ /* case 3a E scarce */
+ M = 10;
+ E = 10;
+ G = 30;
+ D = 5;
+ T = G + M + E + D;
+ ret = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D, T,
+ weight_scale);
+ tt_int_op(ret, OP_EQ, 1);
+ tt_str_op(smartlist_get(chunks, 0), OP_EQ, "bandwidth-weights Wbd=0 Wbe=0 "
+ "Wbg=3333 Wbm=10000 Wdb=10000 Web=10000 Wed=10000 Wee=10000 Weg=10000 "
+ "Wem=10000 Wgb=10000 Wgd=0 Wgg=6667 Wgm=6667 Wmb=10000 Wmd=0 Wme=0 "
+ "Wmg=3333 Wmm=10000\n");
+ SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
+ smartlist_clear(chunks);
+
+ /* case 3bg */
+ M = 10;
+ E = 30;
+ G = 10;
+ D = 10;
+ T = G + M + E + D;
+ ret = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D, T,
+ weight_scale);
+ tt_int_op(ret, OP_EQ, 1);
+ tt_str_op(smartlist_get(chunks, 0), OP_EQ, "bandwidth-weights Wbd=0 "
+ "Wbe=3334 Wbg=0 Wbm=10000 Wdb=10000 Web=10000 Wed=0 Wee=6666 Weg=0 "
+ "Wem=6666 Wgb=10000 Wgd=10000 Wgg=10000 Wgm=10000 Wmb=10000 Wmd=0 "
+ "Wme=3334 Wmg=0 Wmm=10000\n");
+ SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
+ smartlist_clear(chunks);
+
+ /* case 3be */
+ M = 10;
+ E = 10;
+ G = 30;
+ D = 10;
+ T = G + M + E + D;
+ ret = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D, T,
+ weight_scale);
+ tt_int_op(ret, OP_EQ, 1);
+ tt_str_op(smartlist_get(chunks, 0), OP_EQ, "bandwidth-weights Wbd=0 Wbe=0 "
+ "Wbg=3334 Wbm=10000 Wdb=10000 Web=10000 Wed=10000 Wee=10000 Weg=10000 "
+ "Wem=10000 Wgb=10000 Wgd=0 Wgg=6666 Wgm=6666 Wmb=10000 Wmd=0 Wme=0 "
+ "Wmg=3334 Wmm=10000\n");
+ SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
+ smartlist_clear(chunks);
+
+ /* case from 21 Jul 2013 (3be) */
+ G = 5483409;
+ M = 1455379;
+ E = 980834;
+ D = 3385803;
+ T = 11305425;
+ tt_i64_op(G+M+E+D, OP_EQ, T);
+ ret = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D, T,
+ weight_scale);
+ tt_str_op(smartlist_get(chunks, 0), OP_EQ, "bandwidth-weights Wbd=883 Wbe=0 "
+ "Wbg=3673 Wbm=10000 Wdb=10000 Web=10000 Wed=8233 Wee=10000 Weg=8233 "
+ "Wem=10000 Wgb=10000 Wgd=883 Wgg=6327 Wgm=6327 Wmb=10000 Wmd=883 Wme=0 "
+ "Wmg=3673 Wmm=10000\n");
+ SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
+ smartlist_clear(chunks);
+
+ /* case from 04 Oct 2016 (3a E scarce) */
+ G=29322240;
+ M=4721546;
+ E=1522058;
+ D=9273571;
+ T=44839415;
+ tt_i64_op(G+M+E+D, OP_EQ, T);
+ ret = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D, T,
+ weight_scale);
+ tt_str_op(smartlist_get(chunks, 0), OP_EQ, "bandwidth-weights Wbd=0 Wbe=0 "
+ "Wbg=4194 Wbm=10000 Wdb=10000 Web=10000 Wed=10000 Wee=10000 Weg=10000 "
+ "Wem=10000 Wgb=10000 Wgd=0 Wgg=5806 Wgm=5806 Wmb=10000 Wmd=0 Wme=0 "
+ "Wmg=4194 Wmm=10000\n");
+ SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
+ smartlist_clear(chunks);
+
+ /* case from 04 Sep 2013 (2b1) */
+ G=3091352;
+ M=1838837;
+ E=2109300;
+ D=2469369;
+ T=9508858;
+ tt_i64_op(G+M+E+D, OP_EQ, T);
+ ret = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D, T,
+ weight_scale);
+ tt_str_op(smartlist_get(chunks, 0), OP_EQ, "bandwidth-weights Wbd=317 "
+ "Wbe=5938 Wbg=0 Wbm=10000 Wdb=10000 Web=10000 Wed=9366 Wee=4061 "
+ "Weg=9366 Wem=4061 Wgb=10000 Wgd=317 Wgg=10000 Wgm=10000 Wmb=10000 "
+ "Wmd=317 Wme=5938 Wmg=0 Wmm=10000\n");
+ SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
+ smartlist_clear(chunks);
+
+ /* explicitly test initializing weights to 1*/
+ G=1;
+ M=1;
+ E=1;
+ D=1;
+ T=4;
+ tt_i64_op(G+M+E+D, OP_EQ, T);
+ ret = networkstatus_compute_bw_weights_v10(chunks, G, M, E, D, T,
+ weight_scale);
+ tt_str_op(smartlist_get(chunks, 0), OP_EQ, "bandwidth-weights Wbd=3333 "
+ "Wbe=0 Wbg=0 Wbm=10000 Wdb=10000 Web=10000 Wed=3333 Wee=10000 Weg=3333 "
+ "Wem=10000 Wgb=10000 Wgd=3333 Wgg=10000 Wgm=10000 Wmb=10000 Wmd=3333 "
+ "Wme=0 Wmg=0 Wmm=10000\n");
+
+ done:
+ SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
+ smartlist_free(chunks);
+}
+
static authority_cert_t *mock_cert;
static authority_cert_t *
@@ -2042,9 +2317,9 @@ test_a_networkstatus(
tt_int_op(4,OP_EQ, smartlist_len(con->voters)); /*3 voters, 1 legacy key.*/
/* The voter id digests should be in this order. */
- tt_assert(memcmp(cert2->cache_info.identity_digest,
+ tt_assert(fast_memcmp(cert2->cache_info.identity_digest,
cert1->cache_info.identity_digest,DIGEST_LEN)<0);
- tt_assert(memcmp(cert1->cache_info.identity_digest,
+ tt_assert(fast_memcmp(cert1->cache_info.identity_digest,
cert3->cache_info.identity_digest,DIGEST_LEN)<0);
test_same_voter(smartlist_get(con->voters, 1),
smartlist_get(v2->voters, 0));
@@ -3221,20 +3496,87 @@ test_dir_http_handling(void *args)
}
static void
-test_dir_purpose_needs_anonymity(void *arg)
+test_dir_purpose_needs_anonymity_returns_true_by_default(void *arg)
+{
+ (void)arg;
+
+ tor_capture_bugs_(1);
+ tt_int_op(1, ==, purpose_needs_anonymity(0, 0, NULL));
+ tt_int_op(1, ==, smartlist_len(tor_get_captured_bug_log_()));
+ tor_end_capture_bugs_();
+ done: ;
+}
+
+static void
+test_dir_purpose_needs_anonymity_returns_true_for_bridges(void *arg)
{
(void)arg;
- tt_int_op(1, ==, purpose_needs_anonymity(0, ROUTER_PURPOSE_BRIDGE));
- tt_int_op(1, ==, purpose_needs_anonymity(0, ROUTER_PURPOSE_GENERAL));
- tt_int_op(0, ==, purpose_needs_anonymity(DIR_PURPOSE_FETCH_MICRODESC,
- ROUTER_PURPOSE_GENERAL));
+
+ tt_int_op(1, ==, purpose_needs_anonymity(0, ROUTER_PURPOSE_BRIDGE, NULL));
+ tt_int_op(1, ==, purpose_needs_anonymity(0, ROUTER_PURPOSE_BRIDGE,
+ "foobar"));
+ tt_int_op(1, ==, purpose_needs_anonymity(DIR_PURPOSE_HAS_FETCHED_RENDDESC_V2,
+ ROUTER_PURPOSE_BRIDGE, NULL));
done: ;
}
static void
+test_dir_purpose_needs_anonymity_returns_false_for_own_bridge_desc(void *arg)
+{
+ (void)arg;
+ tt_int_op(0, ==, purpose_needs_anonymity(DIR_PURPOSE_FETCH_SERVERDESC,
+ ROUTER_PURPOSE_BRIDGE,
+ "authority.z"));
+ done: ;
+}
+
+static void
+test_dir_purpose_needs_anonymity_returns_true_for_sensitive_purpose(void *arg)
+{
+ (void)arg;
+
+ tt_int_op(1, ==, purpose_needs_anonymity(
+ DIR_PURPOSE_HAS_FETCHED_RENDDESC_V2,
+ ROUTER_PURPOSE_GENERAL, NULL));
+ tt_int_op(1, ==, purpose_needs_anonymity(
+ DIR_PURPOSE_UPLOAD_RENDDESC_V2, 0, NULL));
+ tt_int_op(1, ==, purpose_needs_anonymity(
+ DIR_PURPOSE_FETCH_RENDDESC_V2, 0, NULL));
+ done: ;
+}
+
+static void
+test_dir_purpose_needs_anonymity_ret_false_for_non_sensitive_conn(void *arg)
+{
+ (void)arg;
+
+ tt_int_op(0, ==, purpose_needs_anonymity(DIR_PURPOSE_UPLOAD_DIR,
+ ROUTER_PURPOSE_GENERAL, NULL));
+ tt_int_op(0, ==, purpose_needs_anonymity(DIR_PURPOSE_UPLOAD_VOTE, 0, NULL));
+ tt_int_op(0, ==,
+ purpose_needs_anonymity(DIR_PURPOSE_UPLOAD_SIGNATURES, 0, NULL));
+ tt_int_op(0, ==,
+ purpose_needs_anonymity(DIR_PURPOSE_FETCH_STATUS_VOTE, 0, NULL));
+ tt_int_op(0, ==, purpose_needs_anonymity(
+ DIR_PURPOSE_FETCH_DETACHED_SIGNATURES, 0, NULL));
+ tt_int_op(0, ==,
+ purpose_needs_anonymity(DIR_PURPOSE_FETCH_CONSENSUS, 0, NULL));
+ tt_int_op(0, ==,
+ purpose_needs_anonymity(DIR_PURPOSE_FETCH_CERTIFICATE, 0, NULL));
+ tt_int_op(0, ==,
+ purpose_needs_anonymity(DIR_PURPOSE_FETCH_SERVERDESC, 0, NULL));
+ tt_int_op(0, ==,
+ purpose_needs_anonymity(DIR_PURPOSE_FETCH_EXTRAINFO, 0, NULL));
+ tt_int_op(0, ==,
+ purpose_needs_anonymity(DIR_PURPOSE_FETCH_MICRODESC, 0, NULL));
+ done: ;
+}
+
+static void
test_dir_fetch_type(void *arg)
{
(void)arg;
+
tt_int_op(dir_fetch_type(DIR_PURPOSE_FETCH_EXTRAINFO, ROUTER_PURPOSE_BRIDGE,
NULL), OP_EQ, EXTRAINFO_DIRINFO | BRIDGE_DIRINFO);
tt_int_op(dir_fetch_type(DIR_PURPOSE_FETCH_EXTRAINFO, ROUTER_PURPOSE_GENERAL,
@@ -3260,9 +3602,14 @@ test_dir_fetch_type(void *arg)
tt_int_op(dir_fetch_type(DIR_PURPOSE_FETCH_MICRODESC, ROUTER_PURPOSE_GENERAL,
NULL), OP_EQ, MICRODESC_DIRINFO);
+ /* This will give a warning, because this function isn't supposed to be
+ * used for HS descriptors. */
+ setup_full_capture_of_logs(LOG_WARN);
tt_int_op(dir_fetch_type(DIR_PURPOSE_FETCH_RENDDESC_V2,
ROUTER_PURPOSE_GENERAL, NULL), OP_EQ, NO_DIRINFO);
- done: ;
+ expect_single_log_msg_containing("Unexpected purpose");
+ done:
+ teardown_capture_of_logs();
}
static void
@@ -3951,9 +4298,14 @@ test_dir_conn_purpose_to_string(void *data)
EXPECT_CONN_PURPOSE(DIR_PURPOSE_UPLOAD_RENDDESC_V2,
"hidden-service v2 descriptor upload");
EXPECT_CONN_PURPOSE(DIR_PURPOSE_FETCH_MICRODESC, "microdescriptor fetch");
+
+ /* This will give a warning, because there is no purpose 1024. */
+ setup_full_capture_of_logs(LOG_WARN);
EXPECT_CONN_PURPOSE(1024, "(unknown)");
+ expect_single_log_msg_containing("Called with unknown purpose 1024");
- done: ;
+ done:
+ teardown_capture_of_logs();
}
NS_DECL(int,
@@ -5099,9 +5451,9 @@ listdir_mock(const char *dname)
(void)dname;
l = smartlist_new();
- smartlist_add(l, tor_strdup("foo"));
- smartlist_add(l, tor_strdup("bar"));
- smartlist_add(l, tor_strdup("baz"));
+ smartlist_add_strdup(l, "foo");
+ smartlist_add_strdup(l, "bar");
+ smartlist_add_strdup(l, "baz");
return l;
}
@@ -5346,6 +5698,49 @@ test_dir_find_dl_schedule(void* data)
}
static void
+test_dir_assumed_flags(void *arg)
+{
+ (void)arg;
+ smartlist_t *tokens = smartlist_new();
+ 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. */
+ const char *str1 =
+ "r example hereiswhereyouridentitygoes 2015-08-30 12:00:00 "
+ "192.168.0.1 9001 0\n"
+ "m thisoneislongerbecauseitisa256bitmddigest33\n"
+ "s Fast Guard Stable\n";
+
+ 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);
+ tt_assert(rs->is_valid);
+ tt_assert(! rs->is_exit);
+ tt_assert(rs->is_fast);
+
+ done:
+ smartlist_free(tokens);
+ memarea_drop_all(area);
+ routerstatus_free(rs);
+}
+
+static void
test_dir_post_parsing(void *arg)
{
(void) arg;
@@ -5439,8 +5834,12 @@ struct testcase_t dir_tests[] = {
DIR(fmt_control_ns, 0),
DIR(dirserv_set_routerstatus_testing, 0),
DIR(http_handling, 0),
+ DIR(purpose_needs_anonymity_returns_true_for_bridges, 0),
+ DIR(purpose_needs_anonymity_returns_false_for_own_bridge_desc, 0),
+ DIR(purpose_needs_anonymity_returns_true_by_default, 0),
+ DIR(purpose_needs_anonymity_returns_true_for_sensitive_purpose, 0),
+ DIR(purpose_needs_anonymity_ret_false_for_non_sensitive_conn, 0),
DIR(post_parsing, 0),
- DIR(purpose_needs_anonymity, 0),
DIR(fetch_type, 0),
DIR(packages, 0),
DIR(download_status_schedule, 0),
@@ -5460,6 +5859,8 @@ struct testcase_t dir_tests[] = {
DIR_ARG(find_dl_schedule, TT_FORK, "ba"),
DIR_ARG(find_dl_schedule, TT_FORK, "cf"),
DIR_ARG(find_dl_schedule, TT_FORK, "ca"),
+ DIR(assumed_flags, 0),
+ DIR(networkstatus_compute_bw_weights_v10, 0),
END_OF_TESTCASES
};
diff --git a/src/test/test_dir_common.c b/src/test/test_dir_common.c
index 2448d307b2..ca43dd4c04 100644
--- a/src/test/test_dir_common.c
+++ b/src/test/test_dir_common.c
@@ -89,6 +89,7 @@ dir_common_gen_routerstatus_for_v3ns(int idx, time_t now)
/* all flags but running and v2dir cleared */
rs->is_flagged_running = 1;
rs->is_v2_dir = 1;
+ rs->is_valid = 1; /* xxxxx */
break;
case 1:
/* Generate the second routerstatus. */
diff --git a/src/test/test_dir_handle_get.c b/src/test/test_dir_handle_get.c
index f00570c98d..c215feee26 100644
--- a/src/test/test_dir_handle_get.c
+++ b/src/test/test_dir_handle_get.c
@@ -56,7 +56,13 @@ ENABLE_GCC_WARNING(overlength-strings)
#define NOT_ENOUGH_CONSENSUS_SIGNATURES "HTTP/1.0 404 " \
"Consensus not signed by sufficient number of requested authorities\r\n\r\n"
-static tor_addr_t MOCK_TOR_ADDR;
+static dir_connection_t *
+new_dir_conn(void)
+{
+ dir_connection_t *conn = dir_connection_new(AF_INET);
+ tor_addr_from_ipv4h(&conn->base_.addr, 0x7f000001);
+ return conn;
+}
static void
test_dir_handle_get_bad_request(void *data)
@@ -67,7 +73,7 @@ test_dir_handle_get_bad_request(void *data)
MOCK(connection_write_to_buf_impl_, connection_write_to_buf_mock);
- conn = dir_connection_new(tor_addr_family(&MOCK_TOR_ADDR));
+ conn = new_dir_conn();
tt_int_op(directory_handle_command_get(conn, "", NULL, 0), OP_EQ, 0);
fetch_from_buf_http(TO_CONN(conn)->outbuf, &header, MAX_HEADERS_SIZE,
@@ -90,7 +96,7 @@ test_dir_handle_get_v1_command_not_found(void *data)
MOCK(connection_write_to_buf_impl_, connection_write_to_buf_mock);
- conn = dir_connection_new(tor_addr_family(&MOCK_TOR_ADDR));
+ conn = new_dir_conn();
// no frontpage configured
tt_ptr_op(get_dirportfrontpage(), OP_EQ, NULL);
@@ -132,7 +138,7 @@ test_dir_handle_get_v1_command(void *data)
exp_body = get_dirportfrontpage();
body_len = strlen(exp_body);
- conn = dir_connection_new(tor_addr_family(&MOCK_TOR_ADDR));
+ conn = new_dir_conn();
tt_int_op(directory_handle_command_get(conn, GET("/tor/"), NULL, 0),
OP_EQ, 0);
@@ -167,7 +173,7 @@ test_dir_handle_get_not_found(void *data)
MOCK(connection_write_to_buf_impl_, connection_write_to_buf_mock);
- conn = dir_connection_new(tor_addr_family(&MOCK_TOR_ADDR));
+ conn = new_dir_conn();
/* Unrecognized path */
tt_int_op(directory_handle_command_get(conn, GET("/anything"), NULL, 0),
@@ -194,7 +200,7 @@ test_dir_handle_get_robots_txt(void *data)
MOCK(connection_write_to_buf_impl_, connection_write_to_buf_mock);
- conn = dir_connection_new(tor_addr_family(&MOCK_TOR_ADDR));
+ conn = new_dir_conn();
tt_int_op(directory_handle_command_get(conn, GET("/tor/robots.txt"),
NULL, 0), OP_EQ, 0);
@@ -229,7 +235,7 @@ test_dir_handle_get_rendezvous2_not_found_if_not_encrypted(void *data)
MOCK(connection_write_to_buf_impl_, connection_write_to_buf_mock);
- conn = dir_connection_new(tor_addr_family(&MOCK_TOR_ADDR));
+ conn = new_dir_conn();
// connection is not encrypted
tt_assert(!connection_dir_is_encrypted(conn))
@@ -256,7 +262,7 @@ test_dir_handle_get_rendezvous2_on_encrypted_conn_with_invalid_desc_id(
(void) data;
MOCK(connection_write_to_buf_impl_, connection_write_to_buf_mock);
- conn = dir_connection_new(tor_addr_family(&MOCK_TOR_ADDR));
+ conn = new_dir_conn();
// connection is encrypted
TO_CONN(conn)->linked = 1;
@@ -283,7 +289,7 @@ test_dir_handle_get_rendezvous2_on_encrypted_conn_not_well_formed(void *data)
(void) data;
MOCK(connection_write_to_buf_impl_, connection_write_to_buf_mock);
- conn = dir_connection_new(tor_addr_family(&MOCK_TOR_ADDR));
+ conn = new_dir_conn();
// connection is encrypted
TO_CONN(conn)->linked = 1;
@@ -316,7 +322,7 @@ test_dir_handle_get_rendezvous2_not_found(void *data)
(void) data;
MOCK(connection_write_to_buf_impl_, connection_write_to_buf_mock);
- conn = dir_connection_new(tor_addr_family(&MOCK_TOR_ADDR));
+ conn = new_dir_conn();
rend_cache_init();
@@ -382,7 +388,7 @@ test_dir_handle_get_rendezvous2_on_encrypted_conn_success(void *data)
base32_encode(desc_id_base32, sizeof(desc_id_base32), desc_holder->desc_id,
DIGEST_LEN);
- conn = dir_connection_new(tor_addr_family(&MOCK_TOR_ADDR));
+ conn = new_dir_conn();
// connection is encrypted
TO_CONN(conn)->linked = 1;
@@ -433,7 +439,7 @@ test_dir_handle_get_micro_d_not_found(void *data)
#define B64_256_1 "8/Pz8/u7vz8/Pz+7vz8/Pz+7u/Pz8/P7u/Pz8/P7u78"
#define B64_256_2 "zMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMw"
- conn = dir_connection_new(tor_addr_family(&MOCK_TOR_ADDR));
+ conn = new_dir_conn();
const char *req = MICRODESC_GET(B64_256_1 "-" B64_256_2);
tt_int_op(directory_handle_command_get(conn, req, NULL, 0), OP_EQ, 0);
@@ -513,7 +519,7 @@ test_dir_handle_get_micro_d(void *data)
tt_int_op(1, OP_EQ, smartlist_len(list));
/* Make the request */
- conn = dir_connection_new(tor_addr_family(&MOCK_TOR_ADDR));
+ conn = new_dir_conn();
tor_snprintf(path, sizeof(path), MICRODESC_GET("%s"), digest_base64);
tt_int_op(directory_handle_command_get(conn, path, NULL, 0), OP_EQ, 0);
@@ -583,7 +589,7 @@ test_dir_handle_get_micro_d_server_busy(void *data)
mock_options->CountPrivateBandwidth = 1;
/* Make the request */
- conn = dir_connection_new(tor_addr_family(&MOCK_TOR_ADDR));
+ conn = new_dir_conn();
tor_snprintf(path, sizeof(path), MICRODESC_GET("%s"), digest_base64);
tt_int_op(directory_handle_command_get(conn, path, NULL, 0), OP_EQ, 0);
@@ -620,7 +626,7 @@ test_dir_handle_get_networkstatus_bridges_not_found_without_auth(void *data)
mock_options->BridgeAuthoritativeDir = 1;
mock_options->BridgePassword_AuthDigest_ = tor_strdup("digest");
- conn = dir_connection_new(tor_addr_family(&MOCK_TOR_ADDR));
+ conn = new_dir_conn();
TO_CONN(conn)->linked = 1;
const char *req = GET(BRIDGES_PATH);
@@ -656,7 +662,7 @@ test_dir_handle_get_networkstatus_bridges(void *data)
crypto_digest256(mock_options->BridgePassword_AuthDigest_,
"abcdefghijklm12345", 18, DIGEST_SHA256);
- conn = dir_connection_new(tor_addr_family(&MOCK_TOR_ADDR));
+ conn = new_dir_conn();
TO_CONN(conn)->linked = 1;
const char *req = "GET " BRIDGES_PATH " HTTP/1.0\r\n"
@@ -696,7 +702,7 @@ test_dir_handle_get_networkstatus_bridges_not_found_wrong_auth(void *data)
crypto_digest256(mock_options->BridgePassword_AuthDigest_,
"abcdefghijklm12345", 18, DIGEST_SHA256);
- conn = dir_connection_new(tor_addr_family(&MOCK_TOR_ADDR));
+ conn = new_dir_conn();
TO_CONN(conn)->linked = 1;
const char *req = "GET " BRIDGES_PATH " HTTP/1.0\r\n"
@@ -726,7 +732,7 @@ test_dir_handle_get_server_descriptors_not_found(void* data)
MOCK(connection_write_to_buf_impl_, connection_write_to_buf_mock);
- conn = dir_connection_new(tor_addr_family(&MOCK_TOR_ADDR));
+ conn = new_dir_conn();
const char *req = SERVER_DESC_GET("invalid");
tt_int_op(directory_handle_command_get(conn, req, NULL, 0), OP_EQ, 0);
@@ -769,7 +775,7 @@ test_dir_handle_get_server_descriptors_all(void* data)
/* Treat "all" requests as if they were unencrypted */
mock_routerinfo->cache_info.send_unencrypted = 1;
- conn = dir_connection_new(tor_addr_family(&MOCK_TOR_ADDR));
+ conn = new_dir_conn();
const char *req = SERVER_DESC_GET("all");
tt_int_op(directory_handle_command_get(conn, req, NULL, 0), OP_EQ, 0);
@@ -875,7 +881,7 @@ test_dir_handle_get_server_descriptors_authority(void* data)
strlen(TEST_DESCRIPTOR) - annotation_len;;
mock_routerinfo->cache_info.annotations_len = annotation_len;
- conn = dir_connection_new(tor_addr_family(&MOCK_TOR_ADDR));
+ conn = new_dir_conn();
const char *req = SERVER_DESC_GET("authority");
tt_int_op(directory_handle_command_get(conn, req, NULL, 0), OP_EQ, 0);
@@ -939,7 +945,7 @@ test_dir_handle_get_server_descriptors_fp(void* data)
strlen(TEST_DESCRIPTOR) - annotation_len;
mock_routerinfo->cache_info.annotations_len = annotation_len;
- conn = dir_connection_new(tor_addr_family(&MOCK_TOR_ADDR));
+ conn = new_dir_conn();
#define HEX1 "Fe0daff89127389bc67558691231234551193EEE"
#define HEX2 "Deadbeef99999991111119999911111111f00ba4"
@@ -1005,7 +1011,7 @@ test_dir_handle_get_server_descriptors_d(void* data)
const char *hex_digest = hex_str(router->cache_info.signed_descriptor_digest,
DIGEST_LEN);
- conn = dir_connection_new(tor_addr_family(&MOCK_TOR_ADDR));
+ conn = new_dir_conn();
char req_header[155]; /* XXX Why 155? What kind of number is that?? */
tor_snprintf(req_header, sizeof(req_header),
@@ -1073,7 +1079,7 @@ test_dir_handle_get_server_descriptors_busy(void* data)
const char *hex_digest = hex_str(router->cache_info.signed_descriptor_digest,
DIGEST_LEN);
- conn = dir_connection_new(tor_addr_family(&MOCK_TOR_ADDR));
+ conn = new_dir_conn();
#define HEX1 "Fe0daff89127389bc67558691231234551193EEE"
#define HEX2 "Deadbeef99999991111119999911111111f00ba4"
@@ -1112,7 +1118,7 @@ test_dir_handle_get_server_keys_bad_req(void* data)
MOCK(connection_write_to_buf_impl_, connection_write_to_buf_mock);
- conn = dir_connection_new(tor_addr_family(&MOCK_TOR_ADDR));
+ conn = new_dir_conn();
const char *req = GET("/tor/keys/");
tt_int_op(directory_handle_command_get(conn, req, NULL, 0), OP_EQ, 0);
@@ -1138,7 +1144,7 @@ test_dir_handle_get_server_keys_all_not_found(void* data)
MOCK(connection_write_to_buf_impl_, connection_write_to_buf_mock);
- conn = dir_connection_new(tor_addr_family(&MOCK_TOR_ADDR));
+ conn = new_dir_conn();
const char *req = GET("/tor/keys/all");
tt_int_op(directory_handle_command_get(conn, req, NULL, 0), OP_EQ, 0);
@@ -1190,7 +1196,7 @@ test_dir_handle_get_server_keys_all(void* data)
tt_int_op(0, OP_EQ, trusted_dirs_load_certs_from_string(TEST_CERTIFICATE,
TRUSTED_DIRS_CERTS_SRC_DL_BY_ID_DIGEST, 1, NULL));
- conn = dir_connection_new(tor_addr_family(&MOCK_TOR_ADDR));
+ conn = new_dir_conn();
const char *req = GET("/tor/keys/all");
tt_int_op(directory_handle_command_get(conn, req, NULL, 0), OP_EQ, 0);
@@ -1227,7 +1233,7 @@ test_dir_handle_get_server_keys_authority_not_found(void* data)
MOCK(connection_write_to_buf_impl_, connection_write_to_buf_mock);
- conn = dir_connection_new(tor_addr_family(&MOCK_TOR_ADDR));
+ conn = new_dir_conn();
const char *req = GET("/tor/keys/authority");
tt_int_op(directory_handle_command_get(conn, req, NULL, 0), OP_EQ, 0);
@@ -1267,7 +1273,7 @@ test_dir_handle_get_server_keys_authority(void* data)
MOCK(get_my_v3_authority_cert, get_my_v3_authority_cert_m);
MOCK(connection_write_to_buf_impl_, connection_write_to_buf_mock);
- conn = dir_connection_new(tor_addr_family(&MOCK_TOR_ADDR));
+ conn = new_dir_conn();
const char *req = GET("/tor/keys/authority");
tt_int_op(directory_handle_command_get(conn, req, NULL, 0), OP_EQ, 0);
@@ -1303,7 +1309,7 @@ test_dir_handle_get_server_keys_fp_not_found(void* data)
MOCK(connection_write_to_buf_impl_, connection_write_to_buf_mock);
- conn = dir_connection_new(tor_addr_family(&MOCK_TOR_ADDR));
+ conn = new_dir_conn();
const char *req = GET("/tor/keys/fp/somehex");
tt_int_op(directory_handle_command_get(conn, req, NULL, 0), OP_EQ, 0);
@@ -1349,7 +1355,7 @@ test_dir_handle_get_server_keys_fp(void* data)
tt_int_op(0, OP_EQ, trusted_dirs_load_certs_from_string(TEST_CERTIFICATE,
TRUSTED_DIRS_CERTS_SRC_DL_BY_ID_DIGEST, 1, NULL));
- conn = dir_connection_new(tor_addr_family(&MOCK_TOR_ADDR));
+ conn = new_dir_conn();
char req[71];
tor_snprintf(req, sizeof(req),
GET("/tor/keys/fp/%s"), TEST_CERT_IDENT_KEY);
@@ -1386,7 +1392,7 @@ test_dir_handle_get_server_keys_sk_not_found(void* data)
MOCK(connection_write_to_buf_impl_, connection_write_to_buf_mock);
- conn = dir_connection_new(tor_addr_family(&MOCK_TOR_ADDR));
+ conn = new_dir_conn();
const char *req = GET("/tor/keys/sk/somehex");
tt_int_op(directory_handle_command_get(conn, req, NULL, 0), OP_EQ, 0);
@@ -1422,7 +1428,7 @@ test_dir_handle_get_server_keys_sk(void* data)
tt_int_op(0, OP_EQ, trusted_dirs_load_certs_from_string(TEST_CERTIFICATE,
TRUSTED_DIRS_CERTS_SRC_DL_BY_ID_DIGEST, 1, NULL));
- conn = dir_connection_new(tor_addr_family(&MOCK_TOR_ADDR));
+ conn = new_dir_conn();
char req[71];
tor_snprintf(req, sizeof(req),
GET("/tor/keys/sk/%s"), TEST_SIGNING_KEY);
@@ -1459,7 +1465,7 @@ test_dir_handle_get_server_keys_fpsk_not_found(void* data)
MOCK(connection_write_to_buf_impl_, connection_write_to_buf_mock);
- conn = dir_connection_new(tor_addr_family(&MOCK_TOR_ADDR));
+ conn = new_dir_conn();
const char *req = GET("/tor/keys/fp-sk/somehex");
tt_int_op(directory_handle_command_get(conn, req, NULL, 0), OP_EQ, 0);
@@ -1505,7 +1511,7 @@ test_dir_handle_get_server_keys_fpsk(void* data)
tt_int_op(0, OP_EQ, trusted_dirs_load_certs_from_string(TEST_CERTIFICATE,
TRUSTED_DIRS_CERTS_SRC_DL_BY_ID_DIGEST, 1, NULL));
- conn = dir_connection_new(tor_addr_family(&MOCK_TOR_ADDR));
+ conn = new_dir_conn();
char req[115];
tor_snprintf(req, sizeof(req),
@@ -1569,7 +1575,7 @@ test_dir_handle_get_server_keys_busy(void* data)
init_mock_options();
mock_options->CountPrivateBandwidth = 1;
- conn = dir_connection_new(tor_addr_family(&MOCK_TOR_ADDR));
+ conn = new_dir_conn();
char req[71];
tor_snprintf(req, sizeof(req), GET("/tor/keys/fp/%s"), TEST_CERT_IDENT_KEY);
tt_int_op(directory_handle_command_get(conn, req, NULL, 0), OP_EQ, 0);
@@ -1623,7 +1629,7 @@ test_dir_handle_get_status_vote_current_consensus_ns_not_enough_sigs(void* d)
mock_options->DirReqStatistics = 1;
geoip_dirreq_stats_init(time(NULL));
- conn = dir_connection_new(tor_addr_family(&MOCK_TOR_ADDR));
+ conn = new_dir_conn();
tt_int_op(0, OP_EQ, directory_handle_command_get(conn,
GET("/tor/status-vote/current/consensus-ns/" HEX1 "+" HEX2), NULL, 0));
@@ -1668,7 +1674,7 @@ test_dir_handle_get_status_vote_current_consensus_ns_not_found(void* data)
mock_options->DirReqStatistics = 1;
geoip_dirreq_stats_init(time(NULL));
- conn = dir_connection_new(tor_addr_family(&MOCK_TOR_ADDR));
+ conn = new_dir_conn();
tt_int_op(0, OP_EQ, directory_handle_command_get(conn,
GET("/tor/status-vote/current/consensus-ns"), NULL, 0));
@@ -1721,7 +1727,7 @@ status_vote_current_consensus_ns_test(char **header, char **body,
geoip_parse_entry("10,50,AB", AF_INET);
tt_str_op("ab", OP_EQ, geoip_get_country_name(1));
- conn = dir_connection_new(tor_addr_family(&MOCK_TOR_ADDR));
+ conn = new_dir_conn();
TO_CONN(conn)->address = tor_strdup("127.0.0.1");
tt_int_op(0, OP_EQ, directory_handle_command_get(conn,
@@ -1844,7 +1850,7 @@ test_dir_handle_get_status_vote_current_not_found(void* data)
MOCK(connection_write_to_buf_impl_, connection_write_to_buf_mock);
- conn = dir_connection_new(tor_addr_family(&MOCK_TOR_ADDR));
+ conn = new_dir_conn();
tt_int_op(0, OP_EQ, directory_handle_command_get(conn,
GET("/tor/status-vote/current/" HEX1), NULL, 0));
@@ -1868,7 +1874,7 @@ status_vote_current_d_test(char **header, char **body, size_t *body_l)
MOCK(connection_write_to_buf_impl_, connection_write_to_buf_mock);
- conn = dir_connection_new(tor_addr_family(&MOCK_TOR_ADDR));
+ conn = new_dir_conn();
tt_int_op(0, OP_EQ, directory_handle_command_get(conn,
GET("/tor/status-vote/current/d/" VOTE_DIGEST), NULL, 0));
@@ -1888,7 +1894,7 @@ status_vote_next_d_test(char **header, char **body, size_t *body_l)
MOCK(connection_write_to_buf_impl_, connection_write_to_buf_mock);
- conn = dir_connection_new(tor_addr_family(&MOCK_TOR_ADDR));
+ conn = new_dir_conn();
tt_int_op(0, OP_EQ, directory_handle_command_get(conn,
GET("/tor/status-vote/next/d/" VOTE_DIGEST), NULL, 0));
@@ -2012,7 +2018,7 @@ test_dir_handle_get_status_vote_next_not_found(void* data)
MOCK(connection_write_to_buf_impl_, connection_write_to_buf_mock);
- conn = dir_connection_new(tor_addr_family(&MOCK_TOR_ADDR));
+ conn = new_dir_conn();
tt_int_op(0, OP_EQ, directory_handle_command_get(conn,
GET("/tor/status-vote/next/" HEX1), NULL, 0));
@@ -2034,7 +2040,7 @@ status_vote_next_consensus_test(char **header, char **body, size_t *body_used)
MOCK(connection_write_to_buf_impl_, connection_write_to_buf_mock);
- conn = dir_connection_new(tor_addr_family(&MOCK_TOR_ADDR));
+ conn = new_dir_conn();
tt_int_op(0, OP_EQ, directory_handle_command_get(conn,
GET("/tor/status-vote/next/consensus"), NULL, 0));
@@ -2071,7 +2077,7 @@ test_dir_handle_get_status_vote_current_authority_not_found(void* data)
MOCK(connection_write_to_buf_impl_, connection_write_to_buf_mock);
- conn = dir_connection_new(tor_addr_family(&MOCK_TOR_ADDR));
+ conn = new_dir_conn();
tt_int_op(0, OP_EQ, directory_handle_command_get(conn,
GET("/tor/status-vote/current/authority"), NULL, 0));
@@ -2095,7 +2101,7 @@ test_dir_handle_get_status_vote_next_authority_not_found(void* data)
MOCK(connection_write_to_buf_impl_, connection_write_to_buf_mock);
- conn = dir_connection_new(tor_addr_family(&MOCK_TOR_ADDR));
+ conn = new_dir_conn();
tt_int_op(0, OP_EQ, directory_handle_command_get(conn,
GET("/tor/status-vote/next/authority"), NULL, 0));
@@ -2180,7 +2186,7 @@ status_vote_next_consensus_signatures_test(char **header, char **body,
MOCK(connection_write_to_buf_impl_, connection_write_to_buf_mock);
- conn = dir_connection_new(tor_addr_family(&MOCK_TOR_ADDR));
+ conn = new_dir_conn();
tt_int_op(0, OP_EQ, directory_handle_command_get(conn,
GET("/tor/status-vote/next/consensus-signatures"), NULL, 0));
@@ -2318,7 +2324,7 @@ test_dir_handle_get_status_vote_next_authority(void* data)
MOCK(get_my_v3_authority_cert, get_my_v3_authority_cert_m);
MOCK(connection_write_to_buf_impl_, connection_write_to_buf_mock);
- conn = dir_connection_new(tor_addr_family(&MOCK_TOR_ADDR));
+ conn = new_dir_conn();
tt_int_op(0, OP_EQ, directory_handle_command_get(conn,
GET("/tor/status-vote/next/authority"), NULL, 0));
@@ -2400,7 +2406,7 @@ test_dir_handle_get_status_vote_current_authority(void* data)
MOCK(get_my_v3_authority_cert, get_my_v3_authority_cert_m);
MOCK(connection_write_to_buf_impl_, connection_write_to_buf_mock);
- conn = dir_connection_new(tor_addr_family(&MOCK_TOR_ADDR));
+ conn = new_dir_conn();
tt_int_op(0, OP_EQ, directory_handle_command_get(conn,
GET("/tor/status-vote/current/authority"), NULL, 0));
diff --git a/src/test/test_entryconn.c b/src/test/test_entryconn.c
index 9580a1fd3f..50848cfec2 100644
--- a/src/test/test_entryconn.c
+++ b/src/test/test_entryconn.c
@@ -100,7 +100,7 @@ test_entryconn_rewrite_automap_ipv4(void *arg)
ec3 = entry_connection_new(CONN_TYPE_AP, AF_INET);
get_options_mutable()->AutomapHostsOnResolve = 1;
- smartlist_add(get_options_mutable()->AutomapHostsSuffixes, tor_strdup("."));
+ smartlist_add_strdup(get_options_mutable()->AutomapHostsSuffixes, ".");
parse_virtual_addr_network("127.202.0.0/16", AF_INET, 0, &msg);
/* Automap this on resolve. */
@@ -173,7 +173,7 @@ test_entryconn_rewrite_automap_ipv6(void *arg)
ec3 = entry_connection_new(CONN_TYPE_AP, AF_INET6);
get_options_mutable()->AutomapHostsOnResolve = 1;
- smartlist_add(get_options_mutable()->AutomapHostsSuffixes, tor_strdup("."));
+ smartlist_add_strdup(get_options_mutable()->AutomapHostsSuffixes, ".");
parse_virtual_addr_network("FE80::/32", AF_INET6, 0, &msg);
/* Automap this on resolve. */
@@ -489,8 +489,8 @@ test_entryconn_rewrite_automap_exit(void *arg)
get_options_mutable()->AutomapHostsOnResolve = 1;
get_options_mutable()->AllowDotExit = 1;
- smartlist_add(get_options_mutable()->AutomapHostsSuffixes,
- tor_strdup(".EXIT"));
+ smartlist_add_strdup(get_options_mutable()->AutomapHostsSuffixes,
+ ".EXIT");
parse_virtual_addr_network("127.1.0.0/16", AF_INET, 0, &msg);
/* Automap this on resolve. */
@@ -574,8 +574,8 @@ test_entryconn_rewrite_mapaddress_automap_onion(void *arg)
get_options_mutable()->AutomapHostsOnResolve = 1;
get_options_mutable()->AllowDotExit = 1;
- smartlist_add(get_options_mutable()->AutomapHostsSuffixes,
- tor_strdup(".onion"));
+ smartlist_add_strdup(get_options_mutable()->AutomapHostsSuffixes,
+ ".onion");
parse_virtual_addr_network("192.168.0.0/16", AF_INET, 0, &msg);
config_line_append(&get_options_mutable()->AddressMap,
"MapAddress", "foo.onion abcdefghijklmnop.onion");
@@ -709,8 +709,8 @@ test_entryconn_rewrite_mapaddress_automap_onion2(void *arg)
{
char *msg = NULL;
get_options_mutable()->AutomapHostsOnResolve = 1;
- smartlist_add(get_options_mutable()->AutomapHostsSuffixes,
- tor_strdup(".onion"));
+ smartlist_add_strdup(get_options_mutable()->AutomapHostsSuffixes,
+ ".onion");
parse_virtual_addr_network("192.168.0.0/16", AF_INET, 0, &msg);
config_line_append(&get_options_mutable()->AddressMap,
"MapAddress", "irc.example.com abcdefghijklmnop.onion");
@@ -736,8 +736,8 @@ test_entryconn_rewrite_mapaddress_automap_onion4(void *arg)
{
char *msg = NULL;
get_options_mutable()->AutomapHostsOnResolve = 1;
- smartlist_add(get_options_mutable()->AutomapHostsSuffixes,
- tor_strdup(".onion"));
+ smartlist_add_strdup(get_options_mutable()->AutomapHostsSuffixes,
+ ".onion");
parse_virtual_addr_network("192.168.0.0/16", AF_INET, 0, &msg);
test_entryconn_rewrite_mapaddress_automap_onion_common(arg, 0, 1);
diff --git a/src/test/test_entrynodes.c b/src/test/test_entrynodes.c
index b1c3accfab..8e4f4061c6 100644
--- a/src/test/test_entrynodes.c
+++ b/src/test/test_entrynodes.c
@@ -254,7 +254,9 @@ populate_live_entry_guards_test_helper(int num_needed)
{
smartlist_t *our_nodelist = NULL;
smartlist_t *live_entry_guards = smartlist_new();
- const smartlist_t *all_entry_guards = get_entry_guards();
+ guard_selection_t *gs = get_guard_selection_info();
+ const smartlist_t *all_entry_guards =
+ get_entry_guards_for_guard_selection(gs);
or_options_t *options = get_options_mutable();
int retval;
@@ -271,7 +273,7 @@ populate_live_entry_guards_test_helper(int num_needed)
SMARTLIST_FOREACH_BEGIN(our_nodelist, const node_t *, node) {
const node_t *node_tmp;
- node_tmp = add_an_entry_guard(node, 0, 1, 0, 0);
+ node_tmp = add_an_entry_guard(gs, node, 0, 1, 0, 0);
tt_assert(node_tmp);
} SMARTLIST_FOREACH_END(node);
@@ -582,7 +584,9 @@ static void
test_entry_guards_set_from_config(void *arg)
{
or_options_t *options = get_options_mutable();
- const smartlist_t *all_entry_guards = get_entry_guards();
+ guard_selection_t *gs = get_guard_selection_info();
+ const smartlist_t *all_entry_guards =
+ get_entry_guards_for_guard_selection(gs);
const char *entrynodes_str = "test003r";
const node_t *chosen_entry = NULL;
int retval;
@@ -597,7 +601,7 @@ test_entry_guards_set_from_config(void *arg)
tt_int_op(retval, OP_GE, 0);
/* Read nodes from EntryNodes */
- entry_guards_set_from_config(options);
+ entry_guards_set_from_config(gs, options);
/* Test that only one guard was added. */
tt_int_op(smartlist_len(all_entry_guards), OP_EQ, 1);
@@ -689,7 +693,9 @@ static void
test_entry_is_live(void *arg)
{
smartlist_t *our_nodelist = NULL;
- const smartlist_t *all_entry_guards = get_entry_guards();
+ guard_selection_t *gs = get_guard_selection_info();
+ const smartlist_t *all_entry_guards =
+ get_entry_guards_for_guard_selection(gs);
const node_t *test_node = NULL;
const entry_guard_t *test_entry = NULL;
const char *msg;
@@ -706,7 +712,7 @@ test_entry_is_live(void *arg)
SMARTLIST_FOREACH_BEGIN(our_nodelist, const node_t *, node) {
const node_t *node_tmp;
- node_tmp = add_an_entry_guard(node, 0, 1, 0, 0);
+ node_tmp = add_an_entry_guard(gs, node, 0, 1, 0, 0);
tt_assert(node_tmp);
tt_int_op(node->is_stable, OP_EQ, 0);
diff --git a/src/test/test_guardfraction.c b/src/test/test_guardfraction.c
index 130aff11aa..8173e44d47 100644
--- a/src/test/test_guardfraction.c
+++ b/src/test/test_guardfraction.c
@@ -17,6 +17,7 @@
#include "test.h"
#include "test_helpers.h"
+#include "log_test_helpers.h"
/** Generate a vote_routerstatus_t for a router with identity digest
* <b>digest_in_hex</b>. */
@@ -304,11 +305,15 @@ test_parse_guardfraction_consensus(void *arg)
memset(&rs_no_guard, 0, sizeof(routerstatus_t));
tt_assert(!rs_no_guard.is_possible_guard);
+ setup_full_capture_of_logs(LOG_WARN);
retval = routerstatus_parse_guardfraction(guardfraction_str_good,
NULL, NULL,
&rs_no_guard);
tt_int_op(retval, ==, 0);
tt_assert(!rs_no_guard.has_guardfraction);
+ expect_single_log_msg_containing("Got GuardFraction for non-guard . "
+ "This is not supposed to happen.");
+ teardown_capture_of_logs();
}
{ /* Bad GuardFraction. Function should fail and not apply. */
@@ -334,7 +339,7 @@ test_parse_guardfraction_consensus(void *arg)
}
done:
- ;
+ teardown_capture_of_logs();
}
/** Make sure that we use GuardFraction information when we should,
diff --git a/src/test/test_hs.c b/src/test/test_hs.c
index 3bf4e6db98..67ce1cfaed 100644
--- a/src/test/test_hs.c
+++ b/src/test/test_hs.c
@@ -8,6 +8,7 @@
#define CONTROL_PRIVATE
#define CIRCUITBUILD_PRIVATE
+#define RENDSERVICE_PRIVATE
#include "or.h"
#include "test.h"
@@ -15,6 +16,7 @@
#include "config.h"
#include "hs_common.h"
#include "rendcommon.h"
+#include "rendservice.h"
#include "routerset.h"
#include "circuitbuild.h"
#include "test_helpers.h"
@@ -505,6 +507,212 @@ test_hs_auth_cookies(void *arg)
return;
}
+static int mock_get_options_calls = 0;
+static or_options_t *mock_options = NULL;
+
+static void
+reset_options(or_options_t *options, int *get_options_calls)
+{
+ memset(options, 0, sizeof(or_options_t));
+ options->TestingTorNetwork = 1;
+
+ *get_options_calls = 0;
+}
+
+static const or_options_t *
+mock_get_options(void)
+{
+ ++mock_get_options_calls;
+ tor_assert(mock_options);
+ return mock_options;
+}
+
+/* Test that single onion poisoning works. */
+static void
+test_single_onion_poisoning(void *arg)
+{
+ or_options_t opt;
+ mock_options = &opt;
+ reset_options(mock_options, &mock_get_options_calls);
+ MOCK(get_options, mock_get_options);
+
+ int ret = -1;
+ mock_options->DataDirectory = tor_strdup(get_fname("test_data_dir"));
+ rend_service_t *service_1 = tor_malloc_zero(sizeof(rend_service_t));
+ char *dir1 = tor_strdup(get_fname("test_hs_dir1"));
+ rend_service_t *service_2 = tor_malloc_zero(sizeof(rend_service_t));
+ char *dir2 = tor_strdup(get_fname("test_hs_dir2"));
+ smartlist_t *services = smartlist_new();
+
+ (void) arg;
+
+ /* No services, no problem! */
+ mock_options->HiddenServiceSingleHopMode = 0;
+ mock_options->HiddenServiceNonAnonymousMode = 0;
+ ret = rend_service_list_verify_single_onion_poison(services, mock_options);
+ tt_assert(ret == 0);
+
+ /* Either way, no problem. */
+ mock_options->HiddenServiceSingleHopMode = 1;
+ mock_options->HiddenServiceNonAnonymousMode = 1;
+ ret = rend_service_list_verify_single_onion_poison(services, mock_options);
+ tt_assert(ret == 0);
+
+ /* Create directories for both services */
+
+#ifdef _WIN32
+ ret = mkdir(mock_options->DataDirectory);
+ tt_assert(ret == 0);
+ ret = mkdir(dir1);
+ tt_assert(ret == 0);
+ ret = mkdir(dir2);
+#else
+ ret = mkdir(mock_options->DataDirectory, 0700);
+ tt_assert(ret == 0);
+ ret = mkdir(dir1, 0700);
+ tt_assert(ret == 0);
+ ret = mkdir(dir2, 0700);
+#endif
+ tt_assert(ret == 0);
+
+ service_1->directory = dir1;
+ service_2->directory = dir2;
+ dir1 = dir2 = NULL;
+ smartlist_add(services, service_1);
+ /* But don't add the second service yet. */
+
+ /* Service directories, but no previous keys, no problem! */
+ mock_options->HiddenServiceSingleHopMode = 0;
+ mock_options->HiddenServiceNonAnonymousMode = 0;
+ ret = rend_service_list_verify_single_onion_poison(services, mock_options);
+ tt_assert(ret == 0);
+
+ /* Either way, no problem. */
+ mock_options->HiddenServiceSingleHopMode = 1;
+ mock_options->HiddenServiceNonAnonymousMode = 1;
+ ret = rend_service_list_verify_single_onion_poison(services, mock_options);
+ tt_assert(ret == 0);
+
+ /* Poison! Poison! Poison!
+ * This can only be done in HiddenServiceSingleHopMode. */
+ mock_options->HiddenServiceSingleHopMode = 1;
+ mock_options->HiddenServiceNonAnonymousMode = 1;
+ ret = rend_service_poison_new_single_onion_dirs(services);
+ tt_assert(ret == 0);
+ /* Poisoning twice is a no-op. */
+ ret = rend_service_poison_new_single_onion_dirs(services);
+ tt_assert(ret == 0);
+
+ /* Poisoned service directories, but no previous keys, no problem! */
+ mock_options->HiddenServiceSingleHopMode = 0;
+ mock_options->HiddenServiceNonAnonymousMode = 0;
+ ret = rend_service_list_verify_single_onion_poison(services, mock_options);
+ tt_assert(ret == 0);
+
+ /* Either way, no problem. */
+ mock_options->HiddenServiceSingleHopMode = 1;
+ mock_options->HiddenServiceNonAnonymousMode = 1;
+ ret = rend_service_list_verify_single_onion_poison(services, mock_options);
+ tt_assert(ret == 0);
+
+ /* Now add some keys, and we'll have a problem. */
+ ret = rend_service_load_all_keys(services);
+ tt_assert(ret == 0);
+
+ /* Poisoned service directories with previous keys are not allowed. */
+ mock_options->HiddenServiceSingleHopMode = 0;
+ mock_options->HiddenServiceNonAnonymousMode = 0;
+ ret = rend_service_list_verify_single_onion_poison(services, mock_options);
+ tt_assert(ret < 0);
+
+ /* But they are allowed if we're in non-anonymous mode. */
+ mock_options->HiddenServiceSingleHopMode = 1;
+ mock_options->HiddenServiceNonAnonymousMode = 1;
+ ret = rend_service_list_verify_single_onion_poison(services, mock_options);
+ tt_assert(ret == 0);
+
+ /* Re-poisoning directories with existing keys is a no-op, because
+ * directories with existing keys are ignored. */
+ mock_options->HiddenServiceSingleHopMode = 1;
+ mock_options->HiddenServiceNonAnonymousMode = 1;
+ ret = rend_service_poison_new_single_onion_dirs(services);
+ tt_assert(ret == 0);
+ /* And it keeps the poison. */
+ ret = rend_service_list_verify_single_onion_poison(services, mock_options);
+ tt_assert(ret == 0);
+
+ /* Now add the second service: it has no key and no poison file */
+ smartlist_add(services, service_2);
+
+ /* A new service, and an existing poisoned service. Not ok. */
+ mock_options->HiddenServiceSingleHopMode = 0;
+ mock_options->HiddenServiceNonAnonymousMode = 0;
+ ret = rend_service_list_verify_single_onion_poison(services, mock_options);
+ tt_assert(ret < 0);
+
+ /* But ok to add in non-anonymous mode. */
+ mock_options->HiddenServiceSingleHopMode = 1;
+ mock_options->HiddenServiceNonAnonymousMode = 1;
+ ret = rend_service_list_verify_single_onion_poison(services, mock_options);
+ tt_assert(ret == 0);
+
+ /* Now remove the poisoning from the first service, and we have the opposite
+ * problem. */
+ char *poison_path = rend_service_sos_poison_path(service_1);
+ ret = unlink(poison_path);
+ tor_free(poison_path);
+ tt_assert(ret == 0);
+
+ /* Unpoisoned service directories with previous keys are ok, as are empty
+ * directories. */
+ mock_options->HiddenServiceSingleHopMode = 0;
+ mock_options->HiddenServiceNonAnonymousMode = 0;
+ ret = rend_service_list_verify_single_onion_poison(services, mock_options);
+ tt_assert(ret == 0);
+
+ /* But the existing unpoisoned key is not ok in non-anonymous mode, even if
+ * there is an empty service. */
+ mock_options->HiddenServiceSingleHopMode = 1;
+ mock_options->HiddenServiceNonAnonymousMode = 1;
+ ret = rend_service_list_verify_single_onion_poison(services, mock_options);
+ tt_assert(ret < 0);
+
+ /* Poisoning directories with existing keys is a no-op, because directories
+ * with existing keys are ignored. But the new directory should poison. */
+ mock_options->HiddenServiceSingleHopMode = 1;
+ mock_options->HiddenServiceNonAnonymousMode = 1;
+ ret = rend_service_poison_new_single_onion_dirs(services);
+ tt_assert(ret == 0);
+ /* And the old directory remains unpoisoned. */
+ ret = rend_service_list_verify_single_onion_poison(services, mock_options);
+ tt_assert(ret < 0);
+
+ /* And the new directory should be ignored, because it has no key. */
+ mock_options->HiddenServiceSingleHopMode = 0;
+ mock_options->HiddenServiceNonAnonymousMode = 0;
+ ret = rend_service_list_verify_single_onion_poison(services, mock_options);
+ tt_assert(ret == 0);
+
+ /* Re-poisoning directories without existing keys is a no-op. */
+ mock_options->HiddenServiceSingleHopMode = 1;
+ mock_options->HiddenServiceNonAnonymousMode = 1;
+ ret = rend_service_poison_new_single_onion_dirs(services);
+ tt_assert(ret == 0);
+ /* And the old directory remains unpoisoned. */
+ ret = rend_service_list_verify_single_onion_poison(services, mock_options);
+ tt_assert(ret < 0);
+
+ done:
+ /* TODO: should we delete the directories here? */
+ rend_service_free(service_1);
+ rend_service_free(service_2);
+ smartlist_free(services);
+ UNMOCK(get_options);
+ tor_free(mock_options->DataDirectory);
+ tor_free(dir1);
+ tor_free(dir2);
+}
+
struct testcase_t hs_tests[] = {
{ "hs_rend_data", test_hs_rend_data, TT_FORK,
NULL, NULL },
@@ -517,6 +725,8 @@ struct testcase_t hs_tests[] = {
NULL, NULL },
{ "hs_auth_cookies", test_hs_auth_cookies, TT_FORK,
NULL, NULL },
+ { "single_onion_poisoning", test_single_onion_poisoning, TT_FORK,
+ NULL, NULL },
END_OF_TESTCASES
};
diff --git a/src/test/test_link_handshake.c b/src/test/test_link_handshake.c
index 4038783459..9899e54231 100644
--- a/src/test/test_link_handshake.c
+++ b/src/test/test_link_handshake.c
@@ -6,15 +6,30 @@
#define CHANNELTLS_PRIVATE
#define CONNECTION_PRIVATE
#define TOR_CHANNEL_INTERNAL_
+#define TORTLS_PRIVATE
+
+#include "compat.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/x509.h>
+#include <openssl/ssl.h>
+ENABLE_GCC_WARNING(redundant-decls)
+
#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"
static var_cell_t *mock_got_var_cell = NULL;
@@ -36,6 +51,16 @@ mock_tls_cert_matches_key(const tor_tls_t *tls, const tor_x509_cert_t *cert)
(void) cert; // XXXX look at this.
return 1;
}
+static tor_tls_t *mock_peer_cert_expect_tortls = NULL;
+static tor_x509_cert_t *mock_peer_cert = NULL;
+static tor_x509_cert_t *
+mock_get_peer_cert(tor_tls_t *tls)
+{
+ if (mock_peer_cert_expect_tortls &&
+ mock_peer_cert_expect_tortls != tls)
+ return NULL;
+ return mock_peer_cert;
+}
static int mock_send_netinfo_called = 0;
static int
@@ -56,33 +81,48 @@ mock_close_for_err(or_connection_t *orconn, int flush)
}
static int mock_send_authenticate_called = 0;
+static int mock_send_authenticate_called_with_type = 0;
static int
mock_send_authenticate(or_connection_t *conn, int type)
{
(void) conn;
- (void) type;
+ mock_send_authenticate_called_with_type = type;
++mock_send_authenticate_called;// XXX check_this
return 0;
}
+static int
+mock_export_key_material(tor_tls_t *tls, uint8_t *secrets_out,
+ const uint8_t *context,
+ size_t context_len,
+ const char *label)
+{
+ (void) tls;
+ (void)secrets_out;
+ (void)context;
+ (void)context_len;
+ (void)label;
+ memcpy(secrets_out, "int getRandomNumber(){return 4;}", 32);
+ return 0;
+}
/* Test good certs cells */
static void
test_link_handshake_certs_ok(void *arg)
{
- (void) arg;
-
or_connection_t *c1 = or_connection_new(CONN_TYPE_OR, AF_INET);
or_connection_t *c2 = or_connection_new(CONN_TYPE_OR, AF_INET);
var_cell_t *cell1 = NULL, *cell2 = NULL;
certs_cell_t *cc1 = NULL, *cc2 = NULL;
channel_tls_t *chan1 = NULL, *chan2 = NULL;
crypto_pk_t *key1 = NULL, *key2 = NULL;
+ const int with_ed = !strcmp((const char *)arg, "Ed25519");
scheduler_init();
MOCK(tor_tls_cert_matches_key, mock_tls_cert_matches_key);
MOCK(connection_or_write_var_cell_to_buf, mock_write_var_cell);
MOCK(connection_or_send_netinfo, mock_send_netinfo);
+ MOCK(tor_tls_get_peer_cert, mock_get_peer_cert);
key1 = pk_generate(2);
key2 = pk_generate(3);
@@ -93,10 +133,18 @@ test_link_handshake_certs_ok(void *arg)
tt_int_op(tor_tls_context_init(TOR_TLS_CTX_IS_PUBLIC_SERVER,
key1, key2, 86400), ==, 0);
+ if (with_ed) {
+ /* If we're making a CERTS cell for an ed handshake, let's make sure we
+ * have some Ed25519 certificates and keys. */
+ init_mock_ed_keys(key2);
+ }
+
+ /* c1 has started_here == 1 */
c1->base_.state = OR_CONN_STATE_OR_HANDSHAKING_V3;
c1->link_proto = 3;
tt_int_op(connection_init_or_handshake_state(c1, 1), ==, 0);
+ /* c2 has started_here == 0 */
c2->base_.state = OR_CONN_STATE_OR_HANDSHAKING_V3;
c2->link_proto = 3;
tt_int_op(connection_init_or_handshake_state(c2, 0), ==, 0);
@@ -120,8 +168,13 @@ test_link_handshake_certs_ok(void *arg)
tt_int_op(cell2->payload_len, ==,
certs_cell_parse(&cc2, cell2->payload, cell2->payload_len));
- tt_int_op(2, ==, cc1->n_certs);
- tt_int_op(2, ==, cc2->n_certs);
+ if (with_ed) {
+ tt_int_op(5, ==, cc1->n_certs);
+ tt_int_op(5, ==, cc2->n_certs);
+ } else {
+ tt_int_op(2, ==, cc1->n_certs);
+ tt_int_op(2, ==, cc2->n_certs);
+ }
tt_int_op(certs_cell_get_certs(cc1, 0)->cert_type, ==,
CERTTYPE_RSA1024_ID_AUTH);
@@ -133,6 +186,22 @@ test_link_handshake_certs_ok(void *arg)
tt_int_op(certs_cell_get_certs(cc2, 1)->cert_type, ==,
CERTTYPE_RSA1024_ID_ID);
+ if (with_ed) {
+ tt_int_op(certs_cell_get_certs(cc1, 2)->cert_type, ==,
+ CERTTYPE_ED_ID_SIGN);
+ tt_int_op(certs_cell_get_certs(cc1, 3)->cert_type, ==,
+ CERTTYPE_ED_SIGN_AUTH);
+ tt_int_op(certs_cell_get_certs(cc1, 4)->cert_type, ==,
+ CERTTYPE_RSA1024_ID_EDID);
+
+ tt_int_op(certs_cell_get_certs(cc2, 2)->cert_type, ==,
+ CERTTYPE_ED_ID_SIGN);
+ tt_int_op(certs_cell_get_certs(cc2, 3)->cert_type, ==,
+ CERTTYPE_ED_SIGN_LINK);
+ tt_int_op(certs_cell_get_certs(cc2, 4)->cert_type, ==,
+ CERTTYPE_RSA1024_ID_EDID);
+ }
+
chan1 = tor_malloc_zero(sizeof(*chan1));
channel_tls_common_init(chan1);
c1->chan = chan1;
@@ -143,13 +212,38 @@ test_link_handshake_certs_ok(void *arg)
c1->base_.conn_array_index = -1;
crypto_pk_get_digest(key2, c1->identity_digest);
+ if (with_ed) {
+ const tor_x509_cert_t *linkc, *idc;
+ tor_tls_get_my_certs(1, &linkc, &idc);
+ mock_peer_cert_expect_tortls = c1->tls; /* We should see this tls... */
+ mock_peer_cert = tor_x509_cert_dup(linkc); /* and when we do, the peer's
+ * cert is this... */
+ }
channel_tls_process_certs_cell(cell2, chan1);
+ mock_peer_cert_expect_tortls = NULL;
+ mock_peer_cert = NULL;
+
+ tor_assert(c1->handshake_state->authenticated);
tt_assert(c1->handshake_state->received_certs_cell);
- tt_assert(c1->handshake_state->auth_cert == NULL);
- tt_assert(c1->handshake_state->id_cert);
+ tt_assert(c1->handshake_state->certs->auth_cert == NULL);
+ tt_assert(c1->handshake_state->certs->ed_sign_auth == NULL);
+ tt_assert(c1->handshake_state->certs->id_cert);
+ if (with_ed) {
+ tt_assert(c1->handshake_state->certs->ed_sign_link);
+ tt_assert(c1->handshake_state->certs->ed_rsa_crosscert);
+ tt_assert(c1->handshake_state->certs->ed_id_sign);
+ tt_assert(c1->handshake_state->authenticated_rsa);
+ tt_assert(c1->handshake_state->authenticated_ed25519);
+ } else {
+ tt_assert(c1->handshake_state->certs->ed_sign_link == NULL);
+ tt_assert(c1->handshake_state->certs->ed_rsa_crosscert == NULL);
+ tt_assert(c1->handshake_state->certs->ed_id_sign == NULL);
+ tt_assert(c1->handshake_state->authenticated_rsa);
+ tt_assert(! c1->handshake_state->authenticated_ed25519);
+ }
tt_assert(! tor_mem_is_zero(
- (char*)c1->handshake_state->authenticated_peer_id, 20));
+ (char*)c1->handshake_state->authenticated_rsa_peer_id, 20));
chan2 = tor_malloc_zero(sizeof(*chan2));
channel_tls_common_init(chan2);
@@ -164,15 +258,32 @@ test_link_handshake_certs_ok(void *arg)
channel_tls_process_certs_cell(cell1, chan2);
tt_assert(c2->handshake_state->received_certs_cell);
- tt_assert(c2->handshake_state->auth_cert);
- tt_assert(c2->handshake_state->id_cert);
+ if (with_ed) {
+ tt_assert(c2->handshake_state->certs->ed_sign_auth);
+ tt_assert(c2->handshake_state->certs->ed_rsa_crosscert);
+ tt_assert(c2->handshake_state->certs->ed_id_sign);
+ } else {
+ tt_assert(c2->handshake_state->certs->auth_cert);
+ tt_assert(c2->handshake_state->certs->ed_sign_auth == NULL);
+ tt_assert(c2->handshake_state->certs->ed_rsa_crosscert == NULL);
+ tt_assert(c2->handshake_state->certs->ed_id_sign == NULL);
+ }
+ tt_assert(c2->handshake_state->certs->id_cert);
tt_assert(tor_mem_is_zero(
- (char*)c2->handshake_state->authenticated_peer_id, 20));
+ (char*)c2->handshake_state->authenticated_rsa_peer_id, 20));
+ /* no authentication has happened yet, since we haen't gotten an AUTH cell.
+ */
+ tt_assert(! c2->handshake_state->authenticated);
+ tt_assert(! c2->handshake_state->authenticated_rsa);
+ tt_assert(! c2->handshake_state->authenticated_ed25519);
done:
UNMOCK(tor_tls_cert_matches_key);
UNMOCK(connection_or_write_var_cell_to_buf);
UNMOCK(connection_or_send_netinfo);
+ UNMOCK(tor_tls_get_peer_cert);
+ memset(c1->identity_digest, 0, sizeof(c1->identity_digest));
+ memset(c2->identity_digest, 0, sizeof(c2->identity_digest));
connection_free_(TO_CONN(c1));
connection_free_(TO_CONN(c2));
tor_free(cell1);
@@ -190,6 +301,8 @@ test_link_handshake_certs_ok(void *arg)
}
typedef struct certs_data_s {
+ int is_ed;
+ int is_link_cert;
or_connection_t *c;
channel_tls_t *chan;
certs_cell_t *ccell;
@@ -205,10 +318,12 @@ recv_certs_cleanup(const struct testcase_t *test, void *obj)
UNMOCK(tor_tls_cert_matches_key);
UNMOCK(connection_or_send_netinfo);
UNMOCK(connection_or_close_for_error);
+ UNMOCK(tor_tls_get_peer_cert);
if (d) {
tor_free(d->cell);
certs_cell_free(d->ccell);
+ connection_or_remove_from_identity_map(d->c);
connection_free_(TO_CONN(d->c));
circuitmux_free(d->chan->base_.cmux);
tor_free(d->chan);
@@ -216,6 +331,7 @@ recv_certs_cleanup(const struct testcase_t *test, void *obj)
crypto_pk_free(d->key2);
tor_free(d);
}
+ routerkeys_free_all();
return 1;
}
@@ -227,6 +343,12 @@ recv_certs_setup(const struct testcase_t *test)
certs_cell_cert_t *ccc1 = NULL;
certs_cell_cert_t *ccc2 = NULL;
ssize_t n;
+ int is_ed = d->is_ed = !strcmpstart(test->setup_data, "Ed25519");
+ int is_rsa = !strcmpstart(test->setup_data, "RSA");
+ int is_link = d->is_link_cert = !strcmpend(test->setup_data, "-Link");
+ int is_auth = !strcmpend(test->setup_data, "-Auth");
+ tor_assert(is_ed != is_rsa);
+ tor_assert(is_link != is_auth);
d->c = or_connection_new(CONN_TYPE_OR, AF_INET);
d->chan = tor_malloc_zero(sizeof(*d->chan));
@@ -242,19 +364,25 @@ recv_certs_setup(const struct testcase_t *test)
tt_int_op(tor_tls_context_init(TOR_TLS_CTX_IS_PUBLIC_SERVER,
d->key1, d->key2, 86400), ==, 0);
+ if (is_ed) {
+ init_mock_ed_keys(d->key2);
+ } else {
+ routerkeys_free_all();
+ }
+
d->ccell = certs_cell_new();
ccc1 = certs_cell_cert_new();
certs_cell_add_certs(d->ccell, ccc1);
ccc2 = certs_cell_cert_new();
certs_cell_add_certs(d->ccell, ccc2);
d->ccell->n_certs = 2;
- ccc1->cert_type = 1;
+ ccc1->cert_type = is_link ? 1 : 3;
ccc2->cert_type = 2;
const tor_x509_cert_t *a,*b;
const uint8_t *enca, *encb;
size_t lena, lenb;
- tor_tls_get_my_certs(1, &a, &b);
+ tor_tls_get_my_certs(is_link ? 1 : 0, &a, &b);
tor_x509_cert_get_der(a, &enca, &lena);
tor_x509_cert_get_der(b, &encb, &lenb);
certs_cell_cert_setlen_body(ccc1, lena);
@@ -265,6 +393,41 @@ recv_certs_setup(const struct testcase_t *test)
memcpy(certs_cell_cert_getarray_body(ccc1), enca, lena);
memcpy(certs_cell_cert_getarray_body(ccc2), encb, lenb);
+ if (is_ed) {
+ certs_cell_cert_t *ccc3 = NULL; /* Id->Sign */
+ certs_cell_cert_t *ccc4 = NULL; /* Sign->Link or Sign->Auth. */
+ certs_cell_cert_t *ccc5 = NULL; /* RSAId->Ed Id. */
+ const tor_cert_t *id_sign = get_master_signing_key_cert();
+ const tor_cert_t *secondary =
+ is_link ? get_current_link_cert_cert() : get_current_auth_key_cert();
+ const uint8_t *cc = NULL;
+ size_t cc_sz;
+ get_master_rsa_crosscert(&cc, &cc_sz);
+
+ ccc3 = certs_cell_cert_new();
+ ccc4 = certs_cell_cert_new();
+ ccc5 = certs_cell_cert_new();
+ certs_cell_add_certs(d->ccell, ccc3);
+ certs_cell_add_certs(d->ccell, ccc4);
+ certs_cell_add_certs(d->ccell, ccc5);
+ ccc3->cert_len = id_sign->encoded_len;
+ ccc4->cert_len = secondary->encoded_len;
+ ccc5->cert_len = cc_sz;
+ certs_cell_cert_setlen_body(ccc3, ccc3->cert_len);
+ certs_cell_cert_setlen_body(ccc4, ccc4->cert_len);
+ certs_cell_cert_setlen_body(ccc5, ccc5->cert_len);
+ memcpy(certs_cell_cert_getarray_body(ccc3), id_sign->encoded,
+ ccc3->cert_len);
+ memcpy(certs_cell_cert_getarray_body(ccc4), secondary->encoded,
+ ccc4->cert_len);
+ memcpy(certs_cell_cert_getarray_body(ccc5), cc, ccc5->cert_len);
+ ccc3->cert_type = 4;
+ ccc4->cert_type = is_link ? 5 : 6;
+ ccc5->cert_type = 7;
+
+ d->ccell->n_certs = 5;
+ }
+
d->cell = var_cell_new(4096);
d->cell->command = CELL_CERTS;
@@ -275,6 +438,12 @@ recv_certs_setup(const struct testcase_t *test)
MOCK(tor_tls_cert_matches_key, mock_tls_cert_matches_key);
MOCK(connection_or_send_netinfo, mock_send_netinfo);
MOCK(connection_or_close_for_error, mock_close_for_err);
+ MOCK(tor_tls_get_peer_cert, mock_get_peer_cert);
+
+ if (is_link) {
+ /* Say that this is the peer's certificate */
+ mock_peer_cert = tor_x509_cert_dup(a);
+ }
tt_int_op(0, ==, d->c->handshake_state->received_certs_cell);
tt_int_op(0, ==, mock_send_authenticate_called);
@@ -298,9 +467,24 @@ test_link_handshake_recv_certs_ok(void *arg)
channel_tls_process_certs_cell(d->cell, d->chan);
tt_int_op(0, ==, mock_close_called);
tt_int_op(d->c->handshake_state->authenticated, ==, 1);
+ tt_int_op(d->c->handshake_state->authenticated_rsa, ==, 1);
tt_int_op(d->c->handshake_state->received_certs_cell, ==, 1);
- tt_assert(d->c->handshake_state->id_cert != NULL);
- tt_assert(d->c->handshake_state->auth_cert == NULL);
+ tt_assert(d->c->handshake_state->certs->id_cert != NULL);
+ tt_assert(d->c->handshake_state->certs->auth_cert == NULL);
+
+ if (d->is_ed) {
+ tt_assert(d->c->handshake_state->certs->ed_id_sign != NULL);
+ tt_assert(d->c->handshake_state->certs->ed_sign_link != NULL);
+ tt_assert(d->c->handshake_state->certs->ed_sign_auth == NULL);
+ tt_assert(d->c->handshake_state->certs->ed_rsa_crosscert != NULL);
+ tt_int_op(d->c->handshake_state->authenticated_ed25519, ==, 1);
+ } else {
+ tt_assert(d->c->handshake_state->certs->ed_id_sign == NULL);
+ tt_assert(d->c->handshake_state->certs->ed_sign_link == NULL);
+ tt_assert(d->c->handshake_state->certs->ed_sign_auth == NULL);
+ tt_assert(d->c->handshake_state->certs->ed_rsa_crosscert == NULL);
+ tt_int_op(d->c->handshake_state->authenticated_ed25519, ==, 0);
+ }
done:
;
@@ -311,17 +495,20 @@ test_link_handshake_recv_certs_ok_server(void *arg)
{
certs_data_t *d = arg;
d->c->handshake_state->started_here = 0;
- certs_cell_get_certs(d->ccell, 0)->cert_type = 3;
- certs_cell_get_certs(d->ccell, 1)->cert_type = 2;
- ssize_t n = certs_cell_encode(d->cell->payload, 2048, d->ccell);
- tt_int_op(n, >, 0);
- d->cell->payload_len = n;
+ d->c->handshake_state->certs->started_here = 0;
channel_tls_process_certs_cell(d->cell, d->chan);
tt_int_op(0, ==, mock_close_called);
tt_int_op(d->c->handshake_state->authenticated, ==, 0);
tt_int_op(d->c->handshake_state->received_certs_cell, ==, 1);
- tt_assert(d->c->handshake_state->id_cert != NULL);
- tt_assert(d->c->handshake_state->auth_cert != NULL);
+ tt_assert(d->c->handshake_state->certs->id_cert != NULL);
+ tt_assert(d->c->handshake_state->certs->link_cert == NULL);
+ if (d->is_ed) {
+ tt_assert(d->c->handshake_state->certs->ed_sign_auth != NULL);
+ tt_assert(d->c->handshake_state->certs->auth_cert == NULL);
+ } else {
+ tt_assert(d->c->handshake_state->certs->ed_sign_auth == NULL);
+ tt_assert(d->c->handshake_state->certs->auth_cert != NULL);
+ }
done:
;
@@ -332,65 +519,321 @@ test_link_handshake_recv_certs_ok_server(void *arg)
test_link_handshake_recv_certs_ ## name(void *arg) \
{ \
certs_data_t *d = arg; \
+ const char *require_failure_message = NULL; \
+ setup_capture_of_logs(LOG_INFO); \
{ code ; } \
channel_tls_process_certs_cell(d->cell, d->chan); \
tt_int_op(1, ==, mock_close_called); \
tt_int_op(0, ==, mock_send_authenticate_called); \
tt_int_op(0, ==, mock_send_netinfo_called); \
+ tt_int_op(0, ==, d->c->handshake_state->authenticated_rsa); \
+ tt_int_op(0, ==, d->c->handshake_state->authenticated_ed25519); \
+ if (require_failure_message) { \
+ expect_log_msg_containing(require_failure_message); \
+ } \
done: \
- ; \
+ teardown_capture_of_logs(); \
}
-CERTS_FAIL(badstate, d->c->base_.state = OR_CONN_STATE_CONNECTING)
-CERTS_FAIL(badproto, d->c->link_proto = 2)
-CERTS_FAIL(duplicate, d->c->handshake_state->received_certs_cell = 1)
+CERTS_FAIL(badstate,
+ require_failure_message = "We're not doing a v3 handshake!";
+ d->c->base_.state = OR_CONN_STATE_CONNECTING;)
+CERTS_FAIL(badproto,
+ require_failure_message = "not using link protocol >= 3";
+ d->c->link_proto = 2)
+CERTS_FAIL(duplicate,
+ require_failure_message = "We already got one";
+ d->c->handshake_state->received_certs_cell = 1)
CERTS_FAIL(already_authenticated,
+ require_failure_message = "We're already authenticated!";
d->c->handshake_state->authenticated = 1)
-CERTS_FAIL(empty, d->cell->payload_len = 0)
-CERTS_FAIL(bad_circid, d->cell->circ_id = 1)
-CERTS_FAIL(truncated_1, d->cell->payload[0] = 5)
+CERTS_FAIL(empty,
+ require_failure_message = "It had no body";
+ d->cell->payload_len = 0)
+CERTS_FAIL(bad_circid,
+ require_failure_message = "It had a nonzero circuit ID";
+ d->cell->circ_id = 1)
+CERTS_FAIL(truncated_1,
+ require_failure_message = "It couldn't be parsed";
+ d->cell->payload[0] = 5)
CERTS_FAIL(truncated_2,
{
+ require_failure_message = "It couldn't be parsed";
d->cell->payload_len = 4;
memcpy(d->cell->payload, "\x01\x01\x00\x05", 4);
})
CERTS_FAIL(truncated_3,
{
+ require_failure_message = "It couldn't be parsed";
d->cell->payload_len = 7;
memcpy(d->cell->payload, "\x01\x01\x00\x05""abc", 7);
})
+CERTS_FAIL(truncated_4, /* ed25519 */
+ {
+ require_failure_message = "It couldn't be parsed";
+ d->cell->payload_len -= 10;
+ })
+CERTS_FAIL(truncated_5, /* ed25519 */
+ {
+ require_failure_message = "It couldn't be parsed";
+ d->cell->payload_len -= 100;
+ })
+
#define REENCODE() do { \
+ const char *msg = certs_cell_check(d->ccell); \
+ if (msg) puts(msg); \
ssize_t n = certs_cell_encode(d->cell->payload, 4096, d->ccell); \
tt_int_op(n, >, 0); \
d->cell->payload_len = n; \
} while (0)
+CERTS_FAIL(truncated_6, /* ed25519 */
+ {
+ /* truncate the link certificate */
+ require_failure_message = "undecodable Ed certificate";
+ certs_cell_cert_setlen_body(certs_cell_get_certs(d->ccell, 3), 7);
+ certs_cell_get_certs(d->ccell, 3)->cert_len = 7;
+ REENCODE();
+ })
+CERTS_FAIL(truncated_7, /* ed25519 */
+ {
+ /* truncate the crosscert */
+ require_failure_message = "Unparseable or overlong crosscert";
+ certs_cell_cert_setlen_body(certs_cell_get_certs(d->ccell, 4), 7);
+ certs_cell_get_certs(d->ccell, 4)->cert_len = 7;
+ REENCODE();
+ })
CERTS_FAIL(not_x509,
{
+ require_failure_message = "Received undecodable certificate";
certs_cell_cert_setlen_body(certs_cell_get_certs(d->ccell, 0), 3);
certs_cell_get_certs(d->ccell, 0)->cert_len = 3;
REENCODE();
})
CERTS_FAIL(both_link,
{
+ require_failure_message = "Duplicate x509 certificate";
certs_cell_get_certs(d->ccell, 0)->cert_type = 1;
certs_cell_get_certs(d->ccell, 1)->cert_type = 1;
REENCODE();
})
CERTS_FAIL(both_id_rsa,
{
+ require_failure_message = "Duplicate x509 certificate";
certs_cell_get_certs(d->ccell, 0)->cert_type = 2;
certs_cell_get_certs(d->ccell, 1)->cert_type = 2;
REENCODE();
})
CERTS_FAIL(both_auth,
{
+ require_failure_message = "Duplicate x509 certificate";
certs_cell_get_certs(d->ccell, 0)->cert_type = 3;
certs_cell_get_certs(d->ccell, 1)->cert_type = 3;
REENCODE();
})
+CERTS_FAIL(duplicate_id, /* ed25519 */
+ {
+ require_failure_message = "Duplicate Ed25519 certificate";
+ certs_cell_get_certs(d->ccell, 2)->cert_type = 4;
+ certs_cell_get_certs(d->ccell, 3)->cert_type = 4;
+ REENCODE();
+ })
+CERTS_FAIL(duplicate_link, /* ed25519 */
+ {
+ require_failure_message = "Duplicate Ed25519 certificate";
+ certs_cell_get_certs(d->ccell, 2)->cert_type = 5;
+ certs_cell_get_certs(d->ccell, 3)->cert_type = 5;
+ REENCODE();
+ })
+CERTS_FAIL(duplicate_crosscert, /* ed25519 */
+ {
+ require_failure_message = "Duplicate RSA->Ed25519 crosscert";
+ certs_cell_get_certs(d->ccell, 2)->cert_type = 7;
+ certs_cell_get_certs(d->ccell, 3)->cert_type = 7;
+ REENCODE();
+ })
+static void
+test_link_handshake_recv_certs_missing_id(void *arg) /* ed25519 */
+{
+ certs_data_t *d = arg;
+ tt_int_op(certs_cell_getlen_certs(d->ccell), OP_EQ, 5);
+ certs_cell_set_certs(d->ccell, 2, certs_cell_get_certs(d->ccell, 4));
+ certs_cell_set0_certs(d->ccell, 4, NULL); /* prevent free */
+ certs_cell_setlen_certs(d->ccell, 4);
+ d->ccell->n_certs = 4;
+ REENCODE();
+
+ /* This handshake succeeds, but since we have no ID cert, we will
+ * just do the RSA handshake. */
+ channel_tls_process_certs_cell(d->cell, d->chan);
+ tt_int_op(0, ==, mock_close_called);
+ tt_int_op(0, ==, d->c->handshake_state->authenticated_ed25519);
+ tt_int_op(1, ==, d->c->handshake_state->authenticated_rsa);
+ done:
+ ;
+}
+CERTS_FAIL(missing_signing_key, /* ed25519 */
+ {
+ require_failure_message = "No Ed25519 signing key";
+ tt_int_op(certs_cell_getlen_certs(d->ccell), OP_EQ, 5);
+ certs_cell_cert_t *cert = certs_cell_get_certs(d->ccell, 2);
+ tt_int_op(cert->cert_type, ==, CERTTYPE_ED_ID_SIGN);
+ /* replace this with a valid master->signing cert, but with no
+ * signing key. */
+ const ed25519_keypair_t *mk = get_master_identity_keypair();
+ const ed25519_keypair_t *sk = get_master_signing_keypair();
+ tor_cert_t *bad_cert = tor_cert_create(mk, CERT_TYPE_ID_SIGNING,
+ &sk->pubkey, time(NULL), 86400,
+ 0 /* don't include signer */);
+ certs_cell_cert_setlen_body(cert, bad_cert->encoded_len);
+ memcpy(certs_cell_cert_getarray_body(cert),
+ bad_cert->encoded, bad_cert->encoded_len);
+ cert->cert_len = bad_cert->encoded_len;
+ tor_cert_free(bad_cert);
+ REENCODE();
+ })
+CERTS_FAIL(missing_link, /* ed25519 */
+ {
+ require_failure_message = "No Ed25519 link key";
+ tt_int_op(certs_cell_getlen_certs(d->ccell), OP_EQ, 5);
+ certs_cell_set_certs(d->ccell, 3, certs_cell_get_certs(d->ccell, 4));
+ certs_cell_set0_certs(d->ccell, 4, NULL); /* prevent free */
+ certs_cell_setlen_certs(d->ccell, 4);
+ d->ccell->n_certs = 4;
+ REENCODE();
+ })
+CERTS_FAIL(missing_auth, /* ed25519 */
+ {
+ d->c->handshake_state->started_here = 0;
+ d->c->handshake_state->certs->started_here = 0;
+ require_failure_message = "No Ed25519 link authentication key";
+ tt_int_op(certs_cell_getlen_certs(d->ccell), OP_EQ, 5);
+ certs_cell_set_certs(d->ccell, 3, certs_cell_get_certs(d->ccell, 4));
+ certs_cell_set0_certs(d->ccell, 4, NULL); /* prevent free */
+ certs_cell_setlen_certs(d->ccell, 4);
+ d->ccell->n_certs = 4;
+ REENCODE();
+ })
+CERTS_FAIL(missing_crosscert, /* ed25519 */
+ {
+ require_failure_message = "Missing RSA->Ed25519 crosscert";
+ tt_int_op(certs_cell_getlen_certs(d->ccell), OP_EQ, 5);
+ certs_cell_setlen_certs(d->ccell, 4);
+ d->ccell->n_certs = 4;
+ REENCODE();
+ })
+CERTS_FAIL(missing_rsa_id, /* ed25519 */
+ {
+ require_failure_message = "Missing legacy RSA ID cert";
+ tt_int_op(certs_cell_getlen_certs(d->ccell), OP_EQ, 5);
+ certs_cell_set_certs(d->ccell, 1, certs_cell_get_certs(d->ccell, 4));
+ certs_cell_set0_certs(d->ccell, 4, NULL); /* prevent free */
+ certs_cell_setlen_certs(d->ccell, 4);
+ d->ccell->n_certs = 4;
+ REENCODE();
+ })
+CERTS_FAIL(link_mismatch, /* ed25519 */
+ {
+ require_failure_message = "Link certificate does not match "
+ "TLS certificate";
+ const tor_x509_cert_t *idc;
+ tor_tls_get_my_certs(1, NULL, &idc);
+ tor_x509_cert_free(mock_peer_cert);
+ /* Pretend that the peer cert was something else. */
+ mock_peer_cert = tor_x509_cert_dup(idc);
+ /* No reencode needed. */
+ })
+CERTS_FAIL(bad_ed_sig, /* ed25519 */
+ {
+ require_failure_message = "At least one Ed25519 certificate was "
+ "badly signed";
+ certs_cell_cert_t *cert = certs_cell_get_certs(d->ccell, 3);
+ 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;
+ REENCODE();
+ })
+CERTS_FAIL(bad_crosscert, /*ed25519*/
+ {
+ require_failure_message = "Invalid RSA->Ed25519 crosscert";
+ certs_cell_cert_t *cert = certs_cell_get_certs(d->ccell, 4);
+ 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;
+ REENCODE();
+ })
+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;
+ REENCODE();
+ })
+CERTS_FAIL(expired_rsa_id, /* both */
+ {
+ require_failure_message = "Certificate already expired";
+ /* we're going to replace the identity cert with an expired one. */
+ certs_cell_cert_t *cert = certs_cell_get_certs(d->ccell, 1);
+ const tor_x509_cert_t *idc;
+ tor_tls_get_my_certs(1, NULL, &idc);
+ X509 *newc = X509_dup(idc->cert);
+ time_t new_end = time(NULL) - 86400 * 10;
+ X509_time_adj(X509_get_notAfter(newc), 0, &new_end);
+ EVP_PKEY *pk = crypto_pk_get_evp_pkey_(d->key2, 1);
+ tt_assert(X509_sign(newc, pk, EVP_sha1()));
+ int len = i2d_X509(newc, NULL);
+ certs_cell_cert_setlen_body(cert, len);
+ uint8_t *body = certs_cell_cert_getarray_body(cert);
+ int len2 = i2d_X509(newc, &body);
+ tt_int_op(len, ==, len2);
+ REENCODE();
+ X509_free(newc);
+ EVP_PKEY_free(pk);
+ })
+CERTS_FAIL(expired_ed_id, /* ed25519 */
+ {
+ /* we're going to replace the Ed Id->sign cert with an expired one. */
+ require_failure_message = "At least one certificate expired";
+ /* We don't need to re-sign, since we check for expiration first. */
+ certs_cell_cert_t *cert = certs_cell_get_certs(d->ccell, 2);
+ uint8_t *body = certs_cell_cert_getarray_body(cert);
+ /* The expiration field is bytes [2..5]. It is in HOURS since the
+ * epoch. */
+ set_uint32(body+2, htonl(24)); /* Back to jan 2, 1970. */
+ REENCODE();
+ })
+CERTS_FAIL(expired_ed_link, /* ed25519 */
+ {
+ /* we're going to replace the Ed Sign->link cert with an expired one. */
+ require_failure_message = "At least one certificate expired";
+ /* We don't need to re-sign, since we check for expiration first. */
+ certs_cell_cert_t *cert = certs_cell_get_certs(d->ccell, 3);
+ uint8_t *body = certs_cell_cert_getarray_body(cert);
+ /* The expiration field is bytes [2..5]. It is in HOURS since the
+ * epoch. */
+ set_uint32(body+2, htonl(24)); /* Back to jan 2, 1970. */
+ REENCODE();
+ })
+CERTS_FAIL(expired_crosscert, /* ed25519 */
+ {
+ /* we're going to replace the Ed Sign->link cert with an expired one. */
+ require_failure_message = "Crosscert is expired";
+ /* We don't need to re-sign, since we check for expiration first. */
+ certs_cell_cert_t *cert = certs_cell_get_certs(d->ccell, 4);
+ uint8_t *body = certs_cell_cert_getarray_body(cert);
+ /* The expiration field is bytes [32..35]. once again, HOURS. */
+ set_uint32(body+32, htonl(24)); /* Back to jan 2, 1970. */
+ REENCODE();
+ })
+
CERTS_FAIL(wrong_labels_1,
{
+ require_failure_message = "The link certificate was not valid";
certs_cell_get_certs(d->ccell, 0)->cert_type = 2;
certs_cell_get_certs(d->ccell, 1)->cert_type = 1;
REENCODE();
@@ -401,6 +844,7 @@ CERTS_FAIL(wrong_labels_2,
const tor_x509_cert_t *b;
const uint8_t *enca;
size_t lena;
+ require_failure_message = "The link certificate was not valid";
tor_tls_get_my_certs(1, &a, &b);
tor_x509_cert_get_der(a, &enca, &lena);
certs_cell_cert_setlen_body(certs_cell_get_certs(d->ccell, 1), lena);
@@ -411,17 +855,26 @@ CERTS_FAIL(wrong_labels_2,
})
CERTS_FAIL(wrong_labels_3,
{
+ require_failure_message =
+ "The certs we wanted (ID, Link) were missing";
certs_cell_get_certs(d->ccell, 0)->cert_type = 2;
certs_cell_get_certs(d->ccell, 1)->cert_type = 3;
REENCODE();
})
CERTS_FAIL(server_missing_certs,
{
+ require_failure_message =
+ "The certs we wanted (ID, Auth) were missing";
d->c->handshake_state->started_here = 0;
+ d->c->handshake_state->certs->started_here = 0;
+
})
CERTS_FAIL(server_wrong_labels_1,
{
+ require_failure_message =
+ "The authentication certificate was not valid";
d->c->handshake_state->started_here = 0;
+ d->c->handshake_state->certs->started_here = 0;
certs_cell_get_certs(d->ccell, 0)->cert_type = 2;
certs_cell_get_certs(d->ccell, 1)->cert_type = 3;
REENCODE();
@@ -444,15 +897,15 @@ test_link_handshake_send_authchallenge(void *arg)
cell1 = mock_got_var_cell;
tt_int_op(0, ==, connection_or_send_auth_challenge_cell(c1));
cell2 = mock_got_var_cell;
- tt_int_op(36, ==, cell1->payload_len);
- tt_int_op(36, ==, cell2->payload_len);
+ tt_int_op(38, ==, cell1->payload_len);
+ tt_int_op(38, ==, cell2->payload_len);
tt_int_op(0, ==, cell1->circ_id);
tt_int_op(0, ==, cell2->circ_id);
tt_int_op(CELL_AUTH_CHALLENGE, ==, cell1->command);
tt_int_op(CELL_AUTH_CHALLENGE, ==, cell2->command);
- tt_mem_op("\x00\x01\x00\x01", ==, cell1->payload + 32, 4);
- tt_mem_op("\x00\x01\x00\x01", ==, cell2->payload + 32, 4);
+ tt_mem_op("\x00\x02\x00\x01\x00\x03", ==, cell1->payload + 32, 6);
+ tt_mem_op("\x00\x02\x00\x01\x00\x03", ==, cell2->payload + 32, 6);
tt_mem_op(cell1->payload, !=, cell2->payload, 32);
done:
@@ -504,9 +957,9 @@ recv_authchallenge_setup(const struct testcase_t *test)
d->c->handshake_state->received_certs_cell = 1;
d->cell = var_cell_new(128);
d->cell->payload_len = 38;
- d->cell->payload[33] = 2;
- d->cell->payload[35] = 7;
- d->cell->payload[37] = 1;
+ d->cell->payload[33] = 2; /* 2 methods */
+ d->cell->payload[35] = 7; /* This one isn't real */
+ d->cell->payload[37] = 1; /* This is the old RSA one. */
d->cell->command = CELL_AUTH_CHALLENGE;
get_options_mutable()->ORPort_set = 1;
@@ -514,7 +967,6 @@ recv_authchallenge_setup(const struct testcase_t *test)
MOCK(connection_or_close_for_error, mock_close_for_err);
MOCK(connection_or_send_netinfo, mock_send_netinfo);
MOCK(connection_or_send_authenticate_cell, mock_send_authenticate);
-
tt_int_op(0, ==, d->c->handshake_state->received_auth_challenge);
tt_int_op(0, ==, mock_send_authenticate_called);
tt_int_op(0, ==, mock_send_netinfo_called);
@@ -540,6 +992,26 @@ test_link_handshake_recv_authchallenge_ok(void *arg)
tt_int_op(1, ==, d->c->handshake_state->received_auth_challenge);
tt_int_op(1, ==, mock_send_authenticate_called);
tt_int_op(1, ==, mock_send_netinfo_called);
+ tt_int_op(1, ==, mock_send_authenticate_called_with_type); /* RSA */
+ done:
+ ;
+}
+
+static void
+test_link_handshake_recv_authchallenge_ok_ed25519(void *arg)
+{
+ authchallenge_data_t *d = arg;
+
+ /* Add the ed25519 authentication mechanism here. */
+ d->cell->payload[33] = 3; /* 3 types are supported now. */
+ d->cell->payload[39] = 3;
+ d->cell->payload_len += 2;
+ channel_tls_process_auth_challenge_cell(d->cell, d->chan);
+ tt_int_op(0, ==, mock_close_called);
+ tt_int_op(1, ==, d->c->handshake_state->received_auth_challenge);
+ tt_int_op(1, ==, mock_send_authenticate_called);
+ tt_int_op(1, ==, mock_send_netinfo_called);
+ tt_int_op(3, ==, mock_send_authenticate_called_with_type); /* Ed25519 */
done:
;
}
@@ -579,40 +1051,49 @@ test_link_handshake_recv_authchallenge_ok_unrecognized(void *arg)
test_link_handshake_recv_authchallenge_ ## name(void *arg) \
{ \
authchallenge_data_t *d = arg; \
+ const char *require_failure_message = NULL; \
+ setup_capture_of_logs(LOG_INFO); \
{ code ; } \
channel_tls_process_auth_challenge_cell(d->cell, d->chan); \
tt_int_op(1, ==, mock_close_called); \
tt_int_op(0, ==, mock_send_authenticate_called); \
tt_int_op(0, ==, mock_send_netinfo_called); \
+ if (require_failure_message) { \
+ expect_log_msg_containing(require_failure_message); \
+ } \
done: \
- ; \
+ teardown_capture_of_logs(); \
}
AUTHCHALLENGE_FAIL(badstate,
+ require_failure_message = "We're not currently doing a "
+ "v3 handshake";
d->c->base_.state = OR_CONN_STATE_CONNECTING)
AUTHCHALLENGE_FAIL(badproto,
+ require_failure_message = "not using link protocol >= 3";
d->c->link_proto = 2)
AUTHCHALLENGE_FAIL(as_server,
- d->c->handshake_state->started_here = 0;)
+ require_failure_message = "We didn't originate this "
+ "connection";
+ d->c->handshake_state->started_here = 0;
+ d->c->handshake_state->certs->started_here = 0;)
AUTHCHALLENGE_FAIL(duplicate,
+ require_failure_message = "We already received one";
d->c->handshake_state->received_auth_challenge = 1)
AUTHCHALLENGE_FAIL(nocerts,
+ require_failure_message = "We haven't gotten a CERTS "
+ "cell yet";
d->c->handshake_state->received_certs_cell = 0)
AUTHCHALLENGE_FAIL(tooshort,
+ require_failure_message = "It was not well-formed";
d->cell->payload_len = 33)
AUTHCHALLENGE_FAIL(truncated,
+ require_failure_message = "It was not well-formed";
d->cell->payload_len = 34)
AUTHCHALLENGE_FAIL(nonzero_circid,
+ require_failure_message = "It had a nonzero circuit ID";
d->cell->circ_id = 1337)
-static tor_x509_cert_t *mock_peer_cert = NULL;
-static tor_x509_cert_t *
-mock_get_peer_cert(tor_tls_t *tls)
-{
- (void)tls;
- return mock_peer_cert;
-}
-
static int
mock_get_tlssecrets(tor_tls_t *tls, uint8_t *secrets_out)
{
@@ -632,6 +1113,7 @@ mock_set_circid_type(channel_t *chan,
}
typedef struct authenticate_data_s {
+ int is_ed;
or_connection_t *c1, *c2;
channel_tls_t *chan2;
var_cell_t *cell;
@@ -647,9 +1129,12 @@ authenticate_data_cleanup(const struct testcase_t *test, void *arg)
UNMOCK(tor_tls_get_tlssecrets);
UNMOCK(connection_or_close_for_error);
UNMOCK(channel_set_circid_type);
+ UNMOCK(tor_tls_export_key_material);
authenticate_data_t *d = arg;
if (d) {
tor_free(d->cell);
+ connection_or_remove_from_identity_map(d->c1);
+ connection_or_remove_from_identity_map(d->c2);
connection_free_(TO_CONN(d->c1));
connection_free_(TO_CONN(d->c2));
circuitmux_free(d->chan2->base_.cmux);
@@ -659,7 +1144,6 @@ authenticate_data_cleanup(const struct testcase_t *test, void *arg)
tor_free(d);
}
mock_peer_cert = NULL;
-
return 1;
}
@@ -667,6 +1151,7 @@ static void *
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);
scheduler_init();
@@ -675,14 +1160,19 @@ authenticate_data_setup(const struct testcase_t *test)
MOCK(tor_tls_get_tlssecrets, mock_get_tlssecrets);
MOCK(connection_or_close_for_error, mock_close_for_err);
MOCK(channel_set_circid_type, mock_set_circid_type);
+ MOCK(tor_tls_export_key_material, mock_export_key_material);
d->c1 = or_connection_new(CONN_TYPE_OR, AF_INET);
d->c2 = or_connection_new(CONN_TYPE_OR, AF_INET);
+ tor_addr_from_ipv4h(&d->c1->base_.addr, 0x01020304);
+ tor_addr_from_ipv4h(&d->c2->base_.addr, 0x05060708);
d->key1 = pk_generate(2);
d->key2 = pk_generate(3);
tt_int_op(tor_tls_context_init(TOR_TLS_CTX_IS_PUBLIC_SERVER,
d->key1, d->key2, 86400), ==, 0);
+ init_mock_ed_keys(d->key2);
+
d->c1->base_.state = OR_CONN_STATE_OR_HANDSHAKING_V3;
d->c1->link_proto = 3;
tt_int_op(connection_init_or_handshake_state(d->c1, 1), ==, 0);
@@ -713,19 +1203,34 @@ authenticate_data_setup(const struct testcase_t *test)
const uint8_t *der;
size_t sz;
tor_x509_cert_get_der(id_cert, &der, &sz);
- d->c1->handshake_state->id_cert = tor_x509_cert_decode(der, sz);
- d->c2->handshake_state->id_cert = tor_x509_cert_decode(der, sz);
+ d->c1->handshake_state->certs->id_cert = tor_x509_cert_decode(der, sz);
+ d->c2->handshake_state->certs->id_cert = tor_x509_cert_decode(der, sz);
+
+ if (is_ed) {
+ d->c1->handshake_state->certs->ed_id_sign =
+ tor_cert_dup(get_master_signing_key_cert());
+ d->c2->handshake_state->certs->ed_id_sign =
+ tor_cert_dup(get_master_signing_key_cert());
+ d->c2->handshake_state->certs->ed_sign_auth =
+ tor_cert_dup(get_current_auth_key_cert());
+ } else {
+ tt_assert(! tor_tls_get_my_certs(0, &auth_cert, &id_cert));
+ tor_x509_cert_get_der(auth_cert, &der, &sz);
+ d->c2->handshake_state->certs->auth_cert = tor_x509_cert_decode(der, sz);
+ }
tor_x509_cert_get_der(link_cert, &der, &sz);
mock_peer_cert = tor_x509_cert_decode(der, sz);
tt_assert(mock_peer_cert);
- tt_assert(! tor_tls_get_my_certs(0, &auth_cert, &id_cert));
- tor_x509_cert_get_der(auth_cert, &der, &sz);
- d->c2->handshake_state->auth_cert = tor_x509_cert_decode(der, sz);
/* Make an authenticate cell ... */
- tt_int_op(0, ==, connection_or_send_authenticate_cell(d->c1,
- AUTHTYPE_RSA_SHA256_TLSSECRET));
+ int authtype;
+ if (is_ed)
+ authtype = AUTHTYPE_ED25519_SHA256_RFC5705;
+ else
+ authtype = AUTHTYPE_RSA_SHA256_TLSSECRET;
+ tt_int_op(0, ==, connection_or_send_authenticate_cell(d->c1, authtype));
+
tt_assert(mock_got_var_cell);
d->cell = mock_got_var_cell;
mock_got_var_cell = NULL;
@@ -751,42 +1256,64 @@ test_link_handshake_auth_cell(void *arg)
/* Is the cell well-formed on the outer layer? */
tt_int_op(d->cell->command, ==, CELL_AUTHENTICATE);
tt_int_op(d->cell->payload[0], ==, 0);
- tt_int_op(d->cell->payload[1], ==, 1);
+ if (d->is_ed)
+ tt_int_op(d->cell->payload[1], ==, 3);
+ else
+ tt_int_op(d->cell->payload[1], ==, 1);
tt_int_op(ntohs(get_uint16(d->cell->payload + 2)), ==,
d->cell->payload_len - 4);
/* Check it out for plausibility... */
auth_ctx_t ctx;
- ctx.is_ed = 0;
+ ctx.is_ed = d->is_ed;
tt_int_op(d->cell->payload_len-4, ==, auth1_parse(&auth1,
d->cell->payload+4,
d->cell->payload_len - 4, &ctx));
tt_assert(auth1);
- tt_mem_op(auth1->type, ==, "AUTH0001", 8);
+ if (d->is_ed) {
+ tt_mem_op(auth1->type, ==, "AUTH0003", 8);
+ } else {
+ tt_mem_op(auth1->type, ==, "AUTH0001", 8);
+ }
tt_mem_op(auth1->tlssecrets, ==, "int getRandomNumber(){return 4;}", 32);
- tt_int_op(auth1_getlen_sig(auth1), >, 120);
/* Is the signature okay? */
- uint8_t sig[128];
- uint8_t digest[32];
-
- auth_pubkey = tor_tls_cert_get_key(d->c2->handshake_state->auth_cert);
- int n = crypto_pk_public_checksig(
+ const uint8_t *start = d->cell->payload+4, *end = auth1->end_of_signed;
+ if (d->is_ed) {
+ ed25519_signature_t sig;
+ tt_int_op(auth1_getlen_sig(auth1), ==, ED25519_SIG_LEN);
+ memcpy(&sig.sig, auth1_getarray_sig(auth1), ED25519_SIG_LEN);
+ tt_assert(!ed25519_checksig(&sig, start, end-start,
+ &get_current_auth_keypair()->pubkey));
+ } else {
+ uint8_t sig[128];
+ uint8_t digest[32];
+ tt_int_op(auth1_getlen_sig(auth1), >, 120);
+ auth_pubkey = tor_tls_cert_get_key(
+ d->c2->handshake_state->certs->auth_cert);
+ int n = crypto_pk_public_checksig(
auth_pubkey,
(char*)sig, sizeof(sig), (char*)auth1_getarray_sig(auth1),
auth1_getlen_sig(auth1));
- tt_int_op(n, ==, 32);
- const uint8_t *start = d->cell->payload+4, *end = auth1->end_of_signed;
- crypto_digest256((char*)digest,
- (const char*)start, end-start, DIGEST_SHA256);
- tt_mem_op(sig, ==, digest, 32);
+ tt_int_op(n, ==, 32);
+ crypto_digest256((char*)digest,
+ (const char*)start, end-start, DIGEST_SHA256);
+ tt_mem_op(sig, ==, digest, 32);
+ }
/* Then feed it to c2. */
tt_int_op(d->c2->handshake_state->authenticated, ==, 0);
channel_tls_process_authenticate_cell(d->cell, d->chan2);
tt_int_op(mock_close_called, ==, 0);
tt_int_op(d->c2->handshake_state->authenticated, ==, 1);
+ if (d->is_ed) {
+ tt_int_op(d->c2->handshake_state->authenticated_ed25519, ==, 1);
+ tt_int_op(d->c2->handshake_state->authenticated_rsa, ==, 1);
+ } else {
+ tt_int_op(d->c2->handshake_state->authenticated_ed25519, ==, 0);
+ tt_int_op(d->c2->handshake_state->authenticated_rsa, ==, 1);
+ }
done:
auth1_free(auth1);
@@ -798,61 +1325,110 @@ test_link_handshake_auth_cell(void *arg)
test_link_handshake_auth_ ## name(void *arg) \
{ \
authenticate_data_t *d = arg; \
+ const char *require_failure_message = NULL; \
+ setup_capture_of_logs(LOG_INFO); \
{ code ; } \
tt_int_op(d->c2->handshake_state->authenticated, ==, 0); \
channel_tls_process_authenticate_cell(d->cell, d->chan2); \
tt_int_op(mock_close_called, ==, 1); \
tt_int_op(d->c2->handshake_state->authenticated, ==, 0); \
- done: \
- ; \
+ if (require_failure_message) { \
+ expect_log_msg_containing(require_failure_message); \
+ } \
+ done: \
+ teardown_capture_of_logs(); \
}
AUTHENTICATE_FAIL(badstate,
+ require_failure_message = "We're not doing a v3 handshake";
d->c2->base_.state = OR_CONN_STATE_CONNECTING)
AUTHENTICATE_FAIL(badproto,
+ require_failure_message = "not using link protocol >= 3";
d->c2->link_proto = 2)
AUTHENTICATE_FAIL(atclient,
- d->c2->handshake_state->started_here = 1)
+ require_failure_message = "We originated this connection";
+ d->c2->handshake_state->started_here = 1;
+ d->c2->handshake_state->certs->started_here = 1;)
AUTHENTICATE_FAIL(duplicate,
+ require_failure_message = "We already got one";
d->c2->handshake_state->received_authenticate = 1)
static void
test_link_handshake_auth_already_authenticated(void *arg)
{
authenticate_data_t *d = arg;
+ setup_capture_of_logs(LOG_INFO);
d->c2->handshake_state->authenticated = 1;
channel_tls_process_authenticate_cell(d->cell, d->chan2);
tt_int_op(mock_close_called, ==, 1);
tt_int_op(d->c2->handshake_state->authenticated, ==, 1);
+ expect_log_msg_containing("The peer is already authenticated");
done:
- ;
+ teardown_capture_of_logs();
}
+
AUTHENTICATE_FAIL(nocerts,
+ require_failure_message = "We never got a certs cell";
d->c2->handshake_state->received_certs_cell = 0)
AUTHENTICATE_FAIL(noidcert,
- tor_x509_cert_free(d->c2->handshake_state->id_cert);
- d->c2->handshake_state->id_cert = NULL)
+ require_failure_message = "We never got an identity "
+ "certificate";
+ tor_x509_cert_free(d->c2->handshake_state->certs->id_cert);
+ d->c2->handshake_state->certs->id_cert = NULL)
AUTHENTICATE_FAIL(noauthcert,
- tor_x509_cert_free(d->c2->handshake_state->auth_cert);
- d->c2->handshake_state->auth_cert = NULL)
+ require_failure_message = "We never got an RSA "
+ "authentication certificate";
+ tor_x509_cert_free(d->c2->handshake_state->certs->auth_cert);
+ d->c2->handshake_state->certs->auth_cert = NULL)
AUTHENTICATE_FAIL(tooshort,
+ require_failure_message = "Cell was way too short";
d->cell->payload_len = 3)
AUTHENTICATE_FAIL(badtype,
+ require_failure_message = "Authenticator type was not "
+ "recognized";
d->cell->payload[0] = 0xff)
AUTHENTICATE_FAIL(truncated_1,
+ require_failure_message = "Authenticator was truncated";
d->cell->payload[2]++)
AUTHENTICATE_FAIL(truncated_2,
+ require_failure_message = "Authenticator was truncated";
d->cell->payload[3]++)
AUTHENTICATE_FAIL(tooshort_1,
+ require_failure_message = "Authenticator was too short";
tt_int_op(d->cell->payload_len, >=, 260);
d->cell->payload[2] -= 1;
d->cell->payload_len -= 256;)
AUTHENTICATE_FAIL(badcontent,
+ require_failure_message = "Some field in the AUTHENTICATE "
+ "cell body was not as expected";
d->cell->payload[10] ^= 0xff)
AUTHENTICATE_FAIL(badsig_1,
+ if (d->is_ed)
+ require_failure_message = "Ed25519 signature wasn't valid";
+ else
+ require_failure_message = "RSA signature wasn't valid";
d->cell->payload[d->cell->payload_len - 5] ^= 0xff)
-
-#define TEST(name, flags) \
- { #name , test_link_handshake_ ## name, (flags), NULL, NULL }
+AUTHENTICATE_FAIL(missing_ed_id,
+ {
+ tor_cert_free(d->c2->handshake_state->certs->ed_id_sign);
+ d->c2->handshake_state->certs->ed_id_sign = NULL;
+ require_failure_message = "Ed authenticate without Ed ID "
+ "cert from peer";
+ })
+AUTHENTICATE_FAIL(missing_ed_auth,
+ {
+ tor_cert_free(d->c2->handshake_state->certs->ed_sign_auth);
+ d->c2->handshake_state->certs->ed_sign_auth = NULL;
+ require_failure_message = "We never got an Ed25519 "
+ "authentication certificate";
+ })
+
+#define TEST_RSA(name, flags) \
+ { #name , test_link_handshake_ ## name, (flags), \
+ &passthrough_setup, (void*)"RSA" }
+
+#define TEST_ED(name, flags) \
+ { #name "_ed25519" , test_link_handshake_ ## name, (flags), \
+ &passthrough_setup, (void*)"Ed25519" }
#define TEST_RCV_AUTHCHALLENGE(name) \
{ "recv_authchallenge/" #name , \
@@ -862,17 +1438,34 @@ AUTHENTICATE_FAIL(badsig_1,
#define TEST_RCV_CERTS(name) \
{ "recv_certs/" #name , \
test_link_handshake_recv_certs_ ## name, TT_FORK, \
- &setup_recv_certs, NULL }
+ &setup_recv_certs, (void*)"RSA-Link" }
+
+#define TEST_RCV_CERTS_RSA(name,type) \
+ { "recv_certs/" #name , \
+ test_link_handshake_recv_certs_ ## name, TT_FORK, \
+ &setup_recv_certs, (void*)type }
+
+#define TEST_RCV_CERTS_ED(name, type) \
+ { "recv_certs/" #name "_ed25519", \
+ test_link_handshake_recv_certs_ ## name, TT_FORK, \
+ &setup_recv_certs, (void*)type }
#define TEST_AUTHENTICATE(name) \
{ "authenticate/" #name , test_link_handshake_auth_ ## name, TT_FORK, \
&setup_authenticate, NULL }
+#define TEST_AUTHENTICATE_ED(name) \
+ { "authenticate/" #name "_ed25519" , test_link_handshake_auth_ ## name, \
+ TT_FORK, &setup_authenticate, (void*)3 }
+
struct testcase_t link_handshake_tests[] = {
- TEST(certs_ok, TT_FORK),
- //TEST(certs_bad, TT_FORK),
+ TEST_RSA(certs_ok, TT_FORK),
+ TEST_ED(certs_ok, TT_FORK),
+
TEST_RCV_CERTS(ok),
- TEST_RCV_CERTS(ok_server),
+ TEST_RCV_CERTS_ED(ok, "Ed25519-Link"),
+ TEST_RCV_CERTS_RSA(ok_server, "RSA-Auth"),
+ TEST_RCV_CERTS_ED(ok_server, "Ed25519-Auth"),
TEST_RCV_CERTS(badstate),
TEST_RCV_CERTS(badproto),
TEST_RCV_CERTS(duplicate),
@@ -882,18 +1475,41 @@ struct testcase_t link_handshake_tests[] = {
TEST_RCV_CERTS(truncated_1),
TEST_RCV_CERTS(truncated_2),
TEST_RCV_CERTS(truncated_3),
+ TEST_RCV_CERTS_ED(truncated_4, "Ed25519-Link"),
+ TEST_RCV_CERTS_ED(truncated_5, "Ed25519-Link"),
+ TEST_RCV_CERTS_ED(truncated_6, "Ed25519-Link"),
+ TEST_RCV_CERTS_ED(truncated_7, "Ed25519-Link"),
TEST_RCV_CERTS(not_x509),
TEST_RCV_CERTS(both_link),
TEST_RCV_CERTS(both_id_rsa),
TEST_RCV_CERTS(both_auth),
+ TEST_RCV_CERTS_ED(duplicate_id, "Ed25519-Link"),
+ TEST_RCV_CERTS_ED(duplicate_link, "Ed25519-Link"),
+ TEST_RCV_CERTS_ED(duplicate_crosscert, "Ed25519-Link"),
+ TEST_RCV_CERTS_ED(missing_crosscert, "Ed25519-Link"),
+ TEST_RCV_CERTS_ED(missing_id, "Ed25519-Link"),
+ TEST_RCV_CERTS_ED(missing_signing_key, "Ed25519-Link"),
+ TEST_RCV_CERTS_ED(missing_link, "Ed25519-Link"),
+ TEST_RCV_CERTS_ED(missing_auth, "Ed25519-Auth"),
+ TEST_RCV_CERTS_ED(missing_rsa_id, "Ed25519-Link"),
+ TEST_RCV_CERTS_ED(link_mismatch, "Ed25519-Link"),
+ TEST_RCV_CERTS_ED(bad_ed_sig, "Ed25519-Link"),
+ TEST_RCV_CERTS_ED(bad_rsa_id_cert, "Ed25519-Link"),
+ TEST_RCV_CERTS_ED(bad_crosscert, "Ed25519-Link"),
+ TEST_RCV_CERTS_RSA(expired_rsa_id, "RSA-Link"),
+ TEST_RCV_CERTS_ED(expired_rsa_id, "Ed25519-Link"),
+ TEST_RCV_CERTS_ED(expired_ed_id, "Ed25519-Link"),
+ TEST_RCV_CERTS_ED(expired_ed_link, "Ed25519-Link"),
+ TEST_RCV_CERTS_ED(expired_crosscert, "Ed25519-Link"),
TEST_RCV_CERTS(wrong_labels_1),
TEST_RCV_CERTS(wrong_labels_2),
TEST_RCV_CERTS(wrong_labels_3),
TEST_RCV_CERTS(server_missing_certs),
TEST_RCV_CERTS(server_wrong_labels_1),
- TEST(send_authchallenge, TT_FORK),
+ TEST_RSA(send_authchallenge, TT_FORK),
TEST_RCV_AUTHCHALLENGE(ok),
+ TEST_RCV_AUTHCHALLENGE(ok_ed25519),
TEST_RCV_AUTHCHALLENGE(ok_noserver),
TEST_RCV_AUTHCHALLENGE(ok_unrecognized),
TEST_RCV_AUTHCHALLENGE(badstate),
@@ -906,6 +1522,7 @@ struct testcase_t link_handshake_tests[] = {
TEST_RCV_AUTHCHALLENGE(nonzero_circid),
TEST_AUTHENTICATE(cell),
+ TEST_AUTHENTICATE_ED(cell),
TEST_AUTHENTICATE(badstate),
TEST_AUTHENTICATE(badproto),
TEST_AUTHENTICATE(atclient),
@@ -921,6 +1538,9 @@ struct testcase_t link_handshake_tests[] = {
TEST_AUTHENTICATE(tooshort_1),
TEST_AUTHENTICATE(badcontent),
TEST_AUTHENTICATE(badsig_1),
+ TEST_AUTHENTICATE_ED(badsig_1),
+ TEST_AUTHENTICATE_ED(missing_ed_id),
+ TEST_AUTHENTICATE_ED(missing_ed_auth),
//TEST_AUTHENTICATE(),
END_OF_TESTCASES
diff --git a/src/test/test_options.c b/src/test/test_options.c
index 87f896607a..0eada98cb2 100644
--- a/src/test/test_options.c
+++ b/src/test/test_options.c
@@ -394,14 +394,6 @@ free_options_test_data(options_test_data_t *td)
tor_free(td);
}
-#define expect_log_msg(str) \
- tt_assert_msg(mock_saved_log_has_message(str), \
- "expected log to contain " # str);
-
-#define expect_no_log_msg(str) \
- tt_assert_msg(!mock_saved_log_has_message(str), \
- "expected log to not contain " # str);
-
static void
test_options_validate__uname_for_server(void *ignored)
{
@@ -409,7 +401,7 @@ test_options_validate__uname_for_server(void *ignored)
char *msg;
options_test_data_t *tdata = get_options_test_data(
"ORListenAddress 127.0.0.1:5555");
- int previous_log = setup_capture_of_logs(LOG_WARN);
+ setup_capture_of_logs(LOG_WARN);
MOCK(get_uname, fixed_get_uname);
fixed_get_uname_result = "Windows 95";
@@ -445,7 +437,7 @@ test_options_validate__uname_for_server(void *ignored)
UNMOCK(get_uname);
free_options_test_data(tdata);
tor_free(msg);
- teardown_capture_of_logs(previous_log);
+ teardown_capture_of_logs();
}
static void
@@ -543,7 +535,7 @@ test_options_validate__contactinfo(void *ignored)
char *msg;
options_test_data_t *tdata = get_options_test_data(
"ORListenAddress 127.0.0.1:5555\nORPort 955");
- int previous_log = setup_capture_of_logs(LOG_DEBUG);
+ setup_capture_of_logs(LOG_DEBUG);
tdata->opt->ContactInfo = NULL;
ret = options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg);
@@ -567,7 +559,7 @@ test_options_validate__contactinfo(void *ignored)
tor_free(msg);
done:
- teardown_capture_of_logs(previous_log);
+ teardown_capture_of_logs();
free_options_test_data(tdata);
tor_free(msg);
}
@@ -655,7 +647,7 @@ test_options_validate__authdir(void *ignored)
(void)ignored;
int ret;
char *msg;
- int previous_log = setup_capture_of_logs(LOG_INFO);
+ setup_capture_of_logs(LOG_INFO);
options_test_data_t *tdata = get_options_test_data(
"AuthoritativeDirectory 1\n"
"Address this.should.not_exist.example.org");
@@ -948,7 +940,7 @@ test_options_validate__authdir(void *ignored)
/* "but ClientOnly also set."); */
done:
- teardown_capture_of_logs(previous_log);
+ teardown_capture_of_logs();
// sandbox_free_getaddrinfo_cache();
free_options_test_data(tdata);
tor_free(msg);
@@ -959,7 +951,7 @@ test_options_validate__relay_with_hidden_services(void *ignored)
{
(void)ignored;
char *msg;
- int previous_log = setup_capture_of_logs(LOG_DEBUG);
+ setup_capture_of_logs(LOG_DEBUG);
options_test_data_t *tdata = get_options_test_data(
"ORListenAddress 127.0.0.1:5555\n"
"ORPort 955\n"
@@ -976,7 +968,7 @@ test_options_validate__relay_with_hidden_services(void *ignored)
"https://trac.torproject.org/8742\n");
done:
- teardown_capture_of_logs(previous_log);
+ teardown_capture_of_logs();
free_options_test_data(tdata);
tor_free(msg);
}
@@ -989,7 +981,7 @@ test_options_validate__relay_with_hidden_services(void *ignored)
/* (void)ignored; */
/* int ret; */
/* char *msg; */
-/* int previous_log = setup_capture_of_logs(LOG_WARN); */
+/* setup_capture_of_logs(LOG_WARN); */
/* options_test_data_t *tdata = get_options_test_data(""); */
/* ret = options_validate(tdata->old_opt, tdata->opt, */
/* tdata->def_opt, 0, &msg); */
@@ -998,7 +990,7 @@ test_options_validate__relay_with_hidden_services(void *ignored)
/* "configured. " */
/* " Tor will still run, but probably won't do anything.\n"); */
/* done: */
-/* teardown_capture_of_logs(previous_log); */
+/* teardown_capture_of_logs(); */
/* free_options_test_data(tdata); */
/* tor_free(msg); */
/* } */
@@ -1086,7 +1078,7 @@ test_options_validate__transproxy(void *ignored)
tt_int_op(ret, OP_EQ, -1);
tt_assert(!msg);
#endif
-#if defined(__FreeBSD_kernel__) || defined( DARWIN )
+#if defined(__FreeBSD_kernel__) || defined( DARWIN ) || defined(__NetBSD__)
tdata = get_options_test_data("TransProxyType ipfw\n"
"TransPort 127.0.0.1:123\n");
ret = options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg);
@@ -1139,7 +1131,7 @@ test_options_validate__exclude_nodes(void *ignored)
int ret;
char *msg;
- int previous_log = setup_capture_of_logs(LOG_WARN);
+ setup_capture_of_logs(LOG_WARN);
options_test_data_t *tdata = get_options_test_data(
"ExcludeExitNodes {us}\n");
@@ -1204,7 +1196,7 @@ test_options_validate__exclude_nodes(void *ignored)
done:
NS_UNMOCK(geoip_get_country);
- teardown_capture_of_logs(previous_log);
+ teardown_capture_of_logs();
free_options_test_data(tdata);
tor_free(msg);
}
@@ -1215,7 +1207,7 @@ test_options_validate__scheduler(void *ignored)
(void)ignored;
int ret;
char *msg;
- int previous_log = setup_capture_of_logs(LOG_DEBUG);
+ setup_capture_of_logs(LOG_DEBUG);
options_test_data_t *tdata = get_options_test_data(
"SchedulerLowWaterMark__ 0\n");
@@ -1247,7 +1239,7 @@ test_options_validate__scheduler(void *ignored)
tor_free(msg);
done:
- teardown_capture_of_logs(previous_log);
+ teardown_capture_of_logs();
free_options_test_data(tdata);
tor_free(msg);
}
@@ -1310,7 +1302,7 @@ test_options_validate__tlsec(void *ignored)
(void)ignored;
int ret;
char *msg;
- int previous_log = setup_capture_of_logs(LOG_DEBUG);
+ setup_capture_of_logs(LOG_DEBUG);
options_test_data_t *tdata = get_options_test_data(
"TLSECGroup ed25519\n"
"SchedulerHighWaterMark__ 42\n"
@@ -1347,7 +1339,7 @@ test_options_validate__tlsec(void *ignored)
tor_free(msg);
done:
- teardown_capture_of_logs(previous_log);
+ teardown_capture_of_logs();
free_options_test_data(tdata);
tor_free(msg);
}
@@ -1385,7 +1377,7 @@ test_options_validate__recommended_packages(void *ignored)
(void)ignored;
int ret;
char *msg;
- int previous_log = setup_capture_of_logs(LOG_WARN);
+ setup_capture_of_logs(LOG_WARN);
options_test_data_t *tdata = get_options_test_data(
"RecommendedPackages foo 1.2 http://foo.com sha1=123123123123\n"
"RecommendedPackages invalid-package-line\n"
@@ -1399,7 +1391,7 @@ test_options_validate__recommended_packages(void *ignored)
done:
escaped(NULL); // This will free the leaking memory from the previous escaped
- teardown_capture_of_logs(previous_log);
+ teardown_capture_of_logs();
free_options_test_data(tdata);
tor_free(msg);
}
@@ -1477,7 +1469,7 @@ test_options_validate__paths_needed(void *ignored)
(void)ignored;
int ret;
char *msg;
- int previous_log = setup_capture_of_logs(LOG_WARN);
+ setup_capture_of_logs(LOG_WARN);
options_test_data_t *tdata = get_options_test_data(
"PathsNeededToBuildCircuits 0.1\n"
"ConnLimit 1\n"
@@ -1522,7 +1514,7 @@ test_options_validate__paths_needed(void *ignored)
tor_free(msg);
done:
- teardown_capture_of_logs(previous_log);
+ teardown_capture_of_logs();
free_options_test_data(tdata);
tor_free(msg);
}
@@ -1659,7 +1651,7 @@ test_options_validate__reachable_addresses(void *ignored)
(void)ignored;
int ret;
char *msg;
- int previous_log = setup_capture_of_logs(LOG_NOTICE);
+ setup_capture_of_logs(LOG_NOTICE);
options_test_data_t *tdata = get_options_test_data(
"FascistFirewall 1\n"
"MaxClientCircuitsPending 1\n"
@@ -1873,7 +1865,7 @@ test_options_validate__reachable_addresses(void *ignored)
tt_ptr_op(msg, OP_EQ, NULL);
done:
- teardown_capture_of_logs(previous_log);
+ teardown_capture_of_logs();
free_options_test_data(tdata);
tor_free(msg);
}
@@ -2123,7 +2115,7 @@ test_options_validate__publish_server_descriptor(void *ignored)
(void)ignored;
int ret;
char *msg;
- int previous_log = setup_capture_of_logs(LOG_WARN);
+ setup_capture_of_logs(LOG_WARN);
options_test_data_t *tdata = get_options_test_data(
"PublishServerDescriptor bridge\n" TEST_OPTIONS_DEFAULT_VALUES
);
@@ -2187,7 +2179,7 @@ test_options_validate__publish_server_descriptor(void *ignored)
tt_assert(!tdata->opt->DirPort_set);
done:
- teardown_capture_of_logs(previous_log);
+ teardown_capture_of_logs();
policies_free_all();
free_options_test_data(tdata);
tor_free(msg);
@@ -2274,7 +2266,7 @@ test_options_validate__hidserv(void *ignored)
(void)ignored;
int ret;
char *msg;
- int previous_log = setup_capture_of_logs(LOG_WARN);
+ setup_capture_of_logs(LOG_WARN);
options_test_data_t *tdata = get_options_test_data(
TEST_OPTIONS_DEFAULT_VALUES);
@@ -2309,7 +2301,7 @@ test_options_validate__hidserv(void *ignored)
tor_free(msg);
done:
- teardown_capture_of_logs(previous_log);
+ teardown_capture_of_logs();
policies_free_all();
free_options_test_data(tdata);
tor_free(msg);
@@ -2321,7 +2313,7 @@ test_options_validate__predicted_ports(void *ignored)
(void)ignored;
int ret;
char *msg;
- int previous_log = setup_capture_of_logs(LOG_WARN);
+ setup_capture_of_logs(LOG_WARN);
options_test_data_t *tdata = get_options_test_data(
"PredictedPortsRelevanceTime 100000000\n"
@@ -2333,7 +2325,7 @@ test_options_validate__predicted_ports(void *ignored)
tt_int_op(tdata->opt->PredictedPortsRelevanceTime, OP_EQ, 3600);
done:
- teardown_capture_of_logs(previous_log);
+ teardown_capture_of_logs();
policies_free_all();
free_options_test_data(tdata);
tor_free(msg);
@@ -2547,7 +2539,7 @@ test_options_validate__circuits(void *ignored)
(void)ignored;
char *msg;
options_test_data_t *tdata = NULL;
- int previous_log = setup_capture_of_logs(LOG_WARN);
+ setup_capture_of_logs(LOG_WARN);
free_options_test_data(tdata);
tdata = get_options_test_data(TEST_OPTIONS_DEFAULT_VALUES
@@ -2624,7 +2616,7 @@ test_options_validate__circuits(void *ignored)
done:
policies_free_all();
- teardown_capture_of_logs(previous_log);
+ teardown_capture_of_logs();
free_options_test_data(tdata);
tor_free(msg);
}
@@ -2697,7 +2689,7 @@ test_options_validate__rend(void *ignored)
int ret;
char *msg;
options_test_data_t *tdata = NULL;
- int previous_log = setup_capture_of_logs(LOG_WARN);
+ setup_capture_of_logs(LOG_WARN);
free_options_test_data(tdata);
tdata = get_options_test_data(TEST_OPTIONS_DEFAULT_VALUES
@@ -2752,7 +2744,156 @@ test_options_validate__rend(void *ignored)
done:
policies_free_all();
- teardown_capture_of_logs(previous_log);
+ teardown_capture_of_logs();
+ free_options_test_data(tdata);
+ tor_free(msg);
+}
+
+static void
+test_options_validate__single_onion(void *ignored)
+{
+ (void)ignored;
+ int ret;
+ char *msg;
+ options_test_data_t *tdata = NULL;
+ setup_capture_of_logs(LOG_WARN);
+
+ /* Test that HiddenServiceSingleHopMode must come with
+ * HiddenServiceNonAnonymousMode */
+ tdata = get_options_test_data(TEST_OPTIONS_DEFAULT_VALUES
+ "SOCKSPort 0\n"
+ "HiddenServiceSingleHopMode 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, "HiddenServiceSingleHopMode does not provide any "
+ "server anonymity. It must be used with "
+ "HiddenServiceNonAnonymousMode set to 1.");
+ tor_free(msg);
+ free_options_test_data(tdata);
+
+ tdata = get_options_test_data(TEST_OPTIONS_DEFAULT_VALUES
+ "SOCKSPort 0\n"
+ "HiddenServiceSingleHopMode 1\n"
+ "HiddenServiceNonAnonymousMode 0\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, "HiddenServiceSingleHopMode does not provide any "
+ "server anonymity. It must be used with "
+ "HiddenServiceNonAnonymousMode set to 1.");
+ tor_free(msg);
+ free_options_test_data(tdata);
+
+ tdata = get_options_test_data(TEST_OPTIONS_DEFAULT_VALUES
+ "SOCKSPort 0\n"
+ "HiddenServiceSingleHopMode 1\n"
+ "HiddenServiceNonAnonymousMode 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 SOCKSPort must come with Tor2webMode 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);
+ tt_str_op(msg, OP_EQ, "HiddenServiceNonAnonymousMode is incompatible with "
+ "using Tor as an anonymous client. Please set "
+ "Socks/Trans/NATD/DNSPort to 0, or HiddenServiceNonAnonymousMode "
+ "to 0, or use the non-anonymous Tor2webMode.");
+ tor_free(msg);
+ free_options_test_data(tdata);
+
+ tdata = get_options_test_data(TEST_OPTIONS_DEFAULT_VALUES
+ "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);
+ 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 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 */
+ tdata = get_options_test_data(TEST_OPTIONS_DEFAULT_VALUES
+ "HiddenServiceNonAnonymousMode 1\n"
+ "HiddenServiceDir /Library/Tor/var/lib/tor/hidden_service/\n"
+ "HiddenServicePort 80 127.0.0.1:8080\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, "HiddenServiceNonAnonymousMode does not provide any "
+ "server anonymity. It must be used with "
+ "HiddenServiceSingleHopMode set to 1.");
+ tor_free(msg);
+ free_options_test_data(tdata);
+
+ tdata = get_options_test_data(TEST_OPTIONS_DEFAULT_VALUES
+ "HiddenServiceNonAnonymousMode 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, "HiddenServiceNonAnonymousMode does not provide any "
+ "server anonymity. It must be used with "
+ "HiddenServiceSingleHopMode set to 1.");
+ tor_free(msg);
+ free_options_test_data(tdata);
+
+ tdata = get_options_test_data(TEST_OPTIONS_DEFAULT_VALUES
+ "HiddenServiceDir /Library/Tor/var/lib/tor/hidden_service/\n"
+ "HiddenServicePort 80 127.0.0.1:8080\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
+ "HiddenServiceNonAnonymousMode 1\n"
+ "HiddenServiceDir /Library/Tor/var/lib/tor/hidden_service/\n"
+ "HiddenServicePort 80 127.0.0.1:8080\n"
+ "HiddenServiceSingleHopMode 1\n"
+ "SOCKSPort 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);
+
+ done:
+ policies_free_all();
+ teardown_capture_of_logs();
free_options_test_data(tdata);
tor_free(msg);
}
@@ -2764,7 +2905,7 @@ test_options_validate__accounting(void *ignored)
int ret;
char *msg;
options_test_data_t *tdata = NULL;
- int previous_log = setup_capture_of_logs(LOG_WARN);
+ setup_capture_of_logs(LOG_WARN);
free_options_test_data(tdata);
tdata = get_options_test_data(TEST_OPTIONS_DEFAULT_VALUES
@@ -2869,7 +3010,7 @@ test_options_validate__accounting(void *ignored)
tor_free(msg);
done:
- teardown_capture_of_logs(previous_log);
+ teardown_capture_of_logs();
policies_free_all();
free_options_test_data(tdata);
tor_free(msg);
@@ -2883,7 +3024,7 @@ test_options_validate__proxy(void *ignored)
char *msg;
options_test_data_t *tdata = NULL;
sandbox_disable_getaddrinfo_cache();
- int previous_log = setup_capture_of_logs(LOG_WARN);
+ setup_capture_of_logs(LOG_WARN);
free_options_test_data(tdata);
tdata = get_options_test_data(TEST_OPTIONS_DEFAULT_VALUES
@@ -3199,7 +3340,7 @@ test_options_validate__proxy(void *ignored)
tor_free(msg);
done:
- teardown_capture_of_logs(previous_log);
+ teardown_capture_of_logs();
free_options_test_data(tdata);
policies_free_all();
// sandbox_free_getaddrinfo_cache();
@@ -3213,7 +3354,7 @@ test_options_validate__control(void *ignored)
int ret;
char *msg;
options_test_data_t *tdata = NULL;
- int previous_log = setup_capture_of_logs(LOG_WARN);
+ setup_capture_of_logs(LOG_WARN);
free_options_test_data(tdata);
tdata = get_options_test_data(TEST_OPTIONS_DEFAULT_VALUES
@@ -3427,7 +3568,7 @@ test_options_validate__control(void *ignored)
tor_free(msg);
done:
- teardown_capture_of_logs(previous_log);
+ teardown_capture_of_logs();
policies_free_all();
free_options_test_data(tdata);
tor_free(msg);
@@ -3440,7 +3581,7 @@ test_options_validate__families(void *ignored)
int ret;
char *msg;
options_test_data_t *tdata = NULL;
- int previous_log = setup_capture_of_logs(LOG_WARN);
+ setup_capture_of_logs(LOG_WARN);
free_options_test_data(tdata);
tdata = get_options_test_data(TEST_OPTIONS_DEFAULT_VALUES
@@ -3499,7 +3640,7 @@ test_options_validate__families(void *ignored)
tor_free(msg);
done:
- teardown_capture_of_logs(previous_log);
+ teardown_capture_of_logs();
policies_free_all();
free_options_test_data(tdata);
tor_free(msg);
@@ -3536,7 +3677,7 @@ test_options_validate__dir_auth(void *ignored)
int ret;
char *msg;
options_test_data_t *tdata = NULL;
- int previous_log = setup_capture_of_logs(LOG_WARN);
+ setup_capture_of_logs(LOG_WARN);
free_options_test_data(tdata);
tdata = get_options_test_data(TEST_OPTIONS_DEFAULT_VALUES
@@ -3611,7 +3752,7 @@ test_options_validate__dir_auth(void *ignored)
done:
policies_free_all();
- teardown_capture_of_logs(previous_log);
+ teardown_capture_of_logs();
free_options_test_data(tdata);
tor_free(msg);
}
@@ -3623,7 +3764,7 @@ test_options_validate__transport(void *ignored)
int ret;
char *msg;
options_test_data_t *tdata = NULL;
- int previous_log = setup_capture_of_logs(LOG_NOTICE);
+ setup_capture_of_logs(LOG_NOTICE);
free_options_test_data(tdata);
tdata = get_options_test_data(TEST_OPTIONS_DEFAULT_VALUES
@@ -3736,7 +3877,7 @@ test_options_validate__transport(void *ignored)
done:
escaped(NULL); // This will free the leaking memory from the previous escaped
policies_free_all();
- teardown_capture_of_logs(previous_log);
+ teardown_capture_of_logs();
free_options_test_data(tdata);
tor_free(msg);
}
@@ -3748,7 +3889,7 @@ test_options_validate__constrained_sockets(void *ignored)
int ret;
char *msg;
options_test_data_t *tdata = NULL;
- int previous_log = setup_capture_of_logs(LOG_WARN);
+ setup_capture_of_logs(LOG_WARN);
free_options_test_data(tdata);
tdata = get_options_test_data(TEST_OPTIONS_DEFAULT_VALUES
@@ -3819,7 +3960,7 @@ test_options_validate__constrained_sockets(void *ignored)
done:
policies_free_all();
- teardown_capture_of_logs(previous_log);
+ teardown_capture_of_logs();
free_options_test_data(tdata);
tor_free(msg);
}
@@ -3831,7 +3972,7 @@ test_options_validate__v3_auth(void *ignored)
int ret;
char *msg;
options_test_data_t *tdata = NULL;
- int previous_log = setup_capture_of_logs(LOG_WARN);
+ setup_capture_of_logs(LOG_WARN);
free_options_test_data(tdata);
tdata = get_options_test_data(TEST_OPTIONS_DEFAULT_VALUES
@@ -4038,7 +4179,7 @@ test_options_validate__v3_auth(void *ignored)
done:
policies_free_all();
- teardown_capture_of_logs(previous_log);
+ teardown_capture_of_logs();
free_options_test_data(tdata);
tor_free(msg);
}
@@ -4083,7 +4224,7 @@ test_options_validate__exits(void *ignored)
int ret;
char *msg;
options_test_data_t *tdata = NULL;
- int previous_log = setup_capture_of_logs(LOG_WARN);
+ setup_capture_of_logs(LOG_WARN);
free_options_test_data(tdata);
tdata = get_options_test_data(TEST_OPTIONS_DEFAULT_VALUES
@@ -4113,7 +4254,7 @@ test_options_validate__exits(void *ignored)
done:
policies_free_all();
- teardown_capture_of_logs(previous_log);
+ teardown_capture_of_logs();
free_options_test_data(tdata);
tor_free(msg);
}
@@ -4125,7 +4266,7 @@ test_options_validate__testing_options(void *ignored)
int ret;
char *msg;
options_test_data_t *tdata = NULL;
- int previous_log = setup_capture_of_logs(LOG_WARN);
+ setup_capture_of_logs(LOG_WARN);
#define TEST_TESTING_OPTION(name, low_val, high_val, err_low) \
STMT_BEGIN \
@@ -4281,7 +4422,7 @@ test_options_validate__testing_options(void *ignored)
done:
policies_free_all();
- teardown_capture_of_logs(previous_log);
+ teardown_capture_of_logs();
free_options_test_data(tdata);
tor_free(msg);
}
@@ -4379,6 +4520,7 @@ struct testcase_t options_tests[] = {
LOCAL_VALIDATE_TEST(port_forwarding),
LOCAL_VALIDATE_TEST(tor2web),
LOCAL_VALIDATE_TEST(rend),
+ LOCAL_VALIDATE_TEST(single_onion),
LOCAL_VALIDATE_TEST(accounting),
LOCAL_VALIDATE_TEST(proxy),
LOCAL_VALIDATE_TEST(control),
diff --git a/src/test/test_policy.c b/src/test/test_policy.c
index 0d4a3b104f..b89de01b7b 100644
--- a/src/test/test_policy.c
+++ b/src/test/test_policy.c
@@ -525,10 +525,10 @@ test_policies_general(void *arg)
{
char *policy_strng = NULL;
smartlist_t *chunks = smartlist_new();
- smartlist_add(chunks, tor_strdup("accept "));
+ smartlist_add_strdup(chunks, "accept ");
for (i=1; i<10000; ++i)
smartlist_add_asprintf(chunks, "%d,", i);
- smartlist_add(chunks, tor_strdup("20000"));
+ smartlist_add_strdup(chunks, "20000");
policy_strng = smartlist_join_strings(chunks, "", 0, NULL);
SMARTLIST_FOREACH(chunks, char *, ch, tor_free(ch));
smartlist_free(chunks);
@@ -542,9 +542,9 @@ test_policies_general(void *arg)
for (i=1; i<2000; i+=2) {
char buf[POLICY_BUF_LEN];
tor_snprintf(buf, sizeof(buf), "reject *:%d", i);
- smartlist_add(sm, tor_strdup(buf));
+ smartlist_add_strdup(sm, buf);
}
- smartlist_add(sm, tor_strdup("accept *:*"));
+ smartlist_add_strdup(sm, "accept *:*");
policy_str = smartlist_join_strings(sm, ",", 0, NULL);
test_policy_summary_helper( policy_str,
"accept 2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,"
diff --git a/src/test/test_protover.c b/src/test/test_protover.c
new file mode 100644
index 0000000000..f00955d1b4
--- /dev/null
+++ b/src/test/test_protover.c
@@ -0,0 +1,195 @@
+/* Copyright (c) 2016, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#define PROTOVER_PRIVATE
+
+#include "orconfig.h"
+#include "test.h"
+
+#include "protover.h"
+
+static void
+test_protover_parse(void *arg)
+{
+ (void) arg;
+ char *re_encoded = NULL;
+
+ const char *orig = "Foo=1,3 Bar=3 Baz= Quux=9-12,14,15-16,900";
+ smartlist_t *elts = parse_protocol_list(orig);
+
+ tt_assert(elts);
+ tt_int_op(smartlist_len(elts), OP_EQ, 4);
+
+ const proto_entry_t *e;
+ const proto_range_t *r;
+ e = smartlist_get(elts, 0);
+ tt_str_op(e->name, OP_EQ, "Foo");
+ tt_int_op(smartlist_len(e->ranges), OP_EQ, 2);
+ {
+ r = smartlist_get(e->ranges, 0);
+ tt_int_op(r->low, OP_EQ, 1);
+ tt_int_op(r->high, OP_EQ, 1);
+
+ r = smartlist_get(e->ranges, 1);
+ tt_int_op(r->low, OP_EQ, 3);
+ tt_int_op(r->high, OP_EQ, 3);
+ }
+
+ e = smartlist_get(elts, 1);
+ tt_str_op(e->name, OP_EQ, "Bar");
+ tt_int_op(smartlist_len(e->ranges), OP_EQ, 1);
+ {
+ r = smartlist_get(e->ranges, 0);
+ tt_int_op(r->low, OP_EQ, 3);
+ tt_int_op(r->high, OP_EQ, 3);
+ }
+
+ e = smartlist_get(elts, 2);
+ tt_str_op(e->name, OP_EQ, "Baz");
+ tt_int_op(smartlist_len(e->ranges), OP_EQ, 0);
+
+ e = smartlist_get(elts, 3);
+ tt_str_op(e->name, OP_EQ, "Quux");
+ tt_int_op(smartlist_len(e->ranges), OP_EQ, 4);
+ {
+ r = smartlist_get(e->ranges, 0);
+ tt_int_op(r->low, OP_EQ, 9);
+ tt_int_op(r->high, OP_EQ, 12);
+
+ r = smartlist_get(e->ranges, 1);
+ tt_int_op(r->low, OP_EQ, 14);
+ tt_int_op(r->high, OP_EQ, 14);
+
+ r = smartlist_get(e->ranges, 2);
+ tt_int_op(r->low, OP_EQ, 15);
+ tt_int_op(r->high, OP_EQ, 16);
+
+ r = smartlist_get(e->ranges, 3);
+ tt_int_op(r->low, OP_EQ, 900);
+ tt_int_op(r->high, OP_EQ, 900);
+ }
+
+ re_encoded = encode_protocol_list(elts);
+ tt_assert(re_encoded);
+ tt_str_op(re_encoded, OP_EQ, orig);
+
+ done:
+ if (elts)
+ SMARTLIST_FOREACH(elts, proto_entry_t *, ent, proto_entry_free(ent));
+ smartlist_free(elts);
+ tor_free(re_encoded);
+}
+
+static void
+test_protover_parse_fail(void *arg)
+{
+ (void)arg;
+ smartlist_t *elts;
+
+ /* random junk */
+ elts = parse_protocol_list("!!3@*");
+ tt_assert(elts == NULL);
+
+ /* Missing equals sign in an entry */
+ elts = parse_protocol_list("Link=4 Haprauxymatyve Desc=9");
+ tt_assert(elts == NULL);
+
+ /* Missing word. */
+ elts = parse_protocol_list("Link=4 =3 Desc=9");
+ tt_assert(elts == NULL);
+
+ /* Broken numbers */
+ elts = parse_protocol_list("Link=fred");
+ tt_assert(elts == NULL);
+ elts = parse_protocol_list("Link=1,fred");
+ tt_assert(elts == NULL);
+ elts = parse_protocol_list("Link=1,fred,3");
+ tt_assert(elts == NULL);
+
+ /* Broken range */
+ elts = parse_protocol_list("Link=1,9-8,3");
+ tt_assert(elts == NULL);
+
+ done:
+ ;
+}
+
+static void
+test_protover_vote(void *arg)
+{
+ (void) arg;
+
+ smartlist_t *lst = smartlist_new();
+ char *result = protover_compute_vote(lst, 1);
+
+ tt_str_op(result, OP_EQ, "");
+ tor_free(result);
+
+ smartlist_add(lst, (void*) "Foo=1-10,500 Bar=1,3-7,8");
+ result = protover_compute_vote(lst, 1);
+ tt_str_op(result, OP_EQ, "Bar=1,3-8 Foo=1-10,500");
+ tor_free(result);
+
+ smartlist_add(lst, (void*) "Quux=123-456,78 Bar=2-6,8 Foo=9");
+ result = protover_compute_vote(lst, 1);
+ tt_str_op(result, OP_EQ, "Bar=1-8 Foo=1-10,500 Quux=78,123-456");
+ tor_free(result);
+
+ result = protover_compute_vote(lst, 2);
+ tt_str_op(result, OP_EQ, "Bar=3-6,8 Foo=9");
+ tor_free(result);
+
+ done:
+ tor_free(result);
+ smartlist_free(lst);
+}
+
+static void
+test_protover_all_supported(void *arg)
+{
+ (void)arg;
+ char *msg = NULL;
+
+ tt_assert(protover_all_supported(NULL, &msg));
+ tt_assert(msg == NULL);
+
+ tt_assert(protover_all_supported("", &msg));
+ tt_assert(msg == NULL);
+
+ // Some things that we do support
+ tt_assert(protover_all_supported("Link=3-4", &msg));
+ tt_assert(msg == NULL);
+ tt_assert(protover_all_supported("Link=3-4 Desc=2", &msg));
+ tt_assert(msg == NULL);
+
+ // Some things we don't support
+ tt_assert(! protover_all_supported("Wombat=9", &msg));
+ tt_str_op(msg, OP_EQ, "Wombat=9");
+ tor_free(msg);
+ tt_assert(! protover_all_supported("Link=999", &msg));
+ tt_str_op(msg, OP_EQ, "Link=999");
+ tor_free(msg);
+
+ // Mix of things we support and things we don't
+ tt_assert(! protover_all_supported("Link=3-4 Wombat=9", &msg));
+ tt_str_op(msg, OP_EQ, "Wombat=9");
+ tor_free(msg);
+ tt_assert(! protover_all_supported("Link=3-999", &msg));
+ tt_str_op(msg, OP_EQ, "Link=3-999");
+ tor_free(msg);
+
+ done:
+ tor_free(msg);
+}
+
+#define PV_TEST(name, flags) \
+ { #name, test_protover_ ##name, (flags), NULL, NULL }
+
+struct testcase_t protover_tests[] = {
+ PV_TEST(parse, 0),
+ PV_TEST(parse_fail, 0),
+ PV_TEST(vote, 0),
+ PV_TEST(all_supported, 0),
+ END_OF_TESTCASES
+};
+
diff --git a/src/test/test_pt.c b/src/test/test_pt.c
index e5cdc5f3cd..f93019f1c4 100644
--- a/src/test/test_pt.c
+++ b/src/test/test_pt.c
@@ -155,9 +155,9 @@ test_pt_get_transport_options(void *arg)
opt_str = get_transport_options_for_server_proxy(mp);
tt_ptr_op(opt_str, OP_EQ, NULL);
- smartlist_add(mp->transports_to_launch, tor_strdup("gruyere"));
- smartlist_add(mp->transports_to_launch, tor_strdup("roquefort"));
- smartlist_add(mp->transports_to_launch, tor_strdup("stnectaire"));
+ smartlist_add_strdup(mp->transports_to_launch, "gruyere");
+ smartlist_add_strdup(mp->transports_to_launch, "roquefort");
+ smartlist_add_strdup(mp->transports_to_launch, "stnectaire");
tt_assert(options);
@@ -305,7 +305,7 @@ tor_get_lines_from_handle_replacement(STDIN_HANDLE *handle,
smartlist_add_asprintf(retval_sl, "SMETHOD mock%d 127.0.0.1:555%d",
times_called, times_called);
} else {
- smartlist_add(retval_sl, tor_strdup("SMETHODS DONE"));
+ smartlist_add_strdup(retval_sl, "SMETHODS DONE");
}
return retval_sl;
diff --git a/src/test/test_relay.c b/src/test/test_relay.c
index a7fcad5401..4713c79ea5 100644
--- a/src/test/test_relay.c
+++ b/src/test/test_relay.c
@@ -74,6 +74,10 @@ test_relay_append_cell_to_circuit_queue(void *arg)
/* 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));
@@ -109,8 +113,12 @@ test_relay_append_cell_to_circuit_queue(void *arg)
done:
tor_free(cell);
- cell_queue_clear(&orcirc->base_.n_chan_cells);
- cell_queue_clear(&orcirc->p_chan_cells);
+ 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);
diff --git a/src/test/test_rendcache.c b/src/test/test_rendcache.c
index afcd117350..7f72e441ee 100644
--- a/src/test/test_rendcache.c
+++ b/src/test/test_rendcache.c
@@ -13,6 +13,7 @@
#include "hs_common.h"
#include <openssl/rsa.h>
#include "rend_test_helpers.h"
+#include "log_test_helpers.h"
#define NS_MODULE rend_cache
@@ -658,15 +659,19 @@ test_rend_cache_decrement_allocation(void *data)
// Test when there are not enough allocations
rend_cache_total_allocation = 1;
+ setup_full_capture_of_logs(LOG_WARN);
rend_cache_decrement_allocation(2);
tt_int_op(rend_cache_total_allocation, OP_EQ, 0);
+ expect_single_log_msg_containing(
+ "Underflow in rend_cache_decrement_allocation");
+ teardown_capture_of_logs();
// And again
rend_cache_decrement_allocation(2);
tt_int_op(rend_cache_total_allocation, OP_EQ, 0);
done:
- (void)0;
+ teardown_capture_of_logs();
}
static void
@@ -681,15 +686,19 @@ test_rend_cache_increment_allocation(void *data)
// Test when there are too many allocations
rend_cache_total_allocation = SIZE_MAX-1;
+ setup_full_capture_of_logs(LOG_WARN);
rend_cache_increment_allocation(2);
tt_u64_op(rend_cache_total_allocation, OP_EQ, SIZE_MAX);
+ expect_single_log_msg_containing(
+ "Overflow in rend_cache_increment_allocation");
+ teardown_capture_of_logs();
// And again
rend_cache_increment_allocation(2);
tt_u64_op(rend_cache_total_allocation, OP_EQ, SIZE_MAX);
done:
- (void)0;
+ teardown_capture_of_logs();
}
static void
diff --git a/src/test/test_routerkeys.c b/src/test/test_routerkeys.c
index 24b0da1c46..64692d28a0 100644
--- a/src/test/test_routerkeys.c
+++ b/src/test/test_routerkeys.c
@@ -614,6 +614,66 @@ test_routerkeys_cross_certify_tap(void *args)
crypto_pk_free(onion_key);
}
+static void
+test_routerkeys_rsa_ed_crosscert(void *arg)
+{
+ (void)arg;
+ ed25519_public_key_t ed;
+ crypto_pk_t *rsa = pk_generate(2);
+
+ uint8_t *cc = NULL;
+ ssize_t cc_len;
+ time_t expires_in = 1470846177;
+
+ tt_int_op(0, OP_EQ, ed25519_public_from_base64(&ed,
+ "ThisStringCanContainAnythingSoNoKeyHereNowX"));
+ cc_len = tor_make_rsa_ed25519_crosscert(&ed, rsa, expires_in, &cc);
+
+ tt_int_op(cc_len, OP_GT, 0);
+ tt_int_op(cc_len, OP_GT, 37); /* key, expires, siglen */
+ tt_mem_op(cc, OP_EQ, ed.pubkey, 32);
+ time_t expires_out = 3600 * ntohl(get_uint32(cc+32));
+ tt_int_op(expires_out, OP_GE, expires_in);
+ tt_int_op(expires_out, OP_LE, expires_in + 3600);
+
+ tt_int_op(cc_len, OP_EQ, 37 + get_uint8(cc+36));
+
+ tt_int_op(0, OP_EQ, rsa_ed25519_crosscert_check(cc, cc_len, rsa, &ed,
+ expires_in - 10));
+
+ /* Now try after it has expired */
+ tt_int_op(-4, OP_EQ, rsa_ed25519_crosscert_check(cc, cc_len, rsa, &ed,
+ expires_out + 1));
+
+ /* Truncated object */
+ tt_int_op(-2, OP_EQ, rsa_ed25519_crosscert_check(cc, cc_len - 2, rsa, &ed,
+ expires_in - 10));
+
+ /* Key not as expected */
+ cc[0] ^= 3;
+ tt_int_op(-3, OP_EQ, rsa_ed25519_crosscert_check(cc, cc_len, rsa, &ed,
+ expires_in - 10));
+ cc[0] ^= 3;
+
+ /* Bad signature */
+ cc[40] ^= 3;
+ tt_int_op(-5, OP_EQ, rsa_ed25519_crosscert_check(cc, cc_len, rsa, &ed,
+ expires_in - 10));
+ cc[40] ^= 3;
+
+ /* Signature of wrong data */
+ cc[0] ^= 3;
+ ed.pubkey[0] ^= 3;
+ tt_int_op(-6, OP_EQ, rsa_ed25519_crosscert_check(cc, cc_len, rsa, &ed,
+ expires_in - 10));
+ cc[0] ^= 3;
+ ed.pubkey[0] ^= 3;
+
+ done:
+ crypto_pk_free(rsa);
+ tor_free(cc);
+}
+
#define TEST(name, flags) \
{ #name , test_routerkeys_ ## name, (flags), NULL, NULL }
@@ -626,6 +686,7 @@ struct testcase_t routerkeys_tests[] = {
TEST(ed_keys_init_all, TT_FORK),
TEST(cross_certify_ntor, 0),
TEST(cross_certify_tap, 0),
+ TEST(rsa_ed_crosscert, 0),
END_OF_TESTCASES
};
diff --git a/src/test/test_routerlist.c b/src/test/test_routerlist.c
index 088bd257c3..af5c121ce2 100644
--- a/src/test/test_routerlist.c
+++ b/src/test/test_routerlist.c
@@ -15,6 +15,7 @@
#include "container.h"
#include "directory.h"
#include "dirvote.h"
+#include "entrynodes.h"
#include "microdesc.h"
#include "networkstatus.h"
#include "nodelist.h"
@@ -203,6 +204,53 @@ mock_usable_consensus_flavor(void)
return mock_usable_consensus_flavor_value;
}
+static smartlist_t *mock_is_guard_list = NULL;
+
+static int
+mock_is_node_used_as_guard(const node_t *n)
+{
+ if (mock_is_guard_list) {
+ SMARTLIST_FOREACH_BEGIN(mock_is_guard_list, node_t *, e) {
+ if (e == n) return 1;
+ } SMARTLIST_FOREACH_END(e);
+ }
+
+ return 0;
+}
+
+static void
+mark_node_used_as_guard(node_t *n)
+{
+ if (!n) return;
+
+ if (!mock_is_guard_list) {
+ mock_is_guard_list = smartlist_new();
+ }
+
+ if (!mock_is_node_used_as_guard(n)) {
+ smartlist_add(mock_is_guard_list, n);
+ }
+}
+
+static void
+mark_node_unused_as_guard(node_t *n)
+{
+ if (!n) return;
+
+ if (!mock_is_guard_list) return;
+
+ smartlist_remove(mock_is_guard_list, n);
+}
+
+static void
+clear_mock_guard_list(void)
+{
+ if (mock_is_guard_list) {
+ smartlist_free(mock_is_guard_list);
+ mock_is_guard_list = NULL;
+ }
+}
+
static void
test_router_pick_directory_server_impl(void *arg)
{
@@ -223,6 +271,7 @@ test_router_pick_directory_server_impl(void *arg)
(void)arg;
MOCK(usable_consensus_flavor, mock_usable_consensus_flavor);
+ MOCK(is_node_used_as_guard, mock_is_node_used_as_guard);
/* With no consensus, we must be bootstrapping, regardless of time or flavor
*/
@@ -336,28 +385,28 @@ test_router_pick_directory_server_impl(void *arg)
node_router3->is_valid = 1;
flags |= PDS_FOR_GUARD;
- node_router1->using_as_guard = 1;
- node_router2->using_as_guard = 1;
- node_router3->using_as_guard = 1;
+ mark_node_used_as_guard(node_router1);
+ mark_node_used_as_guard(node_router2);
+ mark_node_used_as_guard(node_router3);
rs = router_pick_directory_server_impl(V3_DIRINFO, flags, NULL);
tt_assert(rs == NULL);
- node_router1->using_as_guard = 0;
+ mark_node_unused_as_guard(node_router1);
rs = router_pick_directory_server_impl(V3_DIRINFO, flags, NULL);
tt_assert(rs != NULL);
tt_assert(tor_memeq(rs->identity_digest, router1_id, DIGEST_LEN));
rs = NULL;
- node_router2->using_as_guard = 0;
- node_router3->using_as_guard = 0;
+ mark_node_unused_as_guard(node_router2);
+ mark_node_unused_as_guard(node_router3);
/* One not valid, one guard. This should leave one remaining */
node_router1->is_valid = 0;
- node_router2->using_as_guard = 1;
+ mark_node_used_as_guard(node_router2);
rs = router_pick_directory_server_impl(V3_DIRINFO, flags, NULL);
tt_assert(rs != NULL);
tt_assert(tor_memeq(rs->identity_digest, router3_id, DIGEST_LEN));
rs = NULL;
node_router1->is_valid = 1;
- node_router2->using_as_guard = 0;
+ mark_node_unused_as_guard(node_router2);
/* Manipulate overloaded */
@@ -420,6 +469,9 @@ test_router_pick_directory_server_impl(void *arg)
done:
UNMOCK(usable_consensus_flavor);
+ UNMOCK(is_node_used_as_guard);
+ clear_mock_guard_list();
+
if (router1_id)
tor_free(router1_id);
if (router2_id)
diff --git a/src/test/test_routerset.c b/src/test/test_routerset.c
index 1b526d430b..7efd042ed5 100644
--- a/src/test/test_routerset.c
+++ b/src/test/test_routerset.c
@@ -623,7 +623,7 @@ NS(test_main)(void *arg)
(void)arg;
tgt = routerset_new();
- smartlist_add(src->list, tor_strdup("{xx}"));
+ smartlist_add_strdup(src->list, "{xx}");
routerset_union(tgt, src);
tt_int_op(smartlist_len(tgt->list), OP_NE, 0);
@@ -745,7 +745,7 @@ NS(test_main)(void *arg)
tt_int_op(is_empty, OP_NE, 0);
set = routerset_new();
- smartlist_add(set->list, tor_strdup("{xx}"));
+ smartlist_add_strdup(set->list, "{xx}");
is_empty = routerset_is_empty(set);
routerset_free(set);
set = NULL;
@@ -1616,7 +1616,7 @@ NS(test_main)(void *arg)
NS_MOCK(node_get_by_nickname);
NS(mock_nickname) = "foo";
- smartlist_add(set->list, tor_strdup(NS(mock_nickname)));
+ smartlist_add_strdup(set->list, NS(mock_nickname));
routerset_get_all_nodes(out, set, NULL, 0);
out_len = smartlist_len(out);
@@ -1667,7 +1667,7 @@ NS(test_main)(void *arg)
NS(mock_node).is_running = 0;
NS(mock_nickname) = "foo";
- smartlist_add(set->list, tor_strdup(NS(mock_nickname)));
+ smartlist_add_strdup(set->list, NS(mock_nickname));
routerset_get_all_nodes(out, set, NULL, 1);
out_len = smartlist_len(out);
@@ -1766,7 +1766,7 @@ NS(test_main)(void *arg)
NS_MOCK(nodelist_get_list);
- smartlist_add(set->country_names, tor_strdup("{xx}"));
+ smartlist_add_strdup(set->country_names, "{xx}");
NS(mock_smartlist) = smartlist_new();
routerset_get_all_nodes(out, set, NULL, 1);
@@ -1813,7 +1813,7 @@ NS(test_main)(void *arg)
NS_MOCK(nodelist_get_list);
- smartlist_add(set->country_names, tor_strdup("{xx}"));
+ smartlist_add_strdup(set->country_names, "{xx}");
NS(mock_smartlist) = smartlist_new();
NS(mock_node).is_running = 0;
smartlist_add(NS(mock_smartlist), (void *)&NS(mock_node));
@@ -1985,7 +1985,7 @@ NS(test_main)(void *arg)
int r;
(void)arg;
- smartlist_add(b->list, tor_strdup("{xx}"));
+ smartlist_add_strdup(b->list, "{xx}");
r = routerset_equal(a, b);
routerset_free(a);
routerset_free(b);
@@ -2010,9 +2010,9 @@ NS(test_main)(void *arg)
int r;
(void)arg;
- smartlist_add(a->list, tor_strdup("{aa}"));
- smartlist_add(b->list, tor_strdup("{b1}"));
- smartlist_add(b->list, tor_strdup("{b2}"));
+ smartlist_add_strdup(a->list, "{aa}");
+ smartlist_add_strdup(b->list, "{b1}");
+ smartlist_add_strdup(b->list, "{b2}");
r = routerset_equal(a, b);
routerset_free(a);
routerset_free(b);
@@ -2037,8 +2037,8 @@ NS(test_main)(void *arg)
int r;
(void)arg;
- smartlist_add(a->list, tor_strdup("foo"));
- smartlist_add(b->list, tor_strdup("bar"));
+ smartlist_add_strdup(a->list, "foo");
+ smartlist_add_strdup(b->list, "bar");
r = routerset_equal(a, b);
routerset_free(a);
routerset_free(b);
@@ -2063,8 +2063,8 @@ NS(test_main)(void *arg)
int r;
(void)arg;
- smartlist_add(a->list, tor_strdup("foo"));
- smartlist_add(b->list, tor_strdup("foo"));
+ smartlist_add_strdup(a->list, "foo");
+ smartlist_add_strdup(b->list, "foo");
r = routerset_equal(a, b);
routerset_free(a);
routerset_free(b);
diff --git a/src/test/test_scheduler.c b/src/test/test_scheduler.c
index 2e0736f99b..05ea8e86e8 100644
--- a/src/test/test_scheduler.c
+++ b/src/test/test_scheduler.c
@@ -1,10 +1,9 @@
/* Copyright (c) 2014-2016, The Tor Project, Inc. */
/* See LICENSE for licensing information */
-#include <math.h>
-
#include "orconfig.h"
+#include <math.h>
#include <event2/event.h>
#define TOR_CHANNEL_INTERNAL_
diff --git a/src/test/test_shared_random.c b/src/test/test_shared_random.c
index d6787e4f45..d511f163e3 100644
--- a/src/test/test_shared_random.c
+++ b/src/test/test_shared_random.c
@@ -14,6 +14,7 @@
#include "router.h"
#include "routerparse.h"
#include "networkstatus.h"
+#include "log_test_helpers.h"
static authority_cert_t *mock_cert;
@@ -274,6 +275,7 @@ test_sr_commit(void *arg)
time_t now = time(NULL);
sr_commit_t *our_commit = NULL;
smartlist_t *args = smartlist_new();
+ sr_commit_t *parsed_commit = NULL;
(void) arg;
@@ -325,14 +327,20 @@ test_sr_commit(void *arg)
/* Timestamp MUST match. */
test_commit.commit_ts = test_commit.reveal_ts - 42;
+ setup_full_capture_of_logs(LOG_WARN);
tt_int_op(-1, ==, verify_commit_and_reveal(&test_commit));
+ expect_log_msg_containing("doesn't match reveal timestamp");
+ teardown_capture_of_logs();
memcpy(&test_commit, our_commit, sizeof(test_commit));
tt_int_op(0, ==, verify_commit_and_reveal(&test_commit));
/* Hashed reveal must match the H(encoded_reveal). */
memset(test_commit.hashed_reveal, 'X',
sizeof(test_commit.hashed_reveal));
+ setup_full_capture_of_logs(LOG_WARN);
tt_int_op(-1, ==, verify_commit_and_reveal(&test_commit));
+ expect_single_log_msg_containing("doesn't match the commit value");
+ teardown_capture_of_logs();
memcpy(&test_commit, our_commit, sizeof(test_commit));
tt_int_op(0, ==, verify_commit_and_reveal(&test_commit));
}
@@ -340,13 +348,12 @@ test_sr_commit(void *arg)
/* We'll build a list of values from our commit that our parsing function
* takes from a vote line and see if we can parse it correctly. */
{
- sr_commit_t *parsed_commit;
- smartlist_add(args, tor_strdup("1"));
- smartlist_add(args,
- tor_strdup(crypto_digest_algorithm_get_name(our_commit->alg)));
- smartlist_add(args, tor_strdup(sr_commit_get_rsa_fpr(our_commit)));
- smartlist_add(args, our_commit->encoded_commit);
- smartlist_add(args, our_commit->encoded_reveal);
+ smartlist_add_strdup(args, "1");
+ smartlist_add_strdup(args,
+ crypto_digest_algorithm_get_name(our_commit->alg));
+ smartlist_add_strdup(args, sr_commit_get_rsa_fpr(our_commit));
+ smartlist_add_strdup(args, our_commit->encoded_commit);
+ smartlist_add_strdup(args, our_commit->encoded_reveal);
parsed_commit = sr_parse_commit(args);
tt_assert(parsed_commit);
/* That parsed commit should be _EXACTLY_ like our original commit (we
@@ -354,15 +361,15 @@ test_sr_commit(void *arg)
parsed_commit->valid = 1;
tt_mem_op(parsed_commit, OP_EQ, our_commit, sizeof(*parsed_commit));
/* Cleanup */
- tor_free(smartlist_get(args, 0)); /* strdup here. */
- tor_free(smartlist_get(args, 1)); /* strdup here. */
- smartlist_clear(args);
- sr_commit_free(parsed_commit);
}
done:
+ teardown_capture_of_logs();
+ SMARTLIST_FOREACH(args, char *, cp, tor_free(cp));
smartlist_free(args);
sr_commit_free(our_commit);
+ sr_commit_free(parsed_commit);
+ authority_cert_free(auth_cert);
}
/* Test the encoding and decoding function for commit and reveal values. */
@@ -370,26 +377,23 @@ static void
test_encoding(void *arg)
{
(void) arg;
- int ret, duper_rand = 42;
+ int ret;
/* Random number is 32 bytes. */
char raw_rand[32];
time_t ts = 1454333590;
char hashed_rand[DIGEST256_LEN], hashed_reveal[DIGEST256_LEN];
sr_commit_t parsed_commit;
- /* Encoded commit is: base64-encode( 1454333590 || H(H(42)) ). Remember
- * that we do no expose the raw bytes of our PRNG to the network thus
- * explaining the double H(). */
- static const char *encoded_commit =
- "AAAAAFavXpZbx2LRneYFSLPCP8DLp9BXfeH5FXzbkxM4iRXKGeA54g==";
- /* Encoded reveal is: base64-encode( 1454333590 || H(42) ). */
+ /* Those values were generated by sr_commit_calc_ref.py where the random
+ * value is 32 'A' and timestamp is the one in ts. */
static const char *encoded_reveal =
- "AAAAAFavXpYk9x9kTjiQWUqjHwSAEOdPAfCaurXgjPy173SzYjeC2g==";
+ "AAAAAFavXpZJxbwTupvaJCTeIUCQmOPxAMblc7ChL5H2nZKuGchdaA==";
+ static const char *encoded_commit =
+ "AAAAAFavXpbkBMzMQG7aNoaGLFNpm2Wkk1ozXhuWWqL//GynltxVAg==";
/* Set up our raw random bytes array. */
- memset(raw_rand, 0, sizeof(raw_rand));
- memcpy(raw_rand, &duper_rand, sizeof(duper_rand));
- /* Hash random number. */
+ memset(raw_rand, 'A', sizeof(raw_rand));
+ /* Hash random number because we don't expose bytes of the RNG. */
ret = crypto_digest256(hashed_rand, raw_rand,
sizeof(raw_rand), SR_DIGEST_ALG);
tt_int_op(0, ==, ret);
@@ -534,8 +538,8 @@ test_vote(void *arg)
HEX_DIGEST_LEN);
tt_mem_op(digest, ==, our_commit->rsa_identity, sizeof(digest));
tt_str_op(smartlist_get(tokens, 4), OP_EQ, our_commit->encoded_commit);
- tt_str_op(smartlist_get(tokens, 5), OP_EQ, our_commit->encoded_reveal);
-
+ tt_str_op(smartlist_get(tokens, 5), OP_EQ, our_commit->encoded_reveal)
+;
/* Finally, does this vote line creates a valid commit object? */
smartlist_t *args = smartlist_new();
smartlist_add(args, smartlist_get(tokens, 1));
@@ -586,6 +590,7 @@ test_vote(void *arg)
smartlist_free(tokens);
smartlist_clear(args);
smartlist_free(args);
+ tor_free(lines);
}
done:
@@ -783,7 +788,7 @@ test_sr_setup_commits(void)
tt_assert(!commit_has_reveal_value(commit_d));
done:
- return;
+ authority_cert_free(auth_cert);
}
/** Verify that the SRV generation procedure is proper by testing it against
@@ -970,6 +975,7 @@ test_utils(void *arg)
/* Change the pubkey. */
memset(commit.rsa_identity, 0, sizeof(commit.rsa_identity));
tt_int_op(commit_is_authoritative(&commit, digest), ==, 0);
+ crypto_pk_free(k);
}
/* Testing get_phase_str(). */
@@ -1047,6 +1053,7 @@ test_state_transition(void *arg)
prev = sr_state_get_previous_srv();
tt_assert(prev == cur);
tt_assert(!sr_state_get_current_srv());
+ sr_state_clean_srvs();
}
/* New protocol run. */
@@ -1095,17 +1102,17 @@ test_keep_commit(void *arg)
sr_commit_t *commit = NULL, *dup_commit = NULL;
sr_state_t *state;
time_t now = time(NULL);
+ crypto_pk_t *k = NULL;
(void) arg;
MOCK(trusteddirserver_get_by_v3_auth_digest,
trusteddirserver_get_by_v3_auth_digest_m);
- { /* Setup a minimal dirauth environment for this test */
- crypto_pk_t *k = crypto_pk_new();
+ {
+ k = pk_generate(1);
+ /* Setup a minimal dirauth environment for this test */
/* Have a key that is not the one from our commit. */
- tt_int_op(0, ==, crypto_pk_generate_key(k));
- tt_int_op(0, ==, crypto_pk_get_fingerprint(k, fp, 0));
init_authority_state();
state = get_sr_state();
}
@@ -1163,8 +1170,14 @@ test_keep_commit(void *arg)
memcpy(place_holder.hashed_reveal, commit->hashed_reveal,
sizeof(place_holder.hashed_reveal));
memset(commit->hashed_reveal, 0, sizeof(commit->hashed_reveal));
+ setup_full_capture_of_logs(LOG_WARN);
tt_int_op(should_keep_commit(commit, commit->rsa_identity,
SR_PHASE_REVEAL), ==, 0);
+ 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");
+ teardown_capture_of_logs();
memcpy(commit->hashed_reveal, place_holder.hashed_reveal,
sizeof(commit->hashed_reveal));
}
@@ -1177,8 +1190,10 @@ test_keep_commit(void *arg)
SR_PHASE_REVEAL), ==, 0);
done:
+ teardown_capture_of_logs();
sr_commit_free(commit);
sr_commit_free(dup_commit);
+ crypto_pk_free(k);
UNMOCK(trusteddirserver_get_by_v3_auth_digest);
}
diff --git a/src/test/test_status.c b/src/test/test_status.c
index b4438aabe9..a3b1a2af87 100644
--- a/src/test/test_status.c
+++ b/src/test/test_status.c
@@ -3,6 +3,8 @@
#define LOG_PRIVATE
#define REPHIST_PRIVATE
+#include "orconfig.h"
+
#include <float.h>
#include <math.h>
diff --git a/src/test/test_threads.c b/src/test/test_threads.c
index 1bbe6f5508..ebbc95c7ca 100644
--- a/src/test/test_threads.c
+++ b/src/test/test_threads.c
@@ -87,11 +87,6 @@ test_threads_basic(void *arg)
char *s1 = NULL, *s2 = NULL;
int done = 0, timedout = 0;
time_t started;
-#ifndef _WIN32
- struct timeval tv;
- tv.tv_sec=0;
- tv.tv_usec=100*1000;
-#endif
(void) arg;
tt_int_op(tor_threadlocal_init(&count), OP_EQ, 0);
@@ -120,10 +115,8 @@ test_threads_basic(void *arg)
timedout = done = 1;
}
tor_mutex_release(thread_test_mutex_);
-#ifndef _WIN32
/* Prevent the main thread from starving the worker threads. */
- select(0, NULL, NULL, NULL, &tv);
-#endif
+ tor_sleep_msec(10);
}
tor_mutex_acquire(thread_test_start1_);
tor_mutex_release(thread_test_start1_);
@@ -286,16 +279,7 @@ test_threads_conditionvar(void *arg)
if (!timeout) {
tt_int_op(ti->n_shutdown, ==, 4);
} else {
-#ifdef _WIN32
- Sleep(500); /* msec */
-#elif defined(HAVE_USLEEP)
- usleep(500*1000); /* usec */
-#else
- {
- struct tv = { 0, 500*1000 };
- select(0, NULL, NULL, NULL, &tv);
- }
-#endif
+ tor_sleep_msec(200);
tor_mutex_acquire(ti->mutex);
tt_int_op(ti->n_shutdown, ==, 2);
tt_int_op(ti->n_timeouts, ==, 2);
diff --git a/src/test/test_tortls.c b/src/test/test_tortls.c
index 3a048fb1f0..44961c88e7 100644
--- a/src/test/test_tortls.c
+++ b/src/test/test_tortls.c
@@ -324,7 +324,7 @@ test_tortls_log_one_error(void *ignored)
ctx = SSL_CTX_new(SSLv23_method());
tls = tor_malloc_zero(sizeof(tor_tls_t));
- int previous_log = setup_capture_of_logs(LOG_INFO);
+ setup_capture_of_logs(LOG_INFO);
tor_tls_log_one_error(NULL, 0, LOG_WARN, 0, "something");
expect_log_msg("TLS error while something: "
@@ -393,7 +393,7 @@ test_tortls_log_one_error(void *ignored)
" (in (null):(null):" SSL_STATE_STR ")\n");
done:
- teardown_capture_of_logs(previous_log);
+ teardown_capture_of_logs();
SSL_free(ssl);
SSL_CTX_free(ctx);
if (tls && tls->ssl)
@@ -416,7 +416,7 @@ test_tortls_get_error(void *ignored)
SSL_load_error_strings();
ctx = SSL_CTX_new(SSLv23_method());
- int previous_log = setup_capture_of_logs(LOG_INFO);
+ 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);
@@ -482,7 +482,7 @@ test_tortls_get_error(void *ignored)
"connect:before/accept initialization)\n");
done:
- teardown_capture_of_logs(previous_log);
+ teardown_capture_of_logs();
SSL_free(tls->ssl);
tor_free(tls);
SSL_CTX_free(ctx);
@@ -1086,13 +1086,13 @@ test_tortls_check_lifetime(void *ignored)
time_t now = time(NULL);
tls = tor_malloc_zero(sizeof(tor_tls_t));
- ret = tor_tls_check_lifetime(LOG_WARN, tls, 0, 0);
+ 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, 0, 0);
+ 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);
@@ -1100,10 +1100,10 @@ test_tortls_check_lifetime(void *ignored)
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, 0, -1000);
+ 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, -1000, 0);
+ ret = tor_tls_check_lifetime(LOG_WARN, tls, time(NULL), -1000, 0);
tt_int_op(ret, OP_EQ, -1);
done:
@@ -1790,7 +1790,7 @@ test_tortls_debug_state_callback(void *ignored)
char *buf = tor_malloc_zero(1000);
int n;
- int previous_log = setup_capture_of_logs(LOG_DEBUG);
+ setup_capture_of_logs(LOG_DEBUG);
ssl = tor_malloc_zero(sizeof(SSL));
@@ -1803,7 +1803,7 @@ test_tortls_debug_state_callback(void *ignored)
expect_log_msg(buf);
done:
- teardown_capture_of_logs(previous_log);
+ teardown_capture_of_logs();
tor_free(buf);
tor_free(ssl);
}
@@ -1817,7 +1817,6 @@ test_tortls_server_info_callback(void *ignored)
tor_tls_t *tls;
SSL_CTX *ctx;
SSL *ssl;
- int previous_log = setup_capture_of_logs(LOG_WARN);
SSL_library_init();
SSL_load_error_strings();
@@ -1831,22 +1830,22 @@ test_tortls_server_info_callback(void *ignored)
tls->magic = TOR_TLS_MAGIC;
tls->ssl = ssl;
- tor_tls_server_info_callback(NULL, 0, 0);
-
+ 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_log_msg("Couldn't look up the tls for an SSL*. How odd!\n");
+ 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_log_msg("Couldn't look up the tls for an SSL*. How odd!\n");
+ 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);
@@ -1867,7 +1866,7 @@ test_tortls_server_info_callback(void *ignored)
tt_int_op(tls->wasV2Handshake, OP_EQ, 0);
done:
- teardown_capture_of_logs(previous_log);
+ teardown_capture_of_logs();
SSL_free(ssl);
SSL_CTX_free(ctx);
tor_free(tls);
@@ -1929,7 +1928,7 @@ test_tortls_shutdown(void *ignored)
int ret;
tor_tls_t *tls;
SSL_METHOD *method = give_me_a_test_method();
- int previous_log = setup_capture_of_logs(LOG_WARN);
+ setup_capture_of_logs(LOG_WARN);
tls = tor_malloc_zero(sizeof(tor_tls_t));
tls->ssl = tor_malloc_zero(sizeof(SSL));
@@ -2012,7 +2011,7 @@ test_tortls_shutdown(void *ignored)
#endif
done:
- teardown_capture_of_logs(previous_log);
+ teardown_capture_of_logs();
tor_free(method);
tor_free(tls->ssl);
tor_free(tls);
@@ -2036,7 +2035,7 @@ test_tortls_read(void *ignored)
tor_tls_t *tls;
char buf[100];
SSL_METHOD *method = give_me_a_test_method();
- int previous_log = setup_capture_of_logs(LOG_WARN);
+ setup_capture_of_logs(LOG_WARN);
tls = tor_malloc_zero(sizeof(tor_tls_t));
tls->ssl = tor_malloc_zero(sizeof(SSL));
@@ -2084,7 +2083,7 @@ test_tortls_read(void *ignored)
// TODO: fill up
done:
- teardown_capture_of_logs(previous_log);
+ teardown_capture_of_logs();
tor_free(tls->ssl);
tor_free(tls);
tor_free(method);
@@ -2109,7 +2108,7 @@ test_tortls_write(void *ignored)
tor_tls_t *tls;
SSL_METHOD *method = give_me_a_test_method();
char buf[100];
- int previous_log = setup_capture_of_logs(LOG_WARN);
+ setup_capture_of_logs(LOG_WARN);
tls = tor_malloc_zero(sizeof(tor_tls_t));
tls->ssl = tor_malloc_zero(sizeof(SSL));
@@ -2149,7 +2148,7 @@ test_tortls_write(void *ignored)
tt_int_op(ret, OP_EQ, TOR_TLS_WANTWRITE);
done:
- teardown_capture_of_logs(previous_log);
+ teardown_capture_of_logs();
BIO_free(tls->ssl->rbio);
tor_free(tls->ssl);
tor_free(tls);
@@ -2194,7 +2193,7 @@ test_tortls_handshake(void *ignored)
tor_tls_t *tls;
SSL_CTX *ctx;
SSL_METHOD *method = give_me_a_test_method();
- int previous_log = setup_capture_of_logs(LOG_INFO);
+ setup_capture_of_logs(LOG_INFO);
SSL_library_init();
SSL_load_error_strings();
@@ -2257,7 +2256,7 @@ test_tortls_handshake(void *ignored)
expect_log_severity(LOG_WARN);
done:
- teardown_capture_of_logs(previous_log);
+ teardown_capture_of_logs();
SSL_free(tls->ssl);
SSL_CTX_free(ctx);
tor_free(tls);
@@ -2291,9 +2290,13 @@ test_tortls_finish_handshake(void *ignored)
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);
@@ -2332,6 +2335,7 @@ test_tortls_finish_handshake(void *ignored)
tor_free(tls);
SSL_CTX_free(ctx);
tor_free(method);
+ teardown_capture_of_logs();
}
#endif
@@ -2418,6 +2422,8 @@ test_tortls_context_new(void *ignored)
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;
@@ -2647,18 +2653,18 @@ test_tortls_cert_is_valid(void *ignored)
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, 0);
+ 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, 0);
+ 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, 0);
+ ret = tor_tls_cert_is_valid(LOG_WARN, cert, scert, time(NULL), 0);
tt_int_op(ret, OP_EQ, 1);
#ifndef OPENSSL_OPAQUE
@@ -2669,7 +2675,7 @@ test_tortls_cert_is_valid(void *ignored)
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, 0);
+ 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);
@@ -2678,7 +2684,7 @@ test_tortls_cert_is_valid(void *ignored)
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, 1);
+ ret = tor_tls_cert_is_valid(LOG_WARN, cert, scert, time(NULL), 1);
tt_int_op(ret, OP_EQ, 0);
#endif
@@ -2689,7 +2695,7 @@ test_tortls_cert_is_valid(void *ignored)
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, 1);
+ 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);
@@ -2698,7 +2704,7 @@ test_tortls_cert_is_valid(void *ignored)
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, 1);
+ 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);
@@ -2707,7 +2713,7 @@ test_tortls_cert_is_valid(void *ignored)
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, 0);
+ 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);
@@ -2717,7 +2723,7 @@ test_tortls_cert_is_valid(void *ignored)
/* 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, 0);
+ ret = tor_tls_cert_is_valid(LOG_WARN, cert, scert, time(NULL), 0);
tt_int_op(ret, OP_EQ, 0);
#endif
@@ -2804,7 +2810,7 @@ struct testcase_t tortls_tests[] = {
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, 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),
diff --git a/src/test/test_util.c b/src/test/test_util.c
index 5432b2ccc4..b74f658146 100644
--- a/src/test/test_util.c
+++ b/src/test/test_util.c
@@ -644,31 +644,57 @@ test_util_time(void *arg)
/* Test tor_timegm out of range */
+ /* The below tests will all cause a BUG message, so we capture, suppress,
+ * and detect. */
+#define CAPTURE() do { \
+ setup_full_capture_of_logs(LOG_WARN); \
+ } while (0)
+#define CHECK_TIMEGM_WARNING(msg) do { \
+ expect_log_msg_containing(msg); \
+ tt_int_op(1, OP_EQ, smartlist_len(mock_saved_logs())); \
+ teardown_capture_of_logs(); \
+ } while (0)
+
+#define CHECK_TIMEGM_ARG_OUT_OF_RANGE(msg) \
+ CHECK_TIMEGM_WARNING("Out-of-range argument to tor_timegm")
+
/* year */
/* Wrong year < 1970 */
a_time.tm_year = 1969-1900;
+ CAPTURE();
tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
+ CHECK_TIMEGM_ARG_OUT_OF_RANGE();
a_time.tm_year = -1-1900;
+ CAPTURE();
tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
+ CHECK_TIMEGM_ARG_OUT_OF_RANGE();
#if SIZEOF_INT == 4 || SIZEOF_INT == 8
a_time.tm_year = -1*(1 << 16);
+ CAPTURE();
tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
+ CHECK_TIMEGM_ARG_OUT_OF_RANGE();
/* one of the smallest tm_year values my 64 bit system supports:
* t_res = -9223372036854775LL without clamping */
a_time.tm_year = -292275055-1900;
+ CAPTURE();
tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
+ CHECK_TIMEGM_ARG_OUT_OF_RANGE();
a_time.tm_year = INT32_MIN;
+ CAPTURE();
tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
+ CHECK_TIMEGM_ARG_OUT_OF_RANGE();
#endif
#if SIZEOF_INT == 8
a_time.tm_year = -1*(1 << 48);
+ CAPTURE();
tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
+ CHECK_TIMEGM_ARG_OUT_OF_RANGE();
/* while unlikely, the system's gmtime(_r) could return
* a "correct" retrospective gregorian negative year value,
@@ -676,25 +702,35 @@ test_util_time(void *arg)
* -1*(2^63)/60/60/24*2000/730485 + 1970 = -292277022657
* 730485 is the number of days in two millenia, including leap days */
a_time.tm_year = -292277022657-1900;
+ CAPTURE();
tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
+ CHECK_TIMEGM_ARG_OUT_OF_RANGE();
a_time.tm_year = INT64_MIN;
+ CAPTURE();
tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
+ CHECK_TIMEGM_ARG_OUT_OF_RANGE();
#endif
/* Wrong year >= INT32_MAX - 1900 */
#if SIZEOF_INT == 4 || SIZEOF_INT == 8
a_time.tm_year = INT32_MAX-1900;
+ CAPTURE();
tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
+ CHECK_TIMEGM_ARG_OUT_OF_RANGE();
a_time.tm_year = INT32_MAX;
+ CAPTURE();
tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
+ CHECK_TIMEGM_ARG_OUT_OF_RANGE();
#endif
#if SIZEOF_INT == 8
/* one of the largest tm_year values my 64 bit system supports */
a_time.tm_year = 292278994-1900;
+ CAPTURE();
tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
+ CHECK_TIMEGM_ARG_OUT_OF_RANGE();
/* while unlikely, the system's gmtime(_r) could return
* a "correct" proleptic gregorian year value,
@@ -702,72 +738,104 @@ test_util_time(void *arg)
* (2^63-1)/60/60/24*2000/730485 + 1970 = 292277026596
* 730485 is the number of days in two millenia, including leap days */
a_time.tm_year = 292277026596-1900;
+ CAPTURE();
tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
+ CHECK_TIMEGM_ARG_OUT_OF_RANGE();
a_time.tm_year = INT64_MAX-1900;
+ CAPTURE();
tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
+ CHECK_TIMEGM_ARG_OUT_OF_RANGE();
a_time.tm_year = INT64_MAX;
+ CAPTURE();
tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
+ CHECK_TIMEGM_ARG_OUT_OF_RANGE();
#endif
/* month */
a_time.tm_year = 2007-1900; /* restore valid year */
a_time.tm_mon = 12; /* Wrong month, it's 0-based */
+ CAPTURE();
tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
+ CHECK_TIMEGM_ARG_OUT_OF_RANGE();
a_time.tm_mon = -1; /* Wrong month */
+ CAPTURE();
tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
+ CHECK_TIMEGM_ARG_OUT_OF_RANGE();
/* day */
a_time.tm_mon = 6; /* Try July */
a_time.tm_mday = 32; /* Wrong day */
+ CAPTURE();
tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
+ CHECK_TIMEGM_ARG_OUT_OF_RANGE();
a_time.tm_mon = 5; /* Try June */
a_time.tm_mday = 31; /* Wrong day */
+ CAPTURE();
tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
+ CHECK_TIMEGM_ARG_OUT_OF_RANGE();
a_time.tm_year = 2008-1900; /* Try a leap year */
a_time.tm_mon = 1; /* in feb. */
a_time.tm_mday = 30; /* Wrong day */
+ CAPTURE();
tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
+ CHECK_TIMEGM_ARG_OUT_OF_RANGE();
a_time.tm_year = 2011-1900; /* Try a non-leap year */
a_time.tm_mon = 1; /* in feb. */
a_time.tm_mday = 29; /* Wrong day */
+ CAPTURE();
tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
+ CHECK_TIMEGM_ARG_OUT_OF_RANGE();
a_time.tm_mday = 0; /* Wrong day, it's 1-based (to be different) */
+ CAPTURE();
tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
+ CHECK_TIMEGM_ARG_OUT_OF_RANGE();
/* hour */
a_time.tm_mday = 3; /* restore valid month day */
a_time.tm_hour = 24; /* Wrong hour, it's 0-based */
+ CAPTURE();
tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
+ CHECK_TIMEGM_ARG_OUT_OF_RANGE();
a_time.tm_hour = -1; /* Wrong hour */
+ CAPTURE();
tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
+ CHECK_TIMEGM_ARG_OUT_OF_RANGE();
/* minute */
a_time.tm_hour = 22; /* restore valid hour */
a_time.tm_min = 60; /* Wrong minute, it's 0-based */
+ CAPTURE();
tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
+ CHECK_TIMEGM_ARG_OUT_OF_RANGE();
a_time.tm_min = -1; /* Wrong minute */
+ CAPTURE();
tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
+ CHECK_TIMEGM_ARG_OUT_OF_RANGE();
/* second */
a_time.tm_min = 37; /* restore valid minute */
a_time.tm_sec = 61; /* Wrong second: 0-based with leap seconds */
+ CAPTURE();
tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
+ CHECK_TIMEGM_ARG_OUT_OF_RANGE();
a_time.tm_sec = -1; /* Wrong second */
+ CAPTURE();
tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
+ CHECK_TIMEGM_ARG_OUT_OF_RANGE();
/* Test tor_gmtime_r out of range */
@@ -807,9 +875,17 @@ test_util_time(void *arg)
* 730485 is the number of days in two millenia, including leap days
* (int64_t)b_time.tm_year == (-292277022657LL-1900LL) without clamping */
t_res = INT64_MIN;
+ CAPTURE();
tor_gmtime_r(&t_res, &b_time);
- tt_assert(b_time.tm_year == (1970-1900) ||
- b_time.tm_year == (1-1900));
+ 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
@@ -845,7 +921,10 @@ test_util_time(void *arg)
* 730485 is the number of days in two millenia, including leap days
* (int64_t)b_time.tm_year == (292277026596L-1900L) without clamping */
t_res = INT64_MAX;
+ CAPTURE();
tor_gmtime_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));
}
@@ -1034,8 +1113,11 @@ test_util_time(void *arg)
#endif
#endif
+#undef CAPTURE
+#undef CHECK_TIMEGM_ARG_OUT_OF_RANGE
+
done:
- ;
+ teardown_capture_of_logs();
}
static void
@@ -1560,6 +1642,35 @@ test_util_config_line_escaped_content(void *arg)
tor_free(v);
}
+static void
+test_util_config_line_crlf(void *arg)
+{
+ char *k=NULL, *v=NULL;
+ const char *err = NULL;
+ (void)arg;
+ const char *str =
+ "Hello world\r\n"
+ "Hello \"nice big world\"\r\n";
+
+ str = parse_config_line_from_str_verbose(str, &k, &v, &err);
+ tt_assert(str);
+ tt_str_op(k,OP_EQ,"Hello");
+ tt_str_op(v,OP_EQ,"world");
+ tt_assert(!err);
+ tor_free(k); tor_free(v);
+
+ str = parse_config_line_from_str_verbose(str, &k, &v, &err);
+ tt_assert(str);
+ tt_str_op(k,OP_EQ,"Hello");
+ tt_str_op(v,OP_EQ,"nice big world");
+ tt_assert(!err);
+ tor_free(k); tor_free(v);
+ tt_str_op(str,OP_EQ, "");
+
+ done:
+ tor_free(k); tor_free(v);
+}
+
#ifndef _WIN32
static void
test_util_expand_filename(void *arg)
@@ -1723,8 +1834,7 @@ static void
test_util_strmisc(void *arg)
{
char buf[1024];
- int i;
- char *cp, *cp_tmp = NULL;
+ char *cp_tmp = NULL;
/* Test strl operations */
(void)arg;
@@ -1749,122 +1859,6 @@ test_util_strmisc(void *arg)
tor_strstrip(buf, "!? ");
tt_str_op(buf,OP_EQ, "Testing123");
- /* Test parse_long */
- /* Empty/zero input */
- tt_int_op(0L,OP_EQ, tor_parse_long("",10,0,100,&i,NULL));
- tt_int_op(0,OP_EQ, i);
- tt_int_op(0L,OP_EQ, tor_parse_long("0",10,0,100,&i,NULL));
- tt_int_op(1,OP_EQ, i);
- /* Normal cases */
- tt_int_op(10L,OP_EQ, tor_parse_long("10",10,0,100,&i,NULL));
- tt_int_op(1,OP_EQ, i);
- tt_int_op(10L,OP_EQ, tor_parse_long("10",10,0,10,&i,NULL));
- tt_int_op(1,OP_EQ, i);
- tt_int_op(10L,OP_EQ, tor_parse_long("10",10,10,100,&i,NULL));
- tt_int_op(1,OP_EQ, i);
- tt_int_op(-50L,OP_EQ, tor_parse_long("-50",10,-100,100,&i,NULL));
- tt_int_op(1,OP_EQ, i);
- tt_int_op(-50L,OP_EQ, tor_parse_long("-50",10,-100,0,&i,NULL));
- tt_int_op(1,OP_EQ, i);
- tt_int_op(-50L,OP_EQ, tor_parse_long("-50",10,-50,0,&i,NULL));
- tt_int_op(1,OP_EQ, i);
- /* Extra garbage */
- tt_int_op(0L,OP_EQ, tor_parse_long("10m",10,0,100,&i,NULL));
- tt_int_op(0,OP_EQ, i);
- tt_int_op(0L,OP_EQ, tor_parse_long("-50 plus garbage",10,-100,100,&i,NULL));
- tt_int_op(0,OP_EQ, i);
- tt_int_op(10L,OP_EQ, tor_parse_long("10m",10,0,100,&i,&cp));
- tt_int_op(1,OP_EQ, i);
- tt_str_op(cp,OP_EQ, "m");
- tt_int_op(-50L,OP_EQ, tor_parse_long("-50 plus garbage",10,-100,100,&i,&cp));
- tt_int_op(1,OP_EQ, i);
- tt_str_op(cp,OP_EQ, " plus garbage");
- /* Illogical min max */
- 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(0L,OP_EQ, tor_parse_long("-50",10,100,-100,&i,NULL));
- tt_int_op(0,OP_EQ, i);
- /* 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);
- tt_int_op(0L,OP_EQ, tor_parse_long("-50",10,0,100,&i,NULL));
- tt_int_op(0,OP_EQ, i);
- /* Base different than 10 */
- tt_int_op(2L,OP_EQ, tor_parse_long("10",2,0,100,NULL,NULL));
- tt_int_op(0L,OP_EQ, tor_parse_long("2",2,0,100,NULL,NULL));
- tt_int_op(0L,OP_EQ, tor_parse_long("10",-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));
- tt_int_op(0,OP_EQ, tor_parse_long("10ABC",-1,0,70000,&i,NULL));
- tt_int_op(i,OP_EQ, 0);
-
- /* Test parse_ulong */
- tt_int_op(0UL,OP_EQ, tor_parse_ulong("",10,0,100,NULL,NULL));
- tt_int_op(0UL,OP_EQ, tor_parse_ulong("0",10,0,100,NULL,NULL));
- tt_int_op(10UL,OP_EQ, tor_parse_ulong("10",10,0,100,NULL,NULL));
- tt_int_op(0UL,OP_EQ, tor_parse_ulong("10",10,50,100,NULL,NULL));
- tt_int_op(10UL,OP_EQ, tor_parse_ulong("10",10,0,10,NULL,NULL));
- tt_int_op(10UL,OP_EQ, tor_parse_ulong("10",10,10,100,NULL,NULL));
- 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,-100,100,NULL,NULL));
- tt_int_op(0UL,OP_EQ, tor_parse_ulong("50",-1,50,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_int_op(1,OP_EQ, i);
- tt_str_op(cp,OP_EQ, " x");
- tt_assert(U64_LITERAL(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) ==
- tor_parse_uint64("12345678901",10,500,INT32_MAX, &i, &cp));
- tt_int_op(0,OP_EQ, i);
- tt_assert(U64_LITERAL(0) ==
- tor_parse_uint64("123",-1,0,INT32_MAX, &i, &cp));
- 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);
- 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);
- d = tor_parse_double(" ", 0, (double)UINT64_MAX,&i,NULL);
- tt_int_op(0,OP_EQ, i);
- d = tor_parse_double(".0a", 0, (double)UINT64_MAX,&i,NULL);
- tt_int_op(0,OP_EQ, i);
- d = tor_parse_double(".0a", 0, (double)UINT64_MAX,&i,&cp);
- 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);
- 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);
- }
-
- {
- /* Test tor_parse_* where we overflow/underflow the underlying type. */
- /* This string should overflow 64-bit ints. */
-#define TOOBIG "100000000000000000000000000"
- tt_int_op(0L, OP_EQ,
- tor_parse_long(TOOBIG, 10, LONG_MIN, LONG_MAX, &i, NULL));
- tt_int_op(i,OP_EQ, 0);
- tt_int_op(0L,OP_EQ,
- tor_parse_long("-"TOOBIG, 10, LONG_MIN, LONG_MAX, &i, NULL));
- 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,
- 0, UINT64_MAX, &i, NULL));
- tt_int_op(i,OP_EQ, 0);
- }
-
/* Test snprintf */
/* Returning -1 when there's not enough room in the output buffer */
tt_int_op(-1,OP_EQ, tor_snprintf(buf, 0, "Foo"));
@@ -2054,6 +2048,144 @@ test_util_strmisc(void *arg)
}
static void
+test_util_parse_integer(void *arg)
+{
+ (void)arg;
+ int i;
+ char *cp;
+
+ /* Test parse_long */
+ /* Empty/zero input */
+ tt_int_op(0L,OP_EQ, tor_parse_long("",10,0,100,&i,NULL));
+ tt_int_op(0,OP_EQ, i);
+ tt_int_op(0L,OP_EQ, tor_parse_long("0",10,0,100,&i,NULL));
+ tt_int_op(1,OP_EQ, i);
+ /* Normal cases */
+ tt_int_op(10L,OP_EQ, tor_parse_long("10",10,0,100,&i,NULL));
+ tt_int_op(1,OP_EQ, i);
+ tt_int_op(10L,OP_EQ, tor_parse_long("10",10,0,10,&i,NULL));
+ tt_int_op(1,OP_EQ, i);
+ tt_int_op(10L,OP_EQ, tor_parse_long("10",10,10,100,&i,NULL));
+ tt_int_op(1,OP_EQ, i);
+ tt_int_op(-50L,OP_EQ, tor_parse_long("-50",10,-100,100,&i,NULL));
+ tt_int_op(1,OP_EQ, i);
+ tt_int_op(-50L,OP_EQ, tor_parse_long("-50",10,-100,0,&i,NULL));
+ tt_int_op(1,OP_EQ, i);
+ tt_int_op(-50L,OP_EQ, tor_parse_long("-50",10,-50,0,&i,NULL));
+ tt_int_op(1,OP_EQ, i);
+ /* Extra garbage */
+ tt_int_op(0L,OP_EQ, tor_parse_long("10m",10,0,100,&i,NULL));
+ tt_int_op(0,OP_EQ, i);
+ tt_int_op(0L,OP_EQ, tor_parse_long("-50 plus garbage",10,-100,100,&i,NULL));
+ tt_int_op(0,OP_EQ, i);
+ tt_int_op(10L,OP_EQ, tor_parse_long("10m",10,0,100,&i,&cp));
+ tt_int_op(1,OP_EQ, i);
+ tt_str_op(cp,OP_EQ, "m");
+ tt_int_op(-50L,OP_EQ, tor_parse_long("-50 plus garbage",10,-100,100,&i,&cp));
+ 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);
+ tt_int_op(0L,OP_EQ, tor_parse_long("-50",10,0,100,&i,NULL));
+ tt_int_op(0,OP_EQ, i);
+ /* Base different than 10 */
+ tt_int_op(2L,OP_EQ, tor_parse_long("10",2,0,100,NULL,NULL));
+ tt_int_op(0L,OP_EQ, tor_parse_long("2",2,0,100,NULL,NULL));
+ tt_int_op(0L,OP_EQ, tor_parse_long("10",-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));
+ tt_int_op(0,OP_EQ, tor_parse_long("10ABC",-1,0,70000,&i,NULL));
+ tt_int_op(i,OP_EQ, 0);
+
+ /* Test parse_ulong */
+ tt_int_op(0UL,OP_EQ, tor_parse_ulong("",10,0,100,NULL,NULL));
+ tt_int_op(0UL,OP_EQ, tor_parse_ulong("0",10,0,100,NULL,NULL));
+ tt_int_op(10UL,OP_EQ, tor_parse_ulong("10",10,0,100,NULL,NULL));
+ tt_int_op(0UL,OP_EQ, tor_parse_ulong("10",10,50,100,NULL,NULL));
+ tt_int_op(10UL,OP_EQ, tor_parse_ulong("10",10,0,10,NULL,NULL));
+ tt_int_op(10UL,OP_EQ, tor_parse_ulong("10",10,10,100,NULL,NULL));
+ 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));
+ tt_int_op(0UL,OP_EQ, tor_parse_ulong("50",-1,50,100,&i,NULL));
+ 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_int_op(1,OP_EQ, i);
+ tt_str_op(cp,OP_EQ, " x");
+ tt_assert(U64_LITERAL(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) ==
+ tor_parse_uint64("12345678901",10,500,INT32_MAX, &i, &cp));
+ tt_int_op(0,OP_EQ, i);
+ tt_assert(U64_LITERAL(0) ==
+ tor_parse_uint64("123",-1,0,INT32_MAX, &i, &cp));
+ 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);
+ 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);
+ d = tor_parse_double(" ", 0, (double)UINT64_MAX,&i,NULL);
+ tt_int_op(0,OP_EQ, i);
+ d = tor_parse_double(".0a", 0, (double)UINT64_MAX,&i,NULL);
+ tt_int_op(0,OP_EQ, i);
+ d = tor_parse_double(".0a", 0, (double)UINT64_MAX,&i,&cp);
+ 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);
+ 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);
+ }
+
+ {
+ /* Test tor_parse_* where we overflow/underflow the underlying type. */
+ /* This string should overflow 64-bit ints. */
+#define TOOBIG "100000000000000000000000000"
+ tt_int_op(0L, OP_EQ,
+ tor_parse_long(TOOBIG, 10, LONG_MIN, LONG_MAX, &i, NULL));
+ tt_int_op(i,OP_EQ, 0);
+ tt_int_op(0L,OP_EQ,
+ tor_parse_long("-"TOOBIG, 10, LONG_MIN, LONG_MAX, &i, NULL));
+ 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,
+ 0, UINT64_MAX, &i, NULL));
+ tt_int_op(i,OP_EQ, 0);
+ }
+ done:
+ tor_end_capture_bugs_();
+}
+
+static void
test_util_pow2(void *arg)
{
/* Test tor_log2(). */
@@ -2217,9 +2349,15 @@ test_util_gzip_compression_bomb(void *arg)
tor_zlib_state_t *state = NULL;
/* Make sure we can't produce a compression bomb */
+ setup_full_capture_of_logs(LOG_WARN);
tt_int_op(-1, OP_EQ, tor_gzip_compress(&result, &result_len,
one_mb, one_million,
ZLIB_METHOD));
+ expect_single_log_msg_containing(
+ "We compressed something and got an insanely high "
+ "compression factor; other Tors would think this "
+ "was a zlib bomb.");
+ teardown_capture_of_logs();
/* Here's a compression bomb that we made manually. */
const char compression_bomb[1039] =
@@ -4965,26 +5103,62 @@ test_util_socket(void *arg)
tt_int_op(fd_is_nonblocking(fd4), OP_EQ, 1);
#endif
- tor_close_socket(fd1);
- tor_close_socket(fd2);
+ tor_assert(tor_close_socket == tor_close_socket__real);
+
+ /* we use close_socket__real here so that coverity can tell that we are
+ * really closing these sockets. */
+ tor_close_socket__real(fd1);
+ tor_close_socket__real(fd2);
fd1 = fd2 = TOR_INVALID_SOCKET;
tt_int_op(get_n_open_sockets(), OP_EQ, n + 2);
- tor_close_socket(fd3);
- tor_close_socket(fd4);
+ tor_close_socket__real(fd3);
+ tor_close_socket__real(fd4);
fd3 = fd4 = TOR_INVALID_SOCKET;
tt_int_op(get_n_open_sockets(), OP_EQ, n);
done:
if (SOCKET_OK(fd1))
- tor_close_socket(fd1);
+ tor_close_socket__real(fd1);
if (SOCKET_OK(fd2))
- tor_close_socket(fd2);
+ tor_close_socket__real(fd2);
if (SOCKET_OK(fd3))
- tor_close_socket(fd3);
+ tor_close_socket__real(fd3);
if (SOCKET_OK(fd4))
- tor_close_socket(fd4);
+ tor_close_socket__real(fd4);
}
+#if 0
+static int
+is_there_a_localhost(int family)
+{
+ tor_socket_t s;
+ s = tor_open_socket(family, SOCK_STREAM, IPPROTO_TCP);
+ tor_assert(SOCKET_OK(s));
+
+ int result = 0;
+ if (family == AF_INET) {
+ struct sockaddr_in s_in;
+ memset(&s_in, 0, sizeof(s_in));
+ s_in.sin_family = AF_INET;
+ s_in.sin_addr.s_addr = htonl(0x7f000001);
+ s_in.sin_port = 0;
+
+ if (bind(s, (void*)&s_in, sizeof(s_in)) == 0) {
+ result = 1;
+ }
+ } else if (family == AF_INET6) {
+ struct sockaddr_in6 sin6;
+ memset(&sin6, 0, sizeof(sin6));
+ sin6.sin6_family = AF_INET6;
+ sin6.sin6_addr.s6_addr[15] = 1;
+ sin6.sin6_port = 0;
+ }
+ tor_close_socket(s);
+
+ return result;
+}
+#endif
+
/* Test for socketpair and ersatz_socketpair(). We test them both, since
* the latter is a tolerably good way to exersize tor_accept_socket(). */
static void
@@ -4999,15 +5173,18 @@ test_util_socketpair(void *arg)
int socketpair_result = 0;
socketpair_result = tor_socketpair_fn(family, SOCK_STREAM, 0, fds);
- /* If there is no 127.0.0.1 or ::1, tor_ersatz_socketpair will and must fail.
+
+#ifdef __FreeBSD__
+ /* If there is no 127.0.0.1, tor_ersatz_socketpair will and must fail.
* Otherwise, we risk exposing a socketpair on a routable IP address. (Some
* BSD jails use a routable address for localhost. Fortunately, they have
* the real AF_UNIX socketpair.) */
- if (ersatz && ERRNO_IS_EPROTO(-socketpair_result)) {
+ if (ersatz && socketpair_result < 0) {
/* In my testing, an IPv6-only FreeBSD jail without ::1 returned EINVAL.
* Assume we're on a machine without 127.0.0.1 or ::1 and give up now. */
- goto done;
+ tt_skip();
}
+#endif
tt_int_op(0, OP_EQ, socketpair_result);
tt_assert(SOCKET_OK(fds[0]));
@@ -5214,7 +5391,6 @@ test_util_pwdb(void *arg)
const struct passwd *me = NULL, *me2, *me3;
char *name = NULL;
char *dir = NULL;
- int prev_level = -100;
/* Uncached case. */
/* Let's assume that we exist. */
@@ -5254,12 +5430,13 @@ test_util_pwdb(void *arg)
tt_assert(found);
tor_free(dir);
- prev_level = setup_capture_of_logs(LOG_ERR); /* We should do a LOG_ERR */
+ /* We should do a LOG_ERR */
+ setup_full_capture_of_logs(LOG_ERR);
dir = get_user_homedir(badname);
tt_assert(dir == NULL);
+ expect_log_msg_containing("not found");
tt_int_op(smartlist_len(mock_saved_logs()), OP_EQ, 1);
- teardown_capture_of_logs(prev_level);
- prev_level = -100;
+ teardown_capture_of_logs();
/* Now try to find a user that doesn't exist by ID. */
found = 0;
@@ -5276,8 +5453,7 @@ test_util_pwdb(void *arg)
done:
tor_free(name);
tor_free(dir);
- if (prev_level >= 0)
- teardown_capture_of_logs(prev_level);
+ teardown_capture_of_logs();
}
#endif
@@ -5321,6 +5497,8 @@ test_util_monotonic_time(void *arg)
uint64_t nsec1, nsec2, usec1, msec1;
uint64_t nsecc1, nsecc2, usecc1, msecc1;
+ monotime_init();
+
monotime_get(&mt1);
monotime_coarse_get(&mtc1);
nsec1 = monotime_absolute_nsec();
@@ -5365,6 +5543,7 @@ static void
test_util_monotonic_time_ratchet(void *arg)
{
(void)arg;
+ monotime_init();
monotime_reset_ratchets_for_testing();
/* win32, performance counter ratchet. */
@@ -5433,6 +5612,33 @@ test_util_monotonic_time_ratchet(void *arg)
;
}
+static void
+test_util_htonll(void *arg)
+{
+ (void)arg;
+#ifdef WORDS_BIGENDIAN
+ const uint64_t res_be = 0x8877665544332211;
+#else
+ const uint64_t res_le = 0x1122334455667788;
+#endif
+
+ tt_u64_op(0, OP_EQ, tor_htonll(0));
+ tt_u64_op(0, OP_EQ, tor_ntohll(0));
+ tt_u64_op(UINT64_MAX, OP_EQ, tor_htonll(UINT64_MAX));
+ tt_u64_op(UINT64_MAX, OP_EQ, tor_ntohll(UINT64_MAX));
+
+#ifdef WORDS_BIGENDIAN
+ tt_u64_op(res_be, OP_EQ, tor_htonll(0x8877665544332211));
+ tt_u64_op(res_be, OP_EQ, tor_ntohll(0x8877665544332211));
+#else
+ tt_u64_op(res_le, OP_EQ, tor_htonll(0x8877665544332211));
+ tt_u64_op(res_le, OP_EQ, tor_ntohll(0x8877665544332211));
+#endif
+
+ done:
+ ;
+}
+
#define UTIL_LEGACY(name) \
{ #name, test_util_ ## name , 0, NULL, NULL }
@@ -5456,13 +5662,15 @@ struct testcase_t util_tests[] = {
UTIL_LEGACY(config_line_quotes),
UTIL_LEGACY(config_line_comment_character),
UTIL_LEGACY(config_line_escaped_content),
+ UTIL_LEGACY(config_line_crlf),
UTIL_LEGACY_NO_WIN(expand_filename),
UTIL_LEGACY(escape_string_socks),
UTIL_LEGACY(string_is_key_value),
UTIL_LEGACY(strmisc),
+ UTIL_TEST(parse_integer, 0),
UTIL_LEGACY(pow2),
UTIL_LEGACY(gzip),
- UTIL_LEGACY(gzip_compression_bomb),
+ UTIL_TEST(gzip_compression_bomb, TT_FORK),
UTIL_LEGACY(datadir),
UTIL_LEGACY(memarea),
UTIL_LEGACY(control_formats),
@@ -5524,6 +5732,7 @@ struct testcase_t util_tests[] = {
UTIL_TEST(calloc_check, 0),
UTIL_TEST(monotonic_time, 0),
UTIL_TEST(monotonic_time_ratchet, TT_FORK),
+ UTIL_TEST(htonll, 0),
END_OF_TESTCASES
};
diff --git a/src/test/test_util_format.c b/src/test/test_util_format.c
index 63a668238c..1d58ba2bf8 100644
--- a/src/test/test_util_format.c
+++ b/src/test/test_util_format.c
@@ -11,25 +11,14 @@
#define NS_MODULE util_format
-#if !defined(HAVE_HTONLL) && !defined(htonll)
-#ifdef WORDS_BIGENDIAN
-#define htonll(x) (x)
-#else
-static uint64_t
-htonll(uint64_t a)
-{
- return htonl((uint32_t)(a>>32)) | (((uint64_t)htonl((uint32_t)a))<<32);
-}
-#endif
-#endif
-
static void
test_util_format_unaligned_accessors(void *ignored)
{
(void)ignored;
char buf[9] = "onionsoup"; // 6f6e696f6e736f7570
- tt_u64_op(get_uint64(buf+1), OP_EQ, htonll(U64_LITERAL(0x6e696f6e736f7570)));
+ tt_u64_op(get_uint64(buf+1), OP_EQ,
+ tor_htonll(U64_LITERAL(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);
@@ -43,7 +32,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, htonll(U64_LITERAL(0x6266757363617465)));
+ set_uint64(buf+1, tor_htonll(U64_LITERAL(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 45c22ef47f..4e75b97f3d 100644
--- a/src/test/test_util_process.c
+++ b/src/test/test_util_process.c
@@ -26,7 +26,7 @@ test_util_process_set_waitpid_callback(void *ignored)
{
(void)ignored;
waitpid_callback_t *res1 = NULL, *res2 = NULL;
- int previous_log = setup_capture_of_logs(LOG_WARN);
+ setup_full_capture_of_logs(LOG_WARN);
pid_t pid = (pid_t)42;
res1 = set_waitpid_callback(pid, temp_callback, NULL);
@@ -34,11 +34,12 @@ test_util_process_set_waitpid_callback(void *ignored)
res2 = set_waitpid_callback(pid, temp_callback, NULL);
tt_assert(res2);
- expect_log_msg("Replaced a waitpid monitor on pid 42. That should be "
+ expect_single_log_msg(
+ "Replaced a waitpid monitor on pid 42. That should be "
"impossible.\n");
done:
- teardown_capture_of_logs(previous_log);
+ teardown_capture_of_logs();
clear_waitpid_callback(res1);
clear_waitpid_callback(res2);
}
@@ -48,7 +49,7 @@ test_util_process_clear_waitpid_callback(void *ignored)
{
(void)ignored;
waitpid_callback_t *res;
- int previous_log = setup_capture_of_logs(LOG_WARN);
+ setup_capture_of_logs(LOG_WARN);
pid_t pid = (pid_t)43;
clear_waitpid_callback(NULL);
@@ -64,7 +65,7 @@ test_util_process_clear_waitpid_callback(void *ignored)
#endif
done:
- teardown_capture_of_logs(previous_log);
+ teardown_capture_of_logs();
}
#endif /* _WIN32 */
diff --git a/src/test/testing_common.c b/src/test/testing_common.c
index ea9366305c..deb11d0112 100644
--- a/src/test/testing_common.c
+++ b/src/test/testing_common.c
@@ -155,68 +155,47 @@ remove_directory(void)
rm_rf(temp_dir);
}
-/** Define this if unit tests spend too much time generating public keys*/
-#undef CACHE_GENERATED_KEYS
-
-static crypto_pk_t *pregen_keys[5] = {NULL, NULL, NULL, NULL, NULL};
-#define N_PREGEN_KEYS ARRAY_LENGTH(pregen_keys)
-
-/** Generate and return a new keypair for use in unit tests. If we're using
- * the key cache optimization, we might reuse keys: we only guarantee that
- * keys made with distinct values for <b>idx</b> are different. The value of
- * <b>idx</b> must be at least 0, and less than N_PREGEN_KEYS. */
-crypto_pk_t *
-pk_generate(int idx)
+static void *
+passthrough_test_setup(const struct testcase_t *testcase)
{
- int res;
-#ifdef CACHE_GENERATED_KEYS
- tor_assert(idx < N_PREGEN_KEYS);
- if (! pregen_keys[idx]) {
- pregen_keys[idx] = crypto_pk_new();
- res = crypto_pk_generate_key(pregen_keys[idx]);
- tor_assert(!res);
- }
- return crypto_pk_dup_key(pregen_keys[idx]);
-#else
- crypto_pk_t *result;
- (void) idx;
- result = crypto_pk_new();
- res = crypto_pk_generate_key(result);
- tor_assert(!res);
- return result;
-#endif
+ return testcase->setup_data;
}
-
-/** Free all storage used for the cached key optimization. */
-static void
-free_pregenerated_keys(void)
+static int
+passthrough_test_cleanup(const struct testcase_t *testcase, void *ptr)
{
- unsigned idx;
- for (idx = 0; idx < N_PREGEN_KEYS; ++idx) {
- if (pregen_keys[idx]) {
- crypto_pk_free(pregen_keys[idx]);
- pregen_keys[idx] = NULL;
- }
- }
+ (void)testcase;
+ (void)ptr;
+ return 1;
}
static void *
-passthrough_test_setup(const struct testcase_t *testcase)
+ed25519_testcase_setup(const struct testcase_t *testcase)
{
+ crypto_ed25519_testing_force_impl(testcase->setup_data);
return testcase->setup_data;
}
static int
-passthrough_test_cleanup(const struct testcase_t *testcase, void *ptr)
+ed25519_testcase_cleanup(const struct testcase_t *testcase, void *ptr)
{
(void)testcase;
(void)ptr;
+ crypto_ed25519_testing_restore_impl();
return 1;
}
+const struct testcase_setup_t ed25519_test_setup = {
+ ed25519_testcase_setup, ed25519_testcase_cleanup
+};
const struct testcase_setup_t passthrough_setup = {
passthrough_test_setup, passthrough_test_cleanup
};
+static void
+an_assertion_failed(void)
+{
+ tinytest_set_test_failed_();
+}
+
/** Main entry point for unit test code: parse the command line, and run
* some unit tests. */
int
@@ -244,6 +223,8 @@ main(int c, const char **v)
network_init();
+ monotime_init();
+
struct tor_libevent_cfg cfg;
memset(&cfg, 0, sizeof(cfg));
tor_libevent_initialize(&cfg);
@@ -272,6 +253,8 @@ main(int c, const char **v)
log_severity_list_t s;
memset(&s, 0, sizeof(s));
set_log_severity_config(loglevel, LOG_ERR, &s);
+ /* ALWAYS log bug warnings. */
+ s.masks[LOG_WARN-LOG_ERR] |= LD_BUG;
add_stream_log(&s, "", fileno(stdout));
}
@@ -295,6 +278,9 @@ main(int c, const char **v)
tor_free(errmsg);
return 1;
}
+ tor_set_failed_assertion_callback(an_assertion_failed);
+
+ init_pregenerated_keys();
atexit(remove_directory);
diff --git a/src/test/testing_rsakeys.c b/src/test/testing_rsakeys.c
new file mode 100644
index 0000000000..134770bb0d
--- /dev/null
+++ b/src/test/testing_rsakeys.c
@@ -0,0 +1,546 @@
+/* Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2016, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#include "orconfig.h"
+#include "or.h"
+#include "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
+keys among */
+#define USE_PREGENERATED_RSA_KEYS
+
+#ifdef USE_PREGENERATED_RSA_KEYS
+
+static const char *PREGEN_KEYS_1024[] = {
+"-----BEGIN RSA PRIVATE KEY-----\n"
+"MIICWwIBAAKBgQCZa39BCgq7KWBWFSjGYHhqmTCHvQ7WNEFAb9Mujb6Xn/Zy01fu\n"
+"WIpVvqmAKeLNEziItUm/gB8GwAN+/ZLwL9pufjIp2Ar+yqVXKySioZQxuCgTP2wm\n"
+"Ku0OfmAra1Xbtrkc2OCJllxkyNPrJ/kxfwjWR96UP0+VMbOlkBoEH1FtvwIDAQAB\n"
+"AoGAUXoygeMIYe+OdwkTt48CRHKIwH3aRE5KHSOGPyIOB05vvvmYqD8jcHgqYqNc\n"
+"DNdZXdkRin9LevU8phObFq4DTXp08XggUx4Kk4AdsFKubQtJ8gHm3xlSKbZXX2m/\n"
+"ZF0GRaZtVDQ3TRGh+OBLILt/2jT+BaFKGAyJ7al76F2nprECQQDJyLlteLDFBmrd\n"
+"0kAjNBE50S5YskBCQeQACROfyTKW8lG1J57UBeYjXvbrDFBR4alIS9DEexGai9Gz\n"
+"wxpgKg2nAkEAwqQmPstjHxvqGQRi41uXO026MLxY7dhEqs1aSw3tuT8v17pW3OEa\n"
+"Qxv7JINePZ3+sNN+Ic+3RXBR0QuD7lSSKQJAZjVSF21GvMXfY7SX4D0DbLHUNAE2\n"
+"I1mUz5/JXOpgwazETmpfPS4vwELd93kpRhBz2rbsbFmaNRoVgmSU+5jRiQJAZ1bV\n"
+"g2NilgKxEGU2x3U6Xt8Oqo9lO6omEvUCKnUTsNWuZf/l3FGbKuQxO5qPr3Ex5tny\n"
+"zqrEqBZRKgbOHfxCuQJAbJY5C3Nm5koemr031r00MY2YD1b6+hyKZyPdZ21HpyY8\n"
+"z1kWShL0POjYPX/BnKE1FkpklWcKBb7wkK7dvAKkEQ==\n"
+"-----END RSA PRIVATE KEY-----\n",
+
+"-----BEGIN RSA PRIVATE KEY-----\n"
+"MIICXQIBAAKBgQCyqMM2TfFGV5tVBTVabxLVln8146nDavIdR6q78DCUMh8Zfzkk\n"
+"h9Lbl1NX4RU+AmrCZMPq21/EjIRxRQyRdgPYJVLdp96eGeYnEzmMkqvXiswXvDg/\n"
+"tXqsjyJeYsoHMQWDTpCLfjYo4K1ol1sg8VIs4wQeq5og6QSdmhBoz7MyqQIDAQAB\n"
+"AoGBAIJekey7nZeV8Bxva4ptSRIg+v0I/2VBUiG5nUX9NIW/uV/yrXERx/VDjKaw\n"
+"8b5JJzxpKWnk4RJc83xwRYaT1qMYHiQfybxEI0K9SjhtaThAjtXkQGtZgLJILl3t\n"
+"yh3LPTh1ocwafsKjU6eGYAe/DYn9/QwYHbtyaimcigu4etp9AkEA2DgC+HndoP1i\n"
+"np26Lx+4TG0vAfrVYGSLT9FXwf2iBV3oJvdKqu6wr8ipb1SbshRPcOQd31/mCh6+\n"
+"2BR+d4ddcwJBANOHrlBbGZdHnoEu6kKbPwwkc31IZYqyfSpkqm0Lb2oWZ9SInKfc\n"
+"cz0qpH91p610XUpYmycaJr4K+N8jgrz86HMCQQCoqGBg1Ca2OpCf66bctWB8dTqS\n"
+"z8d7rlIhC8npr1+f0hWRt5pN5Wx7YgoQpq3gZgllpPtMT7DQOhVh1fKkaDnTAkA4\n"
+"XuskPPLX7t0dvhvtviOSH9CrLXTp/mD+wC7uumJpmij3aaSd01DelxOZaAhUYDNQ\n"
+"UcafKAf1E0V5aaQ4qwljAkA9NVN6CtpzzcLrstTKxrx5P1Ylt/0UYQDo1lIaqwrT\n"
+"aOFbXmOungiC9+p/4U7RbX0MEzjFDHCWlaHASviGVgta\n"
+"-----END RSA PRIVATE KEY-----\n",
+
+"-----BEGIN RSA PRIVATE KEY-----\n"
+"MIICWwIBAAKBgQDDt2V63APj3JSqaRgofUzhtB+prm0wII4uHyxfOxnpYIELOW5z\n"
+"3UHmkr+B4D+Nif5jIp0i6W4OS4S+YHewKsDsXvXKRIW78KzOt6Le4JI9rSarNjy5\n"
+"aJKksWQRALLCmxP/BdolaBFqF3fIPD5+Zxu8ESgxhkEQI4p7awUp3E730QIDAQAB\n"
+"AoGAZktfAR4p8lkCYydW9yK2ommQ+xEuBK+fYL/uYz/yxSYpjIJSFsEYhrlA21Mo\n"
+"JIRxr8MRuoOjgFk8YnztUeimuHpslDlZDaCBzjRjBRFCMepZNG9xqSEL0u7C+SH6\n"
+"KU5f2x2P6PneBj6WaHZM+6Lf2xHlOoeuaVSUfq2Pk2VBF9kCQQDtawWWNwP0+xea\n"
+"oCAQpanaLzYPjlqZfHJQ1AAI5eSkdf1qmlypIHwOtjAEa6XuEO/Or8RNkNy4nQdw\n"
+"qhcQ7PXDAkEA0wjT6Z+Lrt67FnwPgoSvl4Nukcqw4OWHbBKhaQPsO9+oc3PAXLdD\n"
+"SclUUqDF6NX1yONTV1KrPdz4zElmEua+2wJABm4inZnp2oW+cuqpU6oY+pbSwQMb\n"
+"AxMyyWukgJkxYx7q+SsrHU2K7p8Sl9wOh28f/5oVGAC3aayfGfcRXtz8HwJAIqeO\n"
+"dQzYGU1GF7kjquEzHIRewd4xEZ1fkaW1j9MvFd3ygZL+gbsud41yJWd1WHjaNbTu\n"
+"2KYgrLX+vT1IX844hQJAbg0V7iHlttQqXL7yN09jIjQLprqVhDZCUHS9s9Dxe7fz\n"
+"Ac0ZZD0D6EVNmSmBB71q7kLUWX/W/10d447TLnnfew==\n"
+"-----END RSA PRIVATE KEY-----\n",
+
+"-----BEGIN RSA PRIVATE KEY-----\n"
+"MIICXgIBAAKBgQDhCAjPEockl4lqkvoIb5O3NJJG8NWD31c63e/cPWY6MX5nOM/q\n"
+"avof2eWJxFOk0HQ2BRVwIgNex6kLxtsdw7XE0A5uZorTp9DbRCGMqUqHNhHH9ci2\n"
+"mMPP9jptq3ieWg310bH4Tad8h3WE2npSCDBvxyV6EmuH2rlQW9ZlHNoiRQIDAQAB\n"
+"AoGBAI4PgWggPTqng7PJF5mNvsYQpSutzE0VCL977nmuNUQVjMPjRLarVD4ZU+QW\n"
+"EevhQQv9R5xjjJcgGqL5pchzjeKDm0/LA+AygnZoDMs2O68Neieqvr7cPqr5ALGs\n"
+"WuZvSn+bRJTenvV9sUh2ii0/u3GQbL1v7GWDkIdD7itDbmRhAkEA8iijuEY+W67w\n"
+"7JusjY2MQ2Cm6xxxR0YcnYPzT6UDm+Z7NNJwKscQ6AjayNmxmXGpbUdukzLzXf8y\n"
+"fccI9t6iHQJBAO3kx9nZay0Ktl51QP5o2gwoqRIbnogGfR06KJOlzIPGR0aPn8cg\n"
+"uKq2SiyjewEaSBM6S/4UlxYUmvc3VKnxCEkCQQDpTjg2YQ7RPGIIRA/iLV7Wx3bq\n"
+"C/QjjCwjoi44LK6mdE9928WPoUzrkSRg4EQYpwZqL6kcDrmkdSuLPMipOGQNAkA3\n"
+"KtzlujPOiDNuiEaAORSHyU4b8ue6p7aP9pK+Wq6oyGxzAo+NABuTCx78ZxT5Vnzs\n"
+"aJKC44d+CV0+g0hQ+KJxAkEAqFYzNWIzTHX8DVDdK9BpUaBg1DFxIeP5Kk+/X3FF\n"
+"5BafG08B6OiLf8qIGGsxLXNRjIE0GVp3Sy23FUKtUymP+A==\n"
+"-----END RSA PRIVATE KEY-----\n",
+
+"-----BEGIN RSA PRIVATE KEY-----\n"
+"MIICXQIBAAKBgQDMDk01VwPxQq/BAwOBmfGUP/x5BQn+uxI0Aat6bdWuz/2CsjbS\n"
+"CWD/YLCaPm+DpHp9RMwk4HONJaw4B2XOw3ELPx7y9DEgdC1wZ9wRkJmqr2IJZoZR\n"
+"C7x43nNv+/IXTiRkkljCcMpoL1Tld+L2VbmWR29PdZwvspWRILkEZu1mNwIDAQAB\n"
+"AoGANvFK3KfXSei4xfF3yjeXEmHAKx2uOUZJenNQpqBYPr+F9ODjXd5knZ59LqrM\n"
+"/9cTnBMgHHXK5yBTpKppQSjikLeQ2BF04Ktff9oGqVcS9x/rKo0CREuxsEfawZOW\n"
+"OzOWENp4YcDKGP1I/Ctr185QzStaWrXVQftxmYQ53T77ShECQQDnhabwtqW7rfe4\n"
+"+MfkWEJ9Y2s6iMs3JWnwPOX9G9R39PiAD4vAghHJyHHttS9Ipxmvp0hThu0x7a4g\n"
+"8BfUpqgjAkEA4aFAmzarWKigREAACVTYH2RHpXbuk05vF9WqfMPiEvQUd5a1q6vc\n"
+"xkGZsE3v/TExLjPRZP4FeUNV5sD7THzA3QJBAJxPoRlNx3GCEAlDdfnWGPX9JI09\n"
+"hC40RWUcSI7ttjJTI1+an1kWuBnLChhaRpU/tFjikTNLmmMmPHUihIRfDI8CQG7g\n"
+"3WzpKr8A7vFbOilbxnF2yDaqAYfmTXW7DHMPl/OUetJh/5kDdhT/e9VGF5+nIvH/\n"
+"iPFGW85Bpt8lCtmFnQkCQQDjpp9iy2qesE7KKX4Kv3++QfCJ2w3g7lwg4iyncoDd\n"
+"JrM53p29HROM21R6eekvqeWIe9tEX754b+E/N60ZjpGm\n"
+"-----END RSA PRIVATE KEY-----\n",
+
+"-----BEGIN RSA PRIVATE KEY-----\n"
+"MIICXgIBAAKBgQDdDn3H+Eu0AW5GKohqDBntw6ubnd3VaJwZGzZyga4J2kLg8peP\n"
+"RAW6GDD6pcHzW+KZbFWHtRk70FSwvmyGcf+DY0r5tfyCHyDGmbJyPR0o6OVCgSFl\n"
+"ccf4eDvbyszzMdlx3uL05ABIpCShoKtEUqvyIQla3Jon+QBwuVkizMzyVwIDAQAB\n"
+"AoGACoKh4Fwh3VEkGRn0mnYw1Wk0Q5Xh8j+jDF6K3C7mQ3mpLGDca+dkDlEQIxq2\n"
+"egeoYnsQJf+qT3m8TRsAtfO9nj7+7IX4BfCtdIi4RNcorbs5YMWtFyaywnM6SQjS\n"
+"+1qf74aL4On9WRO2FtvnTMjFAAkiWNbQp7mWwTmB59i620ECQQDwde6/PwhUzvZh\n"
+"dyslKJdna5RjkDQyDIuh0zD/tFZ0Iko7Luec8q6n52ev/n0OiTLGetUh8goePsPP\n"
+"HVZHidNJAkEA61eMCmmu+GCAg2vJRtL5sDakAXsbP5M9Bf/QVHXtc4EVXHC6T2ld\n"
+"bldOJriNbBThBuPNmlQbssn9FApkyWT4nwJBAIuHIv3+CUuMvBJaH8L0BsaP+g67\n"
+"wk24Ud2Yujnl3rSMoR4uXV8IwqfS8quAs/gXTEs3QyzrUUuzh9NKZqIkK2ECQQCz\n"
+"vivBEDKIlPvSZBJYO25kfXcJgoKvLb9fw5/TwjXXD/HGpnpFiI3JZnjT7gRlVhT/\n"
+"9CDmC/MTvF3EXqPXhXy1AkEAo3a2me23Ljmub21jycSKaCk09dK85QTRRMe9c/hs\n"
+"i+pcGi9ZZW0Mm7cyQo47oXjNurkkv0fEvXIobVTEXAGU7w==\n"
+"-----END RSA PRIVATE KEY-----\n",
+
+"-----BEGIN RSA PRIVATE KEY-----\n"
+"MIICXAIBAAKBgQCv8R1IbfYnE3R3kNeezJ7m02XnyCBDDy0YfrQldQ+urdg1CFye\n"
+"bO0iPniJb8fmV8NW7x6nUZTDznCg+igroKXtK/w0WYmJJiH4A7Oi5xNjAfRIPvJ/\n"
+"J5GI8szS8rH8tp8pW1h8k/kNg2pnBjwQ2U9omhp95RGaHDQSRYzzH/fEFQIDAQAB\n"
+"AoGAcy7+BcH/iZuB/xjzIIJDcUhqibCJ9n0D/+pLU85sYuZrCmUcBZe4M1gEn61v\n"
+"iExilRJc1hthskL/l1POYql8lk+aqeeDuh38fWJj60TCV/sENiuXOsTmoFVA5pNn\n"
+"lwlG8JlpBMsgr1fGqg1C/WLFfMmvXdKVGvpRqI06j7AYUa0CQQDfZ5rI+FhXBlxo\n"
+"PR5CM1LB90DuHUMW+Kqoj0c9d2esXEQM7UqQ/9BiBQbL6Py7Z3VwCxibOqyz7+V7\n"
+"2aGUMAKnAkEAyZy5Mu2tHs6YBBxPYam7huzMUYjddN7ixAZUyGwxQp9kTIF2NbSQ\n"
+"yVDjKrco3s2lO4qj4pSumwVe3GGlsi6G4wJAOOS3pIqqZK84BUvbUtyjLMZ9AKbv\n"
+"GQCG5ZpneB3ahyiQJAKiRL8BIJVLH87b3hYA8GHDCHUu2jwz4xCPd5+qbQJAV0TP\n"
+"pYvb9AnZI25drhiaY7z8dA6aTYxs/A0Bhf/PEteLwtIHKRgP1BR/QG4n8slxTGSm\n"
+"q91P9ypL9XkPECGzoQJBAIMvGEM7ZGevQHBjJ8HhU8IsgT4cYH/XEYb8jRy4F+Ui\n"
+"jKxHPxLuFK4urAZunNUNrqhT0PxbB7hRjtHZrmFkrcc=\n"
+"-----END RSA PRIVATE KEY-----\n",
+
+"-----BEGIN RSA PRIVATE KEY-----\n"
+"MIICXQIBAAKBgQDSpmV8ncLwc8gXzdFsZGPDtMO7C/IN9jKCIK13WIseMg1APlMt\n"
+"PB5lMQ9fa3m9ZRU0L8HzRo+u/Xdos3yIBI38X2Avy0laGKnQxiOKaDT/5ZHeiBBh\n"
+"nMZjP2WY5V1sgqNP9RD8enE6WaSvq1j0BM++mn9KEe//5+dWD8tboBKF4QIDAQAB\n"
+"AoGBALgVoerdE1Z+WAY1XyaSNHz6o3H6ZnW9CTaex/jb7/dbVikmThnhx842qXCB\n"
+"w8m3ZGhOs/edWkNaTde5wsI6+LhVGco/PWxN4v61jokxUU+5KvUvGacXhXIjzKwG\n"
+"DrNCYmle62QCI1z4+TLQW/Lq+jw2Wzk70NWEvoP58gt5SJoBAkEA9wubRKRs49LW\n"
+"5JNQZ9hjc+mAfP9YK/sMe4jkdloMMWXjSMlF3Z4mI9XQSpfbBqwWIBXsjU/15LIS\n"
+"ftmujZsMKQJBANpJEZI7UFoRdSP7AlM0YJuXWnVGyn/K+VIeEso5AlZdKXCTpxqp\n"
+"9blWq0UVC6jLesZ5UNPuBiAnrBaVwDA8YvkCQF+FQVfdK607TJO80g4VAP9EfcXX\n"
+"BUScIUtytsN8NdKzzpnKGRWDnMOmXI87ABkoWLW3RGuvSyhOIhCiInfmR2ECQASc\n"
+"FmroJcJBLCAeZOYs7P1cLOTdIdmhB7LcP7lVit8YCJAADj9Z536KfgNvdleSNH2M\n"
+"glB3blmvfMrdTrm2DMECQQDj6GJ/Tc2rCsq534xknasVjrgtJMQFxmQCTVgBx9pc\n"
+"gTflJAHAmNDvstacVqeObLCF2ZIvya8fSXGbDOJYeGDv\n"
+"-----END RSA PRIVATE KEY-----\n",
+
+"-----BEGIN RSA PRIVATE KEY-----\n"
+"MIICXAIBAAKBgQDGgUJAm7vf/3focNGwzv4TkzYF2XwpAirnb61dyxvfug1zKv2k\n"
+"AUg3qACiurR7JrI+kAbmxEnNaKV7ts7uO763wP9KE8YAuFZsp7NFA295rEZhw38T\n"
+"rUlWHMCeaZ3mqW2q8gA14C/ZJCG4gS91SIHLjNGsbHwr2Jvri2ItwIP8FQIDAQAB\n"
+"AoGAONceb32oiHWQkkBr6uL6ogRPPdGO2fdC7c5uqCLWsnOGEmpHAsVTNoym0fIA\n"
+"aBsmgv+e2klukKDccdZg3prA+z7lHcc2a4bIFguF6ei80hLIis/dds66fFXofCzy\n"
+"DMlkncSbJwIvQHG9gblxp9qSKElZF7XjABZEImarfUlakGkCQQD//msGy5N0ZhMI\n"
+"yGMXkwXRJXfmRrIrOqHx6u1eUp4OuqDW+hBz4KCHnWfuRJkNGQIammSf18jPasP5\n"
+"YHyr/LifAkEAxoJ8R8Vusexo9ZjuU44qXCSvJQ26UBV7mn6TGEAn2DRK1RWKDaHv\n"
+"j2vnRjt3CO9WPDQL7SB/1HNAy+dIMPyqywJBAIB6tESIz8zPniX+TJ18UKMTZwXP\n"
+"3YQMvVKpUdDRLjq+OBMtFizSRD9MJOlUzGvibUfkzTPcHRDcyNbUMj4vbIkCQBx4\n"
+"6sqAjvgGKKfRX52sbnb47AYsieSisC/gp8h6qzxfg7w8cqix6WJw36M7ND+b1Iqe\n"
+"DHfeiXc3cLvOWJRuKTECQCEYkujtSjXWb26xaESFWGtUI/nEvCyqYPQAFBpaGzQ3\n"
+"tiTDeKHzypesWYoTxOiNQWCQMLrFGuUbDpYOuDOVNjw=\n"
+"-----END RSA PRIVATE KEY-----\n",
+
+"-----BEGIN RSA PRIVATE KEY-----\n"
+"MIICXQIBAAKBgQCcwSAfytnspSSDX/sKmCPOMnpuCYeWA4wbz1wLyb63a8/KXhhG\n"
+"6o2W0kt3x1vnGZkeWwZOeBFUqwoc+xHhoNcZFsMOyqbqA3UMZW5cx27MsexRTQHs\n"
+"Go1newu/E+8NNCohY51G7z1Hdo0L6mi/Tldh7puuGsMwKqNG/Vvo/GQDgwIDAQAB\n"
+"AoGBAIUdpBAbjXDe1OET0vYuOMnUKA/l29RS8tpy/zGrg1/0GCM8QNWIPfEEaL4w\n"
+"+CSKonMazYI5iE4kaZQuygKXOdFqKxX8nrGK2hR0DIEUHhhiqyGMUKrf4ELkAJzK\n"
+"tHtcO64OFEU2EGa72wCmyk2MhqhLxWxA7E00x24uvW6pen6xAkEAzHhbzlRgLZ+K\n"
+"QuXmQHEqkGaS2Ccf6c9TA5Bf5S2/5zBl+OqVyJJQH0yrbPYR6Nn1NeSv3R4IDJYg\n"
+"fSZLaVzWHQJBAMRCU6QtTnZoQ97pLvXCSKRYKJF+CnE3zDFTyoJrpK0W1FSnb1EE\n"
+"DWjjdSdMLynf/InX+VOaLk3Gxwjme4NKjh8CQQCg2b4/HplayrsVzY3I/D2jw02Z\n"
+"xY2RfYusrhMCU284DBbsLn8OfiuRs9rXqOyF5ZDFiNXgeROT8zYzvcBtbp7xAkBU\n"
+"ZET9IvJLXjhZISItUXbVHIeNUIqC9sBaMbKx9EGioF97a2gliT2O7cgRtuPM+ODq\n"
+"ETHILlNc5G3vuNRBt4x3AkBV98Y1SZA3TQlUVTsjGraxkFTfU1IlomiOdOwTQ+xZ\n"
+"x+JxhhgZwZ+kgI3PidEufFCTZJ3WO6Wk9gk18Bx7CLjm\n"
+"-----END RSA PRIVATE KEY-----\n",
+
+"-----BEGIN RSA PRIVATE KEY-----\n"
+"MIICXgIBAAKBgQDq/K7wNW3fcTbaRTjNZlM4W0G7tKeO+X0bca4+9uin3ML3ogNJ\n"
+"6qT/B0QAZB6Vyi9kKa3E8plQkjmPuX8Q27zj2QjEuDZ12RGFnikeOosUhOYiDh3Z\n"
+"T9CHnr6stozzgk79Xd6VI7bqRcgRwbY0uc9QVr6vwddyIfSploSpVcgspQIDAQAB\n"
+"AoGBAJfUpo/sZc6uzxtfCKGmkPTj+ef3hSBbUZuu60AhtxfnC06HrwpOg0eJAUYj\n"
+"aqOsHMziJTYQ7kDiCjE0UMaqxDNS5hueumznq2xM2mSN0nYoktU00kpANVkW4VPA\n"
+"33TB16DyqlKq2/21Rs1g8/8+IKkKDbRLTC//1WqNHASQVoGNAkEA/+z4hxTVXZkr\n"
+"9hz29tAHKURlqzxUEKLnS0eL+XGJRNfGJ+65eXL+gFiIbTnpVeidL1+lKWkZyYzl\n"
+"75cNRdUHhwJBAOsOJ9mUOqTbLW5tzh18ewZGOa1JcxhOvf2E1d56N8tDK6lvoqkF\n"
+"oUUb8kIweDxPLCVLCl8qFrbjn619fxDInXMCQAfEZGKNIlCd5nSoumIRPDZnagKB\n"
+"aTe8CfMB7+CZLoZVWiE6IIzsDYdNqI5QFKHT1nlqmLOiCfNRAGV+GxwEdB8CQQDE\n"
+"sHu4HclU2fMSTOAE3H01qt3om2WsGXfyBI3SNQMrG3IVvkymkwd4BQKbUGPMU5Pl\n"
+"QP3U1CtdruuXCUSijrzxAkEAoqYub6+0zM8fakSQZcZ01TG9Fuo2xVFDCQsvqR3m\n"
+"ZhRT/oinIvOxSh4fQs40bmt1RBmc2L1Is6YB2NTVQEBZDQ==\n"
+"-----END RSA PRIVATE KEY-----\n",
+
+"-----BEGIN RSA PRIVATE KEY-----\n"
+"MIICWwIBAAKBgQCrf0rPvHYaGYQrc1ciRwaONs8TUvSVmUU98HMYXoFEkBL4CAGH\n"
+"4oNHFk8kXHEOsBED0eccSYegWhqKHSz7PbjmJaXloExWrtx5ea3Twf8VTgcfDWQP\n"
+"0TzD3G1TYjAFPQ1/LAZCpQFmwpMmTGGxegUhOzkpEWXdLVEVc9Uw4C4L2QIDAQAB\n"
+"AoGAZXAJZA5pHM7y6nBynYe9TOkGWru6h7H8zsImkcd0VoWRcrvpi+JjG+0KKsuy\n"
+"46kop0XEmWq0mhgxknfnX0QG1MKTqGMIUGN4qCaezOabIpCOdA4d/pr/mWoNgOWw\n"
+"9Kc/tNCrKxPKsQMAlWP6ktHN30XRSlHgAjSeUVUiNHztvTECQQDUNin2nyIvj8ZA\n"
+"QAsFW9qW+TiTkeUK6yiZ9Gvgf20gwZRWOe5/xnMxVvtN6v7Av1ew/l4VhBoj/w5g\n"
+"ydIZk+2LAkEAzuJwdt+ccllG19qmEcbo9XFafgi2PvlEjPJmT1rHV2ns/7HIMu27\n"
+"PJY36GgExSfFco6VmicaoOt+RKg+5acgqwJBAKQxAEjcGWQ5VsgRhTVxO3DChX7Q\n"
+"TColhrWPwwPhM/s7K92HVzwvvKL5TNmdr9xMb7n3Ja56FouxZVuH6/J0XT8CQAat\n"
+"Mhnz/3WFQg8HRGLAe5YoMVZt64u+uaKe1ARtlo9QoNBjqWVTXL6IzocWjEjcjrey\n"
+"uEtARdC5qNqIX3dD3H8CP3pVCPvpHOTxkUaktmLYowSA1HSfO9wkE6bMCHhkLwXF\n"
+"yTIJ+N7c5u5YN1B6hhVqpKbdnSv+K0MQ0xbfwOWNMw==\n"
+"-----END RSA PRIVATE KEY-----\n",
+
+"-----BEGIN RSA PRIVATE KEY-----\n"
+"MIICXAIBAAKBgQDGQmrKfO3WovoXkOTSh/shO9qjbX4izhg4pccVU3Tp45v/dgAE\n"
+"uDUuaa/clToyH5AhOtuazO/asC3ZNajg1ia5VPzmQU3gtqiIZIEXFaOovPlOrXru\n"
+"wyQnxaGORndJwfDXicG6bUwI+PDpNq8c4VOTujReeF0r74qMSc7TQLVlUQIDAQAB\n"
+"AoGAakR/aTm9YibJVohbnl00xoOGlcLCsXU2lmaFZ3DsYdGWdD+TkvQJzW7ozJtQ\n"
+"Lj2sy6L4wujGR7nXWW3hr2IaLpoc1UoyJpieAZM5os6bMN+N4MCqdcZMlazMtSWV\n"
+"UDO7O7xQGFpcvvZmnfKCyluFaJ5K/tWxP+2TnS1/m0BDRIECQQD5DYvToA0eKBt+\n"
+"7K4eEI8pzDot9NlcL21D86kNgpmuY4pifALU7GvXr299JpFFiYa2A1JVRfpQaoI3\n"
+"hZzz0ze1AkEAy8opWJP+T2q4reD5Qq5UjjrHUXFID23KeJEjh5YF40/bHqyVpWVR\n"
+"UMntNgAzs+13vRij48Zn6I8GRhStaQ3ArQJASPyFS8GN1paeaDXoWPs1WWR2cF1f\n"
+"DbsAZHeVxVXOv+J//ZimI8wdVpodLCoPTLee+NxEVqUpVEPCYY8QjgwKOQJAATmj\n"
+"6f5pxvxzQ8hYd0gpBfngfOLbdgxI7VSiDAyg2G8AeDy9YZMsW/n6zRpPNUO2NpLR\n"
+"WWs18LX7aaxyJnGIuQJBAPPfy9pd4XEFsRBIIe3N23Gua1XkS/407RJtAGm73Vrt\n"
+"QhtWh3i6D5gfpEApMoaE8aaQQ7H0z+0Uh1t8SWesy10=\n"
+"-----END RSA PRIVATE KEY-----\n",
+
+"-----BEGIN RSA PRIVATE KEY-----\n"
+"MIICWwIBAAKBgQCc/M/X8etUqrxnmH3PyuAYLIPZhwNySch8qz9NB47izYjxzuBG\n"
+"GSls6H7WeKIrB8UJY1gW8TLkdOLcrI/0hTANNHEPaueOE0xdABFj7tAaiiGPIM25\n"
+"N0wc76me0ZAMYJrZTHk8JZK153y9wInYBwVZreXCVSVf11RuVwe+iFQa5QIDAQAB\n"
+"AoGAQC4XJtivdhDLL6snHFF7pkZkrQTGgu3pOhakrXA+mTigGQOTqvTUe8LdP/9X\n"
+"hTIK+tiTheWcAcxLhx5BSB0/VDKjYhS0ROpTc33Iq9KalOQaTJbBYGA4eagpQjwU\n"
+"jGwr9u2sUsM9WI/Jg0VvLSKhfnNwYIUzLpK3BbWb2qAdh+0CQQDQ2s/8DlibFSBK\n"
+"UsFK7lLpV8UgMk9CkaNM2BPzI8Hsjpp6s3pULVRd36m4YTSg15EEHv7bZ1N/+krX\n"
+"mXb9xUULAkEAwGy5wHsUSjTK+kntkNXjlCU/+9R+HFpzg9Bwm/PqXTBwEWeU24hV\n"
+"iRjPvqPtWFZrWi/nfcviuMaqtdliw1I1zwJAZ2mQxhtMYC2LuYFUWAe9YfClmJWQ\n"
+"jUOTef8bka5I3RqW/t5TWc7AEWMnpDXtWx6hnUrDolt9Cschu7MvKeQ9lQJAL18U\n"
+"46PpPNN+XNuyVoOxgRkihVasrUI/SeYYsuv7eHGiRUagyOLpW9T139LvbV3pE8zT\n"
+"So7VA/Q0towL2lX01QJAGcoBNNouSpum9+5NvGQK1XXsZweawE+pFR2BE5XcjG+n\n"
+"FnaLEUBX7nTxhTU2cSQET1PKRNp568a281NEna0nxw==\n"
+"-----END RSA PRIVATE KEY-----\n",
+
+"-----BEGIN RSA PRIVATE KEY-----\n"
+"MIICXAIBAAKBgQDFOqqGG/VtIScxayZYZ+BT+hcs5W1bD5qRxunbG9O36UVT18UE\n"
+"CWw9HUf0Q5sDMGvVmBxwZ4GjbR5FDPfhIXaRCzobnejJXq/0k+O5NAVkcSPtJvhK\n"
+"AaUqBrWA41vnjKOtJudTsZLfufKafzYwVonze7fXGyVsBRjVwHNS4iqq2QIDAQAB\n"
+"AoGAJCoStI6R3RXUKvKb0GATuTJFZ50WBTmCPTK9FMkwdCuY47vPy2Ky7y3cUMTI\n"
+"urf5PewrYs0H72CFyWGMXkKVi8aOYshsATEXMfGSqOcqXn+UDssRzvabZFlpnAUa\n"
+"WDVt/iN092AdakXNna7/DxrLisDpq8HHJfjtlWGPfkXRg4ECQQDpHeKimTvwJcPc\n"
+"iDa6Qb/n9gwLeRckfzhYtfX1luJYLIOHh+J9vjQN75thenBLQB/B6qlKtOn9ejxg\n"
+"5z+3zIOpAkEA2JbxXVTCOA802p9khvHxDtLHdKi3w/BjjJiC7Mgqo69ZI+s3PB9E\n"
+"F2HJA69kZqpGqvybWHDapjWsq7rcMlxrsQJBAME2yvR3y00VEAyGPc4M1vF8ZqlP\n"
+"uRW/+ETWtEDUyU/JvU6lGt2bu2tdkEyv/cjxIiFIzP4litdT7B1pLc+6S9kCQBwE\n"
+"usiWFGHoJbA6emiyl7qRLdg7kzo3uMkRWa6D3nA6WM+6t/SBHu/faH+fit91G5s2\n"
+"/mmcf8yMmP/GNoIVTqECQFl4Pt6yGiz/YVoYSp35ljY5n3JB6T8o2pOmIrRLuPmT\n"
+"6kgyygtJBAmx5nnQoeG8n08tl9QakWznKzkNJ0DIFKI=\n"
+"-----END RSA PRIVATE KEY-----\n",
+
+"-----BEGIN RSA PRIVATE KEY-----\n"
+"MIICXQIBAAKBgQDCaOqJ0lsSAEBcnNB6X7BvVcEcol+evi/nJsPe0uT1SbtW50Ch\n"
+"vYOHwK6aQR2C5x9VSs47cLynTL7tNt5d8oeryF3NpI8VTPLImDJCcvUZhS7p4bxn\n"
+"JO+Wm+D/e3TWfyjreuWtdL+Mfimw2gzwWuBEtmj51GzQ89eYm7fh11SB6QIDAQAB\n"
+"AoGAWaakMbZNxPlUtOCjyysBY/Y5vYira7rswD3CKak7aFn+CE9QIMYSN7IFUqEg\n"
+"iNMoQd7jR8nvVX8wtJeO5+gF48W13C3n8FZSrW7c5N3bmfMIgo0xa/TGfeXHP98o\n"
+"7vhH0I58j3ZZt0Q+3wTm7t7WPE/nJzgrCk30TqmoaEmstTkCQQDtV6YZ6juEK2Lp\n"
+"LGUiqohcS/WJxvFrF5+LNpk86Xdgomf6FphZlkq42KYkvl7qibKDcfDqLKTbHHle\n"
+"vQQeCgZ7AkEA0bFHi7F8o4iHtKleBvt4QCj1neA0q3CRDypCI5EqFSrNpxY4Krhh\n"
+"WYSVX+xT00QYaCpKKWfYQztCw7Anylv96wJACl86Mwe5ch0zRV1bThiFvQLUyCCZ\n"
+"jESMBFlueOr6/I4cXSF/puqaeVl+aTyoiTdbRcNE8/bffXPRGgLIm0d04QJBAJSY\n"
+"lmTN789Lby99Xh6AkaSV4ghw26Ip8QHYJmph8npxjK69Niw/4Oy44cnKBVUPSmR2\n"
+"o3tYFY7/Lb7S1D+4lOUCQQDbMQUGVsZT+ZjuOG1bAjIuXoAOfOd3mgH5VgQHjSgJ\n"
+"ourZtlJ4OUpNrq9IfWqPkM+zSE8+0Dk8/9MS5ngBA/SJ\n"
+"-----END RSA PRIVATE KEY-----\n",
+
+"-----BEGIN RSA PRIVATE KEY-----\n"
+"MIICXQIBAAKBgQDNbHjwg+7tVNr9erMLowXRnIcttp4pUJbr3B7Jo/u+kD/Yo3F3\n"
+"4rIKhHpJl1uEHP1QmvAD+4ApFFI2hNG54xYI8dGflxL5HOs5xxyOPpkrwzQ8Qvnv\n"
+"LPg7Gf6PAW9zF4McG4wK0TkrV28G6NhqcPs5VFY6UyvfZ0fEdWAeoWTIfQIDAQAB\n"
+"AoGBAKOmkMp7MLLd8QAS6eSRYSdWHdLrMyES1MjduaFGBF4SKOr7en/Zl6ENXSaX\n"
+"cA7V0XCPnjpt9/HCAKTyNupx4LCeFWiqdu8VGXhlzX8bdb896OSR2brKbxgRY5tF\n"
+"36uL8akrZdrYgocykQCxmRARMB7/rHwDusiamjL6RUZ3+c45AkEA6UPTVmKZQRMr\n"
+"A7Qgg5nXrXo9117Lpqf3FdZ1wdni9V59Ptf5xrx9oGZNZzctJPXSAH4M4cumSJrV\n"
+"sZ1V8qE7AwJBAOFx+5luLrVKrdlG7MyOhTAdhKYUvKIvL4wvVSY6y+L2nNEx/cTx\n"
+"KYbxGC+H1RJbkCS09rYir3VfDRWQ3W1c1n8CQH+X4hn2hO3blkPIW6CgniD+JKWR\n"
+"7MOUTMtdK7yFemfM76VYbgAPSohabSxwOfllnSE30cQQqTw9tXYaIdE98BECQG+M\n"
+"QWxSS0QillB6unIgVqBPCrJOcmNhK4qWZPBMiVNcqI0Nyj2nAeAl7MyfzfqOWY0A\n"
+"CU5nbR+LD2NLUXRqSisCQQCN3IGv1WOWInmA5xhU6vCFDX5u48Dcji7VLJO/Nv/i\n"
+"b/zHKAgjHk5Js7bi5ZWEGaUgA4Jt6cKmGdERheqTMKxx\n"
+"-----END RSA PRIVATE KEY-----\n"
+};
+
+static const char *PREGEN_KEYS_2048[] = {
+"-----BEGIN RSA PRIVATE KEY-----\n"
+"MIIEpAIBAAKCAQEAoksI1qIuIaFCqT4QbgDvOQCmr9Z9F0E7ku+U5Ep/5dWNANqB\n"
+"bSzAOq0+cxiisfF+H4desoqiWDUwlOwXH74qD3ZsbChhvFUD78cQBWQkF+whLVHb\n"
+"296QmF0LZqosqz9HMS9CdoMUc1brZb78Hb25QIOOjrg25KYHLZHaqcet1wfhHow6\n"
+"Uehc6QTuWgOWFhJnfiXzYgen2o8lnLixxZozhk7Lm7Aix9ur2ckXdQ2Wgny4xw70\n"
+"JW84Hapnd8oFUD98XXrExk4VFuIcA8qo7r7y18II6wx4Cw1suKru6bhW65cM/y51\n"
+"KC4lB7VkvuoJCelRFdM1PfKZLv2tJP63oAqJrQIDAQABAoIBAQCWc38PEqw3avqU\n"
+"UMAEaoNa0bq1Gd8/Nq8WqVnbRSFKHO2pk+cWIb1W6BITuwvgcGKesezdEV4s7apK\n"
+"9I7/U1hEm2Ep50mrwRh0KZM1nD9Fmharn851Bt//D4qpMytT2caS1yADI8NKpZJ1\n"
+"8VZh7+cT4qG+txHUaAIRgbw3VrBWvTIMu6SOSOZm+e3eOr5UU3du1KvjdJHJ2c2k\n"
+"TceHvUdKxV7OYt+BBSN1oBOhs3ajUSRge1v3twRDg3cmbwG0DeXvwHNhGUTcF8IH\n"
+"JO1RF5njbkFvyqdAi3ltjU41zYd4OMuPtrwzFOtxUjKT62Soz109HUXXE2CGKFPZ\n"
+"PVi5/BIhAoGBANN1xqS5BgHszIB0nXbw5ImYpTRmyhO0KsTblBT9+8Q/B7BCK7bM\n"
+"zl+dOPeyvEadSwE7RSMMt6CAlTakWIf3Quw/VZajvXy9C9/LHf52pEKXjxMFMPKE\n"
+"aGLHpQnwMtDi8/H8AEAXxI3hpxB2KVR7sAYHWihSGjRJ6oPGvEmKEkb5AoGBAMR6\n"
+"G2PKz0xk1vFrjfjSY+y13gH/t7xHaXUggjggUSGKaknQh2BDUllXjadeI0fi1eLW\n"
+"r98ZImZZgntAgjaIZ4bAlooTDk4gRHaz9jI+z8lsRwOKnWdiigM7txiXZTMVwMqj\n"
+"o5mMNGMA+A+ACkTViRHmkDI7S/9FqAvnbOqVwgFVAoGBALUcY6WDvwx5B3Jh7tgH\n"
+"XIYpEh3+h8c2gYcX1g3gtvkPTwN8uToY0gz8eOVV1YHZiHsmi4GIi+HRH3usaRMT\n"
+"COOVHzYlSc8Dj57+tdLTRL6wVl9hC9o647ju64DGlI9qQquYPZKniLZIdbFYsu9j\n"
+"/JA9Tc/I+h6czFpPJccKlbrpAoGAAPWXrKUQ3g6f/g3IY66jTkSVEO1uuDyhBzFh\n"
+"cWS3ALLsUe/yuUWa4VTMHEUZZwB0iucBdNVqlZVaTb/C4wFHgCDwmzv8leUScIHw\n"
+"cc5ctV8R+bJzkk2o3tsrybLzi4xPpK2n3tgQaWtXyruVUUC5qpy1l4kylcyBRY2b\n"
+"uomAqQECgYAiCNWtuWIDlRBcvtIB+kHguzcoFT3vTCCNhalTEn0zi/tbi+voQgVJ\n"
+"SDJNptZv+6vRwQ/HfcQtljKIPO6hUZPYaFWRNhgbh7Ay85lRXYXQOottE8ayReBk\n"
+"zZb0fl853Qah4DPsaOugAvhjjKeBmKg6bFWO1z6hj18I3UpDf2YnVQ==\n"
+"-----END RSA PRIVATE KEY-----\n",
+
+"-----BEGIN RSA PRIVATE KEY-----\n"
+"MIIEpQIBAAKCAQEAssO0r37mSJNAkc/ISwXBsu9JjyLeWlsHPAhylQGkSAdp2rjz\n"
+"E6AT0Eh3wrocNO31I4pvHReAuh1QedGY6T1cQwO/WAAhQtRCBQDK12qWRgfbC11y\n"
+"Xu7zNYPd1Z7YIRy+FxhbL5f+lv3rEUv0HUG5c3CWhLtbANKg+jOieIDzA4Yp1s55\n"
+"ynodQBUkTZrwQiT0P8yDSjiasf+clgJRfA1k2XK12KSAMRgyDuPTE4OtBxBvUM3L\n"
+"Zvxs81PsmcOuAG4DLaFTg2a/QkCjt2VC1SYYuh/LVxpL41FFh3eMoK5g5deHkgRe\n"
+"tlywKjAHIDJu/qgNzNgNW7ymwn2CfBvry9h0/wIDAQABAoIBAEMZ4wDdCWPEokAZ\n"
+"Vn2Ss5qO53WrCPuxn42RPjFgZGIFJl7LfbKoK8fK6+lUIrJbf+DPXdX1tIQn7MVN\n"
+"P7CNL8yX44MMyW9kbUOjgIBLqgyvdjFV6lBoMTKtRN+iuE31lATnR5Md4pqaxVnA\n"
+"wOkaepoycM1x5j7w0SwZparF/HIdkYv0y/MysqT9ByupPA4Fqp/iRSrosHXahNtI\n"
+"KZYj1TyERYtuDXq91P4dr/pWq3FmDNI8O3upblkL0YouvG/ZlFLdiNy77XbAyWcX\n"
+"ps3YDddM+vECnXO3+sa3ZxgBYvXJdWrrIzM5A+jCkDRZQGsFAzK5I5/S7C2ljt6i\n"
+"SmzqvMECgYEA16bGy2XTi6KBPb8aev/OBgK9XuGLwUqK1m15mS9Y2qPHmuc22qaZ\n"
+"hw6zginPFrxAEtQWKanhZy4aVqlLkDPLwRnyeuMo1EZAc5B1gZ5ViSAKxBq99hA9\n"
+"eqyakdb+IUQsEnRDxSc2gqUQ0EagksUyw5wGG5Q/CVEALmS/r1SU3KUCgYEA1DYf\n"
+"6JYdzuRtule3vYeWXKf8sOJpdplgWV7tvLrKkQhdE564uwMCYB23HvYfwWqEdDYG\n"
+"fsYg/ur/stk9MDZ3wZKffTEM8V3sX1t1JXnC3ogSAgMGhLZ3ILOLqkoO4BEZJnsS\n"
+"dMdiNijlAtQkqs/BO/UVUAKysCtKP3v/+1775dMCgYEAvLjGFjApfnSbV/cK7IM6\n"
+"wEXbhdIqZOCgOeEaXjVyM/zKbMRVW+oaR3hVHd8KzSG3jQKv1oxFpu9Qu3ByoWLC\n"
+"uF3Ft0debs6ADuJoAyQWROeWpGGmxlUWCGpO5rxYL7KiQxAeUsXrTU+5NBvq4CbV\n"
+"MxwyuCX3OGb7mp4upfiGQcUCgYEAuhVsDYv1P4LXJVvd5viKRV2ZG5KuYC1Ga5fu\n"
+"aFxzXJI07At2eaa94oKsHR494mEBHNZzA5/BN0fiSHZuTWS1xqxH5oOokc6Gg2ez\n"
+"ZdVLp88x20nD4YQPGkHW6tBeEuVrZG7vVC+yU0Ow7bYRISdkjqrusWZsQkbzqI+X\n"
+"fFliEbkCgYEAu8x+47M1ordbI7NmbBGyiyP0r7nMRCZ+KEvGeCNYracWmsnCNnfV\n"
+"zR2UzmwtSainw3Ho8Jv/rWDC8RIDauyBRYEi2VqOnUzT2ca0iymQyLeBCudAQuio\n"
+"drOu4JU8RzZ3Ad6V3DNFnaqmX/7GA9Pa2GI8NJMyb8p1GAGv7Gi8nxc=\n"
+"-----END RSA PRIVATE KEY-----\n",
+
+"-----BEGIN RSA PRIVATE KEY-----\n"
+"MIIEowIBAAKCAQEAt01S8JuEwWy/Hzb90yO2O7oGWq3GfvfDpFOF4OQnwG3kQ/BP\n"
+"4MoPDCYHdqb3iI9aD3vykZA6Q8zpdfGwjm4+bHrgRdiSmZWv8NvRwuQ5Ji9xbiGn\n"
+"hA1XwqH9hvgFTiy6tRvirWSJ7kzH3Q/bEGpCbHUQkwMog4v6yCNKNrjlwjN++eCi\n"
+"gFK/0RMOJMLOs8BD3zY+lKjd/pd8LBRujkMyUF5SryeRueAFjD2sq4OXq8DPABGt\n"
+"zdR6vbTcsi4JwP1Q6y4x0/LIWEprzzewNU63I5E2zj0WnoRGAIM4aF+VuqcHjWUx\n"
+"VWnyLZldSen6lScZ4xj4seitiDbSFvtFkDF6VwIDAQABAoIBAGTP9im2ntDyyjqU\n"
+"uA0DuxomOZBtupniEouyFBOX5/UBe2WSKZxsBNKdp8UuFz3X+aRCeyprtF/NtyjT\n"
+"AFOVdmebPPWtIxOtK9LAUyFo+7VwqmXzxHnwDLBS/2jXx7MzDozFBWpvvRx+xf1i\n"
+"1wy0JEwaJj90oTeYKRkhr5NhJZwkX8zCNYaemBd3kHB3aGWGJasI1Y81UezeRKCn\n"
+"hSbn2CrWalI7pyJ4lsavM11nIq1Eu2ZthJiNCMghbYrHoBHd+iVWiCYchP2rNEWV\n"
+"sdHtaVHtQ9zdZ43bao3OzPu7lAjd6UAbxsuhUe+a2YdDz/+Up+6+BvQf1FCfYIjW\n"
+"KFUdCoECgYEA4t5O+u0V9gkMUhKsevYb0zgc7O/mo8ivN+V++EpAtL0mhiwxeO8p\n"
+"oef0szLyhdULQeLN9pJQDCeAbkGdwIe3L+AKU8o8BFGEWLFysZjMg9In/UTrp5MN\n"
+"mMDy2SRKKu5BqsvdYH302xpZfHq1T2cMNDWE8lrZffduH06Cgq/XEtECgYEAztbj\n"
+"bhFneADnrvk609VnOQvoQEjySeCQKFQFRRI6k/FguqMisL2IRXnMaWammosdeCAg\n"
+"m7eZchnszHIst9cwZUKXUFqmAqeDuWSNdTI7uKZH6nT/A6IDlgdjaHsqhvpK0Ac9\n"
+"ngycdHONitOZh0ZG74pdWjf828Dwzf+CuYjl9KcCgYEAmIvI6ZqvkJ8m5Kzfw1Jn\n"
+"BVCOypbJK8oOX3R2Orea6KzjEYb3wQx3nwFcHX6danYFOskpmqlpH7MT/Y8rZsEa\n"
+"4RsxdoPedTzm08iFiXtn0R9nejp0hlov402iPXXUVSedih3IflBTa1w9XaEY9wog\n"
+"P57ZBSknYzcTmgNtaDiaUnECgYA5sWauhNw/dMEq5QmrnJK2LsQRakdqo+CR3x25\n"
+"LmR4b5Nze51pfvRLrLV/kMpXwQXvQ8bUqFl8og6S2CXxAWzWUcSy/RXhF6h+RbXP\n"
+"Qru1vWvB0fBvqvklF9p6giBSle3YKKzfMNVTBggs+OiR+uA+YHG5gHRfN2nzi5mC\n"
+"9tRtcQKBgBnDSi4lRCjRe9pPnyAYaa4iyBUGhjPysScSLY9orel89+qmTBQ/Py6J\n"
+"0+sefL4ZJaOsuaR2mSSPP/lbSkF9DMFs4tHbBqY+WkVNYLshAkauHwqv26HTVCSd\n"
+"QKzeb7uZw9lNaRIzDvy/3wfCLvXfdDozPFrOUgkyaBN5pJSA/4sv\n"
+"-----END RSA PRIVATE KEY-----\n",
+
+"-----BEGIN RSA PRIVATE KEY-----\n"
+"MIIEogIBAAKCAQEA9qtiDoJWqU/eSlpj381eG6UcDzfMguFh/q4e4s7QVdRYj5J0\n"
+"Msv0PCkti8JHuvQUyncRpOPccBkhNbVjNbjIgw1pHaIZNdVotUDhP0kseRyJ6z3M\n"
+"qbZ5qKn+0mHjVjPNItVDDe6tebYMT1BZpVyRrCOqY2v5z1ecLC+ReygmHgDpzg+L\n"
+"0rWfIxGT10IPZ8pAlcdEn6xt5aEhi7mPCX/xwqfQChPIJz6zVLEC8UaPtvDBohPR\n"
+"6NQTBTeZZAAtzrQ7+oNxfz1v6Fz6RwMei7Q+qOBnMiwpQmbcDBKABM2RnXSpD0LA\n"
+"1GR7/+CiV1HQoShWVvEwrSIlM6jVAJo6iqF6WQIDAQABAoIBAHqwcdxPnfUm4aTP\n"
+"4r9NcZKEhDlZgqJSoiA/0OL1BRC7xrTanmspoLhPrvTF1FG715+Aq8j9AQbMqQUC\n"
+"zG7LEwiEIhV4K9vn4uXMeHy206UFud/E5EhBl695pmJUB/Q3XcAGnQyP+77++o50\n"
+"o7IpIdeiAbzj1uP3aplbq5u7M4JV7fUZWA/368G4HolqFTxcAfBJ05GXlp97BBwY\n"
+"AnY3/pNrKMz0NiPf3nsJHYWK18up0JCLPL3tomc94wuNZ66spIazHIL9aaKY0q3V\n"
+"LkBrelndfYM1m4xRTnSOy6STu0qKTPOpX0C8XBLYs6uiXjRsChqSYwndCCeASaH3\n"
+"LGNIcbUCgYEA/m4qvt8tdT4wEvnE+QUxEELmBtT4UFa3NnQISrzNlhNeI0Zd2xlp\n"
+"SG0/pcw83mG2uX+V5xSaWL5LYfLBkvy83Y0yIWgYbbIkyyCOUZnTpwaDGU/FjWip\n"
+"3TfXf5qpAgiez94sV+MsFpKfG05yxJh5u+3sIyGTVUAxp0HPx4LVgbMCgYEA+DD1\n"
+"fu6ttpuV1UMrsFdjuk6gBvSbyJ9OilY2jT+yE7hSRc/yP3O9ikuR74tNlVrWTnO2\n"
+"0kcYbyLJXE2cGUC2q5e4r8TDGiozNfQ7/OC2M3XaJ+xJk4zMf/8PuDDpWr+18ZXA\n"
+"Pf+ibXWTFvZ6ZeUmpbrrfCrXdvmIZnwVuOI0FcMCgYAZn26emksxq3mb75tumJ9A\n"
+"S/xuY7Q+Iv2Adl7/Z9QscPbiBowdLIn1yUrHn7Hhk2WbeMXX57NDjKZ6zr+/1cQP\n"
+"a9DInHsZUP9zlWu/vAYcpAM/4VC71PaGWMFTEHhExCl6NZ2xnCcsfseXMGdOdSyN\n"
+"SICnaRI1W6mkdnQ+W2a1EQKBgGEKA3KVr6XuPy8bDEHuaTe29irCCQbwAq1j+ABS\n"
+"HzZGoyRYocbdYgZoda7LMJJs6c3SwHCHC66oU0KbtaTKAKImuDdBH2djiJJX4/yD\n"
+"f7mvIpTpdfsS2gJRn7vMo/CvdFv4ySl0gfV6OwCHbmPYrLuv0dLCjWwfNI2dhoC7\n"
+"MNIxAoGAIPSIG4BrShzbeX4c2L18iwIg+NlOcUbtl0Ccr1t6uLGI+ge/6I6T/5XH\n"
+"DPKqYIf0IRYV8suxpfQNKiz/C0NPffA1d1M2hvuAg2v09o2cSwvdcQwdmakKZ5bl\n"
+"sdCuYKdCIwomEUOz/4XgQrJl4XDUqxftJT6/egAjWvcIYvfNCsY=\n"
+"-----END RSA PRIVATE KEY-----\n",
+
+"-----BEGIN RSA PRIVATE KEY-----\n"
+"MIIEowIBAAKCAQEA1yHZMsgRLckL+v6rgpGq9qmxVBNDxeuul1V/QlFyOlcAk5n/\n"
+"uduTalSqGQhc4NEePMxq6nFui4ucpkZOozmcEnhV0N9jld9IB9rLGt4erdg7RKl9\n"
+"+gQ+zTn69j69U36E2I47H4dM69uxeSOyWP2Odxpw+biisa3o8mMz1zCmuj4GMDtG\n"
+"DlnSpthFzgQR6N1pbvxLXrWg5F16GqFiJOD7kXDfy4/l6kB/mDs1T/3r8kav6DqR\n"
+"c/t3aQZxgWGIpI7hc9Qgvp7coZRMey5dNOZEna3tqS8dn2tZlhkpYV5uyFUjmxjG\n"
+"TERSULQ7hvUqW+eshGGsnxFtL7ANnTSc4xECowIDAQABAoIBAFhJJMhpQFuIySjd\n"
+"AGeZ/g4x/3rgWQzNNp4WUR5XLEhy0eLA7ShJywp06kVRoEQGraEHxsyldldAGS5H\n"
+"ZhgoGTufNKB+PHER646FpJpHE1IGjfQUloVW3qr8I1iQ0MOGBWCVpf+/V7rnMsLi\n"
+"+lr421FXgYuJ0QKXuyRVv72M0q9U6i+ml3aVAhgW/19oFg+dW7YccX+9iVyD05Q5\n"
+"KR64tX8xd4wrAqfAgYA3erbbE6GTyHYD5K54kIgfRr/+pIU4qc1L7XOCblnqc/rI\n"
+"BilFysEC634r2MNe66uQvNui4oQTfBcFFlXg0zAmp7d5QE0ApOL6HpCsmbImm2uJ\n"
+"sdFNYyECgYEA716kfEv7HfnF0P3pAP2AOuEsW6t8q0UtWvnHrwRQXQw8Yv90g7kD\n"
+"pUV3/BjD9VQgsQZosbdSn5wbT4j7dypRdrzYk+8m/hBk4Q8M/tWoRGVOn46NudvK\n"
+"/KX0A4ODLuulj8yAZVc7CM5Cdy4GCGJBVO+oVvBUAnHxfZziOyqBw9MCgYEA5hQg\n"
+"HEORzdxvbbfAx1ggvH1Eg1lqRhmpI43PpRkaoqb8jLwXb2CyBeuv3RBft/X2Tr6F\n"
+"mHpe0U1kN/5YEjii/Q/jUX8azIHaUNNSAjrriEeMQZOqFxmhCdiyeXuqg2fbFbhe\n"
+"K3Q6/fsB1xj9OOSwyPMqm/M5U0LsoGjmg8TFE/ECgYAlImKUIdlwOgp1NJ7MF4eo\n"
+"Gryd8AmkLFQv8+YFgb7R4I8RsJ2rva0SG6fUhScJTSbRL7RYNZ9swXP/L7oLL5Z5\n"
+"vCxBLu22pmZv/7y9X/n9ulWrLRtRhQaFkV08mk9knQwPNeOJVTIEWLM49/vZmxyV\n"
+"h6Ru8FOoGXMkUI1MLnj5HwKBgGJLkNhiacVYeuaWDa9c0EeXARFYvxWJ2wAMkvzG\n"
+"9+ErlFQP+7ciyYvMAItidnJii8NilDLrfNzQwpNFf5zxQ3j4M7bapblfdMT5M10u\n"
+"jPfhEWPm0VEjKvDI+p76HYQcd7YU2W6ZLqbZeRTLYUvQMFL5yGduBzyyJ+P0TR9Y\n"
+"jpYRAoGBAM7vYGTprw4w2tTZPFICXVk1bQ0LO06oNRtwkiQTUT6UqPjWMFyvHnmN\n"
+"11SVVBmRZ0RAk6e5eZLFX8WelJ4J4nSOGRcJheCtoEFlO7D1ewAUSbqWJ0pBqp2T\n"
+"gV4oCS8LYe8zReVoYZJjuLwoHvxZzs/hUjc3SI2HRW2W/HQRPC25\n"
+"-----END RSA PRIVATE KEY-----\n"
+};
+
+#define N_PREGEN_KEYS_1024 ARRAY_LENGTH(PREGEN_KEYS_1024)
+static crypto_pk_t *pregen_keys_1024[N_PREGEN_KEYS_1024];
+static int next_key_idx_1024;
+#define N_PREGEN_KEYS_2048 ARRAY_LENGTH(PREGEN_KEYS_2048)
+static crypto_pk_t *pregen_keys_2048[N_PREGEN_KEYS_2048];
+static int next_key_idx_2048;
+#endif
+
+/** Generate and return a new keypair for use in unit tests. If we're using
+ * the key cache optimization, we might reuse keys. "idx" is ignored.
+ * Our only guarantee is that we won't reuse a key till this function has been
+ * called several times. The order in which keys are returned is slightly
+ * randomized, so that tests that depend on a particular order will not be
+ * reliable. */
+static crypto_pk_t *
+pk_generate_internal(int bits)
+{
+ tor_assert(bits == 2048 || bits == 1024);
+
+#ifdef USE_PREGENERATED_RSA_KEYS
+ int *idxp;
+ int n_pregen;
+ crypto_pk_t **pregen_array;
+ if (bits == 2048) {
+ idxp = &next_key_idx_2048;
+ n_pregen = N_PREGEN_KEYS_2048;
+ pregen_array = pregen_keys_2048;
+ } else {
+ idxp = &next_key_idx_1024;
+ n_pregen = N_PREGEN_KEYS_1024;
+ pregen_array = pregen_keys_1024;
+ }
+ /* Either skip 1 or 2 keys. */
+ *idxp += crypto_rand_int_range(1,3);
+ *idxp %= n_pregen;
+ return crypto_pk_dup_key(pregen_array[*idxp]);
+#else
+ crypto_pk_t *result;
+ int res;
+ result = crypto_pk_new();
+ res = crypto_pk_generate_key_with_bits__real(result, bits);
+ tor_assert(!res);
+ return result;
+#endif
+}
+
+crypto_pk_t *
+pk_generate(int idx)
+{
+ (void) idx;
+ return pk_generate_internal(1024);
+}
+
+#ifdef USE_PREGENERATED_RSA_KEYS
+static int
+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_free(newkey);
+ } else {
+ return crypto_pk_generate_key_with_bits__real(env, bits);
+ }
+ return 0;
+}
+#endif
+
+/** Free all storage used for the cached key optimization. */
+void
+free_pregenerated_keys(void)
+{
+#ifdef USE_PREGENERATED_RSA_KEYS
+ unsigned idx;
+ for (idx = 0; idx < N_PREGEN_KEYS_1024; ++idx) {
+ if (pregen_keys_1024[idx]) {
+ crypto_pk_free(pregen_keys_1024[idx]);
+ pregen_keys_1024[idx] = NULL;
+ }
+ }
+ for (idx = 0; idx < N_PREGEN_KEYS_2048; ++idx) {
+ if (pregen_keys_2048[idx]) {
+ crypto_pk_free(pregen_keys_2048[idx]);
+ pregen_keys_2048[idx] = NULL;
+ }
+ }
+#endif
+}
+
+void
+init_pregenerated_keys(void)
+{
+#ifdef USE_PREGENERATED_RSA_KEYS
+ const char *s;
+ crypto_pk_t *pk;
+ unsigned i;
+ for (i = 0; i < N_PREGEN_KEYS_1024; ++i) {
+ pk = pregen_keys_1024[i] = crypto_pk_new();
+ s = PREGEN_KEYS_1024[i];
+ int r = crypto_pk_read_private_key_from_string(pk, s, strlen(s));
+ tor_assert(r == 0);
+ }
+ for (i = 0; i < N_PREGEN_KEYS_2048; ++i) {
+ pk = pregen_keys_2048[i] = crypto_pk_new();
+ s = PREGEN_KEYS_2048[i];
+ int r = crypto_pk_read_private_key_from_string(pk, s, strlen(s));
+ tor_assert(r == 0);
+ }
+
+ MOCK(crypto_pk_generate_key_with_bits,
+ crypto_pk_generate_key_with_bits__get_cached);
+#endif
+}
+