-/* $OpenBSD: tls_bio_cb.c,v 1.19 2017/01/12 16:18:39 jsing Exp $ */
+/* $OpenBSD: tls_bio_cb.c,v 1.20 2022/01/10 23:39:48 tb Exp $ */
/*
* Copyright (c) 2016 Tobias Pape <tobias@netshed.de>
*
static int bio_cb_puts(BIO *bio, const char *str);
static long bio_cb_ctrl(BIO *bio, int cmd, long num, void *ptr);
-static BIO_METHOD bio_cb_method = {
- .type = BIO_TYPE_MEM,
- .name = "libtls_callbacks",
- .bwrite = bio_cb_write,
- .bread = bio_cb_read,
- .bputs = bio_cb_puts,
- .ctrl = bio_cb_ctrl,
-};
+static BIO_METHOD *bio_cb_method;
+
+static pthread_mutex_t bio_cb_method_lock = PTHREAD_MUTEX_INITIALIZER;
+
+static void
+bio_cb_method_init(void)
+{
+ BIO_METHOD *bio_method;
+
+ if (bio_cb_method != NULL)
+ return;
+
+ bio_method = BIO_meth_new(BIO_TYPE_MEM, "libtls_callbacks");
+ if (bio_method == NULL)
+ return;
+
+ BIO_meth_set_write(bio_method, bio_cb_write);
+ BIO_meth_set_read(bio_method, bio_cb_read);
+ BIO_meth_set_puts(bio_method, bio_cb_puts);
+ BIO_meth_set_ctrl(bio_method, bio_cb_ctrl);
+
+ bio_cb_method = bio_method;
+}
static BIO_METHOD *
bio_s_cb(void)
{
- return (&bio_cb_method);
+ if (bio_cb_method != NULL)
+ return (bio_cb_method);
+
+ pthread_mutex_lock(&bio_cb_method_lock);
+ bio_cb_method_init();
+ pthread_mutex_unlock(&bio_cb_method_lock);
+
+ return (bio_cb_method);
}
static int
switch (cmd) {
case BIO_CTRL_GET_CLOSE:
- ret = (long)bio->shutdown;
+ ret = (long)BIO_get_shutdown(bio);
break;
case BIO_CTRL_SET_CLOSE:
- bio->shutdown = (int)num;
+ BIO_set_shutdown(bio, (int)num);
break;
case BIO_CTRL_DUP:
case BIO_CTRL_FLUSH:
case BIO_CTRL_GET:
case BIO_CTRL_SET:
default:
- ret = BIO_ctrl(bio->next_bio, cmd, num, ptr);
+ ret = BIO_ctrl(BIO_next(bio), cmd, num, ptr);
}
return (ret);
static int
bio_cb_write(BIO *bio, const char *buf, int num)
{
- struct tls *ctx = bio->ptr;
+ struct tls *ctx = BIO_get_data(bio);
int rv;
BIO_clear_retry_flags(bio);
static int
bio_cb_read(BIO *bio, char *buf, int size)
{
- struct tls *ctx = bio->ptr;
+ struct tls *ctx = BIO_get_data(bio);
int rv;
BIO_clear_retry_flags(bio);
tls_set_cbs(struct tls *ctx, tls_read_cb read_cb, tls_write_cb write_cb,
void *cb_arg)
{
- int rv = -1;
+ const BIO_METHOD *bio_cb;
BIO *bio;
+ int rv = -1;
if (read_cb == NULL || write_cb == NULL) {
tls_set_errorx(ctx, "no callbacks provided");
ctx->write_cb = write_cb;
ctx->cb_arg = cb_arg;
- if ((bio = BIO_new(bio_s_cb())) == NULL) {
+ if ((bio_cb = bio_s_cb()) == NULL) {
+ tls_set_errorx(ctx, "failed to create callback method");
+ goto err;
+ }
+ if ((bio = BIO_new(bio_cb)) == NULL) {
tls_set_errorx(ctx, "failed to create callback i/o");
goto err;
}
- bio->ptr = ctx;
- bio->init = 1;
+ BIO_set_data(bio, ctx);
+ BIO_set_init(bio, 1);
SSL_set_bio(ctx->ssl_conn, bio, bio);