bio_lib.c 25.2 KB
Newer Older
R
Rich Salz 已提交
1
/*
R
Richard Levitte 已提交
2
 * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.
3
 *
4
 * Licensed under the Apache License 2.0 (the "License").  You may not use
R
Rich Salz 已提交
5 6 7
 * this file except in compliance with the License.  You can obtain a copy
 * in the file LICENSE in the source distribution or at
 * https://www.openssl.org/source/license.html
8 9
 */

10 11
#define OPENSSL_SUPPRESS_DEPRECATED

12 13
#include <stdio.h>
#include <errno.h>
14
#include <openssl/crypto.h>
15
#include "internal/numbers.h"
16
#include "bio_local.h"
17

18 19 20 21
/*
 * Helper macro for the callback to determine whether an operator expects a
 * len parameter or not
 */
22 23
#define HAS_LEN_OPER(o) ((o) == BIO_CB_READ || (o) == BIO_CB_WRITE \
                         || (o) == BIO_CB_GETS)
24

25 26 27 28 29
#ifndef OPENSSL_NO_DEPRECATED_3_0
# define HAS_CALLBACK(b) ((b)->callback != NULL || (b)->callback_ex != NULL)
#else
# define HAS_CALLBACK(b) ((b)->callback_ex != NULL)
#endif
30 31 32 33 34 35 36 37
/*
 * Helper function to work out whether to call the new style callback or the old
 * one, and translate between the two.
 *
 * This has a long return type for consistency with the old callback. Similarly
 * for the "long" used for "inret"
 */
static long bio_call_callback(BIO *b, int oper, const char *argp, size_t len,
38 39
                              int argi, long argl, long inret,
                              size_t *processed)
40
{
41 42
    long ret = inret;
#ifndef OPENSSL_NO_DEPRECATED_3_0
43 44
    int bareoper;

45
    if (b->callback_ex != NULL)
46
#endif
47 48
        return b->callback_ex(b, oper, argp, len, argi, argl, inret, processed);

49
#ifndef OPENSSL_NO_DEPRECATED_3_0
50 51 52 53 54 55 56 57 58 59 60 61 62
    /* Strip off any BIO_CB_RETURN flag */
    bareoper = oper & ~BIO_CB_RETURN;

    /*
     * We have an old style callback, so we will have to do nasty casts and
     * check for overflows.
     */
    if (HAS_LEN_OPER(bareoper)) {
        /* In this case |len| is set, and should be used instead of |argi| */
        if (len > INT_MAX)
            return -1;

        argi = (int)len;
63
    }
64

65
    if (inret > 0 && (oper & BIO_CB_RETURN) && bareoper != BIO_CB_CTRL) {
66 67 68
        if (*processed > INT_MAX)
            return -1;
        inret = *processed;
69 70 71 72
    }

    ret = b->callback(b, oper, argp, argi, argl, inret);

73
    if (ret > 0 && (oper & BIO_CB_RETURN) && bareoper != BIO_CB_CTRL) {
74 75 76
        *processed = (size_t)ret;
        ret = 1;
    }
77
#endif
78 79 80
    return ret;
}

81
BIO *BIO_new_ex(OSSL_LIB_CTX *libctx, const BIO_METHOD *method)
82
{
F
FdaSilvaYY 已提交
83
    BIO *bio = OPENSSL_zalloc(sizeof(*bio));
84

F
FdaSilvaYY 已提交
85
    if (bio == NULL) {
86
        ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE);
K
KaoruToda 已提交
87
        return NULL;
88
    }
89

90
    bio->libctx = libctx;
91 92 93
    bio->method = method;
    bio->shutdown = 1;
    bio->references = 1;
F
FdaSilvaYY 已提交
94

95
    if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_BIO, bio, &bio->ex_data))
F
FdaSilvaYY 已提交
96
        goto err;
97 98 99

    bio->lock = CRYPTO_THREAD_lock_new();
    if (bio->lock == NULL) {
100
        ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE);
101
        CRYPTO_free_ex_data(CRYPTO_EX_INDEX_BIO, bio, &bio->ex_data);
F
FdaSilvaYY 已提交
102
        goto err;
103 104
    }

F
FdaSilvaYY 已提交
105
    if (method->create != NULL && !method->create(bio)) {
106
        ERR_raise(ERR_LIB_BIO, ERR_R_INIT_FAIL);
F
FdaSilvaYY 已提交
107 108 109
        CRYPTO_free_ex_data(CRYPTO_EX_INDEX_BIO, bio, &bio->ex_data);
        CRYPTO_THREAD_lock_free(bio->lock);
        goto err;
110
    }
111 112
    if (method->create == NULL)
        bio->init = 1;
113

F
FdaSilvaYY 已提交
114 115 116 117 118
    return bio;

err:
    OPENSSL_free(bio);
    return NULL;
119
}
120

