[tor-commits] [tor/master] Initialize and shut down NSS.

nickm at torproject.org nickm at torproject.org
Wed Sep 5 00:47:13 UTC 2018


commit c317e78dd75b6bf9c195c9bef5a0b8300d55411a
Author: Nick Mathewson <nickm at 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 = \





More information about the tor-commits mailing list