commit c317e78dd75b6bf9c195c9bef5a0b8300d55411a Author: Nick Mathewson nickm@torproject.org Date: Wed Jul 11 14:46:28 2018 -0400
Initialize and shut down NSS.
This is largely conjectural, based on online documentation for NSS and NSPR. --- src/lib/crypt_ops/crypto_init.c | 18 +++++-- src/lib/crypt_ops/crypto_nss_mgt.c | 95 ++++++++++++++++++++++++++++++++++ src/lib/crypt_ops/crypto_nss_mgt.h | 31 +++++++++++ src/lib/crypt_ops/crypto_openssl_mgt.c | 11 +++- src/lib/crypt_ops/crypto_openssl_mgt.h | 8 +-- src/lib/crypt_ops/include.am | 10 +++- 6 files changed, 165 insertions(+), 8 deletions(-)
diff --git a/src/lib/crypt_ops/crypto_init.c b/src/lib/crypt_ops/crypto_init.c index 01d5baf5b..7f5a63219 100644 --- a/src/lib/crypt_ops/crypto_init.c +++ b/src/lib/crypt_ops/crypto_init.c @@ -18,6 +18,7 @@ #include "lib/crypt_ops/crypto_dh.h" #include "lib/crypt_ops/crypto_ed25519.h" #include "lib/crypt_ops/crypto_openssl_mgt.h" +#include "lib/crypt_ops/crypto_nss_mgt.h" #include "lib/crypt_ops/crypto_rand.h"
#include "siphash.h" @@ -56,6 +57,9 @@ crypto_early_init(void) #ifdef ENABLE_OPENSSL crypto_openssl_early_init(); #endif +#ifdef ENABLE_NSS + crypto_nss_early_init(); +#endif
if (crypto_seed_rng() < 0) return -1; @@ -80,7 +84,12 @@ crypto_global_init(int useAccel, const char *accelName, const char *accelDir) crypto_global_initialized_ = 1;
#ifdef ENABLE_OPENSSL - return crypto_openssl_late_init(useAccel, accelName, accelDir); + if (crypto_openssl_late_init(useAccel, accelName, accelDir) < 0) + return -1; +#endif +#ifdef ENABLE_NSS + if (crypto_nss_late_init() < 0) + return -1; #endif } return 0; @@ -90,8 +99,8 @@ crypto_global_init(int useAccel, const char *accelName, const char *accelDir) void crypto_thread_cleanup(void) { -#ifndef NEW_THREAD_API - ERR_remove_thread_state(NULL); +#ifdef ENABLE_OPENSSL + crypto_openssl_thread_cleanup(); #endif }
@@ -107,6 +116,9 @@ crypto_global_cleanup(void) #ifdef ENABLE_OPENSSL crypto_openssl_global_cleanup(); #endif +#ifdef ENABLE_NSS + crypto_nss_global_cleanup(); +#endif
crypto_early_initialized_ = 0; crypto_global_initialized_ = 0; diff --git a/src/lib/crypt_ops/crypto_nss_mgt.c b/src/lib/crypt_ops/crypto_nss_mgt.c new file mode 100644 index 000000000..84d9f027a --- /dev/null +++ b/src/lib/crypt_ops/crypto_nss_mgt.c @@ -0,0 +1,95 @@ +/* Copyright (c) 2001, Matej Pfajfar. + * Copyright (c) 2001-2004, Roger Dingledine. + * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. + * Copyright (c) 2007-2018, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +/** + * \file crypto_nss_mgt.c + * + * \brief Manage the NSS library (if used) + **/ + +#include "lib/crypt_ops/crypto_nss_mgt.h" + +#include "lib/log/log.h" +#include "lib/log/util_bug.h" + +#include <nss.h> +#include <pk11func.h> +#include <ssl.h> + +#include <prerror.h> +#include <prtypes.h> +#include <prinit.h> + +const char * +crypto_nss_get_version_str(void) +{ + return NSS_GetVersion(); +} +const char * +crypto_nss_get_header_version_str(void) +{ + return NSS_VERSION; +} + +/** A password function that always returns NULL. */ +static char * +nss_password_func_always_fail(PK11SlotInfo *slot, + PRBool retry, + void *arg) +{ + (void) slot; + (void) retry; + (void) arg; + return NULL; +} + +void +crypto_nss_early_init(void) +{ + PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); + PK11_SetPasswordFunc(nss_password_func_always_fail); + + /* Eventually we should use NSS_Init() instead -- but that wants a + directory. The documentation says that we can't use this if we want + to use OpenSSL. */ + if (NSS_NoDB_Init(NULL) == SECFailure) { + log_err(LD_CRYPTO, "Unable to initialize NSS."); + crypto_nss_log_errors(LOG_ERR, "initializing NSS"); + tor_assert_unreached(); + } + + if (NSS_SetDomesticPolicy() == SECFailure) { + log_err(LD_CRYPTO, "Unable to set NSS cipher policy."); + crypto_nss_log_errors(LOG_ERR, "setting cipher policy"); + tor_assert_unreached(); + } +} + +void +crypto_nss_log_errors(int severity, const char *doing) +{ + PRErrorCode code = PR_GetError(); + /* XXXX how do I convert errors to strings? */ + if (doing) { + tor_log(severity, LD_CRYPTO, "NSS error %u while %s", code, doing); + } else { + tor_log(severity, LD_CRYPTO, "NSS error %u", code); + } +} + +int +crypto_nss_late_init(void) +{ + /* Possibly, SSL_OptionSetDefault? */ + + return 0; +} + +void +crypto_nss_global_cleanup(void) +{ + NSS_Shutdown(); +} diff --git a/src/lib/crypt_ops/crypto_nss_mgt.h b/src/lib/crypt_ops/crypto_nss_mgt.h new file mode 100644 index 000000000..0e899bad0 --- /dev/null +++ b/src/lib/crypt_ops/crypto_nss_mgt.h @@ -0,0 +1,31 @@ +/* Copyright (c) 2001, Matej Pfajfar. + * Copyright (c) 2001-2004, Roger Dingledine. + * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. + * Copyright (c) 2007-2018, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +/** + * \file crypto_nss_mgt.h + * + * \brief Headers for crypto_nss_mgt.c + **/ + +#ifndef TOR_CRYPTO_NSS_MGT_H +#define TOR_CRYPTO_NSS_MGT_H + +#include "orconfig.h" + +#ifdef ENABLE_NSS +/* global nss state */ +const char *crypto_nss_get_version_str(void); +const char *crypto_nss_get_header_version_str(void); + +void crypto_nss_log_errors(int severity, const char *doing); + +void crypto_nss_early_init(void); +int crypto_nss_late_init(void); + +void crypto_nss_global_cleanup(void); +#endif + +#endif /* !defined(TOR_CRYPTO_NSS_H) */ diff --git a/src/lib/crypt_ops/crypto_openssl_mgt.c b/src/lib/crypt_ops/crypto_openssl_mgt.c index bf5b96f9a..125da0786 100644 --- a/src/lib/crypt_ops/crypto_openssl_mgt.c +++ b/src/lib/crypt_ops/crypto_openssl_mgt.c @@ -153,7 +153,7 @@ tor_set_openssl_thread_id(CRYPTO_THREADID *threadid)
/** Helper: Construct mutexes, and set callbacks to help OpenSSL handle being * multithreaded. Returns 0. */ -int +static int setup_openssl_threading(void) { #ifndef NEW_THREAD_API @@ -352,6 +352,15 @@ crypto_openssl_late_init(int useAccel, const char *accelName, return 0; }
+/** Free crypto resources held by this thread. */ +void +crypto_openssl_thread_cleanup(void) +{ +#ifndef NEW_THREAD_API + ERR_remove_thread_state(NULL); +#endif +} + /** Clean up global resources held by openssl. */ void crypto_openssl_global_cleanup(void) diff --git a/src/lib/crypt_ops/crypto_openssl_mgt.h b/src/lib/crypt_ops/crypto_openssl_mgt.h index 417bb36f0..3b288fb9d 100644 --- a/src/lib/crypt_ops/crypto_openssl_mgt.h +++ b/src/lib/crypt_ops/crypto_openssl_mgt.h @@ -14,6 +14,8 @@ #define TOR_CRYPTO_OPENSSL_H
#include "orconfig.h" + +#ifdef ENABLE_OPENSSL #include <openssl/engine.h>
/* @@ -75,13 +77,13 @@ void crypto_openssl_log_errors(int severity, const char *doing); const char * crypto_openssl_get_version_str(void); const char * crypto_openssl_get_header_version_str(void);
-/* OpenSSL threading setup function */ -int setup_openssl_threading(void); - void crypto_openssl_early_init(void); int crypto_openssl_late_init(int useAccel, const char *accelName, const char *accelDir);
+void crypto_openssl_thread_cleanup(void); void crypto_openssl_global_cleanup(void);
+#endif /* ENABLE_OPENSSL */ + #endif /* !defined(TOR_CRYPTO_OPENSSL_H) */ diff --git a/src/lib/crypt_ops/include.am b/src/lib/crypt_ops/include.am index 1caa3fdbc..e96d6b0a5 100644 --- a/src/lib/crypt_ops/include.am +++ b/src/lib/crypt_ops/include.am @@ -15,7 +15,6 @@ src_lib_libtor_crypt_ops_a_SOURCES = \ src/lib/crypt_ops/crypto_format.c \ src/lib/crypt_ops/crypto_hkdf.c \ src/lib/crypt_ops/crypto_init.c \ - src/lib/crypt_ops/crypto_openssl_mgt.c \ src/lib/crypt_ops/crypto_pwbox.c \ src/lib/crypt_ops/crypto_rand.c \ src/lib/crypt_ops/crypto_rsa.c \ @@ -23,6 +22,15 @@ src_lib_libtor_crypt_ops_a_SOURCES = \ src/lib/crypt_ops/crypto_util.c \ src/lib/crypt_ops/digestset.c
+if USE_NSS +src_lib_libtor_crypt_ops_a_SOURCES += \ + src/lib/crypt_ops/crypto_nss_mgt.c +endif +if USE_OPENSSL +src_lib_libtor_crypt_ops_a_SOURCES += \ + src/lib/crypt_ops/crypto_openssl_mgt.c +endif + src_lib_libtor_crypt_ops_a_CFLAGS = $(AM_CFLAGS) $(TOR_CFLAGS_CRYPTLIB)
src_lib_libtor_crypt_ops_testing_a_SOURCES = \
tor-commits@lists.torproject.org