xref: /openssl/crypto/bio/bio_meth.c (revision 0bba8218)
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