handshake_helper.c 59.5 KB
Newer Older
E
Emilia Kasper 已提交
1
/*
M
Matt Caswell 已提交
2
 * Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved.
E
Emilia Kasper 已提交
3
 *
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
#include <openssl/ssl.h>
15 16 17
#ifndef OPENSSL_NO_SRP
#include <openssl/srp.h>
#endif
E
Emilia Kasper 已提交
18

19
#include "../ssl/ssl_locl.h"
M
Matt Caswell 已提交
20
#include "internal/sockets.h"
R
Rich Salz 已提交
21
#include "internal/nelem.h"
E
Emilia Kasper 已提交
22
#include "handshake_helper.h"
E
Emilia Kasper 已提交
23
#include "testutil.h"
E
Emilia Kasper 已提交
24

25 26 27 28
#if !defined(OPENSSL_NO_SCTP) && !defined(OPENSSL_NO_SOCK)
#include <netinet/sctp.h>
#endif

29
HANDSHAKE_RESULT *HANDSHAKE_RESULT_new(void)
30
{
P
Pauli 已提交
31 32 33
    HANDSHAKE_RESULT *ret;

    TEST_ptr(ret = OPENSSL_zalloc(sizeof(*ret)));
34 35 36 37 38
    return ret;
}

void HANDSHAKE_RESULT_free(HANDSHAKE_RESULT *result)
{
39 40
    if (result == NULL)
        return;
41 42 43 44
    OPENSSL_free(result->client_npn_negotiated);
    OPENSSL_free(result->server_npn_negotiated);
    OPENSSL_free(result->client_alpn_negotiated);
    OPENSSL_free(result->server_alpn_negotiated);
T
Todd Short 已提交
45
    OPENSSL_free(result->result_session_ticket_app_data);
D
Dr. Stephen Henson 已提交
46
    sk_X509_NAME_pop_free(result->server_ca_names, X509_NAME_free);
D
Dr. Stephen Henson 已提交
47
    sk_X509_NAME_pop_free(result->client_ca_names, X509_NAME_free);
48
    OPENSSL_free(result->cipher);
49 50 51
    OPENSSL_free(result);
}

E
Emilia Kasper 已提交
52 53 54 55 56
/*
 * 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.
 */
57
typedef struct handshake_ex_data_st {
E
Emilia Kasper 已提交
58
    int alert_sent;
59
    int num_fatal_alerts_sent;
E
Emilia Kasper 已提交
60
    int alert_received;
T
Todd Short 已提交
61
    int session_ticket_do_not_call;
62
    ssl_servername_t servername;
E
Emilia Kasper 已提交
63 64
} HANDSHAKE_EX_DATA;

65
typedef struct ctx_data_st {
66 67 68 69
    unsigned char *npn_protocols;
    size_t npn_protocols_len;
    unsigned char *alpn_protocols;
    size_t alpn_protocols_len;
70 71
    char *srp_user;
    char *srp_password;
T
Todd Short 已提交
72
    char *session_ticket_app_data;
73 74 75 76 77 78 79 80 81
} 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;
82 83 84 85
    OPENSSL_free(ctx_data->srp_user);
    ctx_data->srp_user = NULL;
    OPENSSL_free(ctx_data->srp_password);
    ctx_data->srp_password = NULL;
T
Todd Short 已提交
86 87
    OPENSSL_free(ctx_data->session_ticket_app_data);
    ctx_data->session_ticket_app_data = NULL;
88 89
}

E
Emilia Kasper 已提交
90 91
static int ex_data_idx;

R
Richard Levitte 已提交
92
static void info_cb(const SSL *s, int where, int ret)
E
Emilia Kasper 已提交
93 94 95 96 97 98
{
    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;
99 100 101
            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 已提交
102 103 104 105 106 107
        } else {
            ex_data->alert_received = ret;
        }
    }
}

108
/* Select the appropriate server CTX.
109 110 111 112 113 114
 * 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 已提交
115 116
{
    const char *servername = SSL_get_servername(s, TLSEXT_NAMETYPE_host_name);
117 118 119 120 121 122 123 124 125
    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 已提交
126 127 128 129 130 131 132 133 134
        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));
135 136 137 138 139 140 141 142 143 144 145 146

        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 已提交
147
    }
148 149
}

150
static int client_hello_select_server_ctx(SSL *s, void *arg, int ignore)
B
Benjamin Kaduk 已提交
151 152 153 154 155 156 157 158 159 160 161
{
    const char *servername;
    const unsigned char *p;
    size_t len, remaining;
    HANDSHAKE_EX_DATA *ex_data =
        (HANDSHAKE_EX_DATA*)(SSL_get_ex_data(s, ex_data_idx));

    /*
     * The server_name extension was given too much extensibility when it
     * was written, so parsing the normal case is a bit complex.
     */
162 163
    if (!SSL_client_hello_get0_ext(s, TLSEXT_TYPE_server_name, &p,
                                   &remaining) ||
B
Benjamin Kaduk 已提交
164 165 166
        remaining <= 2)
        return 0;
    /* Extract the length of the supplied list of names. */
167
    len = (*(p++) << 8);
B
Benjamin Kaduk 已提交
168 169 170 171 172 173 174 175 176 177 178 179 180 181
    len += *(p++);
    if (len + 2 != remaining)
        return 0;
    remaining = len;
    /*
     * The list in practice only has a single element, so we only consider
     * the first one.
     */
    if (remaining == 0 || *p++ != TLSEXT_NAMETYPE_host_name)
        return 0;
    remaining--;
    /* Now we can finally pull out the byte array with the actual hostname. */
    if (remaining <= 2)
        return 0;
182
    len = (*(p++) << 8);
