X-Git-Url: https://git.openssl.org/?p=openssl.git;a=blobdiff_plain;f=test%2Fsslapitest.c;h=06d6cb2b68d56f3a1f6ac74605f91311c7da7d85;hp=a71a1a90743eb88c88d2b8690339c3af97f88df0;hb=ba8b48e98dd86851ca20733f819da5b76859e64a;hpb=cffe973c45491b14d980e3b578da28e4a79a8705 diff --git a/test/sslapitest.c b/test/sslapitest.c index a71a1a9074..06d6cb2b68 100644 --- a/test/sslapitest.c +++ b/test/sslapitest.c @@ -16,6 +16,7 @@ #include #include #include +#include #include "ssltestlib.h" #include "testutil.h" @@ -59,6 +60,7 @@ struct sslapitest_log_counts { unsigned int server_handshake_secret_count; unsigned int client_application_secret_count; unsigned int server_application_secret_count; + unsigned int early_exporter_secret_count; unsigned int exporter_secret_count; }; @@ -146,6 +148,7 @@ static int test_keylog_output(char *buffer, const SSL *ssl, unsigned int server_handshake_secret_count = 0; unsigned int client_application_secret_count = 0; unsigned int server_application_secret_count = 0; + unsigned int early_exporter_secret_count = 0; unsigned int exporter_secret_count = 0; for (token = strtok(buffer, " \n"); token != NULL; @@ -205,6 +208,7 @@ static int test_keylog_output(char *buffer, const SSL *ssl, || strcmp(token, "SERVER_HANDSHAKE_TRAFFIC_SECRET") == 0 || strcmp(token, "CLIENT_TRAFFIC_SECRET_0") == 0 || strcmp(token, "SERVER_TRAFFIC_SECRET_0") == 0 + || strcmp(token, "EARLY_EXPORTER_SECRET") == 0 || strcmp(token, "EXPORTER_SECRET") == 0) { /* * TLSv1.3 secret. Tokens should be: 64 ASCII bytes of hex-encoded @@ -222,6 +226,8 @@ static int test_keylog_output(char *buffer, const SSL *ssl, client_application_secret_count++; else if (strcmp(token, "SERVER_TRAFFIC_SECRET_0") == 0) server_application_secret_count++; + else if (strcmp(token, "EARLY_EXPORTER_SECRET") == 0) + early_exporter_secret_count++; else if (strcmp(token, "EXPORTER_SECRET") == 0) exporter_secret_count++; @@ -267,6 +273,8 @@ static int test_keylog_output(char *buffer, const SSL *ssl, expected->client_application_secret_count) || !TEST_size_t_eq(server_application_secret_count, expected->server_application_secret_count) + || !TEST_size_t_eq(early_exporter_secret_count, + expected->early_exporter_secret_count) || !TEST_size_t_eq(exporter_secret_count, expected->exporter_secret_count)) return 0; @@ -375,8 +383,6 @@ static int test_keylog_no_master_key(void) TLS1_VERSION, TLS_MAX_VERSION, &sctx, &cctx, cert, privkey)) || !TEST_true(SSL_CTX_set_max_early_data(sctx, - SSL3_RT_MAX_PLAIN_LENGTH)) - || !TEST_true(SSL_CTX_set_max_early_data(cctx, SSL3_RT_MAX_PLAIN_LENGTH))) return 0; @@ -450,6 +456,7 @@ static int test_keylog_no_master_key(void) /* In addition to the previous entries, expect early secrets. */ expected.client_early_secret_count = 1; + expected.early_exporter_secret_count = 1; if (!TEST_true(test_keylog_output(client_log_buffer, clientssl, SSL_get_session(clientssl), &expected)) || !TEST_true(test_keylog_output(server_log_buffer, serverssl, @@ -1698,8 +1705,6 @@ static int setupearly_data_test(SSL_CTX **cctx, SSL_CTX **sctx, SSL **clientssl, TLS1_VERSION, TLS_MAX_VERSION, sctx, cctx, cert, privkey)) || !TEST_true(SSL_CTX_set_max_early_data(*sctx, - SSL3_RT_MAX_PLAIN_LENGTH)) - || !TEST_true(SSL_CTX_set_max_early_data(*cctx, SSL3_RT_MAX_PLAIN_LENGTH))) return 0; @@ -1764,8 +1769,15 @@ static int setupearly_data_test(SSL_CTX **cctx, SSL_CTX **sctx, SSL **clientssl, } serverpsk = clientpsk; - if (sess != NULL) + if (sess != NULL) { + if (!TEST_true(SSL_SESSION_up_ref(clientpsk))) { + SSL_SESSION_free(clientpsk); + SSL_SESSION_free(serverpsk); + clientpsk = serverpsk = NULL; + return 0; + } *sess = clientpsk; + } return 1; } @@ -1934,9 +1946,7 @@ static int test_early_data_read_write(int idx) || !TEST_mem_eq(buf, readbytes, MSG7, strlen(MSG7))) goto end; - /* We keep the PSK session around if using PSK */ - if (idx != 2) - SSL_SESSION_free(sess); + SSL_SESSION_free(sess); sess = SSL_get1_session(clientssl); use_session_cb_cnt = 0; find_session_cb_cnt = 0; @@ -1986,8 +1996,7 @@ static int test_early_data_read_write(int idx) testresult = 1; end: - if (sess != clientpsk) - SSL_SESSION_free(sess); + SSL_SESSION_free(sess); SSL_SESSION_free(clientpsk); SSL_SESSION_free(serverpsk); clientpsk = serverpsk = NULL; @@ -2038,8 +2047,7 @@ static int test_early_data_replay(int idx) testresult = 1; end: - if (sess != clientpsk) - SSL_SESSION_free(sess); + SSL_SESSION_free(sess); SSL_SESSION_free(clientpsk); SSL_SESSION_free(serverpsk); clientpsk = serverpsk = NULL; @@ -2126,8 +2134,7 @@ static int early_data_skip_helper(int hrr, int idx) testresult = 1; end: - if (sess != clientpsk) - SSL_SESSION_free(clientpsk); + SSL_SESSION_free(clientpsk); SSL_SESSION_free(serverpsk); clientpsk = serverpsk = NULL; SSL_SESSION_free(sess); @@ -2200,9 +2207,9 @@ static int test_early_data_not_sent(int idx) /* * Should block due to the NewSessionTicket arrival unless we're using - * read_ahead + * read_ahead, or PSKs */ - if (idx != 1) { + if (idx != 1 && idx != 2) { if (!TEST_false(SSL_read_ex(clientssl, buf, sizeof(buf), &readbytes))) goto end; } @@ -2214,8 +2221,8 @@ static int test_early_data_not_sent(int idx) testresult = 1; end: - /* If using PSK then clientpsk and sess are the same */ SSL_SESSION_free(sess); + SSL_SESSION_free(clientpsk); SSL_SESSION_free(serverpsk); clientpsk = serverpsk = NULL; SSL_free(serverssl); @@ -2423,6 +2430,7 @@ static int test_early_data_psk(int idx) testresult = 1; end: + SSL_SESSION_free(sess); SSL_SESSION_free(clientpsk); SSL_SESSION_free(serverpsk); clientpsk = serverpsk = NULL; @@ -2480,8 +2488,8 @@ static int test_early_data_not_expected(int idx) testresult = 1; end: - /* If using PSK then clientpsk and sess are the same */ SSL_SESSION_free(sess); + SSL_SESSION_free(clientpsk); SSL_SESSION_free(serverpsk); clientpsk = serverpsk = NULL; SSL_free(serverssl); @@ -2554,7 +2562,6 @@ static int test_early_data_tls1_2(int idx) testresult = 1; end: - /* If using PSK then clientpsk and sess are the same */ SSL_SESSION_free(clientpsk); SSL_SESSION_free(serverpsk); clientpsk = serverpsk = NULL; @@ -2777,6 +2784,13 @@ static int test_ciphersuite_change(void) return testresult; } +/* + * Test TLSv1.3 PSKs + * Test 0 = Test new style callbacks + * Test 1 = Test both new and old style callbacks + * Test 2 = Test old style callbacks + * Test 3 = Test old style callbacks with no certificate + */ static int test_tls13_psk(int idx) { SSL_CTX *sctx = NULL, *cctx = NULL; @@ -2792,15 +2806,21 @@ static int test_tls13_psk(int idx) if (!TEST_true(create_ssl_ctx_pair(TLS_server_method(), TLS_client_method(), TLS1_VERSION, TLS_MAX_VERSION, - &sctx, &cctx, cert, privkey))) + &sctx, &cctx, idx == 3 ? NULL : cert, + idx == 3 ? NULL : privkey))) goto end; - /* - * We use a ciphersuite with SHA256 to ease testing old style PSK callbacks - * which will always default to SHA256 - */ - if (!TEST_true(SSL_CTX_set_ciphersuites(cctx, "TLS_AES_128_GCM_SHA256"))) - goto end; + if (idx != 3) { + /* + * We use a ciphersuite with SHA256 to ease testing old style PSK + * callbacks which will always default to SHA256. This should not be + * necessary if we have no cert/priv key. In that case the server should + * prefer SHA256 automatically. + */ + if (!TEST_true(SSL_CTX_set_ciphersuites(cctx, + "TLS_AES_128_GCM_SHA256"))) + goto end; + } /* * Test 0: New style callbacks only @@ -2812,7 +2832,7 @@ static int test_tls13_psk(int idx) SSL_CTX_set_psk_find_session_callback(sctx, find_session_cb); } #ifndef OPENSSL_NO_PSK - if (idx == 1 || idx == 2) { + if (idx >= 1) { SSL_CTX_set_psk_client_callback(cctx, psk_client_cb); SSL_CTX_set_psk_server_callback(sctx, psk_server_cb); } @@ -2823,36 +2843,41 @@ static int test_tls13_psk(int idx) psk_client_cb_cnt = 0; psk_server_cb_cnt = 0; - /* Check we can create a connection if callback decides not to send a PSK */ - if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl, - NULL, NULL)) - || !TEST_true(create_ssl_connection(serverssl, clientssl, - SSL_ERROR_NONE)) - || !TEST_false(SSL_session_reused(clientssl)) - || !TEST_false(SSL_session_reused(serverssl))) - goto end; - - if (idx == 0 || idx == 1) { - if (!TEST_true(use_session_cb_cnt == 1) - || !TEST_true(find_session_cb_cnt == 0) - /* - * If no old style callback then below should be 0 - * otherwise 1 - */ - || !TEST_true(psk_client_cb_cnt == idx) - || !TEST_true(psk_server_cb_cnt == 0)) - goto end; - } else { - if (!TEST_true(use_session_cb_cnt == 0) - || !TEST_true(find_session_cb_cnt == 0) - || !TEST_true(psk_client_cb_cnt == 1) - || !TEST_true(psk_server_cb_cnt == 0)) + if (idx != 3) { + /* + * Check we can create a connection if callback decides not to send a + * PSK + */ + if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl, + NULL, NULL)) + || !TEST_true(create_ssl_connection(serverssl, clientssl, + SSL_ERROR_NONE)) + || !TEST_false(SSL_session_reused(clientssl)) + || !TEST_false(SSL_session_reused(serverssl))) goto end; - } - shutdown_ssl_connection(serverssl, clientssl); - serverssl = clientssl = NULL; - use_session_cb_cnt = psk_client_cb_cnt = 0; + if (idx == 0 || idx == 1) { + if (!TEST_true(use_session_cb_cnt == 1) + || !TEST_true(find_session_cb_cnt == 0) + /* + * If no old style callback then below should be 0 + * otherwise 1 + */ + || !TEST_true(psk_client_cb_cnt == idx) + || !TEST_true(psk_server_cb_cnt == 0)) + goto end; + } else { + if (!TEST_true(use_session_cb_cnt == 0) + || !TEST_true(find_session_cb_cnt == 0) + || !TEST_true(psk_client_cb_cnt == 1) + || !TEST_true(psk_server_cb_cnt == 0)) + goto end; + } + + shutdown_ssl_connection(serverssl, clientssl); + serverssl = clientssl = NULL; + use_session_cb_cnt = psk_client_cb_cnt = 0; + } if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl, NULL, NULL))) @@ -2933,39 +2958,41 @@ static int test_tls13_psk(int idx) use_session_cb_cnt = find_session_cb_cnt = 0; psk_client_cb_cnt = psk_server_cb_cnt = 0; - /* - * Check that if the server rejects the PSK we can still connect, but with - * a full handshake - */ - srvid = "Dummy Identity"; - if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl, - NULL, NULL)) - || !TEST_true(create_ssl_connection(serverssl, clientssl, - SSL_ERROR_NONE)) - || !TEST_false(SSL_session_reused(clientssl)) - || !TEST_false(SSL_session_reused(serverssl))) - goto end; - - if (idx == 0 || idx == 1) { - if (!TEST_true(use_session_cb_cnt == 1) - || !TEST_true(find_session_cb_cnt == 1) - || !TEST_true(psk_client_cb_cnt == 0) - /* - * If no old style callback then below should be 0 - * otherwise 1 - */ - || !TEST_true(psk_server_cb_cnt == idx)) - goto end; - } else { - if (!TEST_true(use_session_cb_cnt == 0) - || !TEST_true(find_session_cb_cnt == 0) - || !TEST_true(psk_client_cb_cnt == 1) - || !TEST_true(psk_server_cb_cnt == 1)) + if (idx != 3) { + /* + * Check that if the server rejects the PSK we can still connect, but with + * a full handshake + */ + srvid = "Dummy Identity"; + if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl, + NULL, NULL)) + || !TEST_true(create_ssl_connection(serverssl, clientssl, + SSL_ERROR_NONE)) + || !TEST_false(SSL_session_reused(clientssl)) + || !TEST_false(SSL_session_reused(serverssl))) goto end; - } - shutdown_ssl_connection(serverssl, clientssl); - serverssl = clientssl = NULL; + if (idx == 0 || idx == 1) { + if (!TEST_true(use_session_cb_cnt == 1) + || !TEST_true(find_session_cb_cnt == 1) + || !TEST_true(psk_client_cb_cnt == 0) + /* + * If no old style callback then below should be 0 + * otherwise 1 + */ + || !TEST_true(psk_server_cb_cnt == idx)) + goto end; + } else { + if (!TEST_true(use_session_cb_cnt == 0) + || !TEST_true(find_session_cb_cnt == 0) + || !TEST_true(psk_client_cb_cnt == 1) + || !TEST_true(psk_server_cb_cnt == 1)) + goto end; + } + + shutdown_ssl_connection(serverssl, clientssl); + serverssl = clientssl = NULL; + } testresult = 1; end: @@ -3680,8 +3707,7 @@ static int test_export_key_mat_early(int idx) testresult = 1; end: - if (sess != clientpsk) - SSL_SESSION_free(sess); + SSL_SESSION_free(sess); SSL_SESSION_free(clientpsk); SSL_SESSION_free(serverpsk); clientpsk = serverpsk = NULL; @@ -4265,6 +4291,12 @@ static void sslapi_info_callback(const SSL *s, int where, int ret) info_cb_failed = 1; return; } + + /* Check that, if we've got SSL_CB_HANDSHAKE_DONE we are not in init */ + if ((where & SSL_CB_HANDSHAKE_DONE) && SSL_in_init((SSL *)s) != 0) { + info_cb_failed = 1; + return; + } } /* @@ -4304,6 +4336,7 @@ static int test_info_callback(int tst) info_cb_this_state = -1; info_cb_offset = tst; +#ifndef OPENSSL_NO_TLS1_3 if (tst >= 4) { SSL_SESSION *sess = NULL; size_t written, readbytes; @@ -4338,6 +4371,7 @@ static int test_info_callback(int tst) testresult = 1; goto end; } +#endif if (!TEST_true(create_ssl_ctx_pair(TLS_server_method(), TLS_client_method(), @@ -4389,6 +4423,404 @@ static int test_info_callback(int tst) return testresult; } +static int test_ssl_pending(int tst) +{ + SSL_CTX *cctx = NULL, *sctx = NULL; + SSL *clientssl = NULL, *serverssl = NULL; + int testresult = 0; + char msg[] = "A test message"; + char buf[5]; + size_t written, readbytes; + + if (tst == 0) { + if (!TEST_true(create_ssl_ctx_pair(TLS_server_method(), + TLS_client_method(), + TLS1_VERSION, TLS_MAX_VERSION, + &sctx, &cctx, cert, privkey))) + goto end; + } else { +#ifndef OPENSSL_NO_DTLS + if (!TEST_true(create_ssl_ctx_pair(DTLS_server_method(), + DTLS_client_method(), + DTLS1_VERSION, DTLS_MAX_VERSION, + &sctx, &cctx, cert, privkey))) + goto end; +#else + return 1; +#endif + } + + if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl, + NULL, NULL)) + || !TEST_true(create_ssl_connection(serverssl, clientssl, + SSL_ERROR_NONE))) + goto end; + + if (!TEST_int_eq(SSL_pending(clientssl), 0) + || !TEST_false(SSL_has_pending(clientssl)) + || !TEST_int_eq(SSL_pending(serverssl), 0) + || !TEST_false(SSL_has_pending(serverssl)) + || !TEST_true(SSL_write_ex(serverssl, msg, sizeof(msg), &written)) + || !TEST_size_t_eq(written, sizeof(msg)) + || !TEST_true(SSL_read_ex(clientssl, buf, sizeof(buf), &readbytes)) + || !TEST_size_t_eq(readbytes, sizeof(buf)) + || !TEST_int_eq(SSL_pending(clientssl), (int)(written - readbytes)) + || !TEST_true(SSL_has_pending(clientssl))) + goto end; + + testresult = 1; + + end: + SSL_free(serverssl); + SSL_free(clientssl); + SSL_CTX_free(sctx); + SSL_CTX_free(cctx); + + return testresult; +} + +static struct { + unsigned int maxprot; + const char *clntciphers; + const char *clnttls13ciphers; + const char *srvrciphers; + const char *srvrtls13ciphers; + const char *shared; +} shared_ciphers_data[] = { +/* + * We can't establish a connection (even in TLSv1.1) with these ciphersuites if + * TLSv1.3 is enabled but TLSv1.2 is disabled. + */ +#if defined(OPENSSL_NO_TLS1_3) || !defined(OPENSSL_NO_TLS1_2) + { + TLS1_2_VERSION, + "AES128-SHA:AES256-SHA", + NULL, + "AES256-SHA:DHE-RSA-AES128-SHA", + NULL, + "AES256-SHA" + }, + { + TLS1_2_VERSION, + "AES128-SHA:DHE-RSA-AES128-SHA:AES256-SHA", + NULL, + "AES128-SHA:DHE-RSA-AES256-SHA:AES256-SHA", + NULL, + "AES128-SHA:AES256-SHA" + }, + { + TLS1_2_VERSION, + "AES128-SHA:AES256-SHA", + NULL, + "AES128-SHA:DHE-RSA-AES128-SHA", + NULL, + "AES128-SHA" + }, +#endif +/* + * This test combines TLSv1.3 and TLSv1.2 ciphersuites so they must both be + * enabled. + */ +#if !defined(OPENSSL_NO_TLS1_3) && !defined(OPENSSL_NO_TLS1_2) \ + && !defined(OPENSSL_NO_CHACHA) && !defined(OPENSSL_NO_POLY1305) + { + TLS1_3_VERSION, + "AES128-SHA:AES256-SHA", + NULL, + "AES256-SHA:AES128-SHA256", + NULL, + "TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:" + "TLS_AES_128_GCM_SHA256:AES256-SHA" + }, +#endif +#ifndef OPENSSL_NO_TLS1_3 + { + TLS1_3_VERSION, + "AES128-SHA", + "TLS_AES_256_GCM_SHA384", + "AES256-SHA", + "TLS_AES_256_GCM_SHA384", + "TLS_AES_256_GCM_SHA384" + }, +#endif +}; + +static int test_ssl_get_shared_ciphers(int tst) +{ + SSL_CTX *cctx = NULL, *sctx = NULL; + SSL *clientssl = NULL, *serverssl = NULL; + int testresult = 0; + char buf[1024]; + + if (!TEST_true(create_ssl_ctx_pair(TLS_server_method(), + TLS_client_method(), + TLS1_VERSION, + shared_ciphers_data[tst].maxprot, + &sctx, &cctx, cert, privkey))) + goto end; + + if (!TEST_true(SSL_CTX_set_cipher_list(cctx, + shared_ciphers_data[tst].clntciphers)) + || (shared_ciphers_data[tst].clnttls13ciphers != NULL + && !TEST_true(SSL_CTX_set_ciphersuites(cctx, + shared_ciphers_data[tst].clnttls13ciphers))) + || !TEST_true(SSL_CTX_set_cipher_list(sctx, + shared_ciphers_data[tst].srvrciphers)) + || (shared_ciphers_data[tst].srvrtls13ciphers != NULL + && !TEST_true(SSL_CTX_set_ciphersuites(sctx, + shared_ciphers_data[tst].srvrtls13ciphers)))) + goto end; + + + if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl, + NULL, NULL)) + || !TEST_true(create_ssl_connection(serverssl, clientssl, + SSL_ERROR_NONE))) + goto end; + + if (!TEST_ptr(SSL_get_shared_ciphers(serverssl, buf, sizeof(buf))) + || !TEST_int_eq(strcmp(buf, shared_ciphers_data[tst].shared), 0)) { + TEST_info("Shared ciphers are: %s\n", buf); + goto end; + } + + testresult = 1; + + end: + SSL_free(serverssl); + SSL_free(clientssl); + SSL_CTX_free(sctx); + SSL_CTX_free(cctx); + + return testresult; +} + +static const char *appdata = "Hello World"; +static int gen_tick_called, dec_tick_called, tick_key_cb_called; +static int tick_key_renew = 0; +static SSL_TICKET_RETURN tick_dec_ret = SSL_TICKET_RETURN_ABORT; + +static int gen_tick_cb(SSL *s, void *arg) +{ + gen_tick_called = 1; + + return SSL_SESSION_set1_ticket_appdata(SSL_get_session(s), appdata, + strlen(appdata)); +} + +static SSL_TICKET_RETURN dec_tick_cb(SSL *s, SSL_SESSION *ss, + const unsigned char *keyname, + size_t keyname_length, + SSL_TICKET_STATUS status, + void *arg) +{ + void *tickdata; + size_t tickdlen; + + dec_tick_called = 1; + + if (status == SSL_TICKET_EMPTY) + return SSL_TICKET_RETURN_IGNORE_RENEW; + + if (!TEST_true(status == SSL_TICKET_SUCCESS + || status == SSL_TICKET_SUCCESS_RENEW)) + return SSL_TICKET_RETURN_ABORT; + + if (!TEST_true(SSL_SESSION_get0_ticket_appdata(ss, &tickdata, + &tickdlen)) + || !TEST_size_t_eq(tickdlen, strlen(appdata)) + || !TEST_int_eq(memcmp(tickdata, appdata, tickdlen), 0)) + return SSL_TICKET_RETURN_ABORT; + + if (tick_key_cb_called) { + /* Don't change what the ticket key callback wanted to do */ + switch (status) { + 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: + return SSL_TICKET_RETURN_ABORT; + } + } + return tick_dec_ret; + +} + +static int tick_key_cb(SSL *s, unsigned char key_name[16], + unsigned char iv[EVP_MAX_IV_LENGTH], EVP_CIPHER_CTX *ctx, + HMAC_CTX *hctx, int enc) +{ + const unsigned char tick_aes_key[16] = "0123456789abcdef"; + const unsigned char tick_hmac_key[16] = "0123456789abcdef"; + + tick_key_cb_called = 1; + memset(iv, 0, AES_BLOCK_SIZE); + memset(key_name, 0, 16); + if (!EVP_CipherInit_ex(ctx, EVP_aes_128_cbc(), NULL, tick_aes_key, iv, enc) + || !HMAC_Init_ex(hctx, tick_hmac_key, sizeof(tick_hmac_key), + EVP_sha256(), NULL)) + return -1; + + return tick_key_renew ? 2 : 1; +} + +/* + * Test the various ticket callbacks + * Test 0: TLSv1.2, no ticket key callback, no ticket, no renewal + * Test 1: TLSv1.3, no ticket key callback, no ticket, no renewal + * Test 2: TLSv1.2, no ticket key callback, no ticket, renewal + * Test 3: TLSv1.3, no ticket key callback, no ticket, renewal + * Test 4: TLSv1.2, no ticket key callback, ticket, no renewal + * Test 5: TLSv1.3, no ticket key callback, ticket, no renewal + * Test 6: TLSv1.2, no ticket key callback, ticket, renewal + * Test 7: TLSv1.3, no ticket key callback, ticket, renewal + * Test 8: TLSv1.2, ticket key callback, ticket, no renewal + * Test 9: TLSv1.3, ticket key callback, ticket, no renewal + * Test 10: TLSv1.2, ticket key callback, ticket, renewal + * Test 11: TLSv1.3, ticket key callback, ticket, renewal + */ +static int test_ticket_callbacks(int tst) +{ + SSL_CTX *cctx = NULL, *sctx = NULL; + SSL *clientssl = NULL, *serverssl = NULL; + SSL_SESSION *clntsess = NULL; + int testresult = 0; + +#ifdef OPENSSL_NO_TLS1_2 + if (tst % 2 == 0) + return 1; +#endif +#ifdef OPENSSL_NO_TLS1_3 + if (tst % 2 == 1) + return 1; +#endif + + gen_tick_called = dec_tick_called = tick_key_cb_called = 0; + + /* Which tests the ticket key callback should request renewal for */ + if (tst == 10 || tst == 11) + tick_key_renew = 1; + else + tick_key_renew = 0; + + /* Which tests the decrypt ticket callback should request renewal for */ + switch (tst) { + case 0: + case 1: + tick_dec_ret = SSL_TICKET_RETURN_IGNORE; + break; + + case 2: + case 3: + tick_dec_ret = SSL_TICKET_RETURN_IGNORE_RENEW; + break; + + case 4: + case 5: + tick_dec_ret = SSL_TICKET_RETURN_USE; + break; + + case 6: + case 7: + tick_dec_ret = SSL_TICKET_RETURN_USE_RENEW; + break; + + default: + tick_dec_ret = SSL_TICKET_RETURN_ABORT; + } + + if (!TEST_true(create_ssl_ctx_pair(TLS_server_method(), + TLS_client_method(), + TLS1_VERSION, + ((tst % 2) == 0) ? TLS1_2_VERSION + : TLS1_3_VERSION, + &sctx, &cctx, cert, privkey))) + goto end; + + /* + * We only want sessions to resume from tickets - not the session cache. So + * switch the cache off. + */ + if (!TEST_true(SSL_CTX_set_session_cache_mode(sctx, SSL_SESS_CACHE_OFF))) + goto end; + + if (!TEST_true(SSL_CTX_set_session_ticket_cb(sctx, gen_tick_cb, dec_tick_cb, + NULL))) + goto end; + + if (tst >= 8 + && !TEST_true(SSL_CTX_set_tlsext_ticket_key_cb(sctx, tick_key_cb))) + goto end; + + if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl, + NULL, NULL)) + || !TEST_true(create_ssl_connection(serverssl, clientssl, + SSL_ERROR_NONE))) + goto end; + + /* + * The decrypt ticket key callback in TLSv1.2 should be called even though + * we have no ticket yet, because it gets called with a status of + * SSL_TICKET_EMPTY (the client indicates support for tickets but does not + * actually send any ticket data). This does not happen in TLSv1.3 because + * it is not valid to send empty ticket data in TLSv1.3. + */ + if (!TEST_int_eq(gen_tick_called, 1) + || !TEST_int_eq(dec_tick_called, ((tst % 2) == 0) ? 1 : 0)) + goto end; + + gen_tick_called = dec_tick_called = 0; + + clntsess = SSL_get1_session(clientssl); + SSL_shutdown(clientssl); + SSL_shutdown(serverssl); + SSL_free(serverssl); + SSL_free(clientssl); + serverssl = clientssl = NULL; + + /* Now do a resumption */ + if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl, NULL, + NULL)) + || !TEST_true(SSL_set_session(clientssl, clntsess)) + || !TEST_true(create_ssl_connection(serverssl, clientssl, + SSL_ERROR_NONE))) + goto end; + + if (tick_dec_ret == SSL_TICKET_RETURN_IGNORE + || tick_dec_ret == SSL_TICKET_RETURN_IGNORE_RENEW) { + if (!TEST_false(SSL_session_reused(clientssl))) + goto end; + } else { + if (!TEST_true(SSL_session_reused(clientssl))) + goto end; + } + + if (!TEST_int_eq(gen_tick_called, + (tick_key_renew + || tick_dec_ret == SSL_TICKET_RETURN_IGNORE_RENEW + || tick_dec_ret == SSL_TICKET_RETURN_USE_RENEW) + ? 1 : 0) + || !TEST_int_eq(dec_tick_called, 1)) + goto end; + + testresult = 1; + + end: + SSL_SESSION_free(clntsess); + SSL_free(serverssl); + SSL_free(clientssl); + SSL_CTX_free(sctx); + SSL_CTX_free(cctx); + + return testresult; +} + int setup_tests(void) { if (!TEST_ptr(cert = test_get_argument(0)) @@ -4461,7 +4893,7 @@ int setup_tests(void) #ifdef OPENSSL_NO_PSK ADD_ALL_TESTS(test_tls13_psk, 1); #else - ADD_ALL_TESTS(test_tls13_psk, 3); + ADD_ALL_TESTS(test_tls13_psk, 4); #endif /* OPENSSL_NO_PSK */ ADD_ALL_TESTS(test_custom_exts, 5); ADD_TEST(test_stateless); @@ -4480,6 +4912,9 @@ int setup_tests(void) ADD_ALL_TESTS(test_srp, 6); #endif ADD_ALL_TESTS(test_info_callback, 6); + ADD_ALL_TESTS(test_ssl_pending, 2); + ADD_ALL_TESTS(test_ssl_get_shared_ciphers, OSSL_NELEM(shared_ciphers_data)); + ADD_ALL_TESTS(test_ticket_callbacks, 12); return 1; }