1 /*
2 * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
3 *
4 * Licensed under the OpenSSL license (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 <openssl/bio.h>
11
12 #include <assert.h>
13 #include <errno.h>
14 #include <limits.h>
15 #include <string.h>
16
17 #include <openssl/asn1.h>
18 #include <openssl/err.h>
19 #include <openssl/mem.h>
20 #include <openssl/thread.h>
21
22 #include "../internal.h"
23
24
25 static CRYPTO_EX_DATA_CLASS g_ex_data_class =
26 CRYPTO_EX_DATA_CLASS_INIT_WITH_APP_DATA;
27
BIO_new(const BIO_METHOD * method)28 BIO *BIO_new(const BIO_METHOD *method) {
29 BIO *ret = reinterpret_cast<BIO *>(OPENSSL_zalloc(sizeof(BIO)));
30 if (ret == NULL) {
31 return NULL;
32 }
33
34 ret->method = method;
35 ret->shutdown = 1;
36 ret->references = 1;
37 CRYPTO_new_ex_data(&ret->ex_data);
38
39 if (method->create != NULL && !method->create(ret)) {
40 OPENSSL_free(ret);
41 return NULL;
42 }
43
44 return ret;
45 }
46
BIO_free(BIO * bio)47 int BIO_free(BIO *bio) {
48 BIO *next_bio;
49
50 for (; bio != NULL; bio = next_bio) {
51 if (!CRYPTO_refcount_dec_and_test_zero(&bio->references)) {
52 return 0;
53 }
54
55 next_bio = BIO_pop(bio);
56
57 if (bio->method != NULL && bio->method->destroy != NULL) {
58 bio->method->destroy(bio);
59 }
60
61 CRYPTO_free_ex_data(&g_ex_data_class, bio, &bio->ex_data);
62 OPENSSL_free(bio);
63 }
64 return 1;
65 }
66
BIO_up_ref(BIO * bio)67 int BIO_up_ref(BIO *bio) {
68 CRYPTO_refcount_inc(&bio->references);
69 return 1;
70 }
71
BIO_vfree(BIO * bio)72 void BIO_vfree(BIO *bio) { BIO_free(bio); }
73
BIO_free_all(BIO * bio)74 void BIO_free_all(BIO *bio) { BIO_free(bio); }
75
BIO_read(BIO * bio,void * buf,int len)76 int BIO_read(BIO *bio, void *buf, int len) {
77 if (bio == NULL || bio->method == NULL || bio->method->bread == NULL) {
78 OPENSSL_PUT_ERROR(BIO, BIO_R_UNSUPPORTED_METHOD);
79 return -2;
80 }
81 if (!bio->init) {
82 OPENSSL_PUT_ERROR(BIO, BIO_R_UNINITIALIZED);
83 return -2;
84 }
85 if (len <= 0) {
86 return 0;
87 }
88 int ret = bio->method->bread(bio, reinterpret_cast<char *>(buf), len);
89 if (ret > 0) {
90 bio->num_read += ret;
91 }
92 return ret;
93 }
94
BIO_gets(BIO * bio,char * buf,int len)95 int BIO_gets(BIO *bio, char *buf, int len) {
96 if (bio == NULL || bio->method == NULL || bio->method->bgets == NULL) {
97 OPENSSL_PUT_ERROR(BIO, BIO_R_UNSUPPORTED_METHOD);
98 return -2;
99 }
100 if (!bio->init) {
101 OPENSSL_PUT_ERROR(BIO, BIO_R_UNINITIALIZED);
102 return -2;
103 }
104 if (len <= 0) {
105 return 0;
106 }
107 int ret = bio->method->bgets(bio, buf, len);
108 if (ret > 0) {
109 bio->num_read += ret;
110 }
111 return ret;
112 }
113
BIO_write(BIO * bio,const void * in,int inl)114 int BIO_write(BIO *bio, const void *in, int inl) {
115 if (bio == NULL || bio->method == NULL || bio->method->bwrite == NULL) {
116 OPENSSL_PUT_ERROR(BIO, BIO_R_UNSUPPORTED_METHOD);
117 return -2;
118 }
119 if (!bio->init) {
120 OPENSSL_PUT_ERROR(BIO, BIO_R_UNINITIALIZED);
121 return -2;
122 }
123 if (inl <= 0) {
124 return 0;
125 }
126 int ret = bio->method->bwrite(bio, reinterpret_cast<const char *>(in), inl);
127 if (ret > 0) {
128 bio->num_write += ret;
129 }
130 return ret;
131 }
132
BIO_write_all(BIO * bio,const void * data,size_t len)133 int BIO_write_all(BIO *bio, const void *data, size_t len) {
134 const uint8_t *data_u8 = reinterpret_cast<const uint8_t *>(data);
135 while (len > 0) {
136 int ret = BIO_write(bio, data_u8, len > INT_MAX ? INT_MAX : (int)len);
137 if (ret <= 0) {
138 return 0;
139 }
140 data_u8 += ret;
141 len -= ret;
142 }
143 return 1;
144 }
145
BIO_puts(BIO * bio,const char * in)146 int BIO_puts(BIO *bio, const char *in) {
147 size_t len = strlen(in);
148 if (len > INT_MAX) {
149 // |BIO_write| and the return value both assume the string fits in |int|.
150 OPENSSL_PUT_ERROR(BIO, ERR_R_OVERFLOW);
151 return -1;
152 }
153 return BIO_write(bio, in, (int)len);
154 }
155
BIO_flush(BIO * bio)156 int BIO_flush(BIO *bio) { return (int)BIO_ctrl(bio, BIO_CTRL_FLUSH, 0, NULL); }
157
BIO_ctrl(BIO * bio,int cmd,long larg,void * parg)158 long BIO_ctrl(BIO *bio, int cmd, long larg, void *parg) {
159 if (bio == NULL) {
160 return 0;
161 }
162
163 if (bio->method == NULL || bio->method->ctrl == NULL) {
164 OPENSSL_PUT_ERROR(BIO, BIO_R_UNSUPPORTED_METHOD);
165 return -2;
166 }
167
168 return bio->method->ctrl(bio, cmd, larg, parg);
169 }
170
BIO_ptr_ctrl(BIO * b,int cmd,long larg)171 char *BIO_ptr_ctrl(BIO *b, int cmd, long larg) {
172 char *p = NULL;
173
174 if (BIO_ctrl(b, cmd, larg, (void *)&p) <= 0) {
175 return NULL;
176 }
177
178 return p;
179 }
180
BIO_int_ctrl(BIO * b,int cmd,long larg,int iarg)181 long BIO_int_ctrl(BIO *b, int cmd, long larg, int iarg) {
182 int i = iarg;
183
184 return BIO_ctrl(b, cmd, larg, (void *)&i);
185 }
186
BIO_reset(BIO * bio)187 int BIO_reset(BIO *bio) { return (int)BIO_ctrl(bio, BIO_CTRL_RESET, 0, NULL); }
188
BIO_eof(BIO * bio)189 int BIO_eof(BIO *bio) { return (int)BIO_ctrl(bio, BIO_CTRL_EOF, 0, NULL); }
190
BIO_set_flags(BIO * bio,int flags)191 void BIO_set_flags(BIO *bio, int flags) { bio->flags |= flags; }
192
BIO_test_flags(const BIO * bio,int flags)193 int BIO_test_flags(const BIO *bio, int flags) { return bio->flags & flags; }
194
BIO_should_read(const BIO * bio)195 int BIO_should_read(const BIO *bio) {
196 return BIO_test_flags(bio, BIO_FLAGS_READ);
197 }
198
BIO_should_write(const BIO * bio)199 int BIO_should_write(const BIO *bio) {
200 return BIO_test_flags(bio, BIO_FLAGS_WRITE);
201 }
202
BIO_should_retry(const BIO * bio)203 int BIO_should_retry(const BIO *bio) {
204 return BIO_test_flags(bio, BIO_FLAGS_SHOULD_RETRY);
205 }
206
BIO_should_io_special(const BIO * bio)207 int BIO_should_io_special(const BIO *bio) {
208 return BIO_test_flags(bio, BIO_FLAGS_IO_SPECIAL);
209 }
210
BIO_get_retry_reason(const BIO * bio)211 int BIO_get_retry_reason(const BIO *bio) { return bio->retry_reason; }
212
BIO_set_retry_reason(BIO * bio,int reason)213 void BIO_set_retry_reason(BIO *bio, int reason) { bio->retry_reason = reason; }
214
BIO_clear_flags(BIO * bio,int flags)215 void BIO_clear_flags(BIO *bio, int flags) { bio->flags &= ~flags; }
216
BIO_set_retry_read(BIO * bio)217 void BIO_set_retry_read(BIO *bio) {
218 bio->flags |= BIO_FLAGS_READ | BIO_FLAGS_SHOULD_RETRY;
219 }
220
BIO_set_retry_write(BIO * bio)221 void BIO_set_retry_write(BIO *bio) {
222 bio->flags |= BIO_FLAGS_WRITE | BIO_FLAGS_SHOULD_RETRY;
223 }
224
225 static const int kRetryFlags = BIO_FLAGS_RWS | BIO_FLAGS_SHOULD_RETRY;
226
BIO_get_retry_flags(BIO * bio)227 int BIO_get_retry_flags(BIO *bio) { return bio->flags & kRetryFlags; }
228
BIO_clear_retry_flags(BIO * bio)229 void BIO_clear_retry_flags(BIO *bio) {
230 bio->flags &= ~kRetryFlags;
231 bio->retry_reason = 0;
232 }
233
BIO_method_type(const BIO * bio)234 int BIO_method_type(const BIO *bio) { return bio->method->type; }
235
BIO_copy_next_retry(BIO * bio)236 void BIO_copy_next_retry(BIO *bio) {
237 BIO_clear_retry_flags(bio);
238 BIO_set_flags(bio, BIO_get_retry_flags(bio->next_bio));
239 bio->retry_reason = bio->next_bio->retry_reason;
240 }
241
BIO_callback_ctrl(BIO * bio,int cmd,bio_info_cb fp)242 long BIO_callback_ctrl(BIO *bio, int cmd, bio_info_cb fp) {
243 if (bio == NULL) {
244 return 0;
245 }
246
247 if (bio->method == NULL || bio->method->callback_ctrl == NULL) {
248 OPENSSL_PUT_ERROR(BIO, BIO_R_UNSUPPORTED_METHOD);
249 return 0;
250 }
251
252 return bio->method->callback_ctrl(bio, cmd, fp);
253 }
254
BIO_pending(const BIO * bio)255 size_t BIO_pending(const BIO *bio) {
256 const long r = BIO_ctrl((BIO *)bio, BIO_CTRL_PENDING, 0, NULL);
257 assert(r >= 0);
258
259 if (r < 0) {
260 return 0;
261 }
262 return r;
263 }
264
BIO_ctrl_pending(const BIO * bio)265 size_t BIO_ctrl_pending(const BIO *bio) { return BIO_pending(bio); }
266
BIO_wpending(const BIO * bio)267 size_t BIO_wpending(const BIO *bio) {
268 const long r = BIO_ctrl((BIO *)bio, BIO_CTRL_WPENDING, 0, NULL);
269 assert(r >= 0);
270
271 if (r < 0) {
272 return 0;
273 }
274 return r;
275 }
276
BIO_set_close(BIO * bio,int close_flag)277 int BIO_set_close(BIO *bio, int close_flag) {
278 return (int)BIO_ctrl(bio, BIO_CTRL_SET_CLOSE, close_flag, NULL);
279 }
280
BIO_number_read(const BIO * bio)281 OPENSSL_EXPORT uint64_t BIO_number_read(const BIO *bio) {
282 return bio->num_read;
283 }
284
BIO_number_written(const BIO * bio)285 OPENSSL_EXPORT uint64_t BIO_number_written(const BIO *bio) {
286 return bio->num_write;
287 }
288
BIO_push(BIO * bio,BIO * appended_bio)289 BIO *BIO_push(BIO *bio, BIO *appended_bio) {
290 BIO *last_bio;
291
292 if (bio == NULL) {
293 return bio;
294 }
295
296 last_bio = bio;
297 while (last_bio->next_bio != NULL) {
298 last_bio = last_bio->next_bio;
299 }
300
301 last_bio->next_bio = appended_bio;
302 return bio;
303 }
304
BIO_pop(BIO * bio)305 BIO *BIO_pop(BIO *bio) {
306 BIO *ret;
307
308 if (bio == NULL) {
309 return NULL;
310 }
311 ret = bio->next_bio;
312 bio->next_bio = NULL;
313 return ret;
314 }
315
BIO_next(BIO * bio)316 BIO *BIO_next(BIO *bio) {
317 if (!bio) {
318 return NULL;
319 }
320 return bio->next_bio;
321 }
322
BIO_find_type(BIO * bio,int type)323 BIO *BIO_find_type(BIO *bio, int type) {
324 int method_type, mask;
325
326 if (!bio) {
327 return NULL;
328 }
329 mask = type & 0xff;
330
331 do {
332 if (bio->method != NULL) {
333 method_type = bio->method->type;
334
335 if (!mask) {
336 if (method_type & type) {
337 return bio;
338 }
339 } else if (method_type == type) {
340 return bio;
341 }
342 }
343 bio = bio->next_bio;
344 } while (bio != NULL);
345
346 return NULL;
347 }
348
BIO_indent(BIO * bio,unsigned indent,unsigned max_indent)349 int BIO_indent(BIO *bio, unsigned indent, unsigned max_indent) {
350 if (indent > max_indent) {
351 indent = max_indent;
352 }
353
354 while (indent--) {
355 if (BIO_puts(bio, " ") != 1) {
356 return 0;
357 }
358 }
359 return 1;
360 }
361
print_bio(const char * str,size_t len,void * bio)362 static int print_bio(const char *str, size_t len, void *bio) {
363 return BIO_write_all((BIO *)bio, str, len);
364 }
365
ERR_print_errors(BIO * bio)366 void ERR_print_errors(BIO *bio) { ERR_print_errors_cb(print_bio, bio); }
367
368 // bio_read_all reads everything from |bio| and prepends |prefix| to it. On
369 // success, |*out| is set to an allocated buffer (which should be freed with
370 // |OPENSSL_free|), |*out_len| is set to its length and one is returned. The
371 // buffer will contain |prefix| followed by the contents of |bio|. On failure,
372 // zero is returned.
373 //
374 // The function will fail if the size of the output would equal or exceed
375 // |max_len|.
bio_read_all(BIO * bio,uint8_t ** out,size_t * out_len,const uint8_t * prefix,size_t prefix_len,size_t max_len)376 static int bio_read_all(BIO *bio, uint8_t **out, size_t *out_len,
377 const uint8_t *prefix, size_t prefix_len,
378 size_t max_len) {
379 static const size_t kChunkSize = 4096;
380
381 size_t len = prefix_len + kChunkSize;
382 if (len > max_len) {
383 len = max_len;
384 }
385 if (len < prefix_len) {
386 return 0;
387 }
388 *out = reinterpret_cast<uint8_t *>(OPENSSL_malloc(len));
389 if (*out == NULL) {
390 return 0;
391 }
392 OPENSSL_memcpy(*out, prefix, prefix_len);
393 size_t done = prefix_len;
394
395 for (;;) {
396 if (done == len) {
397 OPENSSL_free(*out);
398 return 0;
399 }
400 size_t todo = len - done;
401 if (todo > INT_MAX) {
402 todo = INT_MAX;
403 }
404 const int n = BIO_read(bio, *out + done, (int)todo);
405 if (n == 0) {
406 *out_len = done;
407 return 1;
408 } else if (n == -1) {
409 OPENSSL_free(*out);
410 return 0;
411 }
412
413 done += n;
414 if (len < max_len && len - done < kChunkSize / 2) {
415 len += kChunkSize;
416 if (len < kChunkSize || len > max_len) {
417 len = max_len;
418 }
419 uint8_t *new_buf =
420 reinterpret_cast<uint8_t *>(OPENSSL_realloc(*out, len));
421 if (new_buf == NULL) {
422 OPENSSL_free(*out);
423 return 0;
424 }
425 *out = new_buf;
426 }
427 }
428 }
429
430 // bio_read_full reads |len| bytes |bio| and writes them into |out|. It
431 // tolerates partial reads from |bio| and returns one on success or zero if a
432 // read fails before |len| bytes are read. On failure, it additionally sets
433 // |*out_eof_on_first_read| to whether the error was due to |bio| returning zero
434 // on the first read. |out_eof_on_first_read| may be NULL to discard the value.
bio_read_full(BIO * bio,uint8_t * out,int * out_eof_on_first_read,size_t len)435 static int bio_read_full(BIO *bio, uint8_t *out, int *out_eof_on_first_read,
436 size_t len) {
437 int first_read = 1;
438 while (len > 0) {
439 int todo = len <= INT_MAX ? (int)len : INT_MAX;
440 int ret = BIO_read(bio, out, todo);
441 if (ret <= 0) {
442 if (out_eof_on_first_read != NULL) {
443 *out_eof_on_first_read = first_read && ret == 0;
444 }
445 return 0;
446 }
447 out += ret;
448 len -= (size_t)ret;
449 first_read = 0;
450 }
451
452 return 1;
453 }
454
455 // For compatibility with existing |d2i_*_bio| callers, |BIO_read_asn1| uses
456 // |ERR_LIB_ASN1| errors.
OPENSSL_DECLARE_ERROR_REASON(ASN1,ASN1_R_DECODE_ERROR)457 OPENSSL_DECLARE_ERROR_REASON(ASN1, ASN1_R_DECODE_ERROR)
458 OPENSSL_DECLARE_ERROR_REASON(ASN1, ASN1_R_HEADER_TOO_LONG)
459 OPENSSL_DECLARE_ERROR_REASON(ASN1, ASN1_R_NOT_ENOUGH_DATA)
460 OPENSSL_DECLARE_ERROR_REASON(ASN1, ASN1_R_TOO_LONG)
461
462 int BIO_read_asn1(BIO *bio, uint8_t **out, size_t *out_len, size_t max_len) {
463 uint8_t header[6];
464
465 static const size_t kInitialHeaderLen = 2;
466 int eof_on_first_read;
467 if (!bio_read_full(bio, header, &eof_on_first_read, kInitialHeaderLen)) {
468 if (eof_on_first_read) {
469 // Historically, OpenSSL returned |ASN1_R_HEADER_TOO_LONG| when
470 // |d2i_*_bio| could not read anything. CPython conditions on this to
471 // determine if |bio| was empty.
472 OPENSSL_PUT_ERROR(ASN1, ASN1_R_HEADER_TOO_LONG);
473 } else {
474 OPENSSL_PUT_ERROR(ASN1, ASN1_R_NOT_ENOUGH_DATA);
475 }
476 return 0;
477 }
478
479 const uint8_t tag = header[0];
480 const uint8_t length_byte = header[1];
481
482 if ((tag & 0x1f) == 0x1f) {
483 // Long form tags are not supported.
484 OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR);
485 return 0;
486 }
487
488 size_t len, header_len;
489 if ((length_byte & 0x80) == 0) {
490 // Short form length.
491 len = length_byte;
492 header_len = kInitialHeaderLen;
493 } else {
494 const size_t num_bytes = length_byte & 0x7f;
495
496 if ((tag & 0x20 /* constructed */) != 0 && num_bytes == 0) {
497 // indefinite length.
498 if (!bio_read_all(bio, out, out_len, header, kInitialHeaderLen,
499 max_len)) {
500 OPENSSL_PUT_ERROR(ASN1, ASN1_R_NOT_ENOUGH_DATA);
501 return 0;
502 }
503 return 1;
504 }
505
506 if (num_bytes == 0 || num_bytes > 4) {
507 OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR);
508 return 0;
509 }
510
511 if (!bio_read_full(bio, header + kInitialHeaderLen, NULL, num_bytes)) {
512 OPENSSL_PUT_ERROR(ASN1, ASN1_R_NOT_ENOUGH_DATA);
513 return 0;
514 }
515 header_len = kInitialHeaderLen + num_bytes;
516
517 uint32_t len32 = 0;
518 for (unsigned i = 0; i < num_bytes; i++) {
519 len32 <<= 8;
520 len32 |= header[kInitialHeaderLen + i];
521 }
522
523 if (len32 < 128) {
524 // Length should have used short-form encoding.
525 OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR);
526 return 0;
527 }
528
529 if ((len32 >> ((num_bytes - 1) * 8)) == 0) {
530 // Length should have been at least one byte shorter.
531 OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR);
532 return 0;
533 }
534
535 len = len32;
536 }
537
538 if (len + header_len < len || len + header_len > max_len || len > INT_MAX) {
539 OPENSSL_PUT_ERROR(ASN1, ASN1_R_TOO_LONG);
540 return 0;
541 }
542 len += header_len;
543 *out_len = len;
544
545 *out = reinterpret_cast<uint8_t *>(OPENSSL_malloc(len));
546 if (*out == NULL) {
547 return 0;
548 }
549 OPENSSL_memcpy(*out, header, header_len);
550 if (!bio_read_full(bio, (*out) + header_len, NULL, len - header_len)) {
551 OPENSSL_PUT_ERROR(ASN1, ASN1_R_NOT_ENOUGH_DATA);
552 OPENSSL_free(*out);
553 return 0;
554 }
555
556 return 1;
557 }
558
BIO_set_retry_special(BIO * bio)559 void BIO_set_retry_special(BIO *bio) {
560 bio->flags |= BIO_FLAGS_READ | BIO_FLAGS_IO_SPECIAL;
561 }
562
BIO_set_write_buffer_size(BIO * bio,int buffer_size)563 int BIO_set_write_buffer_size(BIO *bio, int buffer_size) { return 0; }
564
565 static CRYPTO_MUTEX g_index_lock = CRYPTO_MUTEX_INIT;
566 static int g_index = BIO_TYPE_START;
567
BIO_get_new_index(void)568 int BIO_get_new_index(void) {
569 CRYPTO_MUTEX_lock_write(&g_index_lock);
570 // If |g_index| exceeds 255, it will collide with the flags bits.
571 int ret = g_index > 255 ? -1 : g_index++;
572 CRYPTO_MUTEX_unlock_write(&g_index_lock);
573 return ret;
574 }
575
BIO_meth_new(int type,const char * name)576 BIO_METHOD *BIO_meth_new(int type, const char *name) {
577 BIO_METHOD *method =
578 reinterpret_cast<BIO_METHOD *>(OPENSSL_zalloc(sizeof(BIO_METHOD)));
579 if (method == NULL) {
580 return NULL;
581 }
582 method->type = type;
583 method->name = name;
584 return method;
585 }
586
BIO_meth_free(BIO_METHOD * method)587 void BIO_meth_free(BIO_METHOD *method) { OPENSSL_free(method); }
588
BIO_meth_set_create(BIO_METHOD * method,int (* create_func)(BIO *))589 int BIO_meth_set_create(BIO_METHOD *method, int (*create_func)(BIO *)) {
590 method->create = create_func;
591 return 1;
592 }
593
BIO_meth_set_destroy(BIO_METHOD * method,int (* destroy_func)(BIO *))594 int BIO_meth_set_destroy(BIO_METHOD *method, int (*destroy_func)(BIO *)) {
595 method->destroy = destroy_func;
596 return 1;
597 }
598
BIO_meth_set_write(BIO_METHOD * method,int (* write_func)(BIO *,const char *,int))599 int BIO_meth_set_write(BIO_METHOD *method,
600 int (*write_func)(BIO *, const char *, int)) {
601 method->bwrite = write_func;
602 return 1;
603 }
604
BIO_meth_set_read(BIO_METHOD * method,int (* read_func)(BIO *,char *,int))605 int BIO_meth_set_read(BIO_METHOD *method,
606 int (*read_func)(BIO *, char *, int)) {
607 method->bread = read_func;
608 return 1;
609 }
610
BIO_meth_set_gets(BIO_METHOD * method,int (* gets_func)(BIO *,char *,int))611 int BIO_meth_set_gets(BIO_METHOD *method,
612 int (*gets_func)(BIO *, char *, int)) {
613 method->bgets = gets_func;
614 return 1;
615 }
616
BIO_meth_set_ctrl(BIO_METHOD * method,long (* ctrl_func)(BIO *,int,long,void *))617 int BIO_meth_set_ctrl(BIO_METHOD *method,
618 long (*ctrl_func)(BIO *, int, long, void *)) {
619 method->ctrl = ctrl_func;
620 return 1;
621 }
622
BIO_set_data(BIO * bio,void * ptr)623 void BIO_set_data(BIO *bio, void *ptr) { bio->ptr = ptr; }
624
BIO_get_data(BIO * bio)625 void *BIO_get_data(BIO *bio) { return bio->ptr; }
626
BIO_set_init(BIO * bio,int init)627 void BIO_set_init(BIO *bio, int init) { bio->init = init; }
628
BIO_get_init(BIO * bio)629 int BIO_get_init(BIO *bio) { return bio->init; }
630
BIO_set_shutdown(BIO * bio,int shutdown)631 void BIO_set_shutdown(BIO *bio, int shutdown) { bio->shutdown = shutdown; }
632
BIO_get_shutdown(BIO * bio)633 int BIO_get_shutdown(BIO *bio) { return bio->shutdown; }
634
BIO_meth_set_puts(BIO_METHOD * method,int (* puts)(BIO *,const char *))635 int BIO_meth_set_puts(BIO_METHOD *method, int (*puts)(BIO *, const char *)) {
636 // Ignore the parameter. We implement |BIO_puts| using |BIO_write|.
637 return 1;
638 }
639
BIO_get_ex_new_index(long argl,void * argp,CRYPTO_EX_unused * unused,CRYPTO_EX_dup * dup_unused,CRYPTO_EX_free * free_func)640 int BIO_get_ex_new_index(long argl, void *argp, //
641 CRYPTO_EX_unused *unused, //
642 CRYPTO_EX_dup *dup_unused, //
643 CRYPTO_EX_free *free_func) {
644 return CRYPTO_get_ex_new_index_ex(&g_ex_data_class, argl, argp, free_func);
645 }
646
BIO_set_ex_data(BIO * bio,int idx,void * data)647 int BIO_set_ex_data(BIO *bio, int idx, void *data) {
648 return CRYPTO_set_ex_data(&bio->ex_data, idx, data);
649 }
650
BIO_get_ex_data(const BIO * bio,int idx)651 void *BIO_get_ex_data(const BIO *bio, int idx) {
652 return CRYPTO_get_ex_data(&bio->ex_data, idx);
653 }
654