handshake_helper.c 34.4 KB
Newer Older
E
Emilia Kasper 已提交
1 2 3
/*
 * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
 *
R
Rich Salz 已提交
4 5 6
 * 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
E
Emilia Kasper 已提交
7 8 9 10 11 12
 * https://www.openssl.org/source/license.html
 */

#include <string.h>

#include <openssl/bio.h>
13
#include <openssl/x509_vfy.h>
E
Emilia Kasper 已提交
14 15 16
#include <openssl/ssl.h>

#include "handshake_helper.h"
E
Emilia Kasper 已提交
17
#include "testutil.h"
E
Emilia Kasper 已提交
18

19 20
HANDSHAKE_RESULT *HANDSHAKE_RESULT_new()
{
E
Emilia Kasper 已提交
21 22
    HANDSHAKE_RESULT *ret = OPENSSL_zalloc(sizeof(*ret));
    TEST_check(ret != NULL);
23 24 25 26 27
    return ret;
}

void HANDSHAKE_RESULT_free(HANDSHAKE_RESULT *result)
{
28 29
    if (result == NULL)
        return;
30 31 32 33 34 35 36
    OPENSSL_free(result->client_npn_negotiated);
    OPENSSL_free(result->server_npn_negotiated);
    OPENSSL_free(result->client_alpn_negotiated);
    OPENSSL_free(result->server_alpn_negotiated);
    OPENSSL_free(result);
}

E
Emilia Kasper 已提交
37 38 39 40 41
/*
 * Since there appears to be no way to extract the sent/received alert
 * from the SSL object directly, we use the info callback and stash
 * the result in ex_data.
 */
42
typedef struct handshake_ex_data_st {
E
Emilia Kasper 已提交
43
    int alert_sent;
44
    int num_fatal_alerts_sent;
E
Emilia Kasper 已提交
45
    int alert_received;
T
Todd Short 已提交
46
    int session_ticket_do_not_call;
47
    ssl_servername_t servername;
E
Emilia Kasper 已提交
48 49
} HANDSHAKE_EX_DATA;

50
typedef struct ctx_data_st {
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
    unsigned char *npn_protocols;
    size_t npn_protocols_len;
    unsigned char *alpn_protocols;
    size_t alpn_protocols_len;
} CTX_DATA;

/* |ctx_data| itself is stack-allocated. */
static void ctx_data_free_data(CTX_DATA *ctx_data)
{
    OPENSSL_free(ctx_data->npn_protocols);
    ctx_data->npn_protocols = NULL;
    OPENSSL_free(ctx_data->alpn_protocols);
    ctx_data->alpn_protocols = NULL;
}

E
Emilia Kasper 已提交
66 67
static int ex_data_idx;

R
Richard Levitte 已提交
68
static void info_cb(const SSL *s, int where, int ret)
E
Emilia Kasper 已提交
69 70 71 72 73 74
{
    if (where & SSL_CB_ALERT) {
        HANDSHAKE_EX_DATA *ex_data =
            (HANDSHAKE_EX_DATA*)(SSL_get_ex_data(s, ex_data_idx));
        if (where & SSL_CB_WRITE) {
            ex_data->alert_sent = ret;
75 76 77
            if (strcmp(SSL_alert_type_string(ret), "F") == 0
                || strcmp(SSL_alert_desc_string(ret), "CN") == 0)
                ex_data->num_fatal_alerts_sent++;
E
Emilia Kasper 已提交
78 79 80 81 82 83
        } else {
            ex_data->alert_received = ret;
        }
    }
}

84
/* Select the appropriate server CTX.
85 86 87 88 89 90
 * Returns SSL_TLSEXT_ERR_OK if a match was found.
 * If |ignore| is 1, returns SSL_TLSEXT_ERR_NOACK on mismatch.
 * Otherwise, returns SSL_TLSEXT_ERR_ALERT_FATAL on mismatch.
 * An empty SNI extension also returns SSL_TSLEXT_ERR_NOACK.
 */
static int select_server_ctx(SSL *s, void *arg, int ignore)
E
Emilia Kasper 已提交
91 92
{
    const char *servername = SSL_get_servername(s, TLSEXT_NAMETYPE_host_name);
93 94 95 96 97 98 99 100 101
    HANDSHAKE_EX_DATA *ex_data =
        (HANDSHAKE_EX_DATA*)(SSL_get_ex_data(s, ex_data_idx));

    if (servername == NULL) {
        ex_data->servername = SSL_TEST_SERVERNAME_SERVER1;
        return SSL_TLSEXT_ERR_NOACK;
    }

    if (strcmp(servername, "server2") == 0) {
E
Emilia Kasper 已提交
102 103 104 105 106 107 108 109 110
        SSL_CTX *new_ctx = (SSL_CTX*)arg;
        SSL_set_SSL_CTX(s, new_ctx);
        /*
         * Copy over all the SSL_CTX options - reasonable behavior
         * allows testing of cases where the options between two
         * contexts differ/conflict
         */
        SSL_clear_options(s, 0xFFFFFFFFL);
        SSL_set_options(s, SSL_CTX_get_options(new_ctx));
111 112 113 114 115 116 117 118 119 120 121 122

        ex_data->servername = SSL_TEST_SERVERNAME_SERVER2;
        return SSL_TLSEXT_ERR_OK;
    } else if (strcmp(servername, "server1") == 0) {
        ex_data->servername = SSL_TEST_SERVERNAME_SERVER1;
        return SSL_TLSEXT_ERR_OK;
    } else if (ignore) {
        ex_data->servername = SSL_TEST_SERVERNAME_SERVER1;
        return SSL_TLSEXT_ERR_NOACK;
    } else {
        /* Don't set an explicit alert, to test library defaults. */
        return SSL_TLSEXT_ERR_ALERT_FATAL;
E
Emilia Kasper 已提交
123
    }
124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
}

