bio_lib.c 22.3 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

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

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

36
    if (b->callback_ex != NULL)
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
        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;
52
    }
53

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

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

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

    return ret;
}

70
BIO *BIO_new_ex(OSSL_LIB_CTX *libctx, const BIO_METHOD *method)
71
{
F
FdaSilvaYY 已提交
72
    BIO *bio = OPENSSL_zalloc(sizeof(*bio));
73

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

79
    bio->libctx = libctx;
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

110 111 112 113 114
BIO *BIO_new(const BIO_METHOD *method)
{
    return BIO_new_ex(NULL, method);
}

U
Ulf Möller 已提交
115
int BIO_free(BIO *a)
116
{
117
    int ret;
118

119
    if (a == NULL)
120 121
        return 0;

122
    if (CRYPTO_DOWN_REF(&a->references, &ret, a->lock) <= 0)
123
        return 0;
124

R
Rich Salz 已提交
125
    REF_PRINT_COUNT("BIO", a);
126
    if (ret > 0)
127
        return 1;
128 129 130 131 132 133 134
    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;
    }
135

136 137 138
    if ((a->method != NULL) && (a->method->destroy != NULL))
        a->method->destroy(a);

139
    CRYPTO_free_ex_data(CRYPTO_EX_INDEX_BIO, a, &a->ex_data);
140

141 142
    CRYPTO_THREAD_lock_free(a->lock);

143
    OPENSSL_free(a);
144 145

    return 1;
146
}
147

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

183 184 185 186
int BIO_up_ref(BIO *a)
{
    int i;

187
    if (CRYPTO_UP_REF(&a->references, &i, a->lock) <= 0)
188 189 190 191
        return 0;

    REF_PRINT_COUNT("BIO", a);
    REF_ASSERT_ISNT(i < 2);
192
    return i > 1;
193 194
}

N
Nils Larsch 已提交
195
void BIO_clear_flags(BIO *b, int flags)
196 197 198 199 200 201 202 203 204 205 206 207 208 209
{
    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;
}

210 211
BIO_callback_fn BIO_get_callback(const BIO *b)
{
212 213 214
    return b->callback;
}

215
void BIO_set_callback(BIO *b, BIO_callback_fn cb)
216 217 218
{
    b->callback = cb;
}
N
Nils Larsch 已提交
219

220 221 222 223 224 225 226 227 228 229
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 已提交
230
void BIO_set_callback_arg(BIO *b, char *arg)
231 232 233
{
    b->cb_arg = arg;
}
N
Nils Larsch 已提交
234

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

240 241 242 243
const char *BIO_method_name(const BIO *b)
{
    return b->method->name;
}
N
Nils Larsch 已提交
244 245

int BIO_method_type(const BIO *b)
246 247 248
{
    return b->method->type;
}
N
Nils Larsch 已提交
249

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

260
    if (b == NULL) {
261
        ERR_raise(ERR_LIB_BIO, ERR_R_PASSED_NULL_PARAMETER);
262 263 264
        return -1;
    }
    if (b->method == NULL || b->method->bread == NULL) {
265
        ERR_raise(ERR_LIB_BIO, BIO_R_UNSUPPORTED_METHOD);
266
        return -2;
267
    }
268

269
    if ((b->callback != NULL || b->callback_ex != NULL) &&
270
        ((ret = (int)bio_call_callback(b, BIO_CB_READ, data, dlen, 0, 0L, 1L,
271
                                       NULL)) <= 0))
272
        return ret;
273

274
    if (!b->init) {
275
        ERR_raise(ERR_LIB_BIO, BIO_R_UNINITIALIZED);
276
        return -1;
277
    }
278

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

281
    if (ret > 0)
M
Matt Caswell 已提交
282
        b->num_read += (uint64_t)*readbytes;
283 284

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

288
    /* Shouldn't happen */
