bio_lib.c 16.9 KB
Newer Older
R
Rich Salz 已提交
1
/*
M
Matt Caswell 已提交
2
 * Copyright 1995-2018 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 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36

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

/*
 * 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,
                              int argi, long argl, long inret, size_t *processed)
{
    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
        BIOerr(BIO_F_BIO_NEW, 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) {
F
FdaSilvaYY 已提交
89
        BIOerr(BIO_F_BIO_NEW, 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 95 96 97 98
    if (method->create != NULL && !method->create(bio)) {
        BIOerr(BIO_F_BIO_NEW, ERR_R_INIT_FAIL);
        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 187 188 189
        return 0;

    REF_PRINT_COUNT("BIO", a);
    REF_ASSERT_ISNT(i < 2);
    return ((i > 1) ? 1 : 0);
}

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) || (b->method == NULL) || (b->method->bread == NULL)) {
256
        BIOerr(BIO_F_BIO_READ_INTERN, BIO_R_UNSUPPORTED_METHOD);
257
        return -2;
258
    }
259

260
    if ((b->callback != NULL || b->callback_ex != NULL) &&
261
        ((ret = (int)bio_call_callback(b, BIO_CB_READ, data, dlen, 0, 0L, 1L,
262
                                       NULL)) <= 0))
263
        return ret;
264

265
    if (!b->init) {
266
        BIOerr(BIO_F_BIO_READ_INTERN, BIO_R_UNINITIALIZED);
267
        return -2;
268
    }
269

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

272
    if (ret > 0)
M
Matt Caswell 已提交
273
        b->num_read += (uint64_t)*readbytes;
274 275

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

279
    /* Shouldn't happen */
M
Matt Caswell 已提交
280
    if (ret > 0 && *readbytes > dlen) {
281
        BIOerr(BIO_F_BIO_READ_INTERN, ERR_R_INTERNAL_ERROR);
282
        return -1;
283
    }
284

285
    return ret;
286
}
287

288
int BIO_read(BIO *b, void *data, int dlen)
289
{
M
Matt Caswell 已提交
290
    size_t readbytes;
291 292
    int ret;

293
    if (dlen < 0)
294 295
        return 0;

M
Matt Caswell 已提交
296
    ret = bio_read_intern(b, data, (size_t)dlen, &readbytes);
297 298

    if (ret > 0) {
299
        /* *readbytes should always be <= dlen */
M
Matt Caswell 已提交
300
        ret = (int)readbytes;
301 302 303 304 305
    }

    return ret;
}

M
Matt Caswell 已提交
306
int BIO_read_ex(BIO *b, void *data, size_t dlen, size_t *readbytes)
307 308 309
{
    int ret;

M
Matt Caswell 已提交
310
    ret = bio_read_intern(b, data, dlen, readbytes);
311 312 313 314 315 316 317 318 319

    if (ret > 0)
        ret = 1;
    else
        ret = 0;

    return ret;
}

320
static int bio_write_intern(BIO *b, const void *data, size_t dlen,
321
                            size_t *written)
322 323
{
    int ret;
324

325
    if (b == NULL)
326
        return 0;
327

328
    if ((b->method == NULL) || (b->method->bwrite == NULL)) {
329
        BIOerr(BIO_F_BIO_WRITE_INTERN, BIO_R_UNSUPPORTED_METHOD);
330
        return -2;
331
    }
332

333
    if ((b->callback != NULL || b->callback_ex != NULL) &&
334
        ((ret = (int)bio_call_callback(b, BIO_CB_WRITE, data, dlen, 0, 0L, 1L,
335
                                       NULL)) <= 0))
336
        return ret;
337

338
    if (!b->init) {
339
        BIOerr(BIO_F_BIO_WRITE_INTERN, BIO_R_UNINITIALIZED);
340
        return -2;
341
    }
342

343
    ret = b->method->bwrite(b, data, dlen, written);
344

345 346
    if (ret > 0)
        b->num_write += (uint64_t)*written;
347

348
    if (b->callback != NULL || b->callback_ex != NULL)
349
        ret = (int)bio_call_callback(b, BIO_CB_WRITE | BIO_CB_RETURN, data,
350
                                     dlen, 0, 0L, ret, written);
351 352

    return ret;
353
}
354

