[tor-commits] [tor/master] Refactor crypto.[ch] into smaller OpenSSL module.

nickm at torproject.org nickm at torproject.org
Tue Jan 23 19:02:50 UTC 2018


commit 4022277272b5213ef34cfeed46d006800b131687
Author: Fernando Fernandez Mancera <ffernandezmancera at gmail.com>
Date:   Mon Jan 8 13:57:06 2018 +0100

    Refactor crypto.[ch] into smaller OpenSSL module.
    
    Add two new files (crypto_openssl.c, crypto_openssl.h) as new module of
    crypto.[ch]. This new module includes all functions and dependencies related
    to OpenSSL management. Those have been removed from crypto.[ch].
    
    All new changes related to OpenSSL management must be done in these files.
    
    Follows #24658
    
    Signed-off-by: Fernando Fernandez Mancera <ffernandezmancera at gmail.com>
---
 src/common/crypto.c         | 143 --------------------------------------------
 src/common/crypto.h         |  35 -----------
 src/common/crypto_openssl.c | 115 +++++++++++++++++++++++++++++++++++
 src/common/crypto_openssl.h | 105 ++++++++++++++++++++++++++++++++
 4 files changed, 220 insertions(+), 178 deletions(-)

diff --git a/src/common/crypto.c b/src/common/crypto.c
index c9db7cb4b..0abb4a1af 100644
--- a/src/common/crypto.c
+++ b/src/common/crypto.c
@@ -29,21 +29,6 @@
 #include "crypto_ed25519.h"
 #include "crypto_format.h"
 
-DISABLE_GCC_WARNING(redundant-decls)
-
-#include <openssl/err.h>
-#include <openssl/rsa.h>
-#include <openssl/pem.h>
-#include <openssl/evp.h>
-#include <openssl/engine.h>
-#include <openssl/rand.h>
-#include <openssl/bn.h>
-#include <openssl/dh.h>
-#include <openssl/conf.h>
-#include <openssl/hmac.h>
-
-ENABLE_GCC_WARNING(redundant-decls)
-
 #if __GNUC__ && GCC_VERSION >= 402
 #if GCC_VERSION >= 406
 #pragma GCC diagnostic pop
@@ -82,40 +67,12 @@ ENABLE_GCC_WARNING(redundant-decls)
 
 #include "keccak-tiny/keccak-tiny.h"
 
-#ifdef ANDROID
-/* Android's OpenSSL seems to have removed all of its Engine support. */
-#define DISABLE_ENGINES
-#endif
-
-#if OPENSSL_VERSION_NUMBER >= OPENSSL_VER(1,1,0,0,5) && \
-  !defined(LIBRESSL_VERSION_NUMBER)
-/* OpenSSL as of 1.1.0pre4 has an "new" thread API, which doesn't require
- * seting up various callbacks.
- *
- * OpenSSL 1.1.0pre4 has a messed up `ERR_remove_thread_state()` prototype,
- * while the previous one was restored in pre5, and the function made a no-op
- * (along with a deprecated annotation, which produces a compiler warning).
- *
- * While it is possible to support all three versions of the thread API,
- * a version that existed only for one snapshot pre-release is kind of
- * pointless, so let's not.
- */
-#define NEW_THREAD_API
-#endif /* OPENSSL_VERSION_NUMBER >= OPENSSL_VER(1,1,0,0,5) && ... */
-
 /** Longest recognized */
 #define MAX_DNS_LABEL_SIZE 63
 
 /** Largest strong entropy request */
 #define MAX_STRONGEST_RAND_SIZE 256
 