121 122 123 124 125
BIO *BIO_new(const BIO_METHOD *method)
{
    return BIO_new_ex(NULL, method);
}

U
Ulf Möller 已提交
126
int BIO_free(BIO *a)
127
{
128
    int ret;
129

130
    if (a == NULL)
131 132
        return 0;

133
    if (CRYPTO_DOWN_REF(&a->references, &ret, a->lock) <= 0)
134
        return 0;
135

R
Rich Salz 已提交
136
    REF_PRINT_COUNT("BIO", a);
137
    if (ret > 0)
138
        return 1;
139 140
    REF_ASSERT_ISNT(ret < 0);

141
    if (HAS_CALLBACK(a)) {
142 143
        ret = (int)bio_call_callback(a, BIO_CB_FREE, NULL, 0, 0, 0L, 1L, NULL);
        if (ret <= 0)
P
Peiwei Hu 已提交
144
            return 0;
145
    }
146

147 148 149
    if ((a->method != NULL) && (a->method->destroy != NULL))
        a->method->destroy(a);

150
    CRYPTO_free_ex_data(CRYPTO_EX_INDEX_BIO, a, &a->ex_data);
151

152 153
    CRYPTO_THREAD_lock_free(a->lock);

154
    OPENSSL_free(a);
155 156

    return 1;
157
}
158

M
Matt Caswell 已提交
159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188
void BIO_set_data(BIO *a, void *ptr)
{
    a->ptr = ptr;
}

void *BIO_get_data(BIO *a)
{
    return a->ptr;
}

void BIO_set_init(BIO *a, int init)
{
    a->init = init;
}

int BIO_get_init(BIO *a)
{
    return a->init;
}

void BIO_set_shutdown(BIO *a, int shut)
{
    a->shutdown = shut;
}

int BIO_get_shutdown(BIO *a)
{
    return a->shutdown;
}

B
Ben Laurie 已提交
189
void BIO_vfree(BIO *a)
190 191 192
{
    BIO_free(a);
}
B
Ben Laurie 已提交
193

194 195 196 197
int BIO_up_ref(BIO *a)
{
    int i;

198
    if (CRYPTO_UP_REF(&a->references, &i, a->lock) <= 0)
199 200 201 202
        return 0;

    REF_PRINT_COUNT("BIO", a);
    REF_ASSERT_ISNT(i < 2);
203
    return i > 1;
204 205
}

N
Nils Larsch 已提交
206
void BIO_clear_flags(BIO *b, int flags)
207 208 209 210 211 212 213 214 215 216 217 218 219 220
{
    b->flags &= ~flags;
}

int BIO_test_flags(const BIO *b, int flags)
{
    return (b->flags & flags);
}

void BIO_set_flags(BIO *b, int flags)
{
    b->flags |= flags;
}

221
#ifndef OPENSSL_NO_DEPRECATED_3_0
222 223
BIO_callback_fn BIO_get_callback(const BIO *b)
{
224 225 226
    return b->callback;
}

227
void BIO_set_callback(BIO *b, BIO_callback_fn cb)
228 229 230
{
    b->callback = cb;
}
231
#endif
N
Nils Larsch 已提交
232

233 234 235 236 237 238 239 240 241 242
BIO_callback_fn_ex BIO_get_callback_ex(const BIO *b)
{
    return b->callback_ex;
}

void BIO_set_callback_ex(BIO *b, BIO_callback_fn_ex cb)
{
    b->callback_ex = cb;
}

N
Nils Larsch 已提交
243
void BIO_set_callback_arg(BIO *b, char *arg)
244 245 246
{
    b->cb_arg = arg;
}
N
Nils Larsch 已提交
247

248 249 250 251
char *BIO_get_callback_arg(const BIO *b)
{
    return b->cb_arg;
}
N
Nils Larsch 已提交
252

253 254 255 256
const char *BIO_method_name(const BIO *b)
{
    return b->method->name;
}
N
Nils Larsch 已提交
257 258

int BIO_method_type(const BIO *b)
259 260 261
{
    return b->method->type;
}
N
Nils Larsch 已提交
262

263 264
/*
 * This is essentially the same as BIO_read_ex() except that it allows
265 266 267
 * 0 or a negative value to indicate failure (retryable or not) in the return.
 * This is for compatibility with the old style BIO_read(), where existing code
 * may make assumptions about the return value that it might get.
268
 */