M
Matt Caswell 已提交
289
    if (ret > 0 && *readbytes > dlen) {
290
        ERR_raise(ERR_LIB_BIO, ERR_R_INTERNAL_ERROR);
291
        return -1;
292
    }
293

294
    return ret;
295
}
296

297
int BIO_read(BIO *b, void *data, int dlen)
298
{
M
Matt Caswell 已提交
299
    size_t readbytes;
300 301
    int ret;

302
    if (dlen < 0)
303 304
        return 0;

M
Matt Caswell 已提交
305
    ret = bio_read_intern(b, data, (size_t)dlen, &readbytes);
306 307

    if (ret > 0) {
308
        /* *readbytes should always be <= dlen */
M
Matt Caswell 已提交
309
        ret = (int)readbytes;
310 311 312 313 314
    }

    return ret;
}

M
Matt Caswell 已提交
315
int BIO_read_ex(BIO *b, void *data, size_t dlen, size_t *readbytes)
316
{
317
    return bio_read_intern(b, data, dlen, readbytes) > 0;
318 319
}

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
        ERR_raise(ERR_LIB_BIO, ERR_R_PASSED_NULL_PARAMETER);
327 328 329
        return -1;
    }
    if (b->method == NULL || b->method->bwrite == NULL) {
330
        ERR_raise(ERR_LIB_BIO, BIO_R_UNSUPPORTED_METHOD);
331
        return -2;
332
    }
333

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

339
    if (!b->init) {
340
        ERR_raise(ERR_LIB_BIO, BIO_R_UNINITIALIZED);
341
        return -1;
342
    }
343

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

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

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

    return ret;
354
}
355

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

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

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

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

    return ret;
}

374
int BIO_write_ex(BIO *b, const void *data, size_t dlen, size_t *written)
375
{
376
    return bio_write_intern(b, data, dlen, written) > 0;
377 378
}

379
int BIO_puts(BIO *b, const char *buf)
380
{
381
    int ret;
382
    size_t written = 0;
383

384
    if (b == NULL) {
385
        ERR_raise(ERR_LIB_BIO, ERR_R_PASSED_NULL_PARAMETER);
386 387 388
        return -1;
    }
    if (b->method == NULL || b->method->bputs == NULL) {
389
        ERR_raise(ERR_LIB_BIO, BIO_R_UNSUPPORTED_METHOD);
390
        return -2;
391
    }
392

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

399
    if (!b->init) {
400
        ERR_raise(ERR_LIB_BIO, BIO_R_UNINITIALIZED);
401
        return -1;
402
    }
403

404
    ret = b->method->bputs(b, buf);
405

406 407 408 409 410 411 412
    if (ret > 0) {
        b->num_write += (uint64_t)ret;
        written = ret;
        ret = 1;
    }

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

    if (ret > 0) {
417
        if (written > INT_MAX) {
418
            ERR_raise(ERR_LIB_BIO, BIO_R_LENGTH_TOO_LONG);
419
            ret = -1;
420
        } else {
421
            ret = (int)written;
422
        }
423
    }
424

425
    return ret;
426
}
427

428
int BIO_gets(BIO *b, char *buf, int size)
429
{
430
    int ret;
M
Matt Caswell 已提交
431
    size_t readbytes = 0;
432

433
    if (b == NULL) {
434
        ERR_raise(ERR_LIB_BIO, ERR_R_PASSED_NULL_PARAMETER);
435 436 437
        return -1;
    }
    if (b->method == NULL || b->method->bgets == NULL) {
438
        ERR_raise(ERR_LIB_BIO, BIO_R_UNSUPPORTED_METHOD);
K
KaoruToda 已提交
439
        return -2;
440 441
    }

442
    if (size < 0) {
443
        ERR_raise(ERR_LIB_BIO, BIO_R_INVALID_ARGUMENT);
444
        return -1;
445 446
    }

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

    if (!b->init) {
454
        ERR_raise(ERR_LIB_BIO, BIO_R_UNINITIALIZED);
455
        return -1;
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 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510
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;
}

511 512 513 514 515 516 517 518 519 520 521
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;
}
522