B
Benjamin Kaduk 已提交
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
    len += *(p++);
    if (len + 2 > remaining)
        return 0;
    remaining = len;
    servername = (const char *)p;

    if (len == strlen("server2") && strncmp(servername, "server2", len) == 0) {
        SSL_CTX *new_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));

        ex_data->servername = SSL_TEST_SERVERNAME_SERVER2;
        return 1;
    } else if (len == strlen("server1") &&
               strncmp(servername, "server1", len) == 0) {
        ex_data->servername = SSL_TEST_SERVERNAME_SERVER1;
        return 1;
    } else if (ignore) {
        ex_data->servername = SSL_TEST_SERVERNAME_SERVER1;
        return 1;
    }
    return 0;
}
212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230
/*
 * (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 已提交
231 232
}

233
static int client_hello_ignore_cb(SSL *s, int *al, void *arg)
B
Benjamin Kaduk 已提交
234
{
235
    if (!client_hello_select_server_ctx(s, arg, 1)) {
B
Benjamin Kaduk 已提交
236
        *al = SSL_AD_UNRECOGNIZED_NAME;
237
        return SSL_CLIENT_HELLO_ERROR;
B
Benjamin Kaduk 已提交
238
    }
239
    return SSL_CLIENT_HELLO_SUCCESS;
B
Benjamin Kaduk 已提交
240 241
}

242
static int client_hello_reject_cb(SSL *s, int *al, void *arg)
B
Benjamin Kaduk 已提交
243
{
244
    if (!client_hello_select_server_ctx(s, arg, 0)) {
B
Benjamin Kaduk 已提交
245
        *al = SSL_AD_UNRECOGNIZED_NAME;
246
        return SSL_CLIENT_HELLO_ERROR;
B
Benjamin Kaduk 已提交
247
    }
248
    return SSL_CLIENT_HELLO_SUCCESS;
B
Benjamin Kaduk 已提交
249 250
}

251
static int client_hello_nov12_cb(SSL *s, int *al, void *arg)
B
Benjamin Kaduk 已提交
252 253 254 255 256
{
    int ret;
    unsigned int v;
    const unsigned char *p;

257
    v = SSL_client_hello_get0_legacy_version(s);
B
Benjamin Kaduk 已提交
258 259
    if (v > TLS1_2_VERSION || v < SSL3_VERSION) {
        *al = SSL_AD_PROTOCOL_VERSION;
260
        return SSL_CLIENT_HELLO_ERROR;
B
Benjamin Kaduk 已提交
261
    }
262
    (void)SSL_client_hello_get0_session_id(s, &p);
B
Benjamin Kaduk 已提交
263
    if (p == NULL ||
264 265 266
        SSL_client_hello_get0_random(s, &p) == 0 ||
        SSL_client_hello_get0_ciphers(s, &p) == 0 ||
        SSL_client_hello_get0_compression_methods(s, &p) == 0) {
B
Benjamin Kaduk 已提交
267
        *al = SSL_AD_INTERNAL_ERROR;
268
        return SSL_CLIENT_HELLO_ERROR;
B
Benjamin Kaduk 已提交
269
    }
270
    ret = client_hello_select_server_ctx(s, arg, 0);
B
Benjamin Kaduk 已提交
271
    SSL_set_max_proto_version(s, TLS1_1_VERSION);
272
    if (!ret) {
B
Benjamin Kaduk 已提交
273
        *al = SSL_AD_UNRECOGNIZED_NAME;
274 275 276
        return SSL_CLIENT_HELLO_ERROR;
    }
    return SSL_CLIENT_HELLO_SUCCESS;
B
Benjamin Kaduk 已提交
277 278
}

M
Matt Caswell 已提交
279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310
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 已提交
311
static int verify_reject_cb(X509_STORE_CTX *ctx, void *arg) {
312 313 314 315
    X509_STORE_CTX_set_error(ctx, X509_V_ERR_APPLICATION_VERIFICATION);
    return 0;
}

R
Richard Levitte 已提交
316
static int verify_accept_cb(X509_STORE_CTX *ctx, void *arg) {
317 318 319
    return 1;
}

320
static int broken_session_ticket_cb(SSL *s, unsigned char *key_name, unsigned char *iv,
R
Richard Levitte 已提交
321
                                    EVP_CIPHER_CTX *ctx, HMAC_CTX *hctx, int enc)
T
Todd Short 已提交
322 323 324 325
{
    return 0;
}

326
static int do_not_call_session_ticket_cb(SSL *s, unsigned char *key_name,
R
Richard Levitte 已提交
327 328 329
                                         unsigned char *iv,
                                         EVP_CIPHER_CTX *ctx,
                                         HMAC_CTX *hctx, int enc)
T
Todd Short 已提交
330 331 332 333 334 335 336
{
    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;
}

337
/* Parse the comma-separated list into TLS format. */
P
Pauli 已提交
338
static int parse_protos(const char *protos, unsigned char **out, size_t *outlen)
339 340 341 342 343 344
{
    size_t len, i, prefix;

    len = strlen(protos);

    /* Should never have reuse. */
P
Pauli 已提交
345 346 347 348
    if (!TEST_ptr_null(*out)
            /* Test values are small, so we omit length limit checks. */
            || !TEST_ptr(*out = OPENSSL_malloc(len + 1)))
        return 0;
349 350 351 352 353 354 355 356 357 358 359 360
    *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] == ',') {
P
Pauli 已提交
361 362
            if (!TEST_int_gt(i - 1, prefix))
                goto err;
363
            (*out)[prefix] = (unsigned char)(i - 1 - prefix);
364 365 366 367
            prefix = i;
        }
        i++;
    }
P
Pauli 已提交
368 369
    if (!TEST_int_gt(len, prefix))
        goto err;
370
    (*out)[prefix] = (unsigned char)(len - prefix);
P
Pauli 已提交
371 372 373 374 375 376
    return 1;

err:
    OPENSSL_free(*out);
    *out = NULL;
    return 0;
377 378
}

E
Emilia Kasper 已提交
379
#ifndef OPENSSL_NO_NEXTPROTONEG
380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396
/*
 * 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. */
P
Pauli 已提交
397 398
    return TEST_true(ret == OPENSSL_NPN_NEGOTIATED || ret == OPENSSL_NPN_NO_OVERLAP)
        ? SSL_TLSEXT_ERR_OK : SSL_TLSEXT_ERR_ALERT_FATAL;
399 400 401 402 403 404 405 406 407 408
}

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 已提交
409
#endif
410 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

/*
 * 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
439
        : SSL_TLSEXT_ERR_ALERT_FATAL;
440 441
}

442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463
#ifndef OPENSSL_NO_SRP
static char *client_srp_cb(SSL *s, void *arg)
{
    CTX_DATA *ctx_data = (CTX_DATA*)(arg);
    return OPENSSL_strdup(ctx_data->srp_password);
}

static int server_srp_cb(SSL *s, int *ad, void *arg)
{
    CTX_DATA *ctx_data = (CTX_DATA*)(arg);
    if (strcmp(ctx_data->srp_user, SSL_get_srp_username(s)) != 0)
        return SSL3_AL_FATAL;
    if (SSL_set_srp_server_param_pw(s, ctx_data->srp_user,
                                    ctx_data->srp_password,
                                    "2048" /* known group */) < 0) {
        *ad = SSL_AD_INTERNAL_ERROR;
        return SSL3_AL_FATAL;
    }
    return SSL_ERROR_NONE;
}
#endif  /* !OPENSSL_NO_SRP */

T
Todd Short 已提交
464 465 466 467 468 469 470 471 472 473 474 475
static int generate_session_ticket_cb(SSL *s, void *arg)
{
    CTX_DATA *server_ctx_data = arg;
    SSL_SESSION *ss = SSL_get_session(s);
    char *app_data = server_ctx_data->session_ticket_app_data;

    if (ss == NULL || app_data == NULL)
        return 0;

    return SSL_SESSION_set1_ticket_appdata(ss, app_data, strlen(app_data));
}

476 477 478 479 480
static int decrypt_session_ticket_cb(SSL *s, SSL_SESSION *ss,
                                     const unsigned char *keyname,
                                     size_t keyname_len,
                                     SSL_TICKET_STATUS status,
                                     void *arg)
T
Todd Short 已提交
481
{
482 483 484 485 486 487 488 489 490 491 492 493
    switch (status) {
    case SSL_TICKET_EMPTY:
    case SSL_TICKET_NO_DECRYPT:
        return SSL_TICKET_RETURN_IGNORE_RENEW;
    case SSL_TICKET_SUCCESS:
        return SSL_TICKET_RETURN_USE;
    case SSL_TICKET_SUCCESS_RENEW:
        return SSL_TICKET_RETURN_USE_RENEW;
    default:
        break;
    }
    return SSL_TICKET_RETURN_ABORT;
T
Todd Short 已提交
494 495
}

496 497 498 499
/*
 * Configure callbacks and other properties that can't be set directly
 * in the server/client CONF.
 */
P
Pauli 已提交
500 501 502 503 504 505 506
static int configure_handshake_ctx(SSL_CTX *server_ctx, SSL_CTX *server2_ctx,
                                   SSL_CTX *client_ctx,
                                   const SSL_TEST_CTX *test,
                                   const SSL_TEST_EXTRA_CONF *extra,
                                   CTX_DATA *server_ctx_data,
                                   CTX_DATA *server2_ctx_data,
                                   CTX_DATA *client_ctx_data)
