bio_ssl.c 13.0 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
 */

#include <stdio.h>
11
#include <stdlib.h>
12 13
#include <string.h>
#include <errno.h>
14
#include <openssl/crypto.h>
M
Matt Caswell 已提交
15
#include "internal/bio.h"
16
#include <openssl/err.h>
17
#include "ssl_locl.h"
18

19 20
static int ssl_write(BIO *h, const char *buf, size_t size, size_t *written);
static int ssl_read(BIO *b, char *buf, size_t size, size_t *readbytes);
21 22
static int ssl_puts(BIO *h, const char *str);
static long ssl_ctrl(BIO *h, int cmd, long arg1, void *arg2);
23 24
static int ssl_new(BIO *h);
static int ssl_free(BIO *data);
D
 
Dr. Stephen Henson 已提交
25
static long ssl_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp);
26 27 28 29 30
typedef struct bio_ssl_st {
    SSL *ssl;                   /* The ssl handle :-) */
    /* re-negotiate every time the total number of bytes is this size */
    int num_renegotiates;
    unsigned long renegotiate_count;
31
    size_t byte_count;
32 33 34 35
    unsigned long renegotiate_timeout;
    unsigned long last_time;
} BIO_SSL;

36
static const BIO_METHOD methods_sslp = {
37 38
    BIO_TYPE_SSL, "ssl",
    ssl_write,
39
    NULL,
40
    ssl_read,
41
    NULL,
42 43 44 45 46 47 48
    ssl_puts,
    NULL,                       /* ssl_gets, */
    ssl_ctrl,
    ssl_new,
    ssl_free,
    ssl_callback_ctrl,
};
49

50
const BIO_METHOD *BIO_f_ssl(void)
51 52 53
{
    return (&methods_sslp);
}
54

U
Ulf Möller 已提交
55
static int ssl_new(BIO *bi)
56
{
R
Rich Salz 已提交
57
    BIO_SSL *bs = OPENSSL_zalloc(sizeof(*bs));
58 59 60 61 62

    if (bs == NULL) {
        BIOerr(BIO_F_SSL_NEW, ERR_R_MALLOC_FAILURE);
        return (0);
    }
M
Matt Caswell 已提交
63 64 65 66 67 68
    BIO_set_init(bi, 0);
    BIO_set_data(bi, bs);
    /* Clear all flags */
    BIO_clear_flags(bi, ~0);

    return 1;
69
}
70

U
Ulf Möller 已提交
71
static int ssl_free(BIO *a)
72 73 74 75 76
{
    BIO_SSL *bs;

    if (a == NULL)
        return (0);
M
Matt Caswell 已提交
77
    bs = BIO_get_data(a);
78 79
    if (bs->ssl != NULL)
        SSL_shutdown(bs->ssl);
M
Matt Caswell 已提交
80 81
    if (BIO_get_shutdown(a)) {
        if (BIO_get_init(a))
82
            SSL_free(bs->ssl);
M
Matt Caswell 已提交
83 84 85
        /* Clear all flags */
        BIO_clear_flags(a, ~0);
        BIO_set_init(a, 0);
86
    }
M
Matt Caswell 已提交
87 88
    OPENSSL_free(bs);
    return 1;
89 90
}

