Coverage Report

Created: 2024-07-24 06:31

/src/openssl/crypto/bio/bio_lib.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright 1995-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
#define OPENSSL_SUPPRESS_DEPRECATED
11
12
#include <stdio.h>
13
#include <errno.h>
14
#include <openssl/crypto.h>
15
#include "internal/numbers.h"
16
#include "bio_local.h"
17
18
/*
19
 * Helper macro for the callback to determine whether an operator expects a
20
 * len parameter or not
21
 */
22
0
#define HAS_LEN_OPER(o) ((o) == BIO_CB_READ || (o) == BIO_CB_WRITE \
23
0
                         || (o) == BIO_CB_GETS)
24
25
#ifndef OPENSSL_NO_DEPRECATED_3_0
26
4.80M
# define HAS_CALLBACK(b) ((b)->callback != NULL || (b)->callback_ex != NULL)
27
#else
28
# define HAS_CALLBACK(b) ((b)->callback_ex != NULL)
29
#endif
30
/*
31
 * Helper function to work out whether to call the new style callback or the old
32
 * one, and translate between the two.
33
 *
34
 * This has a long return type for consistency with the old callback. Similarly
35
 * for the "long" used for "inret"
36
 */
37
static long bio_call_callback(BIO *b, int oper, const char *argp, size_t len,
38
                              int argi, long argl, long inret,
39
                              size_t *processed)
40
0
{
41
0
    long ret = inret;
42
0
#ifndef OPENSSL_NO_DEPRECATED_3_0
43
0
    int bareoper;
44
45
0
    if (b->callback_ex != NULL)
46
0
#endif
47
0
        return b->callback_ex(b, oper, argp, len, argi, argl, inret, processed);
48
49
0
#ifndef OPENSSL_NO_DEPRECATED_3_0
50
    /* Strip off any BIO_CB_RETURN flag */
51
0
    bareoper = oper & ~BIO_CB_RETURN;
52
53
    /*
54
     * We have an old style callback, so we will have to do nasty casts and
55
     * check for overflows.
56
     */
57
0
    if (HAS_LEN_OPER(bareoper)) {
58
        /* In this case |len| is set, and should be used instead of |argi| */
59
0
        if (len > INT_MAX)
60
0
            return -1;
61
62
0
        argi = (int)len;
63
0
    }
64
65
0
    if (inret > 0 && (oper & BIO_CB_RETURN) && bareoper != BIO_CB_CTRL) {
66
0
        if (*processed > INT_MAX)
67
0
            return -1;
68
0
        inret = *processed;
69
0
    }
70
71
0
    ret = b->callback(b, oper, argp, argi, argl, inret);
72
73
0
    if (ret > 0 && (oper & BIO_CB_RETURN) && bareoper != BIO_CB_CTRL) {
74
0
        *processed = (size_t)ret;
75
0
        ret = 1;
76
0
    }
77
0
#endif
78
0
    return ret;
79
0
}
80
81
BIO *BIO_new_ex(OSSL_LIB_CTX *libctx, const BIO_METHOD *method)
82
270k
{
83
270k
    BIO *bio = OPENSSL_zalloc(sizeof(*bio));
84
85
270k
    if (bio == NULL)
86
0
        return NULL;
87
88
270k
    bio->libctx = libctx;
89
270k
    bio->method = method;
90
270k
    bio->shutdown = 1;
91
92
270k
    if (!CRYPTO_NEW_REF(&bio->references, 1))
93
0
        goto err;
94
95
270k
    if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_BIO, bio, &bio->ex_data))
96
0
        goto err;
97
98
270k
    if (method->create != NULL && !method->create(bio)) {
99
0
        ERR_raise(ERR_LIB_BIO, ERR_R_INIT_FAIL);
100
0
        CRYPTO_free_ex_data(CRYPTO_EX_INDEX_BIO, bio, &bio->ex_data);
101
0
        goto err;
102
0
    }
103
270k
    if (method->create == NULL)
104
0
        bio->init = 1;
105
106
270k
    return bio;
107
108
0
err:
109
0
    CRYPTO_FREE_REF(&bio->references);
110
0
    OPENSSL_free(bio);
111
0
    return NULL;
