Coverage Report

Created: 2024-11-21 07:03

/src/boringssl/crypto/bio/bio.c
Line
Count
Source (jump to first uncovered line)
1
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
2
 * All rights reserved.
3
 *
4
 * This package is an SSL implementation written
5
 * by Eric Young (eay@cryptsoft.com).
6
 * The implementation was written so as to conform with Netscapes SSL.
7
 *
8
 * This library is free for commercial and non-commercial use as long as
9
 * the following conditions are aheared to.  The following conditions
10
 * apply to all code found in this distribution, be it the RC4, RSA,
11
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
12
 * included with this distribution is covered by the same copyright terms
13
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
14
 *
15
 * Copyright remains Eric Young's, and as such any Copyright notices in
16
 * the code are not to be removed.
17
 * If this package is used in a product, Eric Young should be given attribution
18
 * as the author of the parts of the library used.
19
 * This can be in the form of a textual message at program startup or
20
 * in documentation (online or textual) provided with the package.
21
 *
22
 * Redistribution and use in source and binary forms, with or without
23
 * modification, are permitted provided that the following conditions
24
 * are met:
25
 * 1. Redistributions of source code must retain the copyright
26
 *    notice, this list of conditions and the following disclaimer.
27
 * 2. Redistributions in binary form must reproduce the above copyright
28
 *    notice, this list of conditions and the following disclaimer in the
29
 *    documentation and/or other materials provided with the distribution.
30
 * 3. All advertising materials mentioning features or use of this software
31
 *    must display the following acknowledgement:
32
 *    "This product includes cryptographic software written by
33
 *     Eric Young (eay@cryptsoft.com)"
34
 *    The word 'cryptographic' can be left out if the rouines from the library
35
 *    being used are not cryptographic related :-).
36
 * 4. If you include any Windows specific code (or a derivative thereof) from
37
 *    the apps directory (application code) you must include an acknowledgement:
38
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
39
 *
40
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
41
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
43
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
44
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50
 * SUCH DAMAGE.
51
 *
52
 * The licence and distribution terms for any publically available version or
53
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
54
 * copied and put under another distribution licence
55
 * [including the GNU Public Licence.] */
56
57
#include <openssl/bio.h>
58
59
#include <assert.h>
60
#include <errno.h>
61
#include <limits.h>
62
#include <string.h>
63
64
#include <openssl/asn1.h>
65
#include <openssl/err.h>
66
#include <openssl/mem.h>
67
#include <openssl/thread.h>
68
69
#include "../internal.h"
70
71
72
static CRYPTO_EX_DATA_CLASS g_ex_data_class =
73
    CRYPTO_EX_DATA_CLASS_INIT_WITH_APP_DATA;