M
Matt Caswell 已提交
269
static int bio_read_intern(BIO *b, void *data, size_t dlen, size_t *readbytes)
270 271
{
    int ret;
272

273
    if (b == NULL) {
274
        ERR_raise(ERR_LIB_BIO, ERR_R_PASSED_NULL_PARAMETER);
275 276 277
        return -1;
    }
    if (b->method == NULL || b->method->bread == NULL) {
278
        ERR_raise(ERR_LIB_BIO, BIO_R_UNSUPPORTED_METHOD);
279
        return -2;
280
    }
281

282
    if (HAS_CALLBACK(b) &&
283
        ((ret = (int)bio_call_callback(b, BIO_CB_READ, data, dlen, 0, 0L, 1L,
284
                                       NULL)) <= 0))
285
        return ret;
286

287
    if (!b->init) {
288
        ERR_raise(ERR_LIB_BIO, BIO_R_UNINITIALIZED);
289
        return -1;
290
    }
291

M
Matt Caswell 已提交
292
    ret = b->method->bread(b, data, dlen, readbytes);
293

294
    if (ret > 0)
M
Matt Caswell 已提交
295
        b->num_read += (uint64_t)*readbytes;
296

297
    if (HAS_CALLBACK(b))
298
        ret = (int)bio_call_callback(b, BIO_CB_READ | BIO_CB_RETURN, data,
M
Matt Caswell 已提交
299
                                     dlen, 0, 0L, ret, readbytes);
300

301
    /* Shouldn't happen */
M
Matt Caswell 已提交
302
    if (ret > 0 && *readbytes > dlen) {
303
        ERR_raise(ERR_LIB_BIO, ERR_R_INTERNAL_ERROR);
304
        return -1;
305
    }
306

307
    return ret;
308
}
309

310
int BIO_read(BIO *b, void *data, int dlen)
311
{
M
Matt Caswell 已提交
312
    size_t readbytes;
313 314
    int ret;

315
    if (dlen < 0)
316 317
        return 0;

M
Matt Caswell 已提交
318
    ret = bio_read_intern(b, data, (size_t)dlen, &readbytes);
319 320

    if (ret > 0) {
321
        /* *readbytes should always be <= dlen */
M
Matt Caswell 已提交
322
        ret = (int)readbytes;
323 324 325 326 327
    }

    return ret;
}

M
Matt Caswell 已提交
328
int BIO_read_ex(BIO *b, void *data, size_t dlen, size_t *readbytes)
329
{
330
    return bio_read_intern(b, data, dlen, readbytes) > 0;
331 332
}

333
static int bio_write_intern(BIO *b, const void *data, size_t dlen,
334
                            size_t *written)
335
{
336
    size_t local_written;
337
    int ret;
338

339 340
    if (written != NULL)
        *written = 0;
341 342 343 344 345 346 347
    /*
     * b == NULL is not an error but just means that zero bytes are written.
     * Do not raise an error here.
     */
    if (b == NULL)
        return 0;

348
    if (b->method == NULL || b->method->bwrite == NULL) {
349
        ERR_raise(ERR_LIB_BIO, BIO_R_UNSUPPORTED_METHOD);
350
        return -2;
351
    }
352

353
    if (HAS_CALLBACK(b) &&
354
        ((ret = (int)bio_call_callback(b, BIO_CB_WRITE, data, dlen, 0, 0L, 1L,
355
                                       NULL)) <= 0))
356
        return ret;
357

358
    if (!b->init) {
359
        ERR_raise(ERR_LIB_BIO, BIO_R_UNINITIALIZED);
360
        return -1;
361
    }
362

363
    ret = b->method->bwrite(b, data, dlen, &local_written);
364

365
    if (ret > 0)
366
        b->num_write += (uint64_t)local_written;
367

368
    if (HAS_CALLBACK(b))
369
        ret = (int)bio_call_callback(b, BIO_CB_WRITE | BIO_CB_RETURN, data,
370
                                     dlen, 0, 0L, ret, &local_written);
371

372 373
    if (written != NULL)
        *written = local_written;
374
    return ret;
375
}
376

377
int BIO_write(BIO *b, const void *data, int dlen)
378 379 380 381
{
    size_t written;
    int ret;

382
    if (dlen <= 0)
383 384
        return 0;

385
    ret = bio_write_intern(b, data, (size_t)dlen, &written);
386 387

    if (ret > 0) {
388
        /* written should always be <= dlen */
389 390 391 392 393 394
        ret = (int)written;
    }

    return ret;
}

395
int BIO_write_ex(BIO *b, const void *data, size_t dlen, size_t *written)
396
{
397 398
    return bio_write_intern(b, data, dlen, written) > 0
        || (b != NULL && dlen == 0); /* order is important for *written */
399 400
}

