From 2afaee5193c3f567ea00ad613f3ee82f985b7141 Mon Sep 17 00:00:00 2001 From: Benjamin Kaduk Date: Mon, 13 Feb 2017 12:42:43 -0600 Subject: [PATCH] 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 Reviewed-by: Richard Levitte (Merged from https://github.com/openssl/openssl/pull/2279) --- test/sslapitest.c | 84 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) diff --git a/test/sslapitest.c b/test/sslapitest.c index cc852952e7..f492e0bae4 100644 --- a/test/sslapitest.c +++ b/test/sslapitest.c @@ -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]);