X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=test%2Fsslapitest.c;h=3dcf7353259ab5260871d00c50ccd85add3f88ee;hp=f7b0ad8dc11c6a792395d6f373535010eac44986;hb=5281435258b5d8201a00b4a9781bb724d99630f0;hpb=3cb6a4d6d66d566937c08d2d3fc933275e70f73e diff --git a/test/sslapitest.c b/test/sslapitest.c index f7b0ad8dc1..3dcf735325 100644 --- a/test/sslapitest.c +++ b/test/sslapitest.c @@ -1,5 +1,5 @@ /* - * Copyright 2016-2017 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the OpenSSL license (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -17,7 +17,8 @@ #include "ssltestlib.h" #include "testutil.h" -#include "e_os.h" +#include "testutil/output.h" +#include "internal/nelem.h" #include "../ssl/ssl_locl.h" static char *cert = NULL; @@ -40,6 +41,7 @@ static X509 *ocspcert = NULL; #endif #define NUM_EXTRA_CERTS 40 +#define CLIENT_VERSION_LEN 2 /* * This structure is used to validate that the correct number of log messages @@ -91,7 +93,7 @@ static void server_keylog_callback(const SSL *ssl, const char *line) /* If the log doesn't fit, error out. */ if (server_log_buffer_index + line_length > sizeof(server_log_buffer) - 1) { - TEST_info("Server og too full"); + TEST_info("Server log too full"); error_writing_log = 1; return; } @@ -253,6 +255,7 @@ static int test_keylog_output(char *buffer, const SSL *ssl, return 1; } +#if !defined(OPENSSL_NO_TLS1_2) || defined(OPENSSL_NO_TLS1_3) static int test_keylog(void) { SSL_CTX *cctx = NULL, *sctx = NULL; @@ -269,6 +272,7 @@ static int test_keylog(void) if (!TEST_true(create_ssl_ctx_pair(TLS_server_method(), TLS_client_method(), + TLS1_VERSION, TLS_MAX_VERSION, &sctx, &cctx, cert, privkey))) return 0; @@ -329,6 +333,7 @@ end: return testresult; } +#endif #ifndef OPENSSL_NO_TLS1_3 static int test_keylog_no_master_key(void) @@ -345,9 +350,9 @@ static int test_keylog_no_master_key(void) server_log_buffer_index = 0; error_writing_log = 0; - if (!TEST_true(create_ssl_ctx_pair(TLS_server_method(), - TLS_client_method(), &sctx, - &cctx, cert, privkey))) + 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 (!TEST_true(SSL_CTX_get_keylog_callback(cctx) == NULL) @@ -401,7 +406,7 @@ end: #endif #ifndef OPENSSL_NO_TLS1_2 -static int full_early_callback(SSL *s, int *al, void *arg) +static int full_client_hello_callback(SSL *s, int *al, void *arg) { int *ctr = arg; const unsigned char *p; @@ -417,41 +422,42 @@ static int full_early_callback(SSL *s, int *al, void *arg) #ifndef OPENSSL_NO_EC 11, 10, #endif - 35, 13, 22, 23}; + 35, 22, 23, 13}; size_t len; /* Make sure we can defer processing and get called back. */ if ((*ctr)++ == 0) - return -1; + return SSL_CLIENT_HELLO_RETRY; - len = SSL_early_get0_ciphers(s, &p); + len = SSL_client_hello_get0_ciphers(s, &p); if (!TEST_mem_eq(p, len, expected_ciphers, sizeof(expected_ciphers)) - || !TEST_size_t_eq(SSL_early_get0_compression_methods(s, &p), 1) + || !TEST_size_t_eq( + SSL_client_hello_get0_compression_methods(s, &p), 1) || !TEST_int_eq(*p, 0)) - return 0; - if (!SSL_early_get1_extensions_present(s, &exts, &len)) - return 0; + return SSL_CLIENT_HELLO_ERROR; + if (!SSL_client_hello_get1_extensions_present(s, &exts, &len)) + return SSL_CLIENT_HELLO_ERROR; if (len != OSSL_NELEM(expected_extensions) || memcmp(exts, expected_extensions, len * sizeof(*exts)) != 0) { - printf("Early callback expected ClientHello extensions mismatch\n"); + printf("ClientHello callback expected extensions mismatch\n"); OPENSSL_free(exts); - return 0; + return SSL_CLIENT_HELLO_ERROR; } OPENSSL_free(exts); - return 1; + return SSL_CLIENT_HELLO_SUCCESS; } -static int test_early_cb(void) +static int test_client_hello_cb(void) { SSL_CTX *cctx = NULL, *sctx = NULL; SSL *clientssl = NULL, *serverssl = NULL; int testctr = 0, testresult = 0; - if (!TEST_true(create_ssl_ctx_pair(TLS_server_method(), - TLS_client_method(), &sctx, - &cctx, cert, privkey))) + 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_CTX_set_early_cb(sctx, full_early_callback, &testctr); + SSL_CTX_set_client_hello_cb(sctx, full_client_hello_callback, &testctr); /* The gimpy cipher list we configure can't do TLS 1.3. */ SSL_CTX_set_max_proto_version(cctx, TLS1_2_VERSION); @@ -461,12 +467,13 @@ static int test_early_cb(void) || !TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl, NULL, NULL)) || !TEST_false(create_ssl_connection(serverssl, clientssl, - SSL_ERROR_WANT_EARLY)) + SSL_ERROR_WANT_CLIENT_HELLO_CB)) /* * Passing a -1 literal is a hack since * the real value was lost. * */ - || !TEST_int_eq(SSL_get_error(serverssl, -1), SSL_ERROR_WANT_EARLY) + || !TEST_int_eq(SSL_get_error(serverssl, -1), + SSL_ERROR_WANT_CLIENT_HELLO_CB) || !TEST_true(create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE))) goto end; @@ -484,7 +491,9 @@ end: #endif static int execute_test_large_message(const SSL_METHOD *smeth, - const SSL_METHOD *cmeth, int read_ahead) + const SSL_METHOD *cmeth, + int min_version, int max_version, + int read_ahead) { SSL_CTX *cctx = NULL, *sctx = NULL; SSL *clientssl = NULL, *serverssl = NULL; @@ -502,8 +511,8 @@ static int execute_test_large_message(const SSL_METHOD *smeth, if (!TEST_ptr(chaincert)) goto end; - if (!TEST_true(create_ssl_ctx_pair(smeth, cmeth, &sctx, - &cctx, cert, privkey))) + if (!TEST_true(create_ssl_ctx_pair(smeth, cmeth, min_version, max_version, + &sctx, &cctx, cert, privkey))) goto end; if (read_ahead) { @@ -560,12 +569,14 @@ static int execute_test_large_message(const SSL_METHOD *smeth, static int test_large_message_tls(void) { return execute_test_large_message(TLS_server_method(), TLS_client_method(), + TLS1_VERSION, TLS_MAX_VERSION, 0); } static int test_large_message_tls_read_ahead(void) { return execute_test_large_message(TLS_server_method(), TLS_client_method(), + TLS1_VERSION, TLS_MAX_VERSION, 1); } @@ -577,7 +588,9 @@ static int test_large_message_dtls(void) * read_ahead is set. */ return execute_test_large_message(DTLS_server_method(), - DTLS_client_method(), 0); + DTLS_client_method(), + DTLS1_VERSION, DTLS_MAX_VERSION, + 0); } #endif @@ -636,8 +649,9 @@ static int test_tlsext_status_type(void) OCSP_RESPID *id = NULL; BIO *certbio = NULL; - if (!create_ssl_ctx_pair(TLS_server_method(), TLS_client_method(), &sctx, - &cctx, cert, privkey)) + if (!create_ssl_ctx_pair(TLS_server_method(), TLS_client_method(), + TLS1_VERSION, TLS_MAX_VERSION, + &sctx, &cctx, cert, privkey)) return 0; if (SSL_CTX_get_tlsext_status_type(cctx) != -1) @@ -757,7 +771,8 @@ static int test_tlsext_status_type(void) } #endif -static int new_called = 0, remove_called = 0; +#if !defined(OPENSSL_NO_TLS1_3) || !defined(OPENSSL_NO_TLS1_2) +static int new_called, remove_called, get_called; static int new_session_cb(SSL *ssl, SSL_SESSION *sess) { @@ -780,28 +795,28 @@ static SSL_SESSION *get_sess_val = NULL; static SSL_SESSION *get_session_cb(SSL *ssl, const unsigned char *id, int len, int *copy) { + get_called++; *copy = 1; return get_sess_val; } - static int execute_test_session(int maxprot, int use_int_cache, int use_ext_cache) { SSL_CTX *sctx = NULL, *cctx = NULL; SSL *serverssl1 = NULL, *clientssl1 = NULL; SSL *serverssl2 = NULL, *clientssl2 = NULL; -#ifndef OPENSSL_NO_TLS1_1 +# ifndef OPENSSL_NO_TLS1_1 SSL *serverssl3 = NULL, *clientssl3 = NULL; -#endif +# endif SSL_SESSION *sess1 = NULL, *sess2 = NULL; int testresult = 0; new_called = remove_called = 0; - if (!TEST_true(create_ssl_ctx_pair(TLS_server_method(), - TLS_client_method(), &sctx, - &cctx, cert, privkey))) + if (!TEST_true(create_ssl_ctx_pair(TLS_server_method(), TLS_client_method(), + TLS1_VERSION, TLS_MAX_VERSION, + &sctx, &cctx, cert, privkey))) return 0; /* @@ -917,7 +932,7 @@ static int execute_test_session(int maxprot, int use_int_cache, && (!TEST_int_eq(new_called, 0) || !TEST_int_eq(remove_called, 1))) goto end; -#if !defined(OPENSSL_NO_TLS1_1) +# if !defined(OPENSSL_NO_TLS1_1) new_called = remove_called = 0; /* Force a connection failure */ SSL_CTX_set_max_proto_version(sctx, TLS1_1_VERSION); @@ -937,7 +952,7 @@ static int execute_test_session(int maxprot, int use_int_cache, /* Should succeed because it should not already be in the cache */ if (use_int_cache && !TEST_true(SSL_CTX_add_session(cctx, sess2))) goto end; -#endif +# endif /* Now do some tests for server side caching */ if (use_ext_cache) { @@ -969,7 +984,7 @@ static int execute_test_session(int maxprot, int use_int_cache, SSL_CTX_set_max_proto_version(sctx, maxprot); SSL_CTX_set_options(sctx, SSL_OP_NO_TICKET); - new_called = remove_called = 0; + new_called = remove_called = get_called = 0; if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl1, &clientssl1, NULL, NULL)) || !TEST_true(create_ssl_connection(serverssl1, clientssl1, @@ -985,7 +1000,9 @@ static int execute_test_session(int maxprot, int use_int_cache, if (use_ext_cache) { SSL_SESSION *tmp = sess2; - if (!TEST_int_eq(new_called, 1) || !TEST_int_eq(remove_called, 0)) + if (!TEST_int_eq(new_called, 1) + || !TEST_int_eq(remove_called, 0) + || !TEST_int_eq(get_called, 0)) goto end; /* * Delete the session from the internal cache to force a lookup from @@ -1001,7 +1018,7 @@ static int execute_test_session(int maxprot, int use_int_cache, sess2 = tmp; } - new_called = remove_called = 0; + new_called = remove_called = get_called = 0; get_sess_val = sess2; if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl2, &clientssl2, NULL, NULL)) @@ -1011,10 +1028,24 @@ static int execute_test_session(int maxprot, int use_int_cache, || !TEST_true(SSL_session_reused(clientssl2))) goto end; - if (use_ext_cache - && (!TEST_int_eq(new_called, 0) - || !TEST_int_eq(remove_called, 0))) - goto end; + if (use_ext_cache) { + if (!TEST_int_eq(remove_called, 0)) + 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; + } else { + if (!TEST_int_eq(new_called, 0) + || !TEST_int_eq(get_called, 1)) + goto end; + } + } testresult = 1; @@ -1023,10 +1054,10 @@ static int execute_test_session(int maxprot, int use_int_cache, SSL_free(clientssl1); SSL_free(serverssl2); SSL_free(clientssl2); -#ifndef OPENSSL_NO_TLS1_1 +# ifndef OPENSSL_NO_TLS1_1 SSL_free(serverssl3); SSL_free(clientssl3); -#endif +# endif SSL_SESSION_free(sess1); SSL_SESSION_free(sess2); SSL_CTX_free(sctx); @@ -1034,6 +1065,7 @@ static int execute_test_session(int maxprot, int use_int_cache, return testresult; } +#endif /* !defined(OPENSSL_NO_TLS1_3) || !defined(OPENSSL_NO_TLS1_2) */ static int test_session_with_only_int_cache(void) { @@ -1257,6 +1289,7 @@ static int test_ssl_bio_change_wbio(void) return execute_test_ssl_bio(0, CHANGE_WBIO); } +#if !defined(OPENSSL_NO_TLS1_2) || defined(OPENSSL_NO_TLS1_3) typedef struct { /* The list of sig algs */ const int *list; @@ -1271,25 +1304,25 @@ typedef struct { } sigalgs_list; static const int validlist1[] = {NID_sha256, EVP_PKEY_RSA}; -#ifndef OPENSSL_NO_EC +# ifndef OPENSSL_NO_EC static const int validlist2[] = {NID_sha256, EVP_PKEY_RSA, NID_sha512, EVP_PKEY_EC}; static const int validlist3[] = {NID_sha512, EVP_PKEY_EC}; -#endif +# endif static const int invalidlist1[] = {NID_undef, EVP_PKEY_RSA}; static const int invalidlist2[] = {NID_sha256, NID_undef}; static const int invalidlist3[] = {NID_sha256, EVP_PKEY_RSA, NID_sha256}; static const int invalidlist4[] = {NID_sha256}; static const sigalgs_list testsigalgs[] = { {validlist1, OSSL_NELEM(validlist1), NULL, 1, 1}, -#ifndef OPENSSL_NO_EC +# ifndef OPENSSL_NO_EC {validlist2, OSSL_NELEM(validlist2), NULL, 1, 1}, {validlist3, OSSL_NELEM(validlist3), NULL, 1, 0}, -#endif +# endif {NULL, 0, "RSA+SHA256", 1, 1}, -#ifndef OPENSSL_NO_EC +# ifndef OPENSSL_NO_EC {NULL, 0, "RSA+SHA256:ECDSA+SHA512", 1, 1}, {NULL, 0, "ECDSA+SHA512", 1, 0}, -#endif +# endif {invalidlist1, OSSL_NELEM(invalidlist1), NULL, 0, 0}, {invalidlist2, OSSL_NELEM(invalidlist2), NULL, 0, 0}, {invalidlist3, OSSL_NELEM(invalidlist3), NULL, 0, 0}, @@ -1316,9 +1349,9 @@ static int test_set_sigalgs(int idx) curr = testctx ? &testsigalgs[idx] : &testsigalgs[idx - OSSL_NELEM(testsigalgs)]; - if (!TEST_true(create_ssl_ctx_pair(TLS_server_method(), - TLS_client_method(), &sctx, - &cctx, cert, privkey))) + if (!TEST_true(create_ssl_ctx_pair(TLS_server_method(), TLS_client_method(), + TLS1_VERSION, TLS_MAX_VERSION, + &sctx, &cctx, cert, privkey))) return 0; /* @@ -1385,9 +1418,136 @@ static int test_set_sigalgs(int idx) return testresult; } +#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; + +static int use_session_cb(SSL *ssl, const EVP_MD *md, const unsigned char **id, + size_t *idlen, SSL_SESSION **sess) +{ + switch (++use_session_cb_cnt) { + case 1: + /* The first call should always have a NULL md */ + if (md != NULL) + return 0; + break; + + case 2: + /* The second call should always have an md */ + if (md == NULL) + return 0; + break; + + default: + /* We should only be called a maximum of twice */ + return 0; + } + + if (clientpsk != NULL) + SSL_SESSION_up_ref(clientpsk); + + *sess = clientpsk; + *id = (const unsigned char *)pskid; + *idlen = strlen(pskid); + + return 1; +} + +#ifndef OPENSSL_NO_PSK +static unsigned int psk_client_cb(SSL *ssl, const char *hint, char *id, + unsigned int max_id_len, + unsigned char *psk, + unsigned int max_psk_len) +{ + unsigned int psklen = 0; + + psk_client_cb_cnt++; + + if (strlen(pskid) + 1 > max_id_len) + return 0; + + /* We should only ever be called a maximum of twice per connection */ + if (psk_client_cb_cnt > 2) + return 0; + + if (clientpsk == NULL) + return 0; + + /* We'll reuse the PSK we set up for TLSv1.3 */ + if (SSL_SESSION_get_master_key(clientpsk, NULL, 0) > max_psk_len) + return 0; + psklen = SSL_SESSION_get_master_key(clientpsk, psk, max_psk_len); + strncpy(id, pskid, max_id_len); + + return psklen; +} +#endif /* OPENSSL_NO_PSK */ + +static int find_session_cb(SSL *ssl, const unsigned char *identity, + size_t identity_len, SSL_SESSION **sess) +{ + find_session_cb_cnt++; + + /* We should only ever be called a maximum of twice per connection */ + if (find_session_cb_cnt > 2) + return 0; + + if (serverpsk == NULL) + return 0; + + /* Identity should match that set by the client */ + if (strlen(srvid) != identity_len + || strncmp(srvid, (const char *)identity, identity_len) != 0) { + /* No PSK found, continue but without a PSK */ + *sess = NULL; + return 1; + } + + SSL_SESSION_up_ref(serverpsk); + *sess = serverpsk; + + return 1; +} + +#ifndef OPENSSL_NO_PSK +static unsigned int psk_server_cb(SSL *ssl, const char *identity, + unsigned char *psk, unsigned int max_psk_len) +{ + unsigned int psklen = 0; + + psk_server_cb_cnt++; + + /* We should only ever be called a maximum of twice per connection */ + if (find_session_cb_cnt > 2) + return 0; + + if (serverpsk == NULL) + return 0; + + /* Identity should match that set by the client */ + if (strcmp(srvid, identity) != 0) { + return 0; + } + + /* We'll reuse the PSK we set up for TLSv1.3 */ + if (SSL_SESSION_get_master_key(serverpsk, NULL, 0) > max_psk_len) + return 0; + psklen = SSL_SESSION_get_master_key(serverpsk, psk, max_psk_len); + + return psklen; +} +#endif /* OPENSSL_NO_PSK */ + #define MSG1 "Hello" #define MSG2 "World." #define MSG3 "This" @@ -1396,6 +1556,9 @@ static int test_set_sigalgs(int idx) #define MSG6 "test" #define MSG7 "message." +#define TLS13_AES_256_GCM_SHA384_BYTES ((const unsigned char *)"\x13\x02") +#define TLS13_AES_128_GCM_SHA256_BYTES ((const unsigned char *)"\x13\x01") + /* * Helper method to setup objects for early data test. Caller frees objects on * error. @@ -1403,21 +1566,86 @@ static int test_set_sigalgs(int idx) 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(), sctx, - cctx, cert, privkey))) + 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)) + || !TEST_true(SSL_CTX_set_max_early_data(*cctx, + SSL3_RT_MAX_PLAIN_LENGTH))) return 0; - /* When idx == 1 we repeat the tests with read_ahead set */ - if (idx > 0) { + if (idx == 1) { + /* When idx == 1 we repeat the tests with read_ahead set */ SSL_CTX_set_read_ahead(*cctx, 1); SSL_CTX_set_read_ahead(*sctx, 1); + } else if (idx == 2) { + /* When idx == 2 we are doing early_data with a PSK. Set up callbacks */ + SSL_CTX_set_psk_use_session_callback(*cctx, use_session_cb); + SSL_CTX_set_psk_find_session_callback(*sctx, find_session_cb); + use_session_cb_cnt = 0; + find_session_cb_cnt = 0; + srvid = pskid; } if (!TEST_true(create_ssl_objects(*sctx, *cctx, serverssl, clientssl, - NULL, NULL)) - || !TEST_true(create_ssl_connection(*serverssl, *clientssl, - SSL_ERROR_NONE))) + NULL, NULL))) + return 0; + + /* + * For one of the run throughs (doesn't matter which one), we'll try sending + * some SNI data in the initial ClientHello. This will be ignored (because + * there is no SNI cb set up by the server), so it should not impact + * early_data. + */ + if (idx == 1 + && !TEST_true(SSL_set_tlsext_host_name(*clientssl, "localhost"))) + 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(); + 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. + */ + || !TEST_true(SSL_SESSION_set_max_early_data(clientpsk, + 0x100)) + || !TEST_true(SSL_SESSION_up_ref(clientpsk))) { + SSL_SESSION_free(clientpsk); + clientpsk = NULL; + return 0; + } + serverpsk = clientpsk; + + if (sess != NULL) + *sess = clientpsk; + return 1; + } + + if (sess == NULL) + return 1; + + if (!TEST_true(create_ssl_connection(*serverssl, *clientssl, + SSL_ERROR_NONE))) return 0; *sess = SSL_get1_session(*clientssl); @@ -1578,8 +1806,12 @@ static int test_early_data_read_write(int idx) || !TEST_mem_eq(buf, readbytes, MSG7, strlen(MSG7))) goto end; - SSL_SESSION_free(sess); + /* We keep the PSK session around if using PSK */ + if (idx != 2) + SSL_SESSION_free(sess); sess = SSL_get1_session(clientssl); + use_session_cb_cnt = 0; + find_session_cb_cnt = 0; SSL_shutdown(clientssl); SSL_shutdown(serverssl); @@ -1626,7 +1858,63 @@ static int test_early_data_read_write(int idx) testresult = 1; end: - SSL_SESSION_free(sess); + if (sess != clientpsk) + SSL_SESSION_free(sess); + SSL_SESSION_free(clientpsk); + SSL_SESSION_free(serverpsk); + clientpsk = serverpsk = NULL; + SSL_free(serverssl); + SSL_free(clientssl); + SSL_CTX_free(sctx); + SSL_CTX_free(cctx); + return testresult; +} + +static int test_early_data_replay(int idx) +{ + SSL_CTX *cctx = NULL, *sctx = NULL; + SSL *clientssl = NULL, *serverssl = NULL; + int testresult = 0; + SSL_SESSION *sess = NULL; + + if (!TEST_true(setupearly_data_test(&cctx, &sctx, &clientssl, + &serverssl, &sess, idx))) + goto end; + + /* + * The server is configured to accept early data. Create a connection to + * "use up" the ticket + */ + if (!TEST_true(create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE)) + || !TEST_true(SSL_session_reused(clientssl))) + goto end; + + SSL_shutdown(clientssl); + SSL_shutdown(serverssl); + SSL_free(serverssl); + SSL_free(clientssl); + serverssl = clientssl = NULL; + + 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))) + goto end; + + testresult = 1; + + end: + if (sess != clientpsk) + SSL_SESSION_free(sess); + SSL_SESSION_free(clientpsk); + SSL_SESSION_free(serverpsk); + clientpsk = serverpsk = NULL; SSL_free(serverssl); SSL_free(clientssl); SSL_CTX_free(sctx); @@ -1655,13 +1943,19 @@ static int early_data_skip_helper(int hrr, int idx) /* Force an HRR to occur */ if (!TEST_true(SSL_set1_groups_list(serverssl, "P-256"))) goto end; + } else if (idx == 2) { + /* + * We force early_data rejection by ensuring the PSK identity is + * unrecognised + */ + srvid = "Dummy Identity"; } else { /* * Deliberately corrupt the creation time. We take 20 seconds off the * time. It could be any value as long as it is not within tolerance. * This should mean the ticket is rejected. */ - if (!TEST_true(SSL_SESSION_set_time(sess, time(NULL) - 20))) + if (!TEST_true(SSL_SESSION_set_time(sess, (long)(time(NULL) - 20)))) goto end; } @@ -1704,6 +1998,10 @@ static int early_data_skip_helper(int hrr, int idx) testresult = 1; end: + if (sess != clientpsk) + SSL_SESSION_free(clientpsk); + SSL_SESSION_free(serverpsk); + clientpsk = serverpsk = NULL; SSL_SESSION_free(sess); SSL_free(serverssl); SSL_free(clientssl); @@ -1776,7 +2074,7 @@ static int test_early_data_not_sent(int idx) * Should block due to the NewSessionTicket arrival unless we're using * read_ahead */ - if (idx == 0) { + if (idx != 1) { if (!TEST_false(SSL_read_ex(clientssl, buf, sizeof(buf), &readbytes))) goto end; } @@ -1788,7 +2086,10 @@ 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(serverpsk); + clientpsk = serverpsk = NULL; SSL_free(serverssl); SSL_free(clientssl); SSL_CTX_free(sctx); @@ -1796,56 +2097,266 @@ static int test_early_data_not_sent(int idx) return testresult; } -/* - * Test that a server that doesn't try to read early data can handle a - * client sending some. - */ -static int test_early_data_not_expected(int idx) +static int hostname_cb(SSL *s, int *al, void *arg) +{ + const char *hostname = SSL_get_servername(s, TLSEXT_NAMETYPE_host_name); + + if (hostname != NULL && strcmp(hostname, "goodhost") == 0) + return SSL_TLSEXT_ERR_OK; + + return SSL_TLSEXT_ERR_NOACK; +} + +static const char *servalpn; + +static int alpn_select_cb(SSL *ssl, const unsigned char **out, + unsigned char *outlen, const unsigned char *in, + unsigned int inlen, void *arg) +{ + unsigned int protlen = 0; + const unsigned char *prot; + + for (prot = in; prot < in + inlen; prot += protlen) { + protlen = *prot++; + if (in + inlen < prot + protlen) + return SSL_TLSEXT_ERR_NOACK; + + if (protlen == strlen(servalpn) + && memcmp(prot, servalpn, protlen) == 0) { + *out = prot; + *outlen = protlen; + return SSL_TLSEXT_ERR_OK; + } + } + + return SSL_TLSEXT_ERR_NOACK; +} + +/* Test that a PSK can be used to send early_data */ +static int test_early_data_psk(int idx) { SSL_CTX *cctx = NULL, *sctx = NULL; SSL *clientssl = NULL, *serverssl = NULL; int testresult = 0; SSL_SESSION *sess = NULL; + unsigned char alpnlist[] = { + 0x08, 'g', 'o', 'o', 'd', 'a', 'l', 'p', 'n', 0x07, 'b', 'a', 'd', 'a', + 'l', 'p', 'n' + }; +#define GOODALPNLEN 9 +#define BADALPNLEN 8 +#define GOODALPN (alpnlist) +#define BADALPN (alpnlist + GOODALPNLEN) + int err = 0; unsigned char buf[20]; size_t readbytes, written; + int readearlyres = SSL_READ_EARLY_DATA_SUCCESS, connectres = 1; + int edstatus = SSL_EARLY_DATA_ACCEPTED; - + /* We always set this up with a final parameter of "2" for PSK */ if (!TEST_true(setupearly_data_test(&cctx, &sctx, &clientssl, - &serverssl, &sess, idx))) + &serverssl, &sess, 2))) goto end; - /* Write some early data */ - if (!TEST_true(SSL_write_early_data(clientssl, MSG1, strlen(MSG1), - &written))) - goto end; + servalpn = "goodalpn"; /* - * Server should skip over early data and then block waiting for client to - * continue handshake + * Note: There is no test for inconsistent SNI with late client detection. + * This is because servers do not acknowledge SNI even if they are using + * it in a resumption handshake - so it is not actually possible for a + * client to detect a problem. */ - if (!TEST_int_le(SSL_accept(serverssl), 0) - || !TEST_int_gt(SSL_connect(clientssl), 0) - || !TEST_int_eq(SSL_get_early_data_status(serverssl), - SSL_EARLY_DATA_REJECTED) - || !TEST_int_gt(SSL_accept(serverssl), 0) - || !TEST_int_eq(SSL_get_early_data_status(clientssl), - SSL_EARLY_DATA_REJECTED)) - goto end; - - /* Send some normal data from client to server */ - if (!TEST_true(SSL_write_ex(clientssl, MSG2, strlen(MSG2), &written)) - || !TEST_size_t_eq(written, strlen(MSG2))) - goto end; + switch (idx) { + case 0: + /* Set inconsistent SNI (early client detection) */ + err = SSL_R_INCONSISTENT_EARLY_DATA_SNI; + if (!TEST_true(SSL_SESSION_set1_hostname(sess, "goodhost")) + || !TEST_true(SSL_set_tlsext_host_name(clientssl, "badhost"))) + goto end; + break; - if (!TEST_true(SSL_read_ex(serverssl, buf, sizeof(buf), &readbytes)) - || !TEST_mem_eq(buf, readbytes, MSG2, strlen(MSG2))) - goto end; + case 1: + /* Set inconsistent ALPN (early client detection) */ + err = SSL_R_INCONSISTENT_EARLY_DATA_ALPN; + /* SSL_set_alpn_protos returns 0 for success and 1 for failure */ + if (!TEST_true(SSL_SESSION_set1_alpn_selected(sess, GOODALPN, + GOODALPNLEN)) + || !TEST_false(SSL_set_alpn_protos(clientssl, BADALPN, + BADALPNLEN))) + goto end; + break; - testresult = 1; + case 2: + /* + * Set invalid protocol version. Technically this affects PSKs without + * early_data too, but we test it here because it is similar to the + * SNI/ALPN consistency tests. + */ + err = SSL_R_BAD_PSK; + if (!TEST_true(SSL_SESSION_set_protocol_version(sess, TLS1_2_VERSION))) + goto end; + break; - end: - SSL_SESSION_free(sess); - SSL_free(serverssl); + case 3: + /* + * Set inconsistent SNI (server detected). In this case the connection + * will succeed but reject early_data. + */ + SSL_SESSION_free(serverpsk); + serverpsk = SSL_SESSION_dup(clientpsk); + if (!TEST_ptr(serverpsk) + || !TEST_true(SSL_SESSION_set1_hostname(serverpsk, "badhost"))) + goto end; + edstatus = SSL_EARLY_DATA_REJECTED; + readearlyres = SSL_READ_EARLY_DATA_FINISH; + /* Fall through */ + case 4: + /* Set consistent SNI */ + if (!TEST_true(SSL_SESSION_set1_hostname(sess, "goodhost")) + || !TEST_true(SSL_set_tlsext_host_name(clientssl, "goodhost")) + || !TEST_true(SSL_CTX_set_tlsext_servername_callback(sctx, + hostname_cb))) + goto end; + break; + + case 5: + /* + * Set inconsistent ALPN (server detected). In this case the connection + * will succeed but reject early_data. + */ + servalpn = "badalpn"; + edstatus = SSL_EARLY_DATA_REJECTED; + readearlyres = SSL_READ_EARLY_DATA_FINISH; + /* Fall through */ + case 6: + /* + * Set consistent ALPN. + * SSL_set_alpn_protos returns 0 for success and 1 for failure. It + * accepts a list of protos (each one length prefixed). + * SSL_set1_alpn_selected accepts a single protocol (not length + * prefixed) + */ + if (!TEST_true(SSL_SESSION_set1_alpn_selected(sess, GOODALPN + 1, + GOODALPNLEN - 1)) + || !TEST_false(SSL_set_alpn_protos(clientssl, GOODALPN, + GOODALPNLEN))) + goto end; + + SSL_CTX_set_alpn_select_cb(sctx, alpn_select_cb, NULL); + break; + + case 7: + /* Set inconsistent ALPN (late client detection) */ + SSL_SESSION_free(serverpsk); + serverpsk = SSL_SESSION_dup(clientpsk); + if (!TEST_ptr(serverpsk) + || !TEST_true(SSL_SESSION_set1_alpn_selected(clientpsk, + BADALPN + 1, + BADALPNLEN - 1)) + || !TEST_true(SSL_SESSION_set1_alpn_selected(serverpsk, + GOODALPN + 1, + GOODALPNLEN - 1)) + || !TEST_false(SSL_set_alpn_protos(clientssl, alpnlist, + sizeof(alpnlist)))) + goto end; + SSL_CTX_set_alpn_select_cb(sctx, alpn_select_cb, NULL); + edstatus = SSL_EARLY_DATA_ACCEPTED; + readearlyres = SSL_READ_EARLY_DATA_SUCCESS; + /* SSL_connect() call should fail */ + connectres = -1; + break; + + default: + TEST_error("Bad test index"); + goto end; + } + + SSL_set_connect_state(clientssl); + if (err != 0) { + if (!TEST_false(SSL_write_early_data(clientssl, MSG1, strlen(MSG1), + &written)) + || !TEST_int_eq(SSL_get_error(clientssl, 0), SSL_ERROR_SSL) + || !TEST_int_eq(ERR_GET_REASON(ERR_get_error()), err)) + goto end; + } else { + if (!TEST_true(SSL_write_early_data(clientssl, MSG1, strlen(MSG1), + &written))) + goto end; + + if (!TEST_int_eq(SSL_read_early_data(serverssl, buf, sizeof(buf), + &readbytes), readearlyres) + || (readearlyres == SSL_READ_EARLY_DATA_SUCCESS + && !TEST_mem_eq(buf, readbytes, MSG1, strlen(MSG1))) + || !TEST_int_eq(SSL_get_early_data_status(serverssl), edstatus) + || !TEST_int_eq(SSL_connect(clientssl), connectres)) + goto end; + } + + testresult = 1; + + end: + SSL_SESSION_free(clientpsk); + SSL_SESSION_free(serverpsk); + clientpsk = serverpsk = NULL; + SSL_free(serverssl); + SSL_free(clientssl); + SSL_CTX_free(sctx); + SSL_CTX_free(cctx); + return testresult; +} + +/* + * Test that a server that doesn't try to read early data can handle a + * client sending some. + */ +static int test_early_data_not_expected(int idx) +{ + SSL_CTX *cctx = NULL, *sctx = NULL; + SSL *clientssl = NULL, *serverssl = NULL; + int testresult = 0; + SSL_SESSION *sess = NULL; + unsigned char buf[20]; + size_t readbytes, written; + + if (!TEST_true(setupearly_data_test(&cctx, &sctx, &clientssl, + &serverssl, &sess, idx))) + goto end; + + /* Write some early data */ + if (!TEST_true(SSL_write_early_data(clientssl, MSG1, strlen(MSG1), + &written))) + goto end; + + /* + * Server should skip over early data and then block waiting for client to + * continue handshake + */ + if (!TEST_int_le(SSL_accept(serverssl), 0) + || !TEST_int_gt(SSL_connect(clientssl), 0) + || !TEST_int_eq(SSL_get_early_data_status(serverssl), + SSL_EARLY_DATA_REJECTED) + || !TEST_int_gt(SSL_accept(serverssl), 0) + || !TEST_int_eq(SSL_get_early_data_status(clientssl), + SSL_EARLY_DATA_REJECTED)) + goto end; + + /* Send some normal data from client to server */ + if (!TEST_true(SSL_write_ex(clientssl, MSG2, strlen(MSG2), &written)) + || !TEST_size_t_eq(written, strlen(MSG2))) + goto end; + + if (!TEST_true(SSL_read_ex(serverssl, buf, sizeof(buf), &readbytes)) + || !TEST_mem_eq(buf, readbytes, MSG2, strlen(MSG2))) + goto end; + + testresult = 1; + + end: + /* If using PSK then clientpsk and sess are the same */ + SSL_SESSION_free(sess); + SSL_SESSION_free(serverpsk); + clientpsk = serverpsk = NULL; + SSL_free(serverssl); SSL_free(clientssl); SSL_CTX_free(sctx); SSL_CTX_free(cctx); @@ -1866,19 +2377,8 @@ static int test_early_data_tls1_2(int idx) unsigned char buf[20]; size_t readbytes, written; - if (!TEST_true(create_ssl_ctx_pair(TLS_server_method(), - TLS_client_method(), &sctx, - &cctx, cert, privkey))) - goto end; - - /* When idx == 1 we repeat the tests with read_ahead set */ - if (idx > 0) { - SSL_CTX_set_read_ahead(cctx, 1); - SSL_CTX_set_read_ahead(sctx, 1); - } - - if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, - &clientssl, NULL, NULL))) + if (!TEST_true(setupearly_data_test(&cctx, &sctx, &clientssl, + &serverssl, NULL, idx))) goto end; /* Write some data - should block due to handshake with server */ @@ -1926,6 +2426,10 @@ 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; SSL_free(serverssl); SSL_free(clientssl); SSL_CTX_free(sctx); @@ -1944,11 +2448,11 @@ static int test_ciphersuite_change(void) const SSL_CIPHER *aes_128_gcm_sha256 = NULL; /* Create a session based on SHA-256 */ - if (!TEST_true(create_ssl_ctx_pair(TLS_server_method(), - TLS_client_method(), &sctx, - &cctx, cert, privkey)) - || !TEST_true(SSL_CTX_set_cipher_list(cctx, - "TLS13-AES-128-GCM-SHA256")) + 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_ciphersuites(cctx, + "TLS_AES_128_GCM_SHA256")) || !TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl, NULL, NULL)) || !TEST_true(create_ssl_connection(serverssl, clientssl, @@ -1964,9 +2468,10 @@ static int test_ciphersuite_change(void) SSL_free(clientssl); serverssl = clientssl = NULL; +# if !defined(OPENSSL_NO_CHACHA) && !defined(OPENSSL_NO_POLY1305) /* Check we can resume a session with a different SHA-256 ciphersuite */ - if (!TEST_true(SSL_CTX_set_cipher_list(cctx, - "TLS13-CHACHA20-POLY1305-SHA256")) + if (!TEST_true(SSL_CTX_set_ciphersuites(cctx, + "TLS_CHACHA20_POLY1305_SHA256")) || !TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl, NULL, NULL)) || !TEST_true(SSL_set_session(clientssl, clntsess)) @@ -1982,12 +2487,13 @@ static int test_ciphersuite_change(void) SSL_free(serverssl); SSL_free(clientssl); serverssl = clientssl = NULL; +# endif /* * Check attempting to resume a SHA-256 session with no SHA-256 ciphersuites * succeeds but does not resume. */ - if (!TEST_true(SSL_CTX_set_cipher_list(cctx, "TLS13-AES-256-GCM-SHA384")) + if (!TEST_true(SSL_CTX_set_ciphersuites(cctx, "TLS_AES_256_GCM_SHA384")) || !TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl, NULL, NULL)) || !TEST_true(SSL_set_session(clientssl, clntsess)) @@ -2005,7 +2511,7 @@ static int test_ciphersuite_change(void) serverssl = clientssl = NULL; /* Create a session based on SHA384 */ - if (!TEST_true(SSL_CTX_set_cipher_list(cctx, "TLS13-AES-256-GCM-SHA384")) + if (!TEST_true(SSL_CTX_set_ciphersuites(cctx, "TLS_AES_256_GCM_SHA384")) || !TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl, NULL, NULL)) || !TEST_true(create_ssl_connection(serverssl, clientssl, @@ -2019,10 +2525,10 @@ static int test_ciphersuite_change(void) SSL_free(clientssl); serverssl = clientssl = NULL; - if (!TEST_true(SSL_CTX_set_cipher_list(cctx, - "TLS13-AES-128-GCM-SHA256:TLS13-AES-256-GCM-SHA384")) - || !TEST_true(SSL_CTX_set_cipher_list(sctx, - "TLS13-AES-256-GCM-SHA384")) + if (!TEST_true(SSL_CTX_set_ciphersuites(cctx, + "TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384")) + || !TEST_true(SSL_CTX_set_ciphersuites(sctx, + "TLS_AES_256_GCM_SHA384")) || !TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl, NULL, NULL)) || !TEST_true(SSL_set_session(clientssl, clntsess)) @@ -2062,74 +2568,7 @@ static int test_ciphersuite_change(void) return testresult; } - -static SSL_SESSION *psk = 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 use_session_cb(SSL *ssl, const EVP_MD *md, const unsigned char **id, - size_t *idlen, SSL_SESSION **sess) -{ - switch (++use_session_cb_cnt) { - case 1: - /* The first call should always have a NULL md */ - if (md != NULL) - return 0; - break; - - case 2: - /* The second call should always have an md */ - if (md == NULL) - return 0; - break; - - default: - /* We should only be called a maximum of twice */ - return 0; - } - - if (psk != NULL) - SSL_SESSION_up_ref(psk); - - *sess = psk; - *id = (const unsigned char *)pskid; - *idlen = strlen(pskid); - - return 1; -} - -static int find_session_cb(SSL *ssl, const unsigned char *identity, - size_t identity_len, SSL_SESSION **sess) -{ - find_session_cb_cnt++; - - /* We should only ever be called a maximum of twice per connection */ - if (find_session_cb_cnt > 2) - return 0; - - if (psk == NULL) - return 0; - - /* Identity should match that set by the client */ - if (strlen(srvid) != identity_len - || strncmp(srvid, (const char *)identity, identity_len) != 0) { - /* No PSK found, continue but without a PSK */ - *sess = NULL; - return 1; - } - - SSL_SESSION_up_ref(psk); - *sess = psk; - - return 1; -} - -#define TLS13_AES_256_GCM_SHA384_BYTES ((const unsigned char *)"\x13\x02") - -static int test_tls13_psk(void) +static int test_tls13_psk(int idx) { SSL_CTX *sctx = NULL, *cctx = NULL; SSL *serverssl = NULL, *clientssl = NULL; @@ -2142,14 +2581,38 @@ static int test_tls13_psk(void) }; int testresult = 0; - if (!TEST_true(create_ssl_ctx_pair(TLS_server_method(), - TLS_client_method(), &sctx, - &cctx, cert, privkey))) + 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_CTX_set_psk_use_session_callback(cctx, use_session_cb); - SSL_CTX_set_psk_find_session_callback(sctx, find_session_cb); + /* + * 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; + + /* + * Test 0: New style callbacks only + * Test 1: New and old style callbacks (only the new ones should be used) + * Test 2: Old style callbacks only + */ + if (idx == 0 || idx == 1) { + SSL_CTX_set_psk_use_session_callback(cctx, use_session_cb); + SSL_CTX_set_psk_find_session_callback(sctx, find_session_cb); + } +#ifndef OPENSSL_NO_PSK + if (idx == 1 || idx == 2) { + SSL_CTX_set_psk_client_callback(cctx, psk_client_cb); + SSL_CTX_set_psk_server_callback(sctx, psk_server_cb); + } +#endif srvid = pskid; + use_session_cb_cnt = 0; + find_session_cb_cnt = 0; + 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, @@ -2157,41 +2620,73 @@ static int test_tls13_psk(void) || !TEST_true(create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE)) || !TEST_false(SSL_session_reused(clientssl)) - || !TEST_false(SSL_session_reused(serverssl)) - || !TEST_true(use_session_cb_cnt == 1) - || !TEST_true(find_session_cb_cnt == 0)) - goto end; + || !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)) + goto end; + } shutdown_ssl_connection(serverssl, clientssl); serverssl = clientssl = NULL; - use_session_cb_cnt = 0; + use_session_cb_cnt = psk_client_cb_cnt = 0; if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl, NULL, NULL))) goto end; /* Create the PSK */ - cipher = SSL_CIPHER_find(clientssl, TLS13_AES_256_GCM_SHA384_BYTES); - psk = SSL_SESSION_new(); - if (!TEST_ptr(psk) + cipher = SSL_CIPHER_find(clientssl, TLS13_AES_128_GCM_SHA256_BYTES); + clientpsk = SSL_SESSION_new(); + if (!TEST_ptr(clientpsk) || !TEST_ptr(cipher) - || !TEST_true(SSL_SESSION_set1_master_key(psk, key, sizeof(key))) - || !TEST_true(SSL_SESSION_set_cipher(psk, cipher)) - || !TEST_true(SSL_SESSION_set_protocol_version(psk, - TLS1_3_VERSION))) + || !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)) + || !TEST_true(SSL_SESSION_up_ref(clientpsk))) goto end; + serverpsk = clientpsk; /* Check we can create a connection and the PSK is used */ if (!TEST_true(create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE)) || !TEST_true(SSL_session_reused(clientssl)) - || !TEST_true(SSL_session_reused(serverssl)) - || !TEST_true(use_session_cb_cnt == 1) - || !TEST_true(find_session_cb_cnt == 1)) + || !TEST_true(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) + || !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 == 1)) + goto end; + } + shutdown_ssl_connection(serverssl, clientssl); serverssl = clientssl = NULL; use_session_cb_cnt = find_session_cb_cnt = 0; + psk_client_cb_cnt = psk_server_cb_cnt = 0; if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl, NULL, NULL))) @@ -2207,14 +2702,27 @@ static int test_tls13_psk(void) */ if (!TEST_true(create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE)) || !TEST_true(SSL_session_reused(clientssl)) - || !TEST_true(SSL_session_reused(serverssl)) - || !TEST_true(use_session_cb_cnt == 2) - || !TEST_true(find_session_cb_cnt == 2)) + || !TEST_true(SSL_session_reused(serverssl))) goto end; + if (idx == 0 || idx == 1) { + if (!TEST_true(use_session_cb_cnt == 2) + || !TEST_true(find_session_cb_cnt == 2) + || !TEST_true(psk_client_cb_cnt == 0) + || !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 == 2) + || !TEST_true(psk_server_cb_cnt == 2)) + goto end; + } + shutdown_ssl_connection(serverssl, clientssl); serverssl = clientssl = 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 @@ -2226,17 +2734,35 @@ static int test_tls13_psk(void) || !TEST_true(create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE)) || !TEST_false(SSL_session_reused(clientssl)) - || !TEST_false(SSL_session_reused(serverssl)) - || !TEST_true(use_session_cb_cnt == 1) - || !TEST_true(find_session_cb_cnt == 1)) - goto end; + || !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)) + goto end; + } shutdown_ssl_connection(serverssl, clientssl); serverssl = clientssl = NULL; testresult = 1; end: - SSL_SESSION_free(psk); + SSL_SESSION_free(clientpsk); + SSL_SESSION_free(serverpsk); + clientpsk = serverpsk = NULL; SSL_free(serverssl); SSL_free(clientssl); SSL_CTX_free(sctx); @@ -2244,6 +2770,130 @@ static int test_tls13_psk(void) return testresult; } +static unsigned char cookie_magic_value[] = "cookie magic"; + +static int generate_cookie_callback(SSL *ssl, unsigned char *cookie, + unsigned int *cookie_len) +{ + /* + * Not suitable as a real cookie generation function but good enough for + * testing! + */ + memcpy(cookie, cookie_magic_value, sizeof(cookie_magic_value) - 1); + *cookie_len = sizeof(cookie_magic_value) - 1; + + return 1; +} + +static int verify_cookie_callback(SSL *ssl, const unsigned char *cookie, + unsigned int cookie_len) +{ + if (cookie_len == sizeof(cookie_magic_value) - 1 + && memcmp(cookie, cookie_magic_value, cookie_len) == 0) + return 1; + + return 0; +} + +static int generate_stateless_cookie_callback(SSL *ssl, unsigned char *cookie, + size_t *cookie_len) +{ + unsigned int temp; + int res = generate_cookie_callback(ssl, cookie, &temp); + *cookie_len = temp; + return res; +} + +static int verify_stateless_cookie_callback(SSL *ssl, const unsigned char *cookie, + size_t cookie_len) +{ + return verify_cookie_callback(ssl, cookie, cookie_len); +} + +static int test_stateless(void) +{ + SSL_CTX *sctx = NULL, *cctx = NULL; + SSL *serverssl = NULL, *clientssl = NULL; + int testresult = 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; + + /* The arrival of CCS messages can confuse the test */ + SSL_CTX_clear_options(cctx, SSL_OP_ENABLE_MIDDLEBOX_COMPAT); + + if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl, + NULL, NULL)) + /* Send the first ClientHello */ + || !TEST_false(create_ssl_connection(serverssl, clientssl, + SSL_ERROR_WANT_READ)) + /* + * This should fail with a -1 return because we have no callbacks + * set up + */ + || !TEST_int_eq(SSL_stateless(serverssl), -1)) + goto end; + + /* Fatal error so abandon the connection from this client */ + SSL_free(clientssl); + clientssl = NULL; + + /* Set up the cookie generation and verification callbacks */ + SSL_CTX_set_stateless_cookie_generate_cb(sctx, generate_stateless_cookie_callback); + SSL_CTX_set_stateless_cookie_verify_cb(sctx, verify_stateless_cookie_callback); + + /* + * Create a new connection from the client (we can reuse the server SSL + * object). + */ + if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl, + NULL, NULL)) + /* Send the first ClientHello */ + || !TEST_false(create_ssl_connection(serverssl, clientssl, + SSL_ERROR_WANT_READ)) + /* This should fail because there is no cookie */ + || !TEST_int_eq(SSL_stateless(serverssl), 0)) + goto end; + + /* Abandon the connection from this client */ + SSL_free(clientssl); + clientssl = NULL; + + /* + * Now create a connection from a new client but with the same server SSL + * object + */ + if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl, + NULL, NULL)) + /* Send the first ClientHello */ + || !TEST_false(create_ssl_connection(serverssl, clientssl, + SSL_ERROR_WANT_READ)) + /* This should fail because there is no cookie */ + || !TEST_int_eq(SSL_stateless(serverssl), 0) + /* Send the second ClientHello */ + || !TEST_false(create_ssl_connection(serverssl, clientssl, + SSL_ERROR_WANT_READ)) + /* This should succeed because a cookie is now present */ + || !TEST_int_eq(SSL_stateless(serverssl), 1) + /* Complete the connection */ + || !TEST_true(create_ssl_connection(serverssl, clientssl, + SSL_ERROR_NONE))) + goto end; + + shutdown_ssl_connection(serverssl, clientssl); + serverssl = clientssl = NULL; + testresult = 1; + + end: + SSL_free(serverssl); + SSL_free(clientssl); + SSL_CTX_free(sctx); + SSL_CTX_free(cctx); + return testresult; + +} #endif /* OPENSSL_NO_TLS1_3 */ static int clntaddoldcb = 0; @@ -2379,19 +3029,26 @@ static int test_custom_exts(int tst) SSL_SESSION *sess = NULL; unsigned int context; +#if defined(OPENSSL_NO_TLS1_2) && !defined(OPENSSL_NO_TLS1_3) + /* Skip tests for TLSv1.2 and below in this case */ + if (tst < 3) + return 1; +#endif + /* Reset callback counters */ clntaddoldcb = clntparseoldcb = srvaddoldcb = srvparseoldcb = 0; clntaddnewcb = clntparsenewcb = srvaddnewcb = srvparsenewcb = 0; snicb = 0; - if (!TEST_true(create_ssl_ctx_pair(TLS_server_method(), - TLS_client_method(), &sctx, - &cctx, cert, privkey))) + 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 (tst == 2 - && !TEST_true(create_ssl_ctx_pair(TLS_server_method(), NULL, &sctx2, - NULL, cert, privkey))) + && !TEST_true(create_ssl_ctx_pair(TLS_server_method(), NULL, + TLS1_VERSION, TLS_MAX_VERSION, + &sctx2, NULL, cert, privkey))) goto end; @@ -2660,9 +3317,9 @@ static int test_export_key_mat(int tst) if (tst == 3) return 1; #endif - if (!TEST_true(create_ssl_ctx_pair(TLS_server_method(), - TLS_client_method(), &sctx, - &cctx, cert, privkey))) + if (!TEST_true(create_ssl_ctx_pair(TLS_server_method(), TLS_client_method(), + TLS1_VERSION, TLS_MAX_VERSION, + &sctx, &cctx, cert, privkey))) goto end; OPENSSL_assert(tst >= 0 && (size_t)tst < OSSL_NELEM(protocols)); @@ -2748,6 +3405,86 @@ static int test_export_key_mat(int tst) return testresult; } +#ifndef OPENSSL_NO_TLS1_3 +/* + * Test that SSL_export_keying_material_early() produces expected + * results. There are no test vectors so all we do is test that both + * sides of the communication produce the same results for different + * protocol versions. + */ +static int test_export_key_mat_early(int idx) +{ + static const char label[] = "test label"; + static const unsigned char context[] = "context"; + int testresult = 0; + SSL_CTX *cctx = NULL, *sctx = NULL; + SSL *clientssl = NULL, *serverssl = NULL; + SSL_SESSION *sess = NULL; + const unsigned char *emptycontext = NULL; + unsigned char ckeymat1[80], ckeymat2[80]; + unsigned char skeymat1[80], skeymat2[80]; + unsigned char buf[1]; + size_t readbytes, written; + + if (!TEST_true(setupearly_data_test(&cctx, &sctx, &clientssl, &serverssl, + &sess, idx))) + goto end; + + /* Here writing 0 length early data is enough. */ + if (!TEST_true(SSL_write_early_data(clientssl, NULL, 0, &written)) + || !TEST_int_eq(SSL_read_early_data(serverssl, buf, sizeof(buf), + &readbytes), + SSL_READ_EARLY_DATA_ERROR) + || !TEST_int_eq(SSL_get_early_data_status(serverssl), + SSL_EARLY_DATA_ACCEPTED)) + goto end; + + if (!TEST_int_eq(SSL_export_keying_material_early( + clientssl, ckeymat1, sizeof(ckeymat1), label, + sizeof(label) - 1, context, sizeof(context) - 1), 1) + || !TEST_int_eq(SSL_export_keying_material_early( + clientssl, ckeymat2, sizeof(ckeymat2), label, + sizeof(label) - 1, emptycontext, 0), 1) + || !TEST_int_eq(SSL_export_keying_material_early( + serverssl, skeymat1, sizeof(skeymat1), label, + sizeof(label) - 1, context, sizeof(context) - 1), 1) + || !TEST_int_eq(SSL_export_keying_material_early( + serverssl, skeymat2, sizeof(skeymat2), label, + sizeof(label) - 1, emptycontext, 0), 1) + /* + * Check that both sides created the same key material with the + * same context. + */ + || !TEST_mem_eq(ckeymat1, sizeof(ckeymat1), skeymat1, + sizeof(skeymat1)) + /* + * Check that both sides created the same key material with an + * empty context. + */ + || !TEST_mem_eq(ckeymat2, sizeof(ckeymat2), skeymat2, + sizeof(skeymat2)) + /* Different contexts should produce different results */ + || !TEST_mem_ne(ckeymat1, sizeof(ckeymat1), ckeymat2, + sizeof(ckeymat2))) + goto end; + + testresult = 1; + + end: + if (sess != clientpsk) + SSL_SESSION_free(sess); + SSL_SESSION_free(clientpsk); + SSL_SESSION_free(serverpsk); + clientpsk = serverpsk = NULL; + SSL_free(serverssl); + SSL_free(clientssl); + SSL_CTX_free(sctx); + SSL_CTX_free(cctx); + + return testresult; +} +#endif /* OPENSSL_NO_TLS1_3 */ + static int test_ssl_clear(int idx) { SSL_CTX *cctx = NULL, *sctx = NULL; @@ -2760,9 +3497,9 @@ static int test_ssl_clear(int idx) #endif /* Create an initial connection */ - if (!TEST_true(create_ssl_ctx_pair(TLS_server_method(), - TLS_client_method(), &sctx, - &cctx, cert, privkey)) + if (!TEST_true(create_ssl_ctx_pair(TLS_server_method(), TLS_client_method(), + TLS1_VERSION, TLS_MAX_VERSION, + &sctx, &cctx, cert, privkey)) || (idx == 1 && !TEST_true(SSL_CTX_set_max_proto_version(cctx, TLS1_2_VERSION))) @@ -2802,12 +3539,194 @@ static int test_ssl_clear(int idx) return testresult; } +/* Parse CH and retrieve any MFL extension value if present */ +static int get_MFL_from_client_hello(BIO *bio, int *mfl_codemfl_code) +{ + long len; + unsigned char *data; + PACKET pkt = {0}, pkt2 = {0}, pkt3 = {0}; + unsigned int MFL_code = 0, type = 0; + + if (!TEST_uint_gt( len = BIO_get_mem_data( bio, (char **) &data ), 0 ) ) + goto end; + + if (!TEST_true( PACKET_buf_init( &pkt, data, len ) ) + /* Skip the record header */ + || !PACKET_forward(&pkt, SSL3_RT_HEADER_LENGTH) + /* Skip the handshake message header */ + || !TEST_true(PACKET_forward(&pkt, SSL3_HM_HEADER_LENGTH)) + /* Skip client version and random */ + || !TEST_true(PACKET_forward(&pkt, CLIENT_VERSION_LEN + + SSL3_RANDOM_SIZE)) + /* Skip session id */ + || !TEST_true(PACKET_get_length_prefixed_1(&pkt, &pkt2)) + /* Skip ciphers */ + || !TEST_true(PACKET_get_length_prefixed_2(&pkt, &pkt2)) + /* Skip compression */ + || !TEST_true(PACKET_get_length_prefixed_1(&pkt, &pkt2)) + /* Extensions len */ + || !TEST_true(PACKET_as_length_prefixed_2(&pkt, &pkt2))) + goto end; + + /* Loop through all extensions */ + while (PACKET_remaining(&pkt2)) { + if (!TEST_true(PACKET_get_net_2(&pkt2, &type)) + || !TEST_true(PACKET_get_length_prefixed_2(&pkt2, &pkt3))) + goto end; + + if (type == TLSEXT_TYPE_max_fragment_length) { + if (!TEST_uint_ne(PACKET_remaining(&pkt3), 0) + || !TEST_true(PACKET_get_1(&pkt3, &MFL_code))) + goto end; + + *mfl_codemfl_code = MFL_code; + return 1; + } + } + + end: + return 0; +} + +/* Maximum-Fragment-Length TLS extension mode to test */ +static const unsigned char max_fragment_len_test[] = { + TLSEXT_max_fragment_length_512, + TLSEXT_max_fragment_length_1024, + TLSEXT_max_fragment_length_2048, + TLSEXT_max_fragment_length_4096 +}; + +static int test_max_fragment_len_ext(int idx_tst) +{ + SSL_CTX *ctx; + SSL *con = NULL; + int testresult = 0, MFL_mode = 0; + BIO *rbio, *wbio; + + ctx = SSL_CTX_new(TLS_method()); + if (!TEST_ptr(ctx)) + goto end; + + if (!TEST_true(SSL_CTX_set_tlsext_max_fragment_length( + ctx, max_fragment_len_test[idx_tst]))) + goto end; + + con = SSL_new(ctx); + if (!TEST_ptr(con)) + goto end; + + rbio = BIO_new(BIO_s_mem()); + wbio = BIO_new(BIO_s_mem()); + if (!TEST_ptr(rbio)|| !TEST_ptr(wbio)) { + BIO_free(rbio); + BIO_free(wbio); + goto end; + } + + SSL_set_bio(con, rbio, wbio); + SSL_set_connect_state(con); + + if (!TEST_int_le(SSL_connect(con), 0)) { + /* This shouldn't succeed because we don't have a server! */ + goto end; + } + + if (!TEST_true(get_MFL_from_client_hello(wbio, &MFL_mode))) + /* no MFL in client hello */ + goto end; + if (!TEST_true(max_fragment_len_test[idx_tst] == MFL_mode)) + goto end; + + testresult = 1; + +end: + SSL_free(con); + SSL_CTX_free(ctx); + + return testresult; +} + +#ifndef OPENSSL_NO_TLS1_3 +static int test_pha_key_update(void) +{ + SSL_CTX *cctx = NULL, *sctx = NULL; + SSL *clientssl = NULL, *serverssl = NULL; + int testresult = 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 (!TEST_true(SSL_CTX_set_min_proto_version(sctx, TLS1_3_VERSION)) + || !TEST_true(SSL_CTX_set_max_proto_version(sctx, TLS1_3_VERSION)) + || !TEST_true(SSL_CTX_set_min_proto_version(cctx, TLS1_3_VERSION)) + || !TEST_true(SSL_CTX_set_max_proto_version(cctx, TLS1_3_VERSION))) + goto end; + + + 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_set_verify(serverssl, SSL_VERIFY_PEER, NULL); + if (!TEST_true(SSL_verify_client_post_handshake(serverssl))) + goto end; + + if (!TEST_true(SSL_key_update(clientssl, SSL_KEY_UPDATE_NOT_REQUESTED))) + goto end; + + /* Start handshake on the server */ + if (!TEST_int_eq(SSL_do_handshake(serverssl), 1)) + goto end; + + /* Starts with SSL_connect(), but it's really just SSL_do_handshake() */ + if (!TEST_true(create_ssl_connection(serverssl, clientssl, + SSL_ERROR_NONE))) + goto end; + + SSL_shutdown(clientssl); + SSL_shutdown(serverssl); + + testresult = 1; + + end: + SSL_free(serverssl); + SSL_free(clientssl); + SSL_CTX_free(sctx); + SSL_CTX_free(cctx); + return testresult; +} +#endif + int setup_tests(void) { if (!TEST_ptr(cert = test_get_argument(0)) || !TEST_ptr(privkey = test_get_argument(1))) return 0; + if (getenv("OPENSSL_TEST_GETCOUNTS") != NULL) { +#ifdef OPENSSL_NO_CRYPTO_MDEBUG + TEST_error("not supported in this build"); + return 0; +#else + int i, mcount, rcount, fcount; + + for (i = 0; i < 4; i++) + test_export_key_mat(i); + CRYPTO_get_alloc_counts(&mcount, &rcount, &fcount); + test_printf_stdout("malloc %d realloc %d free %d\n", + mcount, rcount, fcount); + return 1; +#endif + } + ADD_TEST(test_large_message_tls); ADD_TEST(test_large_message_tls_read_ahead); #ifndef OPENSSL_NO_DTLS @@ -2824,34 +3743,52 @@ int setup_tests(void) ADD_TEST(test_ssl_bio_pop_ssl_bio); ADD_TEST(test_ssl_bio_change_rbio); ADD_TEST(test_ssl_bio_change_wbio); +#if !defined(OPENSSL_NO_TLS1_2) || defined(OPENSSL_NO_TLS1_3) ADD_ALL_TESTS(test_set_sigalgs, OSSL_NELEM(testsigalgs) * 2); ADD_TEST(test_keylog); +#endif #ifndef OPENSSL_NO_TLS1_3 ADD_TEST(test_keylog_no_master_key); #endif #ifndef OPENSSL_NO_TLS1_2 - ADD_TEST(test_early_cb); + ADD_TEST(test_client_hello_cb); #endif #ifndef OPENSSL_NO_TLS1_3 - ADD_ALL_TESTS(test_early_data_read_write, 2); - ADD_ALL_TESTS(test_early_data_skip, 2); - ADD_ALL_TESTS(test_early_data_skip_hrr, 2); - ADD_ALL_TESTS(test_early_data_not_sent, 2); - ADD_ALL_TESTS(test_early_data_not_expected, 2); + ADD_ALL_TESTS(test_early_data_read_write, 3); + /* + * We don't do replay tests for external PSK. Replay protection isn't used + * in that scenario. + */ + 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_not_sent, 3); + ADD_ALL_TESTS(test_early_data_psk, 8); + ADD_ALL_TESTS(test_early_data_not_expected, 3); # ifndef OPENSSL_NO_TLS1_2 - ADD_ALL_TESTS(test_early_data_tls1_2, 2); + ADD_ALL_TESTS(test_early_data_tls1_2, 3); # endif #endif #ifndef OPENSSL_NO_TLS1_3 ADD_TEST(test_ciphersuite_change); - ADD_TEST(test_tls13_psk); +#ifdef OPENSSL_NO_PSK + ADD_ALL_TESTS(test_tls13_psk, 1); +#else + ADD_ALL_TESTS(test_tls13_psk, 3); +#endif /* OPENSSL_NO_PSK */ ADD_ALL_TESTS(test_custom_exts, 5); + ADD_TEST(test_stateless); + ADD_TEST(test_pha_key_update); #else ADD_ALL_TESTS(test_custom_exts, 3); #endif ADD_ALL_TESTS(test_serverinfo, 8); ADD_ALL_TESTS(test_export_key_mat, 4); +#ifndef OPENSSL_NO_TLS1_3 + ADD_ALL_TESTS(test_export_key_mat_early, 3); +#endif ADD_ALL_TESTS(test_ssl_clear, 2); + ADD_ALL_TESTS(test_max_fragment_len_ext, OSSL_NELEM(max_fragment_len_test)); return 1; }