401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494
int BIO_sendmmsg(BIO *b, BIO_MSG *msg,
                 size_t stride, size_t num_msg, uint64_t flags,
                 size_t *msgs_processed)
{
    size_t ret;
    BIO_MMSG_CB_ARGS args;

    if (b == NULL) {
        *msgs_processed = 0;
        ERR_raise(ERR_LIB_BIO, ERR_R_PASSED_NULL_PARAMETER);
        return 0;
    }

    if (b->method == NULL || b->method->bsendmmsg == NULL) {
        *msgs_processed = 0;
        ERR_raise(ERR_LIB_BIO, BIO_R_UNSUPPORTED_METHOD);
        return 0;
    }

    if (HAS_CALLBACK(b)) {
        args.msg            = msg;
        args.stride         = stride;
        args.num_msg        = num_msg;
        args.flags          = flags;
        args.msgs_processed = msgs_processed;

        ret = (size_t)bio_call_callback(b, BIO_CB_SENDMMSG, (void *)&args,
                                        0, 0, 0, 0, NULL);
        if (ret == 0)
            return 0;
    }

    if (!b->init) {
        *msgs_processed = 0;
        ERR_raise(ERR_LIB_BIO, BIO_R_UNINITIALIZED);
        return 0;
    }

    ret = b->method->bsendmmsg(b, msg, stride, num_msg, flags, msgs_processed);

    if (HAS_CALLBACK(b))
        ret = (size_t)bio_call_callback(b, BIO_CB_SENDMMSG | BIO_CB_RETURN,
                                        (void *)&args, ret, 0, 0, 0, NULL);

    return ret;
}

int BIO_recvmmsg(BIO *b, BIO_MSG *msg,
                 size_t stride, size_t num_msg, uint64_t flags,
                 size_t *msgs_processed)
{
    size_t ret;
    BIO_MMSG_CB_ARGS args;

    if (b == NULL) {
        *msgs_processed = 0;
        ERR_raise(ERR_LIB_BIO, ERR_R_PASSED_NULL_PARAMETER);
        return 0;
    }

    if (b->method == NULL || b->method->brecvmmsg == NULL) {
        *msgs_processed = 0;
        ERR_raise(ERR_LIB_BIO, BIO_R_UNSUPPORTED_METHOD);
        return 0;
    }

    if (HAS_CALLBACK(b)) {
        args.msg            = msg;
        args.stride         = stride;
        args.num_msg        = num_msg;
        args.flags          = flags;
        args.msgs_processed = msgs_processed;

        ret = bio_call_callback(b, BIO_CB_RECVMMSG, (void *)&args,
                                0, 0, 0, 0, NULL);
        if (ret == 0)
            return 0;
    }

    if (!b->init) {
        *msgs_processed = 0;
        ERR_raise(ERR_LIB_BIO, BIO_R_UNINITIALIZED);
        return 0;
    }

    ret = b->method->brecvmmsg(b, msg, stride, num_msg, flags, msgs_processed);

    if (HAS_CALLBACK(b))
        ret = (size_t)bio_call_callback(b, BIO_CB_RECVMMSG | BIO_CB_RETURN,
                                        (void *)&args, ret, 0, 0, 0, NULL);

    return ret;
}

495
int BIO_puts(BIO *b, const char *buf)
496
{
497
    int ret;
498
    size_t written = 0;
499

500
    if (b == NULL) {
501
        ERR_raise(ERR_LIB_BIO, ERR_R_PASSED_NULL_PARAMETER);
502 503 504
        return -1;
    }
    if (b->method == NULL || b->method->bputs == NULL) {
505
        ERR_raise(ERR_LIB_BIO, BIO_R_UNSUPPORTED_METHOD);
506
        return -2;
507
    }
508

509
    if (HAS_CALLBACK(b)) {
510
        ret = (int)bio_call_callback(b, BIO_CB_PUTS, buf, 0, 0, 0L, 1L, NULL);
511 512 513
        if (ret <= 0)
            return ret;
    }
514

515
    if (!b->init) {
516
        ERR_raise(ERR_LIB_BIO, BIO_R_UNINITIALIZED);
517
        return -1;
518
    }
519

520
    ret = b->method->bputs(b, buf);
521

522 523 524 525 526 527
    if (ret > 0) {
        b->num_write += (uint64_t)ret;
        written = ret;
        ret = 1;
    }

528
    if (HAS_CALLBACK(b))
529
        ret = (int)bio_call_callback(b, BIO_CB_PUTS | BIO_CB_RETURN, buf, 0, 0,
530 531 532
                                     0L, ret, &written);

    if (ret > 0) {
533
        if (written > INT_MAX) {
534
            ERR_raise(ERR_LIB_BIO, BIO_R_LENGTH_TOO_LONG);
535
            ret = -1;
536
        } else {
537
            ret = (int)written;
538
        }
539
    }
540

541
    return ret;
542
}
543

