Commit 5a421415 authored by Matt Caswell's avatar Matt Caswell
Browse files

Add a test for the new early data callback

parent dc7a3543
Loading
Loading
Loading
Loading
+98 −14
Original line number Diff line number Diff line
@@ -1847,11 +1847,14 @@ static unsigned int psk_server_cb(SSL *ssl, const char *identity,
static int setupearly_data_test(SSL_CTX **cctx, SSL_CTX **sctx, SSL **clientssl,
                                SSL **serverssl, SSL_SESSION **sess, int idx)
{
    if (!TEST_true(create_ssl_ctx_pair(TLS_server_method(), TLS_client_method(),
    if (*sctx == NULL
            && !TEST_true(create_ssl_ctx_pair(TLS_server_method(),
                                              TLS_client_method(),
                                              TLS1_VERSION, TLS_MAX_VERSION,
                                       sctx, cctx, cert, privkey))
        || !TEST_true(SSL_CTX_set_max_early_data(*sctx,
                                                 SSL3_RT_MAX_PLAIN_LENGTH)))
                                              sctx, cctx, cert, privkey)))
        return 0;

    if (!TEST_true(SSL_CTX_set_max_early_data(*sctx, SSL3_RT_MAX_PLAIN_LENGTH)))
        return 0;

    if (idx == 1) {
@@ -2156,12 +2159,47 @@ static int test_early_data_read_write(int idx)
    return testresult;
}

static int test_early_data_replay(int idx)
static int allow_ed_cb_called = 0;

static int allow_early_data_cb(SSL *s, void *arg)
{
    int *usecb = (int *)arg;

    allow_ed_cb_called++;

    if (*usecb == 1)
        return 0;

    return 1;
}

/*
 * idx == 0: Standard early_data setup
 * idx == 1: early_data setup using read_ahead
 * usecb == 0: Don't use a custom early data callback
 * usecb == 1: Use a custom early data callback and reject the early data
 * usecb == 2: Use a custom early data callback and accept the early data
 */
static int test_early_data_replay_int(int idx, int usecb)
{
    SSL_CTX *cctx = NULL, *sctx = NULL;
    SSL *clientssl = NULL, *serverssl = NULL;
    int testresult = 0;
    SSL_SESSION *sess = NULL;
    size_t readbytes, written;
    unsigned char buf[20];

    allow_ed_cb_called = 0;

    if (!TEST_true(create_ssl_ctx_pair(TLS_server_method(), TLS_client_method(),
                                       TLS1_VERSION, TLS_MAX_VERSION, &sctx,
                                       &cctx, cert, privkey)))
        return 0;

    if (usecb > 0) {
        SSL_CTX_set_options(sctx, SSL_OP_NO_ANTI_REPLAY);
        SSL_CTX_set_allow_early_data_cb(sctx, allow_early_data_cb, &usecb);
    }

    if (!TEST_true(setupearly_data_test(&cctx, &sctx, &clientssl,
                                        &serverssl, &sess, idx)))
@@ -2183,14 +2221,49 @@ static int test_early_data_replay(int idx)

    if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl,
                                      &clientssl, NULL, NULL))
            || !TEST_true(SSL_set_session(clientssl, sess))
            || !TEST_true(create_ssl_connection(serverssl, clientssl,
                          SSL_ERROR_NONE))
            || !TEST_true(SSL_set_session(clientssl, sess)))
        goto end;

    /* Write and read some early data */
    if (!TEST_true(SSL_write_early_data(clientssl, MSG1, strlen(MSG1),
                                        &written))
            || !TEST_size_t_eq(written, strlen(MSG1)))
        goto end;

    if (usecb <= 1) {
        if (!TEST_int_eq(SSL_read_early_data(serverssl, buf, sizeof(buf),
                                             &readbytes),
                         SSL_READ_EARLY_DATA_FINISH)
                   /*
                * This time we should not have resumed the session because we
                * already used it once.
                    * The ticket was reused, so the we should have rejected the
                    * early data
                    */
            || !TEST_false(SSL_session_reused(clientssl)))
                || !TEST_int_eq(SSL_get_early_data_status(serverssl),
                                SSL_EARLY_DATA_REJECTED))
            goto end;
    } else {
        /* In this case the callback decides to accept the early data */
        if (!TEST_int_eq(SSL_read_early_data(serverssl, buf, sizeof(buf),
                                             &readbytes),
                         SSL_READ_EARLY_DATA_SUCCESS)
                || !TEST_mem_eq(MSG1, strlen(MSG1), buf, readbytes)
                   /*
                    * Server will have sent its flight so client can now send
                    * end of early data and complete its half of the handshake
                    */
                || !TEST_int_gt(SSL_connect(clientssl), 0)
                || !TEST_int_eq(SSL_read_early_data(serverssl, buf, sizeof(buf),
                                             &readbytes),
                                SSL_READ_EARLY_DATA_FINISH)
                || !TEST_int_eq(SSL_get_early_data_status(serverssl),
                                SSL_EARLY_DATA_ACCEPTED))
            goto end;
    }

    /* Complete the connection */
    if (!TEST_true(create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE))
            || !TEST_int_eq(SSL_session_reused(clientssl), (usecb > 0) ? 1 : 0)
            || !TEST_int_eq(allow_ed_cb_called, usecb > 0 ? 1 : 0))
        goto end;

    testresult = 1;
@@ -2207,6 +2280,17 @@ static int test_early_data_replay(int idx)
    return testresult;
}

static int test_early_data_replay(int idx)
{
    int ret;

    ret = test_early_data_replay_int(idx, 0);
    ret &= test_early_data_replay_int(idx, 1);
    ret &= test_early_data_replay_int(idx, 2);

    return ret;
}

/*
 * Helper function to test that a server attempting to read early data can
 * handle a connection from a client where the early data should be skipped.