112
270k
}
113
114
BIO *BIO_new(const BIO_METHOD *method)
115
270k
{
116
270k
    return BIO_new_ex(NULL, method);
117
270k
}
118
119
int BIO_free(BIO *a)
120
595k
{
121
595k
    int ret;
122
123
595k
    if (a == NULL)
124
215k
        return 0;
125
126
380k
    if (CRYPTO_DOWN_REF(&a->references, &ret) <= 0)
127
0
        return 0;
128
129
380k
    REF_PRINT_COUNT("BIO", a);
130
380k
    if (ret > 0)
131
109k
        return 1;
132
270k
    REF_ASSERT_ISNT(ret < 0);
133
134
270k
    if (HAS_CALLBACK(a)) {
135
0
        ret = (int)bio_call_callback(a, BIO_CB_FREE, NULL, 0, 0, 0L, 1L, NULL);
136
0
        if (ret <= 0)
137
0
            return 0;
138
0
    }
139
140
270k
    if ((a->method != NULL) && (a->method->destroy != NULL))
141
270k
        a->method->destroy(a);
142
143
270k
    CRYPTO_free_ex_data(CRYPTO_EX_INDEX_BIO, a, &a->ex_data);
144
145
270k
    CRYPTO_FREE_REF(&a->references);
146
147
270k
    OPENSSL_free(a);
148
149
270k
    return 1;
150
270k
}
151
152
void BIO_set_data(BIO *a, void *ptr)
153
100k
{
154
100k
    a->ptr = ptr;
155
100k
}
156
157
void *BIO_get_data(BIO *a)
158
479k
{
159
479k
    return a->ptr;
160
479k
}
161
162
void BIO_set_init(BIO *a, int init)
163
200k
{
164
200k
    a->init = init;
165
200k
}
166
167
int BIO_get_init(BIO *a)
168
0
{
169
0
    return a->init;
170
0
}
171
172
void BIO_set_shutdown(BIO *a, int shut)
173
0
{
174
0
    a->shutdown = shut;
175
0
}
176
177
int BIO_get_shutdown(BIO *a)
178
0
{
179
0
    return a->shutdown;
180
0
}
181
182
void BIO_vfree(BIO *a)
183
0
{
184
0
    BIO_free(a);
185
0
}
186
187
int BIO_up_ref(BIO *a)
188
109k
{
189
109k
    int i;
190
191
109k
    if (CRYPTO_UP_REF(&a->references, &i) <= 0)
192
0
        return 0;
193
194
109k
    REF_PRINT_COUNT("BIO", a);
195
109k
    REF_ASSERT_ISNT(i < 2);
196
109k
    return i > 1;
197
109k
}
198
199
void BIO_clear_flags(BIO *b, int flags)
200
1.56M
{
201
1.56M
    b->flags &= ~flags;
202
1.56M
}
203
204
int BIO_test_flags(const BIO *b, int flags)
205
36.4k
{
206
36.4k
    return (b->flags & flags);
207
36.4k
}
208
209
void BIO_set_flags(BIO *b, int flags)
210
50.1k
{
211
50.1k
    b->flags |= flags;
212
50.1k
}
213
214
#ifndef OPENSSL_NO_DEPRECATED_3_0
215
BIO_callback_fn BIO_get_callback(const BIO *b)
216
0
{
217
0
    return b->callback;
218
0
}
219
220
void BIO_set_callback(BIO *b, BIO_callback_fn cb)
221
0
{
222
0
    b->callback = cb;
223
0
}
224
#endif
225
226
BIO_callback_fn_ex BIO_get_callback_ex(const BIO *b)
227
0
{
228
0
    return b->callback_ex;
229
0
}
230
231
void BIO_set_callback_ex(BIO *b, BIO_callback_fn_ex cb)
232
0
{
233
0
    b->callback_ex = cb;
234
0
}
235
236
void BIO_set_callback_arg(BIO *b, char *arg)
237
0
{
238
0
    b->cb_arg = arg;
239
0
}
240
241
char *BIO_get_callback_arg(const BIO *b)
242
0
{
243
0
    return b->cb_arg;
244
0
}
245
246
const char *BIO_method_name(const BIO *b)
247
0
{
248
0
    return b->method->name;
249
0
}
250
251
int BIO_method_type(const BIO *b)
252
0
{
253
0
    return b->method->type;
254
0
}
255
256
/*
257
 * This is essentially the same as BIO_read_ex() except that it allows
258
 * 0 or a negative value to indicate failure (retryable or not) in the return.
259
 * This is for compatibility with the old style BIO_read(), where existing code
260
 * may make assumptions about the return value that it might get.
261
 */
262
static int bio_read_intern(BIO *b, void *data, size_t dlen, size_t *readbytes)
263
399k
{
264
399k
    int ret;
265
266
399k
    if (b == NULL) {
267
0
        ERR_raise(ERR_LIB_BIO, ERR_R_PASSED_NULL_PARAMETER);
268
0
        return -1;
269
0
    }
270
399k
    if (b->method == NULL || b->method->bread == NULL) {
271
0
        ERR_raise(ERR_LIB_BIO, BIO_R_UNSUPPORTED_METHOD);
272
0
        return -2;
273
0
    }
274
275
399k
    if (HAS_CALLBACK(b) &&
276
399k
        ((ret = (int)bio_call_callback(b, BIO_CB_READ, data, dlen, 0, 0L, 1L,
277
0
                                       NULL)) <= 0))
278
0
        return ret;
279
280
399k
    if (!b->init) {
281
0
        ERR_raise(ERR_LIB_BIO, BIO_R_UNINITIALIZED);
282
0
        return -1;
283
0
    }
284
285
399k
    ret = b->method->bread(b, data, dlen, readbytes);
286
287
399k
    if (ret > 0)
288
395k
        b->num_read += (uint64_t)*readbytes;
289
290
399k
    if (HAS_CALLBACK(b))
291
0
        ret = (int)bio_call_callback(b, BIO_CB_READ | BIO_CB_RETURN, data,
292
0
                                     dlen, 0, 0L, ret, readbytes);
293
294
    /* Shouldn't happen */
295
399k
    if (ret > 0 && *readbytes > dlen) {
296
0
        ERR_raise(ERR_LIB_BIO, ERR_R_INTERNAL_ERROR);
297
0
        return -1;
298
0
    }
299
300
399k
    return ret;
301
399k
}
302
303
int BIO_read(BIO *b, void *data, int dlen)
304
226k
{
305
226k
    size_t readbytes;
306
226k
    int ret;
307
308
226k
    if (dlen < 0)
309
0
        return 0;
310
311
226k
    ret = bio_read_intern(b, data, (size_t)dlen, &readbytes);
312
313
226k
    if (ret > 0) {
314
        /* *readbytes should always be <= dlen */
315
222k
        ret = (int)readbytes;
316
222k
    }
317
318
226k
    return ret;
319
226k
}
320
321
int BIO_read_ex(BIO *b, void *data, size_t dlen, size_t *readbytes)
322
173k
{
323
173k
    return bio_read_intern(b, data, dlen, readbytes) > 0;
324
173k
}
325
326
static int bio_write_intern(BIO *b, const void *data, size_t dlen,
327
                            size_t *written)