91
static int ssl_read(BIO *b, char *buf, size_t size, size_t *readbytes)
92 93 94 95 96 97
{
    int ret = 1;
    BIO_SSL *sb;
    SSL *ssl;
    int retry_reason = 0;
    int r = 0;
98

99 100
    if (buf == NULL)
        return 0;
M
Matt Caswell 已提交
101
    sb = BIO_get_data(b);
102
    ssl = sb->ssl;
103

104
    BIO_clear_retry_flags(b);
105

106
    ret = ssl_read_internal(ssl, buf, size, readbytes);
107 108 109 110

    switch (SSL_get_error(ssl, ret)) {
    case SSL_ERROR_NONE:
        if (sb->renegotiate_count > 0) {
111
            sb->byte_count += *readbytes;
112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155
            if (sb->byte_count > sb->renegotiate_count) {
                sb->byte_count = 0;
                sb->num_renegotiates++;
                SSL_renegotiate(ssl);
                r = 1;
            }
        }
        if ((sb->renegotiate_timeout > 0) && (!r)) {
            unsigned long tm;

            tm = (unsigned long)time(NULL);
            if (tm > sb->last_time + sb->renegotiate_timeout) {
                sb->last_time = tm;
                sb->num_renegotiates++;
                SSL_renegotiate(ssl);
            }
        }

        break;
    case SSL_ERROR_WANT_READ:
        BIO_set_retry_read(b);
        break;
    case SSL_ERROR_WANT_WRITE:
        BIO_set_retry_write(b);
        break;
    case SSL_ERROR_WANT_X509_LOOKUP:
        BIO_set_retry_special(b);
        retry_reason = BIO_RR_SSL_X509_LOOKUP;
        break;
    case SSL_ERROR_WANT_ACCEPT:
        BIO_set_retry_special(b);
        retry_reason = BIO_RR_ACCEPT;
        break;
    case SSL_ERROR_WANT_CONNECT:
        BIO_set_retry_special(b);
        retry_reason = BIO_RR_CONNECT;
        break;
    case SSL_ERROR_SYSCALL:
    case SSL_ERROR_SSL:
    case SSL_ERROR_ZERO_RETURN:
    default:
        break;
    }

M
Matt Caswell 已提交
156
    BIO_set_retry_reason(b, retry_reason);
157

158
    return ret;
159
}
160

161
static int ssl_write(BIO *b, const char *buf, size_t size, size_t *written)
162 163 164 165 166 167
{
    int ret, r = 0;
    int retry_reason = 0;
    SSL *ssl;
    BIO_SSL *bs;

168 169
    if (buf == NULL)
        return 0;
M
Matt Caswell 已提交
170
    bs = BIO_get_data(b);
171 172 173 174
    ssl = bs->ssl;

    BIO_clear_retry_flags(b);

175
    ret = ssl_write_internal(ssl, buf, size, written);
176 177 178 179

    switch (SSL_get_error(ssl, ret)) {
    case SSL_ERROR_NONE:
        if (bs->renegotiate_count > 0) {
180
            bs->byte_count += *written;
181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217
            if (bs->byte_count > bs->renegotiate_count) {
                bs->byte_count = 0;
                bs->num_renegotiates++;
                SSL_renegotiate(ssl);
                r = 1;
            }
        }
        if ((bs->renegotiate_timeout > 0) && (!r)) {
            unsigned long tm;

            tm = (unsigned long)time(NULL);
            if (tm > bs->last_time + bs->renegotiate_timeout) {
                bs->last_time = tm;
                bs->num_renegotiates++;
                SSL_renegotiate(ssl);
            }
        }
        break;
    case SSL_ERROR_WANT_WRITE:
        BIO_set_retry_write(b);
        break;
    case SSL_ERROR_WANT_READ:
        BIO_set_retry_read(b);
        break;
    case SSL_ERROR_WANT_X509_LOOKUP:
        BIO_set_retry_special(b);
        retry_reason = BIO_RR_SSL_X509_LOOKUP;
        break;
    case SSL_ERROR_WANT_CONNECT:
        BIO_set_retry_special(b);
        retry_reason = BIO_RR_CONNECT;
    case SSL_ERROR_SYSCALL:
    case SSL_ERROR_SSL:
    default:
        break;
    }

M
Matt Caswell 已提交
218
    BIO_set_retry_reason(b, retry_reason);
219

M
Matt Caswell 已提交
220
    return ret;
221
}
222

