summaryrefslogtreecommitdiff
path: root/src/test
diff options
context:
space:
mode:
Diffstat (limited to 'src/test')
-rw-r--r--src/test/bench.c14
-rw-r--r--src/test/fuzz/fuzzing_common.c15
-rw-r--r--src/test/fuzz/include.am4
-rw-r--r--src/test/include.am35
-rw-r--r--src/test/log_test_helpers.h37
-rw-r--r--src/test/test-timers.c5
-rw-r--r--src/test/test.c7
-rw-r--r--src/test/test.h3
-rw-r--r--src/test/test_controller.c2
-rw-r--r--src/test/test_crypto.c127
-rw-r--r--src/test/test_crypto_ope.c4
-rw-r--r--src/test/test_crypto_slow.c2
-rw-r--r--src/test/test_dir_handle_get.c2
-rw-r--r--src/test/test_hs_client.c2
-rw-r--r--src/test/test_hs_ntor_cl.c7
-rw-r--r--src/test/test_introduce.c2
-rw-r--r--src/test/test_link_handshake.c34
-rw-r--r--src/test/test_ntor_cl.c8
-rw-r--r--src/test/test_pem.c122
-rw-r--r--src/test/test_relaycell.c2
-rw-r--r--src/test/test_router.c2
-rw-r--r--src/test/test_routerkeys.c2
-rw-r--r--src/test/test_shared_random.c2
-rw-r--r--src/test/test_tortls.c2743
-rw-r--r--src/test/test_tortls.h13
-rw-r--r--src/test/test_tortls_openssl.c2277
-rw-r--r--src/test/test_util_slow.c2
-rw-r--r--src/test/test_workqueue.c1
-rw-r--r--src/test/test_x509.c203
-rw-r--r--src/test/testing_common.c17
-rw-r--r--src/test/testing_rsakeys.c3
31 files changed, 3102 insertions, 2597 deletions
diff --git a/src/test/bench.c b/src/test/bench.c
index 7919a4224f..3594059057 100644
--- a/src/test/bench.c
+++ b/src/test/bench.c
@@ -13,11 +13,14 @@
#include "core/or/or.h"
#include "core/crypto/onion_tap.h"
#include "core/crypto/relay_crypto.h"
+
+#ifdef ENABLE_OPENSSL
#include <openssl/opensslv.h>
#include <openssl/evp.h>
#include <openssl/ec.h>
#include <openssl/ecdh.h>
#include <openssl/obj_mac.h>
+#endif
#include "core/or/circuitlist.h"
#include "app/config/config.h"
@@ -33,6 +36,7 @@
#include "core/or/or_circuit_st.h"
#include "lib/crypt_ops/digestset.h"
+#include "lib/crypt_ops/crypto_init.h"
#if defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_PROCESS_CPUTIME_ID)
static uint64_t nanostart;
@@ -579,6 +583,7 @@ bench_dh(void)
" %f millisec each.\n", NANOCOUNT(start, end, iters)/1e6);
}
+#ifdef ENABLE_OPENSSL
static void
bench_ecdh_impl(int nid, const char *name)
{
@@ -628,6 +633,7 @@ bench_ecdh_p224(void)
{
bench_ecdh_impl(NID_secp224r1, "P-224");
}
+#endif
typedef void (*bench_fn)(void);
@@ -651,8 +657,11 @@ static struct benchmark_t benchmarks[] = {
ENT(cell_aes),
ENT(cell_ops),
ENT(dh),
+
+#ifdef ENABLE_OPENSSL
ENT(ecdh_p256),
ENT(ecdh_p224),
+#endif
{NULL,NULL,0}
};
@@ -680,9 +689,9 @@ main(int argc, const char **argv)
tor_threads_init();
tor_compress_init();
+ init_logging(1);
if (argc == 4 && !strcmp(argv[1], "diff")) {
- init_logging(1);
const int N = 200;
char *f1 = read_file_to_str(argv[2], RFTS_BIN, NULL);
char *f2 = read_file_to_str(argv[3], RFTS_BIN, NULL);
@@ -718,13 +727,12 @@ main(int argc, const char **argv)
reset_perftime();
- if (crypto_seed_rng() < 0) {
+ if (crypto_global_init(0, NULL, NULL) < 0) {
printf("Couldn't seed RNG; exiting.\n");
return 1;
}
init_protocol_warning_severity_level();
- crypto_init_siphash_key();
options = options_new();
init_logging(1);
options->command = CMD_RUN_UNITTESTS;
diff --git a/src/test/fuzz/fuzzing_common.c b/src/test/fuzz/fuzzing_common.c
index 0b3483bf66..1401e4c28d 100644
--- a/src/test/fuzz/fuzzing_common.c
+++ b/src/test/fuzz/fuzzing_common.c
@@ -7,8 +7,8 @@
#include "app/config/config.h"
#include "test/fuzz/fuzzing.h"
#include "lib/compress/compress.h"
-#include "lib/crypt_ops/crypto.h"
#include "lib/crypt_ops/crypto_ed25519.h"
+#include "lib/crypt_ops/crypto_init.h"
static or_options_t *mock_options = NULL;
static const or_options_t *
@@ -96,15 +96,20 @@ global_init(void)
{
tor_threads_init();
tor_compress_init();
- {
- struct sipkey sipkey = { 1337, 7331 };
- siphash_set_global_key(&sipkey);
- }
/* Initialise logging first */
init_logging(1);
configure_backtrace_handler(get_version());
+ if (crypto_global_init(0, NULL, NULL) < 0)
+ abort();
+
+ {
+ struct sipkey sipkey = { 1337, 7331 };
+ siphash_unset_global_key();
+ siphash_set_global_key(&sipkey);
+ }
+
/* set up the options. */
mock_options = tor_malloc_zero(sizeof(or_options_t));
MOCK(get_options, mock_get_options);
diff --git a/src/test/fuzz/include.am b/src/test/fuzz/include.am
index 09594d8272..27eeced8c5 100644
--- a/src/test/fuzz/include.am
+++ b/src/test/fuzz/include.am
@@ -5,12 +5,12 @@ FUZZING_CPPFLAGS = \
FUZZING_CFLAGS = \
$(AM_CFLAGS) $(TEST_CFLAGS)
FUZZING_LDFLAG = \
- @TOR_LDFLAGS_zlib@ @TOR_LDFLAGS_openssl@ @TOR_LDFLAGS_libevent@
+ @TOR_LDFLAGS_zlib@ $(TOR_LDFLAGS_CRYPTLIB) @TOR_LDFLAGS_libevent@
FUZZING_LIBS = \
$(TOR_INTERNAL_TESTING_LIBS) \
$(rust_ldadd) \
@TOR_ZLIB_LIBS@ @TOR_LIB_MATH@ \
- @TOR_LIBEVENT_LIBS@ @TOR_OPENSSL_LIBS@ \
+ @TOR_LIBEVENT_LIBS@ $(TOR_LIBS_CRYPTLIB) \
@TOR_LIB_WS32@ @TOR_LIB_IPHLPAPI@ @TOR_LIB_GDI@ @TOR_LIB_USERENV@ @CURVE25519_LIBS@ \
@TOR_SYSTEMD_LIBS@ \
@TOR_LZMA_LIBS@ \
diff --git a/src/test/include.am b/src/test/include.am
index 9367b0cb82..c54605383c 100644
--- a/src/test/include.am
+++ b/src/test/include.am
@@ -118,7 +118,6 @@ src_test_test_SOURCES += \
src/test/test_controller_events.c \
src/test/test_crypto.c \
src/test/test_crypto_ope.c \
- src/test/test_crypto_openssl.c \
src/test/test_data.c \
src/test/test_dir.c \
src/test/test_dir_common.c \
@@ -151,6 +150,7 @@ src_test_test_SOURCES += \
src/test/test_oom.c \
src/test/test_oos.c \
src/test/test_options.c \
+ src/test/test_pem.c \
src/test/test_periodic_event.c \
src/test/test_policy.c \
src/test/test_procmon.c \
@@ -178,11 +178,21 @@ src_test_test_SOURCES += \
src/test/test_util_format.c \
src/test/test_util_process.c \
src/test/test_voting_schedule.c \
+ src/test/test_x509.c \
src/test/test_helpers.c \
src/test/test_dns.c \
src/test/testing_common.c \
src/test/testing_rsakeys.c \
src/ext/tinytest.c
+
+if USE_NSS
+# ...
+else
+src_test_test_SOURCES += \
+ src/test/test_crypto_openssl.c \
+ src/test/test_tortls_openssl.c
+endif
+
endif
src_test_test_slow_SOURCES =
@@ -226,13 +236,13 @@ src_test_test_switch_id_LDADD = \
@TOR_LIB_WS32@ @TOR_LIB_IPHLPAPI@ @TOR_LIB_USERENV@ \
@TOR_LZMA_LIBS@ @TOR_ZSTD_LIBS@
-src_test_test_LDFLAGS = @TOR_LDFLAGS_zlib@ @TOR_LDFLAGS_openssl@ \
+src_test_test_LDFLAGS = @TOR_LDFLAGS_zlib@ $(TOR_LDFLAGS_CRYPTLIB) \
@TOR_LDFLAGS_libevent@
src_test_test_LDADD = \
$(TOR_INTERNAL_TESTING_LIBS) \
$(rust_ldadd) \
@TOR_ZLIB_LIBS@ @TOR_LIB_MATH@ @TOR_LIBEVENT_LIBS@ \
- @TOR_OPENSSL_LIBS@ @TOR_LIB_WS32@ @TOR_LIB_IPHLPAPI@ @TOR_LIB_GDI@ @TOR_LIB_USERENV@ \
+ $(TOR_LIBS_CRYPTLIB) @TOR_LIB_WS32@ @TOR_LIB_IPHLPAPI@ @TOR_LIB_GDI@ @TOR_LIB_USERENV@ \
@CURVE25519_LIBS@ \
@TOR_SYSTEMD_LIBS@ @TOR_LZMA_LIBS@ @TOR_ZSTD_LIBS@
@@ -249,23 +259,23 @@ src_test_test_memwipe_LDADD = $(src_test_test_LDADD)
# successfully with the libraries built with them.
src_test_test_memwipe_LDFLAGS = $(src_test_test_LDFLAGS) @CFLAGS_BUGTRAP@
-src_test_bench_LDFLAGS = @TOR_LDFLAGS_zlib@ @TOR_LDFLAGS_openssl@ \
+src_test_bench_LDFLAGS = @TOR_LDFLAGS_zlib@ $(TOR_LDFLAGS_CRYPTLIB) \
@TOR_LDFLAGS_libevent@
src_test_bench_LDADD = \
$(TOR_INTERNAL_LIBS) \
$(rust_ldadd) \
@TOR_ZLIB_LIBS@ @TOR_LIB_MATH@ @TOR_LIBEVENT_LIBS@ \
- @TOR_OPENSSL_LIBS@ @TOR_LIB_WS32@ @TOR_LIB_IPHLPAPI@ @TOR_LIB_GDI@ @TOR_LIB_USERENV@ \
+ $(TOR_LIBS_CRYPTLIB) @TOR_LIB_WS32@ @TOR_LIB_IPHLPAPI@ @TOR_LIB_GDI@ @TOR_LIB_USERENV@ \
@CURVE25519_LIBS@ \
@TOR_SYSTEMD_LIBS@ @TOR_LZMA_LIBS@ @TOR_ZSTD_LIBS@
-src_test_test_workqueue_LDFLAGS = @TOR_LDFLAGS_zlib@ @TOR_LDFLAGS_openssl@ \
+src_test_test_workqueue_LDFLAGS = @TOR_LDFLAGS_zlib@ $(TOR_LDFLAGS_CRYPTLIB) \
@TOR_LDFLAGS_libevent@
src_test_test_workqueue_LDADD = \
$(TOR_INTERNAL_TESTING_LIBS) \
$(rust_ldadd) \
@TOR_ZLIB_LIBS@ @TOR_LIB_MATH@ @TOR_LIBEVENT_LIBS@ \
- @TOR_OPENSSL_LIBS@ @TOR_LIB_WS32@ @TOR_LIB_IPHLPAPI@ @TOR_LIB_GDI@ @TOR_LIB_USERENV@ \
+ $(TOR_LIBS_CRYPTLIB) @TOR_LIB_WS32@ @TOR_LIB_IPHLPAPI@ @TOR_LIB_GDI@ @TOR_LIB_USERENV@ \
@CURVE25519_LIBS@ \
@TOR_LZMA_LIBS@ @TOR_ZSTD_LIBS@
@@ -277,7 +287,7 @@ src_test_test_timers_LDADD = \
$(TOR_UTIL_TESTING_LIBS) \
$(rust_ldadd) \
@TOR_ZLIB_LIBS@ @TOR_LIB_MATH@ @TOR_LIBEVENT_LIBS@ \
- @TOR_OPENSSL_LIBS@ @TOR_LIB_WS32@ @TOR_LIB_IPHLPAPI@ @TOR_LIB_GDI@ @TOR_LIB_USERENV@ \
+ $(TOR_LIBS_CRYPTLIB) @TOR_LIB_WS32@ @TOR_LIB_IPHLPAPI@ @TOR_LIB_GDI@ @TOR_LIB_USERENV@ \
@CURVE25519_LIBS@ \
@TOR_LZMA_LIBS@
src_test_test_timers_LDFLAGS = $(src_test_test_LDFLAGS)
@@ -291,6 +301,7 @@ noinst_HEADERS+= \
src/test/test_helpers.h \
src/test/test_dir_common.h \
src/test/test_connection.h \
+ src/test/test_tortls.h \
src/test/test_descriptors.inc \
src/test/example_extrainfo.inc \
src/test/failing_routerdescs.inc \
@@ -302,22 +313,22 @@ noinst_HEADERS+= \
noinst_PROGRAMS+= src/test/test-ntor-cl
noinst_PROGRAMS+= src/test/test-hs-ntor-cl
src_test_test_ntor_cl_SOURCES = src/test/test_ntor_cl.c
-src_test_test_ntor_cl_LDFLAGS = @TOR_LDFLAGS_zlib@ @TOR_LDFLAGS_openssl@
+src_test_test_ntor_cl_LDFLAGS = @TOR_LDFLAGS_zlib@ $(TOR_LDFLAGS_CRYPTLIB)
src_test_test_ntor_cl_LDADD = \
$(TOR_INTERNAL_LIBS) \
$(rust_ldadd) \
@TOR_ZLIB_LIBS@ @TOR_LIB_MATH@ \
- @TOR_OPENSSL_LIBS@ @TOR_LIB_WS32@ @TOR_LIB_IPHLPAPI@ @TOR_LIB_GDI@ @TOR_LIB_USERENV@ \
+ $(TOR_LIBS_CRYPTLIB) @TOR_LIB_WS32@ @TOR_LIB_IPHLPAPI@ @TOR_LIB_GDI@ @TOR_LIB_USERENV@ \
@CURVE25519_LIBS@ @TOR_LZMA_LIBS@
src_test_test_ntor_cl_AM_CPPFLAGS = \
$(AM_CPPFLAGS)
src_test_test_hs_ntor_cl_SOURCES = src/test/test_hs_ntor_cl.c
-src_test_test_hs_ntor_cl_LDFLAGS = @TOR_LDFLAGS_zlib@ @TOR_LDFLAGS_openssl@
+src_test_test_hs_ntor_cl_LDFLAGS = @TOR_LDFLAGS_zlib@ $(TOR_LDFLAGS_CRYPTLIB)
src_test_test_hs_ntor_cl_LDADD = \
$(TOR_INTERNAL_LIBS) \
@TOR_ZLIB_LIBS@ @TOR_LIB_MATH@ \
- @TOR_OPENSSL_LIBS@ @TOR_LIB_WS32@ @TOR_LIB_IPHLPAPI@ @TOR_LIB_GDI@ @CURVE25519_LIBS@
+ $(TOR_LIBS_CRYPTLIB) @TOR_LIB_WS32@ @TOR_LIB_IPHLPAPI@ @TOR_LIB_GDI@ @CURVE25519_LIBS@
src_test_test_hs_ntor_cl_AM_CPPFLAGS = \
$(AM_CPPFLAGS)
diff --git a/src/test/log_test_helpers.h b/src/test/log_test_helpers.h
index dcd3297346..6a774cdfc7 100644
--- a/src/test/log_test_helpers.h
+++ b/src/test/log_test_helpers.h
@@ -33,7 +33,7 @@ void mock_dump_saved_logs(void);
#define assert_log_predicate(predicate, failure_msg) \
do { \
if (!(predicate)) { \
- tt_fail_msg((failure_msg)); \
+ TT_FAIL(failure_msg); \
mock_dump_saved_logs(); \
TT_EXIT_TEST_FUNCTION; \
} \
@@ -41,74 +41,75 @@ void mock_dump_saved_logs(void);
#define expect_log_msg(str) \
assert_log_predicate(mock_saved_log_has_message(str), \
- "expected log to contain " # str);
+ ("expected log to contain \"%s\"", str));
#define expect_log_msg_containing(str) \
assert_log_predicate(mock_saved_log_has_message_containing(str), \
- "expected log to contain " # str);
+ ("expected log to contain \"%s\"", str));
#define expect_log_msg_not_containing(str) \
assert_log_predicate(mock_saved_log_has_message_not_containing(str), \
- "expected log to not contain " # str);
+ ("expected log to not contain \"%s\"", str));
#define expect_log_msg_containing_either(str1, str2) \
assert_log_predicate(mock_saved_log_has_message_containing(str1) || \
mock_saved_log_has_message_containing(str2), \
- "expected log to contain " # str1 " or " # str2);
+ ("expected log to contain \"%s\" or \"%s\"", str1, str2));
#define expect_log_msg_containing_either3(str1, str2, str3) \
assert_log_predicate(mock_saved_log_has_message_containing(str1) || \
mock_saved_log_has_message_containing(str2) || \
mock_saved_log_has_message_containing(str3), \
- "expected log to contain " # str1 " or " # str2 \
- " or " # str3);
+ ("expected log to contain \"%s\" or \"%s\" or \"%s\"", \
+ str1, str2, str3))
#define expect_log_msg_containing_either4(str1, str2, str3, str4) \
assert_log_predicate(mock_saved_log_has_message_containing(str1) || \
mock_saved_log_has_message_containing(str2) || \
mock_saved_log_has_message_containing(str3) || \
mock_saved_log_has_message_containing(str4), \
- "expected log to contain " # str1 " or " # str2 \
- " or " # str3 " or " # str4);
+ ("expected log to contain \"%s\" or \"%s\" or \"%s\" or \"%s\"", \
+ str1, str2, str3, str4))
#define expect_single_log_msg(str) \
do { \
\
assert_log_predicate(mock_saved_log_has_message_containing(str) && \
mock_saved_log_n_entries() == 1, \
- "expected log to contain exactly 1 message " # str); \
+ ("expected log to contain exactly 1 message \"%s\"", \
+ str)); \
} while (0);
#define expect_single_log_msg_containing(str) \
do { \
assert_log_predicate(mock_saved_log_has_message_containing(str)&& \
mock_saved_log_n_entries() == 1 , \
- "expected log to contain 1 message, containing " # str); \
+ ("expected log to contain 1 message, containing \"%s\"",\
+ str)); \
} while (0);
#define expect_no_log_msg(str) \
assert_log_predicate(!mock_saved_log_has_message(str), \
- "expected log to not contain " # str);
+ ("expected log to not contain \"%s\"",str));
#define expect_no_log_msg_containing(str) \
assert_log_predicate(!mock_saved_log_has_message_containing(str), \
- "expected log to not contain " # str);
+ ("expected log to not contain \"%s\"", str));
#define expect_log_severity(severity) \
assert_log_predicate(mock_saved_log_has_severity(severity), \
- "expected log to contain severity " # severity);
+ ("expected log to contain severity " # severity));
#define expect_no_log_severity(severity) \
assert_log_predicate(!mock_saved_log_has_severity(severity), \
- "expected log to not contain severity " # severity);
+ ("expected log to not contain severity " # severity));
#define expect_log_entry() \
assert_log_predicate(mock_saved_log_has_entry(), \
- "expected log to contain entries");
+ ("expected log to contain entries"));
#define expect_no_log_entry() \
assert_log_predicate(!mock_saved_log_has_entry(), \
- "expected log to not contain entries");
+ ("expected log to not contain entries"));
#endif /* !defined(TOR_LOG_TEST_HELPERS_H) */
-
diff --git a/src/test/test-timers.c b/src/test/test-timers.c
index f9276c25d6..923f51ecce 100644
--- a/src/test/test-timers.c
+++ b/src/test/test-timers.c
@@ -9,6 +9,7 @@
#include "lib/evloop/compat_libevent.h"
#include "lib/evloop/timers.h"
+#include "lib/crypt_ops/crypto_init.h"
#include "lib/crypt_ops/crypto_rand.h"
#include "lib/log/util_bug.h"
#include "lib/time/compat_time.h"
@@ -62,6 +63,10 @@ main(int argc, char **argv)
memset(&cfg, 0, sizeof(cfg));
tor_libevent_initialize(&cfg);
timers_initialize();
+ init_logging(1);
+
+ if (crypto_global_init(0, NULL, NULL) < 0)
+ return 1;
int i;
int ret;
diff --git a/src/test/test.c b/src/test/test.c
index f96a0b33ed..dc8e3bede3 100644
--- a/src/test/test.c
+++ b/src/test/test.c
@@ -860,7 +860,10 @@ struct testgroup_t testgroups[] = {
{ "control/event/", controller_event_tests },
{ "crypto/", crypto_tests },
{ "crypto/ope/", crypto_ope_tests },
+#ifdef ENABLE_OPENSSL
{ "crypto/openssl/", crypto_openssl_tests },
+#endif
+ { "crypto/pem/", pem_tests },
{ "dir/", dir_tests },
{ "dir_handle_get/", dir_handle_get_tests },
{ "dir/md/", microdesc_tests },
@@ -912,6 +915,10 @@ struct testgroup_t testgroups[] = {
{ "status/" , status_tests },
{ "storagedir/", storagedir_tests },
{ "tortls/", tortls_tests },
+#ifndef ENABLE_NSS
+ { "tortls/openssl/", tortls_openssl_tests },
+#endif
+ { "tortls/x509/", x509_tests },
{ "util/", util_tests },
{ "util/format/", util_format_tests },
{ "util/logging/", logging_tests },
diff --git a/src/test/test.h b/src/test/test.h
index bfe50cbb8c..a46fedf3e0 100644
--- a/src/test/test.h
+++ b/src/test/test.h
@@ -234,6 +234,7 @@ extern struct testcase_t nodelist_tests[];
extern struct testcase_t oom_tests[];
extern struct testcase_t oos_tests[];
extern struct testcase_t options_tests[];
+extern struct testcase_t pem_tests[];
extern struct testcase_t periodic_event_tests[];
extern struct testcase_t policy_tests[];
extern struct testcase_t procmon_tests[];
@@ -256,6 +257,7 @@ extern struct testcase_t socks_tests[];
extern struct testcase_t status_tests[];
extern struct testcase_t thread_tests[];
extern struct testcase_t tortls_tests[];
+extern struct testcase_t tortls_openssl_tests[];
extern struct testcase_t util_tests[];
extern struct testcase_t util_format_tests[];
extern struct testcase_t util_process_tests[];
@@ -263,6 +265,7 @@ extern struct testcase_t voting_schedule_tests[];
extern struct testcase_t dns_tests[];
extern struct testcase_t handle_tests[];
extern struct testcase_t sr_tests[];
+extern struct testcase_t x509_tests[];
extern struct testcase_t slow_crypto_tests[];
extern struct testcase_t slow_util_tests[];
diff --git a/src/test/test_controller.c b/src/test/test_controller.c
index d0aa868448..d5d51758fb 100644
--- a/src/test/test_controller.c
+++ b/src/test/test_controller.c
@@ -161,7 +161,7 @@ test_add_onion_helper_keyarg_v2(void *arg)
/* Test loading a RSA1024 key. */
tor_free(err_msg);
pk1 = pk_generate(0);
- tt_int_op(0, OP_EQ, crypto_pk_base64_encode(pk1, &encoded));
+ tt_int_op(0, OP_EQ, crypto_pk_base64_encode_private(pk1, &encoded));
tor_asprintf(&arg_str, "RSA1024:%s", encoded);
ret = add_onion_helper_keyarg(arg_str, 0, &key_new_alg, &key_new_blob,
&pk, &hs_version, &err_msg);
diff --git a/src/test/test_crypto.c b/src/test/test_crypto.c
index 2124e22196..b08c5cbc22 100644
--- a/src/test/test_crypto.c
+++ b/src/test/test_crypto.c
@@ -16,7 +16,9 @@
#include "lib/crypt_ops/crypto_format.h"
#include "lib/crypt_ops/crypto_hkdf.h"
#include "lib/crypt_ops/crypto_rand.h"
+#include "lib/crypt_ops/crypto_init.h"
#include "ed25519_vectors.inc"
+#include "test/log_test_helpers.h"
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
@@ -25,6 +27,13 @@
#include <unistd.h>
#endif
+#if defined(ENABLE_OPENSSL)
+#include "lib/crypt_ops/compat_openssl.h"
+DISABLE_GCC_WARNING(redundant-decls)
+#include <openssl/dh.h>
+ENABLE_GCC_WARNING(redundant-decls)
+#endif
+
/** Run unit tests for Diffie-Hellman functionality. */
static void
test_crypto_dh(void *arg)
@@ -37,6 +46,11 @@ test_crypto_dh(void *arg)
char s1[DH1024_KEY_LEN];
char s2[DH1024_KEY_LEN];
ssize_t s1len, s2len;
+#ifdef ENABLE_OPENSSL
+ crypto_dh_t *dh3 = NULL;
+ DH *dh4 = NULL;
+ BIGNUM *pubkey_tmp = NULL;
+#endif
(void)arg;
tt_int_op(crypto_dh_get_bytes(dh1),OP_EQ, DH1024_KEY_LEN);
@@ -91,6 +105,10 @@ test_crypto_dh(void *arg)
s1len = crypto_dh_compute_secret(LOG_WARN, dh1, "\x02", 1, s1, 50);
tt_int_op(50, OP_EQ, s1len);
+ /* 2 a second time is still okay, though weird. */
+ s1len = crypto_dh_compute_secret(LOG_WARN, dh1, "\x02", 1, s1, 50);
+ tt_int_op(50, OP_EQ, s1len);
+
const char P[] =
"FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E08"
"8A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B"
@@ -157,16 +175,59 @@ test_crypto_dh(void *arg)
tt_int_op(s1len, OP_EQ, -1);
}
+#if defined(ENABLE_OPENSSL)
+ {
+ /* Make sure that our crypto library can handshake with openssl. */
+ dh3 = crypto_dh_new(DH_TYPE_TLS);
+ tt_assert(!crypto_dh_get_public(dh3, p1, DH1024_KEY_LEN));
+
+ dh4 = crypto_dh_new_openssl_tls();
+ tt_assert(DH_generate_key(dh4));
+ const BIGNUM *pk=NULL;
+#ifdef OPENSSL_1_1_API
+ const BIGNUM *sk=NULL;
+ DH_get0_key(dh4, &pk, &sk);
+#else
+ pk = dh4->pub_key;
+#endif
+ tt_assert(pk);
+ tt_int_op(BN_num_bytes(pk), OP_LE, DH1024_KEY_LEN);
+ tt_int_op(BN_num_bytes(pk), OP_GT, 0);
+ memset(p2, 0, sizeof(p2));
+ /* right-pad. */
+ BN_bn2bin(pk, (unsigned char *)(p2+DH1024_KEY_LEN-BN_num_bytes(pk)));
+
+ s1len = crypto_dh_handshake(LOG_WARN, dh3, p2, DH1024_KEY_LEN,
+ (unsigned char *)s1, sizeof(s1));
+ pubkey_tmp = BN_bin2bn((unsigned char *)p1, DH1024_KEY_LEN, NULL);
+ s2len = DH_compute_key((unsigned char *)s2, pubkey_tmp, dh4);
+
+ tt_int_op(s1len, OP_EQ, s2len);
+ tt_int_op(s1len, OP_GT, 0);
+ tt_mem_op(s1, OP_EQ, s2, s1len);
+ }
+#endif
+
done:
crypto_dh_free(dh1);
crypto_dh_free(dh2);
crypto_dh_free(dh1_dup);
+#ifdef ENABLE_OPENSSL
+ crypto_dh_free(dh3);
+ if (dh4)
+ DH_free(dh4);
+ if (pubkey_tmp)
+ BN_free(pubkey_tmp);
+#endif
}
static void
test_crypto_openssl_version(void *arg)
{
(void)arg;
+#ifdef ENABLE_NSS
+ tt_skip();
+#else
const char *version = crypto_openssl_get_version_str();
const char *h_version = crypto_openssl_get_header_version_str();
tt_assert(version);
@@ -186,6 +247,7 @@ test_crypto_openssl_version(void *arg)
tt_int_op(a, OP_GE, 0);
tt_int_op(b, OP_GE, 0);
tt_int_op(c, OP_GE, 0);
+#endif
done:
;
@@ -1363,22 +1425,22 @@ test_crypto_pk_base64(void *arg)
/* Test Base64 encoding a key. */
pk1 = pk_generate(0);
tt_assert(pk1);
- tt_int_op(0, OP_EQ, crypto_pk_base64_encode(pk1, &encoded));
+ tt_int_op(0, OP_EQ, crypto_pk_base64_encode_private(pk1, &encoded));
tt_assert(encoded);
/* Test decoding a valid key. */
- pk2 = crypto_pk_base64_decode(encoded, strlen(encoded));
+ pk2 = crypto_pk_base64_decode_private(encoded, strlen(encoded));
tt_assert(pk2);
tt_int_op(crypto_pk_cmp_keys(pk1, pk2), OP_EQ, 0);
crypto_pk_free(pk2);
/* Test decoding a invalid key (not Base64). */
static const char *invalid_b64 = "The key is in another castle!";
- pk2 = crypto_pk_base64_decode(invalid_b64, strlen(invalid_b64));
+ pk2 = crypto_pk_base64_decode_private(invalid_b64, strlen(invalid_b64));
tt_ptr_op(pk2, OP_EQ, NULL);
/* Test decoding a truncated Base64 blob. */
- pk2 = crypto_pk_base64_decode(encoded, strlen(encoded)/2);
+ pk2 = crypto_pk_base64_decode_private(encoded, strlen(encoded)/2);
tt_ptr_op(pk2, OP_EQ, NULL);
done:
@@ -1427,6 +1489,58 @@ test_crypto_pk_pem_encrypted(void *arg)
done:
crypto_pk_free(pk);
}
+
+static void
+test_crypto_pk_invalid_private_key(void *arg)
+{
+ (void)arg;
+ /* Here is a simple invalid private key: it was produced by making
+ * a regular private key, and then adding 2 to the modulus. */
+ const char pem[] =
+ "-----BEGIN RSA PRIVATE KEY-----\n"
+ "MIIEpQIBAAKCAQEAskRyZrs+YAukvBmZlgo6/rCxyKF2xyUk073ap+2CgRUnSfGG\n"
+ "mflHlzqVq7tpH50DafpS+fFAbaEaNV/ac20QG0rUZi38HTB4qURWOu6n0Bws6E4l\n"
+ "UX/AkvDlWnuYH0pHHi2c3DGNFjwoJpjKuUTk+cRffVR8X3Kjr62SUDUaBNW0Kecz\n"
+ "3SYLbmgmZI16dFZ+g9sNM3znXZbhvb33WwPqpZSSPs37cPgF7eS6mAw/gUMx6zfE\n"
+ "HRmUnOQSzUdS05rvc/hsiCLhiIZ8hgfkD07XnTT1Ds8DwE55k7BUWY2wvwWCNLsH\n"
+ "qtqAxTr615XdkMxVkYgImpqPybarpfNYhFqkOwIDAQABAoIBACPC3VxEdbfYvhxJ\n"
+ "2mih9sG++nswAN7kUaX0cRe86rAwaShJPmJHApiQ1ROVTfpciiHJaLnhLraPWe2Z\n"
+ "I/6Bw3hmI4O399p3Lc1u+wlpdNqnvE6B1rSptx0DHE9xecvVH70rE0uM2Su7t6Y+\n"
+ "gnR2IKUGQs2mlCilm7aTUEWs0WJkkl4CG1dyxItuOSdNBjOEzXimJyiB10jEBFsp\n"
+ "SZeCF2FZ7AJbck5CVC42+oTsiDbZrHTHOn7v26rFGdONeHD1wOI1v7JwHFpCB923\n"
+ "aEHBzsPbMeq7DWG1rjzCYpcXHhTDBDBWSia4SEhyr2Nl7m7qxWWWwR+x4dqAj3rD\n"
+ "HeTmos0CgYEA6uf1CLpjPpOs5IaW1DQI8dJA/xFEAC/6GVgq4nFOGHZrm8G3L5o+\n"
+ "qvtQNMpDs2naWuZpqROFqv24o01DykHygR72GlPIY6uvmmf5tvJLoGnbFUay33L4\n"
+ "7b9dkNhuEIBNPzVDie0pgS77WgaPbYkVv5fnDwgPuVnkqfakEt7Pz2MCgYEAwkZ5\n"
+ "R1wLuTQEA2Poo6Gf4L8Bg6yNYI46LHDqDIs818iYLjtcnEEvbPfaoKNpOn7s7s4O\n"
+ "Pc+4HnT1aIQs0IKVLRTp+5a/9wfOkPZnobWOUHZk9UzBL3Hc1uy/qhp93iE3tSzx\n"
+ "v0O1pvR+hr3guTCZx8wZnDvaMgG3hlyPnVlHdrMCgYEAzQQxGbMC1ySv6quEjCP2\n"
+ "AogMbhE1lixJTUFj/EoDbNo9xKznIkauly/Lqqc1OysRhfA/G2+MY9YZBX1zwtyX\n"
+ "uBW7mPKynDrFgi9pBECnvJNmwET57Ic9ttIj6Tzbos83nAjyrzgr1zGX8dRz7ZeN\n"
+ "QbBj2vygLJbGOYinXkjUeh0CgYEAhN5aF9n2EqZmkEMGWtMxWy6HRJ0A3Cap1rcq\n"
+ "+4VHCXWhzwy+XAeg/e/N0MuyLlWcif7XcqLcE8h+BwtO8xQ8HmcNWApUJAls12wO\n"
+ "mGRpftJaXgIupdpD5aJpu1b++qrRRNIGTH9sf1D8L/8w8LcylZkbcuTkaAsQj45C\n"
+ "kqT64U0CgYEAq47IKS6xc3CDc17BqExR6t+1yRe+4ml+z1zcVbfUKony4pGvl1yo\n"
+ "rk0IYDN5Vd8h5xtXrkPdX9h+ywmohnelDKsayEuE+opyqEpSU4/96Bb22RZUoucb\n"
+ "LWkV5gZx5hFnDFtEd4vadMIiY4jVv/3JqiZDKwMVBJKlHRXJEEmIEBk=\n"
+ "-----END RSA PRIVATE KEY-----\n";
+
+ crypto_pk_t *pk = NULL;
+
+ pk = crypto_pk_new();
+ setup_capture_of_logs(LOG_WARN);
+ tt_int_op(-1, OP_EQ,
+ crypto_pk_read_private_key_from_string(pk, pem, strlen(pem)));
+#ifdef ENABLE_NSS
+ expect_single_log_msg_containing("received bad data");
+#else
+ expect_single_log_msg_containing("while checking RSA key");
+#endif
+ done:
+ teardown_capture_of_logs();
+ crypto_pk_free(pk);
+}
+
#ifdef HAVE_TRUNCATE
#define do_truncate truncate
#else
@@ -1462,7 +1576,8 @@ test_crypto_digests(void *arg)
(void)arg;
k = crypto_pk_new();
tt_assert(k);
- r = crypto_pk_read_private_key_from_string(k, AUTHORITY_SIGNKEY_3, -1);
+ r = crypto_pk_read_private_key_from_string(k, AUTHORITY_SIGNKEY_3,
+ strlen(AUTHORITY_SIGNKEY_3));
tt_assert(!r);
r = crypto_pk_get_digest(k, digest);
@@ -3047,6 +3162,8 @@ struct testcase_t crypto_tests[] = {
{ "pk_fingerprints", test_crypto_pk_fingerprints, TT_FORK, NULL, NULL },
{ "pk_base64", test_crypto_pk_base64, TT_FORK, NULL, NULL },
{ "pk_pem_encrypted", test_crypto_pk_pem_encrypted, TT_FORK, NULL, NULL },
+ { "pk_invalid_private_key", test_crypto_pk_invalid_private_key, 0,
+ NULL, NULL },
CRYPTO_LEGACY(digests),
{ "digest_names", test_crypto_digest_names, 0, NULL, NULL },
{ "sha3", test_crypto_sha3, TT_FORK, NULL, NULL},
diff --git a/src/test/test_crypto_ope.c b/src/test/test_crypto_ope.c
index 7dcad7b4b2..4e7b952327 100644
--- a/src/test/test_crypto_ope.c
+++ b/src/test/test_crypto_ope.c
@@ -7,9 +7,11 @@
#define CRYPTO_OPE_PRIVATE
+#include "lib/cc/compat_compiler.h"
#include "lib/crypt_ops/crypto_ope.h"
-#include "lib/crypt_ops/crypto.h"
+#include "lib/crypt_ops/crypto_cipher.h"
#include "lib/encoding/binascii.h"
+#include "lib/malloc/malloc.h"
#include "test/test.h"
#include "tinytest.h"
diff --git a/src/test/test_crypto_slow.c b/src/test/test_crypto_slow.c
index 88b31ad9af..ca6b7b8d4d 100644
--- a/src/test/test_crypto_slow.c
+++ b/src/test/test_crypto_slow.c
@@ -18,7 +18,9 @@
#include <libscrypt.h>
#endif
+#ifdef ENABLE_OPENSSL
#include <openssl/evp.h>
+#endif
/** Run unit tests for our secret-to-key passphrase hashing functionality. */
static void
diff --git a/src/test/test_dir_handle_get.c b/src/test/test_dir_handle_get.c
index 571b0386e2..09799a0e5f 100644
--- a/src/test/test_dir_handle_get.c
+++ b/src/test/test_dir_handle_get.c
@@ -2102,6 +2102,7 @@ test_dir_handle_get_status_vote_d(void* data)
clear_dir_servers();
dirvote_free_all();
+ routerlist_free_all();
}
static void
@@ -2638,4 +2639,3 @@ struct testcase_t dir_handle_get_tests[] = {
DIR_HANDLE_CMD(parse_accept_encoding, 0),
END_OF_TESTCASES
};
-
diff --git a/src/test/test_hs_client.c b/src/test/test_hs_client.c
index 57da03ca28..7fcc1db195 100644
--- a/src/test/test_hs_client.c
+++ b/src/test/test_hs_client.c
@@ -21,7 +21,7 @@
#include "test/hs_test_helpers.h"
#include "app/config/config.h"
-#include "lib/crypt_ops/crypto.h"
+#include "lib/crypt_ops/crypto_cipher.h"
#include "lib/crypt_ops/crypto_dh.h"
#include "core/or/channeltls.h"
#include "feature/dircache/directory.h"
diff --git a/src/test/test_hs_ntor_cl.c b/src/test/test_hs_ntor_cl.c
index 03e34968be..a4915c4f8a 100644
--- a/src/test/test_hs_ntor_cl.c
+++ b/src/test/test_hs_ntor_cl.c
@@ -14,10 +14,11 @@
#define ONION_NTOR_PRIVATE
#include "core/or/or.h"
-#include "lib/crypt_ops/crypto.h"
+#include "lib/crypt_ops/crypto_cipher.h"
#include "lib/crypt_ops/crypto_curve25519.h"
#include "lib/crypt_ops/crypto_ed25519.h"
#include "lib/crypt_ops/crypto_format.h"
+#include "lib/crypt_ops/crypto_init.h"
#include "core/crypto/hs_ntor.h"
#include "core/crypto/onion_ntor.h"
@@ -240,7 +241,11 @@ main(int argc, char **argv)
return 1;
}
+ init_logging(1);
curve25519_init();
+ if (crypto_global_init(0, NULL, NULL) < 0)
+ return 1;
+
if (!strcmp(argv[1], "client1")) {
return client1(argc, argv);
} else if (!strcmp(argv[1], "server1")) {
diff --git a/src/test/test_introduce.c b/src/test/test_introduce.c
index cdfb70bdff..4d2d909945 100644
--- a/src/test/test_introduce.c
+++ b/src/test/test_introduce.c
@@ -2,7 +2,7 @@
/* See LICENSE for licensing information */
#include "orconfig.h"
-#include "lib/crypt_ops/crypto.h"
+#include "lib/crypt_ops/crypto_cipher.h"
#include "core/or/or.h"
#include "test/test.h"
diff --git a/src/test/test_link_handshake.c b/src/test/test_link_handshake.c
index e0d12fb472..df3fa67eb1 100644
--- a/src/test/test_link_handshake.c
+++ b/src/test/test_link_handshake.c
@@ -24,7 +24,9 @@
#include "core/or/or_handshake_state_st.h"
#include "core/or/var_cell_st.h"
+#define TOR_X509_PRIVATE
#include "lib/tls/tortls.h"
+#include "lib/tls/x509.h"
#include "test/test.h"
#include "test/log_test_helpers.h"
@@ -793,11 +795,26 @@ CERTS_FAIL(bad_rsa_id_cert, /*ed25519*/
{
require_failure_message = "legacy RSA ID certificate was not valid";
certs_cell_cert_t *cert = certs_cell_get_certs(d->ccell, 1);
- uint8_t *body = certs_cell_cert_getarray_body(cert);
- ssize_t body_len = certs_cell_cert_getlen_body(cert);
- /* Frob a byte in the signature */
- body[body_len - 13] ^= 7;
+ uint8_t *body;
+ /* Frob a byte in the signature, after making a new cert. (NSS won't let
+ * us just frob the old cert, since it will see that the issuer & serial
+ * number are the same, which will make it fail at an earlier stage than
+ * signature verification.) */
+ const tor_x509_cert_t *idc;
+ tor_x509_cert_t *newc;
+ tor_tls_get_my_certs(1, NULL, &idc);
+ time_t new_end = time(NULL) + 86400 * 10;
+ newc = tor_x509_cert_replace_expiration(idc, new_end, d->key2);
+ const uint8_t *encoded;
+ size_t encoded_len;
+ tor_x509_cert_get_der(newc, &encoded, &encoded_len);
+ certs_cell_cert_setlen_body(cert, encoded_len);
+ certs_cell_cert_set_cert_len(cert, encoded_len);
+ body = certs_cell_cert_getarray_body(cert);
+ memcpy(body, encoded, encoded_len);
+ body[encoded_len - 13] ^= 7;
REENCODE();
+ tor_x509_cert_free(newc);
})
CERTS_FAIL(expired_rsa_id, /* both */
{
@@ -809,9 +826,12 @@ CERTS_FAIL(expired_rsa_id, /* both */
tor_x509_cert_t *newc;
time_t new_end = time(NULL) - 86400 * 10;
newc = tor_x509_cert_replace_expiration(idc, new_end, d->key2);
- certs_cell_cert_setlen_body(cert, newc->encoded_len);
- memcpy(certs_cell_cert_getarray_body(cert),
- newc->encoded, newc->encoded_len);
+ const uint8_t *encoded;
+ size_t encoded_len;
+ tor_x509_cert_get_der(newc, &encoded, &encoded_len);
+ certs_cell_cert_setlen_body(cert, encoded_len);
+ certs_cell_cert_set_cert_len(cert, encoded_len);
+ memcpy(certs_cell_cert_getarray_body(cert), encoded, encoded_len);
REENCODE();
tor_x509_cert_free(newc);
})
diff --git a/src/test/test_ntor_cl.c b/src/test/test_ntor_cl.c
index 744b42c9d9..3f914523a3 100644
--- a/src/test/test_ntor_cl.c
+++ b/src/test/test_ntor_cl.c
@@ -7,8 +7,9 @@
#define ONION_NTOR_PRIVATE
#include "core/or/or.h"
-#include "lib/crypt_ops/crypto.h"
+#include "lib/crypt_ops/crypto_cipher.h"
#include "lib/crypt_ops/crypto_curve25519.h"
+#include "lib/crypt_ops/crypto_init.h"
#include "core/crypto/onion_ntor.h"
#define N_ARGS(n) STMT_BEGIN { \
@@ -153,7 +154,11 @@ main(int argc, char **argv)
return 1;
}
+ init_logging(1);
curve25519_init();
+ if (crypto_global_init(0, NULL, NULL) < 0)
+ return 1;
+
if (!strcmp(argv[1], "client1")) {
return client1(argc, argv);
} else if (!strcmp(argv[1], "server1")) {
@@ -165,4 +170,3 @@ main(int argc, char **argv)
return 1;
}
}
-
diff --git a/src/test/test_pem.c b/src/test/test_pem.c
new file mode 100644
index 0000000000..2bae286e25
--- /dev/null
+++ b/src/test/test_pem.c
@@ -0,0 +1,122 @@
+/* Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2018, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#include "orconfig.h"
+
+#include "lib/encoding/pem.h"
+#include "lib/cc/compat_compiler.h"
+#include "lib/malloc/malloc.h"
+
+#include "test/test.h"
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+static const char example_pre[] =
+ "Lest you get the wrong impression, we wombats "
+ "are not in the habit of tunneling madly about, without any supplies "
+ "or even a map."; /* -- Ursula Vernon, _Digger_ */
+static const char expected[] =
+ "-----BEGIN WOMBAT QUOTE-----\n"
+ "TGVzdCB5b3UgZ2V0IHRoZSB3cm9uZyBpbXByZXNzaW9uLCB3ZSB3b21iYXRzIGFy\n"
+ "ZSBub3QgaW4gdGhlIGhhYml0IG9mIHR1bm5lbGluZyBtYWRseSBhYm91dCwgd2l0\n"
+ "aG91dCBhbnkgc3VwcGxpZXMgb3IgZXZlbiBhIG1hcC4=\n"
+ "-----END WOMBAT QUOTE-----\n";
+
+static void
+test_crypto_pem_encode(void *arg)
+{
+ (void)arg;
+
+ char buf[4096];
+
+ int n = (int) pem_encoded_size(strlen(example_pre), "WOMBAT QUOTE");
+
+ int n2 = pem_encode(buf, sizeof(buf),
+ (const unsigned char *)example_pre, strlen(example_pre),
+ "WOMBAT QUOTE");
+ tt_int_op(strlen(buf)+1, OP_EQ, n);
+ tt_int_op(n2, OP_EQ, 0);
+ tt_str_op(buf, OP_EQ, expected);
+
+ /* Now make sure it succeeds if the buffer is exactly the length we want. */
+ memset(buf, 0, sizeof(buf));
+ n2 = pem_encode(buf, n, (const unsigned char *)example_pre,
+ strlen(example_pre), "WOMBAT QUOTE");
+ tt_int_op(n2, OP_EQ, 0);
+ tt_str_op(buf, OP_EQ, expected);
+
+ /* Make sure it fails if the buffer is too short. */
+ memset(buf, 0, sizeof(buf));
+ n2 = pem_encode(buf, n - 1, (const unsigned char *)example_pre,
+ strlen(example_pre), "WOMBAT QUOTE");
+ tt_int_op(n2, OP_EQ, -1);
+
+ done:
+ ;
+}
+
+static void
+test_crypto_pem_decode(void *arg)
+{
+ (void)arg;
+
+ unsigned char buf[4096];
+
+ /* Try a straightforward decoding. */
+ int n = pem_decode(buf, sizeof(buf),
+ expected, strlen(expected),
+ "WOMBAT QUOTE");
+ tt_int_op(n, OP_EQ, strlen(example_pre));
+ tt_mem_op(buf, OP_EQ, example_pre, n);
+
+ /* Succeed if the buffer is exactly the right size. */
+ memset(buf, 0xff, sizeof(buf));
+ n = pem_decode(buf, strlen(example_pre),
+ expected, strlen(expected),
+ "WOMBAT QUOTE");
+ tt_int_op(n, OP_EQ, strlen(example_pre));
+ tt_mem_op(buf, OP_EQ, example_pre, n);
+ tt_int_op(buf[n], OP_EQ, 0xff);
+
+ /* Verify that it fails if the buffer is too small. */
+ memset(buf, 0xff, sizeof(buf));
+ n = pem_decode(buf, strlen(example_pre) - 1,
+ expected, strlen(expected),
+ "WOMBAT QUOTE");
+ tt_int_op(n, OP_EQ, -1);
+
+ /* Verify that it fails with an incorrect tag. */
+ memset(buf, 0xff, sizeof(buf));
+ n = pem_decode(buf, sizeof(buf),
+ expected, strlen(expected),
+ "QUOKKA VOTE");
+ tt_int_op(n, OP_EQ, -1);
+
+ /* Try truncated buffers of different sizes. */
+ size_t i;
+ for (i = 0; i <= strlen(expected); ++i) {
+ char *truncated = tor_memdup(expected, i);
+ n = pem_decode(buf, sizeof(buf),
+ truncated, i,
+ "WOMBAT QUOTE");
+ tor_free(truncated);
+ if (i < strlen(expected) - 1) {
+ tt_int_op(n, OP_EQ, -1);
+ } else {
+ tt_int_op(n, OP_EQ, strlen(example_pre));
+ }
+ }
+
+ done:
+ ;
+}
+
+struct testcase_t pem_tests[] = {
+ { "encode", test_crypto_pem_encode, 0, NULL, NULL },
+ { "decode", test_crypto_pem_decode, 0, NULL, NULL },
+ END_OF_TESTCASES
+};
diff --git a/src/test/test_relaycell.c b/src/test/test_relaycell.c
index eb30cab0ec..a6c152f738 100644
--- a/src/test/test_relaycell.c
+++ b/src/test/test_relaycell.c
@@ -9,7 +9,7 @@
#include "core/mainloop/main.h"
#include "app/config/config.h"
#include "core/mainloop/connection.h"
-#include "lib/crypt_ops/crypto.h"
+#include "lib/crypt_ops/crypto_cipher.h"
#include "core/or/circuitbuild.h"
#include "core/or/circuitlist.h"
#include "core/or/connection_edge.h"
diff --git a/src/test/test_router.c b/src/test/test_router.c
index 6e64131fc8..533135669f 100644
--- a/src/test/test_router.c
+++ b/src/test/test_router.c
@@ -56,6 +56,8 @@ NS(router_get_my_routerinfo)(void)
&mock_routerinfo->onion_pkey_len);
mock_routerinfo->bandwidthrate = 9001;
mock_routerinfo->bandwidthburst = 9002;
+ crypto_pk_free(ident_key);
+ crypto_pk_free(tap_key);
}
return mock_routerinfo;
diff --git a/src/test/test_routerkeys.c b/src/test/test_routerkeys.c
index 1a9664aa02..b62aea113e 100644
--- a/src/test/test_routerkeys.c
+++ b/src/test/test_routerkeys.c
@@ -9,7 +9,7 @@
#include "app/config/config.h"
#include "feature/relay/router.h"
#include "feature/relay/routerkeys.h"
-#include "lib/crypt_ops/crypto.h"
+#include "lib/crypt_ops/crypto_cipher.h"
#include "lib/crypt_ops/crypto_format.h"
#include "feature/nodelist/torcert.h"
#include "test/test.h"
diff --git a/src/test/test_shared_random.c b/src/test/test_shared_random.c
index 72e4522da1..70adf580ab 100644
--- a/src/test/test_shared_random.c
+++ b/src/test/test_shared_random.c
@@ -1318,7 +1318,7 @@ test_keep_commit(void *arg)
expect_log_msg_containing("doesn't match the commit value.");
expect_log_msg_containing("has an invalid reveal value.");
assert_log_predicate(mock_saved_log_n_entries() == 2,
- "expected 2 log entries");
+ ("expected 2 log entries"));
teardown_capture_of_logs();
memcpy(commit->hashed_reveal, place_holder.hashed_reveal,
sizeof(commit->hashed_reveal));
diff --git a/src/test/test_tortls.c b/src/test/test_tortls.c
index 52dafb9f68..8e8487a408 100644
--- a/src/test/test_tortls.c
+++ b/src/test/test_tortls.c
@@ -2,7 +2,7 @@
/* See LICENSE for licensing information */
#define TORTLS_PRIVATE
-#define TORTLS_OPENSSL_PRIVATE
+#define TOR_X509_PRIVATE
#define LOG_PRIVATE
#include "orconfig.h"
@@ -10,61 +10,132 @@
#include <winsock2.h>
#endif
#include <math.h>
+#include <stddef.h>
#include "lib/cc/compat_compiler.h"
-/* Some versions of OpenSSL declare SSL_get_selected_srtp_profile twice in
- * srtp.h. Suppress the GCC warning so we can build with -Wredundant-decl. */
-DISABLE_GCC_WARNING(redundant-decls)
-
-#include <openssl/opensslv.h>
-
-#include <openssl/ssl.h>
-#include <openssl/ssl3.h>
-#include <openssl/err.h>
-#include <openssl/asn1t.h>
-#include <openssl/x509.h>
-#include <openssl/rsa.h>
-#include <openssl/evp.h>
-#include <openssl/bn.h>
-
-ENABLE_GCC_WARNING(redundant-decls)
-
#include "core/or/or.h"
#include "lib/log/log.h"
#include "app/config/config.h"
+#include "lib/crypt_ops/compat_openssl.h"
+#include "lib/tls/x509.h"
+#include "lib/tls/x509_internal.h"
#include "lib/tls/tortls.h"
+#include "lib/tls/tortls_st.h"
+#include "lib/tls/tortls_internal.h"
+#include "lib/encoding/pem.h"
#include "app/config/or_state_st.h"
#include "test/test.h"
#include "test/log_test_helpers.h"
-#define NS_MODULE tortls
+#include "test/test_tortls.h"
-#ifndef HAVE_SSL_STATE
-#define OPENSSL_OPAQUE
-#endif
+#include "tinytest.h"
-#if defined(OPENSSL_OPAQUE) && !defined(LIBRESSL_VERSION_NUMBER)
-#define SSL_STATE_STR "before SSL initialization"
-#else
-#define SSL_STATE_STR "before/accept initialization"
-#endif
+const char* notCompletelyValidCertString =
+ "-----BEGIN CERTIFICATE-----\n"
+ "MIICVjCCAb8CAg37MA0GCSqGSIb3DQEBBQUAMIGbMQswCQYDVQQGEwJKUDEOMAwG\n"
+ "A1UECBMFVG9reW8xEDAOBgNVBAcTB0NodW8ta3UxETAPBgNVBAoTCEZyYW5rNERE\n"
+ "MRgwFgYDVQQLEw9XZWJDZXJ0IFN1cHBvcnQxGDAWBgNVBAMTD0ZyYW5rNEREIFdl\n"
+ "YiBDQTEjMCEGCSqGSIb3DQEJARYUc3VwcG9ydEBmcmFuazRkZC5jb20wHhcNMTIw\n"
+ "ODIyMDUyNzIzWhcNMTcwODIxMDUyNzIzWjBKMQswCQYDVQQGEwJKUDEOMAwGA1UE\n"
+ "CAwFVG9reW8xETAPBgNVBAoMCEZyYW5rNEREMRgwFgYDVQQDDA93d3cuZXhhbXBs\n"
+ "ZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMYBBrx5PlP0WNI/ZdzD\n"
+ "+6Pktmurn+F2kQYbtc7XQh8/LTBvCo+P6iZoLEmUA9e7EXLRxgU1CVqeAi7QcAn9\n"
+ "MwBlc8ksFJHB0rtf9pmf8Oza9E0Bynlq/4/Kb1x+d+AyhL7oK9tQwB24uHOueHi1\n"
+ "C/iVv8CSWKiYe6hzN1txYe8rAgMBAAEwDQYJKoZIhvcNAQEFBQADgYEAASPdjigJ\n"
+ "kXCqKWpnZ/Oc75EUcMi6HztaW8abUMlYXPIgkV2F7YanHOB7K4f7OOLjiz8DTPFf\n"
+ "jC9UeuErhaA/zzWi8ewMTFZW/WshOrm3fNvcMrMLKtH534JKvcdMg6qIdjTFINIr\n"
+ "evnAhf0cwULaebn+lMs8Pdl7y37+sfluVok=\n"
+ "-----END CERTIFICATE-----\n";
+
+const char* validCertString = "-----BEGIN CERTIFICATE-----\n"
+ "MIIDpTCCAY0CAg3+MA0GCSqGSIb3DQEBBQUAMF4xCzAJBgNVBAYTAlVTMREwDwYD\n"
+ "VQQIDAhJbGxpbm9pczEQMA4GA1UEBwwHQ2hpY2FnbzEUMBIGA1UECgwLVG9yIFRl\n"
+ "c3RpbmcxFDASBgNVBAMMC1RvciBUZXN0aW5nMB4XDTE1MDkwNjEzMzk1OVoXDTQz\n"
+ "MDEyMjEzMzk1OVowVjELMAkGA1UEBhMCVVMxEDAOBgNVBAcMB0NoaWNhZ28xFDAS\n"
+ "BgNVBAoMC1RvciBUZXN0aW5nMR8wHQYDVQQDDBZ0ZXN0aW5nLnRvcnByb2plY3Qu\n"
+ "b3JnMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDoT6uyVVhWyOF3wkHjjYbd\n"
+ "nKaykyRv4JVtKQdZ4OpEErmX1zw4MmyzpQNV6iR4bQnWiyLfzyVJMZDIC/WILBfX\n"
+ "w2Pza/yuLgUvDc3twMuhOACzOQVO8PrEF/aVv2+hbCCy2udXvKhnYn+CCXl3ozc8\n"
+ "XcKYvujTXDyvGWY3xwAjlQIDAQABMA0GCSqGSIb3DQEBBQUAA4ICAQCUvnhzQWuQ\n"
+ "MrN+pERkE+zcTI/9dGS90rUMMLgu8VDNqTa0TUQh8uO0EQ6uDvI8Js6e8tgwS0BR\n"
+ "UBahqb7ZHv+rejGCBr5OudqD+x4STiiuPNJVs86JTLN8SpM9CHjIBH5WCCN2KOy3\n"
+ "mevNoRcRRyYJzSFULCunIK6FGulszigMYGscrO4oiTkZiHPh9KvWT40IMiHfL+Lw\n"
+ "EtEWiLex6064LcA2YQ1AMuSZyCexks63lcfaFmQbkYOKqXa1oLkIRuDsOaSVjTfe\n"
+ "vec+X6jvf12cFTKS5WIeqkKF2Irt+dJoiHEGTe5RscUMN/f+gqHPzfFz5dR23sxo\n"
+ "g+HC6MZHlFkLAOx3wW6epPS8A/m1mw3zMPoTnb2U2YYt8T0dJMMlUn/7Y1sEAa+a\n"
+ "dSTMaeUf6VnJ//11m454EZl1to9Z7oJOgqmFffSrdD4BGIWe8f7hhW6L1Enmqe/J\n"
+ "BKL3wbzZh80O1W0bndAwhnEEhlzneFY84cbBo9pmVxpODHkUcStpr5Z7pBDrcL21\n"
+ "Ss/aB/1YrsVXhdvJdOGxl3Mnl9dUY57CympLGlT8f0pPS6GAKOelECOhFMHmJd8L\n"
+ "dj3XQSmKtYHevZ6IvuMXSlB/fJvSjSlkCuLo5+kJoaqPuRu+i/S1qxeRy3CBwmnE\n"
+ "LdSNdcX4N79GQJ996PA8+mUCQG7YRtK+WA==\n"
+ "-----END CERTIFICATE-----\n";
+
+const char* caCertString = "-----BEGIN CERTIFICATE-----\n"
+ "MIIFjzCCA3egAwIBAgIJAKd5WgyfPMYRMA0GCSqGSIb3DQEBCwUAMF4xCzAJBgNV\n"
+ "BAYTAlVTMREwDwYDVQQIDAhJbGxpbm9pczEQMA4GA1UEBwwHQ2hpY2FnbzEUMBIG\n"
+ "A1UECgwLVG9yIFRlc3RpbmcxFDASBgNVBAMMC1RvciBUZXN0aW5nMB4XDTE1MDkw\n"
+ "NjEzMzc0MVoXDTQzMDEyMjEzMzc0MVowXjELMAkGA1UEBhMCVVMxETAPBgNVBAgM\n"
+ "CElsbGlub2lzMRAwDgYDVQQHDAdDaGljYWdvMRQwEgYDVQQKDAtUb3IgVGVzdGlu\n"
+ "ZzEUMBIGA1UEAwwLVG9yIFRlc3RpbmcwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw\n"
+ "ggIKAoICAQCpLMUEiLW5leUgBZoEJms2V7lZRhIAjnJBhVMHD0e3UubNknmaQoxf\n"
+ "ARz3rvqOaRd0JlV+qM9qE0DjiYcCVP1cAfqAo9d83uS1vwY3YMVJzADlaIiHfyVW\n"
+ "uEgBy0vvkeUBqaua24dYlcwsemOiXYLu41yM1wkcGHW1AhBNHppY6cznb8TyLgNM\n"
+ "2x3SGUdzc5XMyAFx51faKGBA3wjs+Hg1PLY7d30nmCgEOBavpm5I1disM/0k+Mcy\n"
+ "YmAKEo/iHJX/rQzO4b9znP69juLlR8PDBUJEVIG/CYb6+uw8MjjUyiWXYoqfVmN2\n"
+ "hm/lH8b6rXw1a2Aa3VTeD0DxaWeacMYHY/i01fd5n7hCoDTRNdSw5KJ0L3Z0SKTu\n"
+ "0lzffKzDaIfyZGlpW5qdouACkWYzsaitQOePVE01PIdO30vUfzNTFDfy42ccx3Di\n"
+ "59UCu+IXB+eMtrBfsok0Qc63vtF1linJgjHW1z/8ujk8F7/qkOfODhk4l7wngc2A\n"
+ "EmwWFIFoGaiTEZHB9qteXr4unbXZ0AHpM02uGGwZEGohjFyebEb73M+J57WKKAFb\n"
+ "PqbLcGUksL1SHNBNAJcVLttX55sO4nbidOS/kA3m+F1R04MBTyQF9qA6YDDHqdI3\n"
+ "h/3pw0Z4fxVouTYT4/NfRnX4JTP4u+7Mpcoof28VME0qWqD1LnRhFQIDAQABo1Aw\n"
+ "TjAdBgNVHQ4EFgQUMoAgIXH7pZ3QMRwTjT+DM9Yo/v0wHwYDVR0jBBgwFoAUMoAg\n"
+ "IXH7pZ3QMRwTjT+DM9Yo/v0wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOC\n"
+ "AgEAUJxacjXR9sT+Xs6ISFiUsyd0T6WVKMnV46xrYJHirGfx+krWHrjxMY+ZtxYD\n"
+ "DBDGlo11Qc4v6QrclNf5QUBfIiGQsP9Cm6hHcQ+Tpg9HHCgSqG1YNPwCPReCR4br\n"
+ "BLvLfrfkcBL2IWM0PdQdCze+59DBfipsULD2mEn9fjYRXQEwb2QWtQ9qRc20Yb/x\n"
+ "Q4b/+CvUodLkaq7B8MHz0BV8HHcBoph6DYaRmO/N+hPauIuSp6XyaGYcEefGKVKj\n"
+ "G2+fcsdyXsoijNdL8vNKwm4j2gVwCBnw16J00yfFoV46YcbfqEdJB2je0XSvwXqt\n"
+ "14AOTngxso2h9k9HLtrfpO1ZG/B5AcCMs1lzbZ2fp5DPHtjvvmvA2RJqgo3yjw4W\n"
+ "4DHAuTglYFlC3mDHNfNtcGP20JvepcQNzNP2UzwcpOc94hfKikOFw+gf9Vf1qd0y\n"
+ "h/Sk6OZHn2+JVUPiWHIQV98Vtoh4RmUZDJD+b55ia3fQGTGzt4z1XFzQYSva5sfs\n"
+ "wocS/papthqWldQU7x+3wofNd5CNU1x6WKXG/yw30IT/4F8ADJD6GeygNT8QJYvt\n"
+ "u/8lAkbOy6B9xGmSvr0Kk1oq9P2NshA6kalxp1Oz/DTNDdL4AeBXV3JmM6WWCjGn\n"
+ "Yy1RT69d0rwYc5u/vnqODz1IjvT90smsrkBumGt791FAFeg=\n"
+ "-----END CERTIFICATE-----\n";
-#ifndef OPENSSL_OPAQUE
-static SSL_METHOD *
-give_me_a_test_method(void)
+tor_x509_cert_impl_t *
+read_cert_from(const char *str)
{
- SSL_METHOD *method = tor_malloc_zero(sizeof(SSL_METHOD));
- memcpy(method, TLSv1_method(), sizeof(SSL_METHOD));
- return method;
+ size_t len = strlen(str);
+ uint8_t *raw_cert = tor_malloc(len);
+ size_t true_len = pem_decode(raw_cert, len, str, len, "CERTIFICATE");
+ tor_x509_cert_t *cert = tor_x509_cert_decode(raw_cert, true_len);
+ tor_free(raw_cert);
+ if (! cert) {
+ return NULL;
+ }
+ tor_x509_cert_impl_t *res = tor_x509_cert_impl_dup_(cert->cert);
+ tor_x509_cert_free(cert);
+ return res;
}
-static int
-fake_num_ciphers(void)
+static tor_x509_cert_impl_t *
+ fixed_try_to_extract_certs_from_tls_cert_out_result = NULL;
+static tor_x509_cert_impl_t *
+ fixed_try_to_extract_certs_from_tls_id_cert_out_result = NULL;
+
+static void
+fixed_try_to_extract_certs_from_tls(int severity, tor_tls_t *tls,
+ tor_x509_cert_impl_t **cert_out,
+ tor_x509_cert_impl_t **id_cert_out)
{
- return 0;
+ (void) severity;
+ (void) tls;
+ *cert_out = fixed_try_to_extract_certs_from_tls_cert_out_result;
+ *id_cert_out = fixed_try_to_extract_certs_from_tls_id_cert_out_result;
}
-#endif /* !defined(OPENSSL_OPAQUE) */
static void
test_tortls_errno_to_tls_error(void *data)
@@ -108,6 +179,7 @@ test_tortls_err_to_string(void *data)
(void)1;
}
+#ifdef ENABLE_OPENSSL
static int
mock_tls_cert_matches_key(const tor_tls_t *tls, const tor_x509_cert_t *cert)
{
@@ -117,66 +189,6 @@ mock_tls_cert_matches_key(const tor_tls_t *tls, const tor_x509_cert_t *cert)
}
static void
-test_tortls_tor_tls_new(void *data)
-{
- (void) data;
- MOCK(tor_tls_cert_matches_key, mock_tls_cert_matches_key);
- crypto_pk_t *key1 = NULL, *key2 = NULL;
- SSL_METHOD *method = NULL;
-
- key1 = pk_generate(2);
- key2 = pk_generate(3);
-
- tor_tls_t *tls = NULL;
- tt_int_op(tor_tls_context_init(TOR_TLS_CTX_IS_PUBLIC_SERVER,
- key1, key2, 86400), OP_EQ, 0);
- tls = tor_tls_new(-1, 0);
- tt_want(tls);
- tor_tls_free(tls); tls = NULL;
-
- SSL_CTX_free(client_tls_context->ctx);
- client_tls_context->ctx = NULL;
- tls = tor_tls_new(-1, 0);
- tt_ptr_op(tls, OP_EQ, NULL);
-
-#ifndef OPENSSL_OPAQUE
- method = give_me_a_test_method();
- SSL_CTX *ctx = SSL_CTX_new(method);
- method->num_ciphers = fake_num_ciphers;
- client_tls_context->ctx = ctx;
- tls = tor_tls_new(-1, 0);
- tt_ptr_op(tls, OP_EQ, NULL);
-#endif /* !defined(OPENSSL_OPAQUE) */
-
- done:
- UNMOCK(tor_tls_cert_matches_key);
- crypto_pk_free(key1);
- crypto_pk_free(key2);
- tor_tls_free(tls);
- tor_free(method);
- tor_tls_free_all();
-}
-
-#define NS_MODULE tortls
-NS_DECL(void, logv, (int severity, log_domain_mask_t domain,
- const char *funcname, const char *suffix,
- const char *format, va_list ap));
-
-static void
-NS(logv)(int severity, log_domain_mask_t domain,
- const char *funcname, const char *suffix, const char *format,
- va_list ap)
-{
- (void) severity;
- (void) domain;
- (void) funcname;
- (void) suffix;
- (void) format;
- (void) ap; // XXXX look at this.
- CALLED(logv)++;
-}
-
-static void
test_tortls_tor_tls_get_error(void *data)
{
(void) data;
@@ -189,11 +201,10 @@ test_tortls_tor_tls_get_error(void *data)
tt_int_op(tor_tls_context_init(TOR_TLS_CTX_IS_PUBLIC_SERVER,
key1, key2, 86400), OP_EQ, 0);
tls = tor_tls_new(-1, 0);
- NS_MOCK(logv);
- tt_int_op(CALLED(logv), OP_EQ, 0);
+ setup_capture_of_logs(LOG_WARN);
tor_tls_get_error(tls, 0, 0,
- (const char *)"test", 0, 0);
- tt_int_op(CALLED(logv), OP_EQ, 1);
+ (const char *)"in unit test", LOG_WARN, LD_GENERAL);
+ expect_single_log_msg_containing("unexpected close while in unit test");
done:
UNMOCK(tor_tls_cert_matches_key);
@@ -202,332 +213,7 @@ test_tortls_tor_tls_get_error(void *data)
crypto_pk_free(key2);
tor_tls_free(tls);
}
-
-static void
-library_init(void)
-{
-#ifdef OPENSSL_1_1_API
- OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS, NULL);
-#else
- SSL_library_init();
- SSL_load_error_strings();
#endif
-}
-
-static void
-test_tortls_get_state_description(void *ignored)
-{
- (void)ignored;
- tor_tls_t *tls;
- char *buf;
- SSL_CTX *ctx;
-
- library_init();
- ctx = SSL_CTX_new(SSLv23_method());
-
- buf = tor_malloc_zero(1000);
- tls = tor_malloc_zero(sizeof(tor_tls_t));
-
- tor_tls_get_state_description(NULL, buf, 20);
- tt_str_op(buf, OP_EQ, "(No SSL object)");
-
- SSL_free(tls->ssl);
- tls->ssl = NULL;
- tor_tls_get_state_description(tls, buf, 20);
- tt_str_op(buf, OP_EQ, "(No SSL object)");
-
- tls->ssl = SSL_new(ctx);
- tor_tls_get_state_description(tls, buf, 200);
- tt_str_op(buf, OP_EQ, SSL_STATE_STR " in HANDSHAKE");
-
- tls->state = TOR_TLS_ST_OPEN;
- tor_tls_get_state_description(tls, buf, 200);
- tt_str_op(buf, OP_EQ, SSL_STATE_STR " in OPEN");
-
- tls->state = TOR_TLS_ST_GOTCLOSE;
- tor_tls_get_state_description(tls, buf, 200);
- tt_str_op(buf, OP_EQ, SSL_STATE_STR " in GOTCLOSE");
-
- tls->state = TOR_TLS_ST_SENTCLOSE;
- tor_tls_get_state_description(tls, buf, 200);
- tt_str_op(buf, OP_EQ, SSL_STATE_STR " in SENTCLOSE");
-
- tls->state = TOR_TLS_ST_CLOSED;
- tor_tls_get_state_description(tls, buf, 200);
- tt_str_op(buf, OP_EQ, SSL_STATE_STR " in CLOSED");
-
- tls->state = TOR_TLS_ST_RENEGOTIATE;
- tor_tls_get_state_description(tls, buf, 200);
- tt_str_op(buf, OP_EQ, SSL_STATE_STR " in RENEGOTIATE");
-
- tls->state = TOR_TLS_ST_BUFFEREVENT;
- tor_tls_get_state_description(tls, buf, 200);
- tt_str_op(buf, OP_EQ, SSL_STATE_STR);
-
- tls->state = 7;
- tor_tls_get_state_description(tls, buf, 200);
- tt_str_op(buf, OP_EQ, SSL_STATE_STR " in unknown TLS state");
-
- done:
- SSL_CTX_free(ctx);
- SSL_free(tls->ssl);
- tor_free(buf);
- tor_free(tls);
-}
-
-static void
-test_tortls_get_by_ssl(void *ignored)
-{
- (void)ignored;
- tor_tls_t *tls;
- tor_tls_t *res;
- SSL_CTX *ctx;
- SSL *ssl;
-
- library_init();
- tor_tls_allocate_tor_tls_object_ex_data_index();
-
- ctx = SSL_CTX_new(SSLv23_method());
- tls = tor_malloc_zero(sizeof(tor_tls_t));
- tls->magic = TOR_TLS_MAGIC;
-
- ssl = SSL_new(ctx);
-
- res = tor_tls_get_by_ssl(ssl);
- tt_assert(!res);
-
- SSL_set_ex_data(ssl, tor_tls_object_ex_data_index, tls);
-
- res = tor_tls_get_by_ssl(ssl);
- tt_assert(res == tls);
-
- done:
- SSL_free(ssl);
- SSL_CTX_free(ctx);
- tor_free(tls);
-}
-
-static void
-test_tortls_allocate_tor_tls_object_ex_data_index(void *ignored)
-{
- (void)ignored;
- int first;
-
- tor_tls_allocate_tor_tls_object_ex_data_index();
-
- first = tor_tls_object_ex_data_index;
- tor_tls_allocate_tor_tls_object_ex_data_index();
- tt_int_op(first, OP_EQ, tor_tls_object_ex_data_index);
-
- done:
- (void)0;
-}
-
-static void
-test_tortls_log_one_error(void *ignored)
-{
- (void)ignored;
- tor_tls_t *tls;
- SSL_CTX *ctx;
- SSL *ssl = NULL;
-
- library_init();
-
- ctx = SSL_CTX_new(SSLv23_method());
- tls = tor_malloc_zero(sizeof(tor_tls_t));
- setup_capture_of_logs(LOG_INFO);
-
- tor_tls_log_one_error(NULL, 0, LOG_WARN, 0, "something");
- expect_log_msg("TLS error while something: "
- "(null) (in (null):(null):---)\n");
-
- mock_clean_saved_logs();
- tor_tls_log_one_error(tls, 0, LOG_WARN, 0, NULL);
- expect_log_msg("TLS error: (null) "
- "(in (null):(null):---)\n");
-
- mock_clean_saved_logs();
- tls->address = tor_strdup("127.hello");
- tor_tls_log_one_error(tls, 0, LOG_WARN, 0, NULL);
- expect_log_msg("TLS error with 127.hello: "
- "(null) (in (null):(null):---)\n");
- tor_free(tls->address);
-
- mock_clean_saved_logs();
- tls->address = tor_strdup("127.hello");
- tor_tls_log_one_error(tls, 0, LOG_WARN, 0, "blarg");
- expect_log_msg("TLS error while blarg with "
- "127.hello: (null) (in (null):(null):---)\n");
-
- mock_clean_saved_logs();
- tor_tls_log_one_error(tls, ERR_PACK(1, 2, 3), LOG_WARN, 0, NULL);
- expect_log_msg("TLS error with 127.hello: "
- "BN lib (in unknown library:(null):---)\n");
-
- mock_clean_saved_logs();
- tor_tls_log_one_error(tls, ERR_PACK(1, 2, SSL_R_HTTP_REQUEST),
- LOG_WARN, 0, NULL);
- expect_log_severity(LOG_INFO);
-
- mock_clean_saved_logs();
- tor_tls_log_one_error(tls, ERR_PACK(1, 2, SSL_R_HTTPS_PROXY_REQUEST),
- LOG_WARN, 0, NULL);
- expect_log_severity(LOG_INFO);
-
- mock_clean_saved_logs();
- tor_tls_log_one_error(tls, ERR_PACK(1, 2, SSL_R_RECORD_LENGTH_MISMATCH),
- LOG_WARN, 0, NULL);
- expect_log_severity(LOG_INFO);
-
-#ifndef OPENSSL_1_1_API
- mock_clean_saved_logs();
- tor_tls_log_one_error(tls, ERR_PACK(1, 2, SSL_R_RECORD_TOO_LARGE),
- LOG_WARN, 0, NULL);
- expect_log_severity(LOG_INFO);
-#endif /* !defined(OPENSSL_1_1_API) */
-
- mock_clean_saved_logs();
- tor_tls_log_one_error(tls, ERR_PACK(1, 2, SSL_R_UNKNOWN_PROTOCOL),
- LOG_WARN, 0, NULL);
- expect_log_severity(LOG_INFO);
-
- mock_clean_saved_logs();
- tor_tls_log_one_error(tls, ERR_PACK(1, 2, SSL_R_UNSUPPORTED_PROTOCOL),
- LOG_WARN, 0, NULL);
- expect_log_severity(LOG_INFO);
-
- tls->ssl = SSL_new(ctx);
-
- mock_clean_saved_logs();
- tor_tls_log_one_error(tls, 0, LOG_WARN, 0, NULL);
- expect_log_msg("TLS error with 127.hello: (null)"
- " (in (null):(null):" SSL_STATE_STR ")\n");
-
- done:
- teardown_capture_of_logs();
- SSL_free(ssl);
- SSL_CTX_free(ctx);
- if (tls && tls->ssl)
- SSL_free(tls->ssl);
- if (tls)
- tor_free(tls->address);
- tor_free(tls);
-}
-
-#ifndef OPENSSL_OPAQUE
-static void
-test_tortls_get_error(void *ignored)
-{
- (void)ignored;
- tor_tls_t *tls;
- int ret;
- SSL_CTX *ctx;
-
- library_init();
-
- ctx = SSL_CTX_new(SSLv23_method());
- setup_capture_of_logs(LOG_INFO);
- tls = tor_malloc_zero(sizeof(tor_tls_t));
- tls->ssl = SSL_new(ctx);
- SSL_set_bio(tls->ssl, BIO_new(BIO_s_mem()), NULL);
-
- ret = tor_tls_get_error(tls, 0, 0, "something", LOG_WARN, 0);
- tt_int_op(ret, OP_EQ, TOR_TLS_ERROR_IO);
- expect_log_msg("TLS error: unexpected close while"
- " something (before/accept initialization)\n");
-
- mock_clean_saved_logs();
- ret = tor_tls_get_error(tls, 2, 0, "something", LOG_WARN, 0);
- tt_int_op(ret, OP_EQ, 0);
- expect_no_log_entry();
-
- mock_clean_saved_logs();
- ret = tor_tls_get_error(tls, 0, 1, "something", LOG_WARN, 0);
- tt_int_op(ret, OP_EQ, -11);
- expect_no_log_entry();
-
- mock_clean_saved_logs();
- ERR_clear_error();
- ERR_put_error(ERR_LIB_BN, 2, -1, "somewhere.c", 99);
- ret = tor_tls_get_error(tls, 0, 0, "something", LOG_WARN, 0);
- tt_int_op(ret, OP_EQ, TOR_TLS_ERROR_MISC);
- expect_log_msg("TLS error while something: (null)"
- " (in bignum routines:(null):before/accept initialization)\n");
-
- mock_clean_saved_logs();
- ERR_clear_error();
- tls->ssl->rwstate = SSL_READING;
- SSL_get_rbio(tls->ssl)->flags = BIO_FLAGS_READ;
- ret = tor_tls_get_error(tls, -1, 0, "something", LOG_WARN, 0);
- tt_int_op(ret, OP_EQ, TOR_TLS_WANTREAD);
- expect_no_log_entry();
-
- mock_clean_saved_logs();
- ERR_clear_error();
- tls->ssl->rwstate = SSL_READING;
- SSL_get_rbio(tls->ssl)->flags = BIO_FLAGS_WRITE;
- ret = tor_tls_get_error(tls, -1, 0, "something", LOG_WARN, 0);
- tt_int_op(ret, OP_EQ, TOR_TLS_WANTWRITE);
- expect_no_log_entry();
-
- mock_clean_saved_logs();
- ERR_clear_error();
- tls->ssl->rwstate = 0;
- tls->ssl->shutdown = SSL_RECEIVED_SHUTDOWN;
- tls->ssl->s3->warn_alert =SSL_AD_CLOSE_NOTIFY;
- ret = tor_tls_get_error(tls, 0, 0, "something", LOG_WARN, 0);
- tt_int_op(ret, OP_EQ, TOR_TLS_CLOSE);
- expect_log_entry();
-
- mock_clean_saved_logs();
- ret = tor_tls_get_error(tls, 0, 2, "something", LOG_WARN, 0);
- tt_int_op(ret, OP_EQ, -10);
- expect_no_log_entry();
-
- mock_clean_saved_logs();
- ERR_put_error(ERR_LIB_SYS, 2, -1, "somewhere.c", 99);
- ret = tor_tls_get_error(tls, -1, 0, "something", LOG_WARN, 0);
- tt_int_op(ret, OP_EQ, -9);
- expect_log_msg("TLS error while something: (null) (in system library:"
- "connect:before/accept initialization)\n");
-
- done:
- teardown_capture_of_logs();
- SSL_free(tls->ssl);
- tor_free(tls);
- SSL_CTX_free(ctx);
-}
-#endif /* !defined(OPENSSL_OPAQUE) */
-
-static void
-test_tortls_always_accept_verify_cb(void *ignored)
-{
- (void)ignored;
- int ret;
-
- ret = always_accept_verify_cb(0, NULL);
- tt_int_op(ret, OP_EQ, 1);
-
- done:
- (void)0;
-}
-
-#ifndef OPENSSL_OPAQUE
-static void
-test_tortls_x509_cert_free(void *ignored)
-{
- (void)ignored;
- tor_x509_cert_t *cert;
-
- cert = tor_malloc_zero(sizeof(tor_x509_cert_t));
- tor_x509_cert_free(cert);
-
- cert = tor_malloc_zero(sizeof(tor_x509_cert_t));
- cert->cert = X509_new();
- cert->encoded = tor_malloc_zero(1);
- tor_x509_cert_free(cert);
-}
-#endif /* !defined(OPENSSL_OPAQUE) */
static void
test_tortls_x509_cert_get_id_digests(void *ignored)
@@ -553,161 +239,6 @@ test_tortls_x509_cert_get_id_digests(void *ignored)
tor_free(d);
}
-#ifndef OPENSSL_OPAQUE
-/*
- * Use only for the matching fake_x509_free() call
- */
-static X509 *
-fake_x509_malloc(void)
-{
- return tor_malloc_zero(sizeof(X509));
-}
-
-static void
-fake_x509_free(X509 *cert)
-{
- if (cert) {
- if (cert->cert_info) {
- if (cert->cert_info->key) {
- if (cert->cert_info->key->pkey) {
- tor_free(cert->cert_info->key->pkey);
- }
- tor_free(cert->cert_info->key);
- }
- tor_free(cert->cert_info);
- }
- tor_free(cert);
- }
-}
-#endif
-
-static tor_x509_cert_t *fixed_x509_cert = NULL;
-static tor_x509_cert_t *
-get_peer_cert_mock_return_fixed(tor_tls_t *tls)
-{
- (void)tls;
- if (fixed_x509_cert)
- return tor_x509_cert_dup(fixed_x509_cert);
- else
- return NULL;
-}
-
-static void
-test_tortls_cert_matches_key(void *ignored)
-{
- (void)ignored;
-
- X509 *cert1 = NULL, *cert2 = NULL, *cert3 = NULL, *cert4 = NULL;
- tor_x509_cert_t *c1 = NULL, *c2 = NULL, *c3 = NULL, *c4 = NULL;
- crypto_pk_t *k1 = NULL, *k2 = NULL, *k3 = NULL;
-
- k1 = pk_generate(1);
- k2 = pk_generate(2);
- k3 = pk_generate(3);
-
- cert1 = tor_tls_create_certificate(k1, k2, "A", "B", 1000);
- cert2 = tor_tls_create_certificate(k1, k3, "C", "D", 1000);
- cert3 = tor_tls_create_certificate(k2, k3, "C", "D", 1000);
- cert4 = tor_tls_create_certificate(k3, k2, "E", "F", 1000);
-
- tt_assert(cert1 && cert2 && cert3 && cert4);
-
- c1 = tor_x509_cert_new(cert1); cert1 = NULL;
- c2 = tor_x509_cert_new(cert2); cert2 = NULL;
- c3 = tor_x509_cert_new(cert3); cert3 = NULL;
- c4 = tor_x509_cert_new(cert4); cert4 = NULL;
-
- tt_assert(c1 && c2 && c3 && c4);
-
- MOCK(tor_tls_get_peer_cert, get_peer_cert_mock_return_fixed);
-
- fixed_x509_cert = NULL;
- /* If the peer has no certificate, it shouldn't match anything. */
- tt_assert(! tor_tls_cert_matches_key(NULL, c1));
- tt_assert(! tor_tls_cert_matches_key(NULL, c2));
- tt_assert(! tor_tls_cert_matches_key(NULL, c3));
- tt_assert(! tor_tls_cert_matches_key(NULL, c4));
- fixed_x509_cert = c1;
- /* If the peer has a certificate, it should match every cert with the same
- * subject key. */
- tt_assert(tor_tls_cert_matches_key(NULL, c1));
- tt_assert(tor_tls_cert_matches_key(NULL, c2));
- tt_assert(! tor_tls_cert_matches_key(NULL, c3));
- tt_assert(! tor_tls_cert_matches_key(NULL, c4));
-
- done:
- tor_x509_cert_free(c1);
- tor_x509_cert_free(c2);
- tor_x509_cert_free(c3);
- tor_x509_cert_free(c4);
- if (cert1) X509_free(cert1);
- if (cert2) X509_free(cert2);
- if (cert3) X509_free(cert3);
- if (cert4) X509_free(cert4);
- crypto_pk_free(k1);
- crypto_pk_free(k2);
- crypto_pk_free(k3);
- UNMOCK(tor_tls_get_peer_cert);
-}
-
-#ifndef OPENSSL_OPAQUE
-static void
-test_tortls_cert_get_key(void *ignored)
-{
- (void)ignored;
- tor_x509_cert_t *cert = NULL;
- crypto_pk_t *res = NULL;
- cert = tor_malloc_zero(sizeof(tor_x509_cert_t));
- X509 *key = NULL;
- key = fake_x509_malloc();
- key->references = 1;
-
- res = tor_tls_cert_get_key(cert);
- tt_assert(!res);
-
- cert->cert = key;
- key->cert_info = tor_malloc_zero(sizeof(X509_CINF));
- key->cert_info->key = tor_malloc_zero(sizeof(X509_PUBKEY));
- key->cert_info->key->pkey = tor_malloc_zero(sizeof(EVP_PKEY));
- key->cert_info->key->pkey->references = 1;
- key->cert_info->key->pkey->type = 2;
- res = tor_tls_cert_get_key(cert);
- tt_assert(!res);
-
- done:
- fake_x509_free(key);
- tor_free(cert);
- crypto_pk_free(res);
-}
-#endif /* !defined(OPENSSL_OPAQUE) */
-
-static void
-test_tortls_get_my_client_auth_key(void *ignored)
-{
- (void)ignored;
- crypto_pk_t *ret;
- crypto_pk_t *expected;
- tor_tls_context_t *ctx;
- RSA *k = RSA_new();
-
- ctx = tor_malloc_zero(sizeof(tor_tls_context_t));
- expected = crypto_new_pk_from_rsa_(k);
- ctx->auth_key = expected;
-
- client_tls_context = NULL;
- ret = tor_tls_get_my_client_auth_key();
- tt_assert(!ret);
-
- client_tls_context = ctx;
- ret = tor_tls_get_my_client_auth_key();
- tt_assert(ret == expected);
-
- done:
- RSA_free(k);
- tor_free(expected);
- tor_free(ctx);
-}
-
static void
test_tortls_get_my_certs(void *ignored)
{
@@ -743,437 +274,7 @@ test_tortls_get_my_certs(void *ignored)
(void)1;
}
-#ifndef HAVE_SSL_GET_CLIENT_CIPHERS
-static SSL_CIPHER *
-get_cipher_by_name(const char *name)
-{
- int i;
- const SSL_METHOD *method = SSLv23_method();
- int num = method->num_ciphers();
-
- for (i = 0; i < num; ++i) {
- const SSL_CIPHER *cipher = method->get_cipher(i);
- const char *ciphername = SSL_CIPHER_get_name(cipher);
- if (!strcmp(ciphername, name)) {
- return (SSL_CIPHER *)cipher;
- }
- }
-
- return NULL;
-}
-#endif /* !defined(HAVE_SSL_GET_CLIENT_CIPHERS) */
-
-#ifndef OPENSSL_OPAQUE
-static void
-test_tortls_get_ciphersuite_name(void *ignored)
-{
- (void)ignored;
- const char *ret;
- tor_tls_t *ctx;
- ctx = tor_malloc_zero(sizeof(tor_tls_t));
- ctx->ssl = tor_malloc_zero(sizeof(SSL));
-
- ret = tor_tls_get_ciphersuite_name(ctx);
- tt_str_op(ret, OP_EQ, "(NONE)");
-
- done:
- tor_free(ctx->ssl);
- tor_free(ctx);
-}
-
-static SSL_CIPHER *
-get_cipher_by_id(uint16_t id)
-{
- int i;
- const SSL_METHOD *method = SSLv23_method();
- int num = method->num_ciphers();
- for (i = 0; i < num; ++i) {
- const SSL_CIPHER *cipher = method->get_cipher(i);
- if (id == (SSL_CIPHER_get_id(cipher) & 0xffff)) {
- return (SSL_CIPHER *)cipher;
- }
- }
-
- return NULL;
-}
-
-static void
-test_tortls_classify_client_ciphers(void *ignored)
-{
- (void)ignored;
- int i;
- int ret;
- SSL_CTX *ctx;
- SSL *ssl;
- tor_tls_t *tls;
- STACK_OF(SSL_CIPHER) *ciphers;
- SSL_CIPHER *tmp_cipher;
-
- library_init();
-
- tor_tls_allocate_tor_tls_object_ex_data_index();
-
- tls = tor_malloc_zero(sizeof(tor_tls_t));
- tls->magic = TOR_TLS_MAGIC;
-
- ctx = SSL_CTX_new(TLSv1_method());
- ssl = SSL_new(ctx);
- tls->ssl = ssl;
-
- ciphers = sk_SSL_CIPHER_new_null();
-
- ret = tor_tls_classify_client_ciphers(ssl, NULL);
- tt_int_op(ret, OP_EQ, -1);
-
- SSL_set_ex_data(ssl, tor_tls_object_ex_data_index, tls);
- tls->client_cipher_list_type = 42;
-
- ret = tor_tls_classify_client_ciphers(ssl, NULL);
- tt_int_op(ret, OP_EQ, 42);
-
- tls->client_cipher_list_type = 0;
- ret = tor_tls_classify_client_ciphers(ssl, ciphers);
- tt_int_op(ret, OP_EQ, 1);
- tt_int_op(tls->client_cipher_list_type, OP_EQ, 1);
-
- tls->client_cipher_list_type = 0;
- ret = tor_tls_classify_client_ciphers(ssl, SSL_get_ciphers(ssl));
- tt_int_op(ret, OP_EQ, 3);
- tt_int_op(tls->client_cipher_list_type, OP_EQ, 3);
-
- SSL_CIPHER *one = get_cipher_by_name(TLS1_TXT_DHE_RSA_WITH_AES_128_SHA),
- *two = get_cipher_by_name(TLS1_TXT_DHE_RSA_WITH_AES_256_SHA),
- *three = get_cipher_by_name(SSL3_TXT_EDH_RSA_DES_192_CBC3_SHA),
- *four = NULL;
- sk_SSL_CIPHER_push(ciphers, one);
- sk_SSL_CIPHER_push(ciphers, two);
- sk_SSL_CIPHER_push(ciphers, three);
- sk_SSL_CIPHER_push(ciphers, four);
-
- tls->client_cipher_list_type = 0;
- ret = tor_tls_classify_client_ciphers(ssl, ciphers);
- tt_int_op(ret, OP_EQ, 1);
- tt_int_op(tls->client_cipher_list_type, OP_EQ, 1);
-
- sk_SSL_CIPHER_zero(ciphers);
-
- one = get_cipher_by_name("ECDHE-RSA-AES256-GCM-SHA384");
- tt_assert(one);
- one->id = 0x00ff;
- two = get_cipher_by_name("ECDHE-RSA-AES128-GCM-SHA256");
- tt_assert(two);
- two->id = 0x0000;
- sk_SSL_CIPHER_push(ciphers, one);
- tls->client_cipher_list_type = 0;
- ret = tor_tls_classify_client_ciphers(ssl, ciphers);
- tt_int_op(ret, OP_EQ, 3);
- tt_int_op(tls->client_cipher_list_type, OP_EQ, 3);
-
- sk_SSL_CIPHER_push(ciphers, two);
- tls->client_cipher_list_type = 0;
- ret = tor_tls_classify_client_ciphers(ssl, ciphers);
- tt_int_op(ret, OP_EQ, 3);
- tt_int_op(tls->client_cipher_list_type, OP_EQ, 3);
-
- one->id = 0xC00A;
- tls->client_cipher_list_type = 0;
- ret = tor_tls_classify_client_ciphers(ssl, ciphers);
- tt_int_op(ret, OP_EQ, 3);
- tt_int_op(tls->client_cipher_list_type, OP_EQ, 3);
-
- sk_SSL_CIPHER_zero(ciphers);
- for (i=0; v2_cipher_list[i]; i++) {
- tmp_cipher = get_cipher_by_id(v2_cipher_list[i]);
- tt_assert(tmp_cipher);
- sk_SSL_CIPHER_push(ciphers, tmp_cipher);
- }
- tls->client_cipher_list_type = 0;
- ret = tor_tls_classify_client_ciphers(ssl, ciphers);
- tt_int_op(ret, OP_EQ, 2);
- tt_int_op(tls->client_cipher_list_type, OP_EQ, 2);
-
- done:
- sk_SSL_CIPHER_free(ciphers);
- SSL_free(tls->ssl);
- tor_free(tls);
- SSL_CTX_free(ctx);
-}
-#endif /* !defined(OPENSSL_OPAQUE) */
-
-static void
-test_tortls_client_is_using_v2_ciphers(void *ignored)
-{
- (void)ignored;
-
-#ifdef HAVE_SSL_GET_CLIENT_CIPHERS
- tt_skip();
- done:
- (void)1;
-#else
- int ret;
- SSL_CTX *ctx;
- SSL *ssl;
- SSL_SESSION *sess;
- STACK_OF(SSL_CIPHER) *ciphers;
-
- library_init();
-
- ctx = SSL_CTX_new(TLSv1_method());
- ssl = SSL_new(ctx);
- sess = SSL_SESSION_new();
-
- ret = tor_tls_client_is_using_v2_ciphers(ssl);
- tt_int_op(ret, OP_EQ, -1);
-
- ssl->session = sess;
- ret = tor_tls_client_is_using_v2_ciphers(ssl);
- tt_int_op(ret, OP_EQ, 0);
-
- ciphers = sk_SSL_CIPHER_new_null();
- SSL_CIPHER *one = get_cipher_by_name("ECDHE-RSA-AES256-GCM-SHA384");
- tt_assert(one);
- one->id = 0x00ff;
- sk_SSL_CIPHER_push(ciphers, one);
- sess->ciphers = ciphers;
- ret = tor_tls_client_is_using_v2_ciphers(ssl);
- tt_int_op(ret, OP_EQ, 1);
- done:
- SSL_free(ssl);
- SSL_CTX_free(ctx);
-#endif /* defined(HAVE_SSL_GET_CLIENT_CIPHERS) */
-}
-
-#ifndef OPENSSL_OPAQUE
-static X509 *fixed_try_to_extract_certs_from_tls_cert_out_result = NULL;
-static X509 *fixed_try_to_extract_certs_from_tls_id_cert_out_result = NULL;
-
-static void
-fixed_try_to_extract_certs_from_tls(int severity, tor_tls_t *tls,
- X509 **cert_out, X509 **id_cert_out)
-{
- (void) severity;
- (void) tls;
- *cert_out = fixed_try_to_extract_certs_from_tls_cert_out_result;
- *id_cert_out = fixed_try_to_extract_certs_from_tls_id_cert_out_result;
-}
-#endif /* !defined(OPENSSL_OPAQUE) */
-
-#ifndef OPENSSL_OPAQUE
-static const char* notCompletelyValidCertString =
- "-----BEGIN CERTIFICATE-----\n"
- "MIICVjCCAb8CAg37MA0GCSqGSIb3DQEBBQUAMIGbMQswCQYDVQQGEwJKUDEOMAwG\n"
- "A1UECBMFVG9reW8xEDAOBgNVBAcTB0NodW8ta3UxETAPBgNVBAoTCEZyYW5rNERE\n"
- "MRgwFgYDVQQLEw9XZWJDZXJ0IFN1cHBvcnQxGDAWBgNVBAMTD0ZyYW5rNEREIFdl\n"
- "YiBDQTEjMCEGCSqGSIb3DQEJARYUc3VwcG9ydEBmcmFuazRkZC5jb20wHhcNMTIw\n"
- "ODIyMDUyNzIzWhcNMTcwODIxMDUyNzIzWjBKMQswCQYDVQQGEwJKUDEOMAwGA1UE\n"
- "CAwFVG9reW8xETAPBgNVBAoMCEZyYW5rNEREMRgwFgYDVQQDDA93d3cuZXhhbXBs\n"
- "ZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMYBBrx5PlP0WNI/ZdzD\n"
- "+6Pktmurn+F2kQYbtc7XQh8/LTBvCo+P6iZoLEmUA9e7EXLRxgU1CVqeAi7QcAn9\n"
- "MwBlc8ksFJHB0rtf9pmf8Oza9E0Bynlq/4/Kb1x+d+AyhL7oK9tQwB24uHOueHi1\n"
- "C/iVv8CSWKiYe6hzN1txYe8rAgMBAAEwDQYJKoZIhvcNAQEFBQADgYEAASPdjigJ\n"
- "kXCqKWpnZ/Oc75EUcMi6HztaW8abUMlYXPIgkV2F7YanHOB7K4f7OOLjiz8DTPFf\n"
- "jC9UeuErhaA/zzWi8ewMTFZW/WshOrm3fNvcMrMLKtH534JKvcdMg6qIdjTFINIr\n"
- "evnAhf0cwULaebn+lMs8Pdl7y37+sfluVok=\n"
- "-----END CERTIFICATE-----\n";
-#endif /* !defined(OPENSSL_OPAQUE) */
-
-static const char* validCertString = "-----BEGIN CERTIFICATE-----\n"
- "MIIDpTCCAY0CAg3+MA0GCSqGSIb3DQEBBQUAMF4xCzAJBgNVBAYTAlVTMREwDwYD\n"
- "VQQIDAhJbGxpbm9pczEQMA4GA1UEBwwHQ2hpY2FnbzEUMBIGA1UECgwLVG9yIFRl\n"
- "c3RpbmcxFDASBgNVBAMMC1RvciBUZXN0aW5nMB4XDTE1MDkwNjEzMzk1OVoXDTQz\n"
- "MDEyMjEzMzk1OVowVjELMAkGA1UEBhMCVVMxEDAOBgNVBAcMB0NoaWNhZ28xFDAS\n"
- "BgNVBAoMC1RvciBUZXN0aW5nMR8wHQYDVQQDDBZ0ZXN0aW5nLnRvcnByb2plY3Qu\n"
- "b3JnMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDoT6uyVVhWyOF3wkHjjYbd\n"
- "nKaykyRv4JVtKQdZ4OpEErmX1zw4MmyzpQNV6iR4bQnWiyLfzyVJMZDIC/WILBfX\n"
- "w2Pza/yuLgUvDc3twMuhOACzOQVO8PrEF/aVv2+hbCCy2udXvKhnYn+CCXl3ozc8\n"
- "XcKYvujTXDyvGWY3xwAjlQIDAQABMA0GCSqGSIb3DQEBBQUAA4ICAQCUvnhzQWuQ\n"
- "MrN+pERkE+zcTI/9dGS90rUMMLgu8VDNqTa0TUQh8uO0EQ6uDvI8Js6e8tgwS0BR\n"
- "UBahqb7ZHv+rejGCBr5OudqD+x4STiiuPNJVs86JTLN8SpM9CHjIBH5WCCN2KOy3\n"
- "mevNoRcRRyYJzSFULCunIK6FGulszigMYGscrO4oiTkZiHPh9KvWT40IMiHfL+Lw\n"
- "EtEWiLex6064LcA2YQ1AMuSZyCexks63lcfaFmQbkYOKqXa1oLkIRuDsOaSVjTfe\n"
- "vec+X6jvf12cFTKS5WIeqkKF2Irt+dJoiHEGTe5RscUMN/f+gqHPzfFz5dR23sxo\n"
- "g+HC6MZHlFkLAOx3wW6epPS8A/m1mw3zMPoTnb2U2YYt8T0dJMMlUn/7Y1sEAa+a\n"
- "dSTMaeUf6VnJ//11m454EZl1to9Z7oJOgqmFffSrdD4BGIWe8f7hhW6L1Enmqe/J\n"
- "BKL3wbzZh80O1W0bndAwhnEEhlzneFY84cbBo9pmVxpODHkUcStpr5Z7pBDrcL21\n"
- "Ss/aB/1YrsVXhdvJdOGxl3Mnl9dUY57CympLGlT8f0pPS6GAKOelECOhFMHmJd8L\n"
- "dj3XQSmKtYHevZ6IvuMXSlB/fJvSjSlkCuLo5+kJoaqPuRu+i/S1qxeRy3CBwmnE\n"
- "LdSNdcX4N79GQJ996PA8+mUCQG7YRtK+WA==\n"
- "-----END CERTIFICATE-----\n";
-
-static const char* caCertString = "-----BEGIN CERTIFICATE-----\n"
- "MIIFjzCCA3egAwIBAgIJAKd5WgyfPMYRMA0GCSqGSIb3DQEBCwUAMF4xCzAJBgNV\n"
- "BAYTAlVTMREwDwYDVQQIDAhJbGxpbm9pczEQMA4GA1UEBwwHQ2hpY2FnbzEUMBIG\n"
- "A1UECgwLVG9yIFRlc3RpbmcxFDASBgNVBAMMC1RvciBUZXN0aW5nMB4XDTE1MDkw\n"
- "NjEzMzc0MVoXDTQzMDEyMjEzMzc0MVowXjELMAkGA1UEBhMCVVMxETAPBgNVBAgM\n"
- "CElsbGlub2lzMRAwDgYDVQQHDAdDaGljYWdvMRQwEgYDVQQKDAtUb3IgVGVzdGlu\n"
- "ZzEUMBIGA1UEAwwLVG9yIFRlc3RpbmcwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw\n"
- "ggIKAoICAQCpLMUEiLW5leUgBZoEJms2V7lZRhIAjnJBhVMHD0e3UubNknmaQoxf\n"
- "ARz3rvqOaRd0JlV+qM9qE0DjiYcCVP1cAfqAo9d83uS1vwY3YMVJzADlaIiHfyVW\n"
- "uEgBy0vvkeUBqaua24dYlcwsemOiXYLu41yM1wkcGHW1AhBNHppY6cznb8TyLgNM\n"
- "2x3SGUdzc5XMyAFx51faKGBA3wjs+Hg1PLY7d30nmCgEOBavpm5I1disM/0k+Mcy\n"
- "YmAKEo/iHJX/rQzO4b9znP69juLlR8PDBUJEVIG/CYb6+uw8MjjUyiWXYoqfVmN2\n"
- "hm/lH8b6rXw1a2Aa3VTeD0DxaWeacMYHY/i01fd5n7hCoDTRNdSw5KJ0L3Z0SKTu\n"
- "0lzffKzDaIfyZGlpW5qdouACkWYzsaitQOePVE01PIdO30vUfzNTFDfy42ccx3Di\n"
- "59UCu+IXB+eMtrBfsok0Qc63vtF1linJgjHW1z/8ujk8F7/qkOfODhk4l7wngc2A\n"
- "EmwWFIFoGaiTEZHB9qteXr4unbXZ0AHpM02uGGwZEGohjFyebEb73M+J57WKKAFb\n"
- "PqbLcGUksL1SHNBNAJcVLttX55sO4nbidOS/kA3m+F1R04MBTyQF9qA6YDDHqdI3\n"
- "h/3pw0Z4fxVouTYT4/NfRnX4JTP4u+7Mpcoof28VME0qWqD1LnRhFQIDAQABo1Aw\n"
- "TjAdBgNVHQ4EFgQUMoAgIXH7pZ3QMRwTjT+DM9Yo/v0wHwYDVR0jBBgwFoAUMoAg\n"
- "IXH7pZ3QMRwTjT+DM9Yo/v0wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOC\n"
- "AgEAUJxacjXR9sT+Xs6ISFiUsyd0T6WVKMnV46xrYJHirGfx+krWHrjxMY+ZtxYD\n"
- "DBDGlo11Qc4v6QrclNf5QUBfIiGQsP9Cm6hHcQ+Tpg9HHCgSqG1YNPwCPReCR4br\n"
- "BLvLfrfkcBL2IWM0PdQdCze+59DBfipsULD2mEn9fjYRXQEwb2QWtQ9qRc20Yb/x\n"
- "Q4b/+CvUodLkaq7B8MHz0BV8HHcBoph6DYaRmO/N+hPauIuSp6XyaGYcEefGKVKj\n"
- "G2+fcsdyXsoijNdL8vNKwm4j2gVwCBnw16J00yfFoV46YcbfqEdJB2je0XSvwXqt\n"
- "14AOTngxso2h9k9HLtrfpO1ZG/B5AcCMs1lzbZ2fp5DPHtjvvmvA2RJqgo3yjw4W\n"
- "4DHAuTglYFlC3mDHNfNtcGP20JvepcQNzNP2UzwcpOc94hfKikOFw+gf9Vf1qd0y\n"
- "h/Sk6OZHn2+JVUPiWHIQV98Vtoh4RmUZDJD+b55ia3fQGTGzt4z1XFzQYSva5sfs\n"
- "wocS/papthqWldQU7x+3wofNd5CNU1x6WKXG/yw30IT/4F8ADJD6GeygNT8QJYvt\n"
- "u/8lAkbOy6B9xGmSvr0Kk1oq9P2NshA6kalxp1Oz/DTNDdL4AeBXV3JmM6WWCjGn\n"
- "Yy1RT69d0rwYc5u/vnqODz1IjvT90smsrkBumGt791FAFeg=\n"
- "-----END CERTIFICATE-----\n";
-
-static X509 *
-read_cert_from(const char *str)
-{
- BIO *bio = BIO_new(BIO_s_mem());
- BIO_write(bio, str, (int) strlen(str));
- X509 *res = PEM_read_bio_X509(bio, NULL, NULL, NULL);
- BIO_free(bio);
- return res;
-}
-
-#ifndef OPENSSL_OPAQUE
-static void
-test_tortls_verify(void *ignored)
-{
- (void)ignored;
- int ret;
- tor_tls_t *tls;
- crypto_pk_t *k = NULL;
- X509 *cert1 = NULL, *cert2 = NULL, *invalidCert = NULL,
- *validCert = NULL, *caCert = NULL;
-
- cert1 = tor_malloc_zero(sizeof(X509));
- cert1->references = 10;
-
- cert2 = tor_malloc_zero(sizeof(X509));
- cert2->references = 10;
-
- validCert = read_cert_from(validCertString);
- caCert = read_cert_from(caCertString);
- invalidCert = read_cert_from(notCompletelyValidCertString);
-
- tls = tor_malloc_zero(sizeof(tor_tls_t));
- ret = tor_tls_verify(LOG_WARN, tls, &k);
- tt_int_op(ret, OP_EQ, -1);
-
- MOCK(try_to_extract_certs_from_tls, fixed_try_to_extract_certs_from_tls);
-
- fixed_try_to_extract_certs_from_tls_cert_out_result = cert1;
- ret = tor_tls_verify(LOG_WARN, tls, &k);
- tt_int_op(ret, OP_EQ, -1);
-
- fixed_try_to_extract_certs_from_tls_id_cert_out_result = cert2;
- ret = tor_tls_verify(LOG_WARN, tls, &k);
- tt_int_op(ret, OP_EQ, -1);
-
- fixed_try_to_extract_certs_from_tls_cert_out_result = invalidCert;
- fixed_try_to_extract_certs_from_tls_id_cert_out_result = invalidCert;
-
- ret = tor_tls_verify(LOG_WARN, tls, &k);
- tt_int_op(ret, OP_EQ, -1);
-
- fixed_try_to_extract_certs_from_tls_cert_out_result = validCert;
- fixed_try_to_extract_certs_from_tls_id_cert_out_result = caCert;
-
- ret = tor_tls_verify(LOG_WARN, tls, &k);
- tt_int_op(ret, OP_EQ, 0);
- tt_assert(k);
-
- done:
- UNMOCK(try_to_extract_certs_from_tls);
- tor_free(cert1);
- tor_free(cert2);
- tor_free(tls);
- tor_free(k);
-}
-#endif /* !defined(OPENSSL_OPAQUE) */
-
-#ifndef OPENSSL_OPAQUE
-static void
-test_tortls_check_lifetime(void *ignored)
-{
- (void)ignored;
- int ret;
- tor_tls_t *tls;
- X509 *validCert = read_cert_from(validCertString);
- time_t now = time(NULL);
-
- tls = tor_malloc_zero(sizeof(tor_tls_t));
- ret = tor_tls_check_lifetime(LOG_WARN, tls, time(NULL), 0, 0);
- tt_int_op(ret, OP_EQ, -1);
-
- tls->ssl = tor_malloc_zero(sizeof(SSL));
- tls->ssl->session = tor_malloc_zero(sizeof(SSL_SESSION));
- tls->ssl->session->peer = validCert;
- ret = tor_tls_check_lifetime(LOG_WARN, tls, time(NULL), 0, 0);
- tt_int_op(ret, OP_EQ, 0);
-
- ASN1_STRING_free(validCert->cert_info->validity->notBefore);
- validCert->cert_info->validity->notBefore = ASN1_TIME_set(NULL, now-10);
- ASN1_STRING_free(validCert->cert_info->validity->notAfter);
- validCert->cert_info->validity->notAfter = ASN1_TIME_set(NULL, now+60);
-
- ret = tor_tls_check_lifetime(LOG_WARN, tls, time(NULL), 0, -1000);
- tt_int_op(ret, OP_EQ, -1);
-
- ret = tor_tls_check_lifetime(LOG_WARN, tls, time(NULL), -1000, 0);
- tt_int_op(ret, OP_EQ, -1);
-
- done:
- tor_free(tls->ssl->session);
- tor_free(tls->ssl);
- tor_free(tls);
- X509_free(validCert);
-}
-#endif /* !defined(OPENSSL_OPAQUE) */
-
-#ifndef OPENSSL_OPAQUE
-static int fixed_ssl_pending_result = 0;
-
-static int
-fixed_ssl_pending(const SSL *ignored)
-{
- (void)ignored;
- return fixed_ssl_pending_result;
-}
-
-static void
-test_tortls_get_pending_bytes(void *ignored)
-{
- (void)ignored;
- int ret;
- tor_tls_t *tls;
- SSL_METHOD *method;
-
- tls = tor_malloc_zero(sizeof(tor_tls_t));
- tls->ssl = tor_malloc_zero(sizeof(SSL));
- method = tor_malloc_zero(sizeof(SSL_METHOD));
- method->ssl_pending = fixed_ssl_pending;
- tls->ssl->method = method;
-
- fixed_ssl_pending_result = 42;
- ret = tor_tls_get_pending_bytes(tls);
- tt_int_op(ret, OP_EQ, 42);
-
- done:
- tor_free(method);
- tor_free(tls->ssl);
- tor_free(tls);
-}
-#endif /* !defined(OPENSSL_OPAQUE) */
-
+#ifdef ENABLE_OPENSSL
static void
test_tortls_get_forced_write_size(void *ignored)
{
@@ -1192,30 +293,6 @@ test_tortls_get_forced_write_size(void *ignored)
}
static void
-test_tortls_get_write_overhead_ratio(void *ignored)
-{
- (void)ignored;
- double ret;
-
- total_bytes_written_over_tls = 0;
- ret = tls_get_write_overhead_ratio();
- tt_double_op(fabs(ret - 1.0), OP_LT, 1E-12);
-
- total_bytes_written_by_tls = 10;
- total_bytes_written_over_tls = 1;
- ret = tls_get_write_overhead_ratio();
- tt_double_op(fabs(ret - 10.0), OP_LT, 1E-12);
-
- total_bytes_written_by_tls = 10;
- total_bytes_written_over_tls = 2;
- ret = tls_get_write_overhead_ratio();
- tt_double_op(fabs(ret - 5.0), OP_LT, 1E-12);
-
- done:
- (void)0;
-}
-
-static void
test_tortls_used_v1_handshake(void *ignored)
{
(void)ignored;
@@ -1237,23 +314,6 @@ test_tortls_used_v1_handshake(void *ignored)
}
static void
-test_tortls_get_num_server_handshakes(void *ignored)
-{
- (void)ignored;
- int ret;
- tor_tls_t *tls;
-
- tls = tor_malloc_zero(sizeof(tor_tls_t));
-
- tls->server_handshake_count = 3;
- ret = tor_tls_get_num_server_handshakes(tls);
- tt_int_op(ret, OP_EQ, 3);
-
- done:
- tor_free(tls);
-}
-
-static void
test_tortls_server_got_renegotiate(void *ignored)
{
(void)ignored;
@@ -1269,116 +329,7 @@ test_tortls_server_got_renegotiate(void *ignored)
done:
tor_free(tls);
}
-
-#ifndef OPENSSL_OPAQUE
-static void
-test_tortls_SSL_SESSION_get_master_key(void *ignored)
-{
- (void)ignored;
- size_t ret;
- tor_tls_t *tls;
- uint8_t *out;
- out = tor_malloc_zero(1);
- tls = tor_malloc_zero(sizeof(tor_tls_t));
- tls->ssl = tor_malloc_zero(sizeof(SSL));
- tls->ssl->session = tor_malloc_zero(sizeof(SSL_SESSION));
- tls->ssl->session->master_key_length = 1;
-
-#ifndef HAVE_SSL_SESSION_GET_MASTER_KEY
- tls->ssl->session->master_key[0] = 43;
- ret = SSL_SESSION_get_master_key(tls->ssl->session, out, 0);
- tt_int_op(ret, OP_EQ, 1);
- tt_int_op(out[0], OP_EQ, 0);
-
- ret = SSL_SESSION_get_master_key(tls->ssl->session, out, 1);
- tt_int_op(ret, OP_EQ, 1);
- tt_int_op(out[0], OP_EQ, 43);
-
- done:
-#endif /* !defined(HAVE_SSL_SESSION_GET_MASTER_KEY) */
- tor_free(tls->ssl->session);
- tor_free(tls->ssl);
- tor_free(tls);
- tor_free(out);
-}
-#endif /* !defined(OPENSSL_OPAQUE) */
-
-#ifndef OPENSSL_OPAQUE
-static void
-test_tortls_get_tlssecrets(void *ignored)
-{
- (void)ignored;
- int ret;
- uint8_t *secret_out = tor_malloc_zero(DIGEST256_LEN);
- tor_tls_t *tls;
- tls = tor_malloc_zero(sizeof(tor_tls_t));
- tls->ssl = tor_malloc_zero(sizeof(SSL));
- tls->ssl->session = tor_malloc_zero(sizeof(SSL_SESSION));
- tls->ssl->session->master_key_length = 1;
- tls->ssl->s3 = tor_malloc_zero(sizeof(SSL3_STATE));
-
- ret = tor_tls_get_tlssecrets(tls, secret_out);
- tt_int_op(ret, OP_EQ, 0);
-
- done:
- tor_free(secret_out);
- tor_free(tls->ssl->s3);
- tor_free(tls->ssl->session);
- tor_free(tls->ssl);
- tor_free(tls);
-}
-#endif /* !defined(OPENSSL_OPAQUE) */
-
-#ifndef OPENSSL_OPAQUE
-static void
-test_tortls_get_buffer_sizes(void *ignored)
-{
- (void)ignored;
- int ret;
- tor_tls_t *tls;
- size_t rbuf_c=-1, rbuf_b=-1, wbuf_c=-1, wbuf_b=-1;
-
- tls = tor_malloc_zero(sizeof(tor_tls_t));
- tls->ssl = tor_malloc_zero(sizeof(SSL));
- tls->ssl->s3 = tor_malloc_zero(sizeof(SSL3_STATE));
-
- tls->ssl->s3->rbuf.buf = NULL;
- tls->ssl->s3->rbuf.len = 1;
- tls->ssl->s3->rbuf.offset = 0;
- tls->ssl->s3->rbuf.left = 42;
-
- tls->ssl->s3->wbuf.buf = NULL;
- tls->ssl->s3->wbuf.len = 2;
- tls->ssl->s3->wbuf.offset = 0;
- tls->ssl->s3->wbuf.left = 43;
-
- ret = tor_tls_get_buffer_sizes(tls, &rbuf_c, &rbuf_b, &wbuf_c, &wbuf_b);
-#if OPENSSL_VERSION_NUMBER >= OPENSSL_V_SERIES(1,1,0)
- tt_int_op(ret, OP_EQ, -1);
-#else
- tt_int_op(ret, OP_EQ, 0);
- tt_int_op(rbuf_c, OP_EQ, 0);
- tt_int_op(wbuf_c, OP_EQ, 0);
- tt_int_op(rbuf_b, OP_EQ, 42);
- tt_int_op(wbuf_b, OP_EQ, 43);
-
- tls->ssl->s3->rbuf.buf = tor_malloc_zero(1);
- tls->ssl->s3->wbuf.buf = tor_malloc_zero(1);
- ret = tor_tls_get_buffer_sizes(tls, &rbuf_c, &rbuf_b, &wbuf_c, &wbuf_b);
- tt_int_op(ret, OP_EQ, 0);
- tt_int_op(rbuf_c, OP_EQ, 1);
- tt_int_op(wbuf_c, OP_EQ, 2);
-
-#endif /* OPENSSL_VERSION_NUMBER >= OPENSSL_V_SERIES(1,1,0) */
-
- done:
- tor_free(tls->ssl->s3->rbuf.buf);
- tor_free(tls->ssl->s3->wbuf.buf);
- tor_free(tls->ssl->s3);
- tor_free(tls->ssl);
- tor_free(tls);
-}
-#endif /* !defined(OPENSSL_OPAQUE) */
+#endif
static void
test_tortls_evaluate_ecgroup_for_tls(void *ignored)
@@ -1403,1441 +354,173 @@ test_tortls_evaluate_ecgroup_for_tls(void *ignored)
(void)0;
}
-#ifndef OPENSSL_OPAQUE
-typedef struct cert_pkey_st_local
-{
- X509 *x509;
- EVP_PKEY *privatekey;
- const EVP_MD *digest;
-} CERT_PKEY_local;
-
-typedef struct sess_cert_st_local
-{
- STACK_OF(X509) *cert_chain;
- int peer_cert_type;
- CERT_PKEY_local *peer_key;
- CERT_PKEY_local peer_pkeys[8];
- int references;
-} SESS_CERT_local;
-
-static void
-test_tortls_try_to_extract_certs_from_tls(void *ignored)
-{
- (void)ignored;
- tor_tls_t *tls;
- X509 *cert = NULL, *id_cert = NULL, *c1 = NULL, *c2 = NULL;
- SESS_CERT_local *sess = NULL;
-
- c1 = read_cert_from(validCertString);
- c2 = read_cert_from(caCertString);
-
- tls = tor_malloc_zero(sizeof(tor_tls_t));
- tls->ssl = tor_malloc_zero(sizeof(SSL));
- tls->ssl->session = tor_malloc_zero(sizeof(SSL_SESSION));
- sess = tor_malloc_zero(sizeof(SESS_CERT_local));
- tls->ssl->session->sess_cert = (void *)sess;
-
- try_to_extract_certs_from_tls(LOG_WARN, tls, &cert, &id_cert);
- tt_assert(!cert);
- tt_assert(!id_cert);
-
- tls->ssl->session->peer = c1;
- try_to_extract_certs_from_tls(LOG_WARN, tls, &cert, &id_cert);
- tt_assert(cert == c1);
- tt_assert(!id_cert);
- X509_free(cert); /* decrease refcnt */
-
- sess->cert_chain = sk_X509_new_null();
- try_to_extract_certs_from_tls(LOG_WARN, tls, &cert, &id_cert);
- tt_assert(cert == c1);
- tt_assert(!id_cert);
- X509_free(cert); /* decrease refcnt */
-
- sk_X509_push(sess->cert_chain, c1);
- sk_X509_push(sess->cert_chain, c2);
-
- try_to_extract_certs_from_tls(LOG_WARN, tls, &cert, &id_cert);
- tt_assert(cert == c1);
- tt_assert(id_cert);
- X509_free(cert); /* decrease refcnt */
-
- done:
- sk_X509_free(sess->cert_chain);
- tor_free(sess);
- tor_free(tls->ssl->session);
- tor_free(tls->ssl);
- tor_free(tls);
- X509_free(c1);
- X509_free(c2);
-}
-#endif /* !defined(OPENSSL_OPAQUE) */
-
-#ifndef OPENSSL_OPAQUE
-static void
-test_tortls_get_peer_cert(void *ignored)
-{
- (void)ignored;
- tor_x509_cert_t *ret;
- tor_tls_t *tls;
- X509 *cert = NULL;
-
- cert = read_cert_from(validCertString);
-
- tls = tor_malloc_zero(sizeof(tor_tls_t));
- tls->ssl = tor_malloc_zero(sizeof(SSL));
- tls->ssl->session = tor_malloc_zero(sizeof(SSL_SESSION));
-
- ret = tor_tls_get_peer_cert(tls);
- tt_assert(!ret);
-
- tls->ssl->session->peer = cert;
- ret = tor_tls_get_peer_cert(tls);
- tt_assert(ret);
- tt_assert(ret->cert == cert);
-
- done:
- tor_x509_cert_free(ret);
- tor_free(tls->ssl->session);
- tor_free(tls->ssl);
- tor_free(tls);
- X509_free(cert);
-}
-#endif /* !defined(OPENSSL_OPAQUE) */
-
-#ifndef OPENSSL_OPAQUE
-static void
-test_tortls_peer_has_cert(void *ignored)
-{
- (void)ignored;
- int ret;
- tor_tls_t *tls;
- X509 *cert = NULL;
-
- cert = read_cert_from(validCertString);
-
- tls = tor_malloc_zero(sizeof(tor_tls_t));
- tls->ssl = tor_malloc_zero(sizeof(SSL));
- tls->ssl->session = tor_malloc_zero(sizeof(SSL_SESSION));
-
- ret = tor_tls_peer_has_cert(tls);
- tt_assert(!ret);
-
- tls->ssl->session->peer = cert;
- ret = tor_tls_peer_has_cert(tls);
- tt_assert(ret);
-
- done:
- tor_free(tls->ssl->session);
- tor_free(tls->ssl);
- tor_free(tls);
- X509_free(cert);
-}
-#endif /* !defined(OPENSSL_OPAQUE) */
-
-static void
-test_tortls_is_server(void *ignored)
-{
- (void)ignored;
- tor_tls_t *tls;
- int ret;
-
- tls = tor_malloc_zero(sizeof(tor_tls_t));
- tls->isServer = 1;
- ret = tor_tls_is_server(tls);
- tt_int_op(ret, OP_EQ, 1);
-
- done:
- tor_free(tls);
-}
-
-#ifndef OPENSSL_OPAQUE
-static void
-test_tortls_session_secret_cb(void *ignored)
-{
- (void)ignored;
- tor_tls_t *tls;
- SSL_CTX *ctx;
- STACK_OF(SSL_CIPHER) *ciphers = NULL;
- SSL_CIPHER *one;
-
- library_init();
-
- tor_tls_allocate_tor_tls_object_ex_data_index();
-
- tls = tor_malloc_zero(sizeof(tor_tls_t));
-
- tls->magic = TOR_TLS_MAGIC;
-
- ctx = SSL_CTX_new(TLSv1_method());
- tls->ssl = SSL_new(ctx);
- SSL_set_ex_data(tls->ssl, tor_tls_object_ex_data_index, tls);
-
- SSL_set_session_secret_cb(tls->ssl, tor_tls_session_secret_cb, NULL);
-
- tor_tls_session_secret_cb(tls->ssl, NULL, NULL, NULL, NULL, NULL);
- tt_assert(!tls->ssl->tls_session_secret_cb);
-
- one = get_cipher_by_name("ECDHE-RSA-AES256-GCM-SHA384");
- one->id = 0x00ff;
- ciphers = sk_SSL_CIPHER_new_null();
- sk_SSL_CIPHER_push(ciphers, one);
-
- tls->client_cipher_list_type = 0;
- tor_tls_session_secret_cb(tls->ssl, NULL, NULL, ciphers, NULL, NULL);
- tt_assert(!tls->ssl->tls_session_secret_cb);
-
- done:
- sk_SSL_CIPHER_free(ciphers);
- SSL_free(tls->ssl);
- SSL_CTX_free(ctx);
- tor_free(tls);
-}
-#endif /* !defined(OPENSSL_OPAQUE) */
-
-#ifndef OPENSSL_OPAQUE
-/* TODO: It seems block_renegotiation and unblock_renegotiation and
- * using different blags. This might not be correct */
static void
-test_tortls_block_renegotiation(void *ignored)
+test_tortls_double_init(void *arg)
{
- (void)ignored;
- tor_tls_t *tls;
-
- tls = tor_malloc_zero(sizeof(tor_tls_t));
- tls->ssl = tor_malloc_zero(sizeof(SSL));
- tls->ssl->s3 = tor_malloc_zero(sizeof(SSL3_STATE));
-#ifndef SUPPORT_UNSAFE_RENEGOTIATION_FLAG
-#define SSL3_FLAGS_ALLOW_UNSAFE_LEGACY_RENEGOTIATION 0
-#endif
+ (void) arg;
+ /* If we call tor_tls_context_init() a second time, nothing should go
+ * wrong.
+ */
+ crypto_pk_t *pk1 = NULL, *pk2 = NULL;
+ pk1 = pk_generate(2);
+ pk2 = pk_generate(0);
- tls->ssl->s3->flags = SSL3_FLAGS_ALLOW_UNSAFE_LEGACY_RENEGOTIATION;
+ int r = tor_tls_context_init(TOR_TLS_CTX_IS_PUBLIC_SERVER,
+ pk1, pk2, 86400);
+ tt_int_op(r, OP_EQ, 0);
- tor_tls_block_renegotiation(tls);
-
-#ifndef OPENSSL_1_1_API
- tt_assert(!(tls->ssl->s3->flags &
- SSL3_FLAGS_ALLOW_UNSAFE_LEGACY_RENEGOTIATION));
-#endif
+ r = tor_tls_context_init(TOR_TLS_CTX_IS_PUBLIC_SERVER,
+ pk2, pk1, 86400);
+ tt_int_op(r, OP_EQ, 0);
+ /* For a public server context, these are the same */
+ tt_ptr_op(tor_tls_context_get(0), OP_EQ, tor_tls_context_get(1));
done:
- tor_free(tls->ssl->s3);
- tor_free(tls->ssl);
- tor_free(tls);
-}
-
-static void
-test_tortls_unblock_renegotiation(void *ignored)
-{
- (void)ignored;
- tor_tls_t *tls;
-
- tls = tor_malloc_zero(sizeof(tor_tls_t));
- tls->ssl = tor_malloc_zero(sizeof(SSL));
- tor_tls_unblock_renegotiation(tls);
-
- tt_uint_op(SSL_get_options(tls->ssl) &
- SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION, OP_EQ,
- SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION);
-
- done:
- tor_free(tls->ssl);
- tor_free(tls);
-}
-#endif /* !defined(OPENSSL_OPAQUE) */
-
-#ifndef OPENSSL_OPAQUE
-static void
-test_tortls_assert_renegotiation_unblocked(void *ignored)
-{
- (void)ignored;
- tor_tls_t *tls;
-
- tls = tor_malloc_zero(sizeof(tor_tls_t));
- tls->ssl = tor_malloc_zero(sizeof(SSL));
- tor_tls_unblock_renegotiation(tls);
- tor_tls_assert_renegotiation_unblocked(tls);
- /* No assertion here - this test will fail if tor_assert is turned on
- * and things are bad. */
-
- tor_free(tls->ssl);
- tor_free(tls);
-}
-#endif /* !defined(OPENSSL_OPAQUE) */
-
-static void
-test_tortls_set_logged_address(void *ignored)
-{
- (void)ignored;
- tor_tls_t *tls;
-
- tls = tor_malloc_zero(sizeof(tor_tls_t));
-
- tor_tls_set_logged_address(tls, "foo bar");
-
- tt_str_op(tls->address, OP_EQ, "foo bar");
-
- tor_tls_set_logged_address(tls, "foo bar 2");
- tt_str_op(tls->address, OP_EQ, "foo bar 2");
-
- done:
- tor_free(tls->address);
- tor_free(tls);
+ crypto_pk_free(pk1);
+ crypto_pk_free(pk2);
}
-#ifndef OPENSSL_OPAQUE
static void
-example_cb(tor_tls_t *t, void *arg)
+test_tortls_bridge_init(void *arg)
{
- (void)t;
(void)arg;
-}
-
-static void
-test_tortls_set_renegotiate_callback(void *ignored)
-{
- (void)ignored;
- tor_tls_t *tls;
- const char *arg = "hello";
-
- tls = tor_malloc_zero(sizeof(tor_tls_t));
- tls->ssl = tor_malloc_zero(sizeof(SSL));
-
- tor_tls_set_renegotiate_callback(tls, example_cb, (void*)arg);
- tt_assert(tls->negotiated_callback == example_cb);
- tt_assert(tls->callback_arg == arg);
- tt_assert(!tls->got_renegotiate);
-
- /* Assumes V2_HANDSHAKE_SERVER */
- tt_assert(tls->ssl->info_callback == tor_tls_server_info_callback);
-
- tor_tls_set_renegotiate_callback(tls, NULL, (void*)arg);
- tt_assert(tls->ssl->info_callback == tor_tls_debug_state_callback);
-
- done:
- tor_free(tls->ssl);
- tor_free(tls);
-}
-#endif /* !defined(OPENSSL_OPAQUE) */
-
-#ifndef OPENSSL_OPAQUE
-static SSL_CIPHER *fixed_cipher1 = NULL;
-static SSL_CIPHER *fixed_cipher2 = NULL;
-static const SSL_CIPHER *
-fake_get_cipher(unsigned ncipher)
-{
-
- switch (ncipher) {
- case 1:
- return fixed_cipher1;
- case 2:
- return fixed_cipher2;
- default:
- return NULL;
- }
-}
-#endif /* !defined(OPENSSL_OPAQUE) */
-
-#ifndef OPENSSL_OPAQUE
-static void
-test_tortls_find_cipher_by_id(void *ignored)
-{
- (void)ignored;
- int ret;
- SSL *ssl;
- SSL_CTX *ctx;
- const SSL_METHOD *m = TLSv1_method();
- SSL_METHOD *empty_method = tor_malloc_zero(sizeof(SSL_METHOD));
-
- fixed_cipher1 = tor_malloc_zero(sizeof(SSL_CIPHER));
- fixed_cipher2 = tor_malloc_zero(sizeof(SSL_CIPHER));
- fixed_cipher2->id = 0xC00A;
-
- library_init();
-
- ctx = SSL_CTX_new(m);
- ssl = SSL_new(ctx);
-
- ret = find_cipher_by_id(ssl, NULL, 0xC00A);
- tt_int_op(ret, OP_EQ, 1);
-
- ret = find_cipher_by_id(ssl, m, 0xC00A);
- tt_int_op(ret, OP_EQ, 1);
-
- ret = find_cipher_by_id(ssl, m, 0xFFFF);
- tt_int_op(ret, OP_EQ, 0);
-
- ret = find_cipher_by_id(ssl, empty_method, 0xC00A);
- tt_int_op(ret, OP_EQ, 1);
-
- ret = find_cipher_by_id(ssl, empty_method, 0xFFFF);
-#ifdef HAVE_SSL_CIPHER_FIND
- tt_int_op(ret, OP_EQ, 0);
-#else
- tt_int_op(ret, OP_EQ, 1);
-#endif
-
- empty_method->get_cipher = fake_get_cipher;
- ret = find_cipher_by_id(ssl, empty_method, 0xC00A);
- tt_int_op(ret, OP_EQ, 1);
-
- empty_method->get_cipher = m->get_cipher;
- empty_method->num_ciphers = m->num_ciphers;
- ret = find_cipher_by_id(ssl, empty_method, 0xC00A);
- tt_int_op(ret, OP_EQ, 1);
-
- empty_method->get_cipher = fake_get_cipher;
- empty_method->num_ciphers = m->num_ciphers;
- ret = find_cipher_by_id(ssl, empty_method, 0xC00A);
- tt_int_op(ret, OP_EQ, 1);
-
- empty_method->num_ciphers = fake_num_ciphers;
- ret = find_cipher_by_id(ssl, empty_method, 0xC00A);
-#ifdef HAVE_SSL_CIPHER_FIND
- tt_int_op(ret, OP_EQ, 1);
-#else
- tt_int_op(ret, OP_EQ, 0);
-#endif
-
- done:
- tor_free(empty_method);
- SSL_free(ssl);
- SSL_CTX_free(ctx);
- tor_free(fixed_cipher1);
-}
-#endif /* !defined(OPENSSL_OPAQUE) */
-
-#ifndef OPENSSL_OPAQUE
-static void
-test_tortls_debug_state_callback(void *ignored)
-{
- (void)ignored;
- SSL *ssl;
- char *buf = tor_malloc_zero(1000);
- int n;
-
- setup_capture_of_logs(LOG_DEBUG);
-
- ssl = tor_malloc_zero(sizeof(SSL));
-
- tor_tls_debug_state_callback(ssl, 32, 45);
-
- n = tor_snprintf(buf, 1000, "SSL %p is now in state unknown"
- " state [type=32,val=45].\n", ssl);
- /* tor's snprintf returns -1 on error */
- tt_int_op(n, OP_NE, -1);
- expect_log_msg(buf);
-
- done:
- teardown_capture_of_logs();
- tor_free(buf);
- tor_free(ssl);
-}
-#endif /* !defined(OPENSSL_OPAQUE) */
+ crypto_pk_t *pk1 = NULL, *pk2 = NULL;
+ pk1 = pk_generate(2);
+ pk2 = pk_generate(0);
-#ifndef OPENSSL_OPAQUE
-static void
-test_tortls_server_info_callback(void *ignored)
-{
- (void)ignored;
- tor_tls_t *tls;
- SSL_CTX *ctx;
- SSL *ssl;
-
- library_init();
-
- ctx = SSL_CTX_new(TLSv1_method());
- ssl = SSL_new(ctx);
-
- tor_tls_allocate_tor_tls_object_ex_data_index();
-
- tls = tor_malloc_zero(sizeof(tor_tls_t));
- tls->magic = TOR_TLS_MAGIC;
- tls->ssl = ssl;
-
- setup_full_capture_of_logs(LOG_WARN);
- SSL_set_state(ssl, SSL3_ST_SW_SRVR_HELLO_A);
- mock_clean_saved_logs();
- tor_tls_server_info_callback(ssl, SSL_CB_ACCEPT_LOOP, 0);
- expect_single_log_msg("Couldn't look up the tls for an SSL*. How odd!\n");
-
- SSL_set_state(ssl, SSL3_ST_SW_SRVR_HELLO_B);
- mock_clean_saved_logs();
- tor_tls_server_info_callback(ssl, SSL_CB_ACCEPT_LOOP, 0);
- expect_single_log_msg("Couldn't look up the tls for an SSL*. How odd!\n");
-
- SSL_set_state(ssl, 99);
- mock_clean_saved_logs();
- tor_tls_server_info_callback(ssl, SSL_CB_ACCEPT_LOOP, 0);
- expect_no_log_entry();
- teardown_capture_of_logs();
-
- SSL_set_ex_data(tls->ssl, tor_tls_object_ex_data_index, tls);
- SSL_set_state(ssl, SSL3_ST_SW_SRVR_HELLO_B);
- tls->negotiated_callback = 0;
- tls->server_handshake_count = 120;
- tor_tls_server_info_callback(ssl, SSL_CB_ACCEPT_LOOP, 0);
- tt_int_op(tls->server_handshake_count, OP_EQ, 121);
-
- tls->server_handshake_count = 127;
- tls->negotiated_callback = (void *)1;
- tor_tls_server_info_callback(ssl, SSL_CB_ACCEPT_LOOP, 0);
- tt_int_op(tls->server_handshake_count, OP_EQ, 127);
- tt_int_op(tls->got_renegotiate, OP_EQ, 1);
-
- tls->ssl->session = SSL_SESSION_new();
- tls->wasV2Handshake = 0;
- tor_tls_server_info_callback(ssl, SSL_CB_ACCEPT_LOOP, 0);
- tt_int_op(tls->wasV2Handshake, OP_EQ, 0);
+ /* If we pass in a server identity key but not the
+ TOR_TLS_CTX_IS_PUBLIC_SERVER flag, we should get a bridge-style
+ configuration, with two distinct contexts. */
+ int r = tor_tls_context_init(0 /* flags */, pk1, pk2, 86400);
+ tt_int_op(r, OP_EQ, 0);
+ tt_ptr_op(tor_tls_context_get(0), OP_NE, tor_tls_context_get(1));
done:
- teardown_capture_of_logs();
- SSL_free(ssl);
- SSL_CTX_free(ctx);
- tor_free(tls);
-}
-#endif /* !defined(OPENSSL_OPAQUE) */
-
-#ifndef OPENSSL_OPAQUE
-static int fixed_ssl_read_result_index;
-static int fixed_ssl_read_result[5];
-static int fixed_ssl_shutdown_result;
-
-static int
-fixed_ssl_read(SSL *s, void *buf, int len)
-{
- (void)s;
- (void)buf;
- (void)len;
- return fixed_ssl_read_result[fixed_ssl_read_result_index++];
-}
-
-static int
-fixed_ssl_shutdown(SSL *s)
-{
- (void)s;
- return fixed_ssl_shutdown_result;
-}
-
-#ifndef LIBRESSL_VERSION_NUMBER
-static int fixed_ssl_state_to_set;
-static tor_tls_t *fixed_tls;
-
-static int
-setting_version_ssl_shutdown(SSL *s)
-{
- s->version = SSL2_VERSION;
- return fixed_ssl_shutdown_result;
-}
-
-static int
-setting_version_and_state_ssl_shutdown(SSL *s)
-{
- fixed_tls->state = fixed_ssl_state_to_set;
- s->version = SSL2_VERSION;
- return fixed_ssl_shutdown_result;
-}
-#endif /* !defined(LIBRESSL_VERSION_NUMBER) */
-
-static int
-dummy_handshake_func(SSL *s)
-{
- (void)s;
- return 1;
-}
-
-static void
-test_tortls_shutdown(void *ignored)
-{
- (void)ignored;
- int ret;
- tor_tls_t *tls;
- SSL_METHOD *method = give_me_a_test_method();
- setup_capture_of_logs(LOG_WARN);
-
- tls = tor_malloc_zero(sizeof(tor_tls_t));
- tls->ssl = tor_malloc_zero(sizeof(SSL));
- tls->ssl->method = method;
- method->ssl_read = fixed_ssl_read;
- method->ssl_shutdown = fixed_ssl_shutdown;
-
- ret = tor_tls_shutdown(tls);
- tt_int_op(ret, OP_EQ, -9);
-
- tls->state = TOR_TLS_ST_SENTCLOSE;
- fixed_ssl_read_result_index = 0;
- fixed_ssl_read_result[0] = 10;
- fixed_ssl_read_result[1] = -1;
- ret = tor_tls_shutdown(tls);
- tt_int_op(ret, OP_EQ, -9);
-
-#ifndef LIBRESSL_VERSION_NUMBER
- tls->ssl->handshake_func = dummy_handshake_func;
-
- fixed_ssl_read_result_index = 0;
- fixed_ssl_read_result[0] = 10;
- fixed_ssl_read_result[1] = 42;
- fixed_ssl_read_result[2] = 0;
- fixed_ssl_shutdown_result = 1;
- ERR_clear_error();
- tls->ssl->version = SSL2_VERSION;
- ret = tor_tls_shutdown(tls);
- tt_int_op(ret, OP_EQ, TOR_TLS_DONE);
- tt_int_op(tls->state, OP_EQ, TOR_TLS_ST_CLOSED);
-
- fixed_ssl_read_result_index = 0;
- fixed_ssl_read_result[0] = 10;
- fixed_ssl_read_result[1] = 42;
- fixed_ssl_read_result[2] = 0;
- fixed_ssl_shutdown_result = 0;
- ERR_clear_error();
- tls->ssl->version = 0;
- ret = tor_tls_shutdown(tls);
- tt_int_op(ret, OP_EQ, TOR_TLS_DONE);
- tt_int_op(tls->state, OP_EQ, TOR_TLS_ST_CLOSED);
-
- fixed_ssl_read_result_index = 0;
- fixed_ssl_read_result[0] = 10;
- fixed_ssl_read_result[1] = 42;
- fixed_ssl_read_result[2] = 0;
- fixed_ssl_shutdown_result = 0;
- ERR_clear_error();
- tls->ssl->version = 0;
- method->ssl_shutdown = setting_version_ssl_shutdown;
- ret = tor_tls_shutdown(tls);
- tt_int_op(ret, OP_EQ, TOR_TLS_ERROR_MISC);
-
- fixed_ssl_read_result_index = 0;
- fixed_ssl_read_result[0] = 10;
- fixed_ssl_read_result[1] = 42;
- fixed_ssl_read_result[2] = 0;
- fixed_ssl_shutdown_result = 0;
- fixed_tls = tls;
- fixed_ssl_state_to_set = TOR_TLS_ST_GOTCLOSE;
- ERR_clear_error();
- tls->ssl->version = 0;
- method->ssl_shutdown = setting_version_and_state_ssl_shutdown;
- ret = tor_tls_shutdown(tls);
- tt_int_op(ret, OP_EQ, TOR_TLS_ERROR_MISC);
-
- fixed_ssl_read_result_index = 0;
- fixed_ssl_read_result[0] = 10;
- fixed_ssl_read_result[1] = 42;
- fixed_ssl_read_result[2] = 0;
- fixed_ssl_read_result[3] = -1;
- fixed_ssl_shutdown_result = 0;
- fixed_tls = tls;
- fixed_ssl_state_to_set = 0;
- ERR_clear_error();
- tls->ssl->version = 0;
- method->ssl_shutdown = setting_version_and_state_ssl_shutdown;
- ret = tor_tls_shutdown(tls);
- tt_int_op(ret, OP_EQ, TOR_TLS_ERROR_MISC);
-#endif /* !defined(LIBRESSL_VERSION_NUMBER) */
-
- done:
- teardown_capture_of_logs();
- tor_free(method);
- tor_free(tls->ssl);
- tor_free(tls);
+ crypto_pk_free(pk1);
+ crypto_pk_free(pk2);
}
-static int negotiated_callback_called;
-
static void
-negotiated_callback_setter(tor_tls_t *t, void *arg)
+test_tortls_address(void *arg)
{
- (void)t;
(void)arg;
- negotiated_callback_called++;
-}
-
-static void
-test_tortls_read(void *ignored)
-{
- (void)ignored;
- int ret;
- tor_tls_t *tls;
- char buf[100];
- SSL_METHOD *method = give_me_a_test_method();
- setup_capture_of_logs(LOG_WARN);
-
- tls = tor_malloc_zero(sizeof(tor_tls_t));
- tls->ssl = tor_malloc_zero(sizeof(SSL));
- tls->state = TOR_TLS_ST_OPEN;
-
- ret = tor_tls_read(tls, buf, 10);
- tt_int_op(ret, OP_EQ, -9);
-
- /* These tests assume that V2_HANDSHAKE_SERVER is set */
- tls->ssl->handshake_func = dummy_handshake_func;
- tls->ssl->method = method;
- method->ssl_read = fixed_ssl_read;
- fixed_ssl_read_result_index = 0;
- fixed_ssl_read_result[0] = 42;
- tls->state = TOR_TLS_ST_OPEN;
- ERR_clear_error();
- ret = tor_tls_read(tls, buf, 10);
- tt_int_op(ret, OP_EQ, 42);
-
- tls->state = TOR_TLS_ST_OPEN;
- tls->got_renegotiate = 1;
- fixed_ssl_read_result_index = 0;
- ERR_clear_error();
- ret = tor_tls_read(tls, buf, 10);
- tt_int_op(tls->got_renegotiate, OP_EQ, 0);
-
- tls->state = TOR_TLS_ST_OPEN;
- tls->got_renegotiate = 1;
- negotiated_callback_called = 0;
- tls->negotiated_callback = negotiated_callback_setter;
- fixed_ssl_read_result_index = 0;
- ERR_clear_error();
- ret = tor_tls_read(tls, buf, 10);
- tt_int_op(negotiated_callback_called, OP_EQ, 1);
-
-#ifndef LIBRESSL_VERSION_NUMBER
- fixed_ssl_read_result_index = 0;
- fixed_ssl_read_result[0] = 0;
- tls->ssl->version = SSL2_VERSION;
- ERR_clear_error();
- ret = tor_tls_read(tls, buf, 10);
- tt_int_op(ret, OP_EQ, TOR_TLS_CLOSE);
- tt_int_op(tls->state, OP_EQ, TOR_TLS_ST_CLOSED);
-#endif /* !defined(LIBRESSL_VERSION_NUMBER) */
- // TODO: fill up
-
- done:
- teardown_capture_of_logs();
- tor_free(tls->ssl);
- tor_free(tls);
- tor_free(method);
-}
-
-static int fixed_ssl_write_result;
-
-static int
-fixed_ssl_write(SSL *s, const void *buf, int len)
-{
- (void)s;
- (void)buf;
- (void)len;
- return fixed_ssl_write_result;
-}
+ tor_tls_t *tls = NULL;
+ crypto_pk_t *pk1=NULL, *pk2=NULL;
+ pk1 = pk_generate(2);
+ pk2 = pk_generate(0);
-static void
-test_tortls_write(void *ignored)
-{
- (void)ignored;
- int ret;
- tor_tls_t *tls;
- SSL_METHOD *method = give_me_a_test_method();
- char buf[100];
- setup_capture_of_logs(LOG_WARN);
+ int r = tor_tls_context_init(TOR_TLS_CTX_IS_PUBLIC_SERVER,
+ pk1, pk2, 86400);
+ tt_int_op(r, OP_EQ, 0);
- tls = tor_malloc_zero(sizeof(tor_tls_t));
- tls->ssl = tor_malloc_zero(sizeof(SSL));
+ tls = tor_tls_new(-1, 0);
tls->state = TOR_TLS_ST_OPEN;
+ tor_tls_set_logged_address(tls, "zombo.com");
- ret = tor_tls_write(tls, buf, 0);
- tt_int_op(ret, OP_EQ, 0);
-
- ret = tor_tls_write(tls, buf, 10);
- tt_int_op(ret, OP_EQ, -9);
-
- tls->ssl->method = method;
- tls->wantwrite_n = 1;
- ret = tor_tls_write(tls, buf, 10);
- tt_int_op(tls->wantwrite_n, OP_EQ, 0);
-
- method->ssl_write = fixed_ssl_write;
- tls->ssl->handshake_func = dummy_handshake_func;
- fixed_ssl_write_result = 1;
- ERR_clear_error();
- ret = tor_tls_write(tls, buf, 10);
- tt_int_op(ret, OP_EQ, 1);
-
- fixed_ssl_write_result = -1;
- ERR_clear_error();
- tls->ssl->rwstate = SSL_READING;
- SSL_set_bio(tls->ssl, BIO_new(BIO_s_mem()), NULL);
- SSL_get_rbio(tls->ssl)->flags = BIO_FLAGS_READ;
- ret = tor_tls_write(tls, buf, 10);
- tt_int_op(ret, OP_EQ, TOR_TLS_WANTREAD);
-
- ERR_clear_error();
- tls->ssl->rwstate = SSL_READING;
- SSL_set_bio(tls->ssl, BIO_new(BIO_s_mem()), NULL);
- SSL_get_rbio(tls->ssl)->flags = BIO_FLAGS_WRITE;
- ret = tor_tls_write(tls, buf, 10);
- tt_int_op(ret, OP_EQ, TOR_TLS_WANTWRITE);
-
- done:
- teardown_capture_of_logs();
- BIO_free(tls->ssl->rbio);
- tor_free(tls->ssl);
- tor_free(tls);
- tor_free(method);
-}
-#endif /* !defined(OPENSSL_OPAQUE) */
-
-#ifndef OPENSSL_OPAQUE
-static int fixed_ssl_accept_result;
-static int fixed_ssl_connect_result;
-
-static int
-setting_error_ssl_accept(SSL *ssl)
-{
- (void)ssl;
- ERR_put_error(ERR_LIB_BN, 2, -1, "somewhere.c", 99);
- ERR_put_error(ERR_LIB_SYS, 2, -1, "somewhere.c", 99);
- return fixed_ssl_accept_result;
-}
-
-static int
-setting_error_ssl_connect(SSL *ssl)
-{
- (void)ssl;
- ERR_put_error(ERR_LIB_BN, 2, -1, "somewhere.c", 99);
- ERR_put_error(ERR_LIB_SYS, 2, -1, "somewhere.c", 99);
- return fixed_ssl_connect_result;
-}
-
-static int
-fixed_ssl_accept(SSL *ssl)
-{
- (void) ssl;
- return fixed_ssl_accept_result;
-}
-
-static void
-test_tortls_handshake(void *ignored)
-{
- (void)ignored;
- int ret;
- tor_tls_t *tls;
- SSL_CTX *ctx;
- SSL_METHOD *method = give_me_a_test_method();
+ /* This write should fail, since the fd is -1. */
setup_capture_of_logs(LOG_INFO);
-
- SSL_library_init();
- SSL_load_error_strings();
-
- ctx = SSL_CTX_new(TLSv1_method());
-
- tls = tor_malloc_zero(sizeof(tor_tls_t));
- tls->ssl = SSL_new(ctx);
- tls->state = TOR_TLS_ST_HANDSHAKE;
-
- ret = tor_tls_handshake(tls);
- tt_int_op(ret, OP_EQ, -9);
-
- tls->isServer = 1;
- tls->state = TOR_TLS_ST_HANDSHAKE;
- ret = tor_tls_handshake(tls);
- tt_int_op(ret, OP_EQ, -9);
-
- tls->ssl->method = method;
- method->ssl_accept = fixed_ssl_accept;
- fixed_ssl_accept_result = 2;
- ERR_clear_error();
- tls->state = TOR_TLS_ST_HANDSHAKE;
- ret = tor_tls_handshake(tls);
- tt_int_op(tls->state, OP_EQ, TOR_TLS_ST_OPEN);
-
- method->ssl_accept = setting_error_ssl_accept;
- fixed_ssl_accept_result = 1;
- ERR_clear_error();
- mock_clean_saved_logs();
- tls->state = TOR_TLS_ST_HANDSHAKE;
- ret = tor_tls_handshake(tls);
- tt_int_op(ret, OP_EQ, TOR_TLS_ERROR_MISC);
- expect_log_entry();
- /* This fails on jessie. Investigate why! */
-#if 0
- expect_log_msg("TLS error while handshaking: (null) (in bignum routines:"
- "(null):SSLv3 write client hello B)\n");
- expect_log_msg("TLS error while handshaking: (null) (in system library:"
- "connect:SSLv3 write client hello B)\n");
-#endif /* 0 */
- expect_log_severity(LOG_INFO);
-
- tls->isServer = 0;
- method->ssl_connect = setting_error_ssl_connect;
- fixed_ssl_connect_result = 1;
- ERR_clear_error();
- mock_clean_saved_logs();
- tls->state = TOR_TLS_ST_HANDSHAKE;
- ret = tor_tls_handshake(tls);
- tt_int_op(ret, OP_EQ, TOR_TLS_ERROR_MISC);
- expect_log_entry();
-#if 0
- /* See above */
- expect_log_msg("TLS error while handshaking: "
- "(null) (in bignum routines:(null):SSLv3 write client hello B)\n");
- expect_log_msg("TLS error while handshaking: "
- "(null) (in system library:connect:SSLv3 write client hello B)\n");
-#endif /* 0 */
- expect_log_severity(LOG_WARN);
+ int n = tor_tls_write(tls, "welcome", 7);
+ tt_int_op(n, OP_LT, 0);
+ expect_log_msg_containing("with zombo.com");
done:
teardown_capture_of_logs();
- SSL_free(tls->ssl);
- SSL_CTX_free(ctx);
- tor_free(tls);
- tor_free(method);
-}
-#endif /* !defined(OPENSSL_OPAQUE) */
-
-#ifndef OPENSSL_OPAQUE
-static void
-test_tortls_finish_handshake(void *ignored)
-{
- (void)ignored;
- int ret;
- tor_tls_t *tls;
- SSL_CTX *ctx;
- SSL_METHOD *method = give_me_a_test_method();
- SSL_library_init();
- SSL_load_error_strings();
-
- X509 *c1 = read_cert_from(validCertString);
- SESS_CERT_local *sess = NULL;
-
- ctx = SSL_CTX_new(method);
-
- tls = tor_malloc_zero(sizeof(tor_tls_t));
- tls->ssl = SSL_new(ctx);
- tls->state = TOR_TLS_ST_OPEN;
-
- ret = tor_tls_finish_handshake(tls);
- tt_int_op(ret, OP_EQ, 0);
-
- tls->isServer = 1;
- tls->wasV2Handshake = 0;
- setup_full_capture_of_logs(LOG_WARN);
- ret = tor_tls_finish_handshake(tls);
- tt_int_op(ret, OP_EQ, 0);
- tt_int_op(tls->wasV2Handshake, OP_EQ, 1);
- expect_single_log_msg_containing("For some reason, wasV2Handshake didn't "
- "get set.");
- teardown_capture_of_logs();
-
- tls->wasV2Handshake = 1;
- ret = tor_tls_finish_handshake(tls);
- tt_int_op(ret, OP_EQ, 0);
- tt_int_op(tls->wasV2Handshake, OP_EQ, 1);
-
- tls->wasV2Handshake = 1;
- tls->ssl->session = SSL_SESSION_new();
- ret = tor_tls_finish_handshake(tls);
- tt_int_op(ret, OP_EQ, 0);
- tt_int_op(tls->wasV2Handshake, OP_EQ, 0);
-
- tls->isServer = 0;
-
- sess = tor_malloc_zero(sizeof(SESS_CERT_local));
- tls->ssl->session->sess_cert = (void *)sess;
- sess->cert_chain = sk_X509_new_null();
- sk_X509_push(sess->cert_chain, c1);
- tls->ssl->session->peer = c1;
- tls->wasV2Handshake = 0;
- ret = tor_tls_finish_handshake(tls);
- tt_int_op(ret, OP_EQ, 0);
- tt_int_op(tls->wasV2Handshake, OP_EQ, 1);
-
- method->num_ciphers = fake_num_ciphers;
- ret = tor_tls_finish_handshake(tls);
- tt_int_op(ret, OP_EQ, -9);
-
- done:
- if (sess)
- sk_X509_free(sess->cert_chain);
- if (tls->ssl && tls->ssl->session) {
- tor_free(tls->ssl->session->sess_cert);
- }
- SSL_free(tls->ssl);
- tor_free(tls);
- SSL_CTX_free(ctx);
- tor_free(method);
- teardown_capture_of_logs();
-}
-#endif /* !defined(OPENSSL_OPAQUE) */
-
-static int fixed_crypto_pk_new_result_index;
-static crypto_pk_t *fixed_crypto_pk_new_result[5];
-
-static crypto_pk_t *
-fixed_crypto_pk_new(void)
-{
- return fixed_crypto_pk_new_result[fixed_crypto_pk_new_result_index++];
-}
-
-#ifndef OPENSSL_OPAQUE
-static int fixed_crypto_pk_generate_key_with_bits_result_index;
-static int fixed_crypto_pk_generate_key_with_bits_result[5];
-static int fixed_tor_tls_create_certificate_result_index;
-static X509 *fixed_tor_tls_create_certificate_result[5];
-static int fixed_tor_x509_cert_new_result_index;
-static tor_x509_cert_t *fixed_tor_x509_cert_new_result[5];
-
-static int
-fixed_crypto_pk_generate_key_with_bits(crypto_pk_t *env, int bits)
-{
- (void)env;
- (void)bits;
- return fixed_crypto_pk_generate_key_with_bits_result[
- fixed_crypto_pk_generate_key_with_bits_result_index++];
-}
-
-static X509 *
-fixed_tor_tls_create_certificate(crypto_pk_t *rsa,
- crypto_pk_t *rsa_sign,
- const char *cname,
- const char *cname_sign,
- unsigned int cert_lifetime)
-{
- (void)rsa;
- (void)rsa_sign;
- (void)cname;
- (void)cname_sign;
- (void)cert_lifetime;
- return fixed_tor_tls_create_certificate_result[
- fixed_tor_tls_create_certificate_result_index++];
-}
-
-static tor_x509_cert_t *
-fixed_tor_x509_cert_new(X509 *x509_cert)
-{
- (void) x509_cert;
- return fixed_tor_x509_cert_new_result[
- fixed_tor_x509_cert_new_result_index++];
+ tor_tls_free(tls);
+ crypto_pk_free(pk1);
+ crypto_pk_free(pk2);
}
static void
-test_tortls_context_new(void *ignored)
+test_tortls_is_server(void *arg)
{
- (void)ignored;
- tor_tls_context_t *ret;
- crypto_pk_t *pk1, *pk2, *pk3, *pk4, *pk5, *pk6, *pk7, *pk8, *pk9, *pk10,
- *pk11, *pk12, *pk13, *pk14, *pk15, *pk16, *pk17, *pk18;
-
- pk1 = crypto_pk_new();
- pk2 = crypto_pk_new();
- pk3 = crypto_pk_new();
- pk4 = crypto_pk_new();
- pk5 = crypto_pk_new();
- pk6 = crypto_pk_new();
- pk7 = crypto_pk_new();
- pk8 = crypto_pk_new();
- pk9 = crypto_pk_new();
- pk10 = crypto_pk_new();
- pk11 = crypto_pk_new();
- pk12 = crypto_pk_new();
- pk13 = crypto_pk_new();
- pk14 = crypto_pk_new();
- pk15 = crypto_pk_new();
- pk16 = crypto_pk_new();
- pk17 = crypto_pk_new();
- pk18 = crypto_pk_new();
-
- fixed_crypto_pk_new_result_index = 0;
- fixed_crypto_pk_new_result[0] = NULL;
- MOCK(crypto_pk_new, fixed_crypto_pk_new);
- ret = tor_tls_context_new(NULL, 0, 0, 0);
- tt_assert(!ret);
-
- /* note: we already override this in testing_common.c, so we
- * run this unit test in a subprocess. */
- MOCK(crypto_pk_generate_key_with_bits,
- fixed_crypto_pk_generate_key_with_bits);
- fixed_crypto_pk_new_result_index = 0;
- fixed_crypto_pk_new_result[0] = pk1;
- fixed_crypto_pk_new_result[1] = NULL;
- fixed_crypto_pk_generate_key_with_bits_result[0] = -1;
- fixed_crypto_pk_generate_key_with_bits_result_index = 0;
- ret = tor_tls_context_new(NULL, 0, 0, 0);
- tt_assert(!ret);
-
- fixed_crypto_pk_new_result_index = 0;
- fixed_crypto_pk_new_result[0] = pk2;
- fixed_crypto_pk_new_result[1] = NULL;
- fixed_crypto_pk_generate_key_with_bits_result[0] = 0;
- fixed_crypto_pk_generate_key_with_bits_result_index = 0;
- ret = tor_tls_context_new(NULL, 0, 0, 0);
- tt_assert(!ret);
-
- fixed_crypto_pk_new_result_index = 0;
- fixed_crypto_pk_new_result[0] = pk3;
- fixed_crypto_pk_new_result[1] = pk4;
- fixed_crypto_pk_new_result[2] = NULL;
- fixed_crypto_pk_generate_key_with_bits_result[0] = 0;
- fixed_crypto_pk_generate_key_with_bits_result[1] = -1;
- fixed_crypto_pk_generate_key_with_bits_result_index = 0;
- ret = tor_tls_context_new(NULL, 0, 0, 0);
- tt_assert(!ret);
-
- MOCK(tor_tls_create_certificate, fixed_tor_tls_create_certificate);
-
- fixed_crypto_pk_new_result_index = 0;
- fixed_crypto_pk_new_result[0] = pk5;
- fixed_crypto_pk_new_result[1] = pk6;
- fixed_crypto_pk_new_result[2] = NULL;
- fixed_crypto_pk_generate_key_with_bits_result_index = 0;
- fixed_crypto_pk_generate_key_with_bits_result[1] = 0;
- fixed_tor_tls_create_certificate_result_index = 0;
- fixed_tor_tls_create_certificate_result[0] = NULL;
- fixed_tor_tls_create_certificate_result[1] = X509_new();
- fixed_tor_tls_create_certificate_result[2] = X509_new();
- ret = tor_tls_context_new(NULL, 0, 0, 0);
- tt_assert(!ret);
-
- fixed_crypto_pk_new_result_index = 0;
- fixed_crypto_pk_new_result[0] = pk7;
- fixed_crypto_pk_new_result[1] = pk8;
- fixed_crypto_pk_new_result[2] = NULL;
- fixed_crypto_pk_generate_key_with_bits_result_index = 0;
- fixed_tor_tls_create_certificate_result_index = 0;
- fixed_tor_tls_create_certificate_result[0] = X509_new();
- fixed_tor_tls_create_certificate_result[1] = NULL;
- fixed_tor_tls_create_certificate_result[2] = X509_new();
- ret = tor_tls_context_new(NULL, 0, 0, 0);
- tt_assert(!ret);
-
- fixed_crypto_pk_new_result_index = 0;
- fixed_crypto_pk_new_result[0] = pk9;
- fixed_crypto_pk_new_result[1] = pk10;
- fixed_crypto_pk_new_result[2] = NULL;
- fixed_crypto_pk_generate_key_with_bits_result_index = 0;
- fixed_tor_tls_create_certificate_result_index = 0;
- fixed_tor_tls_create_certificate_result[0] = X509_new();
- fixed_tor_tls_create_certificate_result[1] = X509_new();
- fixed_tor_tls_create_certificate_result[2] = NULL;
- ret = tor_tls_context_new(NULL, 0, 0, 0);
- tt_assert(!ret);
-
- MOCK(tor_x509_cert_new, fixed_tor_x509_cert_new);
- fixed_crypto_pk_new_result_index = 0;
- fixed_crypto_pk_new_result[0] = pk11;
- fixed_crypto_pk_new_result[1] = pk12;
- fixed_crypto_pk_new_result[2] = NULL;
- fixed_crypto_pk_generate_key_with_bits_result_index = 0;
- fixed_tor_tls_create_certificate_result_index = 0;
- fixed_tor_tls_create_certificate_result[0] = X509_new();
- fixed_tor_tls_create_certificate_result[1] = X509_new();
- fixed_tor_tls_create_certificate_result[2] = X509_new();
- fixed_tor_x509_cert_new_result_index = 0;
- fixed_tor_x509_cert_new_result[0] = NULL;
- fixed_tor_x509_cert_new_result[1] = NULL;
- fixed_tor_x509_cert_new_result[2] = NULL;
- ret = tor_tls_context_new(NULL, 0, 0, 0);
- tt_assert(!ret);
-
- fixed_crypto_pk_new_result_index = 0;
- fixed_crypto_pk_new_result[0] = pk13;
- fixed_crypto_pk_new_result[1] = pk14;
- fixed_crypto_pk_new_result[2] = NULL;
- fixed_crypto_pk_generate_key_with_bits_result_index = 0;
- fixed_tor_tls_create_certificate_result_index = 0;
- fixed_tor_tls_create_certificate_result[0] = X509_new();
- fixed_tor_tls_create_certificate_result[1] = X509_new();
- fixed_tor_tls_create_certificate_result[2] = X509_new();
- fixed_tor_x509_cert_new_result_index = 0;
- fixed_tor_x509_cert_new_result[0] = tor_malloc_zero(sizeof(tor_x509_cert_t));
- fixed_tor_x509_cert_new_result[1] = NULL;
- fixed_tor_x509_cert_new_result[2] = NULL;
- ret = tor_tls_context_new(NULL, 0, 0, 0);
- tt_assert(!ret);
-
- fixed_crypto_pk_new_result_index = 0;
- fixed_crypto_pk_new_result[0] = pk15;
- fixed_crypto_pk_new_result[1] = pk16;
- fixed_crypto_pk_new_result[2] = NULL;
- fixed_crypto_pk_generate_key_with_bits_result_index = 0;
- fixed_tor_tls_create_certificate_result_index = 0;
- fixed_tor_tls_create_certificate_result[0] = X509_new();
- fixed_tor_tls_create_certificate_result[1] = X509_new();
- fixed_tor_tls_create_certificate_result[2] = X509_new();
- fixed_tor_x509_cert_new_result_index = 0;
- fixed_tor_x509_cert_new_result[0] = tor_malloc_zero(sizeof(tor_x509_cert_t));
- fixed_tor_x509_cert_new_result[1] = tor_malloc_zero(sizeof(tor_x509_cert_t));
- fixed_tor_x509_cert_new_result[2] = NULL;
- ret = tor_tls_context_new(NULL, 0, 0, 0);
- tt_assert(!ret);
-
- fixed_crypto_pk_new_result_index = 0;
- fixed_crypto_pk_new_result[0] = pk17;
- fixed_crypto_pk_new_result[1] = pk18;
- fixed_crypto_pk_new_result[2] = NULL;
- fixed_crypto_pk_generate_key_with_bits_result_index = 0;
- fixed_tor_tls_create_certificate_result_index = 0;
- fixed_tor_tls_create_certificate_result[0] = X509_new();
- fixed_tor_tls_create_certificate_result[1] = X509_new();
- fixed_tor_tls_create_certificate_result[2] = X509_new();
- fixed_tor_x509_cert_new_result_index = 0;
- fixed_tor_x509_cert_new_result[0] = tor_malloc_zero(sizeof(tor_x509_cert_t));
- fixed_tor_x509_cert_new_result[1] = tor_malloc_zero(sizeof(tor_x509_cert_t));
- fixed_tor_x509_cert_new_result[2] = tor_malloc_zero(sizeof(tor_x509_cert_t));
- ret = tor_tls_context_new(NULL, 0, 0, 0);
- tt_assert(!ret);
-
- done:
- UNMOCK(tor_x509_cert_new);
- UNMOCK(tor_tls_create_certificate);
- UNMOCK(crypto_pk_generate_key_with_bits);
- UNMOCK(crypto_pk_new);
-}
-#endif /* !defined(OPENSSL_OPAQUE) */
-
-static int fixed_crypto_pk_get_evp_pkey_result_index = 0;
-static EVP_PKEY *fixed_crypto_pk_get_evp_pkey_result[5];
+ (void)arg;
+ crypto_pk_t *pk1=NULL, *pk2=NULL;
+ tor_tls_t *tls1=NULL, *tls2=NULL;
+ pk1 = pk_generate(2);
+ pk2 = pk_generate(0);
-static EVP_PKEY *
-fixed_crypto_pk_get_evp_pkey_(crypto_pk_t *env, int private)
-{
- (void) env;
- (void) private;
- return fixed_crypto_pk_get_evp_pkey_result[
- fixed_crypto_pk_get_evp_pkey_result_index++];
-}
+ int r = tor_tls_context_init(TOR_TLS_CTX_IS_PUBLIC_SERVER,
+ pk1, pk2, 86400);
+ tt_int_op(r, OP_EQ, 0);
+ tls1 = tor_tls_new(-1, 0);
+ tls2 = tor_tls_new(-1, 1);
-static void
-test_tortls_create_certificate(void *ignored)
-{
- (void)ignored;
- X509 *ret;
- crypto_pk_t *pk1, *pk2;
-
- pk1 = crypto_pk_new();
- pk2 = crypto_pk_new();
-
- MOCK(crypto_pk_get_evp_pkey_, fixed_crypto_pk_get_evp_pkey_);
- fixed_crypto_pk_get_evp_pkey_result_index = 0;
- fixed_crypto_pk_get_evp_pkey_result[0] = NULL;
- ret = tor_tls_create_certificate(pk1, pk2, "hello", "hello2", 1);
- tt_assert(!ret);
-
- fixed_crypto_pk_get_evp_pkey_result_index = 0;
- fixed_crypto_pk_get_evp_pkey_result[0] = EVP_PKEY_new();
- fixed_crypto_pk_get_evp_pkey_result[1] = NULL;
- ret = tor_tls_create_certificate(pk1, pk2, "hello", "hello2", 1);
- tt_assert(!ret);
-
- fixed_crypto_pk_get_evp_pkey_result_index = 0;
- fixed_crypto_pk_get_evp_pkey_result[0] = EVP_PKEY_new();
- fixed_crypto_pk_get_evp_pkey_result[1] = EVP_PKEY_new();
- ret = tor_tls_create_certificate(pk1, pk2, "hello", "hello2", 1);
- tt_assert(!ret);
+ tt_assert(! tor_tls_is_server(tls1));
+ tt_assert(tor_tls_is_server(tls2));
done:
- UNMOCK(crypto_pk_get_evp_pkey_);
+ tor_tls_free(tls1);
+ tor_tls_free(tls2);
crypto_pk_free(pk1);
crypto_pk_free(pk2);
}
static void
-test_tortls_cert_new(void *ignored)
-{
- (void)ignored;
- tor_x509_cert_t *ret;
- X509 *cert = read_cert_from(validCertString);
-
- ret = tor_x509_cert_new(NULL);
- tt_assert(!ret);
-
- ret = tor_x509_cert_new(cert);
- tt_assert(ret);
- tor_x509_cert_free(ret);
- ret = NULL;
-
-#if 0
- cert = read_cert_from(validCertString);
- /* XXX this doesn't do what you think: it alters a copy of the pubkey. */
- X509_get_pubkey(cert)->type = EVP_PKEY_DSA;
- ret = tor_x509_cert_new(cert);
- tt_assert(ret);
-#endif /* 0 */
-
-#ifndef OPENSSL_OPAQUE
- cert = read_cert_from(validCertString);
- X509_CINF_free(cert->cert_info);
- cert->cert_info = NULL;
- ret = tor_x509_cert_new(cert);
- tt_assert(ret);
-#endif /* !defined(OPENSSL_OPAQUE) */
-
- done:
- tor_x509_cert_free(ret);
-}
-
-static void
-test_tortls_cert_is_valid(void *ignored)
+test_tortls_verify(void *ignored)
{
(void)ignored;
int ret;
- tor_x509_cert_t *cert = NULL, *scert = NULL;
+ tor_tls_t *tls;
+ crypto_pk_t *k = NULL;
+ tor_x509_cert_impl_t *cert1 = NULL, *cert2 = NULL, *invalidCert = NULL,
+ *validCert = NULL, *caCert = NULL;
- scert = tor_malloc_zero(sizeof(tor_x509_cert_t));
- ret = tor_tls_cert_is_valid(LOG_WARN, cert, scert, time(NULL), 0);
- tt_int_op(ret, OP_EQ, 0);
+ validCert = read_cert_from(validCertString);
+ caCert = read_cert_from(caCertString);
+ invalidCert = read_cert_from(notCompletelyValidCertString);
- cert = tor_malloc_zero(sizeof(tor_x509_cert_t));
- ret = tor_tls_cert_is_valid(LOG_WARN, cert, scert, time(NULL), 0);
- tt_int_op(ret, OP_EQ, 0);
- tor_free(scert);
- tor_free(cert);
+ tls = tor_malloc_zero(sizeof(tor_tls_t));
- cert = tor_x509_cert_new(read_cert_from(validCertString));
- scert = tor_x509_cert_new(read_cert_from(caCertString));
- ret = tor_tls_cert_is_valid(LOG_WARN, cert, scert, time(NULL), 0);
- tt_int_op(ret, OP_EQ, 1);
+ MOCK(try_to_extract_certs_from_tls, fixed_try_to_extract_certs_from_tls);
-#ifndef OPENSSL_OPAQUE
- tor_x509_cert_free(cert);
- tor_x509_cert_free(scert);
- cert = tor_x509_cert_new(read_cert_from(validCertString));
- scert = tor_x509_cert_new(read_cert_from(caCertString));
- ASN1_TIME_free(cert->cert->cert_info->validity->notAfter);
- cert->cert->cert_info->validity->notAfter =
- ASN1_TIME_set(NULL, time(NULL)-1000000);
- ret = tor_tls_cert_is_valid(LOG_WARN, cert, scert, time(NULL), 0);
- tt_int_op(ret, OP_EQ, 0);
+ fixed_try_to_extract_certs_from_tls_cert_out_result = cert1;
+ ret = tor_tls_verify(LOG_WARN, tls, &k);
+ tt_int_op(ret, OP_EQ, -1);
- tor_x509_cert_free(cert);
- tor_x509_cert_free(scert);
- cert = tor_x509_cert_new(read_cert_from(validCertString));
- scert = tor_x509_cert_new(read_cert_from(caCertString));
- X509_PUBKEY_free(cert->cert->cert_info->key);
- cert->cert->cert_info->key = NULL;
- ret = tor_tls_cert_is_valid(LOG_WARN, cert, scert, time(NULL), 1);
- tt_int_op(ret, OP_EQ, 0);
-#endif /* !defined(OPENSSL_OPAQUE) */
+ fixed_try_to_extract_certs_from_tls_id_cert_out_result = cert2;
+ ret = tor_tls_verify(LOG_WARN, tls, &k);
+ tt_int_op(ret, OP_EQ, -1);
-#if 0
- tor_x509_cert_free(cert);
- tor_x509_cert_free(scert);
- cert = tor_x509_cert_new(read_cert_from(validCertString));
- scert = tor_x509_cert_new(read_cert_from(caCertString));
- /* This doesn't actually change the key in the cert. XXXXXX */
- BN_one(EVP_PKEY_get1_RSA(X509_get_pubkey(cert->cert))->n);
- ret = tor_tls_cert_is_valid(LOG_WARN, cert, scert, time(NULL), 1);
- tt_int_op(ret, OP_EQ, 0);
+ fixed_try_to_extract_certs_from_tls_cert_out_result = invalidCert;
+ fixed_try_to_extract_certs_from_tls_id_cert_out_result = invalidCert;
- tor_x509_cert_free(cert);
- tor_x509_cert_free(scert);
- cert = tor_x509_cert_new(read_cert_from(validCertString));
- scert = tor_x509_cert_new(read_cert_from(caCertString));
- /* This doesn't actually change the key in the cert. XXXXXX */
- X509_get_pubkey(cert->cert)->type = EVP_PKEY_EC;
- ret = tor_tls_cert_is_valid(LOG_WARN, cert, scert, time(NULL), 1);
- tt_int_op(ret, OP_EQ, 0);
+ ret = tor_tls_verify(LOG_WARN, tls, &k);
+ tt_int_op(ret, OP_EQ, -1);
- tor_x509_cert_free(cert);
- tor_x509_cert_free(scert);
- cert = tor_x509_cert_new(read_cert_from(validCertString));
- scert = tor_x509_cert_new(read_cert_from(caCertString));
- /* This doesn't actually change the key in the cert. XXXXXX */
- X509_get_pubkey(cert->cert)->type = EVP_PKEY_EC;
- ret = tor_tls_cert_is_valid(LOG_WARN, cert, scert, time(NULL), 0);
- tt_int_op(ret, OP_EQ, 1);
+ fixed_try_to_extract_certs_from_tls_cert_out_result = validCert;
+ fixed_try_to_extract_certs_from_tls_id_cert_out_result = caCert;
- tor_x509_cert_free(cert);
- tor_x509_cert_free(scert);
- cert = tor_x509_cert_new(read_cert_from(validCertString));
- scert = tor_x509_cert_new(read_cert_from(caCertString));
- /* This doesn't actually change the key in the cert. XXXXXX */
- X509_get_pubkey(cert->cert)->type = EVP_PKEY_EC;
- X509_get_pubkey(cert->cert)->ameth = NULL;
- ret = tor_tls_cert_is_valid(LOG_WARN, cert, scert, time(NULL), 0);
+ ret = tor_tls_verify(LOG_WARN, tls, &k);
tt_int_op(ret, OP_EQ, 0);
-#endif /* 0 */
-
- done:
- tor_x509_cert_free(cert);
- tor_x509_cert_free(scert);
-}
-
-static void
-test_tortls_context_init_one(void *ignored)
-{
- (void)ignored;
- int ret;
- tor_tls_context_t *old = NULL;
-
- MOCK(crypto_pk_new, fixed_crypto_pk_new);
-
- fixed_crypto_pk_new_result_index = 0;
- fixed_crypto_pk_new_result[0] = NULL;
- ret = tor_tls_context_init_one(&old, NULL, 0, 0, 0);
- tt_int_op(ret, OP_EQ, -1);
+ tt_assert(k);
done:
- UNMOCK(crypto_pk_new);
+ UNMOCK(try_to_extract_certs_from_tls);
+ tor_x509_cert_impl_free(cert1);
+ tor_x509_cert_impl_free(cert2);
+ tor_free(tls);
+ crypto_pk_free(k);
}
-#define LOCAL_TEST_CASE(name, flags) \
+#define LOCAL_TEST_CASE(name, flags) \
{ #name, test_tortls_##name, (flags|TT_FORK), NULL, NULL }
-#ifdef OPENSSL_OPAQUE
-#define INTRUSIVE_TEST_CASE(name, flags) \
- { #name, NULL, TT_SKIP, NULL, NULL }
-#else
-#define INTRUSIVE_TEST_CASE(name, flags) LOCAL_TEST_CASE(name, flags)
-#endif /* defined(OPENSSL_OPAQUE) */
-
struct testcase_t tortls_tests[] = {
LOCAL_TEST_CASE(errno_to_tls_error, 0),
LOCAL_TEST_CASE(err_to_string, 0),
- LOCAL_TEST_CASE(tor_tls_new, TT_FORK),
- LOCAL_TEST_CASE(tor_tls_get_error, 0),
- LOCAL_TEST_CASE(get_state_description, TT_FORK),
- LOCAL_TEST_CASE(get_by_ssl, TT_FORK),
- LOCAL_TEST_CASE(allocate_tor_tls_object_ex_data_index, TT_FORK),
- LOCAL_TEST_CASE(log_one_error, TT_FORK),
- INTRUSIVE_TEST_CASE(get_error, TT_FORK),
- LOCAL_TEST_CASE(always_accept_verify_cb, 0),
- INTRUSIVE_TEST_CASE(x509_cert_free, 0),
LOCAL_TEST_CASE(x509_cert_get_id_digests, 0),
- LOCAL_TEST_CASE(cert_matches_key, 0),
- INTRUSIVE_TEST_CASE(cert_get_key, 0),
- LOCAL_TEST_CASE(get_my_client_auth_key, TT_FORK),
LOCAL_TEST_CASE(get_my_certs, TT_FORK),
- INTRUSIVE_TEST_CASE(get_ciphersuite_name, 0),
- INTRUSIVE_TEST_CASE(classify_client_ciphers, 0),
- LOCAL_TEST_CASE(client_is_using_v2_ciphers, 0),
- INTRUSIVE_TEST_CASE(verify, 0),
- INTRUSIVE_TEST_CASE(check_lifetime, 0),
- INTRUSIVE_TEST_CASE(get_pending_bytes, 0),
+#ifdef ENABLE_OPENSSL
+ LOCAL_TEST_CASE(tor_tls_get_error, 0),
LOCAL_TEST_CASE(get_forced_write_size, 0),
- LOCAL_TEST_CASE(get_write_overhead_ratio, TT_FORK),
LOCAL_TEST_CASE(used_v1_handshake, TT_FORK),
- LOCAL_TEST_CASE(get_num_server_handshakes, 0),
LOCAL_TEST_CASE(server_got_renegotiate, 0),
- INTRUSIVE_TEST_CASE(SSL_SESSION_get_master_key, 0),
- INTRUSIVE_TEST_CASE(get_tlssecrets, 0),
- INTRUSIVE_TEST_CASE(get_buffer_sizes, 0),
+#endif
LOCAL_TEST_CASE(evaluate_ecgroup_for_tls, 0),
- INTRUSIVE_TEST_CASE(try_to_extract_certs_from_tls, 0),
- INTRUSIVE_TEST_CASE(get_peer_cert, 0),
- INTRUSIVE_TEST_CASE(peer_has_cert, 0),
- INTRUSIVE_TEST_CASE(shutdown, 0),
- INTRUSIVE_TEST_CASE(finish_handshake, 0),
- INTRUSIVE_TEST_CASE(handshake, 0),
- INTRUSIVE_TEST_CASE(write, 0),
- INTRUSIVE_TEST_CASE(read, 0),
- INTRUSIVE_TEST_CASE(server_info_callback, 0),
+ LOCAL_TEST_CASE(double_init, TT_FORK),
+ LOCAL_TEST_CASE(address, TT_FORK),
LOCAL_TEST_CASE(is_server, 0),
- INTRUSIVE_TEST_CASE(assert_renegotiation_unblocked, 0),
- INTRUSIVE_TEST_CASE(block_renegotiation, 0),
- INTRUSIVE_TEST_CASE(unblock_renegotiation, 0),
- INTRUSIVE_TEST_CASE(set_renegotiate_callback, 0),
- LOCAL_TEST_CASE(set_logged_address, 0),
- INTRUSIVE_TEST_CASE(find_cipher_by_id, 0),
- INTRUSIVE_TEST_CASE(session_secret_cb, 0),
- INTRUSIVE_TEST_CASE(debug_state_callback, 0),
- INTRUSIVE_TEST_CASE(context_new, TT_FORK /* redundant */),
- LOCAL_TEST_CASE(create_certificate, 0),
- LOCAL_TEST_CASE(cert_new, 0),
- LOCAL_TEST_CASE(cert_is_valid, 0),
- LOCAL_TEST_CASE(context_init_one, 0),
+ LOCAL_TEST_CASE(bridge_init, TT_FORK),
+ LOCAL_TEST_CASE(verify, TT_FORK),
END_OF_TESTCASES
};
diff --git a/src/test/test_tortls.h b/src/test/test_tortls.h
new file mode 100644
index 0000000000..c997934ebc
--- /dev/null
+++ b/src/test/test_tortls.h
@@ -0,0 +1,13 @@
+/* Copyright (c) 2010-2018, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#ifndef TEST_TORTLS_H
+#define TEST_TORTLS_H
+
+tor_x509_cert_impl_t *read_cert_from(const char *str);
+
+extern const char *notCompletelyValidCertString;
+extern const char *validCertString;
+extern const char *caCertString;
+
+#endif
diff --git a/src/test/test_tortls_openssl.c b/src/test/test_tortls_openssl.c
new file mode 100644
index 0000000000..6086252882
--- /dev/null
+++ b/src/test/test_tortls_openssl.c
@@ -0,0 +1,2277 @@
+/* Copyright (c) 2010-2018, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#define TORTLS_PRIVATE
+#define TORTLS_OPENSSL_PRIVATE
+#define TOR_X509_PRIVATE
+#define LOG_PRIVATE
+#include "orconfig.h"
+
+#ifdef _WIN32
+#include <winsock2.h>
+#endif
+#include <math.h>
+
+#include "lib/cc/compat_compiler.h"
+
+/* Some versions of OpenSSL declare SSL_get_selected_srtp_profile twice in
+ * srtp.h. Suppress the GCC warning so we can build with -Wredundant-decl. */
+DISABLE_GCC_WARNING(redundant-decls)
+
+#include <openssl/opensslv.h>
+
+#include <openssl/ssl.h>
+#include <openssl/ssl3.h>
+#include <openssl/err.h>
+#include <openssl/asn1t.h>
+#include <openssl/x509.h>
+#include <openssl/rsa.h>
+#include <openssl/evp.h>
+#include <openssl/bn.h>
+
+ENABLE_GCC_WARNING(redundant-decls)
+
+#include "core/or/or.h"
+#include "lib/log/log.h"
+#include "app/config/config.h"
+#include "lib/crypt_ops/compat_openssl.h"
+#include "lib/tls/x509.h"
+#include "lib/tls/x509_internal.h"
+#include "lib/tls/tortls.h"
+#include "lib/tls/tortls_st.h"
+#include "lib/tls/tortls_internal.h"
+#include "app/config/or_state_st.h"
+
+#include "test/test.h"
+#include "test/log_test_helpers.h"
+#include "test/test_tortls.h"
+
+#define NS_MODULE tortls
+
+#ifndef HAVE_SSL_STATE
+#define OPENSSL_OPAQUE
+#endif
+
+#if defined(OPENSSL_OPAQUE) && !defined(LIBRESSL_VERSION_NUMBER)
+#define SSL_STATE_STR "before SSL initialization"
+#else
+#define SSL_STATE_STR "before/accept initialization"
+#endif
+
+#ifndef OPENSSL_OPAQUE
+static SSL_METHOD *
+give_me_a_test_method(void)
+{
+ SSL_METHOD *method = tor_malloc_zero(sizeof(SSL_METHOD));
+ memcpy(method, TLSv1_method(), sizeof(SSL_METHOD));
+ return method;
+}
+
+static int
+fake_num_ciphers(void)
+{
+ return 0;
+}
+#endif /* !defined(OPENSSL_OPAQUE) */
+
+static int
+mock_tls_cert_matches_key(const tor_tls_t *tls, const tor_x509_cert_t *cert)
+{
+ (void) tls;
+ (void) cert; // XXXX look at this.
+ return 1;
+}
+
+static void
+test_tortls_tor_tls_new(void *data)
+{
+ (void) data;
+ MOCK(tor_tls_cert_matches_key, mock_tls_cert_matches_key);
+ crypto_pk_t *key1 = NULL, *key2 = NULL;
+ SSL_METHOD *method = NULL;
+
+ key1 = pk_generate(2);
+ key2 = pk_generate(3);
+
+ tor_tls_t *tls = NULL;
+ tt_int_op(tor_tls_context_init(TOR_TLS_CTX_IS_PUBLIC_SERVER,
+ key1, key2, 86400), OP_EQ, 0);
+ tls = tor_tls_new(-1, 0);
+ tt_want(tls);
+ tor_tls_free(tls); tls = NULL;
+
+ SSL_CTX_free(client_tls_context->ctx);
+ client_tls_context->ctx = NULL;
+ tls = tor_tls_new(-1, 0);
+ tt_ptr_op(tls, OP_EQ, NULL);
+
+#ifndef OPENSSL_OPAQUE
+ method = give_me_a_test_method();
+ SSL_CTX *ctx = SSL_CTX_new(method);
+ method->num_ciphers = fake_num_ciphers;
+ client_tls_context->ctx = ctx;
+ tls = tor_tls_new(-1, 0);
+ tt_ptr_op(tls, OP_EQ, NULL);
+#endif /* !defined(OPENSSL_OPAQUE) */
+
+ done:
+ UNMOCK(tor_tls_cert_matches_key);
+ crypto_pk_free(key1);
+ crypto_pk_free(key2);
+ tor_tls_free(tls);
+ tor_free(method);
+ tor_tls_free_all();
+}
+
+#define NS_MODULE tortls
+
+static void
+library_init(void)
+{
+#ifdef OPENSSL_1_1_API
+ OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS, NULL);
+#else
+ SSL_library_init();
+ SSL_load_error_strings();
+#endif
+}
+
+static void
+test_tortls_get_state_description(void *ignored)
+{
+ (void)ignored;
+ tor_tls_t *tls;
+ char *buf;
+ SSL_CTX *ctx;
+
+ library_init();
+ ctx = SSL_CTX_new(SSLv23_method());
+
+ buf = tor_malloc_zero(1000);
+ tls = tor_malloc_zero(sizeof(tor_tls_t));
+
+ tor_tls_get_state_description(NULL, buf, 20);
+ tt_str_op(buf, OP_EQ, "(No SSL object)");
+
+ SSL_free(tls->ssl);
+ tls->ssl = NULL;
+ tor_tls_get_state_description(tls, buf, 20);
+ tt_str_op(buf, OP_EQ, "(No SSL object)");
+
+ tls->ssl = SSL_new(ctx);
+ tor_tls_get_state_description(tls, buf, 200);
+ tt_str_op(buf, OP_EQ, SSL_STATE_STR " in HANDSHAKE");
+
+ tls->state = TOR_TLS_ST_OPEN;
+ tor_tls_get_state_description(tls, buf, 200);
+ tt_str_op(buf, OP_EQ, SSL_STATE_STR " in OPEN");
+
+ tls->state = TOR_TLS_ST_GOTCLOSE;
+ tor_tls_get_state_description(tls, buf, 200);
+ tt_str_op(buf, OP_EQ, SSL_STATE_STR " in GOTCLOSE");
+
+ tls->state = TOR_TLS_ST_SENTCLOSE;
+ tor_tls_get_state_description(tls, buf, 200);
+ tt_str_op(buf, OP_EQ, SSL_STATE_STR " in SENTCLOSE");
+
+ tls->state = TOR_TLS_ST_CLOSED;
+ tor_tls_get_state_description(tls, buf, 200);
+ tt_str_op(buf, OP_EQ, SSL_STATE_STR " in CLOSED");
+
+ tls->state = TOR_TLS_ST_RENEGOTIATE;
+ tor_tls_get_state_description(tls, buf, 200);
+ tt_str_op(buf, OP_EQ, SSL_STATE_STR " in RENEGOTIATE");
+
+ tls->state = TOR_TLS_ST_BUFFEREVENT;
+ tor_tls_get_state_description(tls, buf, 200);
+ tt_str_op(buf, OP_EQ, SSL_STATE_STR);
+
+ tls->state = 7;
+ tor_tls_get_state_description(tls, buf, 200);
+ tt_str_op(buf, OP_EQ, SSL_STATE_STR " in unknown TLS state");
+
+ done:
+ SSL_CTX_free(ctx);
+ SSL_free(tls->ssl);
+ tor_free(buf);
+ tor_free(tls);
+}
+
+static void
+test_tortls_get_by_ssl(void *ignored)
+{
+ (void)ignored;
+ tor_tls_t *tls;
+ tor_tls_t *res;
+ SSL_CTX *ctx;
+ SSL *ssl;
+
+ library_init();
+ tor_tls_allocate_tor_tls_object_ex_data_index();
+
+ ctx = SSL_CTX_new(SSLv23_method());
+ tls = tor_malloc_zero(sizeof(tor_tls_t));
+ tls->magic = TOR_TLS_MAGIC;
+
+ ssl = SSL_new(ctx);
+
+ res = tor_tls_get_by_ssl(ssl);
+ tt_assert(!res);
+
+ SSL_set_ex_data(ssl, tor_tls_object_ex_data_index, tls);
+
+ res = tor_tls_get_by_ssl(ssl);
+ tt_assert(res == tls);
+
+ done:
+ SSL_free(ssl);
+ SSL_CTX_free(ctx);
+ tor_free(tls);
+}
+
+static void
+test_tortls_allocate_tor_tls_object_ex_data_index(void *ignored)
+{
+ (void)ignored;
+ int first;
+
+ tor_tls_allocate_tor_tls_object_ex_data_index();
+
+ first = tor_tls_object_ex_data_index;
+ tor_tls_allocate_tor_tls_object_ex_data_index();
+ tt_int_op(first, OP_EQ, tor_tls_object_ex_data_index);
+
+ done:
+ (void)0;
+}
+
+static void
+test_tortls_log_one_error(void *ignored)
+{
+ (void)ignored;
+ tor_tls_t *tls;
+ SSL_CTX *ctx;
+ SSL *ssl = NULL;
+
+ library_init();
+
+ ctx = SSL_CTX_new(SSLv23_method());
+ tls = tor_malloc_zero(sizeof(tor_tls_t));
+ setup_capture_of_logs(LOG_INFO);
+
+ tor_tls_log_one_error(NULL, 0, LOG_WARN, 0, "something");
+ expect_log_msg("TLS error while something: "
+ "(null) (in (null):(null):---)\n");
+
+ mock_clean_saved_logs();
+ tor_tls_log_one_error(tls, 0, LOG_WARN, 0, NULL);
+ expect_log_msg("TLS error: (null) "
+ "(in (null):(null):---)\n");
+
+ mock_clean_saved_logs();
+ tls->address = tor_strdup("127.hello");
+ tor_tls_log_one_error(tls, 0, LOG_WARN, 0, NULL);
+ expect_log_msg("TLS error with 127.hello: "
+ "(null) (in (null):(null):---)\n");
+ tor_free(tls->address);
+
+ mock_clean_saved_logs();
+ tls->address = tor_strdup("127.hello");
+ tor_tls_log_one_error(tls, 0, LOG_WARN, 0, "blarg");
+ expect_log_msg("TLS error while blarg with "
+ "127.hello: (null) (in (null):(null):---)\n");
+
+ mock_clean_saved_logs();
+ tor_tls_log_one_error(tls, ERR_PACK(1, 2, 3), LOG_WARN, 0, NULL);
+ expect_log_msg("TLS error with 127.hello: "
+ "BN lib (in unknown library:(null):---)\n");
+
+ mock_clean_saved_logs();
+ tor_tls_log_one_error(tls, ERR_PACK(1, 2, SSL_R_HTTP_REQUEST),
+ LOG_WARN, 0, NULL);
+ expect_log_severity(LOG_INFO);
+
+ mock_clean_saved_logs();
+ tor_tls_log_one_error(tls, ERR_PACK(1, 2, SSL_R_HTTPS_PROXY_REQUEST),
+ LOG_WARN, 0, NULL);
+ expect_log_severity(LOG_INFO);
+
+ mock_clean_saved_logs();
+ tor_tls_log_one_error(tls, ERR_PACK(1, 2, SSL_R_RECORD_LENGTH_MISMATCH),
+ LOG_WARN, 0, NULL);
+ expect_log_severity(LOG_INFO);
+
+#ifndef OPENSSL_1_1_API
+ mock_clean_saved_logs();
+ tor_tls_log_one_error(tls, ERR_PACK(1, 2, SSL_R_RECORD_TOO_LARGE),
+ LOG_WARN, 0, NULL);
+ expect_log_severity(LOG_INFO);
+#endif /* !defined(OPENSSL_1_1_API) */
+
+ mock_clean_saved_logs();
+ tor_tls_log_one_error(tls, ERR_PACK(1, 2, SSL_R_UNKNOWN_PROTOCOL),
+ LOG_WARN, 0, NULL);
+ expect_log_severity(LOG_INFO);
+
+ mock_clean_saved_logs();
+ tor_tls_log_one_error(tls, ERR_PACK(1, 2, SSL_R_UNSUPPORTED_PROTOCOL),
+ LOG_WARN, 0, NULL);
+ expect_log_severity(LOG_INFO);
+
+ tls->ssl = SSL_new(ctx);
+
+ mock_clean_saved_logs();
+ tor_tls_log_one_error(tls, 0, LOG_WARN, 0, NULL);
+ expect_log_msg("TLS error with 127.hello: (null)"
+ " (in (null):(null):" SSL_STATE_STR ")\n");
+
+ done:
+ teardown_capture_of_logs();
+ SSL_free(ssl);
+ SSL_CTX_free(ctx);
+ if (tls && tls->ssl)
+ SSL_free(tls->ssl);
+ if (tls)
+ tor_free(tls->address);
+ tor_free(tls);
+}
+
+#ifndef OPENSSL_OPAQUE
+static void
+test_tortls_get_error(void *ignored)
+{
+ (void)ignored;
+ tor_tls_t *tls;
+ int ret;
+ SSL_CTX *ctx;
+
+ library_init();
+
+ ctx = SSL_CTX_new(SSLv23_method());
+ setup_capture_of_logs(LOG_INFO);
+ tls = tor_malloc_zero(sizeof(tor_tls_t));
+ tls->ssl = SSL_new(ctx);
+ SSL_set_bio(tls->ssl, BIO_new(BIO_s_mem()), NULL);
+
+ ret = tor_tls_get_error(tls, 0, 0, "something", LOG_WARN, 0);
+ tt_int_op(ret, OP_EQ, TOR_TLS_ERROR_IO);
+ expect_log_msg("TLS error: unexpected close while"
+ " something (before/accept initialization)\n");
+
+ mock_clean_saved_logs();
+ ret = tor_tls_get_error(tls, 2, 0, "something", LOG_WARN, 0);
+ tt_int_op(ret, OP_EQ, 0);
+ expect_no_log_entry();
+
+ mock_clean_saved_logs();
+ ret = tor_tls_get_error(tls, 0, 1, "something", LOG_WARN, 0);
+ tt_int_op(ret, OP_EQ, -11);
+ expect_no_log_entry();
+
+ mock_clean_saved_logs();
+ ERR_clear_error();
+ ERR_put_error(ERR_LIB_BN, 2, -1, "somewhere.c", 99);
+ ret = tor_tls_get_error(tls, 0, 0, "something", LOG_WARN, 0);
+ tt_int_op(ret, OP_EQ, TOR_TLS_ERROR_MISC);
+ expect_log_msg("TLS error while something: (null)"
+ " (in bignum routines:(null):before/accept initialization)\n");
+
+ mock_clean_saved_logs();
+ ERR_clear_error();
+ tls->ssl->rwstate = SSL_READING;
+ SSL_get_rbio(tls->ssl)->flags = BIO_FLAGS_READ;
+ ret = tor_tls_get_error(tls, -1, 0, "something", LOG_WARN, 0);
+ tt_int_op(ret, OP_EQ, TOR_TLS_WANTREAD);
+ expect_no_log_entry();
+
+ mock_clean_saved_logs();
+ ERR_clear_error();
+ tls->ssl->rwstate = SSL_READING;
+ SSL_get_rbio(tls->ssl)->flags = BIO_FLAGS_WRITE;
+ ret = tor_tls_get_error(tls, -1, 0, "something", LOG_WARN, 0);
+ tt_int_op(ret, OP_EQ, TOR_TLS_WANTWRITE);
+ expect_no_log_entry();
+
+ mock_clean_saved_logs();
+ ERR_clear_error();
+ tls->ssl->rwstate = 0;
+ tls->ssl->shutdown = SSL_RECEIVED_SHUTDOWN;
+ tls->ssl->s3->warn_alert =SSL_AD_CLOSE_NOTIFY;
+ ret = tor_tls_get_error(tls, 0, 0, "something", LOG_WARN, 0);
+ tt_int_op(ret, OP_EQ, TOR_TLS_CLOSE);
+ expect_log_entry();
+
+ mock_clean_saved_logs();
+ ret = tor_tls_get_error(tls, 0, 2, "something", LOG_WARN, 0);
+ tt_int_op(ret, OP_EQ, -10);
+ expect_no_log_entry();
+
+ mock_clean_saved_logs();
+ ERR_put_error(ERR_LIB_SYS, 2, -1, "somewhere.c", 99);
+ ret = tor_tls_get_error(tls, -1, 0, "something", LOG_WARN, 0);
+ tt_int_op(ret, OP_EQ, -9);
+ expect_log_msg("TLS error while something: (null) (in system library:"
+ "connect:before/accept initialization)\n");
+
+ done:
+ teardown_capture_of_logs();
+ SSL_free(tls->ssl);
+ tor_free(tls);
+ SSL_CTX_free(ctx);
+}
+#endif /* !defined(OPENSSL_OPAQUE) */
+
+static void
+test_tortls_always_accept_verify_cb(void *ignored)
+{
+ (void)ignored;
+ int ret;
+
+ ret = always_accept_verify_cb(0, NULL);
+ tt_int_op(ret, OP_EQ, 1);
+
+ done:
+ (void)0;
+}
+
+#ifndef OPENSSL_OPAQUE
+static void
+test_tortls_x509_cert_free(void *ignored)
+{
+ (void)ignored;
+ tor_x509_cert_t *cert;
+
+ cert = tor_malloc_zero(sizeof(tor_x509_cert_t));
+ tor_x509_cert_free(cert);
+
+ cert = tor_malloc_zero(sizeof(tor_x509_cert_t));
+ cert->cert = X509_new();
+ cert->encoded = tor_malloc_zero(1);
+ tor_x509_cert_free(cert);
+}
+#endif /* !defined(OPENSSL_OPAQUE) */
+
+#ifndef OPENSSL_OPAQUE
+/*
+ * Use only for the matching fake_x509_free() call
+ */
+static X509 *
+fake_x509_malloc(void)
+{
+ return tor_malloc_zero(sizeof(X509));
+}
+
+static void
+fake_x509_free(X509 *cert)
+{
+ if (cert) {
+ if (cert->cert_info) {
+ if (cert->cert_info->key) {
+ if (cert->cert_info->key->pkey) {
+ tor_free(cert->cert_info->key->pkey);
+ }
+ tor_free(cert->cert_info->key);
+ }
+ tor_free(cert->cert_info);
+ }
+ tor_free(cert);
+ }
+}
+#endif
+
+static tor_x509_cert_t *fixed_x509_cert = NULL;
+static tor_x509_cert_t *
+get_peer_cert_mock_return_fixed(tor_tls_t *tls)
+{
+ (void)tls;
+ if (fixed_x509_cert)
+ return tor_x509_cert_dup(fixed_x509_cert);
+ else
+ return NULL;
+}
+
+static void
+test_tortls_cert_matches_key(void *ignored)
+{
+ (void)ignored;
+
+ X509 *cert1 = NULL, *cert2 = NULL, *cert3 = NULL, *cert4 = NULL;
+ tor_x509_cert_t *c1 = NULL, *c2 = NULL, *c3 = NULL, *c4 = NULL;
+ crypto_pk_t *k1 = NULL, *k2 = NULL, *k3 = NULL;
+
+ k1 = pk_generate(1);
+ k2 = pk_generate(2);
+ k3 = pk_generate(3);
+
+ cert1 = tor_tls_create_certificate(k1, k2, "A", "B", 1000);
+ cert2 = tor_tls_create_certificate(k1, k3, "C", "D", 1000);
+ cert3 = tor_tls_create_certificate(k2, k3, "C", "D", 1000);
+ cert4 = tor_tls_create_certificate(k3, k2, "E", "F", 1000);
+
+ tt_assert(cert1 && cert2 && cert3 && cert4);
+
+ c1 = tor_x509_cert_new(cert1); cert1 = NULL;
+ c2 = tor_x509_cert_new(cert2); cert2 = NULL;
+ c3 = tor_x509_cert_new(cert3); cert3 = NULL;
+ c4 = tor_x509_cert_new(cert4); cert4 = NULL;
+
+ tt_assert(c1 && c2 && c3 && c4);
+
+ MOCK(tor_tls_get_peer_cert, get_peer_cert_mock_return_fixed);
+
+ fixed_x509_cert = NULL;
+ /* If the peer has no certificate, it shouldn't match anything. */
+ tt_assert(! tor_tls_cert_matches_key(NULL, c1));
+ tt_assert(! tor_tls_cert_matches_key(NULL, c2));
+ tt_assert(! tor_tls_cert_matches_key(NULL, c3));
+ tt_assert(! tor_tls_cert_matches_key(NULL, c4));
+ fixed_x509_cert = c1;
+ /* If the peer has a certificate, it should match every cert with the same
+ * subject key. */
+ tt_assert(tor_tls_cert_matches_key(NULL, c1));
+ tt_assert(tor_tls_cert_matches_key(NULL, c2));
+ tt_assert(! tor_tls_cert_matches_key(NULL, c3));
+ tt_assert(! tor_tls_cert_matches_key(NULL, c4));
+
+ done:
+ tor_x509_cert_free(c1);
+ tor_x509_cert_free(c2);
+ tor_x509_cert_free(c3);
+ tor_x509_cert_free(c4);
+ if (cert1) X509_free(cert1);
+ if (cert2) X509_free(cert2);
+ if (cert3) X509_free(cert3);
+ if (cert4) X509_free(cert4);
+ crypto_pk_free(k1);
+ crypto_pk_free(k2);
+ crypto_pk_free(k3);
+ UNMOCK(tor_tls_get_peer_cert);
+}
+
+#ifndef OPENSSL_OPAQUE
+static void
+test_tortls_cert_get_key(void *ignored)
+{
+ (void)ignored;
+ tor_x509_cert_t *cert = NULL;
+ crypto_pk_t *res = NULL;
+ cert = tor_malloc_zero(sizeof(tor_x509_cert_t));
+ X509 *key = NULL;
+ key = fake_x509_malloc();
+ key->references = 1;
+
+ res = tor_tls_cert_get_key(cert);
+ tt_assert(!res);
+
+ cert->cert = key;
+ key->cert_info = tor_malloc_zero(sizeof(X509_CINF));
+ key->cert_info->key = tor_malloc_zero(sizeof(X509_PUBKEY));
+ key->cert_info->key->pkey = tor_malloc_zero(sizeof(EVP_PKEY));
+ key->cert_info->key->pkey->references = 1;
+ key->cert_info->key->pkey->type = 2;
+ res = tor_tls_cert_get_key(cert);
+ tt_assert(!res);
+
+ done:
+ fake_x509_free(key);
+ tor_free(cert);
+ crypto_pk_free(res);
+}
+#endif /* !defined(OPENSSL_OPAQUE) */
+
+static void
+test_tortls_get_my_client_auth_key(void *ignored)
+{
+ (void)ignored;
+ crypto_pk_t *ret;
+ crypto_pk_t *expected;
+ tor_tls_context_t *ctx;
+ RSA *k = RSA_new();
+
+ ctx = tor_malloc_zero(sizeof(tor_tls_context_t));
+ expected = crypto_new_pk_from_openssl_rsa_(k);
+ ctx->auth_key = expected;
+
+ client_tls_context = NULL;
+ ret = tor_tls_get_my_client_auth_key();
+ tt_assert(!ret);
+
+ client_tls_context = ctx;
+ ret = tor_tls_get_my_client_auth_key();
+ tt_assert(ret == expected);
+
+ done:
+ crypto_pk_free(expected);
+ tor_free(ctx);
+}
+
+#ifndef HAVE_SSL_GET_CLIENT_CIPHERS
+static SSL_CIPHER *
+get_cipher_by_name(const char *name)
+{
+ int i;
+ const SSL_METHOD *method = SSLv23_method();
+ int num = method->num_ciphers();
+
+ for (i = 0; i < num; ++i) {
+ const SSL_CIPHER *cipher = method->get_cipher(i);
+ const char *ciphername = SSL_CIPHER_get_name(cipher);
+ if (!strcmp(ciphername, name)) {
+ return (SSL_CIPHER *)cipher;
+ }
+ }
+
+ return NULL;
+}
+#endif /* !defined(HAVE_SSL_GET_CLIENT_CIPHERS) */
+
+#ifndef OPENSSL_OPAQUE
+static void
+test_tortls_get_ciphersuite_name(void *ignored)
+{
+ (void)ignored;
+ const char *ret;
+ tor_tls_t *ctx;
+ ctx = tor_malloc_zero(sizeof(tor_tls_t));
+ ctx->ssl = tor_malloc_zero(sizeof(SSL));
+
+ ret = tor_tls_get_ciphersuite_name(ctx);
+ tt_str_op(ret, OP_EQ, "(NONE)");
+
+ done:
+ tor_free(ctx->ssl);
+ tor_free(ctx);
+}
+
+static SSL_CIPHER *
+get_cipher_by_id(uint16_t id)
+{
+ int i;
+ const SSL_METHOD *method = SSLv23_method();
+ int num = method->num_ciphers();
+ for (i = 0; i < num; ++i) {
+ const SSL_CIPHER *cipher = method->get_cipher(i);
+ if (id == (SSL_CIPHER_get_id(cipher) & 0xffff)) {
+ return (SSL_CIPHER *)cipher;
+ }
+ }
+
+ return NULL;
+}
+
+static void
+test_tortls_classify_client_ciphers(void *ignored)
+{
+ (void)ignored;
+ int i;
+ int ret;
+ SSL_CTX *ctx;
+ SSL *ssl;
+ tor_tls_t *tls;
+ STACK_OF(SSL_CIPHER) *ciphers;
+ SSL_CIPHER *tmp_cipher;
+
+ library_init();
+
+ tor_tls_allocate_tor_tls_object_ex_data_index();
+
+ tls = tor_malloc_zero(sizeof(tor_tls_t));
+ tls->magic = TOR_TLS_MAGIC;
+
+ ctx = SSL_CTX_new(TLSv1_method());
+ ssl = SSL_new(ctx);
+ tls->ssl = ssl;
+
+ ciphers = sk_SSL_CIPHER_new_null();
+
+ ret = tor_tls_classify_client_ciphers(ssl, NULL);
+ tt_int_op(ret, OP_EQ, -1);
+
+ SSL_set_ex_data(ssl, tor_tls_object_ex_data_index, tls);
+ tls->client_cipher_list_type = 42;
+
+ ret = tor_tls_classify_client_ciphers(ssl, NULL);
+ tt_int_op(ret, OP_EQ, 42);
+
+ tls->client_cipher_list_type = 0;
+ ret = tor_tls_classify_client_ciphers(ssl, ciphers);
+ tt_int_op(ret, OP_EQ, 1);
+ tt_int_op(tls->client_cipher_list_type, OP_EQ, 1);
+
+ tls->client_cipher_list_type = 0;
+ ret = tor_tls_classify_client_ciphers(ssl, SSL_get_ciphers(ssl));
+ tt_int_op(ret, OP_EQ, 3);
+ tt_int_op(tls->client_cipher_list_type, OP_EQ, 3);
+
+ SSL_CIPHER *one = get_cipher_by_name(TLS1_TXT_DHE_RSA_WITH_AES_128_SHA),
+ *two = get_cipher_by_name(TLS1_TXT_DHE_RSA_WITH_AES_256_SHA),
+ *three = get_cipher_by_name(SSL3_TXT_EDH_RSA_DES_192_CBC3_SHA),
+ *four = NULL;
+ sk_SSL_CIPHER_push(ciphers, one);
+ sk_SSL_CIPHER_push(ciphers, two);
+ sk_SSL_CIPHER_push(ciphers, three);
+ sk_SSL_CIPHER_push(ciphers, four);
+
+ tls->client_cipher_list_type = 0;
+ ret = tor_tls_classify_client_ciphers(ssl, ciphers);
+ tt_int_op(ret, OP_EQ, 1);
+ tt_int_op(tls->client_cipher_list_type, OP_EQ, 1);
+
+ sk_SSL_CIPHER_zero(ciphers);
+
+ one = get_cipher_by_name("ECDHE-RSA-AES256-GCM-SHA384");
+ tt_assert(one);
+ one->id = 0x00ff;
+ two = get_cipher_by_name("ECDHE-RSA-AES128-GCM-SHA256");
+ tt_assert(two);
+ two->id = 0x0000;
+ sk_SSL_CIPHER_push(ciphers, one);
+ tls->client_cipher_list_type = 0;
+ ret = tor_tls_classify_client_ciphers(ssl, ciphers);
+ tt_int_op(ret, OP_EQ, 3);
+ tt_int_op(tls->client_cipher_list_type, OP_EQ, 3);
+
+ sk_SSL_CIPHER_push(ciphers, two);
+ tls->client_cipher_list_type = 0;
+ ret = tor_tls_classify_client_ciphers(ssl, ciphers);
+ tt_int_op(ret, OP_EQ, 3);
+ tt_int_op(tls->client_cipher_list_type, OP_EQ, 3);
+
+ one->id = 0xC00A;
+ tls->client_cipher_list_type = 0;
+ ret = tor_tls_classify_client_ciphers(ssl, ciphers);
+ tt_int_op(ret, OP_EQ, 3);
+ tt_int_op(tls->client_cipher_list_type, OP_EQ, 3);
+
+ sk_SSL_CIPHER_zero(ciphers);
+ for (i=0; v2_cipher_list[i]; i++) {
+ tmp_cipher = get_cipher_by_id(v2_cipher_list[i]);
+ tt_assert(tmp_cipher);
+ sk_SSL_CIPHER_push(ciphers, tmp_cipher);
+ }
+ tls->client_cipher_list_type = 0;
+ ret = tor_tls_classify_client_ciphers(ssl, ciphers);
+ tt_int_op(ret, OP_EQ, 2);
+ tt_int_op(tls->client_cipher_list_type, OP_EQ, 2);
+
+ done:
+ sk_SSL_CIPHER_free(ciphers);
+ SSL_free(tls->ssl);
+ tor_free(tls);
+ SSL_CTX_free(ctx);
+}
+#endif /* !defined(OPENSSL_OPAQUE) */
+
+static void
+test_tortls_client_is_using_v2_ciphers(void *ignored)
+{
+ (void)ignored;
+
+#ifdef HAVE_SSL_GET_CLIENT_CIPHERS
+ tt_skip();
+ done:
+ (void)1;
+#else
+ int ret;
+ SSL_CTX *ctx;
+ SSL *ssl;
+ SSL_SESSION *sess;
+ STACK_OF(SSL_CIPHER) *ciphers;
+
+ library_init();
+
+ ctx = SSL_CTX_new(TLSv1_method());
+ ssl = SSL_new(ctx);
+ sess = SSL_SESSION_new();
+
+ ret = tor_tls_client_is_using_v2_ciphers(ssl);
+ tt_int_op(ret, OP_EQ, -1);
+
+ ssl->session = sess;
+ ret = tor_tls_client_is_using_v2_ciphers(ssl);
+ tt_int_op(ret, OP_EQ, 0);
+
+ ciphers = sk_SSL_CIPHER_new_null();
+ SSL_CIPHER *one = get_cipher_by_name("ECDHE-RSA-AES256-GCM-SHA384");
+ tt_assert(one);
+ one->id = 0x00ff;
+ sk_SSL_CIPHER_push(ciphers, one);
+ sess->ciphers = ciphers;
+ ret = tor_tls_client_is_using_v2_ciphers(ssl);
+ tt_int_op(ret, OP_EQ, 1);
+ done:
+ SSL_free(ssl);
+ SSL_CTX_free(ctx);
+#endif /* defined(HAVE_SSL_GET_CLIENT_CIPHERS) */
+}
+
+#ifndef OPENSSL_OPAQUE
+static int fixed_ssl_pending_result = 0;
+
+static int
+fixed_ssl_pending(const SSL *ignored)
+{
+ (void)ignored;
+ return fixed_ssl_pending_result;
+}
+
+static void
+test_tortls_get_pending_bytes(void *ignored)
+{
+ (void)ignored;
+ int ret;
+ tor_tls_t *tls;
+ SSL_METHOD *method;
+
+ tls = tor_malloc_zero(sizeof(tor_tls_t));
+ tls->ssl = tor_malloc_zero(sizeof(SSL));
+ method = tor_malloc_zero(sizeof(SSL_METHOD));
+ method->ssl_pending = fixed_ssl_pending;
+ tls->ssl->method = method;
+
+ fixed_ssl_pending_result = 42;
+ ret = tor_tls_get_pending_bytes(tls);
+ tt_int_op(ret, OP_EQ, 42);
+
+ done:
+ tor_free(method);
+ tor_free(tls->ssl);
+ tor_free(tls);
+}
+#endif /* !defined(OPENSSL_OPAQUE) */
+
+#ifndef OPENSSL_OPAQUE
+static void
+test_tortls_SSL_SESSION_get_master_key(void *ignored)
+{
+ (void)ignored;
+ size_t ret;
+ tor_tls_t *tls;
+ uint8_t *out;
+ out = tor_malloc_zero(1);
+ tls = tor_malloc_zero(sizeof(tor_tls_t));
+ tls->ssl = tor_malloc_zero(sizeof(SSL));
+ tls->ssl->session = tor_malloc_zero(sizeof(SSL_SESSION));
+ tls->ssl->session->master_key_length = 1;
+
+#ifndef HAVE_SSL_SESSION_GET_MASTER_KEY
+ tls->ssl->session->master_key[0] = 43;
+ ret = SSL_SESSION_get_master_key(tls->ssl->session, out, 0);
+ tt_int_op(ret, OP_EQ, 1);
+ tt_int_op(out[0], OP_EQ, 0);
+
+ ret = SSL_SESSION_get_master_key(tls->ssl->session, out, 1);
+ tt_int_op(ret, OP_EQ, 1);
+ tt_int_op(out[0], OP_EQ, 43);
+
+ done:
+#endif /* !defined(HAVE_SSL_SESSION_GET_MASTER_KEY) */
+ tor_free(tls->ssl->session);
+ tor_free(tls->ssl);
+ tor_free(tls);
+ tor_free(out);
+}
+#endif /* !defined(OPENSSL_OPAQUE) */
+
+#ifndef OPENSSL_OPAQUE
+static void
+test_tortls_get_tlssecrets(void *ignored)
+{
+ (void)ignored;
+ int ret;
+ uint8_t *secret_out = tor_malloc_zero(DIGEST256_LEN);
+ tor_tls_t *tls;
+ tls = tor_malloc_zero(sizeof(tor_tls_t));
+ tls->ssl = tor_malloc_zero(sizeof(SSL));
+ tls->ssl->session = tor_malloc_zero(sizeof(SSL_SESSION));
+ tls->ssl->session->master_key_length = 1;
+ tls->ssl->s3 = tor_malloc_zero(sizeof(SSL3_STATE));
+
+ ret = tor_tls_get_tlssecrets(tls, secret_out);
+ tt_int_op(ret, OP_EQ, 0);
+
+ done:
+ tor_free(secret_out);
+ tor_free(tls->ssl->s3);
+ tor_free(tls->ssl->session);
+ tor_free(tls->ssl);
+ tor_free(tls);
+}
+#endif /* !defined(OPENSSL_OPAQUE) */
+
+#ifndef OPENSSL_OPAQUE
+static void
+test_tortls_get_buffer_sizes(void *ignored)
+{
+ (void)ignored;
+ int ret;
+ tor_tls_t *tls;
+ size_t rbuf_c=-1, rbuf_b=-1, wbuf_c=-1, wbuf_b=-1;
+
+ tls = tor_malloc_zero(sizeof(tor_tls_t));
+ tls->ssl = tor_malloc_zero(sizeof(SSL));
+ tls->ssl->s3 = tor_malloc_zero(sizeof(SSL3_STATE));
+
+ tls->ssl->s3->rbuf.buf = NULL;
+ tls->ssl->s3->rbuf.len = 1;
+ tls->ssl->s3->rbuf.offset = 0;
+ tls->ssl->s3->rbuf.left = 42;
+
+ tls->ssl->s3->wbuf.buf = NULL;
+ tls->ssl->s3->wbuf.len = 2;
+ tls->ssl->s3->wbuf.offset = 0;
+ tls->ssl->s3->wbuf.left = 43;
+
+ ret = tor_tls_get_buffer_sizes(tls, &rbuf_c, &rbuf_b, &wbuf_c, &wbuf_b);
+#if OPENSSL_VERSION_NUMBER >= OPENSSL_V_SERIES(1,1,0)
+ tt_int_op(ret, OP_EQ, -1);
+#else
+ tt_int_op(ret, OP_EQ, 0);
+ tt_int_op(rbuf_c, OP_EQ, 0);
+ tt_int_op(wbuf_c, OP_EQ, 0);
+ tt_int_op(rbuf_b, OP_EQ, 42);
+ tt_int_op(wbuf_b, OP_EQ, 43);
+
+ tls->ssl->s3->rbuf.buf = tor_malloc_zero(1);
+ tls->ssl->s3->wbuf.buf = tor_malloc_zero(1);
+ ret = tor_tls_get_buffer_sizes(tls, &rbuf_c, &rbuf_b, &wbuf_c, &wbuf_b);
+ tt_int_op(ret, OP_EQ, 0);
+ tt_int_op(rbuf_c, OP_EQ, 1);
+ tt_int_op(wbuf_c, OP_EQ, 2);
+
+#endif /* OPENSSL_VERSION_NUMBER >= OPENSSL_V_SERIES(1,1,0) */
+
+ done:
+ tor_free(tls->ssl->s3->rbuf.buf);
+ tor_free(tls->ssl->s3->wbuf.buf);
+ tor_free(tls->ssl->s3);
+ tor_free(tls->ssl);
+ tor_free(tls);
+}
+#endif /* !defined(OPENSSL_OPAQUE) */
+
+#ifndef OPENSSL_OPAQUE
+typedef struct cert_pkey_st_local
+{
+ X509 *x509;
+ EVP_PKEY *privatekey;
+ const EVP_MD *digest;
+} CERT_PKEY_local;
+
+typedef struct sess_cert_st_local
+{
+ STACK_OF(X509) *cert_chain;
+ int peer_cert_type;
+ CERT_PKEY_local *peer_key;
+ CERT_PKEY_local peer_pkeys[8];
+ int references;
+} SESS_CERT_local;
+
+static void
+test_tortls_try_to_extract_certs_from_tls(void *ignored)
+{
+ (void)ignored;
+ tor_tls_t *tls;
+ X509 *cert = NULL, *id_cert = NULL, *c1 = NULL, *c2 = NULL;
+ SESS_CERT_local *sess = NULL;
+
+ c1 = read_cert_from(validCertString);
+ c2 = read_cert_from(caCertString);
+
+ tls = tor_malloc_zero(sizeof(tor_tls_t));
+ tls->ssl = tor_malloc_zero(sizeof(SSL));
+ tls->ssl->session = tor_malloc_zero(sizeof(SSL_SESSION));
+ sess = tor_malloc_zero(sizeof(SESS_CERT_local));
+ tls->ssl->session->sess_cert = (void *)sess;
+
+ try_to_extract_certs_from_tls(LOG_WARN, tls, &cert, &id_cert);
+ tt_assert(!cert);
+ tt_assert(!id_cert);
+
+ tls->ssl->session->peer = c1;
+ try_to_extract_certs_from_tls(LOG_WARN, tls, &cert, &id_cert);
+ tt_assert(cert == c1);
+ tt_assert(!id_cert);
+ X509_free(cert); /* decrease refcnt */
+
+ sess->cert_chain = sk_X509_new_null();
+ try_to_extract_certs_from_tls(LOG_WARN, tls, &cert, &id_cert);
+ tt_assert(cert == c1);
+ tt_assert(!id_cert);
+ X509_free(cert); /* decrease refcnt */
+
+ sk_X509_push(sess->cert_chain, c1);
+ sk_X509_push(sess->cert_chain, c2);
+
+ try_to_extract_certs_from_tls(LOG_WARN, tls, &cert, &id_cert);
+ tt_assert(cert == c1);
+ tt_assert(id_cert);
+ X509_free(cert); /* decrease refcnt */
+
+ done:
+ sk_X509_free(sess->cert_chain);
+ tor_free(sess);
+ tor_free(tls->ssl->session);
+ tor_free(tls->ssl);
+ tor_free(tls);
+ X509_free(c1);
+ X509_free(c2);
+}
+#endif /* !defined(OPENSSL_OPAQUE) */
+
+#ifndef OPENSSL_OPAQUE
+static void
+test_tortls_get_peer_cert(void *ignored)
+{
+ (void)ignored;
+ tor_x509_cert_t *ret;
+ tor_tls_t *tls;
+ X509 *cert = NULL;
+
+ cert = read_cert_from(validCertString);
+
+ tls = tor_malloc_zero(sizeof(tor_tls_t));
+ tls->ssl = tor_malloc_zero(sizeof(SSL));
+ tls->ssl->session = tor_malloc_zero(sizeof(SSL_SESSION));
+
+ ret = tor_tls_get_peer_cert(tls);
+ tt_assert(!ret);
+
+ tls->ssl->session->peer = cert;
+ ret = tor_tls_get_peer_cert(tls);
+ tt_assert(ret);
+ tt_assert(ret->cert == cert);
+
+ done:
+ tor_x509_cert_free(ret);
+ tor_free(tls->ssl->session);
+ tor_free(tls->ssl);
+ tor_free(tls);
+ X509_free(cert);
+}
+#endif /* !defined(OPENSSL_OPAQUE) */
+
+#ifndef OPENSSL_OPAQUE
+static void
+test_tortls_peer_has_cert(void *ignored)
+{
+ (void)ignored;
+ int ret;
+ tor_tls_t *tls;
+ X509 *cert = NULL;
+
+ cert = read_cert_from(validCertString);
+
+ tls = tor_malloc_zero(sizeof(tor_tls_t));
+ tls->ssl = tor_malloc_zero(sizeof(SSL));
+ tls->ssl->session = tor_malloc_zero(sizeof(SSL_SESSION));
+
+ ret = tor_tls_peer_has_cert(tls);
+ tt_assert(!ret);
+
+ tls->ssl->session->peer = cert;
+ ret = tor_tls_peer_has_cert(tls);
+ tt_assert(ret);
+
+ done:
+ tor_free(tls->ssl->session);
+ tor_free(tls->ssl);
+ tor_free(tls);
+ X509_free(cert);
+}
+#endif /* !defined(OPENSSL_OPAQUE) */
+
+static void
+test_tortls_get_write_overhead_ratio(void *ignored)
+{
+ (void)ignored;
+ double ret;
+
+ total_bytes_written_over_tls = 0;
+ ret = tls_get_write_overhead_ratio();
+ tt_double_op(fabs(ret - 1.0), OP_LT, 1E-12);
+
+ total_bytes_written_by_tls = 10;
+ total_bytes_written_over_tls = 1;
+ ret = tls_get_write_overhead_ratio();
+ tt_double_op(fabs(ret - 10.0), OP_LT, 1E-12);
+
+ total_bytes_written_by_tls = 10;
+ total_bytes_written_over_tls = 2;
+ ret = tls_get_write_overhead_ratio();
+ tt_double_op(fabs(ret - 5.0), OP_LT, 1E-12);
+
+ done:
+ (void)0;
+}
+
+static void
+test_tortls_is_server(void *ignored)
+{
+ (void)ignored;
+ tor_tls_t *tls;
+ int ret;
+
+ tls = tor_malloc_zero(sizeof(tor_tls_t));
+ tls->isServer = 1;
+ ret = tor_tls_is_server(tls);
+ tt_int_op(ret, OP_EQ, 1);
+
+ done:
+ tor_free(tls);
+}
+
+#ifndef OPENSSL_OPAQUE
+static void
+test_tortls_session_secret_cb(void *ignored)
+{
+ (void)ignored;
+ tor_tls_t *tls;
+ SSL_CTX *ctx;
+ STACK_OF(SSL_CIPHER) *ciphers = NULL;
+ SSL_CIPHER *one;
+
+ library_init();
+
+ tor_tls_allocate_tor_tls_object_ex_data_index();
+
+ tls = tor_malloc_zero(sizeof(tor_tls_t));
+
+ tls->magic = TOR_TLS_MAGIC;
+
+ ctx = SSL_CTX_new(TLSv1_method());
+ tls->ssl = SSL_new(ctx);
+ SSL_set_ex_data(tls->ssl, tor_tls_object_ex_data_index, tls);
+
+ SSL_set_session_secret_cb(tls->ssl, tor_tls_session_secret_cb, NULL);
+
+ tor_tls_session_secret_cb(tls->ssl, NULL, NULL, NULL, NULL, NULL);
+ tt_assert(!tls->ssl->tls_session_secret_cb);
+
+ one = get_cipher_by_name("ECDHE-RSA-AES256-GCM-SHA384");
+ one->id = 0x00ff;
+ ciphers = sk_SSL_CIPHER_new_null();
+ sk_SSL_CIPHER_push(ciphers, one);
+
+ tls->client_cipher_list_type = 0;
+ tor_tls_session_secret_cb(tls->ssl, NULL, NULL, ciphers, NULL, NULL);
+ tt_assert(!tls->ssl->tls_session_secret_cb);
+
+ done:
+ sk_SSL_CIPHER_free(ciphers);
+ SSL_free(tls->ssl);
+ SSL_CTX_free(ctx);
+ tor_free(tls);
+}
+#endif /* !defined(OPENSSL_OPAQUE) */
+
+#ifndef OPENSSL_OPAQUE
+/* TODO: It seems block_renegotiation and unblock_renegotiation and
+ * using different blags. This might not be correct */
+static void
+test_tortls_block_renegotiation(void *ignored)
+{
+ (void)ignored;
+ tor_tls_t *tls;
+
+ tls = tor_malloc_zero(sizeof(tor_tls_t));
+ tls->ssl = tor_malloc_zero(sizeof(SSL));
+ tls->ssl->s3 = tor_malloc_zero(sizeof(SSL3_STATE));
+#ifndef SUPPORT_UNSAFE_RENEGOTIATION_FLAG
+#define SSL3_FLAGS_ALLOW_UNSAFE_LEGACY_RENEGOTIATION 0
+#endif
+
+ tls->ssl->s3->flags = SSL3_FLAGS_ALLOW_UNSAFE_LEGACY_RENEGOTIATION;
+
+ tor_tls_block_renegotiation(tls);
+
+#ifndef OPENSSL_1_1_API
+ tt_assert(!(tls->ssl->s3->flags &
+ SSL3_FLAGS_ALLOW_UNSAFE_LEGACY_RENEGOTIATION));
+#endif
+
+ done:
+ tor_free(tls->ssl->s3);
+ tor_free(tls->ssl);
+ tor_free(tls);
+}
+
+static void
+test_tortls_unblock_renegotiation(void *ignored)
+{
+ (void)ignored;
+ tor_tls_t *tls;
+
+ tls = tor_malloc_zero(sizeof(tor_tls_t));
+ tls->ssl = tor_malloc_zero(sizeof(SSL));
+ tor_tls_unblock_renegotiation(tls);
+
+ tt_uint_op(SSL_get_options(tls->ssl) &
+ SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION, OP_EQ,
+ SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION);
+
+ done:
+ tor_free(tls->ssl);
+ tor_free(tls);
+}
+#endif /* !defined(OPENSSL_OPAQUE) */
+
+#ifndef OPENSSL_OPAQUE
+static void
+test_tortls_assert_renegotiation_unblocked(void *ignored)
+{
+ (void)ignored;
+ tor_tls_t *tls;
+
+ tls = tor_malloc_zero(sizeof(tor_tls_t));
+ tls->ssl = tor_malloc_zero(sizeof(SSL));
+ tor_tls_unblock_renegotiation(tls);
+ tor_tls_assert_renegotiation_unblocked(tls);
+ /* No assertion here - this test will fail if tor_assert is turned on
+ * and things are bad. */
+
+ tor_free(tls->ssl);
+ tor_free(tls);
+}
+#endif /* !defined(OPENSSL_OPAQUE) */
+
+static void
+test_tortls_set_logged_address(void *ignored)
+{
+ (void)ignored;
+ tor_tls_t *tls;
+
+ tls = tor_malloc_zero(sizeof(tor_tls_t));
+
+ tor_tls_set_logged_address(tls, "foo bar");
+
+ tt_str_op(tls->address, OP_EQ, "foo bar");
+
+ tor_tls_set_logged_address(tls, "foo bar 2");
+ tt_str_op(tls->address, OP_EQ, "foo bar 2");
+
+ done:
+ tor_free(tls->address);
+ tor_free(tls);
+}
+
+#ifndef OPENSSL_OPAQUE
+static void
+example_cb(tor_tls_t *t, void *arg)
+{
+ (void)t;
+ (void)arg;
+}
+
+static void
+test_tortls_set_renegotiate_callback(void *ignored)
+{
+ (void)ignored;
+ tor_tls_t *tls;
+ const char *arg = "hello";
+
+ tls = tor_malloc_zero(sizeof(tor_tls_t));
+ tls->ssl = tor_malloc_zero(sizeof(SSL));
+
+ tor_tls_set_renegotiate_callback(tls, example_cb, (void*)arg);
+ tt_assert(tls->negotiated_callback == example_cb);
+ tt_assert(tls->callback_arg == arg);
+ tt_assert(!tls->got_renegotiate);
+
+ /* Assumes V2_HANDSHAKE_SERVER */
+ tt_assert(tls->ssl->info_callback == tor_tls_server_info_callback);
+
+ tor_tls_set_renegotiate_callback(tls, NULL, (void*)arg);
+ tt_assert(tls->ssl->info_callback == tor_tls_debug_state_callback);
+
+ done:
+ tor_free(tls->ssl);
+ tor_free(tls);
+}
+#endif /* !defined(OPENSSL_OPAQUE) */
+
+#ifndef OPENSSL_OPAQUE
+static SSL_CIPHER *fixed_cipher1 = NULL;
+static SSL_CIPHER *fixed_cipher2 = NULL;
+static const SSL_CIPHER *
+fake_get_cipher(unsigned ncipher)
+{
+
+ switch (ncipher) {
+ case 1:
+ return fixed_cipher1;
+ case 2:
+ return fixed_cipher2;
+ default:
+ return NULL;
+ }
+}
+#endif /* !defined(OPENSSL_OPAQUE) */
+
+#ifndef OPENSSL_OPAQUE
+static void
+test_tortls_find_cipher_by_id(void *ignored)
+{
+ (void)ignored;
+ int ret;
+ SSL *ssl;
+ SSL_CTX *ctx;
+ const SSL_METHOD *m = TLSv1_method();
+ SSL_METHOD *empty_method = tor_malloc_zero(sizeof(SSL_METHOD));
+
+ fixed_cipher1 = tor_malloc_zero(sizeof(SSL_CIPHER));
+ fixed_cipher2 = tor_malloc_zero(sizeof(SSL_CIPHER));
+ fixed_cipher2->id = 0xC00A;
+
+ library_init();
+
+ ctx = SSL_CTX_new(m);
+ ssl = SSL_new(ctx);
+
+ ret = find_cipher_by_id(ssl, NULL, 0xC00A);
+ tt_int_op(ret, OP_EQ, 1);
+
+ ret = find_cipher_by_id(ssl, m, 0xC00A);
+ tt_int_op(ret, OP_EQ, 1);
+
+ ret = find_cipher_by_id(ssl, m, 0xFFFF);
+ tt_int_op(ret, OP_EQ, 0);
+
+ ret = find_cipher_by_id(ssl, empty_method, 0xC00A);
+ tt_int_op(ret, OP_EQ, 1);
+
+ ret = find_cipher_by_id(ssl, empty_method, 0xFFFF);
+#ifdef HAVE_SSL_CIPHER_FIND
+ tt_int_op(ret, OP_EQ, 0);
+#else
+ tt_int_op(ret, OP_EQ, 1);
+#endif
+
+ empty_method->get_cipher = fake_get_cipher;
+ ret = find_cipher_by_id(ssl, empty_method, 0xC00A);
+ tt_int_op(ret, OP_EQ, 1);
+
+ empty_method->get_cipher = m->get_cipher;
+ empty_method->num_ciphers = m->num_ciphers;
+ ret = find_cipher_by_id(ssl, empty_method, 0xC00A);
+ tt_int_op(ret, OP_EQ, 1);
+
+ empty_method->get_cipher = fake_get_cipher;
+ empty_method->num_ciphers = m->num_ciphers;
+ ret = find_cipher_by_id(ssl, empty_method, 0xC00A);
+ tt_int_op(ret, OP_EQ, 1);
+
+ empty_method->num_ciphers = fake_num_ciphers;
+ ret = find_cipher_by_id(ssl, empty_method, 0xC00A);
+#ifdef HAVE_SSL_CIPHER_FIND
+ tt_int_op(ret, OP_EQ, 1);
+#else
+ tt_int_op(ret, OP_EQ, 0);
+#endif
+
+ done:
+ tor_free(empty_method);
+ SSL_free(ssl);
+ SSL_CTX_free(ctx);
+ tor_free(fixed_cipher1);
+}
+#endif /* !defined(OPENSSL_OPAQUE) */
+
+#ifndef OPENSSL_OPAQUE
+static void
+test_tortls_debug_state_callback(void *ignored)
+{
+ (void)ignored;
+ SSL *ssl;
+ char *buf = tor_malloc_zero(1000);
+ int n;
+
+ setup_capture_of_logs(LOG_DEBUG);
+
+ ssl = tor_malloc_zero(sizeof(SSL));
+
+ tor_tls_debug_state_callback(ssl, 32, 45);
+
+ n = tor_snprintf(buf, 1000, "SSL %p is now in state unknown"
+ " state [type=32,val=45].\n", ssl);
+ /* tor's snprintf returns -1 on error */
+ tt_int_op(n, OP_NE, -1);
+ expect_log_msg(buf);
+
+ done:
+ teardown_capture_of_logs();
+ tor_free(buf);
+ tor_free(ssl);
+}
+#endif /* !defined(OPENSSL_OPAQUE) */
+
+#ifndef OPENSSL_OPAQUE
+static void
+test_tortls_server_info_callback(void *ignored)
+{
+ (void)ignored;
+ tor_tls_t *tls;
+ SSL_CTX *ctx;
+ SSL *ssl;
+
+ library_init();
+
+ ctx = SSL_CTX_new(TLSv1_method());
+ ssl = SSL_new(ctx);
+
+ tor_tls_allocate_tor_tls_object_ex_data_index();
+
+ tls = tor_malloc_zero(sizeof(tor_tls_t));
+ tls->magic = TOR_TLS_MAGIC;
+ tls->ssl = ssl;
+
+ setup_full_capture_of_logs(LOG_WARN);
+ SSL_set_state(ssl, SSL3_ST_SW_SRVR_HELLO_A);
+ mock_clean_saved_logs();
+ tor_tls_server_info_callback(ssl, SSL_CB_ACCEPT_LOOP, 0);
+ expect_single_log_msg("Couldn't look up the tls for an SSL*. How odd!\n");
+
+ SSL_set_state(ssl, SSL3_ST_SW_SRVR_HELLO_B);
+ mock_clean_saved_logs();
+ tor_tls_server_info_callback(ssl, SSL_CB_ACCEPT_LOOP, 0);
+ expect_single_log_msg("Couldn't look up the tls for an SSL*. How odd!\n");
+
+ SSL_set_state(ssl, 99);
+ mock_clean_saved_logs();
+ tor_tls_server_info_callback(ssl, SSL_CB_ACCEPT_LOOP, 0);
+ expect_no_log_entry();
+ teardown_capture_of_logs();
+
+ SSL_set_ex_data(tls->ssl, tor_tls_object_ex_data_index, tls);
+ SSL_set_state(ssl, SSL3_ST_SW_SRVR_HELLO_B);
+ tls->negotiated_callback = 0;
+ //tls->server_handshake_count = 120;
+ tor_tls_server_info_callback(ssl, SSL_CB_ACCEPT_LOOP, 0);
+ //tt_int_op(tls->server_handshake_count, OP_EQ, 121);
+
+ //tls->server_handshake_count = 127;
+ tls->negotiated_callback = (void *)1;
+ tor_tls_server_info_callback(ssl, SSL_CB_ACCEPT_LOOP, 0);
+ //tt_int_op(tls->server_handshake_count, OP_EQ, 127);
+ tt_int_op(tls->got_renegotiate, OP_EQ, 1);
+
+ tls->ssl->session = SSL_SESSION_new();
+ tls->wasV2Handshake = 0;
+ tor_tls_server_info_callback(ssl, SSL_CB_ACCEPT_LOOP, 0);
+ tt_int_op(tls->wasV2Handshake, OP_EQ, 0);
+
+ done:
+ teardown_capture_of_logs();
+ SSL_free(ssl);
+ SSL_CTX_free(ctx);
+ tor_free(tls);
+}
+#endif /* !defined(OPENSSL_OPAQUE) */
+
+#ifndef OPENSSL_OPAQUE
+static int fixed_ssl_read_result_index;
+static int fixed_ssl_read_result[5];
+
+static int
+fixed_ssl_read(SSL *s, void *buf, int len)
+{
+ (void)s;
+ (void)buf;
+ (void)len;
+ return fixed_ssl_read_result[fixed_ssl_read_result_index++];
+}
+
+static int
+dummy_handshake_func(SSL *s)
+{
+ (void)s;
+ return 1;
+}
+
+static int negotiated_callback_called;
+
+static void
+negotiated_callback_setter(tor_tls_t *t, void *arg)
+{
+ (void)t;
+ (void)arg;
+ negotiated_callback_called++;
+}
+
+static void
+test_tortls_read(void *ignored)
+{
+ (void)ignored;
+ int ret;
+ tor_tls_t *tls;
+ char buf[100];
+ SSL_METHOD *method = give_me_a_test_method();
+ setup_capture_of_logs(LOG_WARN);
+
+ tls = tor_malloc_zero(sizeof(tor_tls_t));
+ tls->ssl = tor_malloc_zero(sizeof(SSL));
+ tls->state = TOR_TLS_ST_OPEN;
+
+ ret = tor_tls_read(tls, buf, 10);
+ tt_int_op(ret, OP_EQ, -9);
+
+ /* These tests assume that V2_HANDSHAKE_SERVER is set */
+ tls->ssl->handshake_func = dummy_handshake_func;
+ tls->ssl->method = method;
+ method->ssl_read = fixed_ssl_read;
+ fixed_ssl_read_result_index = 0;
+ fixed_ssl_read_result[0] = 42;
+ tls->state = TOR_TLS_ST_OPEN;
+ ERR_clear_error();
+ ret = tor_tls_read(tls, buf, 10);
+ tt_int_op(ret, OP_EQ, 42);
+
+ tls->state = TOR_TLS_ST_OPEN;
+ tls->got_renegotiate = 1;
+ fixed_ssl_read_result_index = 0;
+ ERR_clear_error();
+ ret = tor_tls_read(tls, buf, 10);
+ tt_int_op(tls->got_renegotiate, OP_EQ, 0);
+
+ tls->state = TOR_TLS_ST_OPEN;
+ tls->got_renegotiate = 1;
+ negotiated_callback_called = 0;
+ tls->negotiated_callback = negotiated_callback_setter;
+ fixed_ssl_read_result_index = 0;
+ ERR_clear_error();
+ ret = tor_tls_read(tls, buf, 10);
+ tt_int_op(negotiated_callback_called, OP_EQ, 1);
+
+#ifndef LIBRESSL_VERSION_NUMBER
+ fixed_ssl_read_result_index = 0;
+ fixed_ssl_read_result[0] = 0;
+ tls->ssl->version = SSL2_VERSION;
+ ERR_clear_error();
+ ret = tor_tls_read(tls, buf, 10);
+ tt_int_op(ret, OP_EQ, TOR_TLS_CLOSE);
+ tt_int_op(tls->state, OP_EQ, TOR_TLS_ST_CLOSED);
+#endif /* !defined(LIBRESSL_VERSION_NUMBER) */
+ // TODO: fill up
+
+ done:
+ teardown_capture_of_logs();
+ tor_free(tls->ssl);
+ tor_free(tls);
+ tor_free(method);
+}
+
+static int fixed_ssl_write_result;
+
+static int
+fixed_ssl_write(SSL *s, const void *buf, int len)
+{
+ (void)s;
+ (void)buf;
+ (void)len;
+ return fixed_ssl_write_result;
+}
+
+static void
+test_tortls_write(void *ignored)
+{
+ (void)ignored;
+ int ret;
+ tor_tls_t *tls;
+ SSL_METHOD *method = give_me_a_test_method();
+ char buf[100];
+ setup_capture_of_logs(LOG_WARN);
+
+ tls = tor_malloc_zero(sizeof(tor_tls_t));
+ tls->ssl = tor_malloc_zero(sizeof(SSL));
+ tls->state = TOR_TLS_ST_OPEN;
+
+ ret = tor_tls_write(tls, buf, 0);
+ tt_int_op(ret, OP_EQ, 0);
+
+ ret = tor_tls_write(tls, buf, 10);
+ tt_int_op(ret, OP_EQ, -9);
+
+ tls->ssl->method = method;
+ tls->wantwrite_n = 1;
+ ret = tor_tls_write(tls, buf, 10);
+ tt_int_op(tls->wantwrite_n, OP_EQ, 0);
+
+ method->ssl_write = fixed_ssl_write;
+ tls->ssl->handshake_func = dummy_handshake_func;
+ fixed_ssl_write_result = 1;
+ ERR_clear_error();
+ ret = tor_tls_write(tls, buf, 10);
+ tt_int_op(ret, OP_EQ, 1);
+
+ fixed_ssl_write_result = -1;
+ ERR_clear_error();
+ tls->ssl->rwstate = SSL_READING;
+ SSL_set_bio(tls->ssl, BIO_new(BIO_s_mem()), NULL);
+ SSL_get_rbio(tls->ssl)->flags = BIO_FLAGS_READ;
+ ret = tor_tls_write(tls, buf, 10);
+ tt_int_op(ret, OP_EQ, TOR_TLS_WANTREAD);
+
+ ERR_clear_error();
+ tls->ssl->rwstate = SSL_READING;
+ SSL_set_bio(tls->ssl, BIO_new(BIO_s_mem()), NULL);
+ SSL_get_rbio(tls->ssl)->flags = BIO_FLAGS_WRITE;
+ ret = tor_tls_write(tls, buf, 10);
+ tt_int_op(ret, OP_EQ, TOR_TLS_WANTWRITE);
+
+ done:
+ teardown_capture_of_logs();
+ BIO_free(tls->ssl->rbio);
+ tor_free(tls->ssl);
+ tor_free(tls);
+ tor_free(method);
+}
+#endif /* !defined(OPENSSL_OPAQUE) */
+
+#ifndef OPENSSL_OPAQUE
+static int fixed_ssl_accept_result;
+static int fixed_ssl_connect_result;
+
+static int
+setting_error_ssl_accept(SSL *ssl)
+{
+ (void)ssl;
+ ERR_put_error(ERR_LIB_BN, 2, -1, "somewhere.c", 99);
+ ERR_put_error(ERR_LIB_SYS, 2, -1, "somewhere.c", 99);
+ return fixed_ssl_accept_result;
+}
+
+static int
+setting_error_ssl_connect(SSL *ssl)
+{
+ (void)ssl;
+ ERR_put_error(ERR_LIB_BN, 2, -1, "somewhere.c", 99);
+ ERR_put_error(ERR_LIB_SYS, 2, -1, "somewhere.c", 99);
+ return fixed_ssl_connect_result;
+}
+
+static int
+fixed_ssl_accept(SSL *ssl)
+{
+ (void) ssl;
+ return fixed_ssl_accept_result;
+}
+
+static void
+test_tortls_handshake(void *ignored)
+{
+ (void)ignored;
+ int ret;
+ tor_tls_t *tls;
+ SSL_CTX *ctx;
+ SSL_METHOD *method = give_me_a_test_method();
+ setup_capture_of_logs(LOG_INFO);
+
+ SSL_library_init();
+ SSL_load_error_strings();
+
+ ctx = SSL_CTX_new(TLSv1_method());
+
+ tls = tor_malloc_zero(sizeof(tor_tls_t));
+ tls->ssl = SSL_new(ctx);
+ tls->state = TOR_TLS_ST_HANDSHAKE;
+
+ ret = tor_tls_handshake(tls);
+ tt_int_op(ret, OP_EQ, -9);
+
+ tls->isServer = 1;
+ tls->state = TOR_TLS_ST_HANDSHAKE;
+ ret = tor_tls_handshake(tls);
+ tt_int_op(ret, OP_EQ, -9);
+
+ tls->ssl->method = method;
+ method->ssl_accept = fixed_ssl_accept;
+ fixed_ssl_accept_result = 2;
+ ERR_clear_error();
+ tls->state = TOR_TLS_ST_HANDSHAKE;
+ ret = tor_tls_handshake(tls);
+ tt_int_op(tls->state, OP_EQ, TOR_TLS_ST_OPEN);
+
+ method->ssl_accept = setting_error_ssl_accept;
+ fixed_ssl_accept_result = 1;
+ ERR_clear_error();
+ mock_clean_saved_logs();
+ tls->state = TOR_TLS_ST_HANDSHAKE;
+ ret = tor_tls_handshake(tls);
+ tt_int_op(ret, OP_EQ, TOR_TLS_ERROR_MISC);
+ expect_log_entry();
+ /* This fails on jessie. Investigate why! */
+#if 0
+ expect_log_msg("TLS error while handshaking: (null) (in bignum routines:"
+ "(null):SSLv3 write client hello B)\n");
+ expect_log_msg("TLS error while handshaking: (null) (in system library:"
+ "connect:SSLv3 write client hello B)\n");
+#endif /* 0 */
+ expect_log_severity(LOG_INFO);
+
+ tls->isServer = 0;
+ method->ssl_connect = setting_error_ssl_connect;
+ fixed_ssl_connect_result = 1;
+ ERR_clear_error();
+ mock_clean_saved_logs();
+ tls->state = TOR_TLS_ST_HANDSHAKE;
+ ret = tor_tls_handshake(tls);
+ tt_int_op(ret, OP_EQ, TOR_TLS_ERROR_MISC);
+ expect_log_entry();
+#if 0
+ /* See above */
+ expect_log_msg("TLS error while handshaking: "
+ "(null) (in bignum routines:(null):SSLv3 write client hello B)\n");
+ expect_log_msg("TLS error while handshaking: "
+ "(null) (in system library:connect:SSLv3 write client hello B)\n");
+#endif /* 0 */
+ expect_log_severity(LOG_WARN);
+
+ done:
+ teardown_capture_of_logs();
+ SSL_free(tls->ssl);
+ SSL_CTX_free(ctx);
+ tor_free(tls);
+ tor_free(method);
+}
+#endif /* !defined(OPENSSL_OPAQUE) */
+
+#ifndef OPENSSL_OPAQUE
+static void
+test_tortls_finish_handshake(void *ignored)
+{
+ (void)ignored;
+ int ret;
+ tor_tls_t *tls;
+ SSL_CTX *ctx;
+ SSL_METHOD *method = give_me_a_test_method();
+ SSL_library_init();
+ SSL_load_error_strings();
+
+ X509 *c1 = read_cert_from(validCertString);
+ SESS_CERT_local *sess = NULL;
+
+ ctx = SSL_CTX_new(method);
+
+ tls = tor_malloc_zero(sizeof(tor_tls_t));
+ tls->ssl = SSL_new(ctx);
+ tls->state = TOR_TLS_ST_OPEN;
+
+ ret = tor_tls_finish_handshake(tls);
+ tt_int_op(ret, OP_EQ, 0);
+
+ tls->isServer = 1;
+ tls->wasV2Handshake = 0;
+ setup_full_capture_of_logs(LOG_WARN);
+ ret = tor_tls_finish_handshake(tls);
+ tt_int_op(ret, OP_EQ, 0);
+ tt_int_op(tls->wasV2Handshake, OP_EQ, 1);
+ expect_single_log_msg_containing("For some reason, wasV2Handshake didn't "
+ "get set.");
+ teardown_capture_of_logs();
+
+ tls->wasV2Handshake = 1;
+ ret = tor_tls_finish_handshake(tls);
+ tt_int_op(ret, OP_EQ, 0);
+ tt_int_op(tls->wasV2Handshake, OP_EQ, 1);
+
+ tls->wasV2Handshake = 1;
+ tls->ssl->session = SSL_SESSION_new();
+ ret = tor_tls_finish_handshake(tls);
+ tt_int_op(ret, OP_EQ, 0);
+ tt_int_op(tls->wasV2Handshake, OP_EQ, 0);
+
+ tls->isServer = 0;
+
+ sess = tor_malloc_zero(sizeof(SESS_CERT_local));
+ tls->ssl->session->sess_cert = (void *)sess;
+ sess->cert_chain = sk_X509_new_null();
+ sk_X509_push(sess->cert_chain, c1);
+ tls->ssl->session->peer = c1;
+ tls->wasV2Handshake = 0;
+ ret = tor_tls_finish_handshake(tls);
+ tt_int_op(ret, OP_EQ, 0);
+ tt_int_op(tls->wasV2Handshake, OP_EQ, 1);
+
+ method->num_ciphers = fake_num_ciphers;
+ ret = tor_tls_finish_handshake(tls);
+ tt_int_op(ret, OP_EQ, -9);
+
+ done:
+ if (sess)
+ sk_X509_free(sess->cert_chain);
+ if (tls->ssl && tls->ssl->session) {
+ tor_free(tls->ssl->session->sess_cert);
+ }
+ SSL_free(tls->ssl);
+ tor_free(tls);
+ SSL_CTX_free(ctx);
+ tor_free(method);
+ teardown_capture_of_logs();
+}
+#endif /* !defined(OPENSSL_OPAQUE) */
+
+static int fixed_crypto_pk_new_result_index;
+static crypto_pk_t *fixed_crypto_pk_new_result[5];
+
+static crypto_pk_t *
+fixed_crypto_pk_new(void)
+{
+ return fixed_crypto_pk_new_result[fixed_crypto_pk_new_result_index++];
+}
+
+#ifndef OPENSSL_OPAQUE
+static int fixed_crypto_pk_generate_key_with_bits_result_index;
+static int fixed_crypto_pk_generate_key_with_bits_result[5];
+static int fixed_tor_tls_create_certificate_result_index;
+static X509 *fixed_tor_tls_create_certificate_result[5];
+static int fixed_tor_x509_cert_new_result_index;
+static tor_x509_cert_t *fixed_tor_x509_cert_new_result[5];
+
+static int
+fixed_crypto_pk_generate_key_with_bits(crypto_pk_t *env, int bits)
+{
+ (void)env;
+ (void)bits;
+ return fixed_crypto_pk_generate_key_with_bits_result[
+ fixed_crypto_pk_generate_key_with_bits_result_index++];
+}
+
+static X509 *
+fixed_tor_tls_create_certificate(crypto_pk_t *rsa,
+ crypto_pk_t *rsa_sign,
+ const char *cname,
+ const char *cname_sign,
+ unsigned int cert_lifetime)
+{
+ (void)rsa;
+ (void)rsa_sign;
+ (void)cname;
+ (void)cname_sign;
+ (void)cert_lifetime;
+ return fixed_tor_tls_create_certificate_result[
+ fixed_tor_tls_create_certificate_result_index++];
+}
+
+static tor_x509_cert_t *
+fixed_tor_x509_cert_new(tor_x509_cert_impl_t *x509_cert)
+{
+ (void) x509_cert;
+ return fixed_tor_x509_cert_new_result[
+ fixed_tor_x509_cert_new_result_index++];
+}
+
+static void
+test_tortls_context_new(void *ignored)
+{
+ (void)ignored;
+ tor_tls_context_t *ret;
+ crypto_pk_t *pk1, *pk2, *pk3, *pk4, *pk5, *pk6, *pk7, *pk8, *pk9, *pk10,
+ *pk11, *pk12, *pk13, *pk14, *pk15, *pk16, *pk17, *pk18;
+
+ pk1 = crypto_pk_new();
+ pk2 = crypto_pk_new();
+ pk3 = crypto_pk_new();
+ pk4 = crypto_pk_new();
+ pk5 = crypto_pk_new();
+ pk6 = crypto_pk_new();
+ pk7 = crypto_pk_new();
+ pk8 = crypto_pk_new();
+ pk9 = crypto_pk_new();
+ pk10 = crypto_pk_new();
+ pk11 = crypto_pk_new();
+ pk12 = crypto_pk_new();
+ pk13 = crypto_pk_new();
+ pk14 = crypto_pk_new();
+ pk15 = crypto_pk_new();
+ pk16 = crypto_pk_new();
+ pk17 = crypto_pk_new();
+ pk18 = crypto_pk_new();
+
+ fixed_crypto_pk_new_result_index = 0;
+ fixed_crypto_pk_new_result[0] = NULL;
+ MOCK(crypto_pk_new, fixed_crypto_pk_new);
+ ret = tor_tls_context_new(NULL, 0, 0, 0);
+ tt_assert(!ret);
+
+ /* note: we already override this in testing_common.c, so we
+ * run this unit test in a subprocess. */
+ MOCK(crypto_pk_generate_key_with_bits,
+ fixed_crypto_pk_generate_key_with_bits);
+ fixed_crypto_pk_new_result_index = 0;
+ fixed_crypto_pk_new_result[0] = pk1;
+ fixed_crypto_pk_new_result[1] = NULL;
+ fixed_crypto_pk_generate_key_with_bits_result[0] = -1;
+ fixed_crypto_pk_generate_key_with_bits_result_index = 0;
+ ret = tor_tls_context_new(NULL, 0, 0, 0);
+ tt_assert(!ret);
+
+ fixed_crypto_pk_new_result_index = 0;
+ fixed_crypto_pk_new_result[0] = pk2;
+ fixed_crypto_pk_new_result[1] = NULL;
+ fixed_crypto_pk_generate_key_with_bits_result[0] = 0;
+ fixed_crypto_pk_generate_key_with_bits_result_index = 0;
+ ret = tor_tls_context_new(NULL, 0, 0, 0);
+ tt_assert(!ret);
+
+ fixed_crypto_pk_new_result_index = 0;
+ fixed_crypto_pk_new_result[0] = pk3;
+ fixed_crypto_pk_new_result[1] = pk4;
+ fixed_crypto_pk_new_result[2] = NULL;
+ fixed_crypto_pk_generate_key_with_bits_result[0] = 0;
+ fixed_crypto_pk_generate_key_with_bits_result[1] = -1;
+ fixed_crypto_pk_generate_key_with_bits_result_index = 0;
+ ret = tor_tls_context_new(NULL, 0, 0, 0);
+ tt_assert(!ret);
+
+ MOCK(tor_tls_create_certificate, fixed_tor_tls_create_certificate);
+
+ fixed_crypto_pk_new_result_index = 0;
+ fixed_crypto_pk_new_result[0] = pk5;
+ fixed_crypto_pk_new_result[1] = pk6;
+ fixed_crypto_pk_new_result[2] = NULL;
+ fixed_crypto_pk_generate_key_with_bits_result_index = 0;
+ fixed_crypto_pk_generate_key_with_bits_result[1] = 0;
+ fixed_tor_tls_create_certificate_result_index = 0;
+ fixed_tor_tls_create_certificate_result[0] = NULL;
+ fixed_tor_tls_create_certificate_result[1] = X509_new();
+ fixed_tor_tls_create_certificate_result[2] = X509_new();
+ ret = tor_tls_context_new(NULL, 0, 0, 0);
+ tt_assert(!ret);
+
+ fixed_crypto_pk_new_result_index = 0;
+ fixed_crypto_pk_new_result[0] = pk7;
+ fixed_crypto_pk_new_result[1] = pk8;
+ fixed_crypto_pk_new_result[2] = NULL;
+ fixed_crypto_pk_generate_key_with_bits_result_index = 0;
+ fixed_tor_tls_create_certificate_result_index = 0;
+ fixed_tor_tls_create_certificate_result[0] = X509_new();
+ fixed_tor_tls_create_certificate_result[1] = NULL;
+ fixed_tor_tls_create_certificate_result[2] = X509_new();
+ ret = tor_tls_context_new(NULL, 0, 0, 0);
+ tt_assert(!ret);
+
+ fixed_crypto_pk_new_result_index = 0;
+ fixed_crypto_pk_new_result[0] = pk9;
+ fixed_crypto_pk_new_result[1] = pk10;
+ fixed_crypto_pk_new_result[2] = NULL;
+ fixed_crypto_pk_generate_key_with_bits_result_index = 0;
+ fixed_tor_tls_create_certificate_result_index = 0;
+ fixed_tor_tls_create_certificate_result[0] = X509_new();
+ fixed_tor_tls_create_certificate_result[1] = X509_new();
+ fixed_tor_tls_create_certificate_result[2] = NULL;
+ ret = tor_tls_context_new(NULL, 0, 0, 0);
+ tt_assert(!ret);
+
+ MOCK(tor_x509_cert_new, fixed_tor_x509_cert_new);
+ fixed_crypto_pk_new_result_index = 0;
+ fixed_crypto_pk_new_result[0] = pk11;
+ fixed_crypto_pk_new_result[1] = pk12;
+ fixed_crypto_pk_new_result[2] = NULL;
+ fixed_crypto_pk_generate_key_with_bits_result_index = 0;
+ fixed_tor_tls_create_certificate_result_index = 0;
+ fixed_tor_tls_create_certificate_result[0] = X509_new();
+ fixed_tor_tls_create_certificate_result[1] = X509_new();
+ fixed_tor_tls_create_certificate_result[2] = X509_new();
+ fixed_tor_x509_cert_new_result_index = 0;
+ fixed_tor_x509_cert_new_result[0] = NULL;
+ fixed_tor_x509_cert_new_result[1] = NULL;
+ fixed_tor_x509_cert_new_result[2] = NULL;
+ ret = tor_tls_context_new(NULL, 0, 0, 0);
+ tt_assert(!ret);
+
+ fixed_crypto_pk_new_result_index = 0;
+ fixed_crypto_pk_new_result[0] = pk13;
+ fixed_crypto_pk_new_result[1] = pk14;
+ fixed_crypto_pk_new_result[2] = NULL;
+ fixed_crypto_pk_generate_key_with_bits_result_index = 0;
+ fixed_tor_tls_create_certificate_result_index = 0;
+ fixed_tor_tls_create_certificate_result[0] = X509_new();
+ fixed_tor_tls_create_certificate_result[1] = X509_new();
+ fixed_tor_tls_create_certificate_result[2] = X509_new();
+ fixed_tor_x509_cert_new_result_index = 0;
+ fixed_tor_x509_cert_new_result[0] = tor_malloc_zero(sizeof(tor_x509_cert_t));
+ fixed_tor_x509_cert_new_result[1] = NULL;
+ fixed_tor_x509_cert_new_result[2] = NULL;
+ ret = tor_tls_context_new(NULL, 0, 0, 0);
+ tt_assert(!ret);
+
+ fixed_crypto_pk_new_result_index = 0;
+ fixed_crypto_pk_new_result[0] = pk15;
+ fixed_crypto_pk_new_result[1] = pk16;
+ fixed_crypto_pk_new_result[2] = NULL;
+ fixed_crypto_pk_generate_key_with_bits_result_index = 0;
+ fixed_tor_tls_create_certificate_result_index = 0;
+ fixed_tor_tls_create_certificate_result[0] = X509_new();
+ fixed_tor_tls_create_certificate_result[1] = X509_new();
+ fixed_tor_tls_create_certificate_result[2] = X509_new();
+ fixed_tor_x509_cert_new_result_index = 0;
+ fixed_tor_x509_cert_new_result[0] = tor_malloc_zero(sizeof(tor_x509_cert_t));
+ fixed_tor_x509_cert_new_result[1] = tor_malloc_zero(sizeof(tor_x509_cert_t));
+ fixed_tor_x509_cert_new_result[2] = NULL;
+ ret = tor_tls_context_new(NULL, 0, 0, 0);
+ tt_assert(!ret);
+
+ fixed_crypto_pk_new_result_index = 0;
+ fixed_crypto_pk_new_result[0] = pk17;
+ fixed_crypto_pk_new_result[1] = pk18;
+ fixed_crypto_pk_new_result[2] = NULL;
+ fixed_crypto_pk_generate_key_with_bits_result_index = 0;
+ fixed_tor_tls_create_certificate_result_index = 0;
+ fixed_tor_tls_create_certificate_result[0] = X509_new();
+ fixed_tor_tls_create_certificate_result[1] = X509_new();
+ fixed_tor_tls_create_certificate_result[2] = X509_new();
+ fixed_tor_x509_cert_new_result_index = 0;
+ fixed_tor_x509_cert_new_result[0] = tor_malloc_zero(sizeof(tor_x509_cert_t));
+ fixed_tor_x509_cert_new_result[1] = tor_malloc_zero(sizeof(tor_x509_cert_t));
+ fixed_tor_x509_cert_new_result[2] = tor_malloc_zero(sizeof(tor_x509_cert_t));
+ ret = tor_tls_context_new(NULL, 0, 0, 0);
+ tt_assert(!ret);
+
+ done:
+ UNMOCK(tor_x509_cert_new);
+ UNMOCK(tor_tls_create_certificate);
+ UNMOCK(crypto_pk_generate_key_with_bits);
+ UNMOCK(crypto_pk_new);
+}
+#endif /* !defined(OPENSSL_OPAQUE) */
+
+static int fixed_crypto_pk_get_evp_pkey_result_index = 0;
+static EVP_PKEY *fixed_crypto_pk_get_evp_pkey_result[5];
+
+static EVP_PKEY *
+fixed_crypto_pk_get_evp_pkey_(crypto_pk_t *env, int private)
+{
+ (void) env;
+ (void) private;
+ return fixed_crypto_pk_get_evp_pkey_result[
+ fixed_crypto_pk_get_evp_pkey_result_index++];
+}
+
+static void
+test_tortls_create_certificate(void *ignored)
+{
+ (void)ignored;
+ X509 *ret;
+ crypto_pk_t *pk1, *pk2;
+
+ pk1 = crypto_pk_new();
+ pk2 = crypto_pk_new();
+
+ MOCK(crypto_pk_get_openssl_evp_pkey_, fixed_crypto_pk_get_evp_pkey_);
+ fixed_crypto_pk_get_evp_pkey_result_index = 0;
+ fixed_crypto_pk_get_evp_pkey_result[0] = NULL;
+ ret = tor_tls_create_certificate(pk1, pk2, "hello", "hello2", 1);
+ tt_assert(!ret);
+
+ fixed_crypto_pk_get_evp_pkey_result_index = 0;
+ fixed_crypto_pk_get_evp_pkey_result[0] = EVP_PKEY_new();
+ fixed_crypto_pk_get_evp_pkey_result[1] = NULL;
+ ret = tor_tls_create_certificate(pk1, pk2, "hello", "hello2", 1);
+ tt_assert(!ret);
+
+ fixed_crypto_pk_get_evp_pkey_result_index = 0;
+ fixed_crypto_pk_get_evp_pkey_result[0] = EVP_PKEY_new();
+ fixed_crypto_pk_get_evp_pkey_result[1] = EVP_PKEY_new();
+ ret = tor_tls_create_certificate(pk1, pk2, "hello", "hello2", 1);
+ tt_assert(!ret);
+
+ done:
+ UNMOCK(crypto_pk_get_openssl_evp_pkey_);
+ crypto_pk_free(pk1);
+ crypto_pk_free(pk2);
+}
+
+static void
+test_tortls_cert_new(void *ignored)
+{
+ (void)ignored;
+ tor_x509_cert_t *ret;
+ X509 *cert = read_cert_from(validCertString);
+
+ ret = tor_x509_cert_new(NULL);
+ tt_assert(!ret);
+
+ ret = tor_x509_cert_new(cert);
+ tt_assert(ret);
+ tor_x509_cert_free(ret);
+ ret = NULL;
+
+#if 0
+ cert = read_cert_from(validCertString);
+ /* XXX this doesn't do what you think: it alters a copy of the pubkey. */
+ X509_get_pubkey(cert)->type = EVP_PKEY_DSA;
+ ret = tor_x509_cert_new(cert);
+ tt_assert(ret);
+#endif /* 0 */
+
+#ifndef OPENSSL_OPAQUE
+ cert = read_cert_from(validCertString);
+ X509_CINF_free(cert->cert_info);
+ cert->cert_info = NULL;
+ ret = tor_x509_cert_new(cert);
+ tt_assert(ret);
+#endif /* !defined(OPENSSL_OPAQUE) */
+
+ done:
+ tor_x509_cert_free(ret);
+}
+
+static void
+test_tortls_cert_is_valid(void *ignored)
+{
+ (void)ignored;
+ int ret;
+ tor_x509_cert_t *cert = NULL, *scert = NULL;
+
+ scert = tor_malloc_zero(sizeof(tor_x509_cert_t));
+ ret = tor_tls_cert_is_valid(LOG_WARN, cert, scert, time(NULL), 0);
+ tt_int_op(ret, OP_EQ, 0);
+
+ cert = tor_malloc_zero(sizeof(tor_x509_cert_t));
+ ret = tor_tls_cert_is_valid(LOG_WARN, cert, scert, time(NULL), 0);
+ tt_int_op(ret, OP_EQ, 0);
+ tor_free(scert);
+ tor_free(cert);
+
+ cert = tor_x509_cert_new(read_cert_from(validCertString));
+ scert = tor_x509_cert_new(read_cert_from(caCertString));
+ ret = tor_tls_cert_is_valid(LOG_WARN, cert, scert, time(NULL), 0);
+ tt_int_op(ret, OP_EQ, 1);
+
+#ifndef OPENSSL_OPAQUE
+ tor_x509_cert_free(cert);
+ tor_x509_cert_free(scert);
+ cert = tor_x509_cert_new(read_cert_from(validCertString));
+ scert = tor_x509_cert_new(read_cert_from(caCertString));
+ ASN1_TIME_free(cert->cert->cert_info->validity->notAfter);
+ cert->cert->cert_info->validity->notAfter =
+ ASN1_TIME_set(NULL, time(NULL)-1000000);
+ ret = tor_tls_cert_is_valid(LOG_WARN, cert, scert, time(NULL), 0);
+ tt_int_op(ret, OP_EQ, 0);
+
+ tor_x509_cert_free(cert);
+ tor_x509_cert_free(scert);
+ cert = tor_x509_cert_new(read_cert_from(validCertString));
+ scert = tor_x509_cert_new(read_cert_from(caCertString));
+ X509_PUBKEY_free(cert->cert->cert_info->key);
+ cert->cert->cert_info->key = NULL;
+ ret = tor_tls_cert_is_valid(LOG_WARN, cert, scert, time(NULL), 1);
+ tt_int_op(ret, OP_EQ, 0);
+#endif /* !defined(OPENSSL_OPAQUE) */
+
+#if 0
+ tor_x509_cert_free(cert);
+ tor_x509_cert_free(scert);
+ cert = tor_x509_cert_new(read_cert_from(validCertString));
+ scert = tor_x509_cert_new(read_cert_from(caCertString));
+ /* This doesn't actually change the key in the cert. XXXXXX */
+ BN_one(EVP_PKEY_get1_RSA(X509_get_pubkey(cert->cert))->n);
+ ret = tor_tls_cert_is_valid(LOG_WARN, cert, scert, time(NULL), 1);
+ tt_int_op(ret, OP_EQ, 0);
+
+ tor_x509_cert_free(cert);
+ tor_x509_cert_free(scert);
+ cert = tor_x509_cert_new(read_cert_from(validCertString));
+ scert = tor_x509_cert_new(read_cert_from(caCertString));
+ /* This doesn't actually change the key in the cert. XXXXXX */
+ X509_get_pubkey(cert->cert)->type = EVP_PKEY_EC;
+ ret = tor_tls_cert_is_valid(LOG_WARN, cert, scert, time(NULL), 1);
+ tt_int_op(ret, OP_EQ, 0);
+
+ tor_x509_cert_free(cert);
+ tor_x509_cert_free(scert);
+ cert = tor_x509_cert_new(read_cert_from(validCertString));
+ scert = tor_x509_cert_new(read_cert_from(caCertString));
+ /* This doesn't actually change the key in the cert. XXXXXX */
+ X509_get_pubkey(cert->cert)->type = EVP_PKEY_EC;
+ ret = tor_tls_cert_is_valid(LOG_WARN, cert, scert, time(NULL), 0);
+ tt_int_op(ret, OP_EQ, 1);
+
+ tor_x509_cert_free(cert);
+ tor_x509_cert_free(scert);
+ cert = tor_x509_cert_new(read_cert_from(validCertString));
+ scert = tor_x509_cert_new(read_cert_from(caCertString));
+ /* This doesn't actually change the key in the cert. XXXXXX */
+ X509_get_pubkey(cert->cert)->type = EVP_PKEY_EC;
+ X509_get_pubkey(cert->cert)->ameth = NULL;
+ ret = tor_tls_cert_is_valid(LOG_WARN, cert, scert, time(NULL), 0);
+ tt_int_op(ret, OP_EQ, 0);
+#endif /* 0 */
+
+ done:
+ tor_x509_cert_free(cert);
+ tor_x509_cert_free(scert);
+}
+
+static void
+test_tortls_context_init_one(void *ignored)
+{
+ (void)ignored;
+ int ret;
+ tor_tls_context_t *old = NULL;
+
+ MOCK(crypto_pk_new, fixed_crypto_pk_new);
+
+ fixed_crypto_pk_new_result_index = 0;
+ fixed_crypto_pk_new_result[0] = NULL;
+ ret = tor_tls_context_init_one(&old, NULL, 0, 0, 0);
+ tt_int_op(ret, OP_EQ, -1);
+
+ done:
+ UNMOCK(crypto_pk_new);
+}
+
+#define LOCAL_TEST_CASE(name, flags) \
+ { #name, test_tortls_##name, (flags|TT_FORK), NULL, NULL }
+
+#ifdef OPENSSL_OPAQUE
+#define INTRUSIVE_TEST_CASE(name, flags) \
+ { #name, NULL, TT_SKIP, NULL, NULL }
+#else
+#define INTRUSIVE_TEST_CASE(name, flags) LOCAL_TEST_CASE(name, flags)
+#endif /* defined(OPENSSL_OPAQUE) */
+
+struct testcase_t tortls_openssl_tests[] = {
+ LOCAL_TEST_CASE(tor_tls_new, TT_FORK),
+ LOCAL_TEST_CASE(get_state_description, TT_FORK),
+ LOCAL_TEST_CASE(get_by_ssl, TT_FORK),
+ LOCAL_TEST_CASE(allocate_tor_tls_object_ex_data_index, TT_FORK),
+ LOCAL_TEST_CASE(log_one_error, TT_FORK),
+ INTRUSIVE_TEST_CASE(get_error, TT_FORK),
+ LOCAL_TEST_CASE(always_accept_verify_cb, 0),
+ INTRUSIVE_TEST_CASE(x509_cert_free, 0),
+ LOCAL_TEST_CASE(cert_matches_key, 0),
+ INTRUSIVE_TEST_CASE(cert_get_key, 0),
+ LOCAL_TEST_CASE(get_my_client_auth_key, TT_FORK),
+ INTRUSIVE_TEST_CASE(get_ciphersuite_name, 0),
+ INTRUSIVE_TEST_CASE(classify_client_ciphers, 0),
+ LOCAL_TEST_CASE(client_is_using_v2_ciphers, 0),
+ INTRUSIVE_TEST_CASE(get_pending_bytes, 0),
+ INTRUSIVE_TEST_CASE(SSL_SESSION_get_master_key, 0),
+ INTRUSIVE_TEST_CASE(get_tlssecrets, 0),
+ INTRUSIVE_TEST_CASE(get_buffer_sizes, 0),
+ INTRUSIVE_TEST_CASE(try_to_extract_certs_from_tls, 0),
+ INTRUSIVE_TEST_CASE(get_peer_cert, 0),
+ INTRUSIVE_TEST_CASE(peer_has_cert, 0),
+ INTRUSIVE_TEST_CASE(finish_handshake, 0),
+ INTRUSIVE_TEST_CASE(handshake, 0),
+ INTRUSIVE_TEST_CASE(write, 0),
+ INTRUSIVE_TEST_CASE(read, 0),
+ INTRUSIVE_TEST_CASE(server_info_callback, 0),
+ LOCAL_TEST_CASE(get_write_overhead_ratio, TT_FORK),
+ LOCAL_TEST_CASE(is_server, 0),
+ INTRUSIVE_TEST_CASE(assert_renegotiation_unblocked, 0),
+ INTRUSIVE_TEST_CASE(block_renegotiation, 0),
+ INTRUSIVE_TEST_CASE(unblock_renegotiation, 0),
+ INTRUSIVE_TEST_CASE(set_renegotiate_callback, 0),
+ LOCAL_TEST_CASE(set_logged_address, 0),
+ INTRUSIVE_TEST_CASE(find_cipher_by_id, 0),
+ INTRUSIVE_TEST_CASE(session_secret_cb, 0),
+ INTRUSIVE_TEST_CASE(debug_state_callback, 0),
+ INTRUSIVE_TEST_CASE(context_new, TT_FORK /* redundant */),
+ LOCAL_TEST_CASE(create_certificate, 0),
+ LOCAL_TEST_CASE(cert_new, 0),
+ LOCAL_TEST_CASE(cert_is_valid, 0),
+ LOCAL_TEST_CASE(context_init_one, 0),
+ END_OF_TESTCASES
+};
diff --git a/src/test/test_util_slow.c b/src/test/test_util_slow.c
index c5b24487b1..c7b3e3e2a4 100644
--- a/src/test/test_util_slow.c
+++ b/src/test/test_util_slow.c
@@ -6,7 +6,7 @@
#include "orconfig.h"
#define UTIL_PRIVATE
#define SUBPROCESS_PRIVATE
-#include "lib/crypt_ops/crypto.h"
+#include "lib/crypt_ops/crypto_cipher.h"
#include "lib/log/log.h"
#include "lib/process/subprocess.h"
#include "lib/process/waitpid.h"
diff --git a/src/test/test_workqueue.c b/src/test/test_workqueue.c
index 4550bad1f0..9d48d92773 100644
--- a/src/test/test_workqueue.c
+++ b/src/test/test_workqueue.c
@@ -12,6 +12,7 @@
#include "lib/net/alertsock.h"
#include "lib/evloop/compat_libevent.h"
#include "lib/intmath/weakrng.h"
+#include "lib/crypt_ops/crypto_init.h"
#include <stdio.h>
diff --git a/src/test/test_x509.c b/src/test/test_x509.c
new file mode 100644
index 0000000000..9ec0657d83
--- /dev/null
+++ b/src/test/test_x509.c
@@ -0,0 +1,203 @@
+/* Copyright (c) 2010-2018, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#define TOR_X509_PRIVATE
+#include "orconfig.h"
+
+#ifdef _WIN32
+#include <winsock2.h>
+#endif
+#include <math.h>
+#include <stddef.h>
+
+#include "lib/cc/compat_compiler.h"
+
+#include "core/or/or.h"
+#include "lib/log/log.h"
+#include "app/config/config.h"
+#include "lib/tls/x509.h"
+#include "lib/tls/x509_internal.h"
+#include "app/config/or_state_st.h"
+
+#include "test/test.h"
+#include "test/log_test_helpers.h"
+
+#include "tinytest.h"
+
+/* A mock replacement for crypto_digest that always fails. */
+static int
+mock_failing_digest(char *digest, const char *m, size_t len)
+{
+ (void)digest;
+ (void)m;
+ (void)len;
+ return -1;
+}
+
+static void
+test_x509_cert_new_failing_digest(void *arg)
+{
+ (void)arg;
+ crypto_pk_t *pk1=NULL, *pk2=NULL;
+ tor_x509_cert_impl_t *impl = NULL;
+ tor_x509_cert_t *cert = NULL;
+ pk1 = pk_generate(0);
+ pk2 = pk_generate(1);
+
+ impl = tor_tls_create_certificate(pk1, pk2, "hello", "world", 86400*100);
+ tt_assert(impl);
+ MOCK(crypto_digest, mock_failing_digest);
+
+ setup_full_capture_of_logs(LOG_WARN);
+ cert = tor_x509_cert_new(impl);
+ tt_assert(!cert);
+ expect_log_msg_containing("Couldn't wrap encoded X509 certificate");
+ expect_log_msg_containing("unable to compute digests of certificate key");
+
+ done:
+ crypto_pk_free(pk1);
+ crypto_pk_free(pk2);
+ tor_x509_cert_impl_free(impl);
+ UNMOCK(crypto_digest);
+ teardown_capture_of_logs();
+}
+
+static tor_x509_cert_t *
+cert_from_der64(const char *der64)
+{
+ size_t der64len = strlen(der64);
+ unsigned char *der = tor_malloc_zero(der64len);
+ int derlen;
+ tor_x509_cert_t *cert = NULL;
+
+ derlen = base64_decode((char*)der, der64len,
+ der64, der64len);
+ if (derlen >= 0)
+ cert = tor_x509_cert_decode(der, derlen);
+ tor_free(der);
+ return cert;
+}
+
+static void
+test_x509_consume_ec_cert(void *arg)
+{
+ (void)arg;
+ /* This is a small self-signed EC certificate. */
+ const char certificate[] =
+ "MIIBEzCBugIJAIdl5svgOZ0OMAoGCCqGSM49BAMCMBIxEDAOBgNVBAMMB1Rlc3Rp\n"
+ "bmcwHhcNMTgwODIzMTcyMzI1WhcNMTkwODIzMTcyMzI1WjASMRAwDgYDVQQDDAdU\n"
+ "ZXN0aW5nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAExMDpnRc0Btic3tIyCKNE\n"
+ "iNY4j4gzcaYzS2sTYRoVK3RAukG29Qg6/c8e8XcnsSquU4fItYxDRbi/3nhYk4CP\n"
+ "GDAKBggqhkjOPQQDAgNIADBFAiA0h1q03C2xlONUgAOonJLrlV1SUtMeKDxNsxsU\n"
+ "+FSPvQIhAM7kY9Tlt0ELmyMnORPp1VJieXn/qhL5VoxGxSedTbny\n";
+ const time_t now = 1535045321; /* when I'm writing this test. */
+ tor_x509_cert_t *cert = cert_from_der64(certificate);
+ tt_assert(cert);
+
+ tt_ptr_op(NULL, OP_EQ, tor_tls_cert_get_key(cert));
+
+ /* It's a self-signed cert -- make sure it signed itself. */
+ tt_assert(tor_tls_cert_is_valid(LOG_ERR, cert, cert, now, 0));
+
+ /* Make sure we detect its key as non-RSA1024 */
+ setup_capture_of_logs(LOG_INFO);
+ tt_assert(! tor_tls_cert_is_valid(LOG_INFO, cert, cert, now, 1));
+ expect_log_msg_containing("Key is not RSA1024");
+
+ done:
+ tor_x509_cert_free(cert);
+ teardown_capture_of_logs();
+}
+
+static void
+test_x509_reject_tiny_keys(void *arg)
+{
+ (void)arg;
+ const char *certificates[] = {
+ /* Self-signed RSA512 */
+ "MIIBXDCCAQYCCQDKikjJYZI5uDANBgkqhkiG9w0BAQsFADA1MRUwEwYDVQQHDAxE\n"
+ "ZWZhdWx0IENpdHkxHDAaBgNVBAoME0RlZmF1bHQgQ29tcGFueSBMdGQwHhcNMTgw\n"
+ "ODIzMTczNjQ4WhcNMTkwODIzMTczNjQ4WjA1MRUwEwYDVQQHDAxEZWZhdWx0IENp\n"
+ "dHkxHDAaBgNVBAoME0RlZmF1bHQgQ29tcGFueSBMdGQwXDANBgkqhkiG9w0BAQEF\n"
+ "AANLADBIAkEAqOvVKzrSpmKOTNqDzBG/iZrUdhCrMRsymFXyIScJcdsyn7jB8RMy\n"
+ "fbHqG8EqB8HHLU/eqt/+zhh2w08Lx3+5QwIDAQABMA0GCSqGSIb3DQEBCwUAA0EA\n"
+ "RSCq0sNbD9uWfcBqF0U4MtfFjU5x+RQQCeBVtAzwC9bggSILKZfB9XUvtGh6vqig\n",
+ /* Self-signed secp112r2 */
+ "MIIBLTCB+QIJAI0LtN9uWxy3MAoGCCqGSM49BAMCMEUxCzAJBgNVBAYTAkFVMRMw\n"
+ "EQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0\n"
+ "eSBMdGQwHhcNMTgwODIzMTc0MTQ4WhcNMTkwODIzMTc0MTQ4WjBFMQswCQYDVQQG\n"
+ "EwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lk\n"
+ "Z2l0cyBQdHkgTHRkMDIwEAYHKoZIzj0CAQYFK4EEAAcDHgAEf7dFHo7xhCtIcgyo\n"
+ "Px+IDcUUlntZCtar6V4O0zAKBggqhkjOPQQDAgMjADAgAg4yhBJMEmpkNbZU95Zf\n"
+ "uwIOJAan4J1ETxUII1RrGmw=\n"
+ };
+ const time_t now = 1535046182;
+ tor_x509_cert_t *cert = NULL;
+
+ unsigned i;
+ for (i = 0; i < ARRAY_LENGTH(certificates); ++i) {
+ cert = cert_from_der64(certificates[i]);
+ /* It might parse okay, depending on our version of NSS or OpenSSL. */
+ if (cert == NULL)
+ continue;
+ /* But it should not validate. */
+ tt_assert(! tor_tls_cert_is_valid(LOG_INFO, cert, cert, now, 0));
+ tor_x509_cert_free(cert);
+ }
+
+ done:
+ tor_x509_cert_free(cert);
+}
+
+static void
+test_x509_expiration(void *arg)
+{
+ (void)arg;
+ /* a 365-day RSA2048 cert, created between 0 and 60 minutes before "now" */
+ const char certificate[] =
+ "MIICzjCCAbYCCQDxIONWIQ9OGDANBgkqhkiG9w0BAQsFADApMQswCQYDVQQGEwJV\n"
+ "UzEaMBgGA1UEAwwRSW50ZXJlc3RpbmcgdGltZXMwHhcNMTgwODIzMTc1NTE4WhcN\n"
+ "MTkwODIzMTc1NTE4WjApMQswCQYDVQQGEwJVUzEaMBgGA1UEAwwRSW50ZXJlc3Rp\n"
+ "bmcgdGltZXMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQD0Blz1fBii\n"
+ "OffpFlzMrmfPah/vkPcNrwoyx5YiosbHErYUpqdCtfNb7rbBM5xcac1LmF9kjnOQ\n"
+ "uAw1jsCNE82QHwWMlXOqaZCEJsnttNo0Y7yaSR/ChbGJ54XCp+Lx2acyTeH9cBWU\n"
+ "de8/sKAQ4NqpbEP01pBH4+1mPu2MYWjVWVicUxmw0mJ3cfkJCWUzt0nC4ls8+Itk\n"
+ "7XliKb216Z9uQXu/zD/JGkxAljnFs1jXCX4NyWz46xnJFzXbYCeyQnBz0tUbAvgg\n"
+ "uRdryYtHzD46hd8LTXH6oK2gV64ILAhDnRb1aBjnCXxbex24XoW3hjSrKGTdNsXA\n"
+ "RMWU/8QZaoiBAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAFIYDBcbit2kOMrHECZK\n"
+ "ctem40A3s+0ZifzZ2KLhW8dTr/2Zb6DnlqVm2iUOV4cG/o1RAn/HzkQQuWEq+oBG\n"
+ "yOPVHudvCyGs+2ZQWudgAv9xq8N7KtZwJhnn42c2YSoreqRXDQgJqGFatyr+XdR7\n"
+ "gdQapLI4BFbZToeXp49Nl+q9330hKaSmIYmWEZ7R/33R64PU2el7X9/apYEcuZQT\n"
+ "+FjEqcO1lJ8/dTwM/2C1BJZqUeFTAu+ac1M+4//qyJRUUc6xSJLhiens8atWaxwL\n"
+ "eBCT8fCY8oPOwA1eImc/yWWmWXpv8bBWVe8OeLCMKM/OZoIdFqQpqSdcyGoh/kIW\n"
+ "Dws=\n";
+ const time_t now = 1535046996;
+
+ tor_x509_cert_t *cert = cert_from_der64(certificate);
+ tt_assert(cert);
+
+ tt_assert(tor_tls_cert_is_valid(LOG_ERR, cert, cert, now, 0));
+
+ tt_assert(tor_tls_cert_is_valid(LOG_ERR, cert, cert,
+ now-TOR_X509_FUTURE_SLOP, 0));
+ tt_assert(tor_tls_cert_is_valid(LOG_ERR, cert, cert,
+ now+365*86400+TOR_X509_PAST_SLOP - 3600, 0));
+
+ tt_assert(! tor_tls_cert_is_valid(LOG_INFO, cert, cert,
+ now-TOR_X509_FUTURE_SLOP - 3600, 0));
+ tt_assert(! tor_tls_cert_is_valid(LOG_INFO, cert, cert,
+ now+365*86400+TOR_X509_FUTURE_SLOP, 0));
+
+ done:
+ tor_x509_cert_free(cert);
+}
+
+#define TEST(name) { #name, test_x509_ ## name, TT_FORK, 0, NULL }
+
+struct testcase_t x509_tests[] = {
+ TEST(cert_new_failing_digest),
+ TEST(consume_ec_cert),
+ TEST(reject_tiny_keys),
+ TEST(expiration),
+ END_OF_TESTCASES
+};
diff --git a/src/test/testing_common.c b/src/test/testing_common.c
index 3880bca9c5..42b5190ca0 100644
--- a/src/test/testing_common.c
+++ b/src/test/testing_common.c
@@ -23,6 +23,7 @@
#include "core/mainloop/main.h"
#include "lib/compress/compress.h"
#include "lib/evloop/compat_libevent.h"
+#include "lib/crypt_ops/crypto_init.h"
#include <stdio.h>
#ifdef HAVE_FCNTL_H
@@ -222,6 +223,21 @@ an_assertion_failed(void)
tinytest_set_test_failed_();
}
+void tinytest_prefork(void);
+void tinytest_postfork(void);
+void
+tinytest_prefork(void)
+{
+ free_pregenerated_keys();
+ crypto_prefork();
+}
+void
+tinytest_postfork(void)
+{
+ crypto_postfork();
+ init_pregenerated_keys();
+}
+
/** Main entry point for unit test code: parse the command line, and run
* some unit tests. */
int
@@ -284,7 +300,6 @@ main(int c, const char **v)
printf("Can't initialize crypto subsystem; exiting.\n");
return 1;
}
- crypto_set_tls_dh_prime();
if (crypto_seed_rng() < 0) {
printf("Couldn't seed RNG; exiting.\n");
return 1;
diff --git a/src/test/testing_rsakeys.c b/src/test/testing_rsakeys.c
index a8c9ce4ce8..c8062b82d5 100644
--- a/src/test/testing_rsakeys.c
+++ b/src/test/testing_rsakeys.c
@@ -490,7 +490,7 @@ crypto_pk_generate_key_with_bits__get_cached(crypto_pk_t *env, int bits)
{
if (bits == 1024 || bits == 2048) {
crypto_pk_t *newkey = pk_generate_internal(bits);
- crypto_pk_assign_(env, newkey);
+ crypto_pk_assign_private(env, newkey);
crypto_pk_free(newkey);
} else {
return crypto_pk_generate_key_with_bits__real(env, bits);
@@ -544,4 +544,3 @@ init_pregenerated_keys(void)
crypto_pk_generate_key_with_bits__get_cached);
#endif /* defined(USE_PREGENERATED_RSA_KEYS) */
}
-