/*
 * (RFC 6066):
 *  If the server understood the ClientHello extension but
 *  does not recognize the server name, the server SHOULD take one of two
 *  actions: either abort the handshake by sending a fatal-level
 *  unrecognized_name(112) alert or continue the handshake.
 *
 * This behaviour is up to the application to configure; we test both
 * configurations to ensure the state machine propagates the result
 * correctly.
 */
static int servername_ignore_cb(SSL *s, int *ad, void *arg)
{
    return select_server_ctx(s, arg, 1);
}

static int servername_reject_cb(SSL *s, int *ad, void *arg)
{
    return select_server_ctx(s, arg, 0);
E
Emilia Kasper 已提交
145 146
}

M
Matt Caswell 已提交
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 173 174 175 176 177 178
static unsigned char dummy_ocsp_resp_good_val = 0xff;
static unsigned char dummy_ocsp_resp_bad_val = 0xfe;

static int server_ocsp_cb(SSL *s, void *arg)
{
    unsigned char *resp;

    resp = OPENSSL_malloc(1);
    if (resp == NULL)
        return SSL_TLSEXT_ERR_ALERT_FATAL;
    /*
     * For the purposes of testing we just send back a dummy OCSP response
     */
    *resp = *(unsigned char *)arg;
    if (!SSL_set_tlsext_status_ocsp_resp(s, resp, 1))
        return SSL_TLSEXT_ERR_ALERT_FATAL;

    return SSL_TLSEXT_ERR_OK;
}

static int client_ocsp_cb(SSL *s, void *arg)
{
    const unsigned char *resp;
    int len;

    len = SSL_get_tlsext_status_ocsp_resp(s, &resp);
    if (len != 1 || *resp != dummy_ocsp_resp_good_val)
        return 0;

    return 1;
}

R
Richard Levitte 已提交
179
static int verify_reject_cb(X509_STORE_CTX *ctx, void *arg) {
180 181 182 183
    X509_STORE_CTX_set_error(ctx, X509_V_ERR_APPLICATION_VERIFICATION);
    return 0;
}

R
Richard Levitte 已提交
184
static int verify_accept_cb(X509_STORE_CTX *ctx, void *arg) {
185 186 187
    return 1;
}

188
static int broken_session_ticket_cb(SSL *s, unsigned char *key_name, unsigned char *iv,
R
Richard Levitte 已提交
189
                                    EVP_CIPHER_CTX *ctx, HMAC_CTX *hctx, int enc)
T
Todd Short 已提交
190 191 192 193
{
    return 0;
}

194
static int do_not_call_session_ticket_cb(SSL *s, unsigned char *key_name,
R
Richard Levitte 已提交
195 196 197
                                         unsigned char *iv,
                                         EVP_CIPHER_CTX *ctx,
                                         HMAC_CTX *hctx, int enc)
T
Todd Short 已提交
198 199 200 201 202 203 204
{
    HANDSHAKE_EX_DATA *ex_data =
        (HANDSHAKE_EX_DATA*)(SSL_get_ex_data(s, ex_data_idx));
    ex_data->session_ticket_do_not_call = 1;
    return 0;
}

205 206 207 208 209 210 211 212
/* Parse the comma-separated list into TLS format. */
static void parse_protos(const char *protos, unsigned char **out, size_t *outlen)
{
    size_t len, i, prefix;

    len = strlen(protos);

    /* Should never have reuse. */
E
Emilia Kasper 已提交
213
    TEST_check(*out == NULL);
214 215 216

    /* Test values are small, so we omit length limit checks. */
    *out = OPENSSL_malloc(len + 1);
E
Emilia Kasper 已提交
217
    TEST_check(*out != NULL);
218 219 220 221 222 223 224 225 226 227 228 229
    *outlen = len + 1;

    /*
     * foo => '3', 'f', 'o', 'o'
     * foo,bar => '3', 'f', 'o', 'o', '3', 'b', 'a', 'r'
     */
    memcpy(*out + 1, protos, len);

    prefix = 0;
    i = prefix + 1;
    while (i <= len) {
        if ((*out)[i] == ',') {
E
Emilia Kasper 已提交
230
            TEST_check(i - 1 - prefix > 0);
231 232 233 234 235
            (*out)[prefix] = i - 1 - prefix;
            prefix = i;
        }
        i++;
    }
E
Emilia Kasper 已提交
236
    TEST_check(len - prefix > 0);
237 238 239
    (*out)[prefix] = len - prefix;
}

E
Emilia Kasper 已提交
240
#ifndef OPENSSL_NO_NEXTPROTONEG
241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257
/*
 * The client SHOULD select the first protocol advertised by the server that it
 * also supports.  In the event that the client doesn't support any of server's
 * protocols, or the server doesn't advertise any, it SHOULD select the first
 * protocol that it supports.
 */
static int client_npn_cb(SSL *s, unsigned char **out, unsigned char *outlen,
                         const unsigned char *in, unsigned int inlen,
                         void *arg)
{
    CTX_DATA *ctx_data = (CTX_DATA*)(arg);
    int ret;

    ret = SSL_select_next_proto(out, outlen, in, inlen,
                                ctx_data->npn_protocols,
                                ctx_data->npn_protocols_len);
    /* Accept both OPENSSL_NPN_NEGOTIATED and OPENSSL_NPN_NO_OVERLAP. */
E
Emilia Kasper 已提交
258
    TEST_check(ret == OPENSSL_NPN_NEGOTIATED || ret == OPENSSL_NPN_NO_OVERLAP);
259 260 261 262 263 264 265 266 267 268 269
    return SSL_TLSEXT_ERR_OK;
}

static int server_npn_cb(SSL *s, const unsigned char **data,
                         unsigned int *len, void *arg)
{
    CTX_DATA *ctx_data = (CTX_DATA*)(arg);
    *data = ctx_data->npn_protocols;
    *len = ctx_data->npn_protocols_len;
    return SSL_TLSEXT_ERR_OK;
}
E
Emilia Kasper 已提交
270
#endif
271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302