544
int BIO_gets(BIO *b, char *buf, int size)
545
{
546
    int ret;
M
Matt Caswell 已提交
547
    size_t readbytes = 0;
548

549
    if (b == NULL) {
550
        ERR_raise(ERR_LIB_BIO, ERR_R_PASSED_NULL_PARAMETER);
551 552 553
        return -1;
    }
    if (b->method == NULL || b->method->bgets == NULL) {
554
        ERR_raise(ERR_LIB_BIO, BIO_R_UNSUPPORTED_METHOD);
K
KaoruToda 已提交
555
        return -2;
556 557
    }

558
    if (size < 0) {
559
        ERR_raise(ERR_LIB_BIO, BIO_R_INVALID_ARGUMENT);
560
        return -1;
561 562
    }

563
    if (HAS_CALLBACK(b)) {
564
        ret = (int)bio_call_callback(b, BIO_CB_GETS, buf, size, 0, 0L, 1, NULL);
565 566 567
        if (ret <= 0)
            return ret;
    }
568 569

    if (!b->init) {
570
        ERR_raise(ERR_LIB_BIO, BIO_R_UNINITIALIZED);
571
        return -1;
572 573
    }

574
    ret = b->method->bgets(b, buf, size);
575 576

    if (ret > 0) {
M
Matt Caswell 已提交
577
        readbytes = ret;
578 579 580
        ret = 1;
    }

581
    if (HAS_CALLBACK(b))
582
        ret = (int)bio_call_callback(b, BIO_CB_GETS | BIO_CB_RETURN, buf, size,
M
Matt Caswell 已提交
583
                                     0, 0L, ret, &readbytes);
584 585

    if (ret > 0) {
586
        /* Shouldn't happen */
587
        if (readbytes > (size_t)size)
588 589
            ret = -1;
        else
M
Matt Caswell 已提交
590
            ret = (int)readbytes;
591
    }
592

593
    return ret;
594 595
}

596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626
int BIO_get_line(BIO *bio, char *buf, int size)
{
    int ret = 0;
    char *ptr = buf;

    if (buf == NULL) {
        ERR_raise(ERR_LIB_BIO, ERR_R_PASSED_NULL_PARAMETER);
        return -1;
    }
    if (size <= 0) {
        ERR_raise(ERR_LIB_BIO, BIO_R_INVALID_ARGUMENT);
        return -1;
    }
    *buf = '\0';

    if (bio == NULL) {
        ERR_raise(ERR_LIB_BIO, ERR_R_PASSED_NULL_PARAMETER);
        return -1;
    }
    if (!bio->init) {
        ERR_raise(ERR_LIB_BIO, BIO_R_UNINITIALIZED);
        return -1;
    }

    while (size-- > 1 && (ret = BIO_read(bio, ptr, 1)) > 0)
        if (*ptr++ == '\n')
            break;
    *ptr = '\0';
    return ret > 0 || BIO_eof(bio) ? ptr - buf : ret;
}

627 628 629 630 631 632 633 634 635 636 637
int BIO_indent(BIO *b, int indent, int max)
{
    if (indent < 0)
        indent = 0;
    if (indent > max)
        indent = max;
    while (indent--)
        if (BIO_puts(b, " ") != 1)
            return 0;
    return 1;
}
638

U
Ulf Möller 已提交
639
long BIO_int_ctrl(BIO *b, int cmd, long larg, int iarg)
640 641
{
    int i;
642

643
    i = iarg;
K
KaoruToda 已提交
644
    return BIO_ctrl(b, cmd, larg, (char *)&i);
645
}
646

647
void *BIO_ptr_ctrl(BIO *b, int cmd, long larg)
648
{
649
    void *p = NULL;
650

651
    if (BIO_ctrl(b, cmd, larg, (char *)&p) <= 0)
K
KaoruToda 已提交
652
        return NULL;
653
    else
K
KaoruToda 已提交
654
        return p;
655
}
656

B
Bodo Möller 已提交
657
long BIO_ctrl(BIO *b, int cmd, long larg, void *parg)
658 659
{
    long ret;
660

661
    if (b == NULL)
662 663
        return -1;
    if (b->method == NULL || b->method->ctrl == NULL) {
664
        ERR_raise(ERR_LIB_BIO, BIO_R_UNSUPPORTED_METHOD);
665
        return -2;
666
    }
667

668
    if (HAS_CALLBACK(b)) {
669 670 671 672
        ret = bio_call_callback(b, BIO_CB_CTRL, parg, 0, cmd, larg, 1L, NULL);
        if (ret <= 0)
            return ret;
    }
673

674
    ret = b->method->ctrl(b, cmd, larg, parg);
675

676
    if (HAS_CALLBACK(b))
677 678 679 680
        ret = bio_call_callback(b, BIO_CB_CTRL | BIO_CB_RETURN, parg, 0, cmd,
                                larg, ret, NULL);

    return ret;
681
}
682

B
Bernd Edlinger 已提交
683
long BIO_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp)
684 685
{
    long ret;
686

687
    if (b == NULL)
688
        return -2;
689 690
    if (b->method == NULL || b->method->callback_ctrl == NULL
            || cmd != BIO_CTRL_SET_CALLBACK) {
691
        ERR_raise(ERR_LIB_BIO, BIO_R_UNSUPPORTED_METHOD);
K
KaoruToda 已提交
692
        return -2;
693
    }
694

695
    if (HAS_CALLBACK(b)) {
696 697 698 699 700
        ret = bio_call_callback(b, BIO_CB_CTRL, (void *)&fp, 0, cmd, 0, 1L,
                                NULL);
        if (ret <= 0)
            return ret;
    }
701

702
    ret = b->method->callback_ctrl(b, cmd, fp);
703

704
    if (HAS_CALLBACK(b))
705 706 707 708
        ret = bio_call_callback(b, BIO_CB_CTRL | BIO_CB_RETURN, (void *)&fp, 0,
                                cmd, 0, ret, NULL);

    return ret;
709
}
710