328
77.3k
{
329
77.3k
    size_t local_written;
330
77.3k
    int ret;
331
332
77.3k
    if (written != NULL)
333
77.3k
        *written = 0;
334
    /*
335
     * b == NULL is not an error but just means that zero bytes are written.
336
     * Do not raise an error here.
337
     */
338
77.3k
    if (b == NULL)
339
0
        return 0;
340
341
77.3k
    if (b->method == NULL || b->method->bwrite == NULL) {
342
0
        ERR_raise(ERR_LIB_BIO, BIO_R_UNSUPPORTED_METHOD);
343
0
        return -2;
344
0
    }
345
346
77.3k
    if (HAS_CALLBACK(b) &&
347
77.3k
        ((ret = (int)bio_call_callback(b, BIO_CB_WRITE, data, dlen, 0, 0L, 1L,
348
0
                                       NULL)) <= 0))
349
0
        return ret;
350
351
77.3k
    if (!b->init) {
352
0
        ERR_raise(ERR_LIB_BIO, BIO_R_UNINITIALIZED);
353
0
        return -1;
354
0
    }
355
356
77.3k
    ret = b->method->bwrite(b, data, dlen, &local_written);
357
358
77.3k
    if (ret > 0)
359
77.3k
        b->num_write += (uint64_t)local_written;
360
361
77.3k
    if (HAS_CALLBACK(b))
362
0
        ret = (int)bio_call_callback(b, BIO_CB_WRITE | BIO_CB_RETURN, data,
363
0
                                     dlen, 0, 0L, ret, &local_written);
364
365
77.3k
    if (written != NULL)
366
77.3k
        *written = local_written;
367
77.3k
    return ret;
368
77.3k
}
369
370
int BIO_write(BIO *b, const void *data, int dlen)
371
74.2k
{
372
74.2k
    size_t written;
373
74.2k
    int ret;
374
375
74.2k
    if (dlen <= 0)
376
0
        return 0;
377
378
74.2k
    ret = bio_write_intern(b, data, (size_t)dlen, &written);
379
380
74.2k
    if (ret > 0) {
381
        /* written should always be <= dlen */
382
74.2k
        ret = (int)written;
383
74.2k
    }
384
385
74.2k
    return ret;
386
74.2k
}
387
388
int BIO_write_ex(BIO *b, const void *data, size_t dlen, size_t *written)
389
3.11k
{
390
3.11k
    return bio_write_intern(b, data, dlen, written) > 0
391
3.11k
        || (b != NULL && dlen == 0); /* order is important for *written */
392
3.11k
}
393
394
int BIO_sendmmsg(BIO *b, BIO_MSG *msg,
395
                 size_t stride, size_t num_msg, uint64_t flags,
396
                 size_t *msgs_processed)
397
0
{
398
0
    size_t ret;
399
0
    BIO_MMSG_CB_ARGS args;
400
401
0
    if (b == NULL) {
402
0
        *msgs_processed = 0;
403
0
        ERR_raise(ERR_LIB_BIO, ERR_R_PASSED_NULL_PARAMETER);
404
0
        return 0;
405
0
    }
406
407
0
    if (b->method == NULL || b->method->bsendmmsg == NULL) {
408
0
        *msgs_processed = 0;
409
0
        ERR_raise(ERR_LIB_BIO, BIO_R_UNSUPPORTED_METHOD);
410
0
        return 0;
411
0
    }
412
413
0
    if (HAS_CALLBACK(b)) {
414
0
        args.msg            = msg;
415
0
        args.stride         = stride;
416
0
        args.num_msg        = num_msg;
417
0
        args.flags          = flags;
418
0
        args.msgs_processed = msgs_processed;
419
420
0
        ret = (size_t)bio_call_callback(b, BIO_CB_SENDMMSG, (void *)&args,
421
0
                                        0, 0, 0, 1, NULL);
422
0
        if (ret <= 0)
423
0
            return 0;
424
0
    }
425
426
0
    if (!b->init) {
427
0
        *msgs_processed = 0;
428
0
        ERR_raise(ERR_LIB_BIO, BIO_R_UNINITIALIZED);
429
0
        return 0;
430
0
    }
431
432
0
    ret = b->method->bsendmmsg(b, msg, stride, num_msg, flags, msgs_processed);
433
434
0
    if (HAS_CALLBACK(b))
435
0
        ret = (size_t)bio_call_callback(b, BIO_CB_SENDMMSG | BIO_CB_RETURN,
436
0
                                        (void *)&args, ret, 0, 0, ret, NULL);
437
438
0
    return ret;
439
0
}
440
441
int BIO_recvmmsg(BIO *b, BIO_MSG *msg,
442
                 size_t stride, size_t num_msg, uint64_t flags,
443
                 size_t *msgs_processed)