/*
 * The server SHOULD select the most highly preferred protocol that it supports
 * and that is also advertised by the client.  In the event that the server
 * supports no protocols that the client advertises, then the server SHALL
 * respond with a fatal "no_application_protocol" alert.
 */
static int server_alpn_cb(SSL *s, const unsigned char **out,
                          unsigned char *outlen, const unsigned char *in,
                          unsigned int inlen, void *arg)
{
    CTX_DATA *ctx_data = (CTX_DATA*)(arg);
    int ret;

    /* SSL_select_next_proto isn't const-correct... */
    unsigned char *tmp_out;

    /*
     * The result points either to |in| or to |ctx_data->alpn_protocols|.
     * The callback is allowed to point to |in| or to a long-lived buffer,
     * so we can return directly without storing a copy.
     */
    ret = SSL_select_next_proto(&tmp_out, outlen,
                                ctx_data->alpn_protocols,
                                ctx_data->alpn_protocols_len, in, inlen);

    *out = tmp_out;
    /* Unlike NPN, we don't tolerate a mismatch. */
    return ret == OPENSSL_NPN_NEGOTIATED ? SSL_TLSEXT_ERR_OK
        : SSL_TLSEXT_ERR_NOACK;
}

303 304 305 306
/*
 * Configure callbacks and other properties that can't be set directly
 * in the server/client CONF.
 */
E
Emilia Kasper 已提交
307 308
static void configure_handshake_ctx(SSL_CTX *server_ctx, SSL_CTX *server2_ctx,
                                    SSL_CTX *client_ctx,
E
Emilia Kasper 已提交
309
                                    const SSL_TEST_CTX *test,
E
Emilia Kasper 已提交
310
                                    const SSL_TEST_EXTRA_CONF *extra,
311 312 313
                                    CTX_DATA *server_ctx_data,
                                    CTX_DATA *server2_ctx_data,
                                    CTX_DATA *client_ctx_data)
