mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-11 05:33:47 +01:00
Merge remote-tracking branch 'ffmancera/bug24658-openssl'
This commit is contained in:
commit
13a2acba3c
@ -18,6 +18,7 @@
|
||||
|
||||
#include <openssl/opensslv.h>
|
||||
#include "crypto.h"
|
||||
#include "crypto_openssl_mgt.h"
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER < OPENSSL_V_SERIES(1,0,0)
|
||||
#error "We require OpenSSL >= 1.0.0"
|
||||
|
@ -8,7 +8,7 @@
|
||||
#define TOR_COMPAT_OPENSSL_H
|
||||
|
||||
#include <openssl/opensslv.h>
|
||||
|
||||
#include "crypto_openssl_mgt.h"
|
||||
/**
|
||||
* \file compat_openssl.h
|
||||
*
|
||||
|
@ -82,40 +82,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 +101,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 +191,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
|
||||
@ -3348,36 +3273,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.
|
||||
*/
|
||||
@ -3429,29 +3324,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.
|
||||
*/
|
||||
@ -3494,8 +3366,7 @@ crypto_global_cleanup(void)
|
||||
}
|
||||
#endif /* !defined(NEW_THREAD_API) */
|
||||
|
||||
tor_free(crypto_openssl_version_str);
|
||||
tor_free(crypto_openssl_header_version_str);
|
||||
crypto_openssl_free_all();
|
||||
|
||||
crypto_early_initialized_ = 0;
|
||||
crypto_global_initialized_ = 0;
|
||||
|
@ -21,41 +21,8 @@
|
||||
#include "compat.h"
|
||||
#include "util.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
|
||||
@ -132,8 +99,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,
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
#include "testsupport.h"
|
||||
#include "torint.h"
|
||||
#include "crypto_openssl_mgt.h"
|
||||
|
||||
/** Length of a curve25519 public key when encoded. */
|
||||
#define CURVE25519_PUBKEY_LEN 32
|
||||
|
145
src/common/crypto_openssl_mgt.c
Normal file
145
src/common/crypto_openssl_mgt.c
Normal file
@ -0,0 +1,145 @@
|
||||
/* 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_mgt.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)
|
||||
|
||||
#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) */
|
||||
|
||||
/** Declare STATIC functions */
|
||||
STATIC char * parse_openssl_version_str(const char *raw_version);
|
||||
#ifndef NEW_THREAD_API
|
||||
STATIC void openssl_locking_cb_(int mode, int n, const char *file, int line);
|
||||
STATIC void tor_set_openssl_thread_id(CRYPTO_THREADID *threadid);
|
||||
#endif
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
||||
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. */
|
||||
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) */
|
||||
|
||||
/** 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;
|
||||
}
|
||||
|
||||
/** free OpenSSL variables */
|
||||
void
|
||||
crypto_openssl_free_all(void)
|
||||
{
|
||||
tor_free(crypto_openssl_version_str);
|
||||
tor_free(crypto_openssl_header_version_str);
|
||||
}
|
||||
|
85
src/common/crypto_openssl_mgt.h
Normal file
85
src/common/crypto_openssl_mgt.h
Normal file
@ -0,0 +1,85 @@
|
||||
/* 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>
|
||||
|
||||
/*
|
||||
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) && ... */
|
||||
|
||||
/* global openssl state */
|
||||
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);
|
||||
|
||||
/* Tor OpenSSL utility functions */
|
||||
void crypto_openssl_free_all(void);
|
||||
|
||||
#endif /* !defined(TOR_CRYPTO_OPENSSL_H) */
|
||||
|
@ -113,6 +113,7 @@ LIBOR_CRYPTO_A_SRC = \
|
||||
src/common/compress_zlib.c \
|
||||
src/common/compress_zstd.c \
|
||||
src/common/crypto.c \
|
||||
src/common/crypto_openssl_mgt.c \
|
||||
src/common/crypto_pwbox.c \
|
||||
src/common/crypto_s2k.c \
|
||||
src/common/crypto_format.c \
|
||||
@ -164,6 +165,7 @@ COMMONHEADERS = \
|
||||
src/common/crypto_curve25519.h \
|
||||
src/common/crypto_ed25519.h \
|
||||
src/common/crypto_format.h \
|
||||
src/common/crypto_openssl_mgt.h \
|
||||
src/common/crypto_pwbox.h \
|
||||
src/common/crypto_s2k.h \
|
||||
src/common/di_ops.h \
|
||||
|
Loading…
Reference in New Issue
Block a user