507
{
508 509 510
    unsigned char *ticket_keys;
    size_t ticket_key_len;

P
Pauli 已提交
511 512 513
    if (!TEST_int_eq(SSL_CTX_set_max_send_fragment(server_ctx,
                                                   test->max_fragment_size), 1))
        goto err;
E
Emilia Kasper 已提交
514
    if (server2_ctx != NULL) {
P
Pauli 已提交
515 516 517 518
        if (!TEST_int_eq(SSL_CTX_set_max_send_fragment(server2_ctx,
                                                       test->max_fragment_size),
                         1))
            goto err;
E
Emilia Kasper 已提交
519
    }
P
Pauli 已提交
520 521 522
    if (!TEST_int_eq(SSL_CTX_set_max_send_fragment(client_ctx,
                                                   test->max_fragment_size), 1))
        goto err;
E
Emilia Kasper 已提交
523

E
Emilia Kasper 已提交
524
    switch (extra->client.verify_callback) {
525
    case SSL_TEST_VERIFY_ACCEPT_ALL:
P
Pauli 已提交
526
        SSL_CTX_set_cert_verify_callback(client_ctx, &verify_accept_cb, NULL);
527 528
        break;
    case SSL_TEST_VERIFY_REJECT_ALL:
P
Pauli 已提交
529
        SSL_CTX_set_cert_verify_callback(client_ctx, &verify_reject_cb, NULL);
530
        break;
R
Rich Salz 已提交
531
    case SSL_TEST_VERIFY_NONE:
532 533
        break;
    }
E
Emilia Kasper 已提交
534

535 536 537 538 539 540
    switch (extra->client.max_fragment_len_mode) {
    case TLSEXT_max_fragment_length_512:
    case TLSEXT_max_fragment_length_1024:
    case TLSEXT_max_fragment_length_2048:
    case TLSEXT_max_fragment_length_4096:
    case TLSEXT_max_fragment_length_DISABLED:
541 542
        SSL_CTX_set_tlsext_max_fragment_length(
              client_ctx, extra->client.max_fragment_len_mode);
543 544 545
        break;
    }

B
Benjamin Kaduk 已提交
546 547
    /*
     * Link the two contexts for SNI purposes.
548 549
     * Also do ClientHello callbacks here, as setting both ClientHello and SNI
     * is bad.
B
Benjamin Kaduk 已提交
550
     */
E
Emilia Kasper 已提交
551
    switch (extra->server.servername_callback) {
552 553 554 555 556 557 558 559
    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 已提交
560
    case SSL_TEST_SERVERNAME_CB_NONE:
561
        break;
562 563
    case SSL_TEST_SERVERNAME_CLIENT_HELLO_IGNORE_MISMATCH:
        SSL_CTX_set_client_hello_cb(server_ctx, client_hello_ignore_cb, server2_ctx);
B
Benjamin Kaduk 已提交
564
        break;
565 566
    case SSL_TEST_SERVERNAME_CLIENT_HELLO_REJECT_MISMATCH:
        SSL_CTX_set_client_hello_cb(server_ctx, client_hello_reject_cb, server2_ctx);
B
Benjamin Kaduk 已提交
567
        break;
568 569
    case SSL_TEST_SERVERNAME_CLIENT_HELLO_NO_V12:
        SSL_CTX_set_client_hello_cb(server_ctx, client_hello_nov12_cb, server2_ctx);
570 571
    }

M
Matt Caswell 已提交
572 573 574 575 576 577 578 579 580 581
    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 已提交
582 583 584 585 586
    /*
     * 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
     */
587 588 589
    if (server2_ctx != NULL)
        SSL_CTX_set_tlsext_ticket_key_cb(server2_ctx,
                                         do_not_call_session_ticket_cb);
E
Emilia Kasper 已提交
590

E
Emilia Kasper 已提交
591
    if (extra->server.broken_session_ticket) {
R
Richard Levitte 已提交
592
        SSL_CTX_set_tlsext_ticket_key_cb(server_ctx, broken_session_ticket_cb);
T
Todd Short 已提交
593
    }
B
Ben Laurie 已提交
594
#ifndef OPENSSL_NO_NEXTPROTONEG
E
Emilia Kasper 已提交
595
    if (extra->server.npn_protocols != NULL) {
P
Pauli 已提交
596 597 598 599
        if (!TEST_true(parse_protos(extra->server.npn_protocols,
                                    &server_ctx_data->npn_protocols,
                                    &server_ctx_data->npn_protocols_len)))
            goto err;
R
Rich Salz 已提交
600 601
        SSL_CTX_set_npn_advertised_cb(server_ctx, server_npn_cb,
                                      server_ctx_data);
602
    }
E
Emilia Kasper 已提交
603
    if (extra->server2.npn_protocols != NULL) {
P
Pauli 已提交
604 605 606 607 608
        if (!TEST_true(parse_protos(extra->server2.npn_protocols,
                                    &server2_ctx_data->npn_protocols,
                                    &server2_ctx_data->npn_protocols_len))
                || !TEST_ptr(server2_ctx))
            goto err;
R
Rich Salz 已提交
609 610
        SSL_CTX_set_npn_advertised_cb(server2_ctx, server_npn_cb,
                                      server2_ctx_data);
611
    }
E
Emilia Kasper 已提交
612
    if (extra->client.npn_protocols != NULL) {
P
Pauli 已提交
613 614 615 616
        if (!TEST_true(parse_protos(extra->client.npn_protocols,
                                    &client_ctx_data->npn_protocols,
                                    &client_ctx_data->npn_protocols_len)))
            goto err;
617 618 619
        SSL_CTX_set_next_proto_select_cb(client_ctx, client_npn_cb,
                                         client_ctx_data);
    }
E
Emilia Kasper 已提交
620
#endif
E
Emilia Kasper 已提交
621
    if (extra->server.alpn_protocols != NULL) {
P
Pauli 已提交
622 623 624 625
        if (!TEST_true(parse_protos(extra->server.alpn_protocols,
                                    &server_ctx_data->alpn_protocols,
                                    &server_ctx_data->alpn_protocols_len)))
            goto err;
626 627
        SSL_CTX_set_alpn_select_cb(server_ctx, server_alpn_cb, server_ctx_data);
    }
E
Emilia Kasper 已提交
628
    if (extra->server2.alpn_protocols != NULL) {
P
Pauli 已提交
629 630 631 632 633 634 635 636
        if (!TEST_ptr(server2_ctx)
                || !TEST_true(parse_protos(extra->server2.alpn_protocols,
                                           &server2_ctx_data->alpn_protocols,
                                           &server2_ctx_data->alpn_protocols_len
            )))
            goto err;
        SSL_CTX_set_alpn_select_cb(server2_ctx, server_alpn_cb,
                                   server2_ctx_data);
637
    }
E
Emilia Kasper 已提交
638
    if (extra->client.alpn_protocols != NULL) {
639 640
        unsigned char *alpn_protos = NULL;
        size_t alpn_protos_len;
P
Pauli 已提交
641 642 643 644 645 646
        if (!TEST_true(parse_protos(extra->client.alpn_protocols,
                                    &alpn_protos, &alpn_protos_len))
                /* Reversed return value convention... */
                || !TEST_int_eq(SSL_CTX_set_alpn_protos(client_ctx, alpn_protos,
                                                        alpn_protos_len), 0))
            goto err;
647 648
        OPENSSL_free(alpn_protos);
    }
E
Emilia Kasper 已提交
649

T
Todd Short 已提交
650 651 652 653 654 655 656 657 658 659 660 661 662 663 664
    if (extra->server.session_ticket_app_data != NULL) {
        server_ctx_data->session_ticket_app_data =
            OPENSSL_strdup(extra->server.session_ticket_app_data);
        SSL_CTX_set_session_ticket_cb(server_ctx, generate_session_ticket_cb,
                                      decrypt_session_ticket_cb, server_ctx_data);
    }
    if (extra->server2.session_ticket_app_data != NULL) {
        if (!TEST_ptr(server2_ctx))
            goto err;
        server2_ctx_data->session_ticket_app_data =
            OPENSSL_strdup(extra->server2.session_ticket_app_data);
        SSL_CTX_set_session_ticket_cb(server2_ctx, NULL,
                                      decrypt_session_ticket_cb, server2_ctx_data);
    }

665 666 667 668 669
    /*
     * 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);
P
Pauli 已提交
670 671 672 673 674 675 676
    if (!TEST_ptr(ticket_keys = OPENSSL_zalloc(ticket_key_len))
            || !TEST_int_eq(SSL_CTX_set_tlsext_ticket_keys(server_ctx,
                                                           ticket_keys,
                                                           ticket_key_len), 1)) {
        OPENSSL_free(ticket_keys);
        goto err;
    }
677
    OPENSSL_free(ticket_keys);
678

679 680
    /* The default log list includes EC keys, so CT can't work without EC. */
#if !defined(OPENSSL_NO_CT) && !defined(OPENSSL_NO_EC)
P
Pauli 已提交
681 682
    if (!TEST_true(SSL_CTX_set_default_ctlog_list_file(client_ctx)))
        goto err;
683 684
    switch (extra->client.ct_validation) {
    case SSL_TEST_CT_VALIDATION_PERMISSIVE:
P
Pauli 已提交
685 686 687
        if (!TEST_true(SSL_CTX_enable_ct(client_ctx,
                                         SSL_CT_VALIDATION_PERMISSIVE)))
            goto err;
688 689
        break;
    case SSL_TEST_CT_VALIDATION_STRICT:
P
Pauli 已提交
690 691
        if (!TEST_true(SSL_CTX_enable_ct(client_ctx, SSL_CT_VALIDATION_STRICT)))
            goto err;
692 693 694 695 696
        break;
    case SSL_TEST_CT_VALIDATION_NONE:
        break;
    }
#endif
697 698 699 700 701 702 703 704
#ifndef OPENSSL_NO_SRP
    if (extra->server.srp_user != NULL) {
        SSL_CTX_set_srp_username_callback(server_ctx, server_srp_cb);
        server_ctx_data->srp_user = OPENSSL_strdup(extra->server.srp_user);
        server_ctx_data->srp_password = OPENSSL_strdup(extra->server.srp_password);
        SSL_CTX_set_srp_cb_arg(server_ctx, server_ctx_data);
    }
    if (extra->server2.srp_user != NULL) {
P
Pauli 已提交
705 706
        if (!TEST_ptr(server2_ctx))
            goto err;
707 708 709 710 711 712
        SSL_CTX_set_srp_username_callback(server2_ctx, server_srp_cb);
        server2_ctx_data->srp_user = OPENSSL_strdup(extra->server2.srp_user);
        server2_ctx_data->srp_password = OPENSSL_strdup(extra->server2.srp_password);
        SSL_CTX_set_srp_cb_arg(server2_ctx, server2_ctx_data);
    }
    if (extra->client.srp_user != NULL) {
P
Pauli 已提交
713 714 715
        if (!TEST_true(SSL_CTX_set_srp_username(client_ctx,
                                                extra->client.srp_user)))
            goto err;
716 717 718 719 720
        SSL_CTX_set_srp_client_pwd_callback(client_ctx, client_srp_cb);
        client_ctx_data->srp_password = OPENSSL_strdup(extra->client.srp_password);
        SSL_CTX_set_srp_cb_arg(client_ctx, client_ctx_data);
    }
#endif  /* !OPENSSL_NO_SRP */
P
Pauli 已提交
721 722 723
    return 1;
err:
    return 0;
T
Todd Short 已提交
724 725
}