U
Ulf Möller 已提交
523
long BIO_int_ctrl(BIO *b, int cmd, long larg, int iarg)
524 525
{
    int i;
526

527
    i = iarg;
K
KaoruToda 已提交
528
    return BIO_ctrl(b, cmd, larg, (char *)&i);
529
}
530

531
void *BIO_ptr_ctrl(BIO *b, int cmd, long larg)
532
{
533
    void *p = NULL;
534

535
    if (BIO_ctrl(b, cmd, larg, (char *)&p) <= 0)
K
KaoruToda 已提交
536
        return NULL;
537
    else
K
KaoruToda 已提交
538
        return p;
539
}
540

B
Bodo Möller 已提交
541
long BIO_ctrl(BIO *b, int cmd, long larg, void *parg)
542 543
{
    long ret;
544

545
    if (b == NULL) {
546
        ERR_raise(ERR_LIB_BIO, ERR_R_PASSED_NULL_PARAMETER);
547 548 549
        return -1;
    }
    if (b->method == NULL || b->method->ctrl == NULL) {
550
        ERR_raise(ERR_LIB_BIO, BIO_R_UNSUPPORTED_METHOD);
551
        return -2;
552
    }
553

554 555 556 557 558
    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;
    }
559

560
    ret = b->method->ctrl(b, cmd, larg, parg);
561

562 563 564 565 566
    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;
567
}
568

B
Bernd Edlinger 已提交
569
long BIO_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp)
570 571
{
    long ret;
572

573
    if (b == NULL) {
574 575
        ERR_raise(ERR_LIB_BIO, ERR_R_PASSED_NULL_PARAMETER);
        return -2;
576 577 578
    }
    if (b->method == NULL || b->method->callback_ctrl == NULL
            || cmd != BIO_CTRL_SET_CALLBACK) {
579
        ERR_raise(ERR_LIB_BIO, BIO_R_UNSUPPORTED_METHOD);
K
KaoruToda 已提交
580
        return -2;
581
    }
582

583 584 585 586 587 588
    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;
    }
589

590
    ret = b->method->callback_ctrl(b, cmd, fp);
591

592 593 594 595 596
    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;
597
}
598

599 600
/*
 * It is unfortunate to duplicate in functions what the BIO_(w)pending macros
B
Bodo Möller 已提交
601
 * do; but those macros have inappropriate return type, and for interfacing
602 603
 * from other programming languages, C macros aren't much of a help anyway.
 */
B
Bodo Möller 已提交
604
size_t BIO_ctrl_pending(BIO *bio)
605 606 607
{
    return BIO_ctrl(bio, BIO_CTRL_PENDING, 0, NULL);
}
B
Bodo Möller 已提交
608 609

size_t BIO_ctrl_wpending(BIO *bio)
610 611 612
{
    return BIO_ctrl(bio, BIO_CTRL_WPENDING, 0, NULL);
}
B
Bodo Möller 已提交
613

614
/* put the 'bio' on the end of b's list of operators */
U
Ulf Möller 已提交
615
BIO *BIO_push(BIO *b, BIO *bio)
616 617 618 619
{
    BIO *lb;

    if (b == NULL)
K
KaoruToda 已提交
620
        return bio;
621 622 623 624 625 626 627 628
    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 已提交
629
    return b;
630
}
631 632

/* Remove the first and return the rest */
U
Ulf Möller 已提交
633
BIO *BIO_pop(BIO *b)
634 635
{
    BIO *ret;
636

637
    if (b == NULL) {
638
        ERR_raise(ERR_LIB_BIO, ERR_R_PASSED_NULL_PARAMETER);
K
KaoruToda 已提交
639
        return NULL;
640
    }
641
    ret = b->next_bio;
642

643
    BIO_ctrl(b, BIO_CTRL_POP, 0, b);
644

645 646 647 648
    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;
649

650 651
    b->next_bio = NULL;
    b->prev_bio = NULL;
K
KaoruToda 已提交
652
    return ret;
653
}
654