355
int BIO_write(BIO *b, const void *data, int dlen)
356 357 358 359
{
    size_t written;
    int ret;

360
    if (dlen < 0)
361 362
        return 0;

363
    ret = bio_write_intern(b, data, (size_t)dlen, &written);
364 365

    if (ret > 0) {
366
        /* *written should always be <= dlen */
367 368 369 370 371 372
        ret = (int)written;
    }

    return ret;
}

373
int BIO_write_ex(BIO *b, const void *data, size_t dlen, size_t *written)
374 375 376
{
    int ret;

377
    ret = bio_write_intern(b, data, dlen, written);
378 379 380 381 382 383 384 385 386

    if (ret > 0)
        ret = 1;
    else
        ret = 0;

    return ret;
}

387
int BIO_puts(BIO *b, const char *buf)
388
{
389
    int ret;
390
    size_t written = 0;
391

392 393
    if ((b == NULL) || (b->method == NULL) || (b->method->bputs == NULL)) {
        BIOerr(BIO_F_BIO_PUTS, BIO_R_UNSUPPORTED_METHOD);
394
        return -2;
395
    }
396

397
    if (b->callback != NULL || b->callback_ex != NULL) {
398
        ret = (int)bio_call_callback(b, BIO_CB_PUTS, buf, 0, 0, 0L, 1L, NULL);
399 400 401
        if (ret <= 0)
            return ret;
    }
402

403 404
    if (!b->init) {
        BIOerr(BIO_F_BIO_PUTS, BIO_R_UNINITIALIZED);
405
        return -2;
406
    }
407

408
    ret = b->method->bputs(b, buf);
409

410 411 412 413 414 415 416
    if (ret > 0) {
        b->num_write += (uint64_t)ret;
        written = ret;
        ret = 1;
    }

    if (b->callback != NULL || b->callback_ex != NULL)
417
        ret = (int)bio_call_callback(b, BIO_CB_PUTS | BIO_CB_RETURN, buf, 0, 0,
418 419 420
                                     0L, ret, &written);

    if (ret > 0) {
421 422
        if (written > INT_MAX) {
            BIOerr(BIO_F_BIO_PUTS, BIO_R_LENGTH_TOO_LONG);
423
            ret = -1;
424
        } else {
425
            ret = (int)written;
426
        }
427
    }
428

429
    return ret;
430
}
431

432
int BIO_gets(BIO *b, char *buf, int size)
433
{
434
    int ret;
M
Matt Caswell 已提交
435
    size_t readbytes = 0;
436 437 438

    if ((b == NULL) || (b->method == NULL) || (b->method->bgets == NULL)) {
        BIOerr(BIO_F_BIO_GETS, BIO_R_UNSUPPORTED_METHOD);
K
KaoruToda 已提交
439
        return -2;
440 441
    }

442
    if (size < 0) {
443 444 445 446
        BIOerr(BIO_F_BIO_GETS, BIO_R_INVALID_ARGUMENT);
        return 0;
    }

447
    if (b->callback != NULL || b->callback_ex != NULL) {
448
        ret = (int)bio_call_callback(b, BIO_CB_GETS, buf, size, 0, 0L, 1, NULL);
449 450 451
        if (ret <= 0)
            return ret;
    }
452 453 454

    if (!b->init) {
        BIOerr(BIO_F_BIO_GETS, BIO_R_UNINITIALIZED);
K
KaoruToda 已提交
455
        return -2;
456 457
    }

458
    ret = b->method->bgets(b, buf, size);
459 460

    if (ret > 0) {
M
Matt Caswell 已提交
461
        readbytes = ret;
462 463 464 465
        ret = 1;
    }

    if (b->callback != NULL || b->callback_ex != NULL)
466
        ret = (int)bio_call_callback(b, BIO_CB_GETS | BIO_CB_RETURN, buf, size,
M
Matt Caswell 已提交
467
                                     0, 0L, ret, &readbytes);
468 469

    if (ret > 0) {
470
        /* Shouldn't happen */
471
        if (readbytes > (size_t)size)
472 473
            ret = -1;
        else
M
Matt Caswell 已提交
474
            ret = (int)readbytes;
475
    }
476

477
    return ret;
478 479 480 481 482 483 484 485 486 487 488 489 490
}

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

U
Ulf Möller 已提交
492
long BIO_int_ctrl(BIO *b, int cmd, long larg, int iarg)
493 494
{
    int i;
495

496
    i = iarg;
K
KaoruToda 已提交
497
    return BIO_ctrl(b, cmd, larg, (char *)&i);
498
}
499

