Blame


1 f9ab77a8 2023-08-23 op /* $OpenBSD: tls_bio_cb.c,v 1.21 2023/05/14 07:26:25 op Exp $ */
2 f9ab77a8 2023-08-23 op /*
3 f9ab77a8 2023-08-23 op * Copyright (c) 2016 Tobias Pape <tobias@netshed.de>
4 f9ab77a8 2023-08-23 op *
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.
8 f9ab77a8 2023-08-23 op *
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.
16 f9ab77a8 2023-08-23 op */
17 f9ab77a8 2023-08-23 op
18 f9ab77a8 2023-08-23 op #include "config.h"
19 f9ab77a8 2023-08-23 op
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>
24 f9ab77a8 2023-08-23 op
25 f9ab77a8 2023-08-23 op #include <openssl/bio.h>
26 f9ab77a8 2023-08-23 op
27 f9ab77a8 2023-08-23 op #include <tls.h>
28 f9ab77a8 2023-08-23 op #include "tls_internal.h"
29 f9ab77a8 2023-08-23 op
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);
34 f9ab77a8 2023-08-23 op
35 f9ab77a8 2023-08-23 op static BIO_METHOD *bio_cb_method;
36 f9ab77a8 2023-08-23 op
37 f9ab77a8 2023-08-23 op static void
38 f9ab77a8 2023-08-23 op bio_cb_method_init(void)
39 f9ab77a8 2023-08-23 op {
40 f9ab77a8 2023-08-23 op BIO_METHOD *bio_method;
41 f9ab77a8 2023-08-23 op
42 f9ab77a8 2023-08-23 op if (bio_cb_method != NULL)
43 f9ab77a8 2023-08-23 op return;
44 f9ab77a8 2023-08-23 op
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)
47 f9ab77a8 2023-08-23 op return;
48 f9ab77a8 2023-08-23 op
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);
53 f9ab77a8 2023-08-23 op
54 f9ab77a8 2023-08-23 op bio_cb_method = bio_method;
55 f9ab77a8 2023-08-23 op }
56 f9ab77a8 2023-08-23 op
57 f9ab77a8 2023-08-23 op static BIO_METHOD *
58 f9ab77a8 2023-08-23 op bio_s_cb(void)
59 f9ab77a8 2023-08-23 op {
60 f9ab77a8 2023-08-23 op if (bio_cb_method != NULL)
61 f9ab77a8 2023-08-23 op return (bio_cb_method);
62 f9ab77a8 2023-08-23 op
63 f9ab77a8 2023-08-23 op bio_cb_method_init();
64 f9ab77a8 2023-08-23 op
65 f9ab77a8 2023-08-23 op return (bio_cb_method);
66 f9ab77a8 2023-08-23 op }
67 f9ab77a8 2023-08-23 op
68 f9ab77a8 2023-08-23 op static int
69 f9ab77a8 2023-08-23 op bio_cb_puts(BIO *bio, const char *str)
70 f9ab77a8 2023-08-23 op {
71 f9ab77a8 2023-08-23 op return (bio_cb_write(bio, str, strlen(str)));
72 f9ab77a8 2023-08-23 op }
73 f9ab77a8 2023-08-23 op
74 f9ab77a8 2023-08-23 op static long
75 f9ab77a8 2023-08-23 op bio_cb_ctrl(BIO *bio, int cmd, long num, void *ptr)
76 f9ab77a8 2023-08-23 op {
77 f9ab77a8 2023-08-23 op long ret = 1;
78 f9ab77a8 2023-08-23 op
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);
82 f9ab77a8 2023-08-23 op break;
83 f9ab77a8 2023-08-23 op case BIO_CTRL_SET_CLOSE:
84 f9ab77a8 2023-08-23 op BIO_set_shutdown(bio, (int)num);
85 f9ab77a8 2023-08-23 op break;
86 f9ab77a8 2023-08-23 op case BIO_CTRL_DUP:
87 f9ab77a8 2023-08-23 op case BIO_CTRL_FLUSH:
88 f9ab77a8 2023-08-23 op break;
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:
92 f9ab77a8 2023-08-23 op default:
93 f9ab77a8 2023-08-23 op ret = BIO_ctrl(BIO_next(bio), cmd, num, ptr);
94 f9ab77a8 2023-08-23 op }
95 f9ab77a8 2023-08-23 op
96 f9ab77a8 2023-08-23 op return (ret);
97 f9ab77a8 2023-08-23 op }
98 f9ab77a8 2023-08-23 op
99 f9ab77a8 2023-08-23 op static int
100 f9ab77a8 2023-08-23 op bio_cb_write(BIO *bio, const char *buf, int num)
101 f9ab77a8 2023-08-23 op {
102 f9ab77a8 2023-08-23 op struct tls *ctx = BIO_get_data(bio);
103 f9ab77a8 2023-08-23 op int rv;
104 f9ab77a8 2023-08-23 op
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);
109 f9ab77a8 2023-08-23 op rv = -1;
110 f9ab77a8 2023-08-23 op } else if (rv == TLS_WANT_POLLOUT) {
111 f9ab77a8 2023-08-23 op BIO_set_retry_write(bio);
112 f9ab77a8 2023-08-23 op rv = -1;
113 f9ab77a8 2023-08-23 op }
114 f9ab77a8 2023-08-23 op return (rv);
115 f9ab77a8 2023-08-23 op }
116 f9ab77a8 2023-08-23 op
117 f9ab77a8 2023-08-23 op static int
118 f9ab77a8 2023-08-23 op bio_cb_read(BIO *bio, char *buf, int size)
119 f9ab77a8 2023-08-23 op {
120 f9ab77a8 2023-08-23 op struct tls *ctx = BIO_get_data(bio);
121 f9ab77a8 2023-08-23 op int rv;
122 f9ab77a8 2023-08-23 op
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);
127 f9ab77a8 2023-08-23 op rv = -1;
128 f9ab77a8 2023-08-23 op } else if (rv == TLS_WANT_POLLOUT) {
129 f9ab77a8 2023-08-23 op BIO_set_retry_write(bio);
130 f9ab77a8 2023-08-23 op rv = -1;
131 f9ab77a8 2023-08-23 op }
132 f9ab77a8 2023-08-23 op return (rv);
133 f9ab77a8 2023-08-23 op }
134 f9ab77a8 2023-08-23 op
135 f9ab77a8 2023-08-23 op int
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)
138 f9ab77a8 2023-08-23 op {
139 f9ab77a8 2023-08-23 op const BIO_METHOD *bio_cb;
140 f9ab77a8 2023-08-23 op BIO *bio;
141 f9ab77a8 2023-08-23 op int rv = -1;
142 f9ab77a8 2023-08-23 op
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");
145 f9ab77a8 2023-08-23 op goto err;
146 f9ab77a8 2023-08-23 op }
147 f9ab77a8 2023-08-23 op
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;
151 f9ab77a8 2023-08-23 op
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");
154 f9ab77a8 2023-08-23 op goto err;
155 f9ab77a8 2023-08-23 op }
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");
158 f9ab77a8 2023-08-23 op goto err;
159 f9ab77a8 2023-08-23 op }
160 f9ab77a8 2023-08-23 op BIO_set_data(bio, ctx);
161 f9ab77a8 2023-08-23 op BIO_set_init(bio, 1);
162 f9ab77a8 2023-08-23 op
163 f9ab77a8 2023-08-23 op SSL_set_bio(ctx->ssl_conn, bio, bio);
164 f9ab77a8 2023-08-23 op
165 f9ab77a8 2023-08-23 op rv = 0;
166 f9ab77a8 2023-08-23 op
167 f9ab77a8 2023-08-23 op err:
168 f9ab77a8 2023-08-23 op return (rv);
169 f9ab77a8 2023-08-23 op }