Skip to content

Commit

Permalink
openssl: separate legacy api
Browse files Browse the repository at this point in the history
Refactor the OpenSSL stream implementation so that the legacy code is better
abstracted.  This will enable future development.
  • Loading branch information
ethomson committed Aug 24, 2021
1 parent a09d436 commit 150eddd
Show file tree
Hide file tree
Showing 3 changed files with 249 additions and 188 deletions.
194 changes: 6 additions & 188 deletions src/streams/openssl.c
Expand Up @@ -6,6 +6,7 @@
*/

#include "streams/openssl.h"
#include "streams/openssl_legacy.h"

#ifdef GIT_OPENSSL

Expand Down Expand Up @@ -35,147 +36,6 @@ SSL_CTX *git__ssl_ctx;

#define GIT_SSL_DEFAULT_CIPHERS "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-DSS-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA:DHE-DSS-AES128-SHA256:DHE-DSS-AES256-SHA256:DHE-DSS-AES128-SHA:DHE-DSS-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA"

#if (defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER < 0x10100000L) || \
(defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x20700000L)
# define OPENSSL_LEGACY_API
#endif

/*
* OpenSSL 1.1 made BIO opaque so we have to use functions to interact with it
* which do not exist in previous versions. We define these inline functions so
* we can program against the interface instead of littering the implementation
* with ifdefs. We do the same for OPENSSL_init_ssl.
*/
#if defined(OPENSSL_LEGACY_API)
static int OPENSSL_init_ssl(int opts, void *settings)
{
GIT_UNUSED(opts);
GIT_UNUSED(settings);
SSL_load_error_strings();
OpenSSL_add_ssl_algorithms();
return 0;
}

static BIO_METHOD* BIO_meth_new(int type, const char *name)
{
BIO_METHOD *meth = git__calloc(1, sizeof(BIO_METHOD));
if (!meth) {
return NULL;
}

meth->type = type;
meth->name = name;

return meth;
}

static void BIO_meth_free(BIO_METHOD *biom)
{
git__free(biom);
}

static int BIO_meth_set_write(BIO_METHOD *biom, int (*write) (BIO *, const char *, int))
{
biom->bwrite = write;
return 1;
}

static int BIO_meth_set_read(BIO_METHOD *biom, int (*read) (BIO *, char *, int))
{
biom->bread = read;
return 1;
}

static int BIO_meth_set_puts(BIO_METHOD *biom, int (*puts) (BIO *, const char *))
{
biom->bputs = puts;
return 1;
}

static int BIO_meth_set_gets(BIO_METHOD *biom, int (*gets) (BIO *, char *, int))

{
biom->bgets = gets;
return 1;
}

static int BIO_meth_set_ctrl(BIO_METHOD *biom, long (*ctrl) (BIO *, int, long, void *))
{
biom->ctrl = ctrl;
return 1;
}

static int BIO_meth_set_create(BIO_METHOD *biom, int (*create) (BIO *))
{
biom->create = create;
return 1;
}

static int BIO_meth_set_destroy(BIO_METHOD *biom, int (*destroy) (BIO *))
{
biom->destroy = destroy;
return 1;
}

static int BIO_get_new_index(void)
{
/* This exists as of 1.1 so before we'd just have 0 */
return 0;
}

static void BIO_set_init(BIO *b, int init)
{
b->init = init;
}

static void BIO_set_data(BIO *a, void *ptr)
{
a->ptr = ptr;
}

static void *BIO_get_data(BIO *a)
{
return a->ptr;
}

static const unsigned char *ASN1_STRING_get0_data(const ASN1_STRING *x)
{
return ASN1_STRING_data((ASN1_STRING *)x);
}

# if defined(GIT_THREADS)
static git_mutex *openssl_locks;

static void openssl_locking_function(
int mode, int n, const char *file, int line)
{
int lock;

GIT_UNUSED(file);
GIT_UNUSED(line);

lock = mode & CRYPTO_LOCK;

if (lock) {
(void)git_mutex_lock(&openssl_locks[n]);
} else {
git_mutex_unlock(&openssl_locks[n]);
}
}

static void shutdown_ssl_locking(void)
{
int num_locks, i;

num_locks = CRYPTO_num_locks();
CRYPTO_set_locking_callback(NULL);

for (i = 0; i < num_locks; ++i)
git_mutex_free(&openssl_locks[i]);
git__free(openssl_locks);
}
# endif /* GIT_THREADS */
#endif /* OPENSSL_LEGACY_API */

static BIO_METHOD *git_stream_bio_method;
static int init_bio_method(void);
Expand All @@ -198,22 +58,6 @@ static void shutdown_ssl(void)
}

#ifdef VALGRIND
#ifdef OPENSSL_LEGACY_API
static void *git_openssl_malloc(size_t bytes)
{
return git__calloc(1, bytes);
}

static void *git_openssl_realloc(void *mem, size_t size)
{
return git__realloc(mem, size);
}

static void git_openssl_free(void *mem)
{
return git__free(mem);
}
#else
static void *git_openssl_malloc(size_t bytes, const char *file, int line)
{
GIT_UNUSED(file);
Expand All @@ -235,7 +79,6 @@ static void git_openssl_free(void *mem, const char *file, int line)
return git__free(mem);
}
#endif
#endif

int git_openssl_stream_global_init(void)
{
Expand Down Expand Up @@ -301,42 +144,17 @@ int git_openssl_stream_global_init(void)
return -1;
}

#if defined(GIT_THREADS) && defined(OPENSSL_LEGACY_API)
static void threadid_cb(CRYPTO_THREADID *threadid)
{
GIT_UNUSED(threadid);
CRYPTO_THREADID_set_numeric(threadid, git_thread_currentid());
}
#endif

#ifndef GIT_OPENSSL_LEGACY
int git_openssl_set_locking(void)
{
#if defined(GIT_THREADS) && defined(OPENSSL_LEGACY_API)
int num_locks, i;

CRYPTO_THREADID_set_callback(threadid_cb);

num_locks = CRYPTO_num_locks();
openssl_locks = git__calloc(num_locks, sizeof(git_mutex));
GIT_ERROR_CHECK_ALLOC(openssl_locks);

for (i = 0; i < num_locks; i++) {
if (git_mutex_init(&openssl_locks[i]) != 0) {
git_error_set(GIT_ERROR_SSL, "failed to initialize openssl locks");
return -1;
}
}

CRYPTO_set_locking_callback(openssl_locking_function);
return git_runtime_shutdown_register(shutdown_ssl_locking);

#elif !defined(OPENSSL_LEGACY_API)
# ifdef GIT_THREADS
return 0;
#else
# else
git_error_set(GIT_ERROR_THREAD, "libgit2 was not built with threads");
return -1;
#endif
# endif
}
#endif


static int bio_create(BIO *b)
Expand Down

0 comments on commit 150eddd

Please sign in to comment.