444
0
{
445
0
    size_t ret;
446
0
    BIO_MMSG_CB_ARGS args;
447
448
0
    if (b == NULL) {
449
0
        *msgs_processed = 0;
450
0
        ERR_raise(ERR_LIB_BIO, ERR_R_PASSED_NULL_PARAMETER);
451
0
        return 0;
452
0
    }
453
454
0
    if (b->method == NULL || b->method->brecvmmsg == NULL) {
455
0
        *msgs_processed = 0;
456
0
        ERR_raise(ERR_LIB_BIO, BIO_R_UNSUPPORTED_METHOD);
457
0
        return 0;
458
0
    }
459
460
0
    if (HAS_CALLBACK(b)) {
461
0
        args.msg            = msg;
462
0
        args.stride         = stride;
463
0
        args.num_msg        = num_msg;
464
0
        args.flags          = flags;
465
0
        args.msgs_processed = msgs_processed;
466
467
0
        ret = bio_call_callback(b, BIO_CB_RECVMMSG, (void *)&args,
468
0
                                0, 0, 0, 1, NULL);
469
0
        if (ret <= 0)
470
0
            return 0;
471
0
    }
472
473
0
    if (!b->init) {
474
0
        *msgs_processed = 0;
475
0
        ERR_raise(ERR_LIB_BIO, BIO_R_UNINITIALIZED);
476
0
        return 0;
477
0
    }
478
479
0
    ret = b->method->brecvmmsg(b, msg, stride, num_msg, flags, msgs_processed);
480
481
0
    if (HAS_CALLBACK(b))
482
0
        ret = (size_t)bio_call_callback(b, BIO_CB_RECVMMSG | BIO_CB_RETURN,
483
0
                                        (void *)&args, ret, 0, 0, ret, NULL);
484
485
0
    return ret;
486
0
}
487
488
int BIO_get_rpoll_descriptor(BIO *b, BIO_POLL_DESCRIPTOR *desc)
489
0
{
490
0
    return BIO_ctrl(b, BIO_CTRL_GET_RPOLL_DESCRIPTOR, 0, desc);
491
0
}
492
493
int BIO_get_wpoll_descriptor(BIO *b, BIO_POLL_DESCRIPTOR *desc)
494
0
{
495
0
    return BIO_ctrl(b, BIO_CTRL_GET_WPOLL_DESCRIPTOR, 0, desc);
496
0
}
497
498
int BIO_puts(BIO *b, const char *buf)
499
374k
{
500
374k
    int ret;
501
374k
    size_t written = 0;
502
503
374k
    if (b == NULL) {
504
0
        ERR_raise(ERR_LIB_BIO, ERR_R_PASSED_NULL_PARAMETER);
505
0
        return -1;
506
0
    }
507
374k
    if (b->method == NULL || b->method->bputs == NULL) {
508
0
        ERR_raise(ERR_LIB_BIO, BIO_R_UNSUPPORTED_METHOD);
509
0
        return -2;
510
0
    }
511
512
374k
    if (HAS_CALLBACK(b)) {
513
0
        ret = (int)bio_call_callback(b, BIO_CB_PUTS, buf, 0, 0, 0L, 1L, NULL);
514
0
        if (ret <= 0)
515
0
            return ret;
516
0
    }
517
518
374k
    if (!b->init) {
519
0
        ERR_raise(ERR_LIB_BIO, BIO_R_UNINITIALIZED);
520
0
        return -1;
521
0
    }
522
523
374k
    ret = b->method->bputs(b, buf);
524
525
374k
    if (ret > 0) {
526
374k
        b->num_write += (uint64_t)ret;
527
374k
        written = ret;
528
374k
        ret = 1;
529
374k
    }
530
531
374k
    if (HAS_CALLBACK(b))
532
0
        ret = (int)bio_call_callback(b, BIO_CB_PUTS | BIO_CB_RETURN, buf, 0, 0,
533
0
                                     0L, ret, &written);
534
535
374k
    if (ret > 0) {
536
374k
        if (written > INT_MAX) {
537
0
            ERR_raise(ERR_LIB_BIO, BIO_R_LENGTH_TOO_LONG);
538
0
            ret = -1;
539
374k
        } else {
540
374k
            ret = (int)written;
541
374k
        }
542
374k
    }
543
544
374k
    return ret;
545
374k
}
546
547
int BIO_gets(BIO *b, char *buf, int size)
548
634k
{
549
634k
    int ret;
550
634k
    size_t readbytes = 0;
551
552
634k
    if (b == NULL) {
553
0
        ERR_raise(ERR_LIB_BIO, ERR_R_PASSED_NULL_PARAMETER);
554
0
        return -1;
555
0
    }
556
634k
    if (b->method == NULL || b->method->bgets == NULL) {
557
0
        ERR_raise(ERR_LIB_BIO, BIO_R_UNSUPPORTED_METHOD);
558
0
        return -2;
559
0
    }
560
561
634k
    if (size < 0) {
562
0
        ERR_raise(ERR_LIB_BIO, BIO_R_INVALID_ARGUMENT);
563
0
        return -1;
564
0
    }
565
566
634k
    if (HAS_CALLBACK(b)) {
567
0
        ret = (int)bio_call_callback(b, BIO_CB_GETS, buf, size, 0, 0L, 1, NULL);
568
0
        if (ret <= 0)
569
0
            return ret;
570
0
    }
571
572
634k
    if (!b->init) {
573
0
        ERR_raise(ERR_LIB_BIO, BIO_R_UNINITIALIZED);
574
0
        return -1;
575
0
    }
576
577
634k
    ret = b->method->bgets(b, buf, size);
578
579
634k
    if (ret > 0) {
580
634k
        readbytes = ret;
581
634k
        ret = 1;
582
634k
    }
583
584
634k
    if (HAS_CALLBACK(b))
585
0
        ret = (int)bio_call_callback(b, BIO_CB_GETS | BIO_CB_RETURN, buf, size,
586
0
                                     0, 0L, ret, &readbytes);
587
588
634k
    if (ret > 0) {
589
        /* Shouldn't happen */
590
634k
        if (readbytes > (size_t)size)
591
0
            ret = -1;
592
634k
        else
593
634k
            ret = (int)readbytes;
594
634k
    }
595
596
634k
    return ret;
597
634k
}
598
599
int BIO_get_line(BIO *bio, char *buf, int size)
600
0
{
601
0
    int ret = 0;
602
0
    char *ptr = buf;
603
604
0
    if (buf == NULL) {
605
0
        ERR_raise(ERR_LIB_BIO, ERR_R_PASSED_NULL_PARAMETER);
606
0
        return -1;
607
0
    }
608
0
    if (size <= 0) {
609
0
        ERR_raise(ERR_LIB_BIO, BIO_R_INVALID_ARGUMENT);
610
0
        return -1;
611
0
    }
612
0
    *buf = '\0';
613
614
0
    if (bio == NULL) {
615
0
        ERR_raise(ERR_LIB_BIO, ERR_R_PASSED_NULL_PARAMETER);
616
0
        return -1;
617
0
    }
618
0
    if (!bio->init) {
619
0
        ERR_raise(ERR_LIB_BIO, BIO_R_UNINITIALIZED);
620
0
        return -1;
621
0
    }
622
623
0
    while (size-- > 1 && (ret = BIO_read(bio, ptr, 1)) > 0)
624
0
        if (*ptr++ == '\n')
625
0
            break;
626
0
    *ptr = '\0';
627
0
    return ret > 0 || BIO_eof(bio) ? ptr - buf : ret;
628
0
}
629
630
int BIO_indent(BIO *b, int indent, int max)
631
0
{
632
0
    if (indent < 0)
633
0
        indent = 0;
634
0
    if (indent > max)
635
0
        indent = max;
636
0
    while (indent--)
637
0
        if (BIO_puts(b, " ") != 1)
638
0
            return 0;
639
0
    return 1;
640
0
}
641
642
long BIO_int_ctrl(BIO *b, int cmd, long larg, int iarg)
643
4.56k
{
644
4.56k
    int i;
645
646
4.56k
    i = iarg;
647
4.56k
    return BIO_ctrl(b, cmd, larg, (char *)&i);
648
4.56k
}
649
650
void *BIO_ptr_ctrl(BIO *b, int cmd, long larg)
651
0
{
652
0
    void *p = NULL;
653
654
0
    if (BIO_ctrl(b, cmd, larg, (char *)&p) <= 0)
655
0
        return NULL;
656
0
    else
657
0
        return p;
658
0
}
659
660
long BIO_ctrl(BIO *b, int cmd, long larg, void *parg)
661
542k
{
662
542k
    long ret;
663
664
542k
    if (b == NULL)
665
0
        return -1;
666
542k
    if (b->method == NULL || b->method->ctrl == NULL) {
667
0
        ERR_raise(ERR_LIB_BIO, BIO_R_UNSUPPORTED_METHOD);
668
0
        return -2;
669
0
    }
670
671
542k
    if (HAS_CALLBACK(b)) {
672
0
        ret = bio_call_callback(b, BIO_CB_CTRL, parg, 0, cmd, larg, 1L, NULL);
673
0
        if (ret <= 0)
674
0
            return ret;
675
0
    }
676
677
542k
    ret = b->method->ctrl(b, cmd, larg, parg);
678
679
542k
    if (HAS_CALLBACK(b))
680
0
        ret = bio_call_callback(b, BIO_CB_CTRL | BIO_CB_RETURN, parg, 0, cmd,
681
0
                                larg, ret, NULL);
682
683
542k
    return ret;
684
542k
}
685
686
long BIO_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp)
687
0
{
688
0
    long ret;
689
690
0
    if (b == NULL)
691
0
        return -2;
692
0
    if (b->method == NULL || b->method->callback_ctrl == NULL
693
0
            || cmd != BIO_CTRL_SET_CALLBACK) {
694
0
        ERR_raise(ERR_LIB_BIO, BIO_R_UNSUPPORTED_METHOD);
695
0
        return -2;
696
0
    }
697
698
0
    if (HAS_CALLBACK(b)) {
699
0
        ret = bio_call_callback(b, BIO_CB_CTRL, (void *)&fp, 0, cmd, 0, 1L,
700
0
                                NULL);
701
0
        if (ret <= 0)
702
0
            return ret;
703
0
    }
704
705
0
    ret = b->method->callback_ctrl(b, cmd, fp);
706
707
0
    if (HAS_CALLBACK(b))
708
0
        ret = bio_call_callback(b, BIO_CB_CTRL | BIO_CB_RETURN, (void *)&fp, 0,
709
0
                                cmd, 0, ret, NULL);
710
711
0
    return ret;
712
0
}
713
714
/*
715
 * It is unfortunate to duplicate in functions what the BIO_(w)pending macros
716
 * do; but those macros have inappropriate return type, and for interfacing
717
 * from other programming languages, C macros aren't much of a help anyway.
718
 */
