bio_lib.c 21.5 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
 */

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

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

/*
 * 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,
31 32
                              int argi, long argl, long inret,
                              size_t *processed)
33 34 35 36
{
    long ret;
    int bareoper;

37
    if (b->callback_ex != NULL)
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
        return b->callback_ex(b, oper, argp, len, argi, argl, inret, processed);

    /* 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;
53
    }
54

55
    if (inret > 0 && (oper & BIO_CB_RETURN) && bareoper != BIO_CB_CTRL) {
56 57 58
        if (*processed > INT_MAX)
            return -1;
        inret = *processed;
59 60 61 62
    }

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

63
    if (ret > 0 && (oper & BIO_CB_RETURN) && bareoper != BIO_CB_CTRL) {
64 65 66 67 68 69 70
        *processed = (size_t)ret;
        ret = 1;
    }

    return ret;
}

71
BIO *BIO_new(const BIO_METHOD *method)
72
{
F
FdaSilvaYY 已提交
73
    BIO *bio = OPENSSL_zalloc(sizeof(*bio));
74

F
FdaSilvaYY 已提交
75
    if (bio == NULL) {
76
        ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE);
K
KaoruToda 已提交
77
        return NULL;
78
    }
79

80 81 82
    bio->method = method;
    bio->shutdown = 1;
    bio->references = 1;
F
FdaSilvaYY 已提交
83

84
    if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_BIO, bio, &bio->ex_data))
F
FdaSilvaYY 已提交
85
        goto err;
86 87 88

    bio->lock = CRYPTO_THREAD_lock_new();
    if (bio->lock == NULL) {
89
        ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE);
90
        CRYPTO_free_ex_data(CRYPTO_EX_INDEX_BIO, bio, &bio->ex_data);
F
FdaSilvaYY 已提交
91
        goto err;
92 93
    }

F
FdaSilvaYY 已提交
94
    if (method->create != NULL && !method->create(bio)) {
95
        ERR_raise(ERR_LIB_BIO, ERR_R_INIT_FAIL);
F
FdaSilvaYY 已提交
96 97 98
        CRYPTO_free_ex_data(CRYPTO_EX_INDEX_BIO, bio, &bio->ex_data);
        CRYPTO_THREAD_lock_free(bio->lock);
        goto err;
99
    }
100 101
    if (method->create == NULL)
        bio->init = 1;
102

F
FdaSilvaYY 已提交
103 104 105 106 107
    return bio;

err:
    OPENSSL_free(bio);
    return NULL;
108
}
109

U
Ulf Möller 已提交
110
int BIO_free(BIO *a)
111
{
112
    int ret;
113

114
    if (a == NULL)
115 116
        return 0;

117
    if (CRYPTO_DOWN_REF(&a->references, &ret, a->lock) <= 0)
118
        return 0;
119

R
Rich Salz 已提交
120
    REF_PRINT_COUNT("BIO", a);
121
    if (ret > 0)
122
        return 1;
123 124 125 126 127 128 129
    REF_ASSERT_ISNT(ret < 0);

    if (a->callback != NULL || a->callback_ex != NULL) {
        ret = (int)bio_call_callback(a, BIO_CB_FREE, NULL, 0, 0, 0L, 1L, NULL);
        if (ret <= 0)
            return ret;
    }
130

131 132 133
    if ((a->method != NULL) && (a->method->destroy != NULL))
        a->method->destroy(a);

134
    CRYPTO_free_ex_data(CRYPTO_EX_INDEX_BIO, a, &a->ex_data);
135

136 137
    CRYPTO_THREAD_lock_free(a->lock);

138
    OPENSSL_free(a);
139 140

    return 1;
141
}
142

M
Matt Caswell 已提交
143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172
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 已提交
173
void BIO_vfree(BIO *a)
174 175 176
{
    BIO_free(a);
}
B
Ben Laurie 已提交
177

178 179 180 181
int BIO_up_ref(BIO *a)
{
    int i;

182
    if (CRYPTO_UP_REF(&a->references, &i, a->lock) <= 0)
183 184 185 186
        return 0;

    REF_PRINT_COUNT("BIO", a);
    REF_ASSERT_ISNT(i < 2);
187
    return i > 1;
188 189
}

N
Nils Larsch 已提交
190
void BIO_clear_flags(BIO *b, int flags)
191 192 193 194 195 196 197 198 199 200 201 202 203 204
{
    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;
}

205 206
BIO_callback_fn BIO_get_callback(const BIO *b)
{
207 208 209
    return b->callback;
}

210
void BIO_set_callback(BIO *b, BIO_callback_fn cb)
211 212 213
{
    b->callback = cb;
}
N
Nils Larsch 已提交
214

215 216 217 218 219 220 221 222 223 224
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 已提交
225
void BIO_set_callback_arg(BIO *b, char *arg)
226 227 228
{
    b->cb_arg = arg;
}
N
Nils Larsch 已提交
229

230 231 232 233
char *BIO_get_callback_arg(const BIO *b)
{
    return b->cb_arg;
}
N
Nils Larsch 已提交
234

235 236 237 238
const char *BIO_method_name(const BIO *b)
{
    return b->method->name;
}
N
Nils Larsch 已提交
239 240

int BIO_method_type(const BIO *b)
241 242 243
{
    return b->method->type;
}
N
Nils Larsch 已提交
244

245 246
/*
 * This is essentially the same as BIO_read_ex() except that it allows
247 248 249
 * 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.
250
 */
