diff options
Diffstat (limited to 'src/test')
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) */ } - |