-#ifndef NEW_THREAD_API
-/** A number of preallocated mutexes for use by OpenSSL. */
-static tor_mutex_t **openssl_mutexes_ = NULL;
-/** How many mutexes have we allocated for use by OpenSSL? */
-static int n_openssl_mutexes_ = 0;
-#endif /* !defined(NEW_THREAD_API) */
-
 /** A public key, or a public/private key-pair. */
 struct crypto_pk_t
 {
@@ -129,7 +86,6 @@ struct crypto_dh_t {
   DH *dh; /**< The openssl DH object */
 };
 
-static int setup_openssl_threading(void);
 static int tor_check_dh_key(int severity, const BIGNUM *bn);
 
 /** Return the number of bytes added by padding method <b>padding</b>.
@@ -220,52 +176,6 @@ try_load_engine(const char *path, const char *engine)
 }
 #endif /* !defined(DISABLE_ENGINES) */
 
-/* Returns a trimmed and human-readable version of an openssl version string
-* <b>raw_version</b>. They are usually in the form of 'OpenSSL 1.0.0b 10
-* May 2012' and this will parse them into a form similar to '1.0.0b' */
-static char *
-parse_openssl_version_str(const char *raw_version)
-{
-  const char *end_of_version = NULL;
-  /* The output should be something like "OpenSSL 1.0.0b 10 May 2012. Let's
-     trim that down. */
-  if (!strcmpstart(raw_version, "OpenSSL ")) {
-    raw_version += strlen("OpenSSL ");
-    end_of_version = strchr(raw_version, ' ');
-  }
-
-  if (end_of_version)
-    return tor_strndup(raw_version,
-                      end_of_version-raw_version);
-  else
-    return tor_strdup(raw_version);
-}
-
-static char *crypto_openssl_version_str = NULL;
-/* Return a human-readable version of the run-time openssl version number. */
-const char *
-crypto_openssl_get_version_str(void)
-{
-  if (crypto_openssl_version_str == NULL) {
-    const char *raw_version = OpenSSL_version(OPENSSL_VERSION);
-    crypto_openssl_version_str = parse_openssl_version_str(raw_version);
-  }
-  return crypto_openssl_version_str;
-}
-
-static char *crypto_openssl_header_version_str = NULL;
-/* Return a human-readable version of the compile-time openssl version
-* number. */
-const char *
-crypto_openssl_get_header_version_str(void)
-{
-  if (crypto_openssl_header_version_str == NULL) {
-    crypto_openssl_header_version_str =
-                        parse_openssl_version_str(OPENSSL_VERSION_TEXT);
-  }
-  return crypto_openssl_header_version_str;
-}
-
 /** Make sure that openssl is using its default PRNG. Return 1 if we had to
  * adjust it; 0 otherwise. */
 STATIC int
@@ -3347,36 +3257,6 @@ memwipe(void *mem, uint8_t byte, size_t sz)
   memset(mem, byte, sz);
 }
 
-#ifndef OPENSSL_THREADS
-#error OpenSSL has been built without thread support. Tor requires an \
- OpenSSL library with thread support enabled.
-#endif
-
-#ifndef NEW_THREAD_API
-/** Helper: OpenSSL uses this callback to manipulate mutexes. */
-static void
-openssl_locking_cb_(int mode, int n, const char *file, int line)
-{
-  (void)file;
-  (void)line;
-  if (!openssl_mutexes_)
-    /* This is not a really good fix for the
-     * "release-freed-lock-from-separate-thread-on-shutdown" problem, but
-     * it can't hurt. */
-    return;
-  if (mode & CRYPTO_LOCK)
-    tor_mutex_acquire(openssl_mutexes_[n]);
-  else
-    tor_mutex_release(openssl_mutexes_[n]);
-}
-
-static void
-tor_set_openssl_thread_id(CRYPTO_THREADID *threadid)
-{
-  CRYPTO_THREADID_set_numeric(threadid, tor_get_thread_id());
-}
-#endif /* !defined(NEW_THREAD_API) */
-
 #if 0
 /* This code is disabled, because OpenSSL never actually uses these callbacks.
  */