726
/* Configure per-SSL callbacks and other properties. */
T
Todd Short 已提交
727
static void configure_handshake_ssl(SSL *server, SSL *client,
E
Emilia Kasper 已提交
728
                                    const SSL_TEST_EXTRA_CONF *extra)
T
Todd Short 已提交
729
{
E
Emilia Kasper 已提交
730
    if (extra->client.servername != SSL_TEST_SERVERNAME_NONE)
E
Emilia Kasper 已提交
731
        SSL_set_tlsext_host_name(client,
E
Emilia Kasper 已提交
732
                                 ssl_servername_name(extra->client.servername));
733 734
    if (extra->client.enable_pha)
        SSL_set_post_handshake_auth(client, 1);
735 736
}

737
/* The status for each connection phase. */
E
Emilia Kasper 已提交
738 739 740
typedef enum {
    PEER_SUCCESS,
    PEER_RETRY,
741
    PEER_ERROR,
P
Pauli 已提交
742 743
    PEER_WAITING,
    PEER_TEST_FAILURE
E
Emilia Kasper 已提交
744 745
} peer_status_t;

746 747 748 749 750 751 752 753 754 755 756 757 758
/* 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;

P
Pauli 已提交
759
static int create_peer(PEER *peer, SSL_CTX *ctx)
760 761
{
    static const int peer_buffer_size = 64 * 1024;
P
Pauli 已提交
762 763 764 765 766 767 768
    SSL *ssl = NULL;
    unsigned char *read_buf = NULL, *write_buf = NULL;

    if (!TEST_ptr(ssl = SSL_new(ctx))
            || !TEST_ptr(write_buf = OPENSSL_zalloc(peer_buffer_size))
            || !TEST_ptr(read_buf = OPENSSL_zalloc(peer_buffer_size)))
        goto err;
769

P
Pauli 已提交
770 771 772
    peer->ssl = ssl;
    peer->write_buf = write_buf;
    peer->read_buf = read_buf;
773
    peer->write_buf_len = peer->read_buf_len = peer_buffer_size;
P
Pauli 已提交
774 775 776 777 778 779
    return 1;
err:
    SSL_free(ssl);
    OPENSSL_free(write_buf);
    OPENSSL_free(read_buf);
    return 0;
780 781 782 783 784 785 786 787 788 789 790 791 792 793 794
}

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)
{
P
Pauli 已提交
795 796
    if (!TEST_int_eq(peer->status, PEER_RETRY)) {
        peer->status = PEER_TEST_FAILURE;
797
    } else {
P
Pauli 已提交
798 799 800 801 802
        int ret = SSL_do_handshake(peer->ssl);

        if (ret == 1) {
            peer->status = PEER_SUCCESS;
        } else if (ret == 0) {
803
            peer->status = PEER_ERROR;
P
Pauli 已提交
804 805 806 807 808 809
        } 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;
        }
810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825
    }
}

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

P
Pauli 已提交
826 827 828 829
    if (!TEST_int_eq(peer->status, PEER_RETRY)) {
        peer->status = PEER_TEST_FAILURE;
        return;
    }
830 831 832 833 834

    /* 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) {
P
Pauli 已提交
835 836 837 838
            if (!TEST_int_le(ret, peer->bytes_to_read)) {
                peer->status = PEER_TEST_FAILURE;
                return;
            }
839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858
            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. */
P
Pauli 已提交
859 860 861 862
            if (!TEST_int_eq(ret, write_bytes)) {
                peer->status = PEER_TEST_FAILURE;
                return;
            }
863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884
            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;
    }
}