74
75
0
BIO *BIO_new(const BIO_METHOD *method) {
76
0
  BIO *ret = OPENSSL_zalloc(sizeof(BIO));
77
0
  if (ret == NULL) {
78
0
    return NULL;
79
0
  }
80
81
0
  ret->method = method;
82
0
  ret->shutdown = 1;
83
0
  ret->references = 1;
84
0
  CRYPTO_new_ex_data(&ret->ex_data);
85
86
0
  if (method->create != NULL && !method->create(ret)) {
87
0
    OPENSSL_free(ret);
88
0
    return NULL;
89
0
  }
90
91
0
  return ret;
92
0
}
93
94
0
int BIO_free(BIO *bio) {
95
0
  BIO *next_bio;
96
97
0
  for (; bio != NULL; bio = next_bio) {
98
0
    if (!CRYPTO_refcount_dec_and_test_zero(&bio->references)) {
99
0
      return 0;
100
0
    }
101
102
0
    next_bio = BIO_pop(bio);
103
104
0
    if (bio->method != NULL && bio->method->destroy != NULL) {
105
0
      bio->method->destroy(bio);
106
0
    }
107
108
0
    CRYPTO_free_ex_data(&g_ex_data_class, bio, &bio->ex_data);
109
0
    OPENSSL_free(bio);
110
0
  }
111
0
  return 1;
112
0
}
113
114
0
int BIO_up_ref(BIO *bio) {
115
0
  CRYPTO_refcount_inc(&bio->references);
116
0
  return 1;
117
0
}
118
119
0
void BIO_vfree(BIO *bio) {
120
0
  BIO_free(bio);
121
0
}
122
123
void BIO_free_all(BIO *bio) {
124
  BIO_free(bio);
125
}
126
127
int BIO_read(BIO *bio, void *buf, int len) {
128
  if (bio == NULL || bio->method == NULL || bio->method->bread == NULL) {
129
    OPENSSL_PUT_ERROR(BIO, BIO_R_UNSUPPORTED_METHOD);
130
    return -2;
131
  }
132
  if (!bio->init) {
133
    OPENSSL_PUT_ERROR(BIO, BIO_R_UNINITIALIZED);
134
    return -2;
135
  }
136
  if (len <= 0) {
137
    return 0;
138
  }
139
  int ret = bio->method->bread(bio, buf, len);
140
  if (ret > 0) {
141
    bio->num_read += ret;
142
  }
143
  return ret;
144
}
145
146
0
int BIO_gets(BIO *bio, char *buf, int len) {
147
0
  if (bio == NULL || bio->method == NULL || bio->method->bgets == NULL) {
148
0
    OPENSSL_PUT_ERROR(BIO, BIO_R_UNSUPPORTED_METHOD);
149
0
    return -2;
150
0
  }
151
0
  if (!bio->init) {
152
0
    OPENSSL_PUT_ERROR(BIO, BIO_R_UNINITIALIZED);
153
0
    return -2;
154
0
  }
155
0
  if (len <= 0) {
156
0
    return 0;
157
0
  }
158
0
  int ret = bio->method->bgets(bio, buf, len);
159
0
  if (ret > 0) {
160
0
    bio->num_read += ret;
161
0
  }
162
0
  return ret;
163
0
}
164
165
0
int BIO_write(BIO *bio, const void *in, int inl) {
166
0
  if (bio == NULL || bio->method == NULL || bio->method->bwrite == NULL) {
167
0
    OPENSSL_PUT_ERROR(BIO, BIO_R_UNSUPPORTED_METHOD);
168
0
    return -2;
169
0
  }
170
0
  if (!bio->init) {
171
0
    OPENSSL_PUT_ERROR(BIO, BIO_R_UNINITIALIZED);
172
0
    return -2;
173
0
  }
174
0
  if (inl <= 0) {
175
0
    return 0;
176
0
  }
177
0
  int ret = bio->method->bwrite(bio, in, inl);
178
0
  if (ret > 0) {
179
0
    bio->num_write += ret;
180
0
  }
181
0
  return ret;
182
0
}
183
184
0
int BIO_write_all(BIO *bio, const void *data, size_t len) {
185
0
  const uint8_t *data_u8 = data;
186
0
  while (len > 0) {
187
0
    int ret = BIO_write(bio, data_u8, len > INT_MAX ? INT_MAX : (int)len);
188
0
    if (ret <= 0) {
189
0
      return 0;
190
0
    }
191
0
    data_u8 += ret;
192
0
    len -= ret;
193
0
  }
194
0
  return 1;
195
0
}
196
197
0
int BIO_puts(BIO *bio, const char *in) {
198
0
  size_t len = strlen(in);
199
0
  if (len > INT_MAX) {
200
    // |BIO_write| and the return value both assume the string fits in |int|.
201
0
    OPENSSL_PUT_ERROR(BIO, ERR_R_OVERFLOW);
202
0
    return -1;
203
0
  }
204
0
  return BIO_write(bio, in, (int)len);
205
0
}
206
207
0
int BIO_flush(BIO *bio) {
208
0
  return (int)BIO_ctrl(bio, BIO_CTRL_FLUSH, 0, NULL);
209
0
}
210
211
long BIO_ctrl(BIO *bio, int cmd, long larg, void *parg) {
212
  if (bio == NULL) {
213
    return 0;
214
  }
215
216
  if (bio->method == NULL || bio->method->ctrl == NULL) {
217
    OPENSSL_PUT_ERROR(BIO, BIO_R_UNSUPPORTED_METHOD);
218
    return -2;
219
  }
220
221
  return bio->method->ctrl(bio, cmd, larg, parg);
222
}
223
224
0
char *BIO_ptr_ctrl(BIO *b, int cmd, long larg) {
225
0
  char *p = NULL;
226
227
0
  if (BIO_ctrl(b, cmd, larg, (void *)&p) <= 0) {
228
0
    return NULL;
229
0
  }
230
231
0
  return p;
232
0
}
233
234
0
long BIO_int_ctrl(BIO *b, int cmd, long larg, int iarg) {
235
0
  int i = iarg;
236
237
0
  return BIO_ctrl(b, cmd, larg, (void *)&i);
238
0
}
239
240
0
int BIO_reset(BIO *bio) {
241
0
  return (int)BIO_ctrl(bio, BIO_CTRL_RESET, 0, NULL);
242
0
}
243
244
0
int BIO_eof(BIO *bio) {
245
0
  return (int)BIO_ctrl(bio, BIO_CTRL_EOF, 0, NULL);
246
0
}
247
248
8
void BIO_set_flags(BIO *bio, int flags) {
249
8
  bio->flags |= flags;
250
8
}
251
252
11
int BIO_test_flags(const BIO *bio, int flags) {
253
11
  return bio->flags & flags;
254
11
}
255
256
0
int BIO_should_read(const BIO *bio) {
257
0
  return BIO_test_flags(bio, BIO_FLAGS_READ);
258
0
}
259
260
0
int BIO_should_write(const BIO *bio) {
261
0
  return BIO_test_flags(bio, BIO_FLAGS_WRITE);
262
0
}
263
264
0
int BIO_should_retry(const BIO *bio) {
265
0
  return BIO_test_flags(bio, BIO_FLAGS_SHOULD_RETRY);
266
0
}
267
268
0
int BIO_should_io_special(const BIO *bio) {
269
0
  return BIO_test_flags(bio, BIO_FLAGS_IO_SPECIAL);
270
0
}
271
272
0
int BIO_get_retry_reason(const BIO *bio) { return bio->retry_reason; }
273
274
0
void BIO_set_retry_reason(BIO *bio, int reason) { bio->retry_reason = reason; }
275
276
15
void BIO_clear_flags(BIO *bio, int flags) {
277
15
  bio->flags &= ~flags;
278
15
}
279
280
0
void BIO_set_retry_read(BIO *bio) {
281
0
  bio->flags |= BIO_FLAGS_READ | BIO_FLAGS_SHOULD_RETRY;
282
0
}
283
284
0
void BIO_set_retry_write(BIO *bio) {
285
0
  bio->flags |= BIO_FLAGS_WRITE | BIO_FLAGS_SHOULD_RETRY;
286
0
}
287
288
static const int kRetryFlags = BIO_FLAGS_RWS | BIO_FLAGS_SHOULD_RETRY;
289
290
0
int BIO_get_retry_flags(BIO *bio) {
291
0
  return bio->flags & kRetryFlags;
292
0
}
293
294
0
void BIO_clear_retry_flags(BIO *bio) {
295
0
  bio->flags &= ~kRetryFlags;
296
0
  bio->retry_reason = 0;
297
0
}
298
299
0
int BIO_method_type(const BIO *bio) { return bio->method->type; }
300
301
8
void BIO_copy_next_retry(BIO *bio) {
302
8
  BIO_clear_retry_flags(bio);
303
8
  BIO_set_flags(bio, BIO_get_retry_flags(bio->next_bio));
304
8
  bio->retry_reason = bio->next_bio->retry_reason;
305
8
}
306
307
0
long BIO_callback_ctrl(BIO *bio, int cmd, bio_info_cb fp) {
308
0
  if (bio == NULL) {
309
0
    return 0;
310
0
  }
311
312
0
  if (bio->method == NULL || bio->method->callback_ctrl == NULL) {
313
0
    OPENSSL_PUT_ERROR(BIO, BIO_R_UNSUPPORTED_METHOD);
314
0
    return 0;
315
0
  }
316
317
0
  return bio->method->callback_ctrl(bio, cmd, fp);
318
0
}
319
320
0
size_t BIO_pending(const BIO *bio) {
321
0
  const long r = BIO_ctrl((BIO *) bio, BIO_CTRL_PENDING, 0, NULL);
322
0
  assert(r >= 0);
323
324
0
  if (r < 0) {
325
0
    return 0;
326
0
  }
327
0
  return r;
328
0
}
329
330
0
size_t BIO_ctrl_pending(const BIO *bio) {
331
0
  return BIO_pending(bio);
332
0
}
333
334
0
size_t BIO_wpending(const BIO *bio) {
335
0
  const long r = BIO_ctrl((BIO *) bio, BIO_CTRL_WPENDING, 0, NULL);
336
0
  assert(r >= 0);
337
338
0
  if (r < 0) {
339
0
    return 0;
340
0
  }
341
0
  return r;
342
0
}
343
344
0
int BIO_set_close(BIO *bio, int close_flag) {
345
0
  return (int)BIO_ctrl(bio, BIO_CTRL_SET_CLOSE, close_flag, NULL);
346
0
}
347
348
0
OPENSSL_EXPORT uint64_t BIO_number_read(const BIO *bio) {
349
0
  return bio->num_read;
350
0
}
351
352
0
OPENSSL_EXPORT uint64_t BIO_number_written(const BIO *bio) {
353
0
  return bio->num_write;
354
0
}
355
356
0
BIO *BIO_push(BIO *bio, BIO *appended_bio) {
357
0
  BIO *last_bio;
358
359
0
  if (bio == NULL) {
360
0
    return bio;
361
0
  }
362
363
0
  last_bio = bio;
364
0
  while (last_bio->next_bio != NULL) {
365
0
    last_bio = last_bio->next_bio;
366
0
  }
367
368
0
  last_bio->next_bio = appended_bio;
369
0
  return bio;
370
0
}
371
372
0
BIO *BIO_pop(BIO *bio) {
373
0
  BIO *ret;
374
375
0
  if (bio == NULL) {
376
0
    return NULL;
377
0
  }
378
0
  ret = bio->next_bio;
379
0
  bio->next_bio = NULL;
380
0
  return ret;
381
0
}
382
383
BIO *BIO_next(BIO *bio) {
384
  if (!bio) {
385
    return NULL;
386
  }
387
  return bio->next_bio;
388
}
389
390
0
BIO *BIO_find_type(BIO *bio, int type) {
391
0
  int method_type, mask;
392
393
0
  if (!bio) {
394
0
    return NULL;
395
0
  }
396
0
  mask = type & 0xff;
397
398
0
  do {
399
0
    if (bio->method != NULL) {
400
0
      method_type = bio->method->type;
401
402
0
      if (!mask) {
403
0
        if (method_type & type) {
404
0
          return bio;
405
0
        }
406
0
      } else if (method_type == type) {
407
0
        return bio;
408
0
      }
409
0
    }
410
0
    bio = bio->next_bio;
411
0
  } while (bio != NULL);
412
413
0
  return NULL;
414
0
}
415
416
0
int BIO_indent(BIO *bio, unsigned indent, unsigned max_indent) {
417
0
  if (indent > max_indent) {
418
0
    indent = max_indent;
419
0
  }
420
421
0
  while (indent--) {
422
0
    if (BIO_puts(bio, " ") != 1) {
423
0
      return 0;
424
0
    }
425
0
  }
426
0
  return 1;
427
0
}
428
429
0
static int print_bio(const char *str, size_t len, void *bio) {
430
0
  return BIO_write_all((BIO *)bio, str, len);
431
0
}
432
433
0
void ERR_print_errors(BIO *bio) {
434
0
  ERR_print_errors_cb(print_bio, bio);
435
0
}
436
437
// bio_read_all reads everything from |bio| and prepends |prefix| to it. On
438
// success, |*out| is set to an allocated buffer (which should be freed with
439
// |OPENSSL_free|), |*out_len| is set to its length and one is returned. The
440
// buffer will contain |prefix| followed by the contents of |bio|. On failure,
441
// zero is returned.
442
//
443
// The function will fail if the size of the output would equal or exceed
444
// |max_len|.
445
static int bio_read_all(BIO *bio, uint8_t **out, size_t *out_len,
446
                        const uint8_t *prefix, size_t prefix_len,
447
0
                        size_t max_len) {
448
0
  static const size_t kChunkSize = 4096;
449
450
0
  size_t len = prefix_len + kChunkSize;
451
0
  if (len > max_len) {
452
0
    len = max_len;
453
0
  }
454
0
  if (len < prefix_len) {
455
0
    return 0;
456
0
  }
457
0
  *out = OPENSSL_malloc(len);
458
0
  if (*out == NULL) {
459
0
    return 0;
460
0
  }
461
0
  OPENSSL_memcpy(*out, prefix, prefix_len);
462
0
  size_t done = prefix_len;
463
464
0
  for (;;) {
465
0
    if (done == len) {
466
0
      OPENSSL_free(*out);
467
0
      return 0;
468
0
    }
469
0
    size_t todo = len - done;
470
0
    if (todo > INT_MAX) {
471
0
      todo = INT_MAX;
472
0
    }
473
0
    const int n = BIO_read(bio, *out + done, (int)todo);
474
0
    if (n == 0) {
475
0
      *out_len = done;
476
0
      return 1;
477
0
    } else if (n == -1) {
478
0
      OPENSSL_free(*out);
479
0
      return 0;
480
0
    }
481
482
0
    done += n;
483
0
    if (len < max_len && len - done < kChunkSize / 2) {
484
0
      len += kChunkSize;
485
0
      if (len < kChunkSize || len > max_len) {
486
0
        len = max_len;
487
0
      }
488
0
      uint8_t *new_buf = OPENSSL_realloc(*out, len);
489
0
      if (new_buf == NULL) {
490
0
        OPENSSL_free(*out);
491
0
        return 0;
492
0
      }
493
0
      *out = new_buf;
494
0
    }
495
0
  }
496
0
}
497
498
// bio_read_full reads |len| bytes |bio| and writes them into |out|. It
499
// tolerates partial reads from |bio| and returns one on success or zero if a
500
// read fails before |len| bytes are read. On failure, it additionally sets
501
// |*out_eof_on_first_read| to whether the error was due to |bio| returning zero
502
// on the first read. |out_eof_on_first_read| may be NULL to discard the value.
503
static int bio_read_full(BIO *bio, uint8_t *out, int *out_eof_on_first_read,
504
0
                         size_t len) {
505
0
  int first_read = 1;
506
0
  while (len > 0) {
507
0
    int todo = len <= INT_MAX ? (int)len : INT_MAX;
508
0
    int ret = BIO_read(bio, out, todo);
509
0
    if (ret <= 0) {
510
0
      if (out_eof_on_first_read != NULL) {
511
0
        *out_eof_on_first_read = first_read && ret == 0;
512
0
      }
513
0
      return 0;
514
0
    }
515
0
    out += ret;
516
0
    len -= (size_t)ret;
517
0
    first_read = 0;
518
0
  }
519
520
0
  return 1;
521
0
}
522
523
// For compatibility with existing |d2i_*_bio| callers, |BIO_read_asn1| uses
524
// |ERR_LIB_ASN1| errors.
525
OPENSSL_DECLARE_ERROR_REASON(ASN1, ASN1_R_DECODE_ERROR)
526
OPENSSL_DECLARE_ERROR_REASON(ASN1, ASN1_R_HEADER_TOO_LONG)
527
OPENSSL_DECLARE_ERROR_REASON(ASN1, ASN1_R_NOT_ENOUGH_DATA)
528
OPENSSL_DECLARE_ERROR_REASON(ASN1, ASN1_R_TOO_LONG)
529
530
0
int BIO_read_asn1(BIO *bio, uint8_t **out, size_t *out_len, size_t max_len) {
531
0
  uint8_t header[6];
532
533
0
  static const size_t kInitialHeaderLen = 2;
534
0
  int eof_on_first_read;
535
0
  if (!bio_read_full(bio, header, &eof_on_first_read, kInitialHeaderLen)) {
536
0
    if (eof_on_first_read) {
537
      // Historically, OpenSSL returned |ASN1_R_HEADER_TOO_LONG| when
538
      // |d2i_*_bio| could not read anything. CPython conditions on this to
539
      // determine if |bio| was empty.
540
0
      OPENSSL_PUT_ERROR(ASN1, ASN1_R_HEADER_TOO_LONG);
541
0
    } else {
542
0
      OPENSSL_PUT_ERROR(ASN1, ASN1_R_NOT_ENOUGH_DATA);
543
0
    }
544
0
    return 0;
545
0
  }
546
547
0
  const uint8_t tag = header[0];
548
0
  const uint8_t length_byte = header[1];
549
550
0
  if ((tag & 0x1f) == 0x1f) {
551
    // Long form tags are not supported.
552
0
    OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR);
553
0
    return 0;
554
0
  }
