tls: use per connection bio_method (fixes issue #92) (#93)

This commit is contained in:
Richard Aas 2017-11-08 19:21:38 +01:00 committed by Alfred E. Heggestad
parent 29cfc5225e
commit 4156e4e93e
4 changed files with 84 additions and 75 deletions

View file

@ -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)

View file

@ -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);

View file

@ -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

View file

@ -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