M
Matt Caswell 已提交
885
static void do_reneg_setup_step(const SSL_TEST_CTX *test_ctx, PEER *peer)
886 887 888 889
{
    int ret;
    char buf;

890 891 892 893 894 895 896 897 898 899
    if (peer->status == PEER_SUCCESS) {
        /*
         * We are a client that succeeded this step previously, but the server
         * wanted to retry. Probably there is a no_renegotiation warning alert
         * waiting for us. Attempt to continue the handshake.
         */
        peer->status = PEER_RETRY;
        do_handshake_step(peer);
        return;
    }
P
Pauli 已提交
900

P
Pauli 已提交
901 902 903 904 905 906 907 908
    if (!TEST_int_eq(peer->status, PEER_RETRY)
            || !TEST_true(test_ctx->handshake_mode
                              == SSL_TEST_HANDSHAKE_RENEG_SERVER
                          || test_ctx->handshake_mode
                              == SSL_TEST_HANDSHAKE_RENEG_CLIENT
                          || test_ctx->handshake_mode
                              == SSL_TEST_HANDSHAKE_KEY_UPDATE_SERVER
                          || test_ctx->handshake_mode
909 910 911
                              == SSL_TEST_HANDSHAKE_KEY_UPDATE_CLIENT
                          || test_ctx->handshake_mode
                              == SSL_TEST_HANDSHAKE_POST_HANDSHAKE_AUTH)) {
P
Pauli 已提交
912 913 914
        peer->status = PEER_TEST_FAILURE;
        return;
    }
M
Matt Caswell 已提交
915 916 917

    /* Reset the count of the amount of app data we need to read/write */
    peer->bytes_to_write = peer->bytes_to_read = test_ctx->app_data_size;
M
Matt Caswell 已提交
918 919 920 921 922 923

    /* Check if we are the peer that is going to initiate */
    if ((test_ctx->handshake_mode == SSL_TEST_HANDSHAKE_RENEG_SERVER
                && SSL_is_server(peer->ssl))
            || (test_ctx->handshake_mode == SSL_TEST_HANDSHAKE_RENEG_CLIENT
                && !SSL_is_server(peer->ssl))) {
924
        /*
M
Matt Caswell 已提交
925 926
         * If we already asked for a renegotiation then fall through to the
         * SSL_read() below.
927
         */
M
Matt Caswell 已提交
928 929 930
        if (!SSL_renegotiate_pending(peer->ssl)) {
            /*
             * If we are the client we will always attempt to resume the
F
FdaSilvaYY 已提交
931
             * session. The server may or may not resume dependent on the
M
Matt Caswell 已提交
932 933
             * setting of SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION
             */
934
            if (SSL_is_server(peer->ssl)) {
M
Matt Caswell 已提交
935
                ret = SSL_renegotiate(peer->ssl);
936 937 938 939 940 941 942 943 944 945 946 947
            } else {
                if (test_ctx->extra.client.reneg_ciphers != NULL) {
                    if (!SSL_set_cipher_list(peer->ssl,
                                test_ctx->extra.client.reneg_ciphers)) {
                        peer->status = PEER_ERROR;
                        return;
                    }
                    ret = SSL_renegotiate(peer->ssl);
                } else {
                    ret = SSL_renegotiate_abbreviated(peer->ssl);
                }
            }
M
Matt Caswell 已提交
948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968
            if (!ret) {
                peer->status = PEER_ERROR;
                return;
            }
            do_handshake_step(peer);
            /*
             * If status is PEER_RETRY it means we're waiting on the peer 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 status is PEER_SUCCESS then we are the server and we have
             * successfully sent the HelloRequest. We need to continue to wait
             * until the handshake arrives from the client.
             */
            if (peer->status == PEER_RETRY)
                peer->status = PEER_SUCCESS;
            else if (peer->status == PEER_SUCCESS)
                peer->status = PEER_RETRY;
            return;
        }
M
Matt Caswell 已提交
969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991
    } else if (test_ctx->handshake_mode == SSL_TEST_HANDSHAKE_KEY_UPDATE_SERVER
               || test_ctx->handshake_mode
                  == SSL_TEST_HANDSHAKE_KEY_UPDATE_CLIENT) {
        if (SSL_is_server(peer->ssl)
                != (test_ctx->handshake_mode
                    == SSL_TEST_HANDSHAKE_KEY_UPDATE_SERVER)) {
            peer->status = PEER_SUCCESS;
            return;
        }

        ret = SSL_key_update(peer->ssl, test_ctx->key_update_type);
        if (!ret) {
            peer->status = PEER_ERROR;
            return;
        }
        do_handshake_step(peer);
        /*
         * This is a one step handshake. We shouldn't get anything other than
         * PEER_SUCCESS
         */
        if (peer->status != PEER_SUCCESS)
            peer->status = PEER_ERROR;
        return;
992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010
    } else if (test_ctx->handshake_mode == SSL_TEST_HANDSHAKE_POST_HANDSHAKE_AUTH) {
        if (SSL_is_server(peer->ssl)) {
            /* Make the server believe it's received the extension */
            if (test_ctx->extra.server.force_pha)
                peer->ssl->post_handshake_auth = SSL_PHA_EXT_RECEIVED;
            ret = SSL_verify_client_post_handshake(peer->ssl);
            if (!ret) {
                peer->status = PEER_ERROR;
                return;
            }
        }
        do_handshake_step(peer);
        /*
         * This is a one step handshake. We shouldn't get anything other than
         * PEER_SUCCESS
         */
        if (peer->status != PEER_SUCCESS)
            peer->status = PEER_ERROR;
        return;
1011 1012 1013 1014 1015 1016 1017 1018 1019
    }

    /*
     * 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) {
M
Matt Caswell 已提交
1020 1021 1022 1023
        /*
         * We're not actually expecting data - we're expecting a reneg to
         * start
         */
1024 1025 1026 1027
        peer->status = PEER_ERROR;
        return;
    } else {
        int error = SSL_get_error(peer->ssl, ret);
M
Matt Caswell 已提交
1028
        if (error != SSL_ERROR_WANT_READ) {
1029 1030 1031
            peer->status = PEER_ERROR;
            return;
        }
M
Matt Caswell 已提交
1032
        /* If we're not in init yet then we're not done with setup yet */
M
Matt Caswell 已提交
1033 1034
        if (!SSL_in_init(peer->ssl))
            return;
1035 1036 1037 1038 1039 1040
    }

    peer->status = PEER_SUCCESS;
}


1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055
/*
 * 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.
 */
1056
static void do_shutdown_step(PEER *peer)
E
Emilia Kasper 已提交
1057 1058 1059
{
    int ret;

P
Pauli 已提交
1060 1061 1062 1063
    if (!TEST_int_eq(peer->status, PEER_RETRY)) {
        peer->status = PEER_TEST_FAILURE;
        return;
    }
1064
    ret = SSL_shutdown(peer->ssl);
E
Emilia Kasper 已提交
1065 1066

    if (ret == 1) {
1067 1068 1069
        peer->status = PEER_SUCCESS;
    } else if (ret < 0) { /* On 0, we retry. */
        int error = SSL_get_error(peer->ssl, ret);
1070 1071

        if (error != SSL_ERROR_WANT_READ && error != SSL_ERROR_WANT_WRITE)
1072 1073 1074 1075 1076 1077
            peer->status = PEER_ERROR;
    }
}

typedef enum {
    HANDSHAKE,
1078 1079 1080
    RENEG_APPLICATION_DATA,
    RENEG_SETUP,
    RENEG_HANDSHAKE,
1081 1082 1083 1084 1085
    APPLICATION_DATA,
    SHUTDOWN,
    CONNECTION_DONE
} connect_phase_t;

1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108

static int renegotiate_op(const SSL_TEST_CTX *test_ctx)
{
    switch (test_ctx->handshake_mode) {
    case SSL_TEST_HANDSHAKE_RENEG_SERVER:
    case SSL_TEST_HANDSHAKE_RENEG_CLIENT:
        return 1;
    default:
        return 0;
    }
}
static int post_handshake_op(const SSL_TEST_CTX *test_ctx)
{
    switch (test_ctx->handshake_mode) {
    case SSL_TEST_HANDSHAKE_KEY_UPDATE_CLIENT:
    case SSL_TEST_HANDSHAKE_KEY_UPDATE_SERVER:
    case SSL_TEST_HANDSHAKE_POST_HANDSHAKE_AUTH:
        return 1;
    default:
        return 0;
    }
}

1109 1110
static connect_phase_t next_phase(const SSL_TEST_CTX *test_ctx,
                                  connect_phase_t phase)
1111 1112 1113
{
    switch (phase) {
    case HANDSHAKE:
1114
        if (renegotiate_op(test_ctx) || post_handshake_op(test_ctx))
1115 1116 1117 1118 1119
            return RENEG_APPLICATION_DATA;
        return APPLICATION_DATA;
    case RENEG_APPLICATION_DATA:
        return RENEG_SETUP;
    case RENEG_SETUP:
1120
        if (post_handshake_op(test_ctx))
M
Matt Caswell 已提交
1121
            return APPLICATION_DATA;
1122 1123
        return RENEG_HANDSHAKE;
    case RENEG_HANDSHAKE:
1124 1125 1126 1127 1128
        return APPLICATION_DATA;
    case APPLICATION_DATA:
        return SHUTDOWN;
    case SHUTDOWN:
        return CONNECTION_DONE;
R
Rich Salz 已提交
1129
    case CONNECTION_DONE:
P
Pauli 已提交
1130
        TEST_error("Trying to progress after connection done");
R
Rich Salz 已提交
1131
        break;
1132
    }
R
Rich Salz 已提交
1133
    return -1;
1134 1135
}

M
Matt Caswell 已提交
1136 1137
static void do_connect_step(const SSL_TEST_CTX *test_ctx, PEER *peer,
                            connect_phase_t phase)