M
Matt Caswell 已提交
251
static int bio_read_intern(BIO *b, void *data, size_t dlen, size_t *readbytes)
252 253
{
    int ret;
254

255
    if (b == NULL) {
256
        ERR_raise(ERR_LIB_BIO, ERR_R_PASSED_NULL_PARAMETER);
257 258 259
        return -1;
    }
    if (b->method == NULL || b->method->bread == NULL) {
260
        ERR_raise(ERR_LIB_BIO, BIO_R_UNSUPPORTED_METHOD);
261
        return -2;
262
    }
263

264
    if ((b->callback != NULL || b->callback_ex != NULL) &&
265
        ((ret = (int)bio_call_callback(b, BIO_CB_READ, data, dlen, 0, 0L, 1L,
266
                                       NULL)) <= 0))
267
        return ret;
268

269
    if (!b->init) {
270
        ERR_raise(ERR_LIB_BIO, BIO_R_UNINITIALIZED);
271
        return -1;
272
    }
273

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

276
    if (ret > 0)
M
Matt Caswell 已提交
277
        b->num_read += (uint64_t)*readbytes;
278 279

    if (b->callback != NULL || b->callback_ex != NULL)
280
        ret = (int)bio_call_callback(b, BIO_CB_READ | BIO_CB_RETURN, data,
M
Matt Caswell 已提交
281
                                     dlen, 0, 0L, ret, readbytes);
282

283
    /* Shouldn't happen */
M
Matt Caswell 已提交
284
    if (ret > 0 && *readbytes > dlen) {
285
        ERR_raise(ERR_LIB_BIO, ERR_R_INTERNAL_ERROR);
286
        return -1;
287
    }
288

289
    return ret;
290
}
291

292
int BIO_read(BIO *b, void *data, int dlen)
293
{
M
Matt Caswell 已提交
294
    size_t readbytes;
295 296
    int ret;

297
    if (dlen < 0)
298 299
        return 0;

M
Matt Caswell 已提交
300
    ret = bio_read_intern(b, data, (size_t)dlen, &readbytes);
301 302

    if (ret > 0) {
303
        /* *readbytes should always be <= dlen */
M
Matt Caswell 已提交
304
        ret = (int)readbytes;
305 306 307 308 309
    }

    return ret;
}

M
Matt Caswell 已提交
310
int BIO_read_ex(BIO *b, void *data, size_t dlen, size_t *readbytes)
311
{
312
    return bio_read_intern(b, data, dlen, readbytes) > 0;
313 314
}

315
static int bio_write_intern(BIO *b, const void *data, size_t dlen,
316
                            size_t *written)
317 318
{
    int ret;
319

320
    if (b == NULL) {
321
        ERR_raise(ERR_LIB_BIO, ERR_R_PASSED_NULL_PARAMETER);
322 323 324
        return -1;
    }
    if (b->method == NULL || b->method->bwrite == NULL) {
325
        ERR_raise(ERR_LIB_BIO, BIO_R_UNSUPPORTED_METHOD);
326
        return -2;
327
    }
328

329
    if ((b->callback != NULL || b->callback_ex != NULL) &&
330
        ((ret = (int)bio_call_callback(b, BIO_CB_WRITE, data, dlen, 0, 0L, 1L,
331
                                       NULL)) <= 0))
332
        return ret;
333

334
    if (!b->init) {
335
        ERR_raise(ERR_LIB_BIO, BIO_R_UNINITIALIZED);
336
        return -1;
337
    }
338

339
    ret = b->method->bwrite(b, data, dlen, written);
340

341 342
    if (ret > 0)
        b->num_write += (uint64_t)*written;
343

344
    if (b->callback != NULL || b->callback_ex != NULL)
345
        ret = (int)bio_call_callback(b, BIO_CB_WRITE | BIO_CB_RETURN, data,
346
                                     dlen, 0, 0L, ret, written);
347 348

    return ret;
349
}
350

