/*
* Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved.
*
- * Licensed under the OpenSSL license (the "License"). You may not use
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
#include "testutil.h"
#include "testutil/output.h"
#include "internal/nelem.h"
+#include "internal/ktls.h"
#include "../ssl/ssl_locl.h"
+#ifndef OPENSSL_NO_TLS1_3
+
+static SSL_SESSION *clientpsk = NULL;
+static SSL_SESSION *serverpsk = NULL;
+static const char *pskid = "Identity";
+static const char *srvid;
+
+static int use_session_cb(SSL *ssl, const EVP_MD *md, const unsigned char **id,
+ size_t *idlen, SSL_SESSION **sess);
+static int find_session_cb(SSL *ssl, const unsigned char *identity,
+ size_t identity_len, SSL_SESSION **sess);
+
+static int use_session_cb_cnt = 0;
+static int find_session_cb_cnt = 0;
+
+static SSL_SESSION *create_a_psk(SSL *ssl);
+#endif
+
static char *cert = NULL;
static char *privkey = NULL;
static char *srpvfile = NULL;
return testresult;
}
+#if !defined(OPENSSL_NO_TLS1_2) && !defined(OPENSSL_NO_KTLS)
+
+/* sock must be connected */
+static int ktls_chk_platform(int sock)
+{
+ if (!ktls_enable(sock))
+ return 0;
+ return 1;
+}
+
+static int ping_pong_query(SSL *clientssl, SSL *serverssl, int cfd, int sfd)
+{
+ static char count = 1;
+ unsigned char cbuf[16000] = {0};
+ unsigned char sbuf[16000];
+ size_t err = 0;
+ char crec_wseq_before[TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE];
+ char crec_wseq_after[TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE];
+ char srec_wseq_before[TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE];
+ char srec_wseq_after[TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE];
+ char srec_rseq_before[TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE];
+ char srec_rseq_after[TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE];
+
+ cbuf[0] = count++;
+ memcpy(crec_wseq_before, &clientssl->rlayer.write_sequence,
+ TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE);
+ memcpy(srec_wseq_before, &serverssl->rlayer.write_sequence,
+ TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE);
+ memcpy(srec_rseq_before, &serverssl->rlayer.read_sequence,
+ TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE);
+
+ if (!TEST_true(SSL_write(clientssl, cbuf, sizeof(cbuf)) == sizeof(cbuf)))
+ goto end;
+
+ while ((err = SSL_read(serverssl, &sbuf, sizeof(sbuf))) != sizeof(sbuf)) {
+ if (SSL_get_error(serverssl, err) != SSL_ERROR_WANT_READ) {
+ goto end;
+ }
+ }
+
+ if (!TEST_true(SSL_write(serverssl, sbuf, sizeof(sbuf)) == sizeof(sbuf)))
+ goto end;
+
+ while ((err = SSL_read(clientssl, &cbuf, sizeof(cbuf))) != sizeof(cbuf)) {
+ if (SSL_get_error(clientssl, err) != SSL_ERROR_WANT_READ) {
+ goto end;
+ }
+ }
+
+ memcpy(crec_wseq_after, &clientssl->rlayer.write_sequence,
+ TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE);
+ memcpy(srec_wseq_after, &serverssl->rlayer.write_sequence,
+ TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE);
+ memcpy(srec_rseq_after, &serverssl->rlayer.read_sequence,
+ TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE);
+
+ /* verify the payload */
+ if (!TEST_mem_eq(cbuf, sizeof(cbuf), sbuf, sizeof(sbuf)))
+ goto end;
+
+ /* ktls is used then kernel sequences are used instead of OpenSSL sequences */
+ if (clientssl->mode & SSL_MODE_NO_KTLS_TX) {
+ if (!TEST_mem_ne(crec_wseq_before, TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE,
+ crec_wseq_after, TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE))
+ goto end;
+ } else {
+ if (!TEST_mem_eq(crec_wseq_before, TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE,
+ crec_wseq_after, TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE))
+ goto end;
+ }
+
+ if (serverssl->mode & SSL_MODE_NO_KTLS_TX) {
+ if (!TEST_mem_ne(srec_wseq_before, TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE,
+ srec_wseq_after, TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE))
+ goto end;
+ } else {
+ if (!TEST_mem_eq(srec_wseq_before, TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE,
+ srec_wseq_after, TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE))
+ goto end;
+ }
+
+ if (!TEST_mem_ne(srec_rseq_before, TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE,
+ srec_rseq_after, TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE))
+ goto end;
+
+ return 1;
+end:
+ return 0;
+}
+
+static int execute_test_ktls(int cis_ktls_tx, int sis_ktls_tx)
+{
+ SSL_CTX *cctx = NULL, *sctx = NULL;
+ SSL *clientssl = NULL, *serverssl = NULL;
+ int testresult = 0;
+ int cfd, sfd;
+
+ if (!TEST_true(create_test_sockets(&cfd, &sfd)))
+ goto end;
+
+ /* Skip this test if the platform does not support ktls */
+ if (!ktls_chk_platform(cfd))
+ return 1;
+
+ /* Create a session based on SHA-256 */
+ if (!TEST_true(create_ssl_ctx_pair(TLS_server_method(),
+ TLS_client_method(),
+ TLS1_2_VERSION, TLS1_2_VERSION,
+ &sctx, &cctx, cert, privkey))
+ || !TEST_true(SSL_CTX_set_cipher_list(cctx,
+ "AES128-GCM-SHA256"))
+ || !TEST_true(create_ssl_objects2(sctx, cctx, &serverssl,
+ &clientssl, sfd, cfd)))
+ goto end;
+
+ if (!cis_ktls_tx) {
+ if (!TEST_true(SSL_set_mode(clientssl, SSL_MODE_NO_KTLS_TX)))
+ goto end;
+ }
+
+ if (!sis_ktls_tx) {
+ if (!TEST_true(SSL_set_mode(serverssl, SSL_MODE_NO_KTLS_TX)))
+ goto end;
+ }
+
+ if (!TEST_true(create_ssl_connection(serverssl, clientssl,
+ SSL_ERROR_NONE)))
+ goto end;
+
+ if (!cis_ktls_tx) {
+ if (!TEST_false(BIO_get_ktls_send(clientssl->wbio)))
+ goto end;
+ } else {
+ if (!TEST_true(BIO_get_ktls_send(clientssl->wbio)))
+ goto end;
+ }
+
+ if (!sis_ktls_tx) {
+ if (!TEST_false(BIO_get_ktls_send(serverssl->wbio)))
+ goto end;
+ } else {
+ if (!TEST_true(BIO_get_ktls_send(serverssl->wbio)))
+ goto end;
+ }
+
+ if (!TEST_true(ping_pong_query(clientssl, serverssl, cfd, sfd)))
+ goto end;
+
+ testresult = 1;
+end:
+ if (clientssl) {
+ SSL_shutdown(clientssl);
+ SSL_free(clientssl);
+ }
+ if (serverssl) {
+ SSL_shutdown(serverssl);
+ SSL_free(serverssl);
+ }
+ SSL_CTX_free(sctx);
+ SSL_CTX_free(cctx);
+ serverssl = clientssl = NULL;
+ return testresult;
+}
+
+static int test_ktls_client_server(void)
+{
+ return execute_test_ktls(1, 1);
+}
+
+static int test_ktls_no_client_server(void)
+{
+ return execute_test_ktls(0, 1);
+}
+
+static int test_ktls_client_no_server(void)
+{
+ return execute_test_ktls(1, 0);
+}
+
+static int test_ktls_no_client_no_server(void)
+{
+ return execute_test_ktls(0, 0);
+}
+
+#endif
+
static int test_large_message_tls(void)
{
return execute_test_large_message(TLS_server_method(), TLS_client_method(),
SSL *serverssl3 = NULL, *clientssl3 = NULL;
# endif
SSL_SESSION *sess1 = NULL, *sess2 = NULL;
- int testresult = 0;
+ int testresult = 0, numnewsesstick = 1;
new_called = remove_called = 0;
+ /* TLSv1.3 sends 2 NewSessionTickets */
+ if (maxprot == TLS1_3_VERSION)
+ numnewsesstick = 2;
+
if (!TEST_true(create_ssl_ctx_pair(TLS_server_method(), TLS_client_method(),
TLS1_VERSION, TLS_MAX_VERSION,
&sctx, &cctx, cert, privkey)))
if (use_int_cache && !TEST_false(SSL_CTX_add_session(cctx, sess1)))
goto end;
if (use_ext_cache
- && (!TEST_int_eq(new_called, 1) || !TEST_int_eq(remove_called, 0)))
+ && (!TEST_int_eq(new_called, numnewsesstick)
+
+ || !TEST_int_eq(remove_called, 0)))
goto end;
new_called = remove_called = 0;
if (maxprot == TLS1_3_VERSION) {
/*
* In TLSv1.3 we should have created a new session even though we have
- * resumed. The original session should also have been removed.
+ * resumed. Since we attempted a resume we should also have removed the
+ * old ticket from the cache so that we try to only use tickets once.
*/
if (use_ext_cache
&& (!TEST_int_eq(new_called, 1)
goto end;
if (use_ext_cache
- && (!TEST_int_eq(new_called, 1) || !TEST_int_eq(remove_called, 0)))
+ && (!TEST_int_eq(new_called, numnewsesstick)
+ || !TEST_int_eq(remove_called, 0)))
goto end;
new_called = remove_called = 0;
sess2 = NULL;
SSL_CTX_set_max_proto_version(sctx, maxprot);
- SSL_CTX_set_options(sctx, SSL_OP_NO_TICKET);
+ if (maxprot == TLS1_2_VERSION)
+ SSL_CTX_set_options(sctx, SSL_OP_NO_TICKET);
new_called = remove_called = get_called = 0;
if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl1, &clientssl1,
NULL, NULL))
|| !TEST_ptr(sess2 = SSL_get1_session(serverssl1)))
goto end;
- /* Should fail because it should already be in the cache */
- if (use_int_cache && !TEST_false(SSL_CTX_add_session(sctx, sess2)))
- goto end;
+ if (use_int_cache) {
+ if (maxprot == TLS1_3_VERSION && !use_ext_cache) {
+ /*
+ * In TLSv1.3 it should not have been added to the internal cache,
+ * except in the case where we also have an external cache (in that
+ * case it gets added to the cache in order to generate remove
+ * events after timeout).
+ */
+ if (!TEST_false(SSL_CTX_remove_session(sctx, sess2)))
+ goto end;
+ } else {
+ /* Should fail because it should already be in the cache */
+ if (!TEST_false(SSL_CTX_add_session(sctx, sess2)))
+ goto end;
+ }
+ }
if (use_ext_cache) {
SSL_SESSION *tmp = sess2;
- if (!TEST_int_eq(new_called, 1)
+ if (!TEST_int_eq(new_called, numnewsesstick)
|| !TEST_int_eq(remove_called, 0)
|| !TEST_int_eq(get_called, 0))
goto end;
* the external cache. We take a copy first because
* SSL_CTX_remove_session() also marks the session as non-resumable.
*/
- if (use_int_cache) {
+ if (use_int_cache && maxprot != TLS1_3_VERSION) {
if (!TEST_ptr(tmp = SSL_SESSION_dup(sess2))
|| !TEST_true(SSL_CTX_remove_session(sctx, sess2)))
goto end;
goto end;
if (maxprot == TLS1_3_VERSION) {
- /*
- * Every time we issue a NewSessionTicket we are creating a new
- * session for next time in TLSv1.3
- */
if (!TEST_int_eq(new_called, 1)
|| !TEST_int_eq(get_called, 0))
goto end;
#endif
}
-#define USE_NULL 0
-#define USE_BIO_1 1
-#define USE_BIO_2 2
-#define USE_DEFAULT 3
+#ifndef OPENSSL_NO_TLS1_3
+static SSL_SESSION *sesscache[6];
+static int do_cache;
-#define CONNTYPE_CONNECTION_SUCCESS 0
-#define CONNTYPE_CONNECTION_FAIL 1
-#define CONNTYPE_NO_CONNECTION 2
+static int new_cachesession_cb(SSL *ssl, SSL_SESSION *sess)
+{
+ if (do_cache) {
+ sesscache[new_called] = sess;
+ } else {
+ /* We don't need the reference to the session, so free it */
+ SSL_SESSION_free(sess);
+ }
+ new_called++;
-#define TOTAL_NO_CONN_SSL_SET_BIO_TESTS (3 * 3 * 3 * 3)
-#define TOTAL_CONN_SUCCESS_SSL_SET_BIO_TESTS (2 * 2)
-#if !defined(OPENSSL_NO_TLS1_3) && !defined(OPENSSL_NO_TLS1_2)
-# define TOTAL_CONN_FAIL_SSL_SET_BIO_TESTS (2 * 2)
-#else
-# define TOTAL_CONN_FAIL_SSL_SET_BIO_TESTS 0
-#endif
+ return 1;
+}
+static int post_handshake_verify(SSL *sssl, SSL *cssl)
+{
+ SSL_set_verify(sssl, SSL_VERIFY_PEER, NULL);
+ if (!TEST_true(SSL_verify_client_post_handshake(sssl)))
+ return 0;
-#define TOTAL_SSL_SET_BIO_TESTS TOTAL_NO_CONN_SSL_SET_BIO_TESTS \
- + TOTAL_CONN_SUCCESS_SSL_SET_BIO_TESTS \
- + TOTAL_CONN_FAIL_SSL_SET_BIO_TESTS
+ /* Start handshake on the server and client */
+ if (!TEST_int_eq(SSL_do_handshake(sssl), 1)
+ || !TEST_int_le(SSL_read(cssl, NULL, 0), 0)
+ || !TEST_int_le(SSL_read(sssl, NULL, 0), 0)
+ || !TEST_true(create_ssl_connection(sssl, cssl,
+ SSL_ERROR_NONE)))
+ return 0;
-static void setupbio(BIO **res, BIO *bio1, BIO *bio2, int type)
-{
- switch (type) {
- case USE_NULL:
- *res = NULL;
- break;
- case USE_BIO_1:
- *res = bio1;
- break;
- case USE_BIO_2:
- *res = bio2;
- break;
- }
+ return 1;
}
+static int setup_ticket_test(int stateful, int idx, SSL_CTX **sctx,
+ SSL_CTX **cctx)
+{
+ int sess_id_ctx = 1;
-/*
- * Tests calls to SSL_set_bio() under various conditions.
- *
- * For the first 3 * 3 * 3 * 3 = 81 tests we do 2 calls to SSL_set_bio() with
- * various combinations of valid BIOs or NULL being set for the rbio/wbio. We
- * then do more tests where we create a successful connection first using our
- * standard connection setup functions, and then call SSL_set_bio() with
- * various combinations of valid BIOs or NULL. We then repeat these tests
- * following a failed connection. In this last case we are looking to check that
- * SSL_set_bio() functions correctly in the case where s->bbio is not NULL.
- */
-static int test_ssl_set_bio(int idx)
+ if (!TEST_true(create_ssl_ctx_pair(TLS_server_method(), TLS_client_method(),
+ TLS1_VERSION, TLS_MAX_VERSION, sctx,
+ cctx, cert, privkey))
+ || !TEST_true(SSL_CTX_set_num_tickets(*sctx, idx))
+ || !TEST_true(SSL_CTX_set_session_id_context(*sctx,
+ (void *)&sess_id_ctx,
+ sizeof(sess_id_ctx))))
+ return 0;
+
+ if (stateful)
+ SSL_CTX_set_options(*sctx, SSL_OP_NO_TICKET);
+
+ SSL_CTX_set_session_cache_mode(*cctx, SSL_SESS_CACHE_CLIENT
+ | SSL_SESS_CACHE_NO_INTERNAL_STORE);
+ SSL_CTX_sess_set_new_cb(*cctx, new_cachesession_cb);
+
+ return 1;
+}
+
+static int check_resumption(int idx, SSL_CTX *sctx, SSL_CTX *cctx, int succ)
{
- SSL_CTX *sctx = NULL, *cctx = NULL;
- BIO *bio1 = NULL;
- BIO *bio2 = NULL;
- BIO *irbio = NULL, *iwbio = NULL, *nrbio = NULL, *nwbio = NULL;
SSL *serverssl = NULL, *clientssl = NULL;
- int initrbio, initwbio, newrbio, newwbio, conntype;
- int testresult = 0;
+ int i;
- if (idx < TOTAL_NO_CONN_SSL_SET_BIO_TESTS) {
- initrbio = idx % 3;
- idx /= 3;
- initwbio = idx % 3;
- idx /= 3;
- newrbio = idx % 3;
- idx /= 3;
- newwbio = idx % 3;
- conntype = CONNTYPE_NO_CONNECTION;
- } else {
- idx -= TOTAL_NO_CONN_SSL_SET_BIO_TESTS;
- initrbio = initwbio = USE_DEFAULT;
- newrbio = idx % 2;
- idx /= 2;
- newwbio = idx % 2;
- idx /= 2;
- conntype = idx % 2;
- }
+ /* Test that we can resume with all the tickets we got given */
+ for (i = 0; i < idx * 2; i++) {
+ new_called = 0;
+ if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl,
+ &clientssl, NULL, NULL))
+ || !TEST_true(SSL_set_session(clientssl, sesscache[i])))
+ goto end;
- if (!TEST_true(create_ssl_ctx_pair(TLS_server_method(), TLS_client_method(),
- TLS1_VERSION, TLS_MAX_VERSION,
- &sctx, &cctx, cert, privkey)))
- goto end;
+ SSL_set_post_handshake_auth(clientssl, 1);
+
+ if (!TEST_true(create_ssl_connection(serverssl, clientssl,
+ SSL_ERROR_NONE)))
+ goto end;
- if (conntype == CONNTYPE_CONNECTION_FAIL) {
/*
- * We won't ever get here if either TLSv1.3 or TLSv1.2 is disabled
- * because we reduced the number of tests in the definition of
- * TOTAL_CONN_FAIL_SSL_SET_BIO_TESTS to avoid this scenario. By setting
- * mismatched protocol versions we will force a connection failure.
+ * Following a successful resumption we only get 1 ticket. After a
+ * failed one we should get idx tickets.
*/
- SSL_CTX_set_min_proto_version(sctx, TLS1_3_VERSION);
- SSL_CTX_set_max_proto_version(cctx, TLS1_2_VERSION);
- }
-
- if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl,
- NULL, NULL)))
- goto end;
+ if (succ) {
+ if (!TEST_true(SSL_session_reused(clientssl))
+ || !TEST_int_eq(new_called, 1))
+ goto end;
+ } else {
+ if (!TEST_false(SSL_session_reused(clientssl))
+ || !TEST_int_eq(new_called, idx))
+ goto end;
+ }
- if (initrbio == USE_BIO_1
- || initwbio == USE_BIO_1
- || newrbio == USE_BIO_1
- || newwbio == USE_BIO_1) {
- if (!TEST_ptr(bio1 = BIO_new(BIO_s_mem())))
+ new_called = 0;
+ /* After a post-handshake authentication we should get 1 new ticket */
+ if (succ
+ && (!post_handshake_verify(serverssl, clientssl)
+ || !TEST_int_eq(new_called, 1)))
goto end;
- }
- if (initrbio == USE_BIO_2
- || initwbio == USE_BIO_2
- || newrbio == USE_BIO_2
- || newwbio == USE_BIO_2) {
- if (!TEST_ptr(bio2 = BIO_new(BIO_s_mem())))
- goto end;
+ SSL_shutdown(clientssl);
+ SSL_shutdown(serverssl);
+ SSL_free(serverssl);
+ SSL_free(clientssl);
+ serverssl = clientssl = NULL;
+ SSL_SESSION_free(sesscache[i]);
+ sesscache[i] = NULL;
}
- if (initrbio != USE_DEFAULT) {
- setupbio(&irbio, bio1, bio2, initrbio);
- setupbio(&iwbio, bio1, bio2, initwbio);
+ return 1;
+
+ end:
+ SSL_free(clientssl);
+ SSL_free(serverssl);
+ return 0;
+}
+
+static int test_tickets(int stateful, int idx)
+{
+ SSL_CTX *sctx = NULL, *cctx = NULL;
+ SSL *serverssl = NULL, *clientssl = NULL;
+ int testresult = 0;
+ size_t j;
+
+ /* idx is the test number, but also the number of tickets we want */
+
+ new_called = 0;
+ do_cache = 1;
+
+ if (!setup_ticket_test(stateful, idx, &sctx, &cctx))
+ goto end;
+
+ if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl,
+ &clientssl, NULL, NULL)))
+ goto end;
+
+ if (!TEST_true(create_ssl_connection(serverssl, clientssl,
+ SSL_ERROR_NONE))
+ /* Check we got the number of tickets we were expecting */
+ || !TEST_int_eq(idx, new_called))
+ goto end;
+
+ SSL_shutdown(clientssl);
+ SSL_shutdown(serverssl);
+ SSL_free(serverssl);
+ SSL_free(clientssl);
+ SSL_CTX_free(sctx);
+ SSL_CTX_free(cctx);
+ clientssl = serverssl = NULL;
+ sctx = cctx = NULL;
+
+ /*
+ * Now we try to resume with the tickets we previously created. The
+ * resumption attempt is expected to fail (because we're now using a new
+ * SSL_CTX). We should see idx number of tickets issued again.
+ */
+
+ /* Stop caching sessions - just count them */
+ do_cache = 0;
+
+ if (!setup_ticket_test(stateful, idx, &sctx, &cctx))
+ goto end;
+
+ if (!check_resumption(idx, sctx, cctx, 0))
+ goto end;
+
+ /* Start again with caching sessions */
+ new_called = 0;
+ do_cache = 1;
+ SSL_CTX_free(sctx);
+ SSL_CTX_free(cctx);
+ sctx = cctx = NULL;
+
+ if (!setup_ticket_test(stateful, idx, &sctx, &cctx))
+ goto end;
+
+ if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl,
+ &clientssl, NULL, NULL)))
+ goto end;
+
+ SSL_set_post_handshake_auth(clientssl, 1);
+
+ if (!TEST_true(create_ssl_connection(serverssl, clientssl,
+ SSL_ERROR_NONE))
+ /* Check we got the number of tickets we were expecting */
+ || !TEST_int_eq(idx, new_called))
+ goto end;
+
+ /* After a post-handshake authentication we should get new tickets issued */
+ if (!post_handshake_verify(serverssl, clientssl)
+ || !TEST_int_eq(idx * 2, new_called))
+ goto end;
+
+ SSL_shutdown(clientssl);
+ SSL_shutdown(serverssl);
+ SSL_free(serverssl);
+ SSL_free(clientssl);
+ serverssl = clientssl = NULL;
+
+ /* Stop caching sessions - just count them */
+ do_cache = 0;
+
+ /*
+ * Check we can resume with all the tickets we created. This time around the
+ * resumptions should all be successful.
+ */
+ if (!check_resumption(idx, sctx, cctx, 1))
+ goto end;
+
+ testresult = 1;
+
+ end:
+ SSL_free(serverssl);
+ SSL_free(clientssl);
+ for (j = 0; j < OSSL_NELEM(sesscache); j++) {
+ SSL_SESSION_free(sesscache[j]);
+ sesscache[j] = NULL;
+ }
+ SSL_CTX_free(sctx);
+ SSL_CTX_free(cctx);
+
+ return testresult;
+}
+
+static int test_stateless_tickets(int idx)
+{
+ return test_tickets(0, idx);
+}
+
+static int test_stateful_tickets(int idx)
+{
+ return test_tickets(1, idx);
+}
+
+static int test_psk_tickets(void)
+{
+ SSL_CTX *sctx = NULL, *cctx = NULL;
+ SSL *serverssl = NULL, *clientssl = NULL;
+ int testresult = 0;
+ int sess_id_ctx = 1;
+
+ if (!TEST_true(create_ssl_ctx_pair(TLS_server_method(), TLS_client_method(),
+ TLS1_VERSION, TLS_MAX_VERSION, &sctx,
+ &cctx, NULL, NULL))
+ || !TEST_true(SSL_CTX_set_session_id_context(sctx,
+ (void *)&sess_id_ctx,
+ sizeof(sess_id_ctx))))
+ goto end;
+
+ SSL_CTX_set_session_cache_mode(cctx, SSL_SESS_CACHE_CLIENT
+ | SSL_SESS_CACHE_NO_INTERNAL_STORE);
+ SSL_CTX_set_psk_use_session_callback(cctx, use_session_cb);
+ SSL_CTX_set_psk_find_session_callback(sctx, find_session_cb);
+ SSL_CTX_sess_set_new_cb(cctx, new_session_cb);
+ use_session_cb_cnt = 0;
+ find_session_cb_cnt = 0;
+ srvid = pskid;
+ new_called = 0;
+
+ if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl,
+ NULL, NULL)))
+ goto end;
+ clientpsk = serverpsk = create_a_psk(clientssl);
+ if (!TEST_ptr(clientpsk))
+ goto end;
+ SSL_SESSION_up_ref(clientpsk);
+
+ if (!TEST_true(create_ssl_connection(serverssl, clientssl,
+ SSL_ERROR_NONE))
+ || !TEST_int_eq(1, find_session_cb_cnt)
+ || !TEST_int_eq(1, use_session_cb_cnt)
+ /* We should always get 1 ticket when using external PSK */
+ || !TEST_int_eq(1, new_called))
+ goto end;
+
+ testresult = 1;
+
+ end:
+ SSL_free(serverssl);
+ SSL_free(clientssl);
+ SSL_CTX_free(sctx);
+ SSL_CTX_free(cctx);
+ SSL_SESSION_free(clientpsk);
+ SSL_SESSION_free(serverpsk);
+ clientpsk = serverpsk = NULL;
+
+ return testresult;
+}
+#endif
+
+#define USE_NULL 0
+#define USE_BIO_1 1
+#define USE_BIO_2 2
+#define USE_DEFAULT 3
+
+#define CONNTYPE_CONNECTION_SUCCESS 0
+#define CONNTYPE_CONNECTION_FAIL 1
+#define CONNTYPE_NO_CONNECTION 2
+
+#define TOTAL_NO_CONN_SSL_SET_BIO_TESTS (3 * 3 * 3 * 3)
+#define TOTAL_CONN_SUCCESS_SSL_SET_BIO_TESTS (2 * 2)
+#if !defined(OPENSSL_NO_TLS1_3) && !defined(OPENSSL_NO_TLS1_2)
+# define TOTAL_CONN_FAIL_SSL_SET_BIO_TESTS (2 * 2)
+#else
+# define TOTAL_CONN_FAIL_SSL_SET_BIO_TESTS 0
+#endif
+
+#define TOTAL_SSL_SET_BIO_TESTS TOTAL_NO_CONN_SSL_SET_BIO_TESTS \
+ + TOTAL_CONN_SUCCESS_SSL_SET_BIO_TESTS \
+ + TOTAL_CONN_FAIL_SSL_SET_BIO_TESTS
+
+static void setupbio(BIO **res, BIO *bio1, BIO *bio2, int type)
+{
+ switch (type) {
+ case USE_NULL:
+ *res = NULL;
+ break;
+ case USE_BIO_1:
+ *res = bio1;
+ break;
+ case USE_BIO_2:
+ *res = bio2;
+ break;
+ }
+}
+
+
+/*
+ * Tests calls to SSL_set_bio() under various conditions.
+ *
+ * For the first 3 * 3 * 3 * 3 = 81 tests we do 2 calls to SSL_set_bio() with
+ * various combinations of valid BIOs or NULL being set for the rbio/wbio. We
+ * then do more tests where we create a successful connection first using our
+ * standard connection setup functions, and then call SSL_set_bio() with
+ * various combinations of valid BIOs or NULL. We then repeat these tests
+ * following a failed connection. In this last case we are looking to check that
+ * SSL_set_bio() functions correctly in the case where s->bbio is not NULL.
+ */
+static int test_ssl_set_bio(int idx)
+{
+ SSL_CTX *sctx = NULL, *cctx = NULL;
+ BIO *bio1 = NULL;
+ BIO *bio2 = NULL;
+ BIO *irbio = NULL, *iwbio = NULL, *nrbio = NULL, *nwbio = NULL;
+ SSL *serverssl = NULL, *clientssl = NULL;
+ int initrbio, initwbio, newrbio, newwbio, conntype;
+ int testresult = 0;
+
+ if (idx < TOTAL_NO_CONN_SSL_SET_BIO_TESTS) {
+ initrbio = idx % 3;
+ idx /= 3;
+ initwbio = idx % 3;
+ idx /= 3;
+ newrbio = idx % 3;
+ idx /= 3;
+ newwbio = idx % 3;
+ conntype = CONNTYPE_NO_CONNECTION;
+ } else {
+ idx -= TOTAL_NO_CONN_SSL_SET_BIO_TESTS;
+ initrbio = initwbio = USE_DEFAULT;
+ newrbio = idx % 2;
+ idx /= 2;
+ newwbio = idx % 2;
+ idx /= 2;
+ conntype = idx % 2;
+ }
+
+ if (!TEST_true(create_ssl_ctx_pair(TLS_server_method(), TLS_client_method(),
+ TLS1_VERSION, TLS_MAX_VERSION,
+ &sctx, &cctx, cert, privkey)))
+ goto end;
+
+ if (conntype == CONNTYPE_CONNECTION_FAIL) {
+ /*
+ * We won't ever get here if either TLSv1.3 or TLSv1.2 is disabled
+ * because we reduced the number of tests in the definition of
+ * TOTAL_CONN_FAIL_SSL_SET_BIO_TESTS to avoid this scenario. By setting
+ * mismatched protocol versions we will force a connection failure.
+ */
+ SSL_CTX_set_min_proto_version(sctx, TLS1_3_VERSION);
+ SSL_CTX_set_max_proto_version(cctx, TLS1_2_VERSION);
+ }
+
+ if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl,
+ NULL, NULL)))
+ goto end;
+
+ if (initrbio == USE_BIO_1
+ || initwbio == USE_BIO_1
+ || newrbio == USE_BIO_1
+ || newwbio == USE_BIO_1) {
+ if (!TEST_ptr(bio1 = BIO_new(BIO_s_mem())))
+ goto end;
+ }
+
+ if (initrbio == USE_BIO_2
+ || initwbio == USE_BIO_2
+ || newrbio == USE_BIO_2
+ || newwbio == USE_BIO_2) {
+ if (!TEST_ptr(bio2 = BIO_new(BIO_s_mem())))
+ goto end;
+ }
+
+ if (initrbio != USE_DEFAULT) {
+ setupbio(&irbio, bio1, bio2, initrbio);
+ setupbio(&iwbio, bio1, bio2, initwbio);
SSL_set_bio(clientssl, irbio, iwbio);
/*
#endif
#ifndef OPENSSL_NO_TLS1_3
-
-static SSL_SESSION *clientpsk = NULL;
-static SSL_SESSION *serverpsk = NULL;
-static const char *pskid = "Identity";
-static const char *srvid;
-
-static int use_session_cb_cnt = 0;
-static int find_session_cb_cnt = 0;
static int psk_client_cb_cnt = 0;
static int psk_server_cb_cnt = 0;
#define TLS13_AES_256_GCM_SHA384_BYTES ((const unsigned char *)"\x13\x02")
#define TLS13_AES_128_GCM_SHA256_BYTES ((const unsigned char *)"\x13\x01")
+
+static SSL_SESSION *create_a_psk(SSL *ssl)
+{
+ const SSL_CIPHER *cipher = NULL;
+ const unsigned char key[] = {
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
+ 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15,
+ 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20,
+ 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b,
+ 0x2c, 0x2d, 0x2e, 0x2f
+ };
+ SSL_SESSION *sess = NULL;
+
+ cipher = SSL_CIPHER_find(ssl, TLS13_AES_256_GCM_SHA384_BYTES);
+ sess = SSL_SESSION_new();
+ if (!TEST_ptr(sess)
+ || !TEST_ptr(cipher)
+ || !TEST_true(SSL_SESSION_set1_master_key(sess, key,
+ sizeof(key)))
+ || !TEST_true(SSL_SESSION_set_cipher(sess, cipher))
+ || !TEST_true(
+ SSL_SESSION_set_protocol_version(sess,
+ TLS1_3_VERSION))) {
+ SSL_SESSION_free(sess);
+ return NULL;
+ }
+ return sess;
+}
+
/*
* Helper method to setup objects for early data test. Caller frees objects on
* error.
static int setupearly_data_test(SSL_CTX **cctx, SSL_CTX **sctx, SSL **clientssl,
SSL **serverssl, SSL_SESSION **sess, int idx)
{
- if (!TEST_true(create_ssl_ctx_pair(TLS_server_method(), TLS_client_method(),
- TLS1_VERSION, TLS_MAX_VERSION,
- sctx, cctx, cert, privkey))
- || !TEST_true(SSL_CTX_set_max_early_data(*sctx,
- SSL3_RT_MAX_PLAIN_LENGTH)))
+ if (*sctx == NULL
+ && !TEST_true(create_ssl_ctx_pair(TLS_server_method(),
+ TLS_client_method(),
+ TLS1_VERSION, TLS_MAX_VERSION,
+ sctx, cctx, cert, privkey)))
+ return 0;
+
+ if (!TEST_true(SSL_CTX_set_max_early_data(*sctx, SSL3_RT_MAX_PLAIN_LENGTH)))
return 0;
if (idx == 1) {
return 0;
if (idx == 2) {
- /* Create the PSK */
- const SSL_CIPHER *cipher = NULL;
- const unsigned char key[] = {
- 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
- 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15,
- 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20,
- 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b,
- 0x2c, 0x2d, 0x2e, 0x2f
- };
-
- cipher = SSL_CIPHER_find(*clientssl, TLS13_AES_256_GCM_SHA384_BYTES);
- clientpsk = SSL_SESSION_new();
+ clientpsk = create_a_psk(*clientssl);
if (!TEST_ptr(clientpsk)
- || !TEST_ptr(cipher)
- || !TEST_true(SSL_SESSION_set1_master_key(clientpsk, key,
- sizeof(key)))
- || !TEST_true(SSL_SESSION_set_cipher(clientpsk, cipher))
- || !TEST_true(
- SSL_SESSION_set_protocol_version(clientpsk,
- TLS1_3_VERSION))
/*
* We just choose an arbitrary value for max_early_data which
* should be big enough for testing purposes.
goto end;
/*
- * Make sure we process the NewSessionTicket. This arrives post-handshake.
- * We attempt a read which we do not expect to return any data.
+ * Make sure we process the two NewSessionTickets. These arrive
+ * post-handshake. We attempt reads which we do not expect to return any
+ * data.
*/
- if (!TEST_false(SSL_read_ex(clientssl, buf, sizeof(buf), &readbytes)))
+ if (!TEST_false(SSL_read_ex(clientssl, buf, sizeof(buf), &readbytes))
+ || !TEST_false(SSL_read_ex(clientssl, buf, sizeof(buf),
+ &readbytes)))
goto end;
/* Server should be able to write normal data */
return testresult;
}
-static int test_early_data_replay(int idx)
+static int allow_ed_cb_called = 0;
+
+static int allow_early_data_cb(SSL *s, void *arg)
+{
+ int *usecb = (int *)arg;
+
+ allow_ed_cb_called++;
+
+ if (*usecb == 1)
+ return 0;
+
+ return 1;
+}
+
+/*
+ * idx == 0: Standard early_data setup
+ * idx == 1: early_data setup using read_ahead
+ * usecb == 0: Don't use a custom early data callback
+ * usecb == 1: Use a custom early data callback and reject the early data
+ * usecb == 2: Use a custom early data callback and accept the early data
+ * confopt == 0: Configure anti-replay directly
+ * confopt == 1: Configure anti-replay using SSL_CONF
+ */
+static int test_early_data_replay_int(int idx, int usecb, int confopt)
{
SSL_CTX *cctx = NULL, *sctx = NULL;
SSL *clientssl = NULL, *serverssl = NULL;
int testresult = 0;
SSL_SESSION *sess = NULL;
+ size_t readbytes, written;
+ unsigned char buf[20];
+
+ allow_ed_cb_called = 0;
+
+ if (!TEST_true(create_ssl_ctx_pair(TLS_server_method(), TLS_client_method(),
+ TLS1_VERSION, TLS_MAX_VERSION, &sctx,
+ &cctx, cert, privkey)))
+ return 0;
+
+ if (usecb > 0) {
+ if (confopt == 0) {
+ SSL_CTX_set_options(sctx, SSL_OP_NO_ANTI_REPLAY);
+ } else {
+ SSL_CONF_CTX *confctx = SSL_CONF_CTX_new();
+
+ if (!TEST_ptr(confctx))
+ goto end;
+ SSL_CONF_CTX_set_flags(confctx, SSL_CONF_FLAG_FILE
+ | SSL_CONF_FLAG_SERVER);
+ SSL_CONF_CTX_set_ssl_ctx(confctx, sctx);
+ if (!TEST_int_eq(SSL_CONF_cmd(confctx, "Options", "-AntiReplay"),
+ 2)) {
+ SSL_CONF_CTX_free(confctx);
+ goto end;
+ }
+ SSL_CONF_CTX_free(confctx);
+ }
+ SSL_CTX_set_allow_early_data_cb(sctx, allow_early_data_cb, &usecb);
+ }
if (!TEST_true(setupearly_data_test(&cctx, &sctx, &clientssl,
&serverssl, &sess, idx)))
if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl,
&clientssl, NULL, NULL))
- || !TEST_true(SSL_set_session(clientssl, sess))
- || !TEST_true(create_ssl_connection(serverssl, clientssl,
- SSL_ERROR_NONE))
- /*
- * This time we should not have resumed the session because we
- * already used it once.
- */
- || !TEST_false(SSL_session_reused(clientssl)))
+ || !TEST_true(SSL_set_session(clientssl, sess)))
+ goto end;
+
+ /* Write and read some early data */
+ if (!TEST_true(SSL_write_early_data(clientssl, MSG1, strlen(MSG1),
+ &written))
+ || !TEST_size_t_eq(written, strlen(MSG1)))
+ goto end;
+
+ if (usecb <= 1) {
+ if (!TEST_int_eq(SSL_read_early_data(serverssl, buf, sizeof(buf),
+ &readbytes),
+ SSL_READ_EARLY_DATA_FINISH)
+ /*
+ * The ticket was reused, so the we should have rejected the
+ * early data
+ */
+ || !TEST_int_eq(SSL_get_early_data_status(serverssl),
+ SSL_EARLY_DATA_REJECTED))
+ goto end;
+ } else {
+ /* In this case the callback decides to accept the early data */
+ if (!TEST_int_eq(SSL_read_early_data(serverssl, buf, sizeof(buf),
+ &readbytes),
+ SSL_READ_EARLY_DATA_SUCCESS)
+ || !TEST_mem_eq(MSG1, strlen(MSG1), buf, readbytes)
+ /*
+ * Server will have sent its flight so client can now send
+ * end of early data and complete its half of the handshake
+ */
+ || !TEST_int_gt(SSL_connect(clientssl), 0)
+ || !TEST_int_eq(SSL_read_early_data(serverssl, buf, sizeof(buf),
+ &readbytes),
+ SSL_READ_EARLY_DATA_FINISH)
+ || !TEST_int_eq(SSL_get_early_data_status(serverssl),
+ SSL_EARLY_DATA_ACCEPTED))
+ goto end;
+ }
+
+ /* Complete the connection */
+ if (!TEST_true(create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE))
+ || !TEST_int_eq(SSL_session_reused(clientssl), (usecb > 0) ? 1 : 0)
+ || !TEST_int_eq(allow_ed_cb_called, usecb > 0 ? 1 : 0))
goto end;
testresult = 1;
return testresult;
}
+static int test_early_data_replay(int idx)
+{
+ int ret = 1, usecb, confopt;
+
+ for (usecb = 0; usecb < 3; usecb++) {
+ for (confopt = 0; confopt < 2; confopt++)
+ ret &= test_early_data_replay_int(idx, usecb, confopt);
+ }
+
+ return ret;
+}
+
/*
* Helper function to test that a server attempting to read early data can
* handle a connection from a client where the early data should be skipped.
+ * testtype: 0 == No HRR
+ * testtype: 1 == HRR
+ * testtype: 2 == HRR, invalid early_data sent after HRR
+ * testtype: 3 == recv_max_early_data set to 0
*/
-static int early_data_skip_helper(int hrr, int idx)
+static int early_data_skip_helper(int testtype, int idx)
{
SSL_CTX *cctx = NULL, *sctx = NULL;
SSL *clientssl = NULL, *serverssl = NULL;
&serverssl, &sess, idx)))
goto end;
- if (hrr) {
+ if (testtype == 1 || testtype == 2) {
/* Force an HRR to occur */
if (!TEST_true(SSL_set1_groups_list(serverssl, "P-256")))
goto end;
goto end;
}
+ if (testtype == 3
+ && !TEST_true(SSL_set_recv_max_early_data(serverssl, 0)))
+ goto end;
+
/* Write some early data */
if (!TEST_true(SSL_write_early_data(clientssl, MSG1, strlen(MSG1),
&written))
|| !TEST_size_t_eq(written, strlen(MSG1)))
goto end;
- /* Server should reject the early data and skip over it */
+ /* Server should reject the early data */
if (!TEST_int_eq(SSL_read_early_data(serverssl, buf, sizeof(buf),
&readbytes),
SSL_READ_EARLY_DATA_FINISH)
SSL_EARLY_DATA_REJECTED))
goto end;
- if (hrr) {
+ switch (testtype) {
+ case 0:
+ /* Nothing to do */
+ break;
+
+ case 1:
/*
* Finish off the handshake. We perform the same writes and reads as
* further down but we expect them to fail due to the incomplete
|| !TEST_false(SSL_read_ex(serverssl, buf, sizeof(buf),
&readbytes)))
goto end;
+ break;
+
+ case 2:
+ {
+ BIO *wbio = SSL_get_wbio(clientssl);
+ /* A record that will appear as bad early_data */
+ const unsigned char bad_early_data[] = {
+ 0x17, 0x03, 0x03, 0x00, 0x01, 0x00
+ };
+
+ /*
+ * We force the client to attempt a write. This will fail because
+ * we're still in the handshake. It will cause the second
+ * ClientHello to be sent.
+ */
+ if (!TEST_false(SSL_write_ex(clientssl, MSG2, strlen(MSG2),
+ &written)))
+ goto end;
+
+ /*
+ * Inject some early_data after the second ClientHello. This should
+ * cause the server to fail
+ */
+ if (!TEST_true(BIO_write_ex(wbio, bad_early_data,
+ sizeof(bad_early_data), &written)))
+ goto end;
+ }
+ /* fallthrough */
+
+ case 3:
+ /*
+ * This client has sent more early_data than we are willing to skip
+ * (case 3) or sent invalid early_data (case 2) so the connection should
+ * abort.
+ */
+ if (!TEST_false(SSL_read_ex(serverssl, buf, sizeof(buf), &readbytes))
+ || !TEST_int_eq(SSL_get_error(serverssl, 0), SSL_ERROR_SSL))
+ goto end;
+
+ /* Connection has failed - nothing more to do */
+ testresult = 1;
+ goto end;
+
+ default:
+ TEST_error("Invalid test type");
+ goto end;
}
- /* Should be able to send normal data despite rejection of early data */
+ /*
+ * Should be able to send normal data despite rejection of early data. The
+ * early_data should be skipped.
+ */
if (!TEST_true(SSL_write_ex(clientssl, MSG2, strlen(MSG2), &written))
|| !TEST_size_t_eq(written, strlen(MSG2))
|| !TEST_int_eq(SSL_get_early_data_status(clientssl),
return early_data_skip_helper(1, idx);
}
+/*
+ * Test that a server attempting to read early data can handle a connection
+ * from a client where an HRR occurs and correctly fails if early_data is sent
+ * after the HRR
+ */
+static int test_early_data_skip_hrr_fail(int idx)
+{
+ return early_data_skip_helper(2, idx);
+}
+
+/*
+ * Test that a server attempting to read early data will abort if it tries to
+ * skip over too much.
+ */
+static int test_early_data_skip_abort(int idx)
+{
+ return early_data_skip_helper(3, idx);
+}
+
/*
* Test that a server attempting to read early data can handle a connection
* from a client that doesn't send any.
|| !TEST_size_t_eq(written, strlen(MSG2)))
goto end;
- /*
- * Should block due to the NewSessionTicket arrival unless we're using
- * read_ahead, or PSKs
- */
- if (idx != 1 && idx != 2) {
- if (!TEST_false(SSL_read_ex(clientssl, buf, sizeof(buf), &readbytes)))
- goto end;
- }
-
if (!TEST_true(SSL_read_ex(clientssl, buf, sizeof(buf), &readbytes))
|| !TEST_mem_eq(buf, readbytes, MSG2, strlen(MSG2)))
goto end;
|| (tst == 2 && snicb != 1))
goto end;
} else {
+ /* In this case there 2 NewSessionTicket messages created */
if (clntaddnewcb != 1
- || clntparsenewcb != 4
- || srvaddnewcb != 4
+ || clntparsenewcb != 5
+ || srvaddnewcb != 5
|| srvparsenewcb != 1)
goto end;
}
|| srvparsenewcb != 2)
goto end;
} else {
- /* No Certificate message extensions in the resumption handshake */
+ /*
+ * No Certificate message extensions in the resumption handshake,
+ * 2 NewSessionTickets in the initial handshake, 1 in the resumption
+ */
if (clntaddnewcb != 2
- || clntparsenewcb != 7
- || srvaddnewcb != 7
+ || clntparsenewcb != 8
+ || srvaddnewcb != 8
|| srvparsenewcb != 2)
goto end;
}
* no test vectors so all we do is test that both sides of the communication
* produce the same results for different protocol versions.
*/
+#define SMALL_LABEL_LEN 10
+#define LONG_LABEL_LEN 249
static int test_export_key_mat(int tst)
{
int testresult = 0;
SSL_CTX *cctx = NULL, *sctx = NULL, *sctx2 = NULL;
SSL *clientssl = NULL, *serverssl = NULL;
- const char label[] = "test label";
+ const char label[LONG_LABEL_LEN + 1] = "test label";
const unsigned char context[] = "context";
const unsigned char *emptycontext = NULL;
unsigned char ckeymat1[80], ckeymat2[80], ckeymat3[80];
unsigned char skeymat1[80], skeymat2[80], skeymat3[80];
+ size_t labellen;
const int protocols[] = {
TLS1_VERSION,
TLS1_1_VERSION,
TLS1_2_VERSION,
+ TLS1_3_VERSION,
+ TLS1_3_VERSION,
TLS1_3_VERSION
};
return 1;
#endif
#ifdef OPENSSL_NO_TLS1_3
- if (tst == 3)
+ if (tst >= 3)
return 1;
#endif
if (!TEST_true(create_ssl_ctx_pair(TLS_server_method(), TLS_client_method(),
SSL_ERROR_NONE)))
goto end;
+ if (tst == 5) {
+ /*
+ * TLSv1.3 imposes a maximum label len of 249 bytes. Check we fail if we
+ * go over that.
+ */
+ if (!TEST_int_le(SSL_export_keying_material(clientssl, ckeymat1,
+ sizeof(ckeymat1), label,
+ LONG_LABEL_LEN + 1, context,
+ sizeof(context) - 1, 1), 0))
+ goto end;
+
+ testresult = 1;
+ goto end;
+ } else if (tst == 4) {
+ labellen = LONG_LABEL_LEN;
+ } else {
+ labellen = SMALL_LABEL_LEN;
+ }
+
if (!TEST_int_eq(SSL_export_keying_material(clientssl, ckeymat1,
sizeof(ckeymat1), label,
- sizeof(label) - 1, context,
+ labellen, context,
sizeof(context) - 1, 1), 1)
|| !TEST_int_eq(SSL_export_keying_material(clientssl, ckeymat2,
sizeof(ckeymat2), label,
- sizeof(label) - 1,
+ labellen,
emptycontext,
0, 1), 1)
|| !TEST_int_eq(SSL_export_keying_material(clientssl, ckeymat3,
sizeof(ckeymat3), label,
- sizeof(label) - 1,
+ labellen,
NULL, 0, 0), 1)
|| !TEST_int_eq(SSL_export_keying_material(serverssl, skeymat1,
sizeof(skeymat1), label,
- sizeof(label) - 1,
+ labellen,
context,
sizeof(context) -1, 1),
1)
|| !TEST_int_eq(SSL_export_keying_material(serverssl, skeymat2,
sizeof(skeymat2), label,
- sizeof(label) - 1,
+ labellen,
emptycontext,
0, 1), 1)
|| !TEST_int_eq(SSL_export_keying_material(serverssl, skeymat3,
sizeof(skeymat3), label,
- sizeof(label) - 1,
+ labellen,
NULL, 0, 0), 1)
/*
* Check that both sides created the same key material with the
* Check that an empty context and no context produce different results in
* protocols less than TLSv1.3. In TLSv1.3 they should be the same.
*/
- if ((tst != 3 && !TEST_mem_ne(ckeymat2, sizeof(ckeymat2), ckeymat3,
+ if ((tst < 3 && !TEST_mem_ne(ckeymat2, sizeof(ckeymat2), ckeymat3,
sizeof(ckeymat3)))
- || (tst ==3 && !TEST_mem_eq(ckeymat2, sizeof(ckeymat2), ckeymat3,
- sizeof(ckeymat3))))
+ || (tst >= 3 && !TEST_mem_eq(ckeymat2, sizeof(ckeymat2), ckeymat3,
+ sizeof(ckeymat3))))
goto end;
testresult = 1;
|| !TEST_true(SSL_CTX_set_max_proto_version(cctx, TLS1_3_VERSION)))
goto end;
+ SSL_CTX_set_post_handshake_auth(cctx, 1);
if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl,
NULL, NULL)))
goto end;
- SSL_force_post_handshake_auth(clientssl);
-
if (!TEST_true(create_ssl_connection(serverssl, clientssl,
SSL_ERROR_NONE)))
goto end;
{SSL_CB_EXIT, NULL}, {SSL_CB_LOOP, "TED"}, {SSL_CB_LOOP, "TRFIN"},
{SSL_CB_HANDSHAKE_DONE, NULL}, {SSL_CB_HANDSHAKE_START, NULL},
{SSL_CB_LOOP, "TWST"}, {SSL_CB_HANDSHAKE_DONE, NULL},
- {SSL_CB_EXIT, NULL}, {SSL_CB_ALERT, NULL},
- {SSL_CB_HANDSHAKE_START, NULL}, {SSL_CB_LOOP, "PINIT "},
- {SSL_CB_LOOP, "PINIT "}, {SSL_CB_LOOP, "TRCH"}, {SSL_CB_LOOP, "TWSH"},
- {SSL_CB_LOOP, "TWCCS"}, {SSL_CB_LOOP, "TWEE"}, {SSL_CB_LOOP, "TWFIN"},
- {SSL_CB_LOOP, "TED"}, {SSL_CB_EXIT, NULL}, {SSL_CB_LOOP, "TED"},
- {SSL_CB_LOOP, "TRFIN"}, {SSL_CB_HANDSHAKE_DONE, NULL},
{SSL_CB_HANDSHAKE_START, NULL}, {SSL_CB_LOOP, "TWST"},
- {SSL_CB_HANDSHAKE_DONE, NULL}, {SSL_CB_EXIT, NULL}, {0, NULL},
+ {SSL_CB_HANDSHAKE_DONE, NULL}, {SSL_CB_EXIT, NULL},
+ {SSL_CB_ALERT, NULL}, {SSL_CB_HANDSHAKE_START, NULL},
+ {SSL_CB_LOOP, "PINIT "}, {SSL_CB_LOOP, "PINIT "}, {SSL_CB_LOOP, "TRCH"},
+ {SSL_CB_LOOP, "TWSH"}, {SSL_CB_LOOP, "TWCCS"}, {SSL_CB_LOOP, "TWEE"},
+ {SSL_CB_LOOP, "TWFIN"}, {SSL_CB_LOOP, "TED"}, {SSL_CB_EXIT, NULL},
+ {SSL_CB_LOOP, "TED"}, {SSL_CB_LOOP, "TRFIN"},
+ {SSL_CB_HANDSHAKE_DONE, NULL}, {SSL_CB_HANDSHAKE_START, NULL},
+ {SSL_CB_LOOP, "TWST"}, {SSL_CB_HANDSHAKE_DONE, NULL},
+ {SSL_CB_EXIT, NULL}, {0, NULL},
}, {
/* TLSv1.3 client followed by resumption */
{SSL_CB_HANDSHAKE_START, NULL}, {SSL_CB_LOOP, "PINIT "},
{SSL_CB_EXIT, NULL}, {SSL_CB_HANDSHAKE_START, NULL},
{SSL_CB_LOOP, "SSLOK "}, {SSL_CB_LOOP, "SSLOK "}, {SSL_CB_LOOP, "TRST"},
{SSL_CB_HANDSHAKE_DONE, NULL}, {SSL_CB_EXIT, NULL},
+ {SSL_CB_HANDSHAKE_START, NULL}, {SSL_CB_LOOP, "SSLOK "},
+ {SSL_CB_LOOP, "SSLOK "}, {SSL_CB_LOOP, "TRST"},
+ {SSL_CB_HANDSHAKE_DONE, NULL}, {SSL_CB_EXIT, NULL},
{SSL_CB_ALERT, NULL}, {SSL_CB_HANDSHAKE_START, NULL},
{SSL_CB_LOOP, "PINIT "}, {SSL_CB_LOOP, "TWCH"}, {SSL_CB_EXIT, NULL},
{SSL_CB_LOOP, "TWCH"}, {SSL_CB_LOOP, "TRSH"}, {SSL_CB_LOOP, "TREE"},
int tlsvers;
if (tst < 2) {
-#ifndef OPENSSL_NO_TLS1_2
+/* We need either ECDHE or DHE for the TLSv1.2 test to work */
+#if !defined(OPENSSL_NO_TLS1_2) && (!defined(OPENSSL_NO_EC) \
+ || !defined(OPENSSL_NO_DH))
tlsvers = TLS1_2_VERSION;
#else
return 1;
int testresult = 0;
#ifdef OPENSSL_NO_TLS1_2
- if (tst % 2 == 0);
+ if (tst % 2 == 0)
return 1;
#endif
#ifdef OPENSSL_NO_TLS1_3
- if (tst % 2 == 1);
+ if (tst % 2 == 1)
return 1;
#endif
return testresult;
}
+/*
+ * Test bi-directional shutdown.
+ * Test 0: TLSv1.2
+ * Test 1: TLSv1.2, server continues to read/write after client shutdown
+ * Test 2: TLSv1.3, no pending NewSessionTicket messages
+ * Test 3: TLSv1.3, pending NewSessionTicket messages
+ * Test 4: TLSv1.3, server continues to read/write after client shutdown, server
+ * sends key update, client reads it
+ * Test 5: TLSv1.3, server continues to read/write after client shutdown, server
+ * sends CertificateRequest, client reads and ignores it
+ * Test 6: TLSv1.3, server continues to read/write after client shutdown, client
+ * doesn't read it
+ */
+static int test_shutdown(int tst)
+{
+ SSL_CTX *cctx = NULL, *sctx = NULL;
+ SSL *clientssl = NULL, *serverssl = NULL;
+ int testresult = 0;
+ char msg[] = "A test message";
+ char buf[80];
+ size_t written, readbytes;
+ SSL_SESSION *sess;
+
+#ifdef OPENSSL_NO_TLS1_2
+ if (tst <= 1)
+ return 1;
+#endif
+#ifdef OPENSSL_NO_TLS1_3
+ if (tst >= 2)
+ return 1;
+#endif
+
+ if (!TEST_true(create_ssl_ctx_pair(TLS_server_method(),
+ TLS_client_method(),
+ TLS1_VERSION,
+ (tst <= 1) ? TLS1_2_VERSION
+ : TLS1_3_VERSION,
+ &sctx, &cctx, cert, privkey)))
+ goto end;
+
+ if (tst == 5)
+ SSL_CTX_set_post_handshake_auth(cctx, 1);
+
+ if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl,
+ NULL, NULL)))
+ goto end;
+
+ if (tst == 3) {
+ if (!TEST_true(create_bare_ssl_connection(serverssl, clientssl,
+ SSL_ERROR_NONE))
+ || !TEST_ptr_ne(sess = SSL_get_session(clientssl), NULL)
+ || !TEST_false(SSL_SESSION_is_resumable(sess)))
+ goto end;
+ } else if (!TEST_true(create_ssl_connection(serverssl, clientssl,
+ SSL_ERROR_NONE))
+ || !TEST_ptr_ne(sess = SSL_get_session(clientssl), NULL)
+ || !TEST_true(SSL_SESSION_is_resumable(sess))) {
+ goto end;
+ }
+
+ if (!TEST_int_eq(SSL_shutdown(clientssl), 0))
+ goto end;
+
+ if (tst >= 4) {
+ /*
+ * Reading on the server after the client has sent close_notify should
+ * fail and provide SSL_ERROR_ZERO_RETURN
+ */
+ if (!TEST_false(SSL_read_ex(serverssl, buf, sizeof(buf), &readbytes))
+ || !TEST_int_eq(SSL_get_error(serverssl, 0),
+ SSL_ERROR_ZERO_RETURN)
+ || !TEST_int_eq(SSL_get_shutdown(serverssl),
+ SSL_RECEIVED_SHUTDOWN)
+ /*
+ * Even though we're shutdown on receive we should still be
+ * able to write.
+ */
+ || !TEST_true(SSL_write(serverssl, msg, sizeof(msg))))
+ goto end;
+ if (tst == 4
+ && !TEST_true(SSL_key_update(serverssl,
+ SSL_KEY_UPDATE_REQUESTED)))
+ goto end;
+ if (tst == 5) {
+ SSL_set_verify(serverssl, SSL_VERIFY_PEER, NULL);
+ if (!TEST_true(SSL_verify_client_post_handshake(serverssl)))
+ goto end;
+ }
+ if ((tst == 4 || tst == 5)
+ && !TEST_true(SSL_write(serverssl, msg, sizeof(msg))))
+ goto end;
+ if (!TEST_int_eq(SSL_shutdown(serverssl), 1))
+ goto end;
+ if (tst == 4 || tst == 5) {
+ /* Should still be able to read data from server */
+ if (!TEST_true(SSL_read_ex(clientssl, buf, sizeof(buf),
+ &readbytes))
+ || !TEST_size_t_eq(readbytes, sizeof(msg))
+ || !TEST_int_eq(memcmp(msg, buf, readbytes), 0)
+ || !TEST_true(SSL_read_ex(clientssl, buf, sizeof(buf),
+ &readbytes))
+ || !TEST_size_t_eq(readbytes, sizeof(msg))
+ || !TEST_int_eq(memcmp(msg, buf, readbytes), 0))
+ goto end;
+ }
+ }
+
+ /* Writing on the client after sending close_notify shouldn't be possible */
+ if (!TEST_false(SSL_write_ex(clientssl, msg, sizeof(msg), &written)))
+ goto end;
+
+ if (tst < 4) {
+ /*
+ * For these tests the client has sent close_notify but it has not yet
+ * been received by the server. The server has not sent close_notify
+ * yet.
+ */
+ if (!TEST_int_eq(SSL_shutdown(serverssl), 0)
+ /*
+ * Writing on the server after sending close_notify shouldn't
+ * be possible.
+ */
+ || !TEST_false(SSL_write_ex(serverssl, msg, sizeof(msg), &written))
+ || !TEST_int_eq(SSL_shutdown(clientssl), 1)
+ || !TEST_ptr_ne(sess = SSL_get_session(clientssl), NULL)
+ || !TEST_true(SSL_SESSION_is_resumable(sess))
+ || !TEST_int_eq(SSL_shutdown(serverssl), 1))
+ goto end;
+ } else if (tst == 4 || tst == 5) {
+ /*
+ * In this test the client has sent close_notify and it has been
+ * received by the server which has responded with a close_notify. The
+ * client needs to read the close_notify sent by the server.
+ */
+ if (!TEST_int_eq(SSL_shutdown(clientssl), 1)
+ || !TEST_ptr_ne(sess = SSL_get_session(clientssl), NULL)
+ || !TEST_true(SSL_SESSION_is_resumable(sess)))
+ goto end;
+ } else {
+ /*
+ * tst == 6
+ *
+ * The client has sent close_notify and is expecting a close_notify
+ * back, but instead there is application data first. The shutdown
+ * should fail with a fatal error.
+ */
+ if (!TEST_int_eq(SSL_shutdown(clientssl), -1)
+ || !TEST_int_eq(SSL_get_error(clientssl, -1), SSL_ERROR_SSL))
+ goto end;
+ }
+
+ testresult = 1;
+
+ end:
+ SSL_free(serverssl);
+ SSL_free(clientssl);
+ SSL_CTX_free(sctx);
+ SSL_CTX_free(cctx);
+
+ return testresult;
+}
+
+#if !defined(OPENSSL_NO_TLS1_2) || !defined(OPENSSL_NO_TLS1_3)
+static int cert_cb_cnt;
+
+static int cert_cb(SSL *s, void *arg)
+{
+ SSL_CTX *ctx = (SSL_CTX *)arg;
+
+ if (cert_cb_cnt == 0) {
+ /* Suspend the handshake */
+ cert_cb_cnt++;
+ return -1;
+ } else if (cert_cb_cnt == 1) {
+ /*
+ * Update the SSL_CTX, set the certificate and private key and then
+ * continue the handshake normally.
+ */
+ if (ctx != NULL && !TEST_ptr(SSL_set_SSL_CTX(s, ctx)))
+ return 0;
+
+ if (!TEST_true(SSL_use_certificate_file(s, cert, SSL_FILETYPE_PEM))
+ || !TEST_true(SSL_use_PrivateKey_file(s, privkey,
+ SSL_FILETYPE_PEM))
+ || !TEST_true(SSL_check_private_key(s)))
+ return 0;
+ cert_cb_cnt++;
+ return 1;
+ }
+
+ /* Abort the handshake */
+ return 0;
+}
+
+/*
+ * Test the certificate callback.
+ * Test 0: Callback fails
+ * Test 1: Success - no SSL_set_SSL_CTX() in the callback
+ * Test 2: Success - SSL_set_SSL_CTX() in the callback
+ */
+static int test_cert_cb_int(int prot, int tst)
+{
+ SSL_CTX *cctx = NULL, *sctx = NULL, *snictx = NULL;
+ SSL *clientssl = NULL, *serverssl = NULL;
+ int testresult = 0, ret;
+
+ if (!TEST_true(create_ssl_ctx_pair(TLS_server_method(),
+ TLS_client_method(),
+ TLS1_VERSION,
+ prot,
+ &sctx, &cctx, NULL, NULL)))
+ goto end;
+
+ if (tst == 0)
+ cert_cb_cnt = -1;
+ else
+ cert_cb_cnt = 0;
+ if (tst == 2)
+ snictx = SSL_CTX_new(TLS_server_method());
+ SSL_CTX_set_cert_cb(sctx, cert_cb, snictx);
+
+ if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl,
+ NULL, NULL)))
+ goto end;
+
+ ret = create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE);
+ if (!TEST_true(tst == 0 ? !ret : ret)
+ || (tst > 0 && !TEST_int_eq(cert_cb_cnt, 2))) {
+ goto end;
+ }
+
+ testresult = 1;
+
+ end:
+ SSL_free(serverssl);
+ SSL_free(clientssl);
+ SSL_CTX_free(sctx);
+ SSL_CTX_free(cctx);
+ SSL_CTX_free(snictx);
+
+ return testresult;
+}
+#endif
+
+static int test_cert_cb(int tst)
+{
+ int testresult = 1;
+
+#ifndef OPENSSL_NO_TLS1_2
+ testresult &= test_cert_cb_int(TLS1_2_VERSION, tst);
+#endif
+#ifndef OPENSSL_NO_TLS1_3
+ testresult &= test_cert_cb_int(TLS1_3_VERSION, tst);
+#endif
+
+ return testresult;
+}
+
+static int client_cert_cb(SSL *ssl, X509 **x509, EVP_PKEY **pkey)
+{
+ X509 *xcert, *peer;
+ EVP_PKEY *privpkey;
+ BIO *in = NULL;
+
+ /* Check that SSL_get_peer_certificate() returns something sensible */
+ peer = SSL_get_peer_certificate(ssl);
+ if (!TEST_ptr(peer))
+ return 0;
+ X509_free(peer);
+
+ in = BIO_new_file(cert, "r");
+ if (!TEST_ptr(in))
+ return 0;
+
+ xcert = PEM_read_bio_X509(in, NULL, NULL, NULL);
+ BIO_free(in);
+ if (!TEST_ptr(xcert))
+ return 0;
+
+ in = BIO_new_file(privkey, "r");
+ if (!TEST_ptr(in)) {
+ X509_free(xcert);
+ return 0;
+ }
+
+ privpkey = PEM_read_bio_PrivateKey(in, NULL, NULL, NULL);
+ BIO_free(in);
+ if (!TEST_ptr(privpkey)) {
+ X509_free(xcert);
+ return 0;
+ }
+
+ *x509 = xcert;
+ *pkey = privpkey;
+
+ return 1;
+}
+
+static int verify_cb(int preverify_ok, X509_STORE_CTX *x509_ctx)
+{
+ return 1;
+}
+
+static int test_client_cert_cb(int tst)
+{
+ SSL_CTX *cctx = NULL, *sctx = NULL;
+ SSL *clientssl = NULL, *serverssl = NULL;
+ int testresult = 0;
+
+#ifdef OPENSSL_NO_TLS1_2
+ if (tst == 0)
+ return 1;
+#endif
+#ifdef OPENSSL_NO_TLS1_3
+ if (tst == 1)
+ return 1;
+#endif
+
+ if (!TEST_true(create_ssl_ctx_pair(TLS_server_method(),
+ TLS_client_method(),
+ TLS1_VERSION,
+ tst == 0 ? TLS1_2_VERSION
+ : TLS1_3_VERSION,
+ &sctx, &cctx, cert, privkey)))
+ goto end;
+
+ /*
+ * Test that setting a client_cert_cb results in a client certificate being
+ * sent.
+ */
+ SSL_CTX_set_client_cert_cb(cctx, client_cert_cb);
+ SSL_CTX_set_verify(sctx,
+ SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
+ verify_cb);
+
+ if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl,
+ NULL, NULL))
+ || !TEST_true(create_ssl_connection(serverssl, clientssl,
+ SSL_ERROR_NONE)))
+ goto end;
+
+ testresult = 1;
+
+ end:
+ SSL_free(serverssl);
+ SSL_free(clientssl);
+ SSL_CTX_free(sctx);
+ SSL_CTX_free(cctx);
+
+ return testresult;
+}
+
+#if !defined(OPENSSL_NO_TLS1_2) || !defined(OPENSSL_NO_TLS1_3)
+/*
+ * Test setting certificate authorities on both client and server.
+ *
+ * Test 0: SSL_CTX_set0_CA_list() only
+ * Test 1: Both SSL_CTX_set0_CA_list() and SSL_CTX_set_client_CA_list()
+ * Test 2: Only SSL_CTX_set_client_CA_list()
+ */
+static int test_ca_names_int(int prot, int tst)
+{
+ SSL_CTX *cctx = NULL, *sctx = NULL;
+ SSL *clientssl = NULL, *serverssl = NULL;
+ int testresult = 0;
+ size_t i;
+ X509_NAME *name[] = { NULL, NULL, NULL, NULL };
+ char *strnames[] = { "Jack", "Jill", "John", "Joanne" };
+ STACK_OF(X509_NAME) *sk1 = NULL, *sk2 = NULL;
+ const STACK_OF(X509_NAME) *sktmp = NULL;
+
+ for (i = 0; i < OSSL_NELEM(name); i++) {
+ name[i] = X509_NAME_new();
+ if (!TEST_ptr(name[i])
+ || !TEST_true(X509_NAME_add_entry_by_txt(name[i], "CN",
+ MBSTRING_ASC,
+ (unsigned char *)
+ strnames[i],
+ -1, -1, 0)))
+ goto end;
+ }
+
+ if (!TEST_true(create_ssl_ctx_pair(TLS_server_method(),
+ TLS_client_method(),
+ TLS1_VERSION,
+ prot,
+ &sctx, &cctx, cert, privkey)))
+ goto end;
+
+ SSL_CTX_set_verify(sctx, SSL_VERIFY_PEER, NULL);
+
+ if (tst == 0 || tst == 1) {
+ if (!TEST_ptr(sk1 = sk_X509_NAME_new_null())
+ || !TEST_true(sk_X509_NAME_push(sk1, X509_NAME_dup(name[0])))
+ || !TEST_true(sk_X509_NAME_push(sk1, X509_NAME_dup(name[1])))
+ || !TEST_ptr(sk2 = sk_X509_NAME_new_null())
+ || !TEST_true(sk_X509_NAME_push(sk2, X509_NAME_dup(name[0])))
+ || !TEST_true(sk_X509_NAME_push(sk2, X509_NAME_dup(name[1]))))
+ goto end;
+
+ SSL_CTX_set0_CA_list(sctx, sk1);
+ SSL_CTX_set0_CA_list(cctx, sk2);
+ sk1 = sk2 = NULL;
+ }
+ if (tst == 1 || tst == 2) {
+ if (!TEST_ptr(sk1 = sk_X509_NAME_new_null())
+ || !TEST_true(sk_X509_NAME_push(sk1, X509_NAME_dup(name[2])))
+ || !TEST_true(sk_X509_NAME_push(sk1, X509_NAME_dup(name[3])))
+ || !TEST_ptr(sk2 = sk_X509_NAME_new_null())
+ || !TEST_true(sk_X509_NAME_push(sk2, X509_NAME_dup(name[2])))
+ || !TEST_true(sk_X509_NAME_push(sk2, X509_NAME_dup(name[3]))))
+ goto end;
+
+ SSL_CTX_set_client_CA_list(sctx, sk1);
+ SSL_CTX_set_client_CA_list(cctx, sk2);
+ sk1 = sk2 = NULL;
+ }
+
+ if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl,
+ NULL, NULL))
+ || !TEST_true(create_ssl_connection(serverssl, clientssl,
+ SSL_ERROR_NONE)))
+ goto end;
+
+ /*
+ * We only expect certificate authorities to have been sent to the server
+ * if we are using TLSv1.3 and SSL_set0_CA_list() was used
+ */
+ sktmp = SSL_get0_peer_CA_list(serverssl);
+ if (prot == TLS1_3_VERSION
+ && (tst == 0 || tst == 1)) {
+ if (!TEST_ptr(sktmp)
+ || !TEST_int_eq(sk_X509_NAME_num(sktmp), 2)
+ || !TEST_int_eq(X509_NAME_cmp(sk_X509_NAME_value(sktmp, 0),
+ name[0]), 0)
+ || !TEST_int_eq(X509_NAME_cmp(sk_X509_NAME_value(sktmp, 1),
+ name[1]), 0))
+ goto end;
+ } else if (!TEST_ptr_null(sktmp)) {
+ goto end;
+ }
+
+ /*
+ * In all tests we expect certificate authorities to have been sent to the
+ * client. However, SSL_set_client_CA_list() should override
+ * SSL_set0_CA_list()
+ */
+ sktmp = SSL_get0_peer_CA_list(clientssl);
+ if (!TEST_ptr(sktmp)
+ || !TEST_int_eq(sk_X509_NAME_num(sktmp), 2)
+ || !TEST_int_eq(X509_NAME_cmp(sk_X509_NAME_value(sktmp, 0),
+ name[tst == 0 ? 0 : 2]), 0)
+ || !TEST_int_eq(X509_NAME_cmp(sk_X509_NAME_value(sktmp, 1),
+ name[tst == 0 ? 1 : 3]), 0))
+ goto end;
+
+ testresult = 1;
+
+ end:
+ SSL_free(serverssl);
+ SSL_free(clientssl);
+ SSL_CTX_free(sctx);
+ SSL_CTX_free(cctx);
+ for (i = 0; i < OSSL_NELEM(name); i++)
+ X509_NAME_free(name[i]);
+ sk_X509_NAME_pop_free(sk1, X509_NAME_free);
+ sk_X509_NAME_pop_free(sk2, X509_NAME_free);
+
+ return testresult;
+}
+#endif
+
+static int test_ca_names(int tst)
+{
+ int testresult = 1;
+
+#ifndef OPENSSL_NO_TLS1_2
+ testresult &= test_ca_names_int(TLS1_2_VERSION, tst);
+#endif
+#ifndef OPENSSL_NO_TLS1_3
+ testresult &= test_ca_names_int(TLS1_3_VERSION, tst);
+#endif
+
+ return testresult;
+}
+
int setup_tests(void)
{
if (!TEST_ptr(cert = test_get_argument(0))
#endif
}
+#if !defined(OPENSSL_NO_TLS1_2) && !defined(OPENSSL_NO_KTLS)
+ ADD_TEST(test_ktls_client_server);
+ ADD_TEST(test_ktls_no_client_server);
+ ADD_TEST(test_ktls_client_no_server);
+ ADD_TEST(test_ktls_no_client_no_server);
+#endif
ADD_TEST(test_large_message_tls);
ADD_TEST(test_large_message_tls_read_ahead);
#ifndef OPENSSL_NO_DTLS
ADD_TEST(test_session_with_only_int_cache);
ADD_TEST(test_session_with_only_ext_cache);
ADD_TEST(test_session_with_both_cache);
+#ifndef OPENSSL_NO_TLS1_3
+ ADD_ALL_TESTS(test_stateful_tickets, 3);
+ ADD_ALL_TESTS(test_stateless_tickets, 3);
+ ADD_TEST(test_psk_tickets);
+#endif
ADD_ALL_TESTS(test_ssl_set_bio, TOTAL_SSL_SET_BIO_TESTS);
ADD_TEST(test_ssl_bio_pop_next_bio);
ADD_TEST(test_ssl_bio_pop_ssl_bio);
ADD_ALL_TESTS(test_early_data_replay, 2);
ADD_ALL_TESTS(test_early_data_skip, 3);
ADD_ALL_TESTS(test_early_data_skip_hrr, 3);
+ ADD_ALL_TESTS(test_early_data_skip_hrr_fail, 3);
+ ADD_ALL_TESTS(test_early_data_skip_abort, 3);
ADD_ALL_TESTS(test_early_data_not_sent, 3);
ADD_ALL_TESTS(test_early_data_psk, 8);
ADD_ALL_TESTS(test_early_data_not_expected, 3);
ADD_ALL_TESTS(test_custom_exts, 3);
#endif
ADD_ALL_TESTS(test_serverinfo, 8);
- ADD_ALL_TESTS(test_export_key_mat, 4);
+ ADD_ALL_TESTS(test_export_key_mat, 6);
#ifndef OPENSSL_NO_TLS1_3
ADD_ALL_TESTS(test_export_key_mat_early, 3);
#endif
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);
+ ADD_ALL_TESTS(test_shutdown, 7);
+ ADD_ALL_TESTS(test_cert_cb, 3);
+ ADD_ALL_TESTS(test_client_cert_cb, 2);
+ ADD_ALL_TESTS(test_ca_names, 3);
return 1;
}