U
Ulf Möller 已提交
655
BIO *BIO_get_retry_BIO(BIO *bio, int *reason)
656 657 658 659 660 661 662 663 664 665 666 667 668 669
{
    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 已提交
670
    return last;
671
}
672

U
Ulf Möller 已提交
673
int BIO_get_retry_reason(BIO *bio)
674
{
K
KaoruToda 已提交
675
    return bio->retry_reason;
676
}
677

M
Matt Caswell 已提交
678 679 680 681 682
void BIO_set_retry_reason(BIO *bio, int reason)
{
    bio->retry_reason = reason;
}

U
Ulf Möller 已提交
683
BIO *BIO_find_type(BIO *bio, int type)
684 685 686
{
    int mt, mask;

687
    if (bio == NULL) {
688
        ERR_raise(ERR_LIB_BIO, ERR_R_PASSED_NULL_PARAMETER);
689
        return NULL;
690
    }
691 692 693 694 695 696 697
    mask = type & 0xff;
    do {
        if (bio->method != NULL) {
            mt = bio->method->type;

            if (!mask) {
                if (mt & type)
K
KaoruToda 已提交
698
                    return bio;
699
            } else if (mt == type) {
K
KaoruToda 已提交
700
                return bio;
701
            }
702 703 704
        }
        bio = bio->next_bio;
    } while (bio != NULL);
K
KaoruToda 已提交
705
    return NULL;
706
}
707

D
 
Dr. Stephen Henson 已提交
708
BIO *BIO_next(BIO *b)
709
{
710
    if (b == NULL) {
711
        ERR_raise(ERR_LIB_BIO, ERR_R_PASSED_NULL_PARAMETER);
712
        return NULL;
713
    }
714 715
    return b->next_bio;
}
D
 
Dr. Stephen Henson 已提交
716

M
Matt Caswell 已提交
717 718 719 720 721
void BIO_set_next(BIO *b, BIO *next)
{
    b->next_bio = next;
}

U
Ulf Möller 已提交
722
void BIO_free_all(BIO *bio)
723 724 725 726 727 728 729 730 731 732 733 734 735 736
{
    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;
    }
}
737

U
Ulf Möller 已提交
738
BIO *BIO_dup_chain(BIO *in)
739 740 741 742 743 744 745
{
    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;
746
        new_bio->callback_ex = bio->callback_ex;
747 748 749 750 751 752 753 754 755 756 757 758 759 760 761
        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,
762 763
                                &bio->ex_data)) {
            BIO_free(new_bio);
764
            goto err;
765
        }
766 767 768 769 770 771 772 773 774

        if (ret == NULL) {
            eoc = new_bio;
            ret = eoc;
        } else {
            BIO_push(eoc, new_bio);
            eoc = new_bio;
        }
    }
K
KaoruToda 已提交
775
    return ret;
776
 err:
777 778
    BIO_free_all(ret);

K
KaoruToda 已提交
779
    return NULL;
780
}
781

U
Ulf Möller 已提交
782
void BIO_copy_next_retry(BIO *b)
783 784 785 786
{
    BIO_set_flags(b, BIO_get_retry_flags(b->next_bio));
    b->retry_reason = b->next_bio->retry_reason;
}
787

D
 
Dr. Stephen Henson 已提交
788
int BIO_set_ex_data(BIO *bio, int idx, void *data)
789
{
K
KaoruToda 已提交
790
    return CRYPTO_set_ex_data(&(bio->ex_data), idx, data);
791
}
792

793
void *BIO_get_ex_data(const BIO *bio, int idx)
794
{
K
KaoruToda 已提交
795
    return CRYPTO_get_ex_data(&(bio->ex_data), idx);
796
}
797