@@ -3428,29 +3308,6 @@ openssl_dynlock_destroy_cb_(struct CRYPTO_dynlock_value *v,
 #endif /* 0 */
 
 /** @{ */
-/** Helper: Construct mutexes, and set callbacks to help OpenSSL handle being
- * multithreaded. Returns 0. */
-static int
-setup_openssl_threading(void)
-{
-#ifndef NEW_THREAD_API
-  int i;
-  int n = CRYPTO_num_locks();
-  n_openssl_mutexes_ = n;
-  openssl_mutexes_ = tor_calloc(n, sizeof(tor_mutex_t *));
-  for (i=0; i < n; ++i)
-    openssl_mutexes_[i] = tor_mutex_new();
-  CRYPTO_set_locking_callback(openssl_locking_cb_);
-  CRYPTO_THREADID_set_callback(tor_set_openssl_thread_id);
-#endif /* !defined(NEW_THREAD_API) */
-#if 0
-  CRYPTO_set_dynlock_create_callback(openssl_dynlock_create_cb_);
-  CRYPTO_set_dynlock_lock_callback(openssl_dynlock_lock_cb_);
-  CRYPTO_set_dynlock_destroy_callback(openssl_dynlock_destroy_cb_);
-#endif
-  return 0;
-}
-
 /** Uninitialize the crypto library. Return 0 on success. Does not detect
  * failure.
  */
diff --git a/src/common/crypto.h b/src/common/crypto.h
index f9aeeee2c..879af45fe 100644
--- a/src/common/crypto.h
+++ b/src/common/crypto.h
@@ -20,41 +20,8 @@
 #include "testsupport.h"
 #include "compat.h"
 
-#include <openssl/engine.h>
 #include "keccak-tiny/keccak-tiny.h"
 
-/*
-  Macro to create an arbitrary OpenSSL version number as used by
-  OPENSSL_VERSION_NUMBER or SSLeay(), since the actual numbers are a bit hard
-  to read.
-
-  Don't use this directly, instead use one of the other OPENSSL_V macros
-  below.
-
-  The format is: 4 bits major, 8 bits minor, 8 bits fix, 8 bits patch, 4 bit
-  status.
- */
-#define OPENSSL_VER(a,b,c,d,e)                                \
-  (((a)<<28) |                                                \
-   ((b)<<20) |                                                \
-   ((c)<<12) |                                                \
-   ((d)<< 4) |                                                \
-    (e))
-/** An openssl release number.  For example, OPENSSL_V(0,9,8,'j') is the
- * version for the released version of 0.9.8j */
-#define OPENSSL_V(a,b,c,d) \
-  OPENSSL_VER((a),(b),(c),(d)-'a'+1,0xf)
-/** An openssl release number for the first release in the series.  For
- * example, OPENSSL_V_NOPATCH(1,0,0) is the first released version of OpenSSL
- * 1.0.0. */
-#define OPENSSL_V_NOPATCH(a,b,c) \
-  OPENSSL_VER((a),(b),(c),0,0xf)
-/** The first version that would occur for any alpha or beta in an openssl
- * series. For example, OPENSSL_V_SERIES(0,9,8) is greater than any released
- * 0.9.7, and less than any released 0.9.8. */
-#define OPENSSL_V_SERIES(a,b,c) \
-  OPENSSL_VER((a),(b),(c),0,0)
-
 /** Length of the output of our message digest. */
 #define DIGEST_LEN 20
 /** Length of the output of our second (improved) message digests.  (For now
@@ -131,8 +98,6 @@ typedef struct crypto_xof_t crypto_xof_t;
 typedef struct crypto_dh_t crypto_dh_t;
 
 /* global state */
-const char * crypto_openssl_get_version_str(void);
-const char * crypto_openssl_get_header_version_str(void);
 int crypto_early_init(void) ATTR_WUR;
 int crypto_global_init(int hardwareAccel,
                        const char *accelName,
diff --git a/src/common/crypto_openssl.c b/src/common/crypto_openssl.c
new file mode 100644
index 000000000..03485c052
--- /dev/null
+++ b/src/common/crypto_openssl.c
@@ -0,0 +1,115 @@
+/* Copyright (c) 2001, Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2017, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+/**
+ * \file crypto_openssl.c
+ *
+ * \brief Block of functions related to operations from OpenSSL.
+ **/
+
+#include "crypto_openssl.h"
+
+#ifndef NEW_THREAD_API
+/** A number of preallocated mutexes for use by OpenSSL. */
+tor_mutex_t **openssl_mutexes_ = NULL;
+/** How many mutexes have we allocated for use by OpenSSL? */
+int n_openssl_mutexes_ = 0;
+#endif /* !defined(NEW_THREAD_API) */
+
+/* Returns a trimmed and human-readable version of an openssl version string
+* <b>raw_version</b>. They are usually in the form of 'OpenSSL 1.0.0b 10
+* May 2012' and this will parse them into a form similar to '1.0.0b' */
+char *
+parse_openssl_version_str(const char *raw_version)
+{
+  const char *end_of_version = NULL;
+  /* The output should be something like "OpenSSL 1.0.0b 10 May 2012. Let's
+     trim that down. */
+  if (!strcmpstart(raw_version, "OpenSSL ")) {
+    raw_version += strlen("OpenSSL ");
+    end_of_version = strchr(raw_version, ' ');
+  }
+
+  if (end_of_version)
+    return tor_strndup(raw_version,
+                      end_of_version-raw_version);
+  else
+    return tor_strdup(raw_version);
+}
+
+char *crypto_openssl_version_str = NULL;
+/* Return a human-readable version of the run-time openssl version number. */
+const char *
+crypto_openssl_get_version_str(void)
+{
+  if (crypto_openssl_version_str == NULL) {
+    const char *raw_version = OpenSSL_version(OPENSSL_VERSION);
+    crypto_openssl_version_str = parse_openssl_version_str(raw_version);
+  }
+  return crypto_openssl_version_str;
+}
+
+char *crypto_openssl_header_version_str = NULL;
+/* Return a human-readable version of the compile-time openssl version
+* number. */
+const char *
+crypto_openssl_get_header_version_str(void)
+{
+  if (crypto_openssl_header_version_str == NULL) {
+    crypto_openssl_header_version_str =
+                        parse_openssl_version_str(OPENSSL_VERSION_TEXT);
+  }
+  return crypto_openssl_header_version_str;
+}
+
+#ifndef OPENSSL_THREADS
+#error OpenSSL has been built without thread support. Tor requires an \
+ OpenSSL library with thread support enabled.
+#endif
+
+#ifndef NEW_THREAD_API
+/** Helper: OpenSSL uses this callback to manipulate mutexes. */
+void
+openssl_locking_cb_(int mode, int n, const char *file, int line)
+{
+  (void)file;
+  (void)line;
+  if (!openssl_mutexes_)
+    /* This is not a really good fix for the
+     * "release-freed-lock-from-separate-thread-on-shutdown" problem, but
+     * it can't hurt. */
+    return;
+  if (mode & CRYPTO_LOCK)
+    tor_mutex_acquire(openssl_mutexes_[n]);
+  else
+    tor_mutex_release(openssl_mutexes_[n]);
+}
+
+void
+tor_set_openssl_thread_id(CRYPTO_THREADID *threadid)
+{
+  CRYPTO_THREADID_set_numeric(threadid, tor_get_thread_id());
+}
+#endif /* !defined(NEW_THREAD_API) */
+
+/** Helper: Construct mutexes, and set callbacks to help OpenSSL handle being
+ * multithreaded. Returns 0. */
+int
+setup_openssl_threading(void)
+{
+#ifndef NEW_THREAD_API
+  int i;
+  int n = CRYPTO_num_locks();
+  n_openssl_mutexes_ = n;
+  openssl_mutexes_ = tor_calloc(n, sizeof(tor_mutex_t *));
+  for (i=0; i < n; ++i)
+    openssl_mutexes_[i] = tor_mutex_new();
+  CRYPTO_set_locking_callback(openssl_locking_cb_);
+  CRYPTO_THREADID_set_callback(tor_set_openssl_thread_id);
+#endif /* !defined(NEW_THREAD_API) */
+  return 0;
+}
+
diff --git a/src/common/crypto_openssl.h b/src/common/crypto_openssl.h
new file mode 100644
index 000000000..7b5545f69
--- /dev/null
+++ b/src/common/crypto_openssl.h
@@ -0,0 +1,105 @@
+/* Copyright (c) 2001, Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2017, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+/**
+ * \file crypto_openssl.h
+ *
+ * \brief Headers for crypto_openssl.c
+ **/
+
+#ifndef TOR_CRYPTO_OPENSSL_H
+#define TOR_CRYPTO_OPENSSL_H
+
+#include <stdio.h>
+#include "util.h"
+
+#include <openssl/engine.h>
+
+DISABLE_GCC_WARNING(redundant-decls)
+
+#include <openssl/err.h>
+#include <openssl/rsa.h>
+#include <openssl/pem.h>
+#include <openssl/evp.h>
+#include <openssl/engine.h>
+#include <openssl/rand.h>
+#include <openssl/bn.h>
+#include <openssl/dh.h>
+#include <openssl/conf.h>
+#include <openssl/hmac.h>
+
+ENABLE_GCC_WARNING(redundant-decls)
+
+/*
+  Macro to create an arbitrary OpenSSL version number as used by
+  OPENSSL_VERSION_NUMBER or SSLeay(), since the actual numbers are a bit hard
+  to read.
+
+  Don't use this directly, instead use one of the other OPENSSL_V macros
+  below.
+
+  The format is: 4 bits major, 8 bits minor, 8 bits fix, 8 bits patch, 4 bit
+  status.
+ */
+#define OPENSSL_VER(a,b,c,d,e)                                \
+  (((a)<<28) |                                                \
+   ((b)<<20) |                                                \
+   ((c)<<12) |                                                \
+   ((d)<< 4) |                                                \
+    (e))
+/** An openssl release number.  For example, OPENSSL_V(0,9,8,'j') is the
+ * version for the released version of 0.9.8j */
+#define OPENSSL_V(a,b,c,d) \
+  OPENSSL_VER((a),(b),(c),(d)-'a'+1,0xf)
+/** An openssl release number for the first release in the series.  For
+ * example, OPENSSL_V_NOPATCH(1,0,0) is the first released version of OpenSSL
+ * 1.0.0. */
+#define OPENSSL_V_NOPATCH(a,b,c) \
+  OPENSSL_VER((a),(b),(c),0,0xf)
+/** The first version that would occur for any alpha or beta in an openssl
+ * series. For example, OPENSSL_V_SERIES(0,9,8) is greater than any released
+ * 0.9.7, and less than any released 0.9.8. */
+#define OPENSSL_V_SERIES(a,b,c) \
+  OPENSSL_VER((a),(b),(c),0,0)
+
+#ifdef ANDROID
+/* Android's OpenSSL seems to have removed all of its Engine support. */
+#define DISABLE_ENGINES
+#endif
+
+#if OPENSSL_VERSION_NUMBER >= OPENSSL_VER(1,1,0,0,5) && \
+  !defined(LIBRESSL_VERSION_NUMBER)
+/* OpenSSL as of 1.1.0pre4 has an "new" thread API, which doesn't require
+ * seting up various callbacks.
+ *
+ * OpenSSL 1.1.0pre4 has a messed up `ERR_remove_thread_state()` prototype,
+ * while the previous one was restored in pre5, and the function made a no-op
+ * (along with a deprecated annotation, which produces a compiler warning).
+ *
+ * While it is possible to support all three versions of the thread API,
+ * a version that existed only for one snapshot pre-release is kind of
+ * pointless, so let's not.
+ */
+#define NEW_THREAD_API
+#endif /* OPENSSL_VERSION_NUMBER >= OPENSSL_VER(1,1,0,0,5) && ... */
+
+tor_mutex_t **openssl_mutexes_;
+int n_openssl_mutexes_;
+
+/* global openssl state */
+const char * crypto_openssl_get_version_str(void);
+const char * crypto_openssl_get_header_version_str(void);
+
+/* generics OpenSSL functions */
+char * parse_openssl_version_str(const char *raw_version);
+void openssl_locking_cb_(int mode, int n, const char *file, int line);
+void tor_set_openssl_thread_id(CRYPTO_THREADID *threadid);
+
+/* OpenSSL threading setup function */
+int setup_openssl_threading(void);
+
+#endif /* !defined(TOR_CRYPTO_OPENSSL_H) */
+





More information about the tor-commits mailing list