351
int BIO_write(BIO *b, const void *data, int dlen)
352 353 354 355
{
    size_t written;
    int ret;

356
    if (dlen < 0)
357 358
        return 0;

359
    ret = bio_write_intern(b, data, (size_t)dlen, &written);
360 361

    if (ret > 0) {
362
        /* *written should always be <= dlen */
363 364 365 366 367 368
        ret = (int)written;
    }

    return ret;
}

369
int BIO_write_ex(BIO *b, const void *data, size_t dlen, size_t *written)
370
{
371
    return bio_write_intern(b, data, dlen, written) > 0;
372 373
}

374
int BIO_puts(BIO *b, const char *buf)
375
{
376
    int ret;
377
    size_t written = 0;
378

379
    if (b == NULL) {
380
        ERR_raise(ERR_LIB_BIO, ERR_R_PASSED_NULL_PARAMETER);
381 382 383
        return -1;
    }
    if (b->method == NULL || b->method->bputs == NULL) {
384
        ERR_raise(ERR_LIB_BIO, BIO_R_UNSUPPORTED_METHOD);
385
        return -2;
386
    }
387

388
    if (b->callback != NULL || b->callback_ex != NULL) {
389
        ret = (int)bio_call_callback(b, BIO_CB_PUTS, buf, 0, 0, 0L, 1L, NULL);
390 391 392
        if (ret <= 0)
            return ret;
    }
393

394
    if (!b->init) {
395
        ERR_raise(ERR_LIB_BIO, BIO_R_UNINITIALIZED);
396
        return -1;
397
    }
398

399
    ret = b->method->bputs(b, buf);
400

401 402 403 404 405 406 407
    if (ret > 0) {
        b->num_write += (uint64_t)ret;
        written = ret;
        ret = 1;
    }

    if (b->callback != NULL || b->callback_ex != NULL)
408
        ret = (int)bio_call_callback(b, BIO_CB_PUTS | BIO_CB_RETURN, buf, 0, 0,
409 410 411
                                     0L, ret, &written);

    if (ret > 0) {
412
        if (written > INT_MAX) {
413
            ERR_raise(ERR_LIB_BIO, BIO_R_LENGTH_TOO_LONG);
414
            ret = -1;
415
        } else {
416
            ret = (int)written;
417
        }
418
    }
419

420
    return ret;
421
}
422

423
int BIO_gets(BIO *b, char *buf, int size)
424
{
425
    int ret;
M
Matt Caswell 已提交
426
    size_t readbytes = 0;
427

428
    if (b == NULL) {
429
        ERR_raise(ERR_LIB_BIO, ERR_R_PASSED_NULL_PARAMETER);
430 431 432
        return -1;
    }
    if (b->method == NULL || b->method->bgets == NULL) {
433
        ERR_raise(ERR_LIB_BIO, BIO_R_UNSUPPORTED_METHOD);
K
KaoruToda 已提交
434
        return -2;
435 436
    }

437
    if (size < 0) {
438
        ERR_raise(ERR_LIB_BIO, BIO_R_INVALID_ARGUMENT);
439
        return -1;
440 441
    }

442
    if (b->callback != NULL || b->callback_ex != NULL) {
443
        ret = (int)bio_call_callback(b, BIO_CB_GETS, buf, size, 0, 0L, 1, NULL);
444 445 446
        if (ret <= 0)
            return ret;
    }
447 448

    if (!b->init) {
449
        ERR_raise(ERR_LIB_BIO, BIO_R_UNINITIALIZED);
450
        return -1;
451 452
    }

453
    ret = b->method->bgets(b, buf, size);
454 455

    if (ret > 0) {
M
Matt Caswell 已提交
456
        readbytes = ret;
457 458 459 460
        ret = 1;
    }

    if (b->callback != NULL || b->callback_ex != NULL)
461
        ret = (int)bio_call_callback(b, BIO_CB_GETS | BIO_CB_RETURN, buf, size,
M
Matt Caswell 已提交
462
                                     0, 0L, ret, &readbytes);
463 464

    if (ret > 0) {
465
        /* Shouldn't happen */
466
        if (readbytes > (size_t)size)
467 468
            ret = -1;
        else
M
Matt Caswell 已提交
469
            ret = (int)readbytes;
470
    }
471

472
    return ret;
473 474 475 476 477 478 479 480 481 482 483 484 485
}

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;
}
486