314
{
315 316 317
    unsigned char *ticket_keys;
    size_t ticket_key_len;

E
Emilia Kasper 已提交
318 319 320 321 322 323 324 325 326
    TEST_check(SSL_CTX_set_max_send_fragment(server_ctx,
                                             test->max_fragment_size) == 1);
    if (server2_ctx != NULL) {
        TEST_check(SSL_CTX_set_max_send_fragment(server2_ctx,
                                                 test->max_fragment_size) == 1);
    }
    TEST_check(SSL_CTX_set_max_send_fragment(client_ctx,
                                             test->max_fragment_size) == 1);

E
Emilia Kasper 已提交
327
    switch (extra->client.verify_callback) {
328
    case SSL_TEST_VERIFY_ACCEPT_ALL:
R
Richard Levitte 已提交
329
        SSL_CTX_set_cert_verify_callback(client_ctx, &verify_accept_cb,
330 331 332
                                         NULL);
        break;
    case SSL_TEST_VERIFY_REJECT_ALL:
R
Richard Levitte 已提交
333
        SSL_CTX_set_cert_verify_callback(client_ctx, &verify_reject_cb,
334 335
                                         NULL);
        break;
R
Rich Salz 已提交
336
    case SSL_TEST_VERIFY_NONE:
337 338
        break;
    }
E
Emilia Kasper 已提交
339 340

    /* link the two contexts for SNI purposes */
E
Emilia Kasper 已提交
341
    switch (extra->server.servername_callback) {
342 343 344 345 346 347 348 349
    case SSL_TEST_SERVERNAME_IGNORE_MISMATCH:
        SSL_CTX_set_tlsext_servername_callback(server_ctx, servername_ignore_cb);
        SSL_CTX_set_tlsext_servername_arg(server_ctx, server2_ctx);
        break;
    case SSL_TEST_SERVERNAME_REJECT_MISMATCH:
        SSL_CTX_set_tlsext_servername_callback(server_ctx, servername_reject_cb);
        SSL_CTX_set_tlsext_servername_arg(server_ctx, server2_ctx);
        break;
R
Rich Salz 已提交
350
    case SSL_TEST_SERVERNAME_CB_NONE:
351 352 353
        break;
    }

M
Matt Caswell 已提交
354 355 356 357 358 359 360 361 362 363
    if (extra->server.cert_status != SSL_TEST_CERT_STATUS_NONE) {
        SSL_CTX_set_tlsext_status_type(client_ctx, TLSEXT_STATUSTYPE_ocsp);
        SSL_CTX_set_tlsext_status_cb(client_ctx, client_ocsp_cb);
        SSL_CTX_set_tlsext_status_arg(client_ctx, NULL);
        SSL_CTX_set_tlsext_status_cb(server_ctx, server_ocsp_cb);
        SSL_CTX_set_tlsext_status_arg(server_ctx,
            ((extra->server.cert_status == SSL_TEST_CERT_STATUS_GOOD_RESPONSE)
            ? &dummy_ocsp_resp_good_val : &dummy_ocsp_resp_bad_val));
    }

E
Emilia Kasper 已提交
364 365 366 367 368
    /*
     * The initial_ctx/session_ctx always handles the encrypt/decrypt of the
     * session ticket. This ticket_key callback is assigned to the second
     * session (assigned via SNI), and should never be invoked
     */
369 370 371
    if (server2_ctx != NULL)
        SSL_CTX_set_tlsext_ticket_key_cb(server2_ctx,
                                         do_not_call_session_ticket_cb);
E
Emilia Kasper 已提交
372

E
Emilia Kasper 已提交
373
    if (extra->server.broken_session_ticket) {
R
Richard Levitte 已提交
374
        SSL_CTX_set_tlsext_ticket_key_cb(server_ctx, broken_session_ticket_cb);
T
Todd Short 已提交
375
    }
B
Ben Laurie 已提交
376
#ifndef OPENSSL_NO_NEXTPROTONEG
E
Emilia Kasper 已提交
377 378
    if (extra->server.npn_protocols != NULL) {
        parse_protos(extra->server.npn_protocols,
379 380 381 382 383
                     &server_ctx_data->npn_protocols,
                     &server_ctx_data->npn_protocols_len);
        SSL_CTX_set_next_protos_advertised_cb(server_ctx, server_npn_cb,
                                              server_ctx_data);
    }
E
Emilia Kasper 已提交
384 385
    if (extra->server2.npn_protocols != NULL) {
        parse_protos(extra->server2.npn_protocols,
386 387
                     &server2_ctx_data->npn_protocols,
                     &server2_ctx_data->npn_protocols_len);
E
Emilia Kasper 已提交
388
        TEST_check(server2_ctx != NULL);
389 390 391
        SSL_CTX_set_next_protos_advertised_cb(server2_ctx, server_npn_cb,
                                              server2_ctx_data);
    }
E
Emilia Kasper 已提交
392 393
    if (extra->client.npn_protocols != NULL) {
        parse_protos(extra->client.npn_protocols,
394 395 396 397 398
                     &client_ctx_data->npn_protocols,
                     &client_ctx_data->npn_protocols_len);
        SSL_CTX_set_next_proto_select_cb(client_ctx, client_npn_cb,
                                         client_ctx_data);
    }
E
Emilia Kasper 已提交
399
#endif
E
Emilia Kasper 已提交
400 401
    if (extra->server.alpn_protocols != NULL) {
        parse_protos(extra->server.alpn_protocols,
402 403 404 405
                     &server_ctx_data->alpn_protocols,
                     &server_ctx_data->alpn_protocols_len);
        SSL_CTX_set_alpn_select_cb(server_ctx, server_alpn_cb, server_ctx_data);
    }
E
Emilia Kasper 已提交
406
    if (extra->server2.alpn_protocols != NULL) {
E
Emilia Kasper 已提交
407
        TEST_check(server2_ctx != NULL);
E
Emilia Kasper 已提交
408
        parse_protos(extra->server2.alpn_protocols,
409 410 411 412
                     &server2_ctx_data->alpn_protocols,
                     &server2_ctx_data->alpn_protocols_len);
        SSL_CTX_set_alpn_select_cb(server2_ctx, server_alpn_cb, server2_ctx_data);
    }
E
Emilia Kasper 已提交
413
    if (extra->client.alpn_protocols != NULL) {
414 415
        unsigned char *alpn_protos = NULL;
        size_t alpn_protos_len;
E
Emilia Kasper 已提交
416
        parse_protos(extra->client.alpn_protocols,
417 418
                     &alpn_protos, &alpn_protos_len);
        /* Reversed return value convention... */
E
Emilia Kasper 已提交
419 420
        TEST_check(SSL_CTX_set_alpn_protos(client_ctx, alpn_protos,
                                           alpn_protos_len) == 0);
421 422
        OPENSSL_free(alpn_protos);
    }
E
Emilia Kasper 已提交
423

424 425 426 427 428 429
    /*
     * Use fixed session ticket keys so that we can decrypt a ticket created with
     * one CTX in another CTX. Don't address server2 for the moment.
     */
    ticket_key_len = SSL_CTX_set_tlsext_ticket_keys(server_ctx, NULL, 0);
    ticket_keys = OPENSSL_zalloc(ticket_key_len);
E
Emilia Kasper 已提交
430 431 432
    TEST_check(ticket_keys != NULL);
    TEST_check(SSL_CTX_set_tlsext_ticket_keys(server_ctx, ticket_keys,
                                              ticket_key_len) == 1);
433
    OPENSSL_free(ticket_keys);
434

435 436
    /* The default log list includes EC keys, so CT can't work without EC. */
#if !defined(OPENSSL_NO_CT) && !defined(OPENSSL_NO_EC)
E
Emilia Kasper 已提交
437
    TEST_check(SSL_CTX_set_default_ctlog_list_file(client_ctx));
438 439
    switch (extra->client.ct_validation) {
    case SSL_TEST_CT_VALIDATION_PERMISSIVE:
E
Emilia Kasper 已提交
440
        TEST_check(SSL_CTX_enable_ct(client_ctx, SSL_CT_VALIDATION_PERMISSIVE));
441 442
        break;
    case SSL_TEST_CT_VALIDATION_STRICT:
E
Emilia Kasper 已提交
443
        TEST_check(SSL_CTX_enable_ct(client_ctx, SSL_CT_VALIDATION_STRICT));
444 445 446 447 448
        break;
    case SSL_TEST_CT_VALIDATION_NONE:
        break;
    }
#endif
T
Todd Short 已提交
449 450
}

451
/* Configure per-SSL callbacks and other properties. */
T
Todd Short 已提交
452
static void configure_handshake_ssl(SSL *server, SSL *client,
E
Emilia Kasper 已提交
453
                                    const SSL_TEST_EXTRA_CONF *extra)
T
Todd Short 已提交
454
{
E
Emilia Kasper 已提交
455
    if (extra->client.servername != SSL_TEST_SERVERNAME_NONE)
E
Emilia Kasper 已提交
456
        SSL_set_tlsext_host_name(client,
E
Emilia Kasper 已提交
457
                                 ssl_servername_name(extra->client.servername));
458 459
}

460
/* The status for each connection phase. */
E
Emilia Kasper 已提交
461 462 463 464 465 466
typedef enum {
    PEER_SUCCESS,
    PEER_RETRY,
    PEER_ERROR
} peer_status_t;

467 468 469 470 471 472 473 474 475 476 477 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 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585
/* An SSL object and associated read-write buffers. */
typedef struct peer_st {
    SSL *ssl;
    /* Buffer lengths are int to match the SSL read/write API. */
    unsigned char *write_buf;
    int write_buf_len;
    unsigned char *read_buf;
    int read_buf_len;
    int bytes_to_write;
    int bytes_to_read;
    peer_status_t status;
} PEER;

