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: Matt Caswell <matt@openssl.org>
Reviewed-by: Richard Levitte <levitte@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/2279)
This commit is contained in:
Benjamin Kaduk 2017-02-13 12:42:43 -06:00 committed by Richard Levitte
parent 8e2236eff8
commit 2afaee5193

View file

@ -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]);