diff --git a/src/aes/openssl/aes.c b/src/aes/openssl/aes.c index 195c911..3c9915f 100644 --- a/src/aes/openssl/aes.c +++ b/src/aes/openssl/aes.c @@ -17,7 +17,7 @@ struct aes { - EVP_CIPHER_CTX ctx; + EVP_CIPHER_CTX *ctx; }; @@ -25,7 +25,14 @@ static void destructor(void *arg) { struct aes *st = arg; - EVP_CIPHER_CTX_cleanup(&st->ctx); +#if OPENSSL_VERSION_NUMBER >= 0x10100000L + if (st->ctx) + EVP_CIPHER_CTX_free(st->ctx); +#else + if (st->ctx) + EVP_CIPHER_CTX_cleanup(st->ctx); + mem_deref(st->ctx); +#endif } @@ -47,7 +54,23 @@ int aes_alloc(struct aes **aesp, enum aes_mode mode, if (!st) return ENOMEM; - EVP_CIPHER_CTX_init(&st->ctx); +#if OPENSSL_VERSION_NUMBER >= 0x10100000L + st->ctx = EVP_CIPHER_CTX_new(); + if (!st->ctx) { + ERR_clear_error(); + err = ENOMEM; + goto out; + } + +#else + st->ctx = mem_zalloc(sizeof(*st->ctx), NULL); + if (!st->ctx) { + err = ENOMEM; + goto out; + } + + EVP_CIPHER_CTX_init(st->ctx); +#endif switch (key_bits) { @@ -60,7 +83,7 @@ int aes_alloc(struct aes **aesp, enum aes_mode mode, goto out; } - r = EVP_EncryptInit_ex(&st->ctx, cipher, NULL, key, iv); + r = EVP_EncryptInit_ex(st->ctx, cipher, NULL, key, iv); if (!r) { ERR_clear_error(); err = EPROTO; @@ -83,7 +106,7 @@ void aes_set_iv(struct aes *aes, const uint8_t iv[AES_BLOCK_SIZE]) if (!aes || !iv) return; - r = EVP_EncryptInit_ex(&aes->ctx, NULL, NULL, NULL, iv); + r = EVP_EncryptInit_ex(aes->ctx, NULL, NULL, NULL, iv); if (!r) ERR_clear_error(); } @@ -96,7 +119,7 @@ int aes_encr(struct aes *aes, uint8_t *out, const uint8_t *in, size_t len) if (!aes || !out || !in) return EINVAL; - if (!EVP_EncryptUpdate(&aes->ctx, out, &c_len, in, (int)len)) { + if (!EVP_EncryptUpdate(aes->ctx, out, &c_len, in, (int)len)) { ERR_clear_error(); return EPROTO; } diff --git a/src/hmac/openssl/hmac.c b/src/hmac/openssl/hmac.c index 4813f86..212567f 100644 --- a/src/hmac/openssl/hmac.c +++ b/src/hmac/openssl/hmac.c @@ -12,7 +12,7 @@ struct hmac { - HMAC_CTX ctx; + HMAC_CTX *ctx; }; @@ -20,7 +20,16 @@ static void destructor(void *arg) { struct hmac *hmac = arg; - HMAC_CTX_cleanup(&hmac->ctx); +#if OPENSSL_VERSION_NUMBER >= 0x10100000L && \ + !defined(LIBRESSL_VERSION_NUMBER) + + if (hmac->ctx) + HMAC_CTX_free(hmac->ctx); +#else + if (hmac->ctx) + HMAC_CTX_cleanup(hmac->ctx); + mem_deref(hmac->ctx); +#endif } @@ -52,17 +61,35 @@ int hmac_create(struct hmac **hmacp, enum hmac_hash hash, if (!hmac) return ENOMEM; - HMAC_CTX_init(&hmac->ctx); +#if OPENSSL_VERSION_NUMBER >= 0x10100000L && \ + !defined(LIBRESSL_VERSION_NUMBER) + + hmac->ctx = HMAC_CTX_new(); + if (!hmac->ctx) { + ERR_clear_error(); + err = ENOMEM; + goto out; + } +#else + hmac->ctx = mem_zalloc(sizeof(*hmac->ctx), NULL); + if (!hmac->ctx) { + err = ENOMEM; + goto out; + } + + HMAC_CTX_init(hmac->ctx); +#endif #if (OPENSSL_VERSION_NUMBER >= 0x00909000) - if (!HMAC_Init_ex(&hmac->ctx, key, (int)key_len, evp, NULL)) { + if (!HMAC_Init_ex(hmac->ctx, key, (int)key_len, evp, NULL)) { ERR_clear_error(); err = EPROTO; } #else - HMAC_Init_ex(&hmac->ctx, key, (int)key_len, evp, NULL); + HMAC_Init_ex(hmac->ctx, key, (int)key_len, evp, NULL); #endif + out: if (err) mem_deref(hmac); else @@ -82,12 +109,12 @@ int hmac_digest(struct hmac *hmac, uint8_t *md, size_t md_len, #if (OPENSSL_VERSION_NUMBER >= 0x00909000) /* the HMAC context must be reset here */ - if (!HMAC_Init_ex(&hmac->ctx, 0, 0, 0, NULL)) + if (!HMAC_Init_ex(hmac->ctx, 0, 0, 0, NULL)) goto error; - if (!HMAC_Update(&hmac->ctx, data, (int)data_len)) + if (!HMAC_Update(hmac->ctx, data, (int)data_len)) goto error; - if (!HMAC_Final(&hmac->ctx, md, &len)) + if (!HMAC_Final(hmac->ctx, md, &len)) goto error; return 0; @@ -98,10 +125,10 @@ int hmac_digest(struct hmac *hmac, uint8_t *md, size_t md_len, #else /* the HMAC context must be reset here */ - HMAC_Init_ex(&hmac->ctx, 0, 0, 0, NULL); + HMAC_Init_ex(hmac->ctx, 0, 0, 0, NULL); - HMAC_Update(&hmac->ctx, data, (int)data_len); - HMAC_Final(&hmac->ctx, md, &len); + HMAC_Update(hmac->ctx, data, (int)data_len); + HMAC_Final(hmac->ctx, md, &len); return 0; #endif diff --git a/src/main/openssl.c b/src/main/openssl.c index be86bdd..dfeb91e 100644 --- a/src/main/openssl.c +++ b/src/main/openssl.c @@ -18,7 +18,8 @@ #include "main.h" -#ifdef HAVE_PTHREAD +#if defined (HAVE_PTHREAD) && (OPENSSL_VERSION_NUMBER < 0x10100000L) + static pthread_mutex_t *lockv; @@ -58,9 +59,11 @@ static void locking_handler(int mode, int type, const char *file, int line) (void)pthread_mutex_unlock(&lockv[type]); } + #endif +#if OPENSSL_VERSION_NUMBER < 0x10100000L static struct CRYPTO_dynlock_value *dynlock_create_handler(const char *file, int line) { @@ -97,6 +100,7 @@ static void dynlock_destroy_handler(struct CRYPTO_dynlock_value *l, mem_deref(l); } +#endif #ifdef SIGPIPE @@ -110,7 +114,7 @@ static void sigpipe_handler(int x) int openssl_init(void) { -#ifdef HAVE_PTHREAD +#if defined (HAVE_PTHREAD) && (OPENSSL_VERSION_NUMBER < 0x10100000L) int err, i; lockv = mem_zalloc(sizeof(pthread_mutex_t) * CRYPTO_num_locks(), NULL); @@ -135,9 +139,11 @@ int openssl_init(void) CRYPTO_set_locking_callback(locking_handler); #endif +#if OPENSSL_VERSION_NUMBER < 0x10100000L CRYPTO_set_dynlock_create_callback(dynlock_create_handler); CRYPTO_set_dynlock_lock_callback(dynlock_lock_handler); CRYPTO_set_dynlock_destroy_callback(dynlock_destroy_handler); +#endif #ifdef SIGPIPE (void)signal(SIGPIPE, sigpipe_handler); @@ -153,7 +159,7 @@ int openssl_init(void) void openssl_close(void) { ERR_free_strings(); -#ifdef HAVE_PTHREAD +#if defined (HAVE_PTHREAD) && (OPENSSL_VERSION_NUMBER < 0x10100000L) lockv = mem_deref(lockv); #endif } diff --git a/src/tls/openssl/tls.c b/src/tls/openssl/tls.c index 671750c..31ae997 100644 --- a/src/tls/openssl/tls.c +++ b/src/tls/openssl/tls.c @@ -4,7 +4,6 @@ * Copyright (C) 2010 Creytiv.com */ #include -#define OPENSSL_NO_KRB5 1 #include #include #include @@ -45,6 +44,13 @@ static void destructor(void *data) X509_free(tls->cert); mem_deref(tls->pass); + +#ifdef TLS_BIO_OPAQUE + if (tls->method_tcp) + BIO_meth_free(tls->method_tcp); + if (tls->method_udp) + BIO_meth_free(tls->method_udp); +#endif } @@ -97,7 +103,13 @@ int tls_alloc(struct tls **tlsp, enum tls_method method, const char *keyfile, #ifdef USE_OPENSSL_DTLS case TLS_METHOD_DTLSV1: +#if OPENSSL_VERSION_NUMBER >= 0x10100000L && \ + !defined(LIBRESSL_VERSION_NUMBER) + + tls->ctx = SSL_CTX_new(DTLS_method()); +#else tls->ctx = SSL_CTX_new(DTLSv1_method()); +#endif break; #ifdef SSL_OP_NO_DTLSv1_2 @@ -108,7 +120,13 @@ int tls_alloc(struct tls **tlsp, enum tls_method method, const char *keyfile, break; case TLS_METHOD_DTLSV1_2: +#if OPENSSL_VERSION_NUMBER >= 0x10100000L && \ + !defined(LIBRESSL_VERSION_NUMBER) + + tls->ctx = SSL_CTX_new(DTLS_method()); +#else tls->ctx = SSL_CTX_new(DTLSv1_2_method()); +#endif break; #endif @@ -161,6 +179,15 @@ int tls_alloc(struct tls **tlsp, enum tls_method method, const char *keyfile, } } +#ifdef TLS_BIO_OPAQUE + tls->method_tcp = tls_method_tcp(); + tls->method_udp = tls_method_udp(); + if (!tls->method_tcp || !tls->method_udp) { + err = ENOMEM; + goto out; + } +#endif + err = 0; out: if (err) diff --git a/src/tls/openssl/tls.h b/src/tls/openssl/tls.h index d15c6f6..0466513 100644 --- a/src/tls/openssl/tls.h +++ b/src/tls/openssl/tls.h @@ -5,11 +5,41 @@ */ +/* + * Mapping of feature macros + */ + +#if OPENSSL_VERSION_NUMBER >= 0x10100000L +#define TLS_BIO_OPAQUE 1 +#endif + +#if defined (LIBRESSL_VERSION_NUMBER) +#undef TLS_BIO_OPAQUE +#endif + + +#if OPENSSL_VERSION_NUMBER >= 0x10100000L && \ + !defined(LIBRESSL_VERSION_NUMBER) +#define SSL_state SSL_get_state +#define SSL_ST_OK TLS_ST_OK +#endif + + struct tls { SSL_CTX *ctx; X509 *cert; char *pass; /* password for private key */ +#ifdef TLS_BIO_OPAQUE + BIO_METHOD *method_tcp; + BIO_METHOD *method_udp; +#endif }; +#ifdef TLS_BIO_OPAQUE +BIO_METHOD *tls_method_tcp(void); +BIO_METHOD *tls_method_udp(void); +#endif + + void tls_flush_error(void); diff --git a/src/tls/openssl/tls_tcp.c b/src/tls/openssl/tls_tcp.c index 215168d..dcf4172 100644 --- a/src/tls/openssl/tls_tcp.c +++ b/src/tls/openssl/tls_tcp.c @@ -3,7 +3,7 @@ * * Copyright (C) 2010 Creytiv.com */ -#define OPENSSL_NO_KRB5 1 + #include #include #include @@ -54,10 +54,16 @@ static void destructor(void *arg) static int bio_create(BIO *b) { +#ifdef TLS_BIO_OPAQUE + BIO_set_init(b, 1); + BIO_set_data(b, NULL); + BIO_set_flags(b, 0); +#else b->init = 1; b->num = 0; b->ptr = NULL; b->flags = 0; +#endif return 1; } @@ -68,9 +74,15 @@ static int bio_destroy(BIO *b) if (!b) return 0; +#ifdef TLS_BIO_OPAQUE + BIO_set_init(b, 0); + BIO_set_data(b, NULL); + BIO_set_flags(b, 0); +#else b->ptr = NULL; b->init = 0; b->flags = 0; +#endif return 1; } @@ -78,7 +90,11 @@ static int bio_destroy(BIO *b) static int bio_write(BIO *b, const char *buf, int len) { +#ifdef TLS_BIO_OPAQUE + struct tls_conn *tc = BIO_get_data(b); +#else struct tls_conn *tc = b->ptr; +#endif struct mbuf mb; int err; @@ -109,6 +125,7 @@ static long bio_ctrl(BIO *b, int cmd, long num, void *ptr) } +#ifndef TLS_BIO_OPAQUE static struct bio_method_st bio_tcp_send = { BIO_TYPE_SOURCE_SINK, "tcp_send", @@ -121,6 +138,7 @@ static struct bio_method_st bio_tcp_send = { bio_destroy, 0 }; +#endif static int tls_connect(struct tls_conn *tc) @@ -346,7 +364,12 @@ int tls_start_tcp(struct tls_conn **ptc, struct tls *tls, struct tcp_conn *tcp, goto out; } + +#ifdef TLS_BIO_OPAQUE + tc->sbio_out = BIO_new(tls->method_tcp); +#else tc->sbio_out = BIO_new(&bio_tcp_send); +#endif if (!tc->sbio_out) { DEBUG_WARNING("alloc: BIO_new_socket() failed\n"); ERR_clear_error(); @@ -354,7 +377,11 @@ int tls_start_tcp(struct tls_conn **ptc, struct tls *tls, struct tcp_conn *tcp, goto out; } +#ifdef TLS_BIO_OPAQUE + BIO_set_data(tc->sbio_out, tc); +#else tc->sbio_out->ptr = tc; +#endif SSL_set_bio(tc->ssl, tc->sbio_in, tc->sbio_out); @@ -368,3 +395,26 @@ int tls_start_tcp(struct tls_conn **ptc, struct tls *tls, struct tcp_conn *tcp, return err; } + + +#ifdef TLS_BIO_OPAQUE + +BIO_METHOD *tls_method_tcp(void) +{ + BIO_METHOD *method; + + method = BIO_meth_new(BIO_TYPE_SOURCE_SINK, "tcp_send"); + if (!method) { + DEBUG_WARNING("alloc: BIO_meth_new() failed\n"); + ERR_clear_error(); + return NULL; + } + + BIO_meth_set_write(method, bio_write); + BIO_meth_set_ctrl(method, bio_ctrl); + BIO_meth_set_create(method, bio_create); + BIO_meth_set_destroy(method, bio_destroy); + + return method; +} +#endif diff --git a/src/tls/openssl/tls_udp.c b/src/tls/openssl/tls_udp.c index 4a2e980..a073b33 100644 --- a/src/tls/openssl/tls_udp.c +++ b/src/tls/openssl/tls_udp.c @@ -3,7 +3,8 @@ * * Copyright (C) 2010 Creytiv.com */ -#define OPENSSL_NO_KRB5 1 + +#include #include #include #include @@ -63,10 +64,16 @@ struct tls_conn { static int bio_create(BIO *b) { +#ifdef TLS_BIO_OPAQUE + BIO_set_init(b, 1); + BIO_set_data(b, NULL); + BIO_set_flags(b, 0); +#else b->init = 1; b->num = 0; b->ptr = NULL; b->flags = 0; +#endif return 1; } @@ -77,9 +84,15 @@ static int bio_destroy(BIO *b) if (!b) return 0; +#ifdef TLS_BIO_OPAQUE + BIO_set_init(b, 0); + BIO_set_data(b, NULL); + BIO_set_flags(b, 0); +#else b->ptr = NULL; b->init = 0; b->flags = 0; +#endif return 1; } @@ -87,7 +100,11 @@ static int bio_destroy(BIO *b) static int bio_write(BIO *b, const char *buf, int len) { +#ifdef TLS_BIO_OPAQUE + struct tls_conn *tc = BIO_get_data(b); +#else struct tls_conn *tc = b->ptr; +#endif struct mbuf *mb; enum {SPACE = 4}; int err; @@ -110,7 +127,11 @@ static int bio_write(BIO *b, const char *buf, int len) static long bio_ctrl(BIO *b, int cmd, long num, void *ptr) { +#ifdef TLS_BIO_OPAQUE + struct tls_conn *tc = BIO_get_data(b); +#else struct tls_conn *tc = b->ptr; +#endif (void)num; (void)ptr; @@ -135,6 +156,7 @@ static long bio_ctrl(BIO *b, int cmd, long num, void *ptr) } +#ifndef TLS_BIO_OPAQUE static struct bio_method_st bio_udp_send = { BIO_TYPE_SOURCE_SINK, "udp_send", @@ -147,6 +169,7 @@ static struct bio_method_st bio_udp_send = { bio_destroy, 0 }; +#endif static void tls_close(struct tls_conn *tc) @@ -442,7 +465,11 @@ static int conn_alloc(struct tls_conn **ptc, struct tls *tls, goto out; } +#ifdef TLS_BIO_OPAQUE + tc->sbio_out = BIO_new(tls->method_udp); +#else tc->sbio_out = BIO_new(&bio_udp_send); +#endif if (!tc->sbio_out) { ERR_clear_error(); BIO_free(tc->sbio_in); @@ -450,7 +477,11 @@ static int conn_alloc(struct tls_conn **ptc, struct tls *tls, goto out; } +#ifdef TLS_BIO_OPAQUE + BIO_set_data(tc->sbio_out, tc); +#else tc->sbio_out->ptr = tc; +#endif SSL_set_bio(tc->ssl, tc->sbio_in, tc->sbio_out); @@ -765,3 +796,25 @@ void dtls_set_mtu(struct dtls_sock *sock, size_t mtu) sock->mtu = mtu; } + + +#ifdef TLS_BIO_OPAQUE +BIO_METHOD *tls_method_udp(void) +{ + BIO_METHOD *method; + + method = BIO_meth_new(BIO_TYPE_SOURCE_SINK, "udp_send"); + if (!method) { + DEBUG_WARNING("alloc: BIO_meth_new() failed\n"); + ERR_clear_error(); + return NULL; + } + + BIO_meth_set_write(method, bio_write); + BIO_meth_set_ctrl(method, bio_ctrl); + BIO_meth_set_create(method, bio_create); + BIO_meth_set_destroy(method, bio_destroy); + + return method; +} +#endif