555
556
0
  size_t len, header_len;
557
0
  if ((length_byte & 0x80) == 0) {
558
    // Short form length.
559
0
    len = length_byte;
560
0
    header_len = kInitialHeaderLen;
561
0
  } else {
562
0
    const size_t num_bytes = length_byte & 0x7f;
563
564
0
    if ((tag & 0x20 /* constructed */) != 0 && num_bytes == 0) {
565
      // indefinite length.
566
0
      if (!bio_read_all(bio, out, out_len, header, kInitialHeaderLen,
567
0
                        max_len)) {
568
0
        OPENSSL_PUT_ERROR(ASN1, ASN1_R_NOT_ENOUGH_DATA);
569
0
        return 0;
570
0
      }
571
0
      return 1;
572
0
    }
573
574
0
    if (num_bytes == 0 || num_bytes > 4) {
575
0
      OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR);
576
0
      return 0;
577
0
    }
578
579
0
    if (!bio_read_full(bio, header + kInitialHeaderLen, NULL, num_bytes)) {
580
0
      OPENSSL_PUT_ERROR(ASN1, ASN1_R_NOT_ENOUGH_DATA);
581
0
      return 0;
582
0
    }
583
0
    header_len = kInitialHeaderLen + num_bytes;
584
585
0
    uint32_t len32 = 0;