static void create_peer(PEER *peer, SSL_CTX *ctx)
{
    static const int peer_buffer_size = 64 * 1024;

    peer->ssl = SSL_new(ctx);
    TEST_check(peer->ssl != NULL);
    peer->write_buf = OPENSSL_zalloc(peer_buffer_size);
    TEST_check(peer->write_buf != NULL);
    peer->read_buf = OPENSSL_zalloc(peer_buffer_size);
    TEST_check(peer->read_buf != NULL);
    peer->write_buf_len = peer->read_buf_len = peer_buffer_size;
}

static void peer_free_data(PEER *peer)
{
    SSL_free(peer->ssl);
    OPENSSL_free(peer->write_buf);
    OPENSSL_free(peer->read_buf);
}

/*
 * Note that we could do the handshake transparently under an SSL_write,
 * but separating the steps is more helpful for debugging test failures.
 */
static void do_handshake_step(PEER *peer)
{
    int ret;

    TEST_check(peer->status == PEER_RETRY);
    ret = SSL_do_handshake(peer->ssl);

    if (ret == 1) {
        peer->status = PEER_SUCCESS;
    } else if (ret == 0) {
        peer->status = PEER_ERROR;
    } else {
        int error = SSL_get_error(peer->ssl, ret);
        /* Memory bios should never block with SSL_ERROR_WANT_WRITE. */
        if (error != SSL_ERROR_WANT_READ)
            peer->status = PEER_ERROR;
    }
}

/*-
 * Send/receive some application data. The read-write sequence is
 * Peer A: (R) W - first read will yield no data
 * Peer B:  R  W
 * ...
 * Peer A:  R  W
 * Peer B:  R  W
 * Peer A:  R
 */
static void do_app_data_step(PEER *peer)
{
    int ret = 1, write_bytes;

    TEST_check(peer->status == PEER_RETRY);

    /* We read everything available... */
    while (ret > 0 && peer->bytes_to_read) {
        ret = SSL_read(peer->ssl, peer->read_buf, peer->read_buf_len);
        if (ret > 0) {
            TEST_check(ret <= peer->bytes_to_read);
            peer->bytes_to_read -= ret;
        } else if (ret == 0) {
            peer->status = PEER_ERROR;
            return;
        } else {
            int error = SSL_get_error(peer->ssl, ret);
            if (error != SSL_ERROR_WANT_READ) {
                peer->status = PEER_ERROR;
                return;
            } /* Else continue with write. */
        }
    }

    /* ... but we only write one write-buffer-full of data. */
    write_bytes = peer->bytes_to_write < peer->write_buf_len ? peer->bytes_to_write :
        peer->write_buf_len;
    if (write_bytes) {
        ret = SSL_write(peer->ssl, peer->write_buf, write_bytes);
        if (ret > 0) {
            /* SSL_write will only succeed with a complete write. */
            TEST_check(ret == write_bytes);
            peer->bytes_to_write -= ret;
        } else {
            /*
             * We should perhaps check for SSL_ERROR_WANT_READ/WRITE here
             * but this doesn't yet occur with current app data sizes.
             */
            peer->status = PEER_ERROR;
            return;
        }
    }

    /*
     * We could simply finish when there was nothing to read, and we have
     * nothing left to write. But keeping track of the expected number of bytes
     * to read gives us somewhat better guarantees that all data sent is in fact
     * received.
     */
    if (!peer->bytes_to_write && !peer->bytes_to_read) {
        peer->status = PEER_SUCCESS;
    }
}

586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633
static void do_reneg_setup_step(PEER *peer)
{
    int ret;
    char buf;

    TEST_check(peer->status == PEER_RETRY);
    /* We only support client initiated reneg at the moment */
    /* TODO: server side */
    if (!SSL_is_server(peer->ssl)) {
        ret = SSL_renegotiate(peer->ssl);
        if (!ret) {
            peer->status = PEER_ERROR;
            return;
        }
        do_handshake_step(peer);
        /*
         * If status is PEER_RETRY it means we're waiting on the server to
         * continue the handshake. As far as setting up the renegotiation is
         * concerned that is a success. The next step will continue the
         * handshake to its conclusion.
         */
        if (peer->status == PEER_RETRY)
            peer->status = PEER_SUCCESS;
        return;
    }

    /*
     * The SSL object is still expecting app data, even though it's going to
     * get a handshake message. We try to read, and it should fail - after which
     * we should be in a handshake
     */
    ret = SSL_read(peer->ssl, &buf, sizeof(buf));
    if (ret >= 0) {
        /* We're not actually expecting data - we're expect a reneg to start */
        peer->status = PEER_ERROR;
        return;
    } else {
        int error = SSL_get_error(peer->ssl, ret);
        if (error != SSL_ERROR_WANT_READ || !SSL_in_init(peer->ssl)) {
            peer->status = PEER_ERROR;
            return;
        }
    }

    peer->status = PEER_SUCCESS;
}


634 635 636 637 638 639 640 641 642 643 644 645 646 647 648
/*
 * RFC 5246 says:
 *
 * Note that as of TLS 1.1,
 *     failure to properly close a connection no longer requires that a
 *     session not be resumed.  This is a change from TLS 1.0 to conform
 *     with widespread implementation practice.
 *
 * However,
 * (a) OpenSSL requires that a connection be shutdown for all protocol versions.
 * (b) We test lower versions, too.
 * So we just implement shutdown. We do a full bidirectional shutdown so that we
 * can compare sent and received close_notify alerts and get some test coverage
 * for SSL_shutdown as a bonus.
 */