1138 1139 1140 1141 1142
{
    switch (phase) {
    case HANDSHAKE:
        do_handshake_step(peer);
        break;
1143 1144 1145 1146
    case RENEG_APPLICATION_DATA:
        do_app_data_step(peer);
        break;
    case RENEG_SETUP:
M
Matt Caswell 已提交
1147
        do_reneg_setup_step(test_ctx, peer);
1148 1149 1150 1151
        break;
    case RENEG_HANDSHAKE:
        do_handshake_step(peer);
        break;
1152 1153 1154 1155 1156 1157
    case APPLICATION_DATA:
        do_app_data_step(peer);
        break;
    case SHUTDOWN:
        do_shutdown_step(peer);
        break;
R
Rich Salz 已提交
1158
    case CONNECTION_DONE:
P
Pauli 已提交
1159
        TEST_error("Action after connection done");
R
Rich Salz 已提交
1160
        break;
E
Emilia Kasper 已提交
1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187
    }
}

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) {
P
Pauli 已提交
1188 1189 1190
    case PEER_TEST_FAILURE:
        return INTERNAL_ERROR;

1191 1192 1193 1194
    case PEER_WAITING:
        /* Shouldn't ever happen */
        return INTERNAL_ERROR;

E
Emilia Kasper 已提交
1195 1196
    case PEER_SUCCESS:
        switch (previous_status) {
P
Pauli 已提交
1197 1198
        case PEER_TEST_FAILURE:
            return INTERNAL_ERROR;
E
Emilia Kasper 已提交
1199 1200 1201
        case PEER_SUCCESS:
            /* Both succeeded. */
            return HANDSHAKE_SUCCESS;
1202
        case PEER_WAITING:
E
Emilia Kasper 已提交
1203 1204 1205 1206 1207 1208 1209 1210 1211 1212
        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;
        }
1213
        break;
E
Emilia Kasper 已提交
1214 1215

    case PEER_RETRY:
1216 1217
        return HANDSHAKE_RETRY;

E
Emilia Kasper 已提交
1218 1219
    case PEER_ERROR:
        switch (previous_status) {
P
Pauli 已提交
1220 1221
        case PEER_TEST_FAILURE:
            return INTERNAL_ERROR;
1222 1223 1224
        case PEER_WAITING:
            /* The client failed immediately before sending the ClientHello */
            return client_spoke_last ? CLIENT_ERROR : INTERNAL_ERROR;
E
Emilia Kasper 已提交
1225 1226 1227 1228 1229 1230
        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.
1231
             * (No tests currently exercise this branch.)
E
Emilia Kasper 已提交
1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245
             */
            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;
}

1246 1247 1248
/* 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)
{
P
Pauli 已提交
1249
    char *ret = NULL;
1250

1251
    if (len == 0)
1252 1253 1254
        return NULL;

    /* Assert that the string does not contain NUL-bytes. */
P
Pauli 已提交
1255 1256
    if (TEST_size_t_eq(OPENSSL_strnlen((const char*)(in), len), len))
        TEST_ptr(ret = OPENSSL_strndup((const char*)(in), len));
1257 1258 1259
    return ret;
}

1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285
static int pkey_type(EVP_PKEY *pkey)
{
    int nid = EVP_PKEY_id(pkey);

#ifndef OPENSSL_NO_EC
    if (nid == EVP_PKEY_EC) {
        const EC_KEY *ec = EVP_PKEY_get0_EC_KEY(pkey);
        return EC_GROUP_get_curve_name(EC_KEY_get0_group(ec));
    }
#endif
    return nid;
}

static int peer_pkey_type(SSL *s)
{
    X509 *x = SSL_get_peer_certificate(s);

    if (x != NULL) {
        int nid = pkey_type(X509_get0_pubkey(x));

        X509_free(x);
        return nid;
    }
    return NID_undef;
}

1286 1287 1288
#if !defined(OPENSSL_NO_SCTP) && !defined(OPENSSL_NO_SOCK)
static int set_sock_as_sctp(int sock)
{
1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308
    struct sctp_assocparams assocparams;
    struct sctp_rtoinfo rto_info;
    BIO *tmpbio;

    /*
     * To allow tests to fail fast (within a second or so), reduce the
     * retransmission timeouts and the number of retransmissions.
     */
    memset(&rto_info, 0, sizeof(struct sctp_rtoinfo));
    rto_info.srto_initial = 100;
    rto_info.srto_max = 200;
    rto_info.srto_min = 50;
    (void)setsockopt(sock, IPPROTO_SCTP, SCTP_RTOINFO,
                     (const void *)&rto_info, sizeof(struct sctp_rtoinfo));
    memset(&assocparams, 0, sizeof(struct sctp_assocparams));
    assocparams.sasoc_asocmaxrxt = 2;
    (void)setsockopt(sock, IPPROTO_SCTP, SCTP_ASSOCINFO,
                     (const void *)&assocparams,
                     sizeof(struct sctp_assocparams));

1309 1310 1311 1312 1313 1314
    /*
     * For SCTP we have to set various options on the socket prior to
     * connecting. This is done automatically by BIO_new_dgram_sctp().
     * We don't actually need the created BIO though so we free it again
     * immediately.
     */
1315
    tmpbio = BIO_new_dgram_sctp(sock, BIO_NOCLOSE);
1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332

    if (tmpbio == NULL)
        return 0;
    BIO_free(tmpbio);

    return 1;
}

static int create_sctp_socks(int *ssock, int *csock)
{
    BIO_ADDRINFO *res = NULL;
    const BIO_ADDRINFO *ai = NULL;
    int lsock = INVALID_SOCKET, asock = INVALID_SOCKET;
    int consock = INVALID_SOCKET;
    int ret = 0;
    int family = 0;

1333
    if (BIO_sock_init() != 1)
1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406
        return 0;

    /*
     * Port is 4463. It could be anything. It will fail if it's already being
     * used for some other SCTP service. It seems unlikely though so we don't
     * worry about it here.
     */
    if (!BIO_lookup_ex(NULL, "4463", BIO_LOOKUP_SERVER, family, SOCK_STREAM,
                       IPPROTO_SCTP, &res))
        return 0;

    for (ai = res; ai != NULL; ai = BIO_ADDRINFO_next(ai)) {
        family = BIO_ADDRINFO_family(ai);
        lsock = BIO_socket(family, SOCK_STREAM, IPPROTO_SCTP, 0);
        if (lsock == INVALID_SOCKET) {
            /* Maybe the kernel doesn't support the socket family, even if
             * BIO_lookup() added it in the returned result...
             */
            continue;
        }

        if (!set_sock_as_sctp(lsock)
                || !BIO_listen(lsock, BIO_ADDRINFO_address(ai),
                               BIO_SOCK_REUSEADDR)) {
            BIO_closesocket(lsock);
            lsock = INVALID_SOCKET;
            continue;
        }

        /* Success, don't try any more addresses */
        break;
    }

    if (lsock == INVALID_SOCKET)
        goto err;

    BIO_ADDRINFO_free(res);
    res = NULL;

    if (!BIO_lookup_ex(NULL, "4463", BIO_LOOKUP_CLIENT, family, SOCK_STREAM,
                        IPPROTO_SCTP, &res))
        goto err;

    consock = BIO_socket(family, SOCK_STREAM, IPPROTO_SCTP, 0);
    if (consock == INVALID_SOCKET)
        goto err;

    if (!set_sock_as_sctp(consock)
            || !BIO_connect(consock, BIO_ADDRINFO_address(res), 0)
            || !BIO_socket_nbio(consock, 1))
        goto err;

    asock = BIO_accept_ex(lsock, NULL, BIO_SOCK_NONBLOCK);
    if (asock == INVALID_SOCKET)
        goto err;

    *csock = consock;
    *ssock = asock;
    consock = asock = INVALID_SOCKET;
    ret = 1;

 err:
    BIO_ADDRINFO_free(res);
    if (consock != INVALID_SOCKET)
        BIO_closesocket(consock);
    if (lsock != INVALID_SOCKET)
        BIO_closesocket(lsock);
    if (asock != INVALID_SOCKET)
        BIO_closesocket(asock);
    return ret;
}
#endif

E
Emilia Kasper 已提交
1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419
/*
 * 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.)
 */
1420 1421
static HANDSHAKE_RESULT *do_handshake_internal(
    SSL_CTX *server_ctx, SSL_CTX *server2_ctx, SSL_CTX *client_ctx,
E
Emilia Kasper 已提交
1422
    const SSL_TEST_CTX *test_ctx, const SSL_TEST_EXTRA_CONF *extra,
1423 1424
    SSL_SESSION *session_in, SSL_SESSION *serv_sess_in,
    SSL_SESSION **session_out, SSL_SESSION **serv_sess_out)
