Commit 2afaee51 authored by Benjamin Kaduk's avatar Benjamin Kaduk Committed by Richard Levitte
Browse files

Add an sslapitest for early callback



Make sure that we can stop handshake processing and resume it later.
Also check that the cipher list and compression methods are sane.
Unfortunately, we don't have the client-side APIs needed to force
a specific (known) session ID to be sent in the ClientHello, so
that accessor cannot be tested here.

Reviewed-by: default avatarMatt Caswell <matt@openssl.org>
Reviewed-by: default avatarRichard Levitte <levitte@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/2279)
parent 8e2236ef
Loading
Loading
Loading
Loading
+84 −0
Original line number Diff line number Diff line
@@ -477,6 +477,89 @@ end:
}
#endif

static int full_early_callback(SSL *s, int *al, void *arg)
{
    int *ctr = arg;
    const unsigned char *p;
    /* We only configure two ciphers, but the SCSV is added automatically. */
#ifdef OPENSSL_NO_EC
    const unsigned char expected_ciphers[] = {0x00, 0x9d, 0x00, 0xff};
#else
    const unsigned char expected_ciphers[] = {0x00, 0x9d, 0xc0,
                                              0x2c, 0x00, 0xff};
#endif
    size_t len;

    /* Make sure we can defer processing and get called back. */
    if ((*ctr)++ == 0)
        return -1;

    len = SSL_early_get0_ciphers(s, &p);
    if (len != sizeof(expected_ciphers) ||
        memcmp(p, expected_ciphers, len) != 0) {
        printf("Early callback expected ciphers mismatch\n");
        return 0;
    }
    len = SSL_early_get0_compression_methods(s, &p);
    if (len != 1 || *p != 0) {
        printf("Early callback expected comperssion methods mismatch\n");
        return 0;
    }
    return 1;
}

static int test_early_cb(void) {
    SSL_CTX *cctx = NULL, *sctx = NULL;
    SSL *clientssl = NULL, *serverssl = NULL;
    int testctr = 0, testresult = 0;

    if (!create_ssl_ctx_pair(TLS_server_method(), TLS_client_method(), &sctx,
                             &cctx, cert, privkey)) {
        printf("Unable to create SSL_CTX pair\n");
        goto end;
    }

    SSL_CTX_set_early_cb(sctx, full_early_callback, &testctr);
    /* The gimpy cipher list we configure can't do TLS 1.3. */
    SSL_CTX_set_max_proto_version(cctx, TLS1_2_VERSION);
    if (!SSL_CTX_set_cipher_list(cctx,
            "AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384")) {
        printf("Failed to set cipher list\n");
        goto end;
    }

    if (!create_ssl_objects(sctx, cctx, &serverssl, &clientssl, NULL, NULL)) {
        printf("Unable to create SSL objects\n");
        goto end;
    }

    if (create_ssl_connection(serverssl, clientssl, SSL_ERROR_WANT_EARLY)) {
        printf("Creating SSL connection succeeded with async early return\n");
        goto end;
    }

    /* Passing a -1 literal is a hack since the real value was lost. */
    if (SSL_get_error(serverssl, -1) != SSL_ERROR_WANT_EARLY) {
        printf("Early callback failed to make state SSL_ERROR_WANT_EARLY\n");
        goto end;
    }

    if (!create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE)) {
        printf("Restarting SSL connection failed\n");
        goto end;
    }

    testresult = 1;

end:
    SSL_free(serverssl);
    SSL_free(clientssl);
    SSL_CTX_free(sctx);
    SSL_CTX_free(cctx);

    return testresult;
}

static int execute_test_large_message(const SSL_METHOD *smeth,
                                      const SSL_METHOD *cmeth, int read_ahead)
{
@@ -1485,6 +1568,7 @@ int test_main(int argc, char *argv[])
#ifndef OPENSSL_NO_TLS1_3
    ADD_TEST(test_keylog_no_master_key);
#endif
    ADD_TEST(test_early_cb);

    testresult = run_tests(argv[0]);