handshake_helper.c 29.7 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 44
    int alert_sent;
    int alert_received;
T
Todd Short 已提交
45
    int session_ticket_do_not_call;
46
    ssl_servername_t servername;
E
Emilia Kasper 已提交
47 48
} HANDSHAKE_EX_DATA;

49
typedef struct ctx_data_st {
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
    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 已提交
65 66
static int ex_data_idx;

R
Richard Levitte 已提交
67
static void info_cb(const SSL *s, int where, int ret)
E
Emilia Kasper 已提交
68 69 70 71 72 73 74 75 76 77 78 79
{
    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;
        } else {
            ex_data->alert_received = ret;
        }
    }
}

80
/* Select the appropriate server CTX.
81 82 83 84 85 86
 * 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 已提交
87 88
{
    const char *servername = SSL_get_servername(s, TLSEXT_NAMETYPE_host_name);
89 90 91 92 93 94 95 96 97
    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 已提交
98 99 100 101 102 103 104 105 106
        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));
107 108 109 110 111 112 113 114 115 116 117 118

        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 已提交
119
    }
120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
}

/*
 * (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 已提交
141 142
}

R
Richard Levitte 已提交
143
static int verify_reject_cb(X509_STORE_CTX *ctx, void *arg) {
144 145 146 147
    X509_STORE_CTX_set_error(ctx, X509_V_ERR_APPLICATION_VERIFICATION);
    return 0;
}

R
Richard Levitte 已提交
148
static int verify_accept_cb(X509_STORE_CTX *ctx, void *arg) {
149 150 151
    return 1;
}

152
static int broken_session_ticket_cb(SSL *s, unsigned char *key_name, unsigned char *iv,
R
Richard Levitte 已提交
153
                                    EVP_CIPHER_CTX *ctx, HMAC_CTX *hctx, int enc)
T
Todd Short 已提交
154 155 156 157
{
    return 0;
}

158
static int do_not_call_session_ticket_cb(SSL *s, unsigned char *key_name,
R
Richard Levitte 已提交
159 160 161
                                         unsigned char *iv,
                                         EVP_CIPHER_CTX *ctx,
                                         HMAC_CTX *hctx, int enc)
T
Todd Short 已提交
162 163 164 165 166 167 168
{
    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;
}

169 170 171 172 173 174 175 176
/* 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 已提交
177
    TEST_check(*out == NULL);
178 179 180

    /* Test values are small, so we omit length limit checks. */
    *out = OPENSSL_malloc(len + 1);
E
Emilia Kasper 已提交
181
    TEST_check(*out != NULL);
182 183 184 185 186 187 188 189 190 191 192 193
    *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 已提交
194
            TEST_check(i - 1 - prefix > 0);
195 196 197 198 199
            (*out)[prefix] = i - 1 - prefix;
            prefix = i;
        }
        i++;
    }
E
Emilia Kasper 已提交
200
    TEST_check(len - prefix > 0);
201 202 203
    (*out)[prefix] = len - prefix;
}

E
Emilia Kasper 已提交
204
#ifndef OPENSSL_NO_NEXTPROTONEG
205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221
/*
 * 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 已提交
222
    TEST_check(ret == OPENSSL_NPN_NEGOTIATED || ret == OPENSSL_NPN_NO_OVERLAP);
223 224 225 226 227 228 229 230 231 232 233
    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 已提交
234
#endif
235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266

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

267 268 269 270
/*
 * Configure callbacks and other properties that can't be set directly
 * in the server/client CONF.
 */
E
Emilia Kasper 已提交
271 272
static void configure_handshake_ctx(SSL_CTX *server_ctx, SSL_CTX *server2_ctx,
                                    SSL_CTX *client_ctx,
E
Emilia Kasper 已提交
273
                                    const SSL_TEST_EXTRA_CONF *extra,
274 275 276
                                    CTX_DATA *server_ctx_data,
                                    CTX_DATA *server2_ctx_data,
                                    CTX_DATA *client_ctx_data)