E
Emilia Kasper 已提交
1425
{
1426
    PEER server, client;
1427
    BIO *client_to_server = NULL, *server_to_client = NULL;
E
Emilia Kasper 已提交
1428
    HANDSHAKE_EX_DATA server_ex_data, client_ex_data;
1429 1430
    CTX_DATA client_ctx_data, server_ctx_data, server2_ctx_data;
    HANDSHAKE_RESULT *ret = HANDSHAKE_RESULT_new();
1431
    int client_turn = 1, client_turn_count = 0, client_wait_count = 0;
1432
    connect_phase_t phase = HANDSHAKE;
E
Emilia Kasper 已提交
1433
    handshake_status_t status = HANDSHAKE_RETRY;
1434
    const unsigned char* tick = NULL;
1435
    size_t tick_len = 0;
1436 1437
    const unsigned char* sess_id = NULL;
    unsigned int sess_id_len = 0;
T
Todd Short 已提交
1438
    SSL_SESSION* sess = NULL;
1439 1440 1441
    const unsigned char *proto = NULL;
    /* API dictates unsigned int rather than size_t. */
    unsigned int proto_len = 0;
D
Dr. Stephen Henson 已提交
1442
    EVP_PKEY *tmp_key;
D
Dr. Stephen Henson 已提交
1443
    const STACK_OF(X509_NAME) *names;
1444
    time_t start;
1445
    const char* cipher;
E
Emilia Kasper 已提交
1446

P
Pauli 已提交
1447 1448 1449
    if (ret == NULL)
        return NULL;

1450 1451 1452
    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));
1453 1454
    memset(&server, 0, sizeof(server));
    memset(&client, 0, sizeof(client));
P
Pauli 已提交
1455 1456
    memset(&server_ex_data, 0, sizeof(server_ex_data));
    memset(&client_ex_data, 0, sizeof(client_ex_data));
1457

P
Pauli 已提交
1458 1459 1460 1461 1462 1463
    if (!configure_handshake_ctx(server_ctx, server2_ctx, client_ctx,
                                 test_ctx, extra, &server_ctx_data,
                                 &server2_ctx_data, &client_ctx_data)) {
        TEST_note("configure_handshake_ctx");
        return NULL;
    }
1464

1465 1466 1467 1468 1469 1470 1471
#if !defined(OPENSSL_NO_SCTP) && !defined(OPENSSL_NO_SOCK)
    if (test_ctx->enable_client_sctp_label_bug)
        SSL_CTX_set_mode(client_ctx, SSL_MODE_DTLS_SCTP_LABEL_LENGTH_BUG);
    if (test_ctx->enable_server_sctp_label_bug)
        SSL_CTX_set_mode(server_ctx, SSL_MODE_DTLS_SCTP_LABEL_LENGTH_BUG);
#endif

1472
    /* Setup SSL and buffers; additional configuration happens below. */
P
Pauli 已提交
1473 1474 1475 1476 1477 1478 1479 1480
    if (!create_peer(&server, server_ctx)) {
        TEST_note("creating server context");
        goto err;
    }
    if (!create_peer(&client, client_ctx)) {
        TEST_note("creating client context");
        goto err;
    }
E
Emilia Kasper 已提交
1481

E
Emilia Kasper 已提交
1482 1483
    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;
1484 1485

    configure_handshake_ssl(server.ssl, client.ssl, extra);
1486
    if (session_in != NULL) {
1487
        SSL_SESSION_get_id(serv_sess_in, &sess_id_len);
1488
        /* In case we're testing resumption without tickets. */
1489 1490 1491
        if ((sess_id_len > 0
                    && !TEST_true(SSL_CTX_add_session(server_ctx,
                                                      serv_sess_in)))
P
Pauli 已提交
1492 1493
                || !TEST_true(SSL_set_session(client.ssl, session_in)))
            goto err;
1494
        sess_id_len = 0;
1495
    }
T
Todd Short 已提交
1496

1497
    ret->result = SSL_TEST_INTERNAL_ERROR;
E
Emilia Kasper 已提交
1498

1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511
    if (test_ctx->use_sctp) {
#if !defined(OPENSSL_NO_SCTP) && !defined(OPENSSL_NO_SOCK)
        int csock, ssock;

        if (create_sctp_socks(&ssock, &csock)) {
            client_to_server = BIO_new_dgram_sctp(csock, BIO_CLOSE);
            server_to_client = BIO_new_dgram_sctp(ssock, BIO_CLOSE);
        }
#endif
    } else {
        client_to_server = BIO_new(BIO_s_mem());
        server_to_client = BIO_new(BIO_s_mem());
    }
E
Emilia Kasper 已提交
1512

P
Pauli 已提交
1513 1514 1515
    if (!TEST_ptr(client_to_server)
            || !TEST_ptr(server_to_client))
        goto err;
E
Emilia Kasper 已提交
1516 1517 1518 1519 1520

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

1521 1522
    SSL_set_connect_state(client.ssl);
    SSL_set_accept_state(server.ssl);
E
Emilia Kasper 已提交
1523 1524

    /* The bios are now owned by the SSL object. */
1525 1526 1527 1528 1529
    if (test_ctx->use_sctp) {
        SSL_set_bio(client.ssl, client_to_server, client_to_server);
        SSL_set_bio(server.ssl, server_to_client, server_to_client);
    } else {
        SSL_set_bio(client.ssl, server_to_client, client_to_server);
P
Pauli 已提交
1530 1531 1532
        if (!TEST_int_gt(BIO_up_ref(server_to_client), 0)
                || !TEST_int_gt(BIO_up_ref(client_to_server), 0))
            goto err;
1533 1534
        SSL_set_bio(server.ssl, client_to_server, server_to_client);
    }
E
Emilia Kasper 已提交
1535 1536

    ex_data_idx = SSL_get_ex_new_index(0, "ex data", NULL, NULL, NULL);
P
Pauli 已提交
1537 1538 1539 1540
    if (!TEST_int_ge(ex_data_idx, 0)
            || !TEST_int_eq(SSL_set_ex_data(server.ssl, ex_data_idx, &server_ex_data), 1)
            || !TEST_int_eq(SSL_set_ex_data(client.ssl, ex_data_idx, &client_ex_data), 1))
        goto err;
1541 1542 1543

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

1545 1546 1547 1548
    client.status = PEER_RETRY;
    server.status = PEER_WAITING;

    start = time(NULL);
E
Emilia Kasper 已提交
1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559

    /*
     * 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) {
M
Matt Caswell 已提交
1560
            do_connect_step(test_ctx, &client, phase);
1561
            status = handshake_status(client.status, server.status,
E
Emilia Kasper 已提交
1562
                                      1 /* client went last */);
1563 1564
            if (server.status == PEER_WAITING)
                server.status = PEER_RETRY;
E
Emilia Kasper 已提交
1565
        } else {
M
Matt Caswell 已提交
1566
            do_connect_step(test_ctx, &server, phase);
1567
            status = handshake_status(server.status, client.status,
E
Emilia Kasper 已提交
1568 1569 1570 1571 1572
                                      0 /* server went last */);
        }

        switch (status) {
        case HANDSHAKE_SUCCESS:
1573
            client_turn_count = 0;
1574
            phase = next_phase(test_ctx, phase);
1575
            if (phase == CONNECTION_DONE) {
1576 1577 1578
                ret->result = SSL_TEST_SUCCESS;
                goto err;
            } else {
1579 1580 1581 1582 1583 1584 1585
                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.
                 */
1586 1587 1588
                client_turn = 1;
                break;
            }
E
Emilia Kasper 已提交
1589
        case CLIENT_ERROR:
1590
            ret->result = SSL_TEST_CLIENT_FAIL;
E
Emilia Kasper 已提交
1591 1592
            goto err;
        case SERVER_ERROR:
1593
            ret->result = SSL_TEST_SERVER_FAIL;
E
Emilia Kasper 已提交
1594 1595
            goto err;
        case INTERNAL_ERROR:
1596
            ret->result = SSL_TEST_INTERNAL_ERROR;
E
Emilia Kasper 已提交
1597 1598
            goto err;
        case HANDSHAKE_RETRY:
1599 1600 1601 1602 1603 1604 1605 1606
            if (test_ctx->use_sctp) {
                if (time(NULL) - start > 3) {
                    /*
                     * We've waited for too long. Give up.
                     */
                    ret->result = SSL_TEST_INTERNAL_ERROR;
                    goto err;
                }
1607
                /*
1608 1609 1610
                 * With "real" sockets we only swap to processing the peer
                 * if they are expecting to retry. Otherwise we just retry the
                 * same endpoint again.
1611
                 */
1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624
                if ((client_turn && server.status == PEER_RETRY)
                        || (!client_turn && client.status == PEER_RETRY))
                    client_turn ^= 1;
            } else {
                if (client_turn_count++ >= 2000) {
                    /*
                     * At this point, there's been so many PEER_RETRY in a row
                     * that it's likely both sides are stuck waiting for a read.
                     * It's time to give up.
                     */
                    ret->result = SSL_TEST_INTERNAL_ERROR;
                    goto err;
                }
1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637
                if (client_turn && server.status == PEER_SUCCESS) {
                    /*
                     * The server may finish before the client because the
                     * client spends some turns processing NewSessionTickets.
                     */
                    if (client_wait_count++ >= 2) {
                        ret->result = SSL_TEST_INTERNAL_ERROR;
                        goto err;
                    }
                } else {
                    /* Continue. */
                    client_turn ^= 1;
                }
1638
            }
E
Emilia Kasper 已提交
1639 1640 1641 1642
            break;
        }
    }
 err:
