#include <openssl/ocsp.h>
#include <openssl/srp.h>
#include <openssl/txt_db.h>
+#include <openssl/aes.h>
#include "ssltestlib.h"
#include "testutil.h"
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;
};
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;
|| 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
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++;
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;
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;
/* 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,
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;
}
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;
}
|| !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;
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;
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;
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);
/*
* 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;
}
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);
testresult = 1;
end:
+ SSL_SESSION_free(sess);
SSL_SESSION_free(clientpsk);
SSL_SESSION_free(serverpsk);
clientpsk = serverpsk = NULL;
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);
testresult = 1;
end:
- /* If using PSK then clientpsk and sess are the same */
SSL_SESSION_free(clientpsk);
SSL_SESSION_free(serverpsk);
clientpsk = serverpsk = NULL;
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;
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
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);
}
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)))
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:
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;
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;
+ }
}
/*
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;
testresult = 1;
goto end;
}
+#endif
if (!TEST_true(create_ssl_ctx_pair(TLS_server_method(),
TLS_client_method(),
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))
#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);
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;
}