• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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