1 f9ab77a8 2023-08-23 op /* $OpenBSD: tls_bio_cb.c,v 1.21 2023/05/14 07:26:25 op Exp $ */
3 f9ab77a8 2023-08-23 op * Copyright (c) 2016 Tobias Pape <tobias@netshed.de>
5 f9ab77a8 2023-08-23 op * Permission to use, copy, modify, and distribute this software for any
6 f9ab77a8 2023-08-23 op * purpose with or without fee is hereby granted, provided that the above
7 f9ab77a8 2023-08-23 op * copyright notice and this permission notice appear in all copies.
9 f9ab77a8 2023-08-23 op * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 f9ab77a8 2023-08-23 op * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 f9ab77a8 2023-08-23 op * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 f9ab77a8 2023-08-23 op * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 f9ab77a8 2023-08-23 op * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 f9ab77a8 2023-08-23 op * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 f9ab77a8 2023-08-23 op * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 f9ab77a8 2023-08-23 op #include "config.h"
20 f9ab77a8 2023-08-23 op #include <fcntl.h>
21 f9ab77a8 2023-08-23 op #include <stdlib.h>
22 f9ab77a8 2023-08-23 op #include <string.h>
23 f9ab77a8 2023-08-23 op #include <unistd.h>
25 f9ab77a8 2023-08-23 op #include <openssl/bio.h>
27 f9ab77a8 2023-08-23 op #include <tls.h>
28 f9ab77a8 2023-08-23 op #include "tls_internal.h"
30 f9ab77a8 2023-08-23 op static int bio_cb_write(BIO *bio, const char *buf, int num);
31 f9ab77a8 2023-08-23 op static int bio_cb_read(BIO *bio, char *buf, int size);
32 f9ab77a8 2023-08-23 op static int bio_cb_puts(BIO *bio, const char *str);
33 f9ab77a8 2023-08-23 op static long bio_cb_ctrl(BIO *bio, int cmd, long num, void *ptr);
35 f9ab77a8 2023-08-23 op static BIO_METHOD *bio_cb_method;
38 f9ab77a8 2023-08-23 op bio_cb_method_init(void)
40 f9ab77a8 2023-08-23 op BIO_METHOD *bio_method;
42 f9ab77a8 2023-08-23 op if (bio_cb_method != NULL)
45 f9ab77a8 2023-08-23 op bio_method = BIO_meth_new(BIO_TYPE_MEM, "libtls_callbacks");
46 f9ab77a8 2023-08-23 op if (bio_method == NULL)
49 f9ab77a8 2023-08-23 op BIO_meth_set_write(bio_method, bio_cb_write);
50 f9ab77a8 2023-08-23 op BIO_meth_set_read(bio_method, bio_cb_read);
51 f9ab77a8 2023-08-23 op BIO_meth_set_puts(bio_method, bio_cb_puts);
52 f9ab77a8 2023-08-23 op BIO_meth_set_ctrl(bio_method, bio_cb_ctrl);
54 f9ab77a8 2023-08-23 op bio_cb_method = bio_method;
57 f9ab77a8 2023-08-23 op static BIO_METHOD *
58 f9ab77a8 2023-08-23 op bio_s_cb(void)
60 f9ab77a8 2023-08-23 op if (bio_cb_method != NULL)
61 f9ab77a8 2023-08-23 op return (bio_cb_method);
63 f9ab77a8 2023-08-23 op bio_cb_method_init();
65 f9ab77a8 2023-08-23 op return (bio_cb_method);
69 f9ab77a8 2023-08-23 op bio_cb_puts(BIO *bio, const char *str)
71 f9ab77a8 2023-08-23 op return (bio_cb_write(bio, str, strlen(str)));
75 f9ab77a8 2023-08-23 op bio_cb_ctrl(BIO *bio, int cmd, long num, void *ptr)
79 f9ab77a8 2023-08-23 op switch (cmd) {
80 f9ab77a8 2023-08-23 op case BIO_CTRL_GET_CLOSE:
81 f9ab77a8 2023-08-23 op ret = (long)BIO_get_shutdown(bio);
83 f9ab77a8 2023-08-23 op case BIO_CTRL_SET_CLOSE:
84 f9ab77a8 2023-08-23 op BIO_set_shutdown(bio, (int)num);
86 f9ab77a8 2023-08-23 op case BIO_CTRL_DUP:
87 f9ab77a8 2023-08-23 op case BIO_CTRL_FLUSH:
89 f9ab77a8 2023-08-23 op case BIO_CTRL_INFO:
90 f9ab77a8 2023-08-23 op case BIO_CTRL_GET:
91 f9ab77a8 2023-08-23 op case BIO_CTRL_SET:
93 f9ab77a8 2023-08-23 op ret = BIO_ctrl(BIO_next(bio), cmd, num, ptr);
100 f9ab77a8 2023-08-23 op bio_cb_write(BIO *bio, const char *buf, int num)
102 f9ab77a8 2023-08-23 op struct tls *ctx = BIO_get_data(bio);
105 f9ab77a8 2023-08-23 op BIO_clear_retry_flags(bio);
106 f9ab77a8 2023-08-23 op rv = (ctx->write_cb)(ctx, buf, num, ctx->cb_arg);
107 f9ab77a8 2023-08-23 op if (rv == TLS_WANT_POLLIN) {
108 f9ab77a8 2023-08-23 op BIO_set_retry_read(bio);
110 f9ab77a8 2023-08-23 op } else if (rv == TLS_WANT_POLLOUT) {
111 f9ab77a8 2023-08-23 op BIO_set_retry_write(bio);
118 f9ab77a8 2023-08-23 op bio_cb_read(BIO *bio, char *buf, int size)
120 f9ab77a8 2023-08-23 op struct tls *ctx = BIO_get_data(bio);
123 f9ab77a8 2023-08-23 op BIO_clear_retry_flags(bio);
124 f9ab77a8 2023-08-23 op rv = (ctx->read_cb)(ctx, buf, size, ctx->cb_arg);
125 f9ab77a8 2023-08-23 op if (rv == TLS_WANT_POLLIN) {
126 f9ab77a8 2023-08-23 op BIO_set_retry_read(bio);
128 f9ab77a8 2023-08-23 op } else if (rv == TLS_WANT_POLLOUT) {
129 f9ab77a8 2023-08-23 op BIO_set_retry_write(bio);
136 f9ab77a8 2023-08-23 op tls_set_cbs(struct tls *ctx, tls_read_cb read_cb, tls_write_cb write_cb,
137 f9ab77a8 2023-08-23 op void *cb_arg)
139 f9ab77a8 2023-08-23 op const BIO_METHOD *bio_cb;
143 f9ab77a8 2023-08-23 op if (read_cb == NULL || write_cb == NULL) {
144 f9ab77a8 2023-08-23 op tls_set_errorx(ctx, "no callbacks provided");
148 f9ab77a8 2023-08-23 op ctx->read_cb = read_cb;
149 f9ab77a8 2023-08-23 op ctx->write_cb = write_cb;
150 f9ab77a8 2023-08-23 op ctx->cb_arg = cb_arg;
152 f9ab77a8 2023-08-23 op if ((bio_cb = bio_s_cb()) == NULL) {
153 f9ab77a8 2023-08-23 op tls_set_errorx(ctx, "failed to create callback method");
156 f9ab77a8 2023-08-23 op if ((bio = BIO_new(bio_cb)) == NULL) {
157 f9ab77a8 2023-08-23 op tls_set_errorx(ctx, "failed to create callback i/o");
160 f9ab77a8 2023-08-23 op BIO_set_data(bio, ctx);
161 f9ab77a8 2023-08-23 op BIO_set_init(bio, 1);
163 f9ab77a8 2023-08-23 op SSL_set_bio(ctx->ssl_conn, bio, bio);