711 712
/*
 * It is unfortunate to duplicate in functions what the BIO_(w)pending macros
B
Bodo Möller 已提交
713
 * do; but those macros have inappropriate return type, and for interfacing
714 715
 * from other programming languages, C macros aren't much of a help anyway.
 */
B
Bodo Möller 已提交
716
size_t BIO_ctrl_pending(BIO *bio)
717
{
718 719 720 721
    long ret = BIO_ctrl(bio, BIO_CTRL_PENDING, 0, NULL);

    if (ret < 0)
        ret = 0;
722 723 724 725
#if LONG_MAX > SIZE_MAX
    if (ret > SIZE_MAX)
        ret = SIZE_MAX;
#endif
726
    return (size_t)ret;
727
}
B
Bodo Möller 已提交
728 729

size_t BIO_ctrl_wpending(BIO *bio)
730
{
731 732 733 734
    long ret = BIO_ctrl(bio, BIO_CTRL_WPENDING, 0, NULL);

    if (ret < 0)
        ret = 0;
735 736 737 738
#if LONG_MAX > SIZE_MAX
    if (ret > SIZE_MAX)
        ret = SIZE_MAX;
#endif
739
    return (size_t)ret;
740
}
B
Bodo Möller 已提交
741

742
/* put the 'bio' on the end of b's list of operators */
U
Ulf Möller 已提交
743
BIO *BIO_push(BIO *b, BIO *bio)
744 745 746 747
{
    BIO *lb;

    if (b == NULL)
K
KaoruToda 已提交
748
        return bio;
749 750 751 752 753 754 755 756
    lb = b;
    while (lb->next_bio != NULL)
        lb = lb->next_bio;
    lb->next_bio = bio;
    if (bio != NULL)
        bio->prev_bio = lb;
    /* called to do internal processing */
    BIO_ctrl(b, BIO_CTRL_PUSH, 0, lb);
K
KaoruToda 已提交
757
    return b;
758
}
759 760

/* Remove the first and return the rest */
U
Ulf Möller 已提交
761
BIO *BIO_pop(BIO *b)
762 763
{
    BIO *ret;
764

765
    if (b == NULL)
K
KaoruToda 已提交
766
        return NULL;
767
    ret = b->next_bio;
768

769
    BIO_ctrl(b, BIO_CTRL_POP, 0, b);
770

771 772 773 774
    if (b->prev_bio != NULL)
        b->prev_bio->next_bio = b->next_bio;
    if (b->next_bio != NULL)
        b->next_bio->prev_bio = b->prev_bio;
775

776 777
    b->next_bio = NULL;
    b->prev_bio = NULL;
K
KaoruToda 已提交
778
    return ret;
779
}
780

U
Ulf Möller 已提交
781
BIO *BIO_get_retry_BIO(BIO *bio, int *reason)
782 783 784 785 786 787 788 789 790 791 792 793 794 795
{
    BIO *b, *last;

    b = last = bio;
    for (;;) {
        if (!BIO_should_retry(b))
            break;
        last = b;
        b = b->next_bio;
        if (b == NULL)
            break;
    }
    if (reason != NULL)
        *reason = last->retry_reason;
K
KaoruToda 已提交
796
    return last;
797
}
798

U
Ulf Möller 已提交
799
int BIO_get_retry_reason(BIO *bio)
800
{
K
KaoruToda 已提交
801
    return bio->retry_reason;
802
}
803

M
Matt Caswell 已提交
804 805 806 807 808
void BIO_set_retry_reason(BIO *bio, int reason)
{
    bio->retry_reason = reason;
}

U
Ulf Möller 已提交
809
BIO *BIO_find_type(BIO *bio, int type)
810 811 812
{
    int mt, mask;

813
    if (bio == NULL) {
814
        ERR_raise(ERR_LIB_BIO, ERR_R_PASSED_NULL_PARAMETER);
815
        return NULL;
816
    }
817 818 819 820 821 822 823
    mask = type & 0xff;
    do {
        if (bio->method != NULL) {
            mt = bio->method->type;

            if (!mask) {
                if (mt & type)
K
KaoruToda 已提交
824
                    return bio;
825
            } else if (mt == type) {
K
KaoruToda 已提交
826
                return bio;
827
            }
828 829 830
        }
        bio = bio->next_bio;
    } while (bio != NULL);
K
KaoruToda 已提交
831
    return NULL;
832
}
833