649
static void do_shutdown_step(PEER *peer)
E
Emilia Kasper 已提交
650 651 652
{
    int ret;

653 654
    TEST_check(peer->status == PEER_RETRY);
    ret = SSL_shutdown(peer->ssl);
E
Emilia Kasper 已提交
655 656

    if (ret == 1) {
657 658 659
        peer->status = PEER_SUCCESS;
    } else if (ret < 0) { /* On 0, we retry. */
        int error = SSL_get_error(peer->ssl, ret);
E
Emilia Kasper 已提交
660
        /* Memory bios should never block with SSL_ERROR_WANT_WRITE. */
661 662 663 664 665 666 667
        if (error != SSL_ERROR_WANT_READ)
            peer->status = PEER_ERROR;
    }
}

typedef enum {
    HANDSHAKE,
668 669 670
    RENEG_APPLICATION_DATA,
    RENEG_SETUP,
    RENEG_HANDSHAKE,
671 672 673 674 675
    APPLICATION_DATA,
    SHUTDOWN,
    CONNECTION_DONE
} connect_phase_t;

676 677
static connect_phase_t next_phase(const SSL_TEST_CTX *test_ctx,
                                  connect_phase_t phase)
678 679 680
{
    switch (phase) {
    case HANDSHAKE:
681 682 683 684 685 686 687 688
        if (test_ctx->handshake_mode == SSL_TEST_HANDSHAKE_RENEGOTIATE)
            return RENEG_APPLICATION_DATA;
        return APPLICATION_DATA;
    case RENEG_APPLICATION_DATA:
        return RENEG_SETUP;
    case RENEG_SETUP:
        return RENEG_HANDSHAKE;
    case RENEG_HANDSHAKE:
689 690 691 692 693
        return APPLICATION_DATA;
    case APPLICATION_DATA:
        return SHUTDOWN;
    case SHUTDOWN:
        return CONNECTION_DONE;
R
Rich Salz 已提交
694 695 696
    case CONNECTION_DONE:
        TEST_check(0);
        break;
697
    }
R
Rich Salz 已提交
698
    return -1;
699 700 701 702 703 704 705 706
}

static void do_connect_step(PEER *peer, connect_phase_t phase)
{
    switch (phase) {
    case HANDSHAKE:
        do_handshake_step(peer);
        break;
707 708 709 710 711 712 713 714 715
    case RENEG_APPLICATION_DATA:
        do_app_data_step(peer);
        break;
    case RENEG_SETUP:
        do_reneg_setup_step(peer);
        break;
    case RENEG_HANDSHAKE:
        do_handshake_step(peer);
        break;
716 717 718 719 720 721
    case APPLICATION_DATA:
        do_app_data_step(peer);
        break;
    case SHUTDOWN:
        do_shutdown_step(peer);
        break;
R
Rich Salz 已提交
722
    case CONNECTION_DONE:
723
        TEST_check(0);
R
Rich Salz 已提交
724
        break;
E
Emilia Kasper 已提交
725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786
    }
}

typedef enum {
    /* Both parties succeeded. */
    HANDSHAKE_SUCCESS,
    /* Client errored. */
    CLIENT_ERROR,
    /* Server errored. */
    SERVER_ERROR,
    /* Peers are in inconsistent state. */
    INTERNAL_ERROR,
    /* One or both peers not done. */
    HANDSHAKE_RETRY
} handshake_status_t;

/*
 * Determine the handshake outcome.
 * last_status: the status of the peer to have acted last.
 * previous_status: the status of the peer that didn't act last.
 * client_spoke_last: 1 if the client went last.
 */
static handshake_status_t handshake_status(peer_status_t last_status,
                                           peer_status_t previous_status,
                                           int client_spoke_last)
{
    switch (last_status) {
    case PEER_SUCCESS:
        switch (previous_status) {
        case PEER_SUCCESS:
            /* Both succeeded. */
            return HANDSHAKE_SUCCESS;
        case PEER_RETRY:
            /* Let the first peer finish. */
            return HANDSHAKE_RETRY;
        case PEER_ERROR:
            /*
             * Second peer succeeded despite the fact that the first peer
             * already errored. This shouldn't happen.
             */
            return INTERNAL_ERROR;
        }

    case PEER_RETRY:
        if (previous_status == PEER_RETRY) {
            /* Neither peer is done. */
            return HANDSHAKE_RETRY;
        } else {
            /*
             * Deadlock: second peer is waiting for more input while first
             * peer thinks they're done (no more input is coming).
             */
            return INTERNAL_ERROR;
        }
    case PEER_ERROR:
        switch (previous_status) {
        case PEER_SUCCESS:
            /*
             * First peer succeeded but second peer errored.
             * TODO(emilia): we should be able to continue here (with some
             * application data?) to ensure the first peer receives the
             * alert / close_notify.
787
             * (No tests currently exercise this branch.)
E
Emilia Kasper 已提交
788 789 790 791 792 793 794 795 796 797 798 799 800 801
             */
            return client_spoke_last ? CLIENT_ERROR : SERVER_ERROR;
        case PEER_RETRY:
            /* We errored; let the peer finish. */
            return HANDSHAKE_RETRY;
        case PEER_ERROR:
            /* Both peers errored. Return the one that errored first. */
            return client_spoke_last ? SERVER_ERROR : CLIENT_ERROR;
        }
    }
    /* Control should never reach here. */
    return INTERNAL_ERROR;
}

802 803 804 805 806 807 808 809 810
/* Convert unsigned char buf's that shouldn't contain any NUL-bytes to char. */
static char *dup_str(const unsigned char *in, size_t len)
{
    char *ret;

    if(len == 0)
        return NULL;

    /* Assert that the string does not contain NUL-bytes. */
E
Emilia Kasper 已提交
811
    TEST_check(OPENSSL_strnlen((const char*)(in), len) == len);
812
    ret = OPENSSL_strndup((const char*)(in), len);
E
Emilia Kasper 已提交
813
    TEST_check(ret != NULL);
814 815 816
    return ret;
}