798
uint64_t BIO_number_read(BIO *bio)
799
{
800 801 802
    if (bio)
        return bio->num_read;
    return 0;
803 804
}

805
uint64_t BIO_number_written(BIO *bio)
806
{
807 808 809
    if (bio)
        return bio->num_write;
    return 0;
810
}
811

M
Matt Caswell 已提交
812 813 814 815
void bio_free_ex_data(BIO *bio)
{
    CRYPTO_free_ex_data(CRYPTO_EX_INDEX_BIO, bio, &bio->ex_data);
}
816 817 818 819 820 821 822

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 已提交
823
#endif
R
Rich Salz 已提交
824 825
    CRYPTO_THREAD_lock_free(bio_type_lock);
    bio_type_lock = NULL;
826
}
827 828

/* Internal variant of the below BIO_wait() not calling BIOerr() */
829
static int bio_wait(BIO *bio, time_t max_time, unsigned int nap_milliseconds)
830
{
831
#ifndef OPENSSL_NO_SOCK
832
    int fd;
833
#endif
834
    long sec_diff;
835

836
    if (max_time == 0) /* no timeout */
837 838 839
        return 1;

#ifndef OPENSSL_NO_SOCK
840
    if (BIO_get_fd(bio, &fd) > 0 && fd < FD_SETSIZE)
841 842
        return BIO_socket_wait(fd, BIO_should_read(bio), max_time);
#endif
843
    /* fall back to polling since no sockets are available */
844

845 846 847 848 849 850 851 852 853 854 855
    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;
856
    }
857
    ossl_sleep(nap_milliseconds);
858 859 860
    return 1;
}

861
/*-
862
 * Wait on (typically socket-based) BIO at most until max_time.
863 864 865 866
 * 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.
867 868
 * Returns -1 on error, 0 on timeout, and 1 on success.
 */
869
int BIO_wait(BIO *bio, time_t max_time, unsigned int nap_milliseconds)
870
{
871
    int rv = bio_wait(bio, max_time, nap_milliseconds);
872 873

    if (rv <= 0)
874 875
        ERR_raise(ERR_LIB_BIO,
                  rv == 0 ? BIO_R_TRANSFER_TIMEOUT : BIO_R_TRANSFER_ERROR);
876 877 878 879
    return rv;
}

/*
880 881 882 883 884
 * 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.
885 886
 * Returns -1 on error, 0 on timeout, and 1 on success.
 */
887
int BIO_do_connect_retry(BIO *bio, int timeout, int nap_milliseconds)
888
{
889
    int blocking = timeout <= 0;
890 891 892 893
    time_t max_time = timeout > 0 ? time(NULL) + timeout : 0;
    int rv;

    if (bio == NULL) {
894
        ERR_raise(ERR_LIB_BIO, ERR_R_PASSED_NULL_PARAMETER);
895 896 897
        return -1;
    }

898 899 900 901 902
    if (nap_milliseconds < 0)
        nap_milliseconds = 100;
    BIO_set_nbio(bio, !blocking);

 retry:
903 904
    ERR_set_mark();
    rv = BIO_do_connect(bio);
905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930

    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) {
931
            ERR_pop_to_mark();
932 933
            /* will not actually wait if timeout == 0 (i.e., blocking BIO): */
            rv = bio_wait(bio, max_time, nap_milliseconds);
934 935
            if (rv > 0)
                goto retry;
936 937
            ERR_raise(ERR_LIB_BIO,
                      rv == 0 ? BIO_R_CONNECT_TIMEOUT : BIO_R_CONNECT_ERROR);
938
        } else {
939
            ERR_clear_last_mark();
940
            rv = -1;
941
            if (err == 0) /* missing error queue entry */
942 943
                /* workaround: general error */
                ERR_raise(ERR_LIB_BIO, BIO_R_CONNECT_ERROR);
944
        }
945 946
    } else {
        ERR_clear_last_mark();
947 948 949 950
    }

    return rv;
}