586
0
    for (unsigned i = 0; i < num_bytes; i++) {
587
0
      len32 <<= 8;
588
0
      len32 |= header[kInitialHeaderLen + i];
589
0
    }
590
591
0
    if (len32 < 128) {
592
      // Length should have used short-form encoding.
593
0
      OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR);
594
0
      return 0;
595
0
    }
596
597
0
    if ((len32 >> ((num_bytes-1)*8)) == 0) {
598
      // Length should have been at least one byte shorter.
599
0
      OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR);
600
0
      return 0;
601
0
    }
602
603
0
    len = len32;
604
0
  }
605
606
0
  if (len + header_len < len ||
607
0
      len + header_len > max_len ||
608
0
      len > INT_MAX) {
609
0
    OPENSSL_PUT_ERROR(ASN1, ASN1_R_TOO_LONG);
610
0
    return 0;
611
0
  }
612
0
  len += header_len;
613
0
  *out_len = len;
614
615
0
  *out = OPENSSL_malloc(len);
616
0
  if (*out == NULL) {
617
0
    return 0;
618
0
  }
619
0
  OPENSSL_memcpy(*out, header, header_len);
620
0
  if (!bio_read_full(bio, (*out) + header_len, NULL, len - header_len)) {
621
0
    OPENSSL_PUT_ERROR(ASN1, ASN1_R_NOT_ENOUGH_DATA);
622
0
    OPENSSL_free(*out);
623
0
    return 0;
624
0
  }