223
static long ssl_ctrl(BIO *b, int cmd, long num, void *ptr)
224 225
{
    SSL **sslp, *ssl;
M
Matt Caswell 已提交
226
    BIO_SSL *bs, *dbs;
227 228
    BIO *dbio, *bio;
    long ret = 1;
M
Matt Caswell 已提交
229
    BIO *next;
230

M
Matt Caswell 已提交
231 232
    bs = BIO_get_data(b);
    next = BIO_next(b);
233 234 235 236 237 238 239 240 241 242 243 244
    ssl = bs->ssl;
    if ((ssl == NULL) && (cmd != BIO_C_SET_SSL))
        return (0);
    switch (cmd) {
    case BIO_CTRL_RESET:
        SSL_shutdown(ssl);

        if (ssl->handshake_func == ssl->method->ssl_connect)
            SSL_set_connect_state(ssl);
        else if (ssl->handshake_func == ssl->method->ssl_accept)
            SSL_set_accept_state(ssl);

V
Viktor Dukhovni 已提交
245
        if (!SSL_clear(ssl)) {
M
Matt Caswell 已提交
246 247 248
            ret = 0;
            break;
        }
249

M
Matt Caswell 已提交
250 251
        if (next != NULL)
            ret = BIO_ctrl(next, cmd, num, ptr);
252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286
        else if (ssl->rbio != NULL)
            ret = BIO_ctrl(ssl->rbio, cmd, num, ptr);
        else
            ret = 1;
        break;
    case BIO_CTRL_INFO:
        ret = 0;
        break;
    case BIO_C_SSL_MODE:
        if (num)                /* client mode */
            SSL_set_connect_state(ssl);
        else
            SSL_set_accept_state(ssl);
        break;
    case BIO_C_SET_SSL_RENEGOTIATE_TIMEOUT:
        ret = bs->renegotiate_timeout;
        if (num < 60)
            num = 5;
        bs->renegotiate_timeout = (unsigned long)num;
        bs->last_time = (unsigned long)time(NULL);
        break;
    case BIO_C_SET_SSL_RENEGOTIATE_BYTES:
        ret = bs->renegotiate_count;
        if ((long)num >= 512)
            bs->renegotiate_count = (unsigned long)num;
        break;
    case BIO_C_GET_SSL_NUM_RENEGOTIATES:
        ret = bs->num_renegotiates;
        break;
    case BIO_C_SET_SSL:
        if (ssl != NULL) {
            ssl_free(b);
            if (!ssl_new(b))
                return 0;
        }
M
Matt Caswell 已提交
287
        BIO_set_shutdown(b, num);
288
        ssl = (SSL *)ptr;
M
Matt Caswell 已提交
289
        bs->ssl = ssl;
290 291
        bio = SSL_get_rbio(ssl);
        if (bio != NULL) {
M
Matt Caswell 已提交
292 293 294
            if (next != NULL)
                BIO_push(bio, next);
            BIO_set_next(b, bio);
295
            BIO_up_ref(bio);
296
        }
M
Matt Caswell 已提交
297
        BIO_set_init(b, 1);
298 299 300 301 302 303 304 305 306
        break;
    case BIO_C_GET_SSL:
        if (ptr != NULL) {
            sslp = (SSL **)ptr;
            *sslp = ssl;
        } else
            ret = 0;
        break;
    case BIO_CTRL_GET_CLOSE:
M
Matt Caswell 已提交
307
        ret = BIO_get_shutdown(b);
308 309
        break;
    case BIO_CTRL_SET_CLOSE:
M
Matt Caswell 已提交
310
        BIO_set_shutdown(b, (int)num);
311 312 313 314 315 316 317 318 319 320 321 322 323 324 325
        break;
    case BIO_CTRL_WPENDING:
        ret = BIO_ctrl(ssl->wbio, cmd, num, ptr);
        break;
    case BIO_CTRL_PENDING:
        ret = SSL_pending(ssl);
        if (ret == 0)
            ret = BIO_pending(ssl->rbio);
        break;
    case BIO_CTRL_FLUSH:
        BIO_clear_retry_flags(b);
        ret = BIO_ctrl(ssl->wbio, cmd, num, ptr);
        BIO_copy_next_retry(b);
        break;
    case BIO_CTRL_PUSH:
M
Matt Caswell 已提交
326
        if ((next != NULL) && (next != ssl->rbio)) {
327 328 329 330 331
            /*
             * We are going to pass ownership of next to the SSL object...but
             * we don't own a reference to pass yet - so up ref
             */
            BIO_up_ref(next);
M
Matt Caswell 已提交
332
            SSL_set_bio(ssl, next, next);
333 334 335 336 337
        }
        break;
    case BIO_CTRL_POP:
        /* Only detach if we are the BIO explicitly being popped */
        if (b == ptr) {
M
Matt Caswell 已提交
338 339
            /* This will clear the reference we obtained during push */
            SSL_set_bio(ssl, NULL, NULL);
340 341 342 343 344
        }
        break;
    case BIO_C_DO_STATE_MACHINE:
        BIO_clear_retry_flags(b);

M
Matt Caswell 已提交
345
        BIO_set_retry_reason(b, 0);
346 347 348 349 350 351 352 353 354 355 356
        ret = (int)SSL_do_handshake(ssl);

        switch (SSL_get_error(ssl, (int)ret)) {
        case SSL_ERROR_WANT_READ:
            BIO_set_flags(b, BIO_FLAGS_READ | BIO_FLAGS_SHOULD_RETRY);
            break;
        case SSL_ERROR_WANT_WRITE:
            BIO_set_flags(b, BIO_FLAGS_WRITE | BIO_FLAGS_SHOULD_RETRY);
            break;
        case SSL_ERROR_WANT_CONNECT:
            BIO_set_flags(b, BIO_FLAGS_IO_SPECIAL | BIO_FLAGS_SHOULD_RETRY);
M
Matt Caswell 已提交
357
            BIO_set_retry_reason(b, BIO_get_retry_reason(next));
358
            break;
359 360
        case SSL_ERROR_WANT_X509_LOOKUP:
            BIO_set_retry_special(b);
M
Matt Caswell 已提交
361
            BIO_set_retry_reason(b, BIO_RR_SSL_X509_LOOKUP);
362
            break;
363 364 365 366 367 368
        default:
            break;
        }
        break;
    case BIO_CTRL_DUP:
        dbio = (BIO *)ptr;
M
Matt Caswell 已提交
369 370 371
        dbs = BIO_get_data(dbio);
        SSL_free(dbs->ssl);
        dbs->ssl = SSL_dup(ssl);
M
Matt Caswell 已提交
372 373 374 375 376
        dbs->num_renegotiates = bs->num_renegotiates;
        dbs->renegotiate_count = bs->renegotiate_count;
        dbs->byte_count = bs->byte_count;
        dbs->renegotiate_timeout = bs->renegotiate_timeout;
        dbs->last_time = bs->last_time;
M
Matt Caswell 已提交
377
        ret = (dbs->ssl != NULL);
378 379 380 381 382
        break;
    case BIO_C_GET_FD:
        ret = BIO_ctrl(ssl->rbio, cmd, num, ptr);
        break;
    case BIO_CTRL_SET_CALLBACK:
383
        ret = 0; /* use callback ctrl */
384 385 386 387 388 389 390 391 392 393 394 395 396 397 398
        break;
    case BIO_CTRL_GET_CALLBACK:
        {
            void (**fptr) (const SSL *xssl, int type, int val);

            fptr = (void (**)(const SSL *xssl, int type, int val))ptr;
            *fptr = SSL_get_info_callback(ssl);
        }
        break;
    default:
        ret = BIO_ctrl(ssl->rbio, cmd, num, ptr);
        break;
    }
    return (ret);
}
399