500
void *BIO_ptr_ctrl(BIO *b, int cmd, long larg)
501
{
502
    void *p = NULL;
503

504
    if (BIO_ctrl(b, cmd, larg, (char *)&p) <= 0)
K
KaoruToda 已提交
505
        return NULL;
506
    else
K
KaoruToda 已提交
507
        return p;
508
}
509

B
Bodo Möller 已提交
510
long BIO_ctrl(BIO *b, int cmd, long larg, void *parg)
511 512
{
    long ret;
513

514
    if (b == NULL)
515
        return 0;
516

517 518
    if ((b->method == NULL) || (b->method->ctrl == NULL)) {
        BIOerr(BIO_F_BIO_CTRL, BIO_R_UNSUPPORTED_METHOD);
519
        return -2;
520
    }
521

522 523 524 525 526
    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;
    }
527

528
    ret = b->method->ctrl(b, cmd, larg, parg);
529

530 531 532 533 534
    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;
535
}
536

B
Bernd Edlinger 已提交
537
long BIO_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp)
538 539
{
    long ret;
540

541
    if (b == NULL)
K
KaoruToda 已提交
542
        return 0;
543

544 545
    if ((b->method == NULL) || (b->method->callback_ctrl == NULL)
            || (cmd != BIO_CTRL_SET_CALLBACK)) {
546
        BIOerr(BIO_F_BIO_CALLBACK_CTRL, BIO_R_UNSUPPORTED_METHOD);
K
KaoruToda 已提交
547
        return -2;
548
    }
549

550 551 552 553 554 555
    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;
    }
556

557
    ret = b->method->callback_ctrl(b, cmd, fp);
558

559 560 561 562 563
    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;
564
}
565

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

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

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

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

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

604
    if (b == NULL)
K
KaoruToda 已提交
605
        return NULL;
606
    ret = b->next_bio;
607

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

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

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

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

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

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

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

R
Rich Salz 已提交
652
    if (bio == NULL)
653 654 655 656 657 658 659 660
        return NULL;
    mask = type & 0xff;
    do {
        if (bio->method != NULL) {
            mt = bio->method->type;

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

D
 
Dr. Stephen Henson 已提交
670
BIO *BIO_next(BIO *b)
671
{
R
Rich Salz 已提交
672
    if (b == NULL)
673 674 675
        return NULL;
    return b->next_bio;
}
D
 
Dr. Stephen Henson 已提交
676

M
Matt Caswell 已提交
677 678 679 680 681
void BIO_set_next(BIO *b, BIO *next)
{
    b->next_bio = next;
}

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

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

        if (ret == NULL) {
            eoc = new_bio;
            ret = eoc;
        } else {
            BIO_push(eoc, new_bio);
            eoc = new_bio;
        }
    }
K
KaoruToda 已提交
735
    return ret;
736
 err:
737 738
    BIO_free_all(ret);

K
KaoruToda 已提交
739
    return NULL;
740
}
741

U
Ulf Möller 已提交
742
void BIO_copy_next_retry(BIO *b)
743 744 745 746
{
    BIO_set_flags(b, BIO_get_retry_flags(b->next_bio));
    b->retry_reason = b->next_bio->retry_reason;
}
747

D
 
Dr. Stephen Henson 已提交
748
int BIO_set_ex_data(BIO *bio, int idx, void *data)
749
{
K
KaoruToda 已提交
750
    return CRYPTO_set_ex_data(&(bio->ex_data), idx, data);
751
}
752

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

758
uint64_t BIO_number_read(BIO *bio)
759
{
760 761 762
    if (bio)
        return bio->num_read;
    return 0;
763 764
}

765
uint64_t BIO_number_written(BIO *bio)
766
{
767 768 769
    if (bio)
        return bio->num_write;
    return 0;
770
}
771

M
Matt Caswell 已提交
772 773 774 775
void bio_free_ex_data(BIO *bio)
{
    CRYPTO_free_ex_data(CRYPTO_EX_INDEX_BIO, bio, &bio->ex_data);
}
776 777 778 779 780 781 782

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 已提交
783
#endif
R
Rich Salz 已提交
784 785
    CRYPTO_THREAD_lock_free(bio_type_lock);
    bio_type_lock = NULL;
786
}