E
Emilia Kasper 已提交
817 818 819 820 821 822 823 824 825 826 827 828 829
/*
 * Note that |extra| points to the correct client/server configuration
 * within |test_ctx|. When configuring the handshake, general mode settings
 * are taken from |test_ctx|, and client/server-specific settings should be
 * taken from |extra|.
 *
 * The configuration code should never reach into |test_ctx->extra| or
 * |test_ctx->resume_extra| directly.
 *
 * (We could refactor test mode settings into a substructure. This would result
 * in cleaner argument passing but would complicate the test configuration
 * parsing.)
 */
830 831
static HANDSHAKE_RESULT *do_handshake_internal(
    SSL_CTX *server_ctx, SSL_CTX *server2_ctx, SSL_CTX *client_ctx,
E
Emilia Kasper 已提交
832
    const SSL_TEST_CTX *test_ctx, const SSL_TEST_EXTRA_CONF *extra,
833
    SSL_SESSION *session_in, SSL_SESSION **session_out)
E
Emilia Kasper 已提交
834
{
835
    PEER server, client;
E
Emilia Kasper 已提交
836 837
    BIO *client_to_server, *server_to_client;
    HANDSHAKE_EX_DATA server_ex_data, client_ex_data;
838 839
    CTX_DATA client_ctx_data, server_ctx_data, server2_ctx_data;
    HANDSHAKE_RESULT *ret = HANDSHAKE_RESULT_new();
840 841
    int client_turn = 1;
    connect_phase_t phase = HANDSHAKE;
E
Emilia Kasper 已提交
842
    handshake_status_t status = HANDSHAKE_RETRY;
843
    const unsigned char* tick = NULL;
844
    size_t tick_len = 0;
T
Todd Short 已提交
845
    SSL_SESSION* sess = NULL;
846 847 848
    const unsigned char *proto = NULL;
    /* API dictates unsigned int rather than size_t. */
    unsigned int proto_len = 0;
E
Emilia Kasper 已提交
849

850 851 852
    memset(&server_ctx_data, 0, sizeof(server_ctx_data));
    memset(&server2_ctx_data, 0, sizeof(server2_ctx_data));
    memset(&client_ctx_data, 0, sizeof(client_ctx_data));
853 854
    memset(&server, 0, sizeof(server));
    memset(&client, 0, sizeof(client));
855

E
Emilia Kasper 已提交
856
    configure_handshake_ctx(server_ctx, server2_ctx, client_ctx, test_ctx, extra,
857
                            &server_ctx_data, &server2_ctx_data, &client_ctx_data);
858

859 860 861
    /* Setup SSL and buffers; additional configuration happens below. */
    create_peer(&server, server_ctx);
    create_peer(&client, client_ctx);
E
Emilia Kasper 已提交
862

E
Emilia Kasper 已提交
863 864
    server.bytes_to_write = client.bytes_to_read = test_ctx->app_data_size;
    client.bytes_to_write = server.bytes_to_read = test_ctx->app_data_size;
865 866

    configure_handshake_ssl(server.ssl, client.ssl, extra);
867 868
    if (session_in != NULL) {
        /* In case we're testing resumption without tickets. */
E
Emilia Kasper 已提交
869
        TEST_check(SSL_CTX_add_session(server_ctx, session_in));
870
        TEST_check(SSL_set_session(client.ssl, session_in));
871
    }
T
Todd Short 已提交
872

E
Emilia Kasper 已提交
873 874
    memset(&server_ex_data, 0, sizeof(server_ex_data));
    memset(&client_ex_data, 0, sizeof(client_ex_data));
875 876

    ret->result = SSL_TEST_INTERNAL_ERROR;
E
Emilia Kasper 已提交
877 878 879 880

    client_to_server = BIO_new(BIO_s_mem());
    server_to_client = BIO_new(BIO_s_mem());

881 882
    TEST_check(client_to_server != NULL);
    TEST_check(server_to_client != NULL);
E
Emilia Kasper 已提交
883 884 885 886 887

    /* Non-blocking bio. */
    BIO_set_nbio(client_to_server, 1);
    BIO_set_nbio(server_to_client, 1);

888 889
    SSL_set_connect_state(client.ssl);
    SSL_set_accept_state(server.ssl);
E
Emilia Kasper 已提交
890 891

    /* The bios are now owned by the SSL object. */
892
    SSL_set_bio(client.ssl, server_to_client, client_to_server);
E
Emilia Kasper 已提交
893 894
    TEST_check(BIO_up_ref(server_to_client) > 0);
    TEST_check(BIO_up_ref(client_to_server) > 0);
895
    SSL_set_bio(server.ssl, client_to_server, server_to_client);
E
Emilia Kasper 已提交
896 897

    ex_data_idx = SSL_get_ex_new_index(0, "ex data", NULL, NULL, NULL);
E
Emilia Kasper 已提交
898
    TEST_check(ex_data_idx >= 0);
E
Emilia Kasper 已提交
899

900 901 902 903 904
    TEST_check(SSL_set_ex_data(server.ssl, ex_data_idx, &server_ex_data) == 1);
    TEST_check(SSL_set_ex_data(client.ssl, ex_data_idx, &client_ex_data) == 1);

    SSL_set_info_callback(server.ssl, &info_cb);
    SSL_set_info_callback(client.ssl, &info_cb);
E
Emilia Kasper 已提交
905

906
    client.status = server.status = PEER_RETRY;
E
Emilia Kasper 已提交
907 908 909 910 911 912 913 914 915 916 917

    /*
     * Half-duplex handshake loop.
     * Client and server speak to each other synchronously in the same process.
     * We use non-blocking BIOs, so whenever one peer blocks for read, it
     * returns PEER_RETRY to indicate that it's the other peer's turn to write.
     * The handshake succeeds once both peers have succeeded. If one peer
     * errors out, we also let the other peer retry (and presumably fail).
     */
    for(;;) {
        if (client_turn) {
918 919
            do_connect_step(&client, phase);
            status = handshake_status(client.status, server.status,
E
Emilia Kasper 已提交
920 921
                                      1 /* client went last */);
        } else {
922 923
            do_connect_step(&server, phase);
            status = handshake_status(server.status, client.status,
E
Emilia Kasper 已提交
924 925 926 927 928
                                      0 /* server went last */);
        }

        switch (status) {
        case HANDSHAKE_SUCCESS:
929
            phase = next_phase(test_ctx, phase);
930
            if (phase == CONNECTION_DONE) {
931 932 933
                ret->result = SSL_TEST_SUCCESS;
                goto err;
            } else {
934 935 936 937 938 939 940
                client.status = server.status = PEER_RETRY;
                /*
                 * For now, client starts each phase. Since each phase is
                 * started separately, we can later control this more
                 * precisely, for example, to test client-initiated and
                 * server-initiated shutdown.
                 */
941 942 943
                client_turn = 1;
                break;
            }
E
Emilia Kasper 已提交
944
        case CLIENT_ERROR:
945
            ret->result = SSL_TEST_CLIENT_FAIL;
E
Emilia Kasper 已提交
946 947
            goto err;
        case SERVER_ERROR:
948
            ret->result = SSL_TEST_SERVER_FAIL;
E
Emilia Kasper 已提交
949 950
            goto err;
        case INTERNAL_ERROR:
951
            ret->result = SSL_TEST_INTERNAL_ERROR;
E
Emilia Kasper 已提交
952 953 954 955 956 957 958 959
            goto err;
        case HANDSHAKE_RETRY:
            /* Continue. */
            client_turn ^= 1;
            break;
        }
    }
 err:
960
    ret->server_alert_sent = server_ex_data.alert_sent;
961
    ret->server_num_fatal_alerts_sent = server_ex_data.num_fatal_alerts_sent;
962 963
    ret->server_alert_received = client_ex_data.alert_received;
    ret->client_alert_sent = client_ex_data.alert_sent;
964
    ret->client_num_fatal_alerts_sent = client_ex_data.num_fatal_alerts_sent;
965
    ret->client_alert_received = server_ex_data.alert_received;
966 967
    ret->server_protocol = SSL_version(server.ssl);
    ret->client_protocol = SSL_version(client.ssl);
968
    ret->servername = server_ex_data.servername;
969
    if ((sess = SSL_get0_session(client.ssl)) != NULL)
970 971 972
        SSL_SESSION_get0_ticket(sess, &tick, &tick_len);
    if (tick == NULL || tick_len == 0)
        ret->session_ticket = SSL_TEST_SESSION_TICKET_NO;
T
Todd Short 已提交
973
    else
974 975 976
        ret->session_ticket = SSL_TEST_SESSION_TICKET_YES;
    ret->session_ticket_do_not_call = server_ex_data.session_ticket_do_not_call;

B
Ben Laurie 已提交
977
#ifndef OPENSSL_NO_NEXTPROTONEG
978
    SSL_get0_next_proto_negotiated(client.ssl, &proto, &proto_len);
979 980
    ret->client_npn_negotiated = dup_str(proto, proto_len);

981
    SSL_get0_next_proto_negotiated(server.ssl, &proto, &proto_len);
982
    ret->server_npn_negotiated = dup_str(proto, proto_len);
E
Emilia Kasper 已提交
983
#endif
984

985
    SSL_get0_alpn_selected(client.ssl, &proto, &proto_len);
986 987
    ret->client_alpn_negotiated = dup_str(proto, proto_len);

988
    SSL_get0_alpn_selected(server.ssl, &proto, &proto_len);
989
    ret->server_alpn_negotiated = dup_str(proto, proto_len);
E
Emilia Kasper 已提交
990

991 992
    ret->client_resumed = SSL_session_reused(client.ssl);
    ret->server_resumed = SSL_session_reused(server.ssl);
993 994

    if (session_out != NULL)
995
        *session_out = SSL_get1_session(client.ssl);
996

997 998 999
    ctx_data_free_data(&server_ctx_data);
    ctx_data_free_data(&server2_ctx_data);
    ctx_data_free_data(&client_ctx_data);
1000

1001 1002
    peer_free_data(&server);
    peer_free_data(&client);
E
Emilia Kasper 已提交
1003 1004
    return ret;
}
1005 1006 1007

