Coverage Report

Created: 2025-11-03 06:30

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