bio_lib.c 16.8 KB
Newer Older
R
Rich Salz 已提交
1 2
/*
 * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
3
 *
R
Rich Salz 已提交
4 5 6 7
 * Licensed under the OpenSSL license (the "License").  You may not use
 * 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>
M
Matt Caswell 已提交
13
#include "bio_lcl.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 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71

/*
 * 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;

    if (b->callback_ex != NULL) {
        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;

        if (inret && (oper & BIO_CB_RETURN)) {
            if (*processed > INT_MAX)
                return -1;
            inret = *processed;
        }
    }

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

    if (ret >= 0 && (HAS_LEN_OPER(bareoper) || bareoper == BIO_CB_PUTS)) {
        *processed = (size_t)ret;
        ret = 1;
    }

    return ret;
}

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

F
FdaSilvaYY 已提交
76
    if (bio == NULL) {
77
        BIOerr(BIO_F_BIO_NEW, ERR_R_MALLOC_FAILURE);
K
KaoruToda 已提交
78
        return NULL;
79
    }
80

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

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

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

F
FdaSilvaYY 已提交
95 96 97 98 99
    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;
100 101
    }

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

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

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

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

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

R
Rich Salz 已提交
119
    REF_PRINT_COUNT("BIO", a);
120
    if (ret > 0)
121
        return 1;
122 123 124 125 126 127 128
    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;
    }
129

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

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

135 136
    CRYPTO_THREAD_lock_free(a->lock);

137
    OPENSSL_free(a);
138 139

    return 1;
140
}
141

M
Matt Caswell 已提交
142 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
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 已提交
172
void BIO_vfree(BIO *a)
173 174 175
{
    BIO_free(a);
}
B
Ben Laurie 已提交
176

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

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

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

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

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

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

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

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

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

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

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

254
    if ((b == NULL) || (b->method == NULL) || (b->method->bread == NULL)) {
255
        BIOerr(BIO_F_BIO_READ_INTERN, BIO_R_UNSUPPORTED_METHOD);
256
        return -2;
257
    }
258

259
    if ((b->callback != NULL || b->callback_ex != NULL) &&
260
        ((ret = (int)bio_call_callback(b, BIO_CB_READ, data, dlen, 0, 0L, 1L,
M
Matt Caswell 已提交
261
                                       readbytes)) <= 0))
262
        return ret;
263

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

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

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

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

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

284
    return ret;
285
}
286

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

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

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

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

    return ret;
}

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

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

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

    return ret;
}

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

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

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

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

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

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

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

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

    return ret;
352
}
353

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

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

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

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

    return ret;
}

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

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

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

    return ret;
}

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

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

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

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

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

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

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

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

428
    return ret;
429
}
430

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

548 549 550 551 552 553
    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;
    }
554

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

557 558 559 560 561
    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;
562
}
563

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

K
KaoruToda 已提交
737
    return NULL;
738
}
739

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

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

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

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

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

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

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