U
Ulf Möller 已提交
487
long BIO_int_ctrl(BIO *b, int cmd, long larg, int iarg)
488 489
{
    int i;
490

491
    i = iarg;
K
KaoruToda 已提交
492
    return BIO_ctrl(b, cmd, larg, (char *)&i);
493
}
494

495
void *BIO_ptr_ctrl(BIO *b, int cmd, long larg)
496
{
497
    void *p = NULL;
498

499
    if (BIO_ctrl(b, cmd, larg, (char *)&p) <= 0)
K
KaoruToda 已提交
500
        return NULL;
501
    else
K
KaoruToda 已提交
502
        return p;
503
}
504

B
Bodo Möller 已提交
505
long BIO_ctrl(BIO *b, int cmd, long larg, void *parg)
506 507
{
    long ret;
508

509
    if (b == NULL) {
510
        ERR_raise(ERR_LIB_BIO, ERR_R_PASSED_NULL_PARAMETER);
511 512 513
        return -1;
    }
    if (b->method == NULL || b->method->ctrl == NULL) {
514
        ERR_raise(ERR_LIB_BIO, BIO_R_UNSUPPORTED_METHOD);
515
        return -2;
516
    }
517

518 519 520 521 522
    if (b->callback != NULL || b->callback_ex != NULL) {
        ret = bio_call_callback(b, BIO_CB_CTRL, parg, 0, cmd, larg, 1L, NULL);
        if (ret <= 0)
            return ret;
    }
523

524
    ret = b->method->ctrl(b, cmd, larg, parg);
525

526 527 528 529 530
    if (b->callback != NULL || b->callback_ex != NULL)
        ret = bio_call_callback(b, BIO_CB_CTRL | BIO_CB_RETURN, parg, 0, cmd,
                                larg, ret, NULL);

    return ret;
531
}
532

B
Bernd Edlinger 已提交
533
long BIO_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp)
534 535
{
    long ret;
536

537
    if (b == NULL) {
538 539
        ERR_raise(ERR_LIB_BIO, ERR_R_PASSED_NULL_PARAMETER);
        return -2;
540 541 542
    }
    if (b->method == NULL || b->method->callback_ctrl == NULL
            || cmd != BIO_CTRL_SET_CALLBACK) {
543
        ERR_raise(ERR_LIB_BIO, BIO_R_UNSUPPORTED_METHOD);
K
KaoruToda 已提交
544
        return -2;
545
    }
546

547 548 549 550 551 552
    if (b->callback != NULL || b->callback_ex != NULL) {
        ret = bio_call_callback(b, BIO_CB_CTRL, (void *)&fp, 0, cmd, 0, 1L,
                                NULL);
        if (ret <= 0)
            return ret;
    }
553

554
    ret = b->method->callback_ctrl(b, cmd, fp);
555

556 557 558 559 560
    if (b->callback != NULL || b->callback_ex != NULL)
        ret = bio_call_callback(b, BIO_CB_CTRL | BIO_CB_RETURN, (void *)&fp, 0,
                                cmd, 0, ret, NULL);

    return ret;
561
}
562

563 564
/*
 * It is unfortunate to duplicate in functions what the BIO_(w)pending macros
B
Bodo Möller 已提交
565
 * do; but those macros have inappropriate return type, and for interfacing
566 567
 * from other programming languages, C macros aren't much of a help anyway.
 */
B
Bodo Möller 已提交
568
size_t BIO_ctrl_pending(BIO *bio)
569 570 571
{
    return BIO_ctrl(bio, BIO_CTRL_PENDING, 0, NULL);
}
B
Bodo Möller 已提交
572 573

size_t BIO_ctrl_wpending(BIO *bio)
574 575 576
{
    return BIO_ctrl(bio, BIO_CTRL_WPENDING, 0, NULL);
}
B
Bodo Möller 已提交
577