625
626
0
  return 1;
627
0
}
628
629
0
void BIO_set_retry_special(BIO *bio) {
630
0
  bio->flags |= BIO_FLAGS_READ | BIO_FLAGS_IO_SPECIAL;
631
0
}
632
633
0
int BIO_set_write_buffer_size(BIO *bio, int buffer_size) { return 0; }
634
635
static CRYPTO_MUTEX g_index_lock = CRYPTO_MUTEX_INIT;
636
static int g_index = BIO_TYPE_START;
637
638
0
int BIO_get_new_index(void) {
639
0
  CRYPTO_MUTEX_lock_write(&g_index_lock);
640
  // If |g_index| exceeds 255, it will collide with the flags bits.
641
0
  int ret = g_index > 255 ? -1 : g_index++;
642
0
  CRYPTO_MUTEX_unlock_write(&g_index_lock);
643
0
  return ret;
644
0
}
645
646
BIO_METHOD *BIO_meth_new(int type, const char *name) {
647
  BIO_METHOD *method = OPENSSL_zalloc(sizeof(BIO_METHOD));
648
  if (method == NULL) {
649
    return NULL;
650
  }
651
  method->type = type;
652
  method->name = name;
653
  return method;
654
}
655
656
void BIO_meth_free(BIO_METHOD *method) {
657
  OPENSSL_free(method);
658
}
659
660
int BIO_meth_set_create(BIO_METHOD *method,
661
2
                        int (*create_func)(BIO *)) {
662
2
  method->create = create_func;
663
2
  return 1;
664
2
}
665
666
int BIO_meth_set_destroy(BIO_METHOD *method,
667
2
                         int (*destroy_func)(BIO *)) {
668
2
  method->destroy = destroy_func;
669
2
  return 1;
670
2
}
671
672
int BIO_meth_set_write(BIO_METHOD *method,
673
0
                       int (*write_func)(BIO *, const char *, int)) {
674
0
  method->bwrite = write_func;
675
0
  return 1;
676
0
}
677
678
int BIO_meth_set_read(BIO_METHOD *method,
679
0
                      int (*read_func)(BIO *, char *, int)) {
680
0
  method->bread = read_func;
681
0
  return 1;
682
0
}
683
684
int BIO_meth_set_gets(BIO_METHOD *method,
685
2
                      int (*gets_func)(BIO *, char *, int)) {
686
2
  method->bgets = gets_func;
687
2
  return 1;
688
2
}
689
690
int BIO_meth_set_ctrl(BIO_METHOD *method,
691
2
                      long (*ctrl_func)(BIO *, int, long, void *)) {
692
2
  method->ctrl = ctrl_func;
693
2
  return 1;
694
2
}
695
696
8
void BIO_set_data(BIO *bio, void *ptr) { bio->ptr = ptr; }
697
698
20
void *BIO_get_data(BIO *bio) { return bio->ptr; }
699
700
12
void BIO_set_init(BIO *bio, int init) { bio->init = init; }
701
702
0
int BIO_get_init(BIO *bio) { return bio->init; }
703
704
0
void BIO_set_shutdown(BIO *bio, int shutdown) { bio->shutdown = shutdown; }
705
706
0
int BIO_get_shutdown(BIO *bio) { return bio->shutdown; }
707
708
2
int BIO_meth_set_puts(BIO_METHOD *method, int (*puts)(BIO *, const char *)) {
709
  // Ignore the parameter. We implement |BIO_puts| using |BIO_write|.
710
2
  return 1;
711
2
}
712
713
int BIO_get_ex_new_index(long argl, void *argp,
714
                                    CRYPTO_EX_unused *unused,
715
                                    CRYPTO_EX_dup *dup_unused,
716
0
                                    CRYPTO_EX_free *free_func) {
717
0
  return CRYPTO_get_ex_new_index_ex(&g_ex_data_class, argl, argp, free_func);
718
0
}
719
720
0
int BIO_set_ex_data(BIO *bio, int idx, void *data) {
721
0
  return CRYPTO_set_ex_data(&bio->ex_data, idx, data);
722
0
}
723
724
0
void *BIO_get_ex_data(const BIO *bio, int idx) {
725
0
  return CRYPTO_get_ex_data(&bio->ex_data, idx);
726
0
}