+ /*
+ * In the normal case. We have 5 pipelines with 10 bytes per pipeline
+ * (50 bytes in total). This is a ridiculously small number of bytes -
+ * but sufficient for our purposes
+ */
+ if (!TEST_true(SSL_set_max_pipelines(peera, numpipes))
+ || !TEST_true(SSL_set_split_send_fragment(peera, fragsize)))
+ goto end;
+
+ if (!TEST_true(create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE)))
+ goto end;
+
+ /* Write some data from peera to peerb */
+ if (!TEST_true(SSL_write_ex(peera, msg, msglen, &written))
+ || !TEST_size_t_eq(written, msglen))
+ goto end;
+
+ /*
+ * If the pipelining code worked, then we expect all |numpipes| pipelines to
+ * have been used - except in test 3 where only |numpipes - 1| pipelines
+ * will be used. This will result in |numpipes| records (|numpipes - 1| for
+ * test 3) having been sent to peerb. Since peerb is not using read_ahead we
+ * expect this to be read in |numpipes| or |numpipes - 1| separate
+ * SSL_read_ex calls. In the case of test 4, there is then one additional
+ * read for left over data that couldn't fit in the previous pipelines
+ */
+ for (offset = 0, numreads = 0;
+ offset < msglen;
+ offset += readbytes, numreads++) {
+ if (!TEST_true(SSL_read_ex(peerb, buf + offset,
+ msglen - offset, &readbytes)))
+ goto end;
+ }
+
+ expectedreads = idx == 4 ? numpipes + 1
+ : (idx == 3 ? numpipes - 1 : numpipes);
+ if (!TEST_mem_eq(msg, msglen, buf, offset)
+ || !TEST_int_eq(numreads, expectedreads))
+ goto end;
+
+ /*
+ * Write some data from peerb to peera. We do this in up to |numpipes + 1|
+ * chunks to exercise the read pipelining code on peera.
+ */
+ for (offset = 0; offset < msglen; offset += fragsize) {
+ size_t sendlen = msglen - offset;
+
+ if (sendlen > fragsize)
+ sendlen = fragsize;
+ if (!TEST_true(SSL_write_ex(peerb, msg + offset, sendlen, &written))
+ || !TEST_size_t_eq(written, sendlen))
+ goto end;
+ }
+
+ /*
+ * The data was written in |numpipes|, |numpipes - 1| or |numpipes + 1|
+ * separate chunks (depending on which test we are running). If the
+ * pipelining is working then we expect peera to read up to numpipes chunks
+ * and process them in parallel, giving back the complete result in a single
+ * call to SSL_read_ex
+ */
+ if (!TEST_true(SSL_read_ex(peera, buf, msglen, &readbytes))
+ || !TEST_size_t_le(readbytes, msglen))
+ goto end;
+
+ if (idx == 4) {
+ size_t readbytes2;
+
+ if (!TEST_true(SSL_read_ex(peera, buf + readbytes,
+ msglen - readbytes, &readbytes2)))
+ goto end;
+ readbytes += readbytes2;
+ if (!TEST_size_t_le(readbytes, msglen))
+ goto end;
+ }
+
+ if (!TEST_mem_eq(msg, msglen, buf, readbytes))
+ goto end;
+
+ testresult = 1;
+end:
+ SSL_free(serverssl);
+ SSL_free(clientssl);
+ SSL_CTX_free(sctx);
+ SSL_CTX_free(cctx);
+ if (e != NULL) {
+ ENGINE_unregister_ciphers(e);
+ ENGINE_finish(e);
+ ENGINE_free(e);
+ }
+ OPENSSL_free(buf);
+ if (fragsize == SSL3_RT_MAX_PLAIN_LENGTH)
+ OPENSSL_free(msg);
+ return testresult;
+}
+#endif /* !defined(OPENSSL_NO_TLS1_2) && !defined(OPENSSL_NO_DYNAMIC_ENGINE) */
+
+static int check_version_string(SSL *s, int version)
+{
+ const char *verstr = NULL;
+
+ switch (version) {
+ case SSL3_VERSION:
+ verstr = "SSLv3";
+ break;
+ case TLS1_VERSION:
+ verstr = "TLSv1";
+ break;
+ case TLS1_1_VERSION:
+ verstr = "TLSv1.1";
+ break;
+ case TLS1_2_VERSION:
+ verstr = "TLSv1.2";
+ break;
+ case TLS1_3_VERSION:
+ verstr = "TLSv1.3";
+ break;
+ case DTLS1_VERSION:
+ verstr = "DTLSv1";
+ break;
+ case DTLS1_2_VERSION:
+ verstr = "DTLSv1.2";
+ }
+
+ return TEST_str_eq(verstr, SSL_get_version(s));
+}
+
+/*
+ * Test that SSL_version, SSL_get_version, SSL_is_quic, SSL_is_tls and
+ * SSL_is_dtls return the expected results for a (D)TLS connection. Compare with
+ * test_version() in quicapitest.c which does the same thing for QUIC
+ * connections.
+ */
+static int test_version(int idx)
+{
+ SSL_CTX *cctx = NULL, *sctx = NULL;
+ SSL *clientssl = NULL, *serverssl = NULL;
+ int testresult = 0, version;
+ const SSL_METHOD *servmeth = TLS_server_method();
+ const SSL_METHOD *clientmeth = TLS_client_method();
+
+ switch (idx) {
+#if !defined(OPENSSL_NO_SSL3)
+ case 0:
+ version = SSL3_VERSION;
+ break;
+#endif
+#if !defined(OPENSSL_NO_TLS1)
+ case 1:
+ version = TLS1_VERSION;
+ break;
+#endif
+#if !defined(OPENSSL_NO_TLS1_2)
+ case 2:
+ version = TLS1_2_VERSION;
+ break;
+#endif
+#if !defined(OSSL_NO_USABLE_TLS1_3)
+ case 3:
+ version = TLS1_3_VERSION;
+ break;
+#endif
+#if !defined(OPENSSL_NO_DTLS1)
+ case 4:
+ version = DTLS1_VERSION;
+ break;
+#endif
+#if !defined(OPENSSL_NO_DTLS1_2)
+ case 5:
+ version = DTLS1_2_VERSION;
+ break;
+#endif
+ /*
+ * NB we do not support QUIC in this test. That is covered by quicapitest.c
+ * We also don't support DTLS1_BAD_VER since we have no server support for
+ * that.
+ */
+ default:
+ TEST_skip("Unsupported protocol version");
+ return 1;
+ }
+
+ if (is_fips
+ && (version == SSL3_VERSION
+ || version == TLS1_VERSION
+ || version == DTLS1_VERSION)) {
+ TEST_skip("Protocol version not supported with FIPS");
+ return 1;
+ }
+
+#if !defined(OPENSSL_NO_DTLS)
+ if (version == DTLS1_VERSION || version == DTLS1_2_VERSION) {
+ servmeth = DTLS_server_method();
+ clientmeth = DTLS_client_method();
+ }
+#endif
+
+ if (!TEST_true(create_ssl_ctx_pair(libctx, servmeth, clientmeth, version,
+ version, &sctx, &cctx, cert, privkey)))
+ goto end;
+
+ if (!TEST_true(SSL_CTX_set_cipher_list(sctx, "DEFAULT:@SECLEVEL=0"))
+ || !TEST_true(SSL_CTX_set_cipher_list(cctx,
+ "DEFAULT:@SECLEVEL=0")))
+ goto end;
+
+ if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl,
+ &clientssl, NULL, NULL)))
+ goto end;
+
+ if (!TEST_true(create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE)))
+ goto end;
+
+ if (!TEST_int_eq(SSL_version(serverssl), version)
+ || !TEST_int_eq(SSL_version(clientssl), version)
+ || !TEST_true(check_version_string(serverssl, version))
+ || !TEST_true(check_version_string(clientssl, version)))
+ goto end;
+
+ if (version == DTLS1_VERSION || version == DTLS1_2_VERSION) {
+ if (!TEST_true(SSL_is_dtls(serverssl))
+ || !TEST_true(SSL_is_dtls(clientssl))
+ || !TEST_false(SSL_is_tls(serverssl))
+ || !TEST_false(SSL_is_tls(clientssl))
+ || !TEST_false(SSL_is_quic(serverssl))
+ || !TEST_false(SSL_is_quic(clientssl)))
+ goto end;
+ } else {
+ if (!TEST_true(SSL_is_tls(serverssl))
+ || !TEST_true(SSL_is_tls(clientssl))
+ || !TEST_false(SSL_is_dtls(serverssl))
+ || !TEST_false(SSL_is_dtls(clientssl))
+ || !TEST_false(SSL_is_quic(serverssl))
+ || !TEST_false(SSL_is_quic(clientssl)))
+ goto end;
+ }
+
+ testresult = 1;
+end:
+ SSL_free(serverssl);
+ SSL_free(clientssl);
+ SSL_CTX_free(sctx);
+ SSL_CTX_free(cctx);
+ return testresult;
+}
+
+/*
+ * Test that the SSL_rstate_string*() APIs return sane results
+ */
+static int test_rstate_string(void)
+{
+ SSL_CTX *cctx = NULL, *sctx = NULL;
+ SSL *clientssl = NULL, *serverssl = NULL;
+ int testresult = 0, version;
+ const SSL_METHOD *servmeth = TLS_server_method();
+ const SSL_METHOD *clientmeth = TLS_client_method();
+ size_t written, readbytes;
+ unsigned char buf[2];
+ unsigned char dummyheader[SSL3_RT_HEADER_LENGTH] = {
+ SSL3_RT_APPLICATION_DATA,
+ TLS1_2_VERSION_MAJOR,
+ 0, /* To be filled in later */
+ 0,
+ 1
+ };
+
+ if (!TEST_true(create_ssl_ctx_pair(libctx, servmeth, clientmeth, 0,
+ 0, &sctx, &cctx, cert, privkey)))
+ goto end;
+
+ if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl,
+ &clientssl, NULL, NULL)))
+ goto end;
+
+ if (!TEST_str_eq(SSL_rstate_string(serverssl), "RH")
+ || !TEST_str_eq(SSL_rstate_string_long(serverssl), "read header"))
+ goto end;
+
+ if (!TEST_true(create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE)))
+ goto end;
+
+ if (!TEST_str_eq(SSL_rstate_string(serverssl), "RH")
+ || !TEST_str_eq(SSL_rstate_string_long(serverssl), "read header"))
+ goto end;
+
+ /* Fill in the correct version for the record header */
+ version = SSL_version(serverssl);
+ if (version == TLS1_3_VERSION)
+ version = TLS1_2_VERSION;
+ dummyheader[2] = version & 0xff;
+
+ /*
+ * Send a dummy header. If we continued to read the body as well this
+ * would fail with a bad record mac, but we're not going to go that far.
+ */
+ if (!TEST_true(BIO_write_ex(SSL_get_rbio(serverssl), dummyheader,
+ sizeof(dummyheader), &written))
+ || !TEST_size_t_eq(written, SSL3_RT_HEADER_LENGTH))
+ goto end;
+
+ if (!TEST_false(SSL_read_ex(serverssl, buf, sizeof(buf), &readbytes)))
+ goto end;
+
+ if (!TEST_str_eq(SSL_rstate_string(serverssl), "RB")
+ || !TEST_str_eq(SSL_rstate_string_long(serverssl), "read body"))
+ goto end;
+
+ testresult = 1;
+end:
+ SSL_free(serverssl);
+ SSL_free(clientssl);
+ SSL_CTX_free(sctx);
+ SSL_CTX_free(cctx);
+ return testresult;
+}
+
+/*
+ * Force a write retry during handshaking. We test various combinations of
+ * scenarios. We test a large certificate message which will fill the buffering
+ * BIO used in the handshake. We try with client auth on and off. Finally we
+ * also try a BIO that indicates retry via a 0 return. BIO_write() is documented
+ * to indicate retry via -1 - but sometimes BIOs don't do that.
+ *
+ * Test 0: Standard certificate message
+ * Test 1: Large certificate message
+ * Test 2: Standard cert, verify peer
+ * Test 3: Large cert, verify peer
+ * Test 4: Standard cert, BIO returns 0 on retry
+ * Test 5: Large cert, BIO returns 0 on retry
+ * Test 6: Standard cert, verify peer, BIO returns 0 on retry
+ * Test 7: Large cert, verify peer, BIO returns 0 on retry
+ * Test 8-15: Repeat of above with TLSv1.2
+ */
+static int test_handshake_retry(int idx)
+{
+ SSL_CTX *cctx = NULL, *sctx = NULL;
+ SSL *clientssl = NULL, *serverssl = NULL;
+ int testresult = 0;
+ BIO *tmp = NULL, *bretry = BIO_new(bio_s_always_retry());
+ int maxversion = 0;
+
+ if (!TEST_ptr(bretry))
+ goto end;
+
+#ifndef OPENSSL_NO_TLS1_2
+ if ((idx & 8) == 8)
+ maxversion = TLS1_2_VERSION;
+#else
+ if ((idx & 8) == 8)
+ return TEST_skip("No TLSv1.2");
+#endif
+
+ if (!TEST_true(create_ssl_ctx_pair(libctx, TLS_server_method(),
+ TLS_client_method(), 0, maxversion,
+ &sctx, &cctx, cert, privkey)))
+ goto end;
+
+ /*
+ * Add a large amount of data to fill the buffering BIO used by the SSL
+ * object
+ */
+ if ((idx & 1) == 1 && !ssl_ctx_add_large_cert_chain(libctx, sctx, cert))
+ goto end;
+
+ /*
+ * We don't actually configure a client cert, but neither do we fail if one
+ * isn't present.
+ */
+ if ((idx & 2) == 2)
+ SSL_CTX_set_verify(sctx, SSL_VERIFY_PEER, NULL);
+
+ if ((idx & 4) == 4)
+ set_always_retry_err_val(0);
+
+ if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl,
+ &clientssl, NULL, NULL)))
+ goto end;
+
+ tmp = SSL_get_wbio(serverssl);
+ if (!TEST_ptr(tmp) || !TEST_true(BIO_up_ref(tmp))) {
+ tmp = NULL;
+ goto end;
+ }
+ SSL_set0_wbio(serverssl, bretry);
+ bretry = NULL;
+
+ if (!TEST_int_eq(SSL_connect(clientssl), -1))
+ goto end;
+
+ if (!TEST_int_eq(SSL_accept(serverssl), -1)
+ || !TEST_int_eq(SSL_get_error(serverssl, -1), SSL_ERROR_WANT_WRITE))
+ goto end;
+
+ /* Restore a BIO that will let the write succeed */
+ SSL_set0_wbio(serverssl, tmp);
+ tmp = NULL;
+
+ if (!TEST_true(create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE)))
+ goto end;
+
+ testresult = 1;
+end:
+ SSL_free(serverssl);
+ SSL_free(clientssl);
+ SSL_CTX_free(sctx);
+ SSL_CTX_free(cctx);
+ BIO_free(bretry);
+ BIO_free(tmp);
+ set_always_retry_err_val(-1);
+ return testresult;
+}
+
+/*
+ * Test that receiving retries when writing application data works as expected
+ */
+static int test_data_retry(void)
+{
+ SSL_CTX *cctx = NULL, *sctx = NULL;
+ SSL *clientssl = NULL, *serverssl = NULL;
+ int testresult = 0;
+ unsigned char inbuf[1200], outbuf[1200];
+ size_t i;
+ BIO *tmp = NULL;
+ BIO *bretry = BIO_new(bio_s_maybe_retry());
+ size_t written, readbytes, totread = 0;
+
+ if (!TEST_ptr(bretry))
+ goto end;
+
+ for (i = 0; i < sizeof(inbuf); i++)
+ inbuf[i] = (unsigned char)(0xff & i);
+ memset(outbuf, 0, sizeof(outbuf));
+
+ if (!TEST_true(create_ssl_ctx_pair(libctx, TLS_server_method(),
+ TLS_client_method(), 0, 0, &sctx, &cctx,
+ cert, privkey)))
+ goto end;
+
+ if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl, NULL,
+ NULL)))
+ goto end;
+
+ if (!TEST_true(create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE)))
+ goto end;
+
+ /* Smallest possible max send fragment is 512 */
+ if (!TEST_true(SSL_set_max_send_fragment(clientssl, 512)))
+ goto end;
+
+ tmp = SSL_get_wbio(clientssl);
+ if (!TEST_ptr(tmp))
+ goto end;
+ if (!TEST_true(BIO_up_ref(tmp)))
+ goto end;
+ BIO_push(bretry, tmp);
+ tmp = NULL;
+ SSL_set0_wbio(clientssl, bretry);
+ if (!BIO_up_ref(bretry)) {
+ bretry = NULL;
+ goto end;
+ }
+
+ for (i = 0; i < 3; i++) {
+ /* We expect this call to make no progress and indicate retry */
+ if (!TEST_false(SSL_write_ex(clientssl, inbuf, sizeof(inbuf), &written)))
+ goto end;
+ if (!TEST_int_eq(SSL_get_error(clientssl, 0), SSL_ERROR_WANT_WRITE))
+ goto end;
+
+ /* Allow one write to progress, but the next one to signal retry */
+ if (!TEST_true(BIO_ctrl(bretry, MAYBE_RETRY_CTRL_SET_RETRY_AFTER_CNT, 1,
+ NULL)))
+ goto end;
+
+ if (i == 2)
+ break;
+
+ /*
+ * This call will hopefully make progress but will still indicate retry
+ * because there is more data than will fit into a single record.
+ */
+ if (!TEST_false(SSL_write_ex(clientssl, inbuf, sizeof(inbuf), &written)))
+ goto end;
+ if (!TEST_int_eq(SSL_get_error(clientssl, 0), SSL_ERROR_WANT_WRITE))
+ goto end;
+ }
+
+ /* The final call should write the last chunk of data and succeed */
+ if (!TEST_true(SSL_write_ex(clientssl, inbuf, sizeof(inbuf), &written)))
+ goto end;
+ /* Read all the data available */
+ while (SSL_read_ex(serverssl, outbuf + totread, sizeof(outbuf) - totread,
+ &readbytes))
+ totread += readbytes;
+ if (!TEST_mem_eq(inbuf, sizeof(inbuf), outbuf, totread))
+ goto end;
+
+ testresult = 1;
+end:
+ SSL_free(serverssl);
+ SSL_free(clientssl);
+ SSL_CTX_free(sctx);
+ SSL_CTX_free(cctx);
+ BIO_free_all(bretry);
+ BIO_free(tmp);
+ return testresult;
+}
+
+struct resume_servername_cb_data {
+ int i;
+ SSL_CTX *cctx;
+ SSL_CTX *sctx;
+ SSL_SESSION *sess;
+ int recurse;
+};
+
+/*
+ * Servername callback. We use it here to run another complete handshake using
+ * the same session - and mark the session as not_resuamble at the end
+ */
+static int resume_servername_cb(SSL *s, int *ad, void *arg)
+{
+ struct resume_servername_cb_data *cbdata = arg;
+ SSL *serverssl = NULL, *clientssl = NULL;
+ int ret = SSL_TLSEXT_ERR_ALERT_FATAL;
+
+ if (cbdata->recurse)
+ return SSL_TLSEXT_ERR_ALERT_FATAL;
+
+ if ((cbdata->i % 3) != 1)
+ return SSL_TLSEXT_ERR_OK;
+
+ cbdata->recurse = 1;
+
+ if (!TEST_true(create_ssl_objects(cbdata->sctx, cbdata->cctx, &serverssl,
+ &clientssl, NULL, NULL))
+ || !TEST_true(SSL_set_session(clientssl, cbdata->sess)))
+ goto end;
+
+ ERR_set_mark();
+ /*
+ * We expect this to fail - because the servername cb will fail. This will
+ * mark the session as not_resumable.
+ */
+ if (!TEST_false(create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE))) {
+ ERR_clear_last_mark();
+ goto end;
+ }
+ ERR_pop_to_mark();
+
+ ret = SSL_TLSEXT_ERR_OK;
+ end:
+ SSL_free(serverssl);
+ SSL_free(clientssl);
+ cbdata->recurse = 0;
+ return ret;
+}
+/*
+ * Test multiple resumptions and cache size handling
+ * Test 0: TLSv1.3 (max_early_data set)
+ * Test 1: TLSv1.3 (SSL_OP_NO_TICKET set)
+ * Test 2: TLSv1.3 (max_early_data and SSL_OP_NO_TICKET set)
+ * Test 3: TLSv1.3 (SSL_OP_NO_TICKET, simultaneous resumes)
+ * Test 4: TLSv1.2
+ */
+static int test_multi_resume(int idx)
+{
+ SSL_CTX *sctx = NULL, *cctx = NULL;
+ SSL *serverssl = NULL, *clientssl = NULL;
+ SSL_SESSION *sess = NULL;
+ int max_version = TLS1_3_VERSION;
+ int i, testresult = 0;
+ struct resume_servername_cb_data cbdata;
+
+#if defined(OPENSSL_NO_TLS1_2)
+ if (idx == 4)
+ return TEST_skip("TLSv1.2 is disabled in this build");
+#else
+ if (idx == 4)
+ max_version = TLS1_2_VERSION;
+#endif
+#if defined(OSSL_NO_USABLE_TLS1_3)
+ if (idx != 4)
+ return TEST_skip("No usable TLSv1.3 in this build");
+#endif
+
+ if (!TEST_true(create_ssl_ctx_pair(libctx, TLS_server_method(),
+ TLS_client_method(), TLS1_VERSION,
+ max_version, &sctx, &cctx, cert,
+ privkey)))
+ goto end;
+
+ /*
+ * TLSv1.3 only uses a session cache if either max_early_data > 0 (used for
+ * replay protection), or if SSL_OP_NO_TICKET is in use
+ */
+ if (idx == 0 || idx == 2) {
+ if (!TEST_true(SSL_CTX_set_max_early_data(sctx, 1024)))
+ goto end;
+ }
+ if (idx == 1 || idx == 2 || idx == 3)
+ SSL_CTX_set_options(sctx, SSL_OP_NO_TICKET);
+
+ SSL_CTX_sess_set_cache_size(sctx, 5);
+
+ if (idx == 3) {
+ SSL_CTX_set_tlsext_servername_callback(sctx, resume_servername_cb);
+ SSL_CTX_set_tlsext_servername_arg(sctx, &cbdata);
+ cbdata.cctx = cctx;
+ cbdata.sctx = sctx;
+ cbdata.recurse = 0;
+ }
+
+ for (i = 0; i < 30; i++) {
+ if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl,
+ NULL, NULL))
+ || !TEST_true(SSL_set_session(clientssl, sess)))
+ goto end;
+
+ /*
+ * Check simultaneous resumes. We pause the connection part way through
+ * the handshake by (mis)using the servername_cb. The pause occurs after
+ * session resumption has already occurred, but before any session
+ * tickets have been issued. While paused we run another complete
+ * handshake resuming the same session.
+ */
+ if (idx == 3) {
+ cbdata.i = i;
+ cbdata.sess = sess;
+ }
+
+ /*
+ * Recreate a bug where dynamically changing the max_early_data value
+ * can cause sessions in the session cache which cannot be deleted.
+ */
+ if ((idx == 0 || idx == 2) && (i % 3) == 2)
+ SSL_set_max_early_data(serverssl, 0);
+
+ if (!TEST_true(create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE)))
+ goto end;
+
+ if (sess == NULL || (idx == 0 && (i % 3) == 2)) {
+ if (!TEST_false(SSL_session_reused(clientssl)))
+ goto end;
+ } else {
+ if (!TEST_true(SSL_session_reused(clientssl)))
+ goto end;
+ }
+ SSL_SESSION_free(sess);
+
+ /* Do a full handshake, followed by two resumptions */
+ if ((i % 3) == 2) {
+ sess = NULL;
+ } else {
+ if (!TEST_ptr((sess = SSL_get1_session(clientssl))))
+ goto end;
+ }
+
+ SSL_shutdown(clientssl);
+ SSL_shutdown(serverssl);
+ SSL_free(serverssl);
+ SSL_free(clientssl);
+ serverssl = clientssl = NULL;
+ }
+
+ /* We should never exceed the session cache size limit */
+ if (!TEST_long_le(SSL_CTX_sess_number(sctx), 5))
+ goto end;
+
+ testresult = 1;
+ end:
+ SSL_free(serverssl);
+ SSL_free(clientssl);
+ SSL_CTX_free(sctx);
+ SSL_CTX_free(cctx);
+ SSL_SESSION_free(sess);
+ return testresult;
+}
+
+OPT_TEST_DECLARE_USAGE("certfile privkeyfile srpvfile tmpfile provider config dhfile\n")
+
+int setup_tests(void)
+{
+ char *modulename;
+ char *configfile;
+
+ libctx = OSSL_LIB_CTX_new();
+ if (!TEST_ptr(libctx))
+ return 0;
+
+ defctxnull = OSSL_PROVIDER_load(NULL, "null");
+
+ /*
+ * Verify that the default and fips providers in the default libctx are not
+ * available
+ */
+ if (!TEST_false(OSSL_PROVIDER_available(NULL, "default"))
+ || !TEST_false(OSSL_PROVIDER_available(NULL, "fips")))
+ return 0;
+
+ if (!test_skip_common_options()) {
+ TEST_error("Error parsing test options\n");
+ return 0;
+ }
+
+ if (!TEST_ptr(certsdir = test_get_argument(0))
+ || !TEST_ptr(srpvfile = test_get_argument(1))
+ || !TEST_ptr(tmpfilename = test_get_argument(2))
+ || !TEST_ptr(modulename = test_get_argument(3))
+ || !TEST_ptr(configfile = test_get_argument(4))
+ || !TEST_ptr(dhfile = test_get_argument(5)))
+ return 0;
+
+ if (!TEST_true(OSSL_LIB_CTX_load_config(libctx, configfile)))
+ return 0;
+
+ /* Check we have the expected provider available */
+ if (!TEST_true(OSSL_PROVIDER_available(libctx, modulename)))
+ return 0;
+
+ /* Check the default provider is not available */
+ if (strcmp(modulename, "default") != 0
+ && !TEST_false(OSSL_PROVIDER_available(libctx, "default")))
+ return 0;
+
+ if (strcmp(modulename, "fips") == 0) {
+ OSSL_PROVIDER *prov = NULL;
+ OSSL_PARAM params[2];
+
+ is_fips = 1;
+
+ prov = OSSL_PROVIDER_load(libctx, "fips");
+ if (prov != NULL) {
+ /* Query the fips provider to check if the check ems option is enabled */
+ params[0] =
+ OSSL_PARAM_construct_int(OSSL_PROV_PARAM_TLS1_PRF_EMS_CHECK,
+ &fips_ems_check);
+ params[1] = OSSL_PARAM_construct_end();
+ OSSL_PROVIDER_get_params(prov, params);
+ OSSL_PROVIDER_unload(prov);
+ }
+ }
+
+ /*
+ * We add, but don't load the test "tls-provider". We'll load it when we
+ * need it.
+ */
+ if (!TEST_true(OSSL_PROVIDER_add_builtin(libctx, "tls-provider",
+ tls_provider_init)))
+ 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
+ }
+
+ cert = test_mk_file_path(certsdir, "servercert.pem");
+ if (cert == NULL)
+ goto err;
+
+ privkey = test_mk_file_path(certsdir, "serverkey.pem");
+ if (privkey == NULL)
+ goto err;
+
+ cert2 = test_mk_file_path(certsdir, "server-ecdsa-cert.pem");
+ if (cert2 == NULL)
+ goto err;
+
+ privkey2 = test_mk_file_path(certsdir, "server-ecdsa-key.pem");
+ if (privkey2 == NULL)
+ goto err;
+
+ cert1024 = test_mk_file_path(certsdir, "ee-cert-1024.pem");
+ if (cert1024 == NULL)
+ goto err;
+
+ privkey1024 = test_mk_file_path(certsdir, "ee-key-1024.pem");
+ if (privkey1024 == NULL)
+ goto err;
+
+ cert3072 = test_mk_file_path(certsdir, "ee-cert-3072.pem");
+ if (cert3072 == NULL)
+ goto err;
+
+ privkey3072 = test_mk_file_path(certsdir, "ee-key-3072.pem");
+ if (privkey3072 == NULL)
+ goto err;
+
+ cert4096 = test_mk_file_path(certsdir, "ee-cert-4096.pem");
+ if (cert4096 == NULL)
+ goto err;
+
+ privkey4096 = test_mk_file_path(certsdir, "ee-key-4096.pem");
+ if (privkey4096 == NULL)
+ goto err;
+
+ cert8192 = test_mk_file_path(certsdir, "ee-cert-8192.pem");
+ if (cert8192 == NULL)
+ goto err;
+
+ privkey8192 = test_mk_file_path(certsdir, "ee-key-8192.pem");
+ if (privkey8192 == NULL)
+ goto err;
+
+ if (fips_ems_check) {
+#ifndef OPENSSL_NO_TLS1_2
+ ADD_TEST(test_no_ems);
+#endif
+ return 1;
+ }
+#if !defined(OPENSSL_NO_KTLS) && !defined(OPENSSL_NO_SOCK)
+# if !defined(OPENSSL_NO_TLS1_2) || !defined(OSSL_NO_USABLE_TLS1_3)
+ ADD_ALL_TESTS(test_ktls, NUM_KTLS_TEST_CIPHERS * 4);
+ ADD_ALL_TESTS(test_ktls_sendfile, NUM_KTLS_TEST_CIPHERS * 2);
+# endif