719
size_t BIO_ctrl_pending(BIO *bio)
720
0
{
721
0
    long ret = BIO_ctrl(bio, BIO_CTRL_PENDING, 0, NULL);
722
723
0
    if (ret < 0)
724
0
        ret = 0;
725
#if LONG_MAX > SIZE_MAX
726
    if (ret > SIZE_MAX)
727
        ret = SIZE_MAX;
728
#endif
729
0
    return (size_t)ret;
730
0
}
731
732
size_t BIO_ctrl_wpending(BIO *bio)
733
0
{
734
0
    long ret = BIO_ctrl(bio, BIO_CTRL_WPENDING, 0, NULL);
735
736
0
    if (ret < 0)
737
0
        ret = 0;
738
#if LONG_MAX > SIZE_MAX
739
    if (ret > SIZE_MAX)
740
        ret = SIZE_MAX;
741
#endif
742
0
    return (size_t)ret;
743
0
}
744
745
/* put the 'bio' on the end of b's list of operators */
746
BIO *BIO_push(BIO *b, BIO *bio)
747
4.56k
{
748
4.56k
    BIO *lb;
749
750
4.56k
    if (b == NULL)
751
0
        return bio;
752
4.56k
    lb = b;
753
4.56k
    while (lb->next_bio != NULL)
754
0
        lb = lb->next_bio;
755
4.56k
    lb->next_bio = bio;
756
4.56k
    if (bio != NULL)
757
4.56k
        bio->prev_bio = lb;
758
    /* called to do internal processing */
759
4.56k
    BIO_ctrl(b, BIO_CTRL_PUSH, 0, lb);
760
4.56k
    return b;
761
4.56k
}
762
763
/* Remove the first and return the rest */
764
BIO *BIO_pop(BIO *b)
765
4.56k
{
766
4.56k
    BIO *ret;
767
768
4.56k
    if (b == NULL)
769
0
        return NULL;
770
4.56k
    ret = b->next_bio;
771
772
4.56k
    BIO_ctrl(b, BIO_CTRL_POP, 0, b);
773
774
4.56k
    if (b->prev_bio != NULL)
775
0
        b->prev_bio->next_bio = b->next_bio;
776
4.56k
    if (b->next_bio != NULL)
777
4.56k
        b->next_bio->prev_bio = b->prev_bio;
778
779
4.56k
    b->next_bio = NULL;
780
4.56k
    b->prev_bio = NULL;
781
4.56k
    return ret;
782
4.56k
}
783
784
BIO *BIO_get_retry_BIO(BIO *bio, int *reason)
785
0
{
786
0
    BIO *b, *last;
787
788
0
    b = last = bio;
789
0
    for (;;) {
790
0
        if (!BIO_should_retry(b))
791
0
            break;
792
0
        last = b;
793
0
        b = b->next_bio;
794
0
        if (b == NULL)
795
0
            break;
796
0
    }
797
0
    if (reason != NULL)
798
0
        *reason = last->retry_reason;
799
0
    return last;
800
0
}
801
802
int BIO_get_retry_reason(BIO *bio)
803
0
{
804
0
    return bio->retry_reason;
805
0
}
806
807
void BIO_set_retry_reason(BIO *bio, int reason)
808
0
{
809
0
    bio->retry_reason = reason;
810
0
}
811
812
BIO *BIO_find_type(BIO *bio, int type)
813
0
{
814
0
    int mt, mask;
815
816
0
    if (bio == NULL) {
817
0
        ERR_raise(ERR_LIB_BIO, ERR_R_PASSED_NULL_PARAMETER);
818
0
        return NULL;
819
0
    }
820
0
    mask = type & BIO_TYPE_MASK;
821
0
    do {
822
0
        if (bio->method != NULL) {
823
0
            mt = bio->method->type;
824
825
0
            if (!mask) {
826
0
                if (mt & type)
827
0
                    return bio;
828
0
            } else if (mt == type) {
829
0
                return bio;
830
0
            }
831
0
        }
832
0
        bio = bio->next_bio;
833
0
    } while (bio != NULL);
834
0
    return NULL;
835
0
}
836
837
BIO *BIO_next(BIO *b)
838
30.7k
{
839
30.7k
    if (b == NULL)
840
0
        return NULL;
841
30.7k
    return b->next_bio;
842
30.7k
}
843
844
void BIO_set_next(BIO *b, BIO *next)
845
0
{
846
0
    b->next_bio = next;
847
0
}
848
849
void BIO_free_all(BIO *bio)
850
18.2k
{
851
18.2k
    BIO *b;
852
18.2k
    int ref;
853
854
27.3k
    while (bio != NULL) {
855
9.12k
        b = bio;
856
9.12k
        CRYPTO_GET_REF(&b->references, &ref);
857
9.12k
        bio = bio->next_bio;
858
9.12k
        BIO_free(b);
859
        /* Since ref count > 1, don't free anyone else. */
860
9.12k
        if (ref > 1)
861
0
            break;
862
9.12k
    }
863
18.2k
}
864
865
BIO *BIO_dup_chain(BIO *in)
866
0
{
867
0
    BIO *ret = NULL, *eoc = NULL, *bio, *new_bio;
868
869
0
    for (bio = in; bio != NULL; bio = bio->next_bio) {
870
0
        if ((new_bio = BIO_new(bio->method)) == NULL)
871
0
            goto err;
872
0
#ifndef OPENSSL_NO_DEPRECATED_3_0
873
0
        new_bio->callback = bio->callback;
874
0
#endif
875
0
        new_bio->callback_ex = bio->callback_ex;
876
0
        new_bio->cb_arg = bio->cb_arg;
877
0
        new_bio->init = bio->init;
878
0
        new_bio->shutdown = bio->shutdown;
879
0
        new_bio->flags = bio->flags;
880
881
        /* This will let SSL_s_sock() work with stdin/stdout */
882
0
        new_bio->num = bio->num;
883
884
0
        if (BIO_dup_state(bio, (char *)new_bio) <= 0) {
885
0
            BIO_free(new_bio);
886
0
            goto err;
887
0
        }
888
889
        /* copy app data */
890
0
        if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_BIO, &new_bio->ex_data,
891
0
                                &bio->ex_data)) {
892
0
            BIO_free(new_bio);
893
0
            goto err;
894
0
        }