D
 
Dr. Stephen Henson 已提交
834
BIO *BIO_next(BIO *b)
835
{
836
    if (b == NULL)
837 838 839
        return NULL;
    return b->next_bio;
}
D
 
Dr. Stephen Henson 已提交
840

M
Matt Caswell 已提交
841 842 843 844 845
void BIO_set_next(BIO *b, BIO *next)
{
    b->next_bio = next;
}

U
Ulf Möller 已提交
846
void BIO_free_all(BIO *bio)
847 848 849 850 851 852 853 854 855 856 857 858 859 860
{
    BIO *b;
    int ref;

    while (bio != NULL) {
        b = bio;
        ref = b->references;
        bio = bio->next_bio;
        BIO_free(b);
        /* Since ref count > 1, don't free anyone else. */
        if (ref > 1)
            break;
    }
}
861

U
Ulf Möller 已提交
862
BIO *BIO_dup_chain(BIO *in)
863 864 865 866 867 868
{
    BIO *ret = NULL, *eoc = NULL, *bio, *new_bio;

    for (bio = in; bio != NULL; bio = bio->next_bio) {
        if ((new_bio = BIO_new(bio->method)) == NULL)
            goto err;
869
#ifndef OPENSSL_NO_DEPRECATED_3_0
870
        new_bio->callback = bio->callback;
871
#endif
872
        new_bio->callback_ex = bio->callback_ex;
873 874 875 876 877 878 879 880 881 882 883 884 885 886 887
        new_bio->cb_arg = bio->cb_arg;
        new_bio->init = bio->init;
        new_bio->shutdown = bio->shutdown;
        new_bio->flags = bio->flags;

        /* This will let SSL_s_sock() work with stdin/stdout */
        new_bio->num = bio->num;

        if (!BIO_dup_state(bio, (char *)new_bio)) {
            BIO_free(new_bio);
            goto err;
        }

        /* copy app data */
        if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_BIO, &new_bio->ex_data,
888 889
                                &bio->ex_data)) {
            BIO_free(new_bio);
890
            goto err;
891
        }
892 893 894 895 896 897 898 899 900

        if (ret == NULL) {
            eoc = new_bio;
            ret = eoc;
        } else {
            BIO_push(eoc, new_bio);
            eoc = new_bio;
        }
    }
K
KaoruToda 已提交
901
    return ret;
902
 err:
903 904
    BIO_free_all(ret);

K
KaoruToda 已提交
905
    return NULL;
906
}
907

U
Ulf Möller 已提交
908
void BIO_copy_next_retry(BIO *b)
909 910 911 912
{
    BIO_set_flags(b, BIO_get_retry_flags(b->next_bio));
    b->retry_reason = b->next_bio->retry_reason;
}
913

D
 
Dr. Stephen Henson 已提交
914
int BIO_set_ex_data(BIO *bio, int idx, void *data)
915
{
K
KaoruToda 已提交
916
    return CRYPTO_set_ex_data(&(bio->ex_data), idx, data);
917
}
918

919
void *BIO_get_ex_data(const BIO *bio, int idx)
920
{
K
KaoruToda 已提交
921
    return CRYPTO_get_ex_data(&(bio->ex_data), idx);
922
}
923

924
uint64_t BIO_number_read(BIO *bio)
925
{
926 927 928
    if (bio)
        return bio->num_read;
    return 0;
929 930
}

931
uint64_t BIO_number_written(BIO *bio)
932
{
933 934 935
    if (bio)
        return bio->num_write;
    return 0;
936
}
937

M
Matt Caswell 已提交
938 939 940 941
void bio_free_ex_data(BIO *bio)
{
    CRYPTO_free_ex_data(CRYPTO_EX_INDEX_BIO, bio, &bio->ex_data);
}
942 943 944 945 946 947 948

void bio_cleanup(void)
{
#ifndef OPENSSL_NO_SOCK
    bio_sock_cleanup_int();
    CRYPTO_THREAD_lock_free(bio_lookup_lock);
    bio_lookup_lock = NULL;
R
Rich Salz 已提交
949
#endif
R
Rich Salz 已提交
950 951
    CRYPTO_THREAD_lock_free(bio_type_lock);
    bio_type_lock = NULL;
952
}
953

