From 4156e4e93edb973ea5bad24a22bac97923cbd0ef Mon Sep 17 00:00:00 2001 From: Richard Aas Date: Wed, 8 Nov 2017 19:21:38 +0100 Subject: [PATCH] tls: use per connection bio_method (fixes issue #92) (#93) --- src/tls/openssl/tls.c | 16 ---------- src/tls/openssl/tls.h | 10 ------ src/tls/openssl/tls_tcp.c | 67 ++++++++++++++++++++++++--------------- src/tls/openssl/tls_udp.c | 66 ++++++++++++++++++++++++-------------- 4 files changed, 84 insertions(+), 75 deletions(-) diff --git a/src/tls/openssl/tls.c b/src/tls/openssl/tls.c index c82d937..8594ca5 100644 --- a/src/tls/openssl/tls.c +++ b/src/tls/openssl/tls.c @@ -52,13 +52,6 @@ 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 } @@ -200,15 +193,6 @@ 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 0466513..2c621d5 100644 --- a/src/tls/openssl/tls.h +++ b/src/tls/openssl/tls.h @@ -29,17 +29,7 @@ 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 dcf4172..ef3601e 100644 --- a/src/tls/openssl/tls_tcp.c +++ b/src/tls/openssl/tls_tcp.c @@ -27,6 +27,9 @@ /* NOTE: shadow struct defined in tls_*.c */ struct tls_conn { SSL *ssl; +#ifdef TLS_BIO_OPAQUE + BIO_METHOD *biomet; +#endif BIO *sbio_out; BIO *sbio_in; struct tcp_helper *th; @@ -47,6 +50,12 @@ static void destructor(void *arg) SSL_free(tc->ssl); } + +#ifdef TLS_BIO_OPAQUE + if (tc->biomet) + BIO_meth_free(tc->biomet); +#endif + mem_deref(tc->th); mem_deref(tc->tcp); } @@ -125,7 +134,29 @@ static long bio_ctrl(BIO *b, int cmd, long num, void *ptr) } -#ifndef TLS_BIO_OPAQUE +#ifdef TLS_BIO_OPAQUE + +static BIO_METHOD *bio_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; +} + +#else + static struct bio_method_st bio_tcp_send = { BIO_TYPE_SOURCE_SINK, "tcp_send", @@ -138,6 +169,7 @@ static struct bio_method_st bio_tcp_send = { bio_destroy, 0 }; + #endif @@ -347,6 +379,14 @@ int tls_start_tcp(struct tls_conn **ptc, struct tls *tls, struct tcp_conn *tcp, tc->tcp = mem_ref(tcp); +#ifdef TLS_BIO_OPAQUE + tc->biomet = bio_method_tcp(); + if (!tc->biomet) { + err = ENOMEM; + goto out; + } +#endif + err = ENOMEM; /* Connect the SSL socket */ @@ -366,7 +406,7 @@ int tls_start_tcp(struct tls_conn **ptc, struct tls *tls, struct tcp_conn *tcp, #ifdef TLS_BIO_OPAQUE - tc->sbio_out = BIO_new(tls->method_tcp); + tc->sbio_out = BIO_new(tc->biomet); #else tc->sbio_out = BIO_new(&bio_tcp_send); #endif @@ -395,26 +435,3 @@ 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 7d518fb..4ec81a3 100644 --- a/src/tls/openssl/tls_udp.c +++ b/src/tls/openssl/tls_udp.c @@ -47,6 +47,9 @@ struct dtls_sock { /* NOTE: shadow struct defined in tls_*.c */ struct tls_conn { SSL *ssl; /* inheritance */ +#ifdef TLS_BIO_OPAQUE + BIO_METHOD *biomet; +#endif BIO *sbio_out; BIO *sbio_in; struct tmr tmr; @@ -156,7 +159,29 @@ static long bio_ctrl(BIO *b, int cmd, long num, void *ptr) } -#ifndef TLS_BIO_OPAQUE +#ifdef TLS_BIO_OPAQUE + +static BIO_METHOD *bio_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; +} + +#else + static struct bio_method_st bio_udp_send = { BIO_TYPE_SOURCE_SINK, "udp_send", @@ -169,6 +194,7 @@ static struct bio_method_st bio_udp_send = { bio_destroy, 0 }; + #endif @@ -195,6 +221,12 @@ static void conn_destructor(void *arg) hash_unlink(&tc->he); tmr_cancel(&tc->tmr); tls_close(tc); + +#ifdef TLS_BIO_OPAQUE + if (tc->biomet) + BIO_meth_free(tc->biomet); +#endif + mem_deref(tc->sock); } @@ -448,6 +480,14 @@ static int conn_alloc(struct tls_conn **ptc, struct tls *tls, tc->closeh = closeh; tc->arg = arg; +#ifdef TLS_BIO_OPAQUE + tc->biomet = bio_method_udp(); + if (!tc->biomet) { + err = ENOMEM; + goto out; + } +#endif + /* Connect the SSL socket */ tc->ssl = SSL_new(tls->ctx); if (!tc->ssl) { @@ -466,7 +506,7 @@ static int conn_alloc(struct tls_conn **ptc, struct tls *tls, } #ifdef TLS_BIO_OPAQUE - tc->sbio_out = BIO_new(tls->method_udp); + tc->sbio_out = BIO_new(tc->biomet); #else tc->sbio_out = BIO_new(&bio_udp_send); #endif @@ -841,25 +881,3 @@ void dtls_recv_packet(struct dtls_sock *sock, const struct sa *src, recv_handler(&addr, mb, sock); } - - -#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