578
/* put the 'bio' on the end of b's list of operators */
U
Ulf Möller 已提交
579
BIO *BIO_push(BIO *b, BIO *bio)
580 581 582 583
{
    BIO *lb;

    if (b == NULL)
K
KaoruToda 已提交
584
        return bio;
585 586 587 588 589 590 591 592
    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 已提交
593
    return b;
594
}
595 596

/* Remove the first and return the rest */
U
Ulf Möller 已提交
597
BIO *BIO_pop(BIO *b)
598 599
{
    BIO *ret;
600

601
    if (b == NULL) {
602
        ERR_raise(ERR_LIB_BIO, ERR_R_PASSED_NULL_PARAMETER);
K
KaoruToda 已提交
603
        return NULL;
604
    }
605
    ret = b->next_bio;
606

607
    BIO_ctrl(b, BIO_CTRL_POP, 0, b);
608

609 610 611 612
    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;
613

614 615
    b->next_bio = NULL;
    b->prev_bio = NULL;
K
KaoruToda 已提交
616
    return ret;
617
}
618

U
Ulf Möller 已提交
619
BIO *BIO_get_retry_BIO(BIO *bio, int *reason)
620 621 622 623 624 625 626 627 628 629 630 631 632 633
{
    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 已提交
634
    return last;
635
}
636

U
Ulf Möller 已提交
637
int BIO_get_retry_reason(BIO *bio)
638
{
K
KaoruToda 已提交
639
    return bio->retry_reason;
640
}
641

M
Matt Caswell 已提交
642 643 644 645 646
void BIO_set_retry_reason(BIO *bio, int reason)
{
    bio->retry_reason = reason;
}

U
Ulf Möller 已提交
647
BIO *BIO_find_type(BIO *bio, int type)
648 649 650
{
    int mt, mask;

651
    if (bio == NULL) {
652
        ERR_raise(ERR_LIB_BIO, ERR_R_PASSED_NULL_PARAMETER);
653
        return NULL;
654
    }
655 656 657 658 659 660 661
    mask = type & 0xff;
    do {
        if (bio->method != NULL) {
            mt = bio->method->type;

            if (!mask) {
                if (mt & type)
K
KaoruToda 已提交
662
                    return bio;
663
            } else if (mt == type) {
K
KaoruToda 已提交
664
                return bio;
665
            }
666 667 668
        }
        bio = bio->next_bio;
    } while (bio != NULL);
K
KaoruToda 已提交
669
    return NULL;
670
}
671

D
 
Dr. Stephen Henson 已提交
672
BIO *BIO_next(BIO *b)
673
{
674
    if (b == NULL) {
675
        ERR_raise(ERR_LIB_BIO, ERR_R_PASSED_NULL_PARAMETER);
676
        return NULL;
677
    }
678 679
    return b->next_bio;
}
D
 
Dr. Stephen Henson 已提交
680

M
Matt Caswell 已提交
681 682 683 684 685
void BIO_set_next(BIO *b, BIO *next)
{
    b->next_bio = next;
}

U
Ulf Möller 已提交
686
void BIO_free_all(BIO *bio)
687 688 689 690 691 692 693 694 695 696 697 698 699 700
{
    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;
    }
}
701

U
Ulf Möller 已提交
702
BIO *BIO_dup_chain(BIO *in)
703 704 705 706 707 708 709
{
    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;
        new_bio->callback = bio->callback;
710
        new_bio->callback_ex = bio->callback_ex;
711 712 713 714 715 716 717 718 719 720 721 722 723 724 725
        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,
726 727
                                &bio->ex_data)) {
            BIO_free(new_bio);
728
            goto err;
729
        }
730 731 732 733 734 735 736 737 738

        if (ret == NULL) {
            eoc = new_bio;
            ret = eoc;
        } else {
            BIO_push(eoc, new_bio);
            eoc = new_bio;
        }
    }
K
KaoruToda 已提交
739
    return ret;
740
 err:
741 742
    BIO_free_all(ret);

K
KaoruToda 已提交
743
    return NULL;
744
}
745

U
Ulf Möller 已提交
746
void BIO_copy_next_retry(BIO *b)
747 748 749 750
{
    BIO_set_flags(b, BIO_get_retry_flags(b->next_bio));
    b->retry_reason = b->next_bio->retry_reason;
}
751

D
 