954
/* Internal variant of the below BIO_wait() not calling ERR_raise(...) */
955
static int bio_wait(BIO *bio, time_t max_time, unsigned int nap_milliseconds)
956
{
957
#ifndef OPENSSL_NO_SOCK
958
    int fd;
959
#endif
960
    long sec_diff;
961

962
    if (max_time == 0) /* no timeout */
963 964 965
        return 1;

#ifndef OPENSSL_NO_SOCK
966
    if (BIO_get_fd(bio, &fd) > 0 && fd < FD_SETSIZE)
967 968
        return BIO_socket_wait(fd, BIO_should_read(bio), max_time);
#endif
969
    /* fall back to polling since no sockets are available */
970

971 972 973 974 975 976 977 978 979 980 981
    sec_diff = (long)(max_time - time(NULL)); /* might overflow */
    if (sec_diff < 0)
        return 0; /* clearly timeout */

    /* now take a nap at most the given number of milliseconds */
    if (sec_diff == 0) { /* we are below the 1 seconds resolution of max_time */
        if (nap_milliseconds > 1000)
            nap_milliseconds = 1000;
    } else { /* for sec_diff > 0, take min(sec_diff * 1000, nap_milliseconds) */
        if ((unsigned long)sec_diff * 1000 < nap_milliseconds)
            nap_milliseconds = (unsigned int)sec_diff * 1000;
982
    }
983
    ossl_sleep(nap_milliseconds);
984 985 986
    return 1;
}

987
/*-
988
 * Wait on (typically socket-based) BIO at most until max_time.
989 990 991
 * Succeed immediately if max_time == 0.
 * If sockets are not available support polling: succeed after waiting at most
 * the number of nap_milliseconds in order to avoid a tight busy loop.
992
 * Call ERR_raise(ERR_LIB_BIO, ...) on timeout or error.
993 994
 * Returns -1 on error, 0 on timeout, and 1 on success.
 */
995
int BIO_wait(BIO *bio, time_t max_time, unsigned int nap_milliseconds)
996
{
997
    int rv = bio_wait(bio, max_time, nap_milliseconds);
998 999

    if (rv <= 0)
1000 1001
        ERR_raise(ERR_LIB_BIO,
                  rv == 0 ? BIO_R_TRANSFER_TIMEOUT : BIO_R_TRANSFER_ERROR);
1002 1003 1004 1005
    return rv;
}

/*
1006 1007 1008 1009 1010
 * Connect via given BIO using BIO_do_connect() until success/timeout/error.
 * Parameter timeout == 0 means no timeout, < 0 means exactly one try.
 * For non-blocking and potentially even non-socket BIOs perform polling with
 * the given density: between polls sleep nap_milliseconds using BIO_wait()
 * in order to avoid a tight busy loop.
1011 1012
 * Returns -1 on error, 0 on timeout, and 1 on success.
 */
1013
int BIO_do_connect_retry(BIO *bio, int timeout, int nap_milliseconds)
1014
{
1015
    int blocking = timeout <= 0;
1016 1017 1018 1019
    time_t max_time = timeout > 0 ? time(NULL) + timeout : 0;
    int rv;

    if (bio == NULL) {
1020
        ERR_raise(ERR_LIB_BIO, ERR_R_PASSED_NULL_PARAMETER);
1021 1022 1023
        return -1;
    }

1024 1025 1026 1027 1028
    if (nap_milliseconds < 0)
        nap_milliseconds = 100;
    BIO_set_nbio(bio, !blocking);

 retry:
1029 1030
    ERR_set_mark();
    rv = BIO_do_connect(bio);
1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056

    if (rv <= 0) { /* could be timeout or retryable error or fatal error */
        int err = ERR_peek_last_error();
        int reason = ERR_GET_REASON(err);
        int do_retry = BIO_should_retry(bio); /* may be 1 only if !blocking */

        if (ERR_GET_LIB(err) == ERR_LIB_BIO) {
            switch (reason) {
            case ERR_R_SYS_LIB:
                /*
                 * likely retryable system error occurred, which may be
                 * EAGAIN (resource temporarily unavailable) some 40 secs after
                 * calling getaddrinfo(): Temporary failure in name resolution
                 * or a premature ETIMEDOUT, some 30 seconds after connect()
                 */
            case BIO_R_CONNECT_ERROR:
            case BIO_R_NBIO_CONNECT_ERROR:
                /* some likely retryable connection error occurred */
                (void)BIO_reset(bio); /* often needed to avoid retry failure */
                do_retry = 1;
                break;
            default:
                break;
            }
        }
        if (timeout >= 0 && do_retry) {
1057
            ERR_pop_to_mark();
1058 1059
            /* will not actually wait if timeout == 0 (i.e., blocking BIO): */
            rv = bio_wait(bio, max_time, nap_milliseconds);
1060 1061
            if (rv > 0)
                goto retry;
1062 1063
            ERR_raise(ERR_LIB_BIO,
                      rv == 0 ? BIO_R_CONNECT_TIMEOUT : BIO_R_CONNECT_ERROR);
1064
        } else {
1065
            ERR_clear_last_mark();
1066
            rv = -1;
1067
            if (err == 0) /* missing error queue entry */
1068 1069
                /* workaround: general error */
                ERR_raise(ERR_LIB_BIO, BIO_R_CONNECT_ERROR);
1070
        }
1071 1072
    } else {
        ERR_clear_last_mark();
1073 1074 1075 1076
    }

    return rv;
}