1 /*
2 * Copyright 2016-2024 The OpenSSL Project Authors. All Rights Reserved.
3 *
4 * Licensed under the Apache License 2.0 (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
8 */
9
10 #include "bio_local.h"
11 #include "internal/thread_once.h"
12
13 CRYPTO_REF_COUNT bio_type_count;
14 static CRYPTO_ONCE bio_type_init = CRYPTO_ONCE_STATIC_INIT;
15
DEFINE_RUN_ONCE_STATIC(do_bio_type_init)16 DEFINE_RUN_ONCE_STATIC(do_bio_type_init)
17 {
18 return CRYPTO_NEW_REF(&bio_type_count, BIO_TYPE_START);
19 }
20
BIO_get_new_index(void)21 int BIO_get_new_index(void)
22 {
23 int newval;
24
25 if (!RUN_ONCE(&bio_type_init, do_bio_type_init)) {
26 /* Perhaps the error should be raised in do_bio_type_init()? */
27 ERR_raise(ERR_LIB_BIO, ERR_R_CRYPTO_LIB);
28 return -1;
29 }
30 if (!CRYPTO_UP_REF(&bio_type_count, &newval))
31 return -1;
32 if (newval > BIO_TYPE_MASK)
33 return -1;
34 return newval;
35 }
36
BIO_meth_new(int type,const char * name)37 BIO_METHOD *BIO_meth_new(int type, const char *name)
38 {
39 BIO_METHOD *biom = OPENSSL_zalloc(sizeof(BIO_METHOD));
40
41 if (biom == NULL
42 || (biom->name = OPENSSL_strdup(name)) == NULL) {
43 OPENSSL_free(biom);
44 return NULL;
45 }
46 biom->type = type;
47 return biom;
48 }
49
BIO_meth_free(BIO_METHOD * biom)50 void BIO_meth_free(BIO_METHOD *biom)
51 {
52 if (biom != NULL) {
53 OPENSSL_free(biom->name);
54 OPENSSL_free(biom);
55 }
56 }
57
58 #ifndef OPENSSL_NO_DEPRECATED_3_5
BIO_meth_get_write(const BIO_METHOD * biom)59 int (*BIO_meth_get_write(const BIO_METHOD *biom)) (BIO *, const char *, int)
60 {
61 return biom->bwrite_old;
62 }
63
BIO_meth_get_write_ex(const BIO_METHOD * biom)64 int (*BIO_meth_get_write_ex(const BIO_METHOD *biom)) (BIO *, const char *, size_t,
65 size_t *)
66 {
67 return biom->bwrite;
68 }
69 #endif
70
71 /* Conversion for old style bwrite to new style */
bwrite_conv(BIO * bio,const char * data,size_t datal,size_t * written)72 int bwrite_conv(BIO *bio, const char *data, size_t datal, size_t *written)
73 {
74 int ret;
75
76 if (datal > INT_MAX)
77 datal = INT_MAX;
78
79 ret = bio->method->bwrite_old(bio, data, (int)datal);
80
81 if (ret <= 0) {
82 *written = 0;
83 return ret;
84 }
85
86 *written = (size_t)ret;
87
88 return 1;
89 }
90
BIO_meth_set_write(BIO_METHOD * biom,int (* bwrite)(BIO *,const char *,int))91 int BIO_meth_set_write(BIO_METHOD *biom,
92 int (*bwrite) (BIO *, const char *, int))
93 {
94 biom->bwrite_old = bwrite;
95 biom->bwrite = bwrite_conv;
96 return 1;
97 }
98
BIO_meth_set_write_ex(BIO_METHOD * biom,int (* bwrite)(BIO *,const char *,size_t,size_t *))99 int BIO_meth_set_write_ex(BIO_METHOD *biom,
100 int (*bwrite) (BIO *, const char *, size_t, size_t *))
101 {
102 biom->bwrite_old = NULL;
103 biom->bwrite = bwrite;
104 return 1;
105 }
106
107 #ifndef OPENSSL_NO_DEPRECATED_3_5
BIO_meth_get_read(const BIO_METHOD * biom)108 int (*BIO_meth_get_read(const BIO_METHOD *biom)) (BIO *, char *, int)
109 {
110 return biom->bread_old;
111 }
112
BIO_meth_get_read_ex(const BIO_METHOD * biom)113 int (*BIO_meth_get_read_ex(const BIO_METHOD *biom)) (BIO *, char *, size_t, size_t *)
114 {
115 return biom->bread;
116 }
117 #endif
118
119 /* Conversion for old style bread to new style */
bread_conv(BIO * bio,char * data,size_t datal,size_t * readbytes)120 int bread_conv(BIO *bio, char *data, size_t datal, size_t *readbytes)
121 {
122 int ret;
123
124 if (datal > INT_MAX)
125 datal = INT_MAX;
126
127 ret = bio->method->bread_old(bio, data, (int)datal);
128
129 if (ret <= 0) {
130 *readbytes = 0;
131 return ret;
132 }
133
134 *readbytes = (size_t)ret;
135
136 return 1;
137 }
138
BIO_meth_set_read(BIO_METHOD * biom,int (* bread)(BIO *,char *,int))139 int BIO_meth_set_read(BIO_METHOD *biom,
140 int (*bread) (BIO *, char *, int))
141 {
142 biom->bread_old = bread;
143 biom->bread = bread_conv;
144 return 1;
145 }
146
BIO_meth_set_read_ex(BIO_METHOD * biom,int (* bread)(BIO *,char *,size_t,size_t *))147 int BIO_meth_set_read_ex(BIO_METHOD *biom,
148 int (*bread) (BIO *, char *, size_t, size_t *))
149 {
150 biom->bread_old = NULL;
151 biom->bread = bread;
152 return 1;
153 }
154
155 #ifndef OPENSSL_NO_DEPRECATED_3_5
BIO_meth_get_puts(const BIO_METHOD * biom)156 int (*BIO_meth_get_puts(const BIO_METHOD *biom)) (BIO *, const char *)
157 {
158 return biom->bputs;
159 }
160 #endif
161
BIO_meth_set_puts(BIO_METHOD * biom,int (* bputs)(BIO *,const char *))162 int BIO_meth_set_puts(BIO_METHOD *biom,
163 int (*bputs) (BIO *, const char *))
164 {
165 biom->bputs = bputs;
166 return 1;
167 }
168
169 #ifndef OPENSSL_NO_DEPRECATED_3_5
BIO_meth_get_gets(const BIO_METHOD * biom)170 int (*BIO_meth_get_gets(const BIO_METHOD *biom)) (BIO *, char *, int)
171 {
172 return biom->bgets;
173 }
174 #endif
175
BIO_meth_set_gets(BIO_METHOD * biom,int (* bgets)(BIO *,char *,int))176 int BIO_meth_set_gets(BIO_METHOD *biom,
177 int (*bgets) (BIO *, char *, int))
178 {
179 biom->bgets = bgets;
180 return 1;
181 }
182
183 #ifndef OPENSSL_NO_DEPRECATED_3_5
BIO_meth_get_ctrl(const BIO_METHOD * biom)184 long (*BIO_meth_get_ctrl(const BIO_METHOD *biom)) (BIO *, int, long, void *)
185 {
186 return biom->ctrl;
187 }
188 #endif
189
BIO_meth_set_ctrl(BIO_METHOD * biom,long (* ctrl)(BIO *,int,long,void *))190 int BIO_meth_set_ctrl(BIO_METHOD *biom,
191 long (*ctrl) (BIO *, int, long, void *))
192 {
193 biom->ctrl = ctrl;
194 return 1;
195 }
196
197 #ifndef OPENSSL_NO_DEPRECATED_3_5
BIO_meth_get_create(const BIO_METHOD * biom)198 int (*BIO_meth_get_create(const BIO_METHOD *biom)) (BIO *)
199 {
200 return biom->create;
201 }
202 #endif
203
BIO_meth_set_create(BIO_METHOD * biom,int (* create)(BIO *))204 int BIO_meth_set_create(BIO_METHOD *biom, int (*create) (BIO *))
205 {
206 biom->create = create;
207 return 1;
208 }
209
210 #ifndef OPENSSL_NO_DEPRECATED_3_5
BIO_meth_get_destroy(const BIO_METHOD * biom)211 int (*BIO_meth_get_destroy(const BIO_METHOD *biom)) (BIO *)
212 {
213 return biom->destroy;
214 }
215 #endif
216
BIO_meth_set_destroy(BIO_METHOD * biom,int (* destroy)(BIO *))217 int BIO_meth_set_destroy(BIO_METHOD *biom, int (*destroy) (BIO *))
218 {
219 biom->destroy = destroy;
220 return 1;
221 }
222
223 #ifndef OPENSSL_NO_DEPRECATED_3_5
BIO_meth_get_callback_ctrl(const BIO_METHOD * biom)224 long (*BIO_meth_get_callback_ctrl(const BIO_METHOD *biom)) (BIO *, int, BIO_info_cb *)
225 {
226 return biom->callback_ctrl;
227 }
228 #endif
229
BIO_meth_set_callback_ctrl(BIO_METHOD * biom,long (* callback_ctrl)(BIO *,int,BIO_info_cb *))230 int BIO_meth_set_callback_ctrl(BIO_METHOD *biom,
231 long (*callback_ctrl) (BIO *, int,
232 BIO_info_cb *))
233 {
234 biom->callback_ctrl = callback_ctrl;
235 return 1;
236 }
237
BIO_meth_set_sendmmsg(BIO_METHOD * biom,int (* bsendmmsg)(BIO *,BIO_MSG *,size_t,size_t,uint64_t,size_t *))238 int BIO_meth_set_sendmmsg(BIO_METHOD *biom,
239 int (*bsendmmsg) (BIO *, BIO_MSG *, size_t, size_t, uint64_t, size_t *))
240 {
241 biom->bsendmmsg = bsendmmsg;
242 return 1;
243 }
244
245 #ifndef OPENSSL_NO_DEPRECATED_3_5
BIO_meth_get_sendmmsg(const BIO_METHOD * biom)246 int (*BIO_meth_get_sendmmsg(const BIO_METHOD *biom))(BIO *, BIO_MSG *, size_t, size_t, uint64_t, size_t *) {
247 return biom->bsendmmsg;
248 }
249 #endif
250
BIO_meth_set_recvmmsg(BIO_METHOD * biom,int (* brecvmmsg)(BIO *,BIO_MSG *,size_t,size_t,uint64_t,size_t *))251 int BIO_meth_set_recvmmsg(BIO_METHOD *biom,
252 int (*brecvmmsg) (BIO *, BIO_MSG *, size_t, size_t, uint64_t, size_t *))
253 {
254 biom->brecvmmsg = brecvmmsg;
255 return 1;
256 }
257
258 #ifndef OPENSSL_NO_DEPRECATED_3_5
BIO_meth_get_recvmmsg(const BIO_METHOD * biom)259 int (*BIO_meth_get_recvmmsg(const BIO_METHOD *biom))(BIO *, BIO_MSG *, size_t, size_t, uint64_t, size_t *) {
260 return biom->brecvmmsg;
261 }
262 #endif
263