Fix dsaparam -genkey with DER outform
[openssl.git] / test / sslapitest.c
index 6267ce8e92aaccc5a35b66877d4488105b3d3b14..3dcf7353259ab5260871d00c50ccd85add3f88ee 100644 (file)
@@ -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,6 +17,7 @@
 
 #include "ssltestlib.h"
 #include "testutil.h"
+#include "testutil/output.h"
 #include "internal/nelem.h"
 #include "../ssl/ssl_locl.h"
 
@@ -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
@@ -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)
@@ -448,9 +453,9 @@ static int test_client_hello_cb(void)
     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_client_hello_cb(sctx, full_client_hello_callback, &testctr);
 
@@ -486,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;
@@ -504,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) {
@@ -562,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);
 }
 
@@ -579,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
 
@@ -638,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)
@@ -802,9 +814,9 @@ static int execute_test_session(int maxprot, int use_int_cache,
 
     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;
 
     /*
@@ -1017,15 +1029,20 @@ static int execute_test_session(int maxprot, int use_int_cache,
         goto end;
 
     if (use_ext_cache) {
-        if (!TEST_int_eq(new_called, 0)
-                || !TEST_int_eq(remove_called, 0))
+        if (!TEST_int_eq(remove_called, 0))
             goto end;
 
         if (maxprot == TLS1_3_VERSION) {
-            if (!TEST_int_eq(get_called, 0))
+            /*
+             * 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(get_called, 1))
+            if (!TEST_int_eq(new_called, 0)
+                    || !TEST_int_eq(get_called, 1))
                 goto end;
         }
     }
@@ -1272,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;
@@ -1286,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},
@@ -1331,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;
 
     /*
@@ -1400,6 +1418,7 @@ static int test_set_sigalgs(int idx)
 
     return testresult;
 }
+#endif
 
 #ifndef OPENSSL_NO_TLS1_3
 
@@ -1410,6 +1429,8 @@ 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)
@@ -1442,6 +1463,36 @@ static int use_session_cb(SSL *ssl, const EVP_MD *md, const unsigned char **id,
     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)
 {
@@ -1468,6 +1519,35 @@ static int find_session_cb(SSL *ssl, const unsigned char *identity,
     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"
@@ -1477,6 +1557,7 @@ static int find_session_cb(SSL *ssl, const unsigned char *identity,
 #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
@@ -1485,9 +1566,13 @@ static int find_session_cb(SSL *ssl, const unsigned char *identity,
 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;
 
     if (idx == 1) {
@@ -1785,6 +1870,58 @@ static int test_early_data_read_write(int idx)
     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);
+    SSL_CTX_free(cctx);
+    return testresult;
+}
+
 /*
  * 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.
@@ -1818,7 +1955,7 @@ static int early_data_skip_helper(int hrr, int idx)
          * 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;
     }
 
@@ -1960,13 +2097,11 @@ static int test_early_data_not_sent(int idx)
     return testresult;
 }
 
-static const char *servhostname;
-
 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, servhostname) == 0)
+    if (hostname != NULL && strcmp(hostname, "goodhost") == 0)
         return  SSL_TLSEXT_ERR_OK;
 
     return SSL_TLSEXT_ERR_NOACK;
@@ -1983,7 +2118,7 @@ static int alpn_select_cb(SSL *ssl, const unsigned char **out,
 
     for (prot = in; prot < in + inlen; prot += protlen) {
         protlen = *prot++;
-        if (in + inlen - prot < protlen)
+        if (in + inlen < prot + protlen)
             return SSL_TLSEXT_ERR_NOACK;
 
         if (protlen == strlen(servalpn)
@@ -2023,7 +2158,6 @@ static int test_early_data_psk(int idx)
                                         &serverssl, &sess, 2)))
         goto end;
 
-    servhostname = "goodhost";
     servalpn = "goodalpn";
 
     /*
@@ -2068,7 +2202,11 @@ static int test_early_data_psk(int idx)
          * Set inconsistent SNI (server detected). In this case the connection
          * will succeed but reject early_data.
          */
-        servhostname = "badhost";
+        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 */
@@ -2310,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,
@@ -2330,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))
@@ -2348,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))
@@ -2371,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,
@@ -2385,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))
@@ -2428,7 +2568,7 @@ static int test_ciphersuite_change(void)
     return testresult;
 }
 
-static int test_tls13_psk(void)
+static int test_tls13_psk(int idx)
 {
     SSL_CTX *sctx = NULL, *cctx = NULL;
     SSL *serverssl = NULL, *clientssl = NULL;
@@ -2441,16 +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;
+
+    /*
+     * 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;
 
-    SSL_CTX_set_psk_use_session_callback(cctx, use_session_cb);
-    SSL_CTX_set_psk_find_session_callback(sctx, find_session_cb);
+    /*
+     * 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,
@@ -2458,21 +2620,37 @@ 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))
+            || !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);
+    cipher = SSL_CIPHER_find(clientssl, TLS13_AES_128_GCM_SHA256_BYTES);
     clientpsk = SSL_SESSION_new();
     if (!TEST_ptr(clientpsk)
             || !TEST_ptr(cipher)
@@ -2488,14 +2666,27 @@ static int test_tls13_psk(void)
     /* 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)))
@@ -2511,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
@@ -2530,11 +2734,27 @@ 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))
+            || !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;
@@ -2550,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;
@@ -2685,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;
 
 
@@ -2966,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));
@@ -3054,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;
@@ -3066,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)))
@@ -3108,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
@@ -3130,8 +3743,10 @@ 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
@@ -3140,6 +3755,11 @@ int setup_tests(void)
 #endif
 #ifndef OPENSSL_NO_TLS1_3
     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);
@@ -3151,14 +3771,24 @@ int setup_tests(void)
 #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;
 }