D
 
Dr. Stephen Henson 已提交
400
static long ssl_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
401 402 403 404 405
{
    SSL *ssl;
    BIO_SSL *bs;
    long ret = 1;

M
Matt Caswell 已提交
406
    bs = BIO_get_data(b);
407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423
    ssl = bs->ssl;
    switch (cmd) {
    case BIO_CTRL_SET_CALLBACK:
        {
            /*
             * FIXME: setting this via a completely different prototype seems
             * like a crap idea
             */
            SSL_set_info_callback(ssl, (void (*)(const SSL *, int, int))fp);
        }
        break;
    default:
        ret = BIO_callback_ctrl(ssl->rbio, cmd, fp);
        break;
    }
    return (ret);
}
424

425
static int ssl_puts(BIO *bp, const char *str)
426 427
{
    int n, ret;
428

429 430 431 432
    n = strlen(str);
    ret = BIO_write(bp, str, n);
    return (ret);
}
433

U
Ulf Möller 已提交
434
BIO *BIO_new_buffer_ssl_connect(SSL_CTX *ctx)
435
{
436
#ifndef OPENSSL_NO_SOCK
437 438 439 440 441 442 443 444 445 446
    BIO *ret = NULL, *buf = NULL, *ssl = NULL;

    if ((buf = BIO_new(BIO_f_buffer())) == NULL)
        return (NULL);
    if ((ssl = BIO_new_ssl_connect(ctx)) == NULL)
        goto err;
    if ((ret = BIO_push(buf, ssl)) == NULL)
        goto err;
    return (ret);
 err:
R
Rich Salz 已提交
447 448
    BIO_free(buf);
    BIO_free(ssl);
449
#endif
450 451
    return (NULL);
}
452