895
896
0
        if (ret == NULL) {
897
0
            eoc = new_bio;
898
0
            ret = eoc;
899
0
        } else {
900
0
            BIO_push(eoc, new_bio);
901
0
            eoc = new_bio;
902
0
        }
903
0
    }
904
0
    return ret;
905
0
 err:
906
0
    BIO_free_all(ret);
907
908
0
    return NULL;
909
0
}
910
911
void BIO_copy_next_retry(BIO *b)
912
32.2k
{
913
32.2k
    BIO_set_flags(b, BIO_get_retry_flags(b->next_bio));
914
32.2k
    b->retry_reason = b->next_bio->retry_reason;
915
32.2k
}
916
917
int BIO_set_ex_data(BIO *bio, int idx, void *data)
918
0
{
919
0
    return CRYPTO_set_ex_data(&(bio->ex_data), idx, data);
920
0
}
921
922
void *BIO_get_ex_data(const BIO *bio, int idx)
923
0
{
924
0
    return CRYPTO_get_ex_data(&(bio->ex_data), idx);
925
0
}
926
927
uint64_t BIO_number_read(BIO *bio)
928
0
{
929
0
    if (bio)
930
0
        return bio->num_read;
931
0
    return 0;
932
0
}
933
934
uint64_t BIO_number_written(BIO *bio)
935
0
{
936
0
    if (bio)
937
0
        return bio->num_write;
938
0
    return 0;
939
0
}
940
941
void bio_free_ex_data(BIO *bio)
942
0
{
943
0
    CRYPTO_free_ex_data(CRYPTO_EX_INDEX_BIO, bio, &bio->ex_data);
944
0
}
945
946
void bio_cleanup(void)
947
2
{
948
2
#ifndef OPENSSL_NO_SOCK
949
2
    bio_sock_cleanup_int();
950
2
    CRYPTO_THREAD_lock_free(bio_lookup_lock);
951
2
    bio_lookup_lock = NULL;
952
2
#endif
953
2
    CRYPTO_FREE_REF(&bio_type_count);
954
2
}
955
956
/* Internal variant of the below BIO_wait() not calling ERR_raise(...) */
957
static int bio_wait(BIO *bio, time_t max_time, unsigned int nap_milliseconds)
958
0
{
959
0
#ifndef OPENSSL_NO_SOCK
960
0
    int fd;
961
0
#endif
962
0
    long sec_diff;
963
964
0
    if (max_time == 0) /* no timeout */
965
0
        return 1;
966
967
0
#ifndef OPENSSL_NO_SOCK
968
0
    if (BIO_get_fd(bio, &fd) > 0) {
969
0
        int ret = BIO_socket_wait(fd, BIO_should_read(bio), max_time);
970
971
0
        if (ret != -1)
972
0
            return ret;
973
0
    }
974
0
#endif
975
    /* fall back to polling since no sockets are available */
976
977
0
    sec_diff = (long)(max_time - time(NULL)); /* might overflow */
978
0
    if (sec_diff < 0)
979
0
        return 0; /* clearly timeout */
980
981
    /* now take a nap at most the given number of milliseconds */
982
0
    if (sec_diff == 0) { /* we are below the 1 seconds resolution of max_time */
983
0
        if (nap_milliseconds > 1000)
984
0
            nap_milliseconds = 1000;
985
0
    } else { /* for sec_diff > 0, take min(sec_diff * 1000, nap_milliseconds) */
986
0
        if ((unsigned long)sec_diff * 1000 < nap_milliseconds)
987
0
            nap_milliseconds = (unsigned int)sec_diff * 1000;
988
0
    }
989
0
    OSSL_sleep(nap_milliseconds);
990
0
    return 1;
991
0
}
992
993
/*-
994
 * Wait on (typically socket-based) BIO at most until max_time.
995
 * Succeed immediately if max_time == 0.
996
 * If sockets are not available support polling: succeed after waiting at most
997
 * the number of nap_milliseconds in order to avoid a tight busy loop.
998
 * Call ERR_raise(ERR_LIB_BIO, ...) on timeout or error.
999
 * Returns -1 on error, 0 on timeout, and 1 on success.
1000
 */