1643
    ret->server_alert_sent = server_ex_data.alert_sent;
1644
    ret->server_num_fatal_alerts_sent = server_ex_data.num_fatal_alerts_sent;
1645 1646
    ret->server_alert_received = client_ex_data.alert_received;
    ret->client_alert_sent = client_ex_data.alert_sent;
1647
    ret->client_num_fatal_alerts_sent = client_ex_data.num_fatal_alerts_sent;
1648
    ret->client_alert_received = server_ex_data.alert_received;
1649 1650
    ret->server_protocol = SSL_version(server.ssl);
    ret->client_protocol = SSL_version(client.ssl);
1651
    ret->servername = server_ex_data.servername;
1652
    if ((sess = SSL_get0_session(client.ssl)) != NULL) {
1653
        SSL_SESSION_get0_ticket(sess, &tick, &tick_len);
1654 1655
        sess_id = SSL_SESSION_get_id(sess, &sess_id_len);
    }
1656 1657
    if (tick == NULL || tick_len == 0)
        ret->session_ticket = SSL_TEST_SESSION_TICKET_NO;
T
Todd Short 已提交
1658
    else
1659
        ret->session_ticket = SSL_TEST_SESSION_TICKET_YES;
M
Matt Caswell 已提交
1660 1661 1662
    ret->compression = (SSL_get_current_compression(client.ssl) == NULL)
                       ? SSL_TEST_COMPRESSION_NO
                       : SSL_TEST_COMPRESSION_YES;
1663 1664 1665 1666
    if (sess_id == NULL || sess_id_len == 0)
        ret->session_id = SSL_TEST_SESSION_ID_NO;
    else
        ret->session_id = SSL_TEST_SESSION_ID_YES;
1667 1668
    ret->session_ticket_do_not_call = server_ex_data.session_ticket_do_not_call;

B
Ben Laurie 已提交
1669
#ifndef OPENSSL_NO_NEXTPROTONEG
1670
    SSL_get0_next_proto_negotiated(client.ssl, &proto, &proto_len);
1671 1672
    ret->client_npn_negotiated = dup_str(proto, proto_len);

1673
    SSL_get0_next_proto_negotiated(server.ssl, &proto, &proto_len);
1674
    ret->server_npn_negotiated = dup_str(proto, proto_len);
E
Emilia Kasper 已提交
1675
#endif
1676

1677
    SSL_get0_alpn_selected(client.ssl, &proto, &proto_len);
1678 1679
    ret->client_alpn_negotiated = dup_str(proto, proto_len);

1680
    SSL_get0_alpn_selected(server.ssl, &proto, &proto_len);
1681
    ret->server_alpn_negotiated = dup_str(proto, proto_len);
E
Emilia Kasper 已提交
1682

T
Todd Short 已提交
1683 1684 1685 1686 1687
    if ((sess = SSL_get0_session(server.ssl)) != NULL) {
        SSL_SESSION_get0_ticket_appdata(sess, (void**)&tick, &tick_len);
        ret->result_session_ticket_app_data = OPENSSL_strndup((const char*)tick, tick_len);
    }

1688 1689
    ret->client_resumed = SSL_session_reused(client.ssl);
    ret->server_resumed = SSL_session_reused(server.ssl);
1690

1691 1692 1693
    cipher = SSL_CIPHER_get_name(SSL_get_current_cipher(client.ssl));
    ret->cipher = dup_str((const unsigned char*)cipher, strlen(cipher));

1694
    if (session_out != NULL)
1695
        *session_out = SSL_get1_session(client.ssl);
1696 1697 1698 1699 1700 1701 1702 1703 1704 1705
    if (serv_sess_out != NULL) {
        SSL_SESSION *tmp = SSL_get_session(server.ssl);

        /*
         * We create a fresh copy that is not in the server session ctx linked
         * list.
         */
        if (tmp != NULL)
            *serv_sess_out = SSL_SESSION_dup(tmp);
    }
1706

1707
    if (SSL_get_peer_tmp_key(client.ssl, &tmp_key)) {
1708
        ret->tmp_key_type = pkey_type(tmp_key);
D
Dr. Stephen Henson 已提交
1709 1710 1711
        EVP_PKEY_free(tmp_key);
    }

1712 1713 1714
    SSL_get_peer_signature_nid(client.ssl, &ret->server_sign_hash);
    SSL_get_peer_signature_nid(server.ssl, &ret->client_sign_hash);

1715 1716 1717
    SSL_get_peer_signature_type_nid(client.ssl, &ret->server_sign_type);
    SSL_get_peer_signature_type_nid(server.ssl, &ret->client_sign_type);

D
Dr. Stephen Henson 已提交
1718
    names = SSL_get0_peer_CA_list(client.ssl);
D
Dr. Stephen Henson 已提交
1719 1720 1721 1722 1723
    if (names == NULL)
        ret->client_ca_names = NULL;
    else
        ret->client_ca_names = SSL_dup_CA_list(names);

D
Dr. Stephen Henson 已提交
1724 1725 1726 1727 1728 1729
    names = SSL_get0_peer_CA_list(server.ssl);
    if (names == NULL)
        ret->server_ca_names = NULL;
    else
        ret->server_ca_names = SSL_dup_CA_list(names);

1730 1731 1732
    ret->server_cert_type = peer_pkey_type(client.ssl);
    ret->client_cert_type = peer_pkey_type(server.ssl);

1733 1734 1735
    ctx_data_free_data(&server_ctx_data);
    ctx_data_free_data(&server2_ctx_data);
    ctx_data_free_data(&client_ctx_data);
1736

1737 1738
    peer_free_data(&server);
    peer_free_data(&client);
E
Emilia Kasper 已提交
1739 1740
    return ret;
}
1741 1742 1743

HANDSHAKE_RESULT *do_handshake(SSL_CTX *server_ctx, SSL_CTX *server2_ctx,
                               SSL_CTX *client_ctx, SSL_CTX *resume_server_ctx,
E
Emilia Kasper 已提交
1744
                               SSL_CTX *resume_client_ctx,
1745 1746 1747
                               const SSL_TEST_CTX *test_ctx)
{
    HANDSHAKE_RESULT *result;
1748
    SSL_SESSION *session = NULL, *serv_sess = NULL;
1749 1750

    result = do_handshake_internal(server_ctx, server2_ctx, client_ctx,
E
Emilia Kasper 已提交
1751
                                   test_ctx, &test_ctx->extra,
1752
                                   NULL, NULL, &session, &serv_sess);
P
Pauli 已提交
1753 1754 1755
    if (result == NULL
            || test_ctx->handshake_mode != SSL_TEST_HANDSHAKE_RESUME
            || result->result == SSL_TEST_INTERNAL_ERROR)
1756 1757 1758 1759
        goto end;

    if (result->result != SSL_TEST_SUCCESS) {
        result->result = SSL_TEST_FIRST_HANDSHAKE_FAILED;
1760
        goto end;
1761 1762 1763 1764
    }

    HANDSHAKE_RESULT_free(result);
    /* We don't support SNI on second handshake yet, so server2_ctx is NULL. */
E
Emilia Kasper 已提交
1765
    result = do_handshake_internal(resume_server_ctx, NULL, resume_client_ctx,
E
Emilia Kasper 已提交
1766
                                   test_ctx, &test_ctx->resume_extra,
1767
                                   session, serv_sess, NULL, NULL);
1768 1769
 end:
    SSL_SESSION_free(session);
1770
    SSL_SESSION_free(serv_sess);
1771 1772
    return result;
}