Dr. Stephen Henson 已提交
752
int BIO_set_ex_data(BIO *bio, int idx, void *data)
753
{
K
KaoruToda 已提交
754
    return CRYPTO_set_ex_data(&(bio->ex_data), idx, data);
755
}
756

757
void *BIO_get_ex_data(const BIO *bio, int idx)
758
{
K
KaoruToda 已提交
759
    return CRYPTO_get_ex_data(&(bio->ex_data), idx);
760
}
761

762
uint64_t BIO_number_read(BIO *bio)
763
{
764 765 766
    if (bio)
        return bio->num_read;
    return 0;
767 768
}

769
uint64_t BIO_number_written(BIO *bio)
770
{
771 772 773
    if (bio)
        return bio->num_write;
    return 0;
774
}
775

M
Matt Caswell 已提交
776 777 778 779
void bio_free_ex_data(BIO *bio)
{
    CRYPTO_free_ex_data(CRYPTO_EX_INDEX_BIO, bio, &bio->ex_data);
}
780 781 782 783 784 785 786

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 已提交
787
#endif
R
Rich Salz 已提交
788 789
    CRYPTO_THREAD_lock_free(bio_type_lock);
    bio_type_lock = NULL;
790
}
791 792

/* Internal variant of the below BIO_wait() not calling BIOerr() */
793
static int bio_wait(BIO *bio, time_t max_time, unsigned int nap_milliseconds)
794
{
795
#ifndef OPENSSL_NO_SOCK
796
    int fd;
797
#endif
798
    long sec_diff;
799

800
    if (max_time == 0) /* no timeout */
801 802 803
        return 1;

#ifndef OPENSSL_NO_SOCK
804
    if (BIO_get_fd(bio, &fd) > 0 && fd < FD_SETSIZE)
805 806
        return BIO_socket_wait(fd, BIO_should_read(bio), max_time);
#endif
807
    /* fall back to polling since no sockets are available */
808

809 810 811 812 813 814 815 816 817 818 819
    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;
820
    }
821
    ossl_sleep(nap_milliseconds);
822 823 824
    return 1;
}

825
/*-
826
 * Wait on (typically socket-based) BIO at most until max_time.
827 828 829 830
 * 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.
 * Call BIOerr(...) on timeout or error.
831 832
 * Returns -1 on error, 0 on timeout, and 1 on success.
 */
833
int BIO_wait(BIO *bio, time_t max_time, unsigned int nap_milliseconds)
834
{
835
    int rv = bio_wait(bio, max_time, nap_milliseconds);
836 837

    if (rv <= 0)
838 839
        ERR_raise(ERR_LIB_BIO,
                  rv == 0 ? BIO_R_TRANSFER_TIMEOUT : BIO_R_TRANSFER_ERROR);
840 841 842 843
    return rv;
}

/*
844 845 846 847 848
 * 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.
849 850
 * Returns -1 on error, 0 on timeout, and 1 on success.
 */
851
int BIO_do_connect_retry(BIO *bio, int timeout, int nap_milliseconds)
852
{
853
    int blocking = timeout <= 0;
854 855 856 857
    time_t max_time = timeout > 0 ? time(NULL) + timeout : 0;
    int rv;

    if (bio == NULL) {
858
        ERR_raise(ERR_LIB_BIO, ERR_R_PASSED_NULL_PARAMETER);
859 860 861
        return -1;
    }

862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896
    if (nap_milliseconds < 0)
        nap_milliseconds = 100;
    BIO_set_nbio(bio, !blocking);

 retry:
    rv = BIO_do_connect(bio); /* This may indirectly call ERR_clear_error(); */

    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) {
            ERR_clear_error(); /* using ERR_pop_to_mark() would be cleaner */
            /* will not actually wait if timeout == 0 (i.e., blocking BIO): */
            rv = bio_wait(bio, max_time, nap_milliseconds);
897 898
            if (rv > 0)
                goto retry;
899 900
            ERR_raise(ERR_LIB_BIO,
                      rv == 0 ? BIO_R_CONNECT_TIMEOUT : BIO_R_CONNECT_ERROR);
901 902
        } else {
            rv = -1;
903
            if (err == 0) /* missing error queue entry */
904 905
                /* workaround: general error */
                ERR_raise(ERR_LIB_BIO, BIO_R_CONNECT_ERROR);
906 907 908 909 910
        }
    }

    return rv;
}