1001
int BIO_wait(BIO *bio, time_t max_time, unsigned int nap_milliseconds)
1002
0
{
1003
0
    int rv = bio_wait(bio, max_time, nap_milliseconds);
1004
1005
0
    if (rv <= 0)
1006
0
        ERR_raise(ERR_LIB_BIO,
1007
0
                  rv == 0 ? BIO_R_TRANSFER_TIMEOUT : BIO_R_TRANSFER_ERROR);
1008
0
    return rv;
1009
0
}
1010
1011
/*
1012
 * Connect via given BIO using BIO_do_connect() until success/timeout/error.
1013
 * Parameter timeout == 0 means no timeout, < 0 means exactly one try.
1014
 * For non-blocking and potentially even non-socket BIOs perform polling with
1015
 * the given density: between polls sleep nap_milliseconds using BIO_wait()
1016
 * in order to avoid a tight busy loop.
1017
 * Returns -1 on error, 0 on timeout, and 1 on success.
1018
 */
1019
int BIO_do_connect_retry(BIO *bio, int timeout, int nap_milliseconds)
1020
0
{
1021
0
    int blocking = timeout <= 0;
1022
0
    time_t max_time = timeout > 0 ? time(NULL) + timeout : 0;
1023
0
    int rv;
1024
1025
0
    if (bio == NULL) {
1026
0
        ERR_raise(ERR_LIB_BIO, ERR_R_PASSED_NULL_PARAMETER);
1027
0
        return -1;
1028
0
    }
1029
1030
0
    if (nap_milliseconds < 0)
1031
0
        nap_milliseconds = 100;
1032
0
    BIO_set_nbio(bio, !blocking);
1033
1034
0
 retry:
1035
0
    ERR_set_mark();
1036
0
    rv = BIO_do_connect(bio);
1037
1038
0
    if (rv <= 0) { /* could be timeout or retryable error or fatal error */
1039
0
        int err = ERR_peek_last_error();
1040
0
        int reason = ERR_GET_REASON(err);
1041
0
        int do_retry = BIO_should_retry(bio); /* may be 1 only if !blocking */
1042
1043
0
        if (ERR_GET_LIB(err) == ERR_LIB_BIO) {
1044
0
            switch (reason) {
1045
0
            case ERR_R_SYS_LIB:
1046
                /*
1047
                 * likely retryable system error occurred, which may be
1048
                 * EAGAIN (resource temporarily unavailable) some 40 secs after
1049
                 * calling getaddrinfo(): Temporary failure in name resolution
1050
                 * or a premature ETIMEDOUT, some 30 seconds after connect()
1051
                 */
1052
0
            case BIO_R_CONNECT_ERROR:
1053
0
            case BIO_R_NBIO_CONNECT_ERROR:
1054
                /* some likely retryable connection error occurred */
1055
0
                (void)BIO_reset(bio); /* often needed to avoid retry failure */
1056
0
                do_retry = 1;
1057
0
                break;
1058
0
            default:
1059
0
                break;
1060
0
            }
1061
0
        }
1062
0
        if (timeout >= 0 && do_retry) {
1063
0
            ERR_pop_to_mark();
1064
            /* will not actually wait if timeout == 0 (i.e., blocking BIO): */
1065
0
            rv = bio_wait(bio, max_time, nap_milliseconds);
1066
0
            if (rv > 0)
1067
0
                goto retry;
1068
0
            ERR_raise(ERR_LIB_BIO,
1069
0
                      rv == 0 ? BIO_R_CONNECT_TIMEOUT : BIO_R_CONNECT_ERROR);
1070
0
        } else {
1071
0
            ERR_clear_last_mark();
1072
0
            rv = -1;
1073
0
            if (err == 0) /* missing error queue entry */
1074
                /* workaround: general error */
1075
0
                ERR_raise(ERR_LIB_BIO, BIO_R_CONNECT_ERROR);
1076
0
        }
1077
0
    } else {
1078
0
        ERR_clear_last_mark();
1079
0
    }
1080
1081
0
    return rv;
1082
0
}