U
Ulf Möller 已提交
453
BIO *BIO_new_ssl_connect(SSL_CTX *ctx)
454
{
A
Andy Polyakov 已提交
455
#ifndef OPENSSL_NO_SOCK
456 457 458 459 460 461 462 463 464 465
    BIO *ret = NULL, *con = NULL, *ssl = NULL;

    if ((con = BIO_new(BIO_s_connect())) == NULL)
        return (NULL);
    if ((ssl = BIO_new_ssl(ctx, 1)) == NULL)
        goto err;
    if ((ret = BIO_push(ssl, con)) == NULL)
        goto err;
    return (ret);
 err:
R
Rich Salz 已提交
466
    BIO_free(con);
A
Andy Polyakov 已提交
467
#endif
468 469
    return (NULL);
}
470

U
Ulf Möller 已提交
471
BIO *BIO_new_ssl(SSL_CTX *ctx, int client)
472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489
{
    BIO *ret;
    SSL *ssl;

    if ((ret = BIO_new(BIO_f_ssl())) == NULL)
        return (NULL);
    if ((ssl = SSL_new(ctx)) == NULL) {
        BIO_free(ret);
        return (NULL);
    }
    if (client)
        SSL_set_connect_state(ssl);
    else
        SSL_set_accept_state(ssl);

    BIO_set_ssl(ret, ssl, BIO_CLOSE);
    return (ret);
}
490

U
Ulf Möller 已提交
491
int BIO_ssl_copy_session_id(BIO *t, BIO *f)
492
{
M
Matt Caswell 已提交
493
    BIO_SSL *tdata, *fdata;
494 495 496
    t = BIO_find_type(t, BIO_TYPE_SSL);
    f = BIO_find_type(f, BIO_TYPE_SSL);
    if ((t == NULL) || (f == NULL))
M
Matt Caswell 已提交
497 498 499 500
        return 0;
    tdata = BIO_get_data(t);
    fdata = BIO_get_data(f);
    if ((tdata->ssl == NULL) || (fdata->ssl == NULL))
501
        return (0);
M
Matt Caswell 已提交
502
    if (!SSL_copy_session_id(tdata->ssl, (fdata->ssl)))
M
Matt Caswell 已提交
503
        return 0;
504 505
    return (1);
}
506

U
Ulf Möller 已提交
507
void BIO_ssl_shutdown(BIO *b)
508 509 510
{
    SSL *s;

M
Matt Caswell 已提交
511 512 513 514 515 516
    b = BIO_find_type(b, BIO_TYPE_SSL);
    if (b == NULL)
        return;

    s = BIO_get_data(b);
    SSL_shutdown(s);
517
}