HANDSHAKE_RESULT *do_handshake(SSL_CTX *server_ctx, SSL_CTX *server2_ctx,
                               SSL_CTX *client_ctx, SSL_CTX *resume_server_ctx,
E
Emilia Kasper 已提交
1008
                               SSL_CTX *resume_client_ctx,
1009 1010 1011 1012 1013 1014
                               const SSL_TEST_CTX *test_ctx)
{
    HANDSHAKE_RESULT *result;
    SSL_SESSION *session = NULL;

    result = do_handshake_internal(server_ctx, server2_ctx, client_ctx,
E
Emilia Kasper 已提交
1015
                                   test_ctx, &test_ctx->extra,
1016
                                   NULL, &session);
1017
    if (test_ctx->handshake_mode != SSL_TEST_HANDSHAKE_RESUME)
1018 1019 1020 1021
        goto end;

    if (result->result != SSL_TEST_SUCCESS) {
        result->result = SSL_TEST_FIRST_HANDSHAKE_FAILED;
1022
        goto end;
1023 1024 1025 1026
    }

    HANDSHAKE_RESULT_free(result);
    /* We don't support SNI on second handshake yet, so server2_ctx is NULL. */
E
Emilia Kasper 已提交
1027
    result = do_handshake_internal(resume_server_ctx, NULL, resume_client_ctx,
E
Emilia Kasper 已提交
1028
                                   test_ctx, &test_ctx->resume_extra,
1029
                                   session, NULL);
1030 1031 1032 1033
 end:
    SSL_SESSION_free(session);
    return result;
}