277
{
278 279 280
    unsigned char *ticket_keys;
    size_t ticket_key_len;

E
Emilia Kasper 已提交
281
    switch (extra->client.verify_callback) {
282
    case SSL_TEST_VERIFY_ACCEPT_ALL:
R
Richard Levitte 已提交
283
        SSL_CTX_set_cert_verify_callback(client_ctx, &verify_accept_cb,
284 285 286
                                         NULL);
        break;
    case SSL_TEST_VERIFY_REJECT_ALL:
R
Richard Levitte 已提交
287
        SSL_CTX_set_cert_verify_callback(client_ctx, &verify_reject_cb,
288 289 290 291 292
                                         NULL);
        break;
    default:
        break;
    }
E
Emilia Kasper 已提交
293 294

    /* link the two contexts for SNI purposes */
E
Emilia Kasper 已提交
295
    switch (extra->server.servername_callback) {
296 297 298 299 300 301 302 303 304 305 306 307
    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;
    default:
        break;
    }

E
Emilia Kasper 已提交
308 309 310 311 312
    /*
     * 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
     */
313 314 315
    if (server2_ctx != NULL)
        SSL_CTX_set_tlsext_ticket_key_cb(server2_ctx,
                                         do_not_call_session_ticket_cb);
E
Emilia Kasper 已提交
316

E
Emilia Kasper 已提交
317
    if (extra->server.broken_session_ticket) {
R
Richard Levitte 已提交
318
        SSL_CTX_set_tlsext_ticket_key_cb(server_ctx, broken_session_ticket_cb);
T
Todd Short 已提交
319
    }
B
Ben Laurie 已提交
320
#ifndef OPENSSL_NO_NEXTPROTONEG
E
Emilia Kasper 已提交
321 322
    if (extra->server.npn_protocols != NULL) {
        parse_protos(extra->server.npn_protocols,
323 324 325 326 327
                     &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 已提交
328 329
    if (extra->server2.npn_protocols != NULL) {
        parse_protos(extra->server2.npn_protocols,
330 331
                     &server2_ctx_data->npn_protocols,
                     &server2_ctx_data->npn_protocols_len);
E
Emilia Kasper 已提交
332
        TEST_check(server2_ctx != NULL);
333 334 335
        SSL_CTX_set_next_protos_advertised_cb(server2_ctx, server_npn_cb,
                                              server2_ctx_data);
    }
E
Emilia Kasper 已提交
336 337
    if (extra->client.npn_protocols != NULL) {
        parse_protos(extra->client.npn_protocols,
338 339 340 341 342
                     &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 已提交
343
#endif
E
Emilia Kasper 已提交
344 345
    if (extra->server.alpn_protocols != NULL) {
        parse_protos(extra->server.alpn_protocols,
346 347 348 349
                     &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 已提交
350
    if (extra->server2.alpn_protocols != NULL) {
E
Emilia Kasper 已提交
351
        TEST_check(server2_ctx != NULL);
E
Emilia Kasper 已提交
352
        parse_protos(extra->server2.alpn_protocols,
353 354 355 356
                     &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 已提交
357
    if (extra->client.alpn_protocols != NULL) {
358 359
        unsigned char *alpn_protos = NULL;
        size_t alpn_protos_len;
E
Emilia Kasper 已提交
360
        parse_protos(extra->client.alpn_protocols,
361 362
                     &alpn_protos, &alpn_protos_len);
        /* Reversed return value convention... */
E
Emilia Kasper 已提交
363 364
        TEST_check(SSL_CTX_set_alpn_protos(client_ctx, alpn_protos,
                                           alpn_protos_len) == 0);
365 366
        OPENSSL_free(alpn_protos);
    }
E
Emilia Kasper 已提交
367

368 369 370 371 372 373
    /*
     * 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 已提交
374 375 376
    TEST_check(ticket_keys != NULL);
    TEST_check(SSL_CTX_set_tlsext_ticket_keys(server_ctx, ticket_keys,
                                              ticket_key_len) == 1);
377
    OPENSSL_free(ticket_keys);
378

379 380
    /* 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 已提交
381
    TEST_check(SSL_CTX_set_default_ctlog_list_file(client_ctx));
382 383
    switch (extra->client.ct_validation) {
    case SSL_TEST_CT_VALIDATION_PERMISSIVE:
E
Emilia Kasper 已提交
384
        TEST_check(SSL_CTX_enable_ct(client_ctx, SSL_CT_VALIDATION_PERMISSIVE));
385 386
        break;
    case SSL_TEST_CT_VALIDATION_STRICT:
E
Emilia Kasper 已提交
387
        TEST_check(SSL_CTX_enable_ct(client_ctx, SSL_CT_VALIDATION_STRICT));
388 389 390 391 392
        break;
    case SSL_TEST_CT_VALIDATION_NONE:
        break;
    }
#endif
T
Todd Short 已提交
393 394
}

395
/* Configure per-SSL callbacks and other properties. */
T
Todd Short 已提交
396
static void configure_handshake_ssl(SSL *server, SSL *client,
E
Emilia Kasper 已提交
397
                                    const SSL_TEST_EXTRA_CONF *extra)
T
Todd Short 已提交
398
{
E
Emilia Kasper 已提交
399
    if (extra->client.servername != SSL_TEST_SERVERNAME_NONE)
E
Emilia Kasper 已提交
400
        SSL_set_tlsext_host_name(client,
E
Emilia Kasper 已提交
401
                                 ssl_servername_name(extra->client.servername));
402 403
}

404
/* The status for each connection phase. */
E
Emilia Kasper 已提交
405 406 407 408 409 410
typedef enum {
    PEER_SUCCESS,
    PEER_RETRY,
    PEER_ERROR
} peer_status_t;

411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 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
/* 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;
    }
}

530 531 532 533 534 535 536 537 538 539 540 541 542 543 544
/*
 * 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.
 */
545
static void do_shutdown_step(PEER *peer)
E
Emilia Kasper 已提交
546 547 548
{
    int ret;

549 550
    TEST_check(peer->status == PEER_RETRY);
    ret = SSL_shutdown(peer->ssl);
E
Emilia Kasper 已提交
551 552

    if (ret == 1) {
553 554 555
        peer->status = PEER_SUCCESS;
    } else if (ret < 0) { /* On 0, we retry. */
        int error = SSL_get_error(peer->ssl, ret);
E
Emilia Kasper 已提交
556
        /* Memory bios should never block with SSL_ERROR_WANT_WRITE. */
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 586 587 588 589 590 591 592 593 594 595 596
        if (error != SSL_ERROR_WANT_READ)
            peer->status = PEER_ERROR;
    }
}

typedef enum {
    HANDSHAKE,
    APPLICATION_DATA,
    SHUTDOWN,
    CONNECTION_DONE
} connect_phase_t;

static connect_phase_t next_phase(connect_phase_t phase)
{
    switch (phase) {
    case HANDSHAKE:
        return APPLICATION_DATA;
    case APPLICATION_DATA:
        return SHUTDOWN;
    case SHUTDOWN:
        return CONNECTION_DONE;
    default:
        TEST_check(0); /* Should never call next_phase when done. */
    }
}

static void do_connect_step(PEER *peer, connect_phase_t phase)
{
    switch (phase) {
    case HANDSHAKE:
        do_handshake_step(peer);
        break;
    case APPLICATION_DATA:
        do_app_data_step(peer);
        break;
    case SHUTDOWN:
        do_shutdown_step(peer);
        break;
    default:
        TEST_check(0);
E
Emilia Kasper 已提交
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 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658
    }
}

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.
659
             * (No tests currently exercise this branch.)
E
Emilia Kasper 已提交
660 661 662 663 664 665 666 667 668 669 670 671 672 673
             */
            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;
}

674 675 676 677 678 679 680 681 682
/* 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 已提交
683
    TEST_check(OPENSSL_strnlen((const char*)(in), len) == len);
684
    ret = OPENSSL_strndup((const char*)(in), len);
E
Emilia Kasper 已提交
685
    TEST_check(ret != NULL);
686 687 688
    return ret;
}

689 690
static HANDSHAKE_RESULT *do_handshake_internal(
    SSL_CTX *server_ctx, SSL_CTX *server2_ctx, SSL_CTX *client_ctx,
691 692
    const SSL_TEST_EXTRA_CONF *extra, int app_data_size,
    SSL_SESSION *session_in, SSL_SESSION **session_out)
E
Emilia Kasper 已提交
693
{
694
    PEER server, client;
E
Emilia Kasper 已提交
695 696
    BIO *client_to_server, *server_to_client;
    HANDSHAKE_EX_DATA server_ex_data, client_ex_data;
697 698
    CTX_DATA client_ctx_data, server_ctx_data, server2_ctx_data;
    HANDSHAKE_RESULT *ret = HANDSHAKE_RESULT_new();
699 700
    int client_turn = 1;
    connect_phase_t phase = HANDSHAKE;
E
Emilia Kasper 已提交
701
    handshake_status_t status = HANDSHAKE_RETRY;
702
    const unsigned char* tick = NULL;
703
    size_t tick_len = 0;
T
Todd Short 已提交
704
    SSL_SESSION* sess = NULL;
705 706 707
    const unsigned char *proto = NULL;
    /* API dictates unsigned int rather than size_t. */
    unsigned int proto_len = 0;
E
Emilia Kasper 已提交
708

709 710 711
    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));
712 713
    memset(&server, 0, sizeof(server));
    memset(&client, 0, sizeof(client));
714

E
Emilia Kasper 已提交
715
    configure_handshake_ctx(server_ctx, server2_ctx, client_ctx, extra,
716
                            &server_ctx_data, &server2_ctx_data, &client_ctx_data);
717

718 719 720
    /* Setup SSL and buffers; additional configuration happens below. */
    create_peer(&server, server_ctx);
    create_peer(&client, client_ctx);
E
Emilia Kasper 已提交
721

722 723 724 725
    server.bytes_to_write = client.bytes_to_read = app_data_size;
    client.bytes_to_write = server.bytes_to_read = app_data_size;

    configure_handshake_ssl(server.ssl, client.ssl, extra);
726 727
    if (session_in != NULL) {
        /* In case we're testing resumption without tickets. */
E
Emilia Kasper 已提交
728
        TEST_check(SSL_CTX_add_session(server_ctx, session_in));
729
        TEST_check(SSL_set_session(client.ssl, session_in));
730
    }
T
Todd Short 已提交
731

E
Emilia Kasper 已提交
732 733
    memset(&server_ex_data, 0, sizeof(server_ex_data));
    memset(&client_ex_data, 0, sizeof(client_ex_data));
734 735

    ret->result = SSL_TEST_INTERNAL_ERROR;
E
Emilia Kasper 已提交
736 737 738 739

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

740 741
    TEST_check(client_to_server != NULL);
    TEST_check(server_to_client != NULL);
E
Emilia Kasper 已提交
742 743 744 745 746

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

747 748
    SSL_set_connect_state(client.ssl);
    SSL_set_accept_state(server.ssl);
E
Emilia Kasper 已提交
749 750

    /* The bios are now owned by the SSL object. */
751
    SSL_set_bio(client.ssl, server_to_client, client_to_server);
E
Emilia Kasper 已提交
752 753
    TEST_check(BIO_up_ref(server_to_client) > 0);
    TEST_check(BIO_up_ref(client_to_server) > 0);
754
    SSL_set_bio(server.ssl, client_to_server, server_to_client);
E
Emilia Kasper 已提交
755 756

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

759 760 761 762 763
    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 已提交
764

765
    client.status = server.status = PEER_RETRY;
E
Emilia Kasper 已提交
766 767 768 769 770 771 772 773 774 775 776

    /*
     * 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) {
777 778
            do_connect_step(&client, phase);
            status = handshake_status(client.status, server.status,
E
Emilia Kasper 已提交
779 780
                                      1 /* client went last */);
        } else {
781 782
            do_connect_step(&server, phase);
            status = handshake_status(server.status, client.status,
E
Emilia Kasper 已提交
783 784 785 786 787
                                      0 /* server went last */);
        }

        switch (status) {
        case HANDSHAKE_SUCCESS:
788 789
            phase = next_phase(phase);
            if (phase == CONNECTION_DONE) {
790 791 792
                ret->result = SSL_TEST_SUCCESS;
                goto err;
            } else {
793 794 795 796 797 798 799
                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.
                 */
800 801 802
                client_turn = 1;
                break;
            }
E
Emilia Kasper 已提交
803
        case CLIENT_ERROR:
804
            ret->result = SSL_TEST_CLIENT_FAIL;
E
Emilia Kasper 已提交
805 806
            goto err;
        case SERVER_ERROR:
807
            ret->result = SSL_TEST_SERVER_FAIL;
E
Emilia Kasper 已提交
808 809
            goto err;
        case INTERNAL_ERROR:
810
            ret->result = SSL_TEST_INTERNAL_ERROR;
E
Emilia Kasper 已提交
811 812 813 814 815 816 817 818
            goto err;
        case HANDSHAKE_RETRY:
            /* Continue. */
            client_turn ^= 1;
            break;
        }
    }
 err:
819 820 821 822
    ret->server_alert_sent = server_ex_data.alert_sent;
    ret->server_alert_received = client_ex_data.alert_received;
    ret->client_alert_sent = client_ex_data.alert_sent;
    ret->client_alert_received = server_ex_data.alert_received;
823 824
    ret->server_protocol = SSL_version(server.ssl);
    ret->client_protocol = SSL_version(client.ssl);
825
    ret->servername = server_ex_data.servername;
826
    if ((sess = SSL_get0_session(client.ssl)) != NULL)
827 828 829
        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 已提交
830
    else
831 832 833
        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 已提交
834
#ifndef OPENSSL_NO_NEXTPROTONEG
835
    SSL_get0_next_proto_negotiated(client.ssl, &proto, &proto_len);
836 837
    ret->client_npn_negotiated = dup_str(proto, proto_len);

838
    SSL_get0_next_proto_negotiated(server.ssl, &proto, &proto_len);
839
    ret->server_npn_negotiated = dup_str(proto, proto_len);
E
Emilia Kasper 已提交
840
#endif
841

842
    SSL_get0_alpn_selected(client.ssl, &proto, &proto_len);
843 844
    ret->client_alpn_negotiated = dup_str(proto, proto_len);

845
    SSL_get0_alpn_selected(server.ssl, &proto, &proto_len);
846
    ret->server_alpn_negotiated = dup_str(proto, proto_len);
E
Emilia Kasper 已提交
847

848 849
    ret->client_resumed = SSL_session_reused(client.ssl);
    ret->server_resumed = SSL_session_reused(server.ssl);
850 851

    if (session_out != NULL)
852
        *session_out = SSL_get1_session(client.ssl);
853

854 855 856
    ctx_data_free_data(&server_ctx_data);
    ctx_data_free_data(&server2_ctx_data);
    ctx_data_free_data(&client_ctx_data);
857

858 859
    peer_free_data(&server);
    peer_free_data(&client);
E
Emilia Kasper 已提交
860 861
    return ret;
}
862 863 864

HANDSHAKE_RESULT *do_handshake(SSL_CTX *server_ctx, SSL_CTX *server2_ctx,
                               SSL_CTX *client_ctx, SSL_CTX *resume_server_ctx,
E
Emilia Kasper 已提交
865
                               SSL_CTX *resume_client_ctx,
866 867 868 869 870 871
                               const SSL_TEST_CTX *test_ctx)
{
    HANDSHAKE_RESULT *result;
    SSL_SESSION *session = NULL;

    result = do_handshake_internal(server_ctx, server2_ctx, client_ctx,
872 873
                                   &test_ctx->extra, test_ctx->app_data_size,
                                   NULL, &session);
874 875 876
    if (test_ctx->handshake_mode == SSL_TEST_HANDSHAKE_SIMPLE)
        goto end;

E
Emilia Kasper 已提交
877
    TEST_check(test_ctx->handshake_mode == SSL_TEST_HANDSHAKE_RESUME);
878 879 880

    if (result->result != SSL_TEST_SUCCESS) {
        result->result = SSL_TEST_FIRST_HANDSHAKE_FAILED;
881
        goto end;
882 883 884 885
    }

    HANDSHAKE_RESULT_free(result);
    /* We don't support SNI on second handshake yet, so server2_ctx is NULL. */
E
Emilia Kasper 已提交
886
    result = do_handshake_internal(resume_server_ctx, NULL, resume_client_ctx,
887 888
                                   &test_ctx->resume_extra, test_ctx->app_data_size,
                                   session, NULL);
889 890 891 892
 end:
    SSL_SESSION_free(session);
    return result;
}