zte's code,first commit
Change-Id: I9a04da59e459a9bc0d67f101f700d9d7dc8d681b
diff --git a/ap/lib/libwolfssl/install/share/doc/wolfssl/README.txt b/ap/lib/libwolfssl/install/share/doc/wolfssl/README.txt
new file mode 100644
index 0000000..efaed1b
--- /dev/null
+++ b/ap/lib/libwolfssl/install/share/doc/wolfssl/README.txt
@@ -0,0 +1,8 @@
+The wolfSSL manual is available at:
+http://www.wolfssl.com/documentation/wolfSSL-Manual.pdf
+
+The wolfSSL API guide is available at:
+https://www.wolfssl.com/doxygen/wolfssl_API.html
+
+The wolfCrypt API guide is available at:
+https://www.wolfssl.com/doxygen/wolfcrypt_API.html
diff --git a/ap/lib/libwolfssl/install/share/doc/wolfssl/example/client.c b/ap/lib/libwolfssl/install/share/doc/wolfssl/example/client.c
new file mode 100644
index 0000000..6772c82
--- /dev/null
+++ b/ap/lib/libwolfssl/install/share/doc/wolfssl/example/client.c
@@ -0,0 +1,4018 @@
+/* client.c
+ *
+ * Copyright (C) 2006-2021 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL.
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
+ */
+
+#ifdef HAVE_CONFIG_H
+ #include <config.h>
+#endif
+
+#ifndef WOLFSSL_USER_SETTINGS
+ #include <wolfssl/options.h>
+#endif
+#include <wolfssl/wolfcrypt/settings.h>
+
+#include <wolfssl/ssl.h>
+
+#ifdef WOLFSSL_WOLFSENTRY_HOOKS
+#include <wolfsentry/wolfsentry.h>
+#if !defined(NO_FILESYSTEM) && !defined(WOLFSENTRY_NO_JSON)
+static const char *wolfsentry_config_path = NULL;
+#endif
+#endif /* WOLFSSL_WOLFSENTRY_HOOKS */
+
+#if defined(WOLFSSL_MDK_ARM) || defined(WOLFSSL_KEIL_TCP_NET)
+ #include <stdio.h>
+ #include <string.h>
+ #include "rl_fs.h"
+ #include "rl_net.h"
+#endif
+
+#include <wolfssl/test.h>
+
+#include <examples/client/client.h>
+#include <wolfssl/error-ssl.h>
+
+#ifndef NO_WOLFSSL_CLIENT
+
+#ifdef NO_FILESYSTEM
+#ifdef NO_RSA
+#error currently the example only tries to load in a RSA buffer
+#endif
+#undef USE_CERT_BUFFERS_256
+#define USE_CERT_BUFFERS_256
+#undef USE_CERT_BUFFERS_2048
+#define USE_CERT_BUFFERS_2048
+#include <wolfssl/certs_test.h>
+#endif
+
+#ifdef USE_FAST_MATH
+ /* included to inspect the size of FP_MAX_BITS */
+ /* need integer.h header to make sure right math version used */
+ #include <wolfssl/wolfcrypt/integer.h>
+#endif
+#ifdef HAVE_ECC
+ #include <wolfssl/wolfcrypt/ecc.h>
+#endif
+
+#ifdef WOLFSSL_ASYNC_CRYPT
+ static int devId = INVALID_DEVID;
+#endif
+
+#define DEFAULT_TIMEOUT_SEC 2
+#ifndef MAX_NON_BLOCK_SEC
+#define MAX_NON_BLOCK_SEC 10
+#endif
+
+#define OCSP_STAPLING 1
+#define OCSP_STAPLINGV2 2
+#define OCSP_STAPLINGV2_MULTI 3
+#define OCSP_STAPLING_OPT_MAX OCSP_STAPLINGV2_MULTI
+
+#ifdef WOLFSSL_ALT_TEST_STRINGS
+ #define TEST_STR_TERM "\n"
+#else
+ #define TEST_STR_TERM
+#endif
+
+static const char kHelloMsg[] = "hello wolfssl!" TEST_STR_TERM;
+#ifndef NO_SESSION_CACHE
+static const char kResumeMsg[] = "resuming wolfssl!" TEST_STR_TERM;
+#endif
+
+#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_EARLY_DATA)
+ static const char kEarlyMsg[] = "A drop of info" TEST_STR_TERM;
+#endif
+static const char kHttpGetMsg[] = "GET /index.html HTTP/1.0\r\n\r\n";
+
+/* Write needs to be largest of the above strings (29) */
+#define CLI_MSG_SZ 32
+/* Read needs to be at least sizeof server.c `webServerMsg` (226) */
+#define CLI_REPLY_SZ 256
+
+#if defined(XSLEEP_US) && defined(NO_MAIN_DRIVER)
+ /* This is to force the server's thread to get a chance to
+ * execute before continuing the resume in non-blocking
+ * DTLS test cases. */
+ #define TEST_DELAY() XSLEEP_US(10000)
+#else
+ #define TEST_DELAY() XSLEEP_MS(1000)
+#endif
+
+/* Note on using port 0: the client standalone example doesn't utilize the
+ * port 0 port sharing; that is used by (1) the server in external control
+ * test mode and (2) the testsuite which uses this code and sets up the correct
+ * port numbers when the internal thread using the server code using port 0. */
+
+static int lng_index = 0;
+#ifdef WOLFSSL_CALLBACKS
+ WOLFSSL_TIMEVAL timeoutConnect;
+ static int handShakeCB(HandShakeInfo* info)
+ {
+ (void)info;
+ return 0;
+ }
+
+ static int timeoutCB(TimeoutInfo* info)
+ {
+ (void)info;
+ return 0;
+ }
+
+#endif
+
+#ifdef HAVE_SESSION_TICKET
+ static int sessionTicketCB(WOLFSSL* ssl,
+ const unsigned char* ticket, int ticketSz,
+ void* ctx)
+ {
+ (void)ssl;
+ (void)ticket;
+ printf("Session Ticket CB: ticketSz = %d, ctx = %s\n",
+ ticketSz, (char*)ctx);
+ return 0;
+ }
+#endif
+
+static int NonBlockingSSL_Connect(WOLFSSL* ssl)
+{
+ int ret;
+ int error;
+ SOCKET_T sockfd;
+ int select_ret = 0;
+ int elapsedSec = 0;
+
+#ifndef WOLFSSL_CALLBACKS
+ ret = wolfSSL_connect(ssl);
+#else
+ ret = wolfSSL_connect_ex(ssl, handShakeCB, timeoutCB, timeoutConnect);
+#endif
+ error = wolfSSL_get_error(ssl, 0);
+ sockfd = (SOCKET_T)wolfSSL_get_fd(ssl);
+
+ while (ret != WOLFSSL_SUCCESS &&
+ (error == WOLFSSL_ERROR_WANT_READ || error == WOLFSSL_ERROR_WANT_WRITE
+ #ifdef WOLFSSL_ASYNC_CRYPT
+ || error == WC_PENDING_E
+ #endif
+ #ifdef WOLFSSL_NONBLOCK_OCSP
+ || error == OCSP_WANT_READ
+ #endif
+ )) {
+ int currTimeout = 1;
+
+ if (error == WOLFSSL_ERROR_WANT_READ)
+ printf("... client would read block\n");
+ else if (error == WOLFSSL_ERROR_WANT_WRITE)
+ printf("... client would write block\n");
+
+#ifdef WOLFSSL_ASYNC_CRYPT
+ if (error == WC_PENDING_E) {
+ ret = wolfSSL_AsyncPoll(ssl, WOLF_POLL_FLAG_CHECK_HW);
+ if (ret < 0) break;
+ }
+ else
+#endif
+ {
+ if (error == WOLFSSL_ERROR_WANT_WRITE) {
+ select_ret = tcp_select_tx(sockfd, currTimeout);
+
+ }
+ else
+ {
+ #ifdef WOLFSSL_DTLS
+ currTimeout = wolfSSL_dtls_get_current_timeout(ssl);
+ #endif
+ select_ret = tcp_select(sockfd, currTimeout);
+ }
+ }
+
+ if ((select_ret == TEST_RECV_READY) || (select_ret == TEST_SEND_READY)
+ || (select_ret == TEST_ERROR_READY)
+ #ifdef WOLFSSL_ASYNC_CRYPT
+ || error == WC_PENDING_E
+ #endif
+ ) {
+ #ifndef WOLFSSL_CALLBACKS
+ ret = wolfSSL_connect(ssl);
+ #else
+ ret = wolfSSL_connect_ex(ssl, handShakeCB, timeoutCB,
+ timeoutConnect);
+ #endif
+ error = wolfSSL_get_error(ssl, 0);
+ elapsedSec = 0; /* reset elapsed */
+ }
+ else if (select_ret == TEST_TIMEOUT && !wolfSSL_dtls(ssl)) {
+ error = WOLFSSL_ERROR_WANT_READ;
+
+ elapsedSec += currTimeout;
+ if (elapsedSec > MAX_NON_BLOCK_SEC) {
+ printf("Nonblocking connect timeout\n");
+ error = WOLFSSL_FATAL_ERROR;
+ }
+ }
+#ifdef WOLFSSL_DTLS
+ else if (select_ret == TEST_TIMEOUT && wolfSSL_dtls(ssl) &&
+ wolfSSL_dtls_got_timeout(ssl) >= 0) {
+ error = WOLFSSL_ERROR_WANT_READ;
+ }
+#endif
+ else {
+ error = WOLFSSL_FATAL_ERROR;
+ }
+ }
+
+ return ret;
+}
+
+
+static void ShowCiphers(void)
+{
+ static char ciphers[WOLFSSL_CIPHER_LIST_MAX_SIZE];
+
+ int ret = wolfSSL_get_ciphers(ciphers, (int)sizeof(ciphers));
+
+ if (ret == WOLFSSL_SUCCESS)
+ printf("%s\n", ciphers);
+}
+
+/* Shows which versions are valid */
+static void ShowVersions(void)
+{
+#ifndef NO_OLD_TLS
+ #ifdef WOLFSSL_ALLOW_SSLV3
+ printf("0:");
+ #endif
+ #ifdef WOLFSSL_ALLOW_TLSV10
+ printf("1:");
+ #endif
+ printf("2:");
+#endif /* NO_OLD_TLS */
+#ifndef WOLFSSL_NO_TLS12
+ printf("3:");
+#endif
+#ifdef WOLFSSL_TLS13
+ printf("4:");
+#endif
+ printf("d(downgrade):");
+#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EITHER_SIDE)
+ printf("e(either):");
+#endif
+ printf("\n");
+}
+
+#if defined(WOLFSSL_TLS13) && defined(HAVE_SUPPORTED_CURVES)
+#define MAX_GROUP_NUMBER 4
+static void SetKeyShare(WOLFSSL* ssl, int onlyKeyShare, int useX25519,
+ int useX448, int setGroups)
+{
+ int ret;
+ int groups[MAX_GROUP_NUMBER] = {0};
+ int count = 0;
+
+ (void)useX25519;
+ (void)useX448;
+
+ WOLFSSL_START(WC_FUNC_CLIENT_KEY_EXCHANGE_SEND);
+ if (onlyKeyShare == 0 || onlyKeyShare == 2) {
+ if (useX25519) {
+ #ifdef HAVE_CURVE25519
+ do {
+ ret = wolfSSL_UseKeyShare(ssl, WOLFSSL_ECC_X25519);
+ if (ret == WOLFSSL_SUCCESS)
+ groups[count++] = WOLFSSL_ECC_X25519;
+ #ifdef WOLFSSL_ASYNC_CRYPT
+ else if (ret == WC_PENDING_E)
+ wolfSSL_AsyncPoll(ssl, WOLF_POLL_FLAG_CHECK_HW);
+ #endif
+ else
+ err_sys("unable to use curve x25519");
+ } while (ret == WC_PENDING_E);
+ #endif
+ }
+ else if (useX448) {
+ #ifdef HAVE_CURVE448
+ do {
+ ret = wolfSSL_UseKeyShare(ssl, WOLFSSL_ECC_X448);
+ if (ret == WOLFSSL_SUCCESS)
+ groups[count++] = WOLFSSL_ECC_X448;
+ #ifdef WOLFSSL_ASYNC_CRYPT
+ else if (ret == WC_PENDING_E)
+ wolfSSL_AsyncPoll(ssl, WOLF_POLL_FLAG_CHECK_HW);
+ #endif
+ else
+ err_sys("unable to use curve x448");
+ } while (ret == WC_PENDING_E);
+ #endif
+ }
+ else {
+ #ifdef HAVE_ECC
+ #if !defined(NO_ECC256) || defined(HAVE_ALL_CURVES)
+ do {
+ ret = wolfSSL_UseKeyShare(ssl, WOLFSSL_ECC_SECP256R1);
+ if (ret == WOLFSSL_SUCCESS)
+ groups[count++] = WOLFSSL_ECC_SECP256R1;
+ #ifdef WOLFSSL_ASYNC_CRYPT
+ else if (ret == WC_PENDING_E)
+ wolfSSL_AsyncPoll(ssl, WOLF_POLL_FLAG_CHECK_HW);
+ #endif
+ else
+ err_sys("unable to use curve secp256r1");
+ } while (ret == WC_PENDING_E);
+ #endif
+ #endif
+ }
+ }
+ if (onlyKeyShare == 0 || onlyKeyShare == 1) {
+ #ifdef HAVE_FFDHE_2048
+ do {
+ ret = wolfSSL_UseKeyShare(ssl, WOLFSSL_FFDHE_2048);
+ if (ret == WOLFSSL_SUCCESS)
+ groups[count++] = WOLFSSL_FFDHE_2048;
+ #ifdef WOLFSSL_ASYNC_CRYPT
+ else if (ret == WC_PENDING_E)
+ wolfSSL_AsyncPoll(ssl, WOLF_POLL_FLAG_CHECK_HW);
+ #endif
+ else
+ err_sys("unable to use DH 2048-bit parameters");
+ } while (ret == WC_PENDING_E);
+ #endif
+ }
+ if (count >= MAX_GROUP_NUMBER)
+ err_sys("example group array size error");
+ if (setGroups && count > 0) {
+ if (wolfSSL_set_groups(ssl, groups, count) != WOLFSSL_SUCCESS)
+ err_sys("unable to set groups");
+ }
+ WOLFSSL_END(WC_FUNC_CLIENT_KEY_EXCHANGE_SEND);
+}
+#endif /* WOLFSSL_TLS13 && HAVE_SUPPORTED_CURVES */
+
+#ifdef WOLFSSL_EARLY_DATA
+static void EarlyData(WOLFSSL_CTX* ctx, WOLFSSL* ssl, const char* msg,
+ int msgSz, char* buffer)
+{
+ int err;
+ int ret;
+
+ do {
+ err = 0; /* reset error */
+ ret = wolfSSL_write_early_data(ssl, msg, msgSz, &msgSz);
+ if (ret <= 0) {
+ err = wolfSSL_get_error(ssl, 0);
+ #ifdef WOLFSSL_ASYNC_CRYPT
+ if (err == WC_PENDING_E) {
+ ret = wolfSSL_AsyncPoll(ssl, WOLF_POLL_FLAG_CHECK_HW);
+ if (ret < 0) break;
+ }
+ #endif
+ }
+ } while (err == WC_PENDING_E);
+ if (ret != msgSz) {
+ printf("SSL_write_early_data msg error %d, %s\n", err,
+ wolfSSL_ERR_error_string(err, buffer));
+ wolfSSL_free(ssl); ssl = NULL;
+ wolfSSL_CTX_free(ctx); ctx = NULL;
+ err_sys("SSL_write_early_data failed");
+ }
+ do {
+ err = 0; /* reset error */
+ ret = wolfSSL_write_early_data(ssl, msg, msgSz, &msgSz);
+ if (ret <= 0) {
+ err = wolfSSL_get_error(ssl, 0);
+ #ifdef WOLFSSL_ASYNC_CRYPT
+ if (err == WC_PENDING_E) {
+ ret = wolfSSL_AsyncPoll(ssl, WOLF_POLL_FLAG_CHECK_HW);
+ if (ret < 0) break;
+ }
+ #endif
+ }
+ } while (err == WC_PENDING_E);
+ if (ret != msgSz) {
+ printf("SSL_write_early_data msg error %d, %s\n", err,
+ wolfSSL_ERR_error_string(err, buffer));
+ wolfSSL_free(ssl);
+ wolfSSL_CTX_free(ctx);
+ err_sys("SSL_write_early_data failed");
+ }
+}
+#endif
+
+/* Measures average time to create, connect and disconnect a connection (TPS).
+Benchmark = number of connections. */
+static const char* client_bench_conmsg[][5] = {
+ /* English */
+ {
+ "wolfSSL_resume avg took:", "milliseconds\n",
+ "wolfSSL_connect avg took:", "milliseconds\n",
+ NULL
+ },
+ #ifndef NO_MULTIBYTE_PRINT
+ /* Japanese */
+ {
+ "wolfSSL_resume 平均時間:", "ミリ秒\n",
+ "wolfSSL_connect 平均時間:", "ミリ秒\n",
+ }
+ #endif
+};
+
+static int ClientBenchmarkConnections(WOLFSSL_CTX* ctx, char* host, word16 port,
+ int dtlsUDP, int dtlsSCTP, int benchmark, int resumeSession, int useX25519,
+ int useX448, int helloRetry, int onlyKeyShare, int version, int earlyData)
+{
+ /* time passed in number of connects give average */
+ int times = benchmark, skip = times * 0.1;
+ int loops = resumeSession ? 2 : 1;
+ int i = 0, err, ret;
+#ifndef NO_SESSION_CACHE
+ WOLFSSL_SESSION* benchSession = NULL;
+#endif
+#ifdef WOLFSSL_TLS13
+ byte reply[CLI_REPLY_SZ];
+#endif
+ const char** words = client_bench_conmsg[lng_index];
+
+ (void)resumeSession;
+ (void)useX25519;
+ (void)useX448;
+ (void)helloRetry;
+ (void)onlyKeyShare;
+ (void)version;
+ (void)earlyData;
+
+ while (loops--) {
+ #ifndef NO_SESSION_CACHE
+ int benchResume = resumeSession && loops == 0;
+ #endif
+ double start = current_time(1), avg;
+
+ for (i = 0; i < times; i++) {
+ SOCKET_T sockfd;
+ WOLFSSL* ssl;
+
+ if (i == skip)
+ start = current_time(1);
+
+ ssl = wolfSSL_new(ctx);
+ if (ssl == NULL)
+ err_sys("unable to get SSL object");
+
+ #ifndef NO_SESSION_CACHE
+ if (benchResume)
+ wolfSSL_set_session(ssl, benchSession);
+ #endif
+ #if defined(WOLFSSL_TLS13) && defined(HAVE_SUPPORTED_CURVES)
+ else if (version >= 4) {
+ if (!helloRetry)
+ SetKeyShare(ssl, onlyKeyShare, useX25519, useX448, 1);
+ else
+ wolfSSL_NoKeyShares(ssl);
+ }
+ #endif
+
+ tcp_connect(&sockfd, host, port, dtlsUDP, dtlsSCTP, ssl);
+
+ if (wolfSSL_set_fd(ssl, sockfd) != WOLFSSL_SUCCESS) {
+ err_sys("error in setting fd");
+ }
+
+ #if defined(WOLFSSL_TLS13) && !defined(NO_SESSION_CACHE) && \
+ defined(WOLFSSL_EARLY_DATA)
+ if (version >= 4 && benchResume && earlyData) {
+ char buffer[WOLFSSL_MAX_ERROR_SZ];
+ EarlyData(ctx, ssl, kEarlyMsg, sizeof(kEarlyMsg)-1, buffer);
+ }
+ #endif
+ do {
+ err = 0; /* reset error */
+ ret = wolfSSL_connect(ssl);
+#ifdef WOLFSSL_EARLY_DATA
+ EarlyDataStatus(ssl);
+#endif
+ if (ret != WOLFSSL_SUCCESS) {
+ err = wolfSSL_get_error(ssl, 0);
+ #ifdef WOLFSSL_ASYNC_CRYPT
+ if (err == WC_PENDING_E) {
+ ret = wolfSSL_AsyncPoll(ssl, WOLF_POLL_FLAG_CHECK_HW);
+ if (ret < 0) break;
+ }
+ #endif
+ }
+ } while (err == WC_PENDING_E);
+ if (ret != WOLFSSL_SUCCESS) {
+ err_sys("SSL_connect failed");
+ }
+
+ #ifdef WOLFSSL_TLS13
+ #ifndef NO_SESSION_CACHE
+ if (version >= 4 && resumeSession && !benchResume)
+ #else
+ if (version >= 4 && resumeSession)
+ #endif
+ {
+ /* no null term */
+ if (wolfSSL_write(ssl, kHttpGetMsg, sizeof(kHttpGetMsg)-1) <= 0)
+ err_sys("SSL_write failed");
+
+ if (wolfSSL_read(ssl, reply, sizeof(reply)-1) <= 0)
+ err_sys("SSL_read failed");
+ }
+ #endif
+
+
+ wolfSSL_shutdown(ssl);
+ #ifndef NO_SESSION_CACHE
+ if (i == (times-1) && resumeSession) {
+ benchSession = wolfSSL_get_session(ssl);
+ }
+ #endif
+ wolfSSL_free(ssl); ssl = NULL;
+ CloseSocket(sockfd);
+ }
+ avg = current_time(0) - start;
+ avg /= (times - skip);
+ avg *= 1000; /* milliseconds */
+ #ifndef NO_SESSION_CACHE
+ if (benchResume)
+ printf("%s %8.3f %s\n", words[0],avg, words[1]);
+ else
+ #endif
+ printf("%s %8.3f %s\n", words[2],avg, words[3]);
+
+ WOLFSSL_TIME(times);
+ }
+
+ return EXIT_SUCCESS;
+}
+
+/* Measures throughput in mbps. Throughput = number of bytes */
+static int ClientBenchmarkThroughput(WOLFSSL_CTX* ctx, char* host, word16 port,
+ int dtlsUDP, int dtlsSCTP, int block, size_t throughput, int useX25519,
+ int useX448, int exitWithRet, int version, int onlyKeyShare)
+{
+ double start, conn_time = 0, tx_time = 0, rx_time = 0;
+ SOCKET_T sockfd;
+ WOLFSSL* ssl;
+ int ret = 0, err = 0;
+
+ start = current_time(1);
+ ssl = wolfSSL_new(ctx);
+ if (ssl == NULL)
+ err_sys("unable to get SSL object");
+
+ tcp_connect(&sockfd, host, port, dtlsUDP, dtlsSCTP, ssl);
+ if (wolfSSL_set_fd(ssl, sockfd) != WOLFSSL_SUCCESS) {
+ err_sys("error in setting fd");
+ }
+
+ (void)useX25519;
+ (void)useX448;
+ (void)version;
+ (void)onlyKeyShare;
+#if defined(WOLFSSL_TLS13) && defined(HAVE_SUPPORTED_CURVES)
+ if (version >= 4) {
+ SetKeyShare(ssl, onlyKeyShare, useX25519, useX448, 1);
+ }
+#endif
+
+ do {
+ err = 0; /* reset error */
+ ret = wolfSSL_connect(ssl);
+ if (ret != WOLFSSL_SUCCESS) {
+ err = wolfSSL_get_error(ssl, 0);
+ #ifdef WOLFSSL_ASYNC_CRYPT
+ if (err == WC_PENDING_E) {
+ ret = wolfSSL_AsyncPoll(ssl, WOLF_POLL_FLAG_CHECK_HW);
+ if (ret < 0) break;
+ }
+ #endif
+ }
+ } while (err == WC_PENDING_E);
+ if (ret == WOLFSSL_SUCCESS) {
+ /* Perform throughput test */
+ char *tx_buffer, *rx_buffer;
+
+ /* Record connection time */
+ conn_time = current_time(0) - start;
+
+ /* Allocate TX/RX buffers */
+ tx_buffer = (char*)XMALLOC(block, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+ rx_buffer = (char*)XMALLOC(block, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+ if (tx_buffer && rx_buffer) {
+ WC_RNG rng;
+
+ /* Startup the RNG */
+ #if !defined(HAVE_FIPS) && defined(WOLFSSL_ASYNC_CRYPT)
+ ret = wc_InitRng_ex(&rng, NULL, devId);
+ #else
+ ret = wc_InitRng(&rng);
+ #endif
+ if (ret == 0) {
+ size_t xfer_bytes;
+
+ /* Generate random data to send */
+ ret = wc_RNG_GenerateBlock(&rng, (byte*)tx_buffer, block);
+ wc_FreeRng(&rng);
+ if(ret != 0) {
+ err_sys("wc_RNG_GenerateBlock failed");
+ }
+
+ /* Perform TX and RX of bytes */
+ xfer_bytes = 0;
+ while (throughput > xfer_bytes) {
+ int len, rx_pos, select_ret;
+
+ /* Determine packet size */
+ len = min(block, (int)(throughput - xfer_bytes));
+
+ /* Perform TX */
+ start = current_time(1);
+ do {
+ err = 0; /* reset error */
+ ret = wolfSSL_write(ssl, tx_buffer, len);
+ if (ret <= 0) {
+ err = wolfSSL_get_error(ssl, 0);
+ #ifdef WOLFSSL_ASYNC_CRYPT
+ if (err == WC_PENDING_E) {
+ ret = wolfSSL_AsyncPoll(ssl, WOLF_POLL_FLAG_CHECK_HW);
+ if (ret < 0) break;
+ }
+ #endif
+ }
+ } while (err == WC_PENDING_E);
+ if (ret != len) {
+ printf("SSL_write bench error %d!\n", err);
+ if (!exitWithRet)
+ err_sys("SSL_write failed");
+ goto doExit;
+ }
+ tx_time += current_time(0) - start;
+
+ /* Perform RX */
+ select_ret = tcp_select(sockfd, DEFAULT_TIMEOUT_SEC);
+ if (select_ret == TEST_RECV_READY) {
+ start = current_time(1);
+ rx_pos = 0;
+ while (rx_pos < len) {
+ ret = wolfSSL_read(ssl, &rx_buffer[rx_pos],
+ len - rx_pos);
+ if (ret <= 0) {
+ err = wolfSSL_get_error(ssl, 0);
+ #ifdef WOLFSSL_ASYNC_CRYPT
+ if (err == WC_PENDING_E) {
+ ret = wolfSSL_AsyncPoll(ssl, WOLF_POLL_FLAG_CHECK_HW);
+ if (ret < 0) break;
+ }
+ else
+ #endif
+ if (err != WOLFSSL_ERROR_WANT_READ) {
+ printf("SSL_read bench error %d\n", err);
+ err_sys("SSL_read failed");
+ }
+ }
+ else {
+ rx_pos += ret;
+ }
+ }
+ rx_time += current_time(0) - start;
+ }
+
+ /* Compare TX and RX buffers */
+ if (XMEMCMP(tx_buffer, rx_buffer, len) != 0) {
+ free(tx_buffer);
+ tx_buffer = NULL;
+ free(rx_buffer);
+ rx_buffer = NULL;
+ err_sys("Compare TX and RX buffers failed");
+ }
+
+ /* Update overall position */
+ xfer_bytes += len;
+ }
+ }
+ else {
+ err_sys("wc_InitRng failed");
+ }
+ (void)rng; /* for WC_NO_RNG case */
+ }
+ else {
+ err_sys("Client buffer malloc failed");
+ }
+doExit:
+ if (tx_buffer) XFREE(tx_buffer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+ if (rx_buffer) XFREE(rx_buffer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+ }
+ else {
+ err_sys("wolfSSL_connect failed");
+ }
+
+ wolfSSL_shutdown(ssl);
+ wolfSSL_free(ssl); ssl = NULL;
+ CloseSocket(sockfd);
+
+ if (exitWithRet)
+ return err;
+
+ printf(
+#if !defined(__MINGW32__)
+ "wolfSSL Client Benchmark %zu bytes\n"
+#else
+ "wolfSSL Client Benchmark %d bytes\n"
+#endif
+ "\tConnect %8.3f ms\n"
+ "\tTX %8.3f ms (%8.3f MBps)\n"
+ "\tRX %8.3f ms (%8.3f MBps)\n",
+#if !defined(__MINGW32__)
+ throughput,
+#else
+ (int)throughput,
+#endif
+ conn_time * 1000,
+ tx_time * 1000, throughput / tx_time / 1024 / 1024,
+ rx_time * 1000, throughput / rx_time / 1024 / 1024
+ );
+
+ return EXIT_SUCCESS;
+}
+
+const char* starttlsCmd[6] = {
+ "220",
+ "EHLO mail.example.com\r\n",
+ "250",
+ "STARTTLS\r\n",
+ "220",
+ "QUIT\r\n",
+};
+
+/* Initiates the STARTTLS command sequence over TCP */
+static int StartTLS_Init(SOCKET_T* sockfd)
+{
+ char tmpBuf[256];
+
+ if (sockfd == NULL)
+ return BAD_FUNC_ARG;
+
+ /* S: 220 <host> SMTP service ready */
+ XMEMSET(tmpBuf, 0, sizeof(tmpBuf));
+ if (recv(*sockfd, tmpBuf, sizeof(tmpBuf)-1, 0) < 0)
+ err_sys("failed to read STARTTLS command\n");
+
+ if (!XSTRNCMP(tmpBuf, starttlsCmd[0], XSTRLEN(starttlsCmd[0]))) {
+ printf("%s\n", tmpBuf);
+ } else {
+ err_sys("incorrect STARTTLS command received");
+ }
+
+ /* C: EHLO mail.example.com */
+ if (send(*sockfd, starttlsCmd[1], (int)XSTRLEN(starttlsCmd[1]), 0) !=
+ (int)XSTRLEN(starttlsCmd[1]))
+ err_sys("failed to send STARTTLS EHLO command\n");
+
+ /* S: 250 <host> offers a warm hug of welcome */
+ XMEMSET(tmpBuf, 0, sizeof(tmpBuf));
+ if (recv(*sockfd, tmpBuf, sizeof(tmpBuf)-1, 0) < 0)
+ err_sys("failed to read STARTTLS command\n");
+
+ if (!XSTRNCMP(tmpBuf, starttlsCmd[2], XSTRLEN(starttlsCmd[2]))) {
+ printf("%s\n", tmpBuf);
+ } else {
+ err_sys("incorrect STARTTLS command received");
+ }
+
+ /* C: STARTTLS */
+ if (send(*sockfd, starttlsCmd[3], (int)XSTRLEN(starttlsCmd[3]), 0) !=
+ (int)XSTRLEN(starttlsCmd[3])) {
+ err_sys("failed to send STARTTLS command\n");
+ }
+
+ /* S: 220 Go ahead */
+ XMEMSET(tmpBuf, 0, sizeof(tmpBuf));
+ if (recv(*sockfd, tmpBuf, sizeof(tmpBuf)-1, 0) < 0)
+ err_sys("failed to read STARTTLS command\n");
+ tmpBuf[sizeof(tmpBuf)-1] = '\0';
+ if (!XSTRNCMP(tmpBuf, starttlsCmd[4], XSTRLEN(starttlsCmd[4]))) {
+ printf("%s\n", tmpBuf);
+ } else {
+ err_sys("incorrect STARTTLS command received, expected 220");
+ }
+
+ return WOLFSSL_SUCCESS;
+}
+
+/* Closes down the SMTP connection */
+static int SMTP_Shutdown(WOLFSSL* ssl, int wc_shutdown)
+{
+ int ret, err = 0;
+ char tmpBuf[256];
+
+ if (ssl == NULL)
+ return BAD_FUNC_ARG;
+
+ printf("\nwolfSSL client shutting down SMTP connection\n");
+
+ XMEMSET(tmpBuf, 0, sizeof(tmpBuf));
+
+ /* C: QUIT */
+ do {
+ ret = wolfSSL_write(ssl, starttlsCmd[5], (int)XSTRLEN(starttlsCmd[5]));
+ if (ret < 0) {
+ err = wolfSSL_get_error(ssl, 0);
+ #ifdef WOLFSSL_ASYNC_CRYPT
+ if (err == WC_PENDING_E) {
+ ret = wolfSSL_AsyncPoll(ssl, WOLF_POLL_FLAG_CHECK_HW);
+ if (ret < 0) break;
+ }
+ #endif
+ }
+ } while (err == WC_PENDING_E);
+ if (ret != (int)XSTRLEN(starttlsCmd[5])) {
+ err_sys("failed to send SMTP QUIT command\n");
+ }
+
+ /* S: 221 2.0.0 Service closing transmission channel */
+ do {
+ ret = wolfSSL_read(ssl, tmpBuf, sizeof(tmpBuf)-1);
+ if (ret < 0) {
+ err = wolfSSL_get_error(ssl, 0);
+ #ifdef WOLFSSL_ASYNC_CRYPT
+ if (err == WC_PENDING_E) {
+ ret = wolfSSL_AsyncPoll(ssl, WOLF_POLL_FLAG_CHECK_HW);
+ if (ret < 0) break;
+ }
+ #endif
+ }
+ } while (err == WC_PENDING_E);
+ if (ret < 0) {
+ err_sys("failed to read SMTP closing down response\n");
+ }
+ tmpBuf[ret] = 0; /* null terminate message */
+ printf("%s\n", tmpBuf);
+
+ ret = wolfSSL_shutdown(ssl);
+ if (wc_shutdown && ret == WOLFSSL_SHUTDOWN_NOT_DONE) {
+ if (tcp_select(wolfSSL_get_fd(ssl), DEFAULT_TIMEOUT_SEC) ==
+ TEST_RECV_READY) {
+ ret = wolfSSL_shutdown(ssl); /* bidirectional shutdown */
+ if (ret == WOLFSSL_SUCCESS)
+ printf("Bidirectional shutdown complete\n");
+ }
+ if (ret != WOLFSSL_SUCCESS)
+ printf("Bidirectional shutdown failed\n");
+ }
+
+ return WOLFSSL_SUCCESS;
+}
+
+static int ClientWrite(WOLFSSL* ssl, const char* msg, int msgSz, const char* str,
+ int exitWithRet)
+{
+ int ret, err;
+ char buffer[WOLFSSL_MAX_ERROR_SZ];
+
+ do {
+ err = 0; /* reset error */
+ ret = wolfSSL_write(ssl, msg, msgSz);
+ if (ret <= 0) {
+ err = wolfSSL_get_error(ssl, 0);
+ #ifdef WOLFSSL_ASYNC_CRYPT
+ if (err == WC_PENDING_E) {
+ ret = wolfSSL_AsyncPoll(ssl, WOLF_POLL_FLAG_CHECK_HW);
+ if (ret < 0) break;
+ }
+ #endif
+ }
+ } while (err == WOLFSSL_ERROR_WANT_WRITE ||
+ err == WOLFSSL_ERROR_WANT_READ
+ #ifdef WOLFSSL_ASYNC_CRYPT
+ || err == WC_PENDING_E
+ #endif
+ );
+ if (ret != msgSz) {
+ printf("SSL_write%s msg error %d, %s\n", str, err,
+ wolfSSL_ERR_error_string(err, buffer));
+ if (!exitWithRet) {
+ err_sys("SSL_write failed");
+ }
+ }
+
+ return err;
+}
+
+static int ClientRead(WOLFSSL* ssl, char* reply, int replyLen, int mustRead,
+ const char* str, int exitWithRet)
+{
+ int ret, err;
+ char buffer[WOLFSSL_MAX_ERROR_SZ];
+ double start = current_time(1), elapsed;
+
+ do {
+ err = 0; /* reset error */
+ ret = wolfSSL_read(ssl, reply, replyLen);
+ if (ret <= 0) {
+ err = wolfSSL_get_error(ssl, 0);
+ #ifdef WOLFSSL_ASYNC_CRYPT
+ if (err == WC_PENDING_E) {
+ ret = wolfSSL_AsyncPoll(ssl, WOLF_POLL_FLAG_CHECK_HW);
+ if (ret < 0) break;
+ }
+ else
+ #endif
+ if (err != WOLFSSL_ERROR_WANT_READ) {
+ printf("SSL_read reply error %d, %s\n", err,
+ wolfSSL_ERR_error_string(err, buffer));
+ if (!exitWithRet) {
+ err_sys("SSL_read failed");
+ }
+ else {
+ break;
+ }
+ }
+ }
+
+ if (mustRead && err == WOLFSSL_ERROR_WANT_READ) {
+ elapsed = current_time(0) - start;
+ if (elapsed > MAX_NON_BLOCK_SEC) {
+ printf("Nonblocking read timeout\n");
+ ret = WOLFSSL_FATAL_ERROR;
+ break;
+ }
+ }
+ } while ((mustRead && err == WOLFSSL_ERROR_WANT_READ)
+ #ifdef WOLFSSL_ASYNC_CRYPT
+ || err == WC_PENDING_E
+ #endif
+ );
+ if (ret > 0) {
+ reply[ret] = 0; /* null terminate */
+ printf("%s%s\n", str, reply);
+ }
+
+ return err;
+}
+
+
+/* when adding new option, please follow the steps below: */
+/* 1. add new option message in English section */
+/* 2. increase the number of the second column */
+/* 3. increase the array dimension */
+/* 4. add the same message into Japanese section */
+/* (will be translated later) */
+/* 5. add printf() into suitable position of Usage() */
+static const char* client_usage_msg[][69] = {
+ /* English */
+ {
+ " NOTE: All files relative to wolfSSL home dir\n", /* 0 */
+ "Max RSA key size in bits for build is set at : ", /* 1 */
+#ifdef NO_RSA
+ "RSA not supported\n", /* 2 */
+#elif defined(WOLFSSL_SP_MATH) /* case of SP math only */
+#ifdef WOLFSSL_SP_4096
+ "4096\n", /* 2 */
+#elif !defined(WOLFSSL_SP_NO_3072)
+ "3072\n", /* 2 */
+#elif !defined(WOLFSSL_SP_NO_2048)
+ "2048\n", /* 2 */
+#else
+ "0\n", /* 2 */
+#endif
+#elif defined(USE_FAST_MATH)
+#else
+ "INFINITE\n", /* 2 */
+#endif
+ "-? <num> Help, print this usage\n"
+ " 0: English, 1: Japanese\n"
+ "--help Help, in English\n", /* 3 */
+ "-h <host> Host to connect to, default", /* 4 */
+ "-p <num> Port to connect on, not 0, default", /* 5 */
+
+#ifndef WOLFSSL_TLS13
+ "-v <num> SSL version [0-3], SSLv3(0) - TLS1.2(3)), default", /* 6 */
+ "-V Prints valid ssl version numbers"
+ ", SSLv3(0) - TLS1.2(3)\n", /* 7 */
+#else
+ "-v <num> SSL version [0-4], SSLv3(0) - TLS1.3(4)), default", /* 6 */
+ "-V Prints valid ssl version numbers,"
+ " SSLv3(0) - TLS1.3(4)\n", /* 7 */
+#endif
+ "-l <str> Cipher suite list (: delimited)\n", /* 8 */
+#ifndef NO_CERTS
+ "-c <file> Certificate file, default", /* 9 */
+ "-k <file> Key file, default", /* 10 */
+ "-A <file> Certificate Authority file, default", /* 11 */
+#endif
+#ifndef NO_DH
+ "-Z <num> Minimum DH key bits, default", /* 12 */
+#endif
+ "-b <num> Benchmark <num> connections and print stats\n", /* 13 */
+#ifdef HAVE_ALPN
+ "-L <str> Application-Layer Protocol"
+ " Negotiation ({C,F}:<list>)\n", /* 14 */
+#endif
+ "-B <num> Benchmark throughput"
+ " using <num> bytes and print stats\n", /* 15 */
+#ifndef NO_PSK
+ "-s Use pre Shared keys\n", /* 16 */
+#endif
+ "-d Disable peer checks\n", /* 17 */
+ "-D Override Date Errors example\n", /* 18 */
+ "-e List Every cipher suite available, \n", /* 19 */
+ "-g Send server HTTP GET\n", /* 20 */
+ "-u Use UDP DTLS,"
+ " add -v 2 for DTLSv1, -v 3 for DTLSv1.2 (default)\n", /* 21 */
+#ifdef WOLFSSL_SCTP
+ "-G Use SCTP DTLS,"
+ " add -v 2 for DTLSv1, -v 3 for DTLSv1.2 (default)\n", /* 22 */
+#endif
+#ifndef NO_CERTS
+ "-m Match domain name in cert\n", /* 23 */
+#endif
+ "-N Use Non-blocking sockets\n", /* 24 */
+#ifndef NO_SESSION_CACHE
+ "-r Resume session\n", /* 25 */
+#endif
+ "-w Wait for bidirectional shutdown\n", /* 26 */
+ "-M <prot> Use STARTTLS, using <prot> protocol (smtp)\n", /* 27 */
+#ifdef HAVE_SECURE_RENEGOTIATION
+ "-R Allow Secure Renegotiation\n", /* 28 */
+ "-i <str> Force client Initiated Secure Renegotiation. If the\n"
+ " string 'scr-app-data' is passed in as the value and\n"
+ " Non-blocking sockets are enabled ('-N') then wolfSSL\n"
+ " sends a test message during the secure renegotiation.\n"
+ " The string parameter is optional.\n", /* 29 */
+#endif
+ "-f Fewer packets/group messages\n", /* 30 */
+#ifndef NO_CERTS
+ "-x Disable client cert/key loading\n", /* 31 */
+#endif
+ "-X Driven by eXternal test case\n", /* 32 */
+ "-j Use verify callback override\n", /* 33 */
+#ifdef SHOW_SIZES
+ "-z Print structure sizes\n", /* 34 */
+#endif
+#ifdef HAVE_SNI
+ "-S <str> Use Host Name Indication\n", /* 35 */
+#endif
+#ifdef HAVE_MAX_FRAGMENT
+ "-F <num> Use Maximum Fragment Length [1-6]\n", /* 36 */
+#endif
+#ifdef HAVE_TRUNCATED_HMAC
+ "-T Use Truncated HMAC\n", /* 37 */
+#endif
+#ifdef HAVE_EXTENDED_MASTER
+ "-n Disable Extended Master Secret\n", /* 38 */
+#endif
+#ifdef HAVE_OCSP
+ "-o Perform OCSP lookup on peer certificate\n", /* 39 */
+ "-O <url> Perform OCSP lookup using <url> as responder\n", /* 40 */
+#endif
+#if defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
+ || defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
+ "-W <num> Use OCSP Stapling (1 v1, 2 v2, 3 v2 multi)\n", /* 41 */
+ " With 'm' at end indicates MUST staple\n", /* 42 */
+#endif
+#if defined(ATOMIC_USER) && !defined(WOLFSSL_AEAD_ONLY)
+ "-U Atomic User Record Layer Callbacks\n", /* 43 */
+#endif
+#ifdef HAVE_PK_CALLBACKS
+ "-P Public Key Callbacks\n", /* 44 */
+#endif
+#ifdef HAVE_ANON
+ "-a Anonymous client\n", /* 45 */
+#endif
+#ifdef HAVE_CRL
+ "-C Disable CRL\n", /* 46 */
+#endif
+#ifdef WOLFSSL_TRUST_PEER_CERT
+ "-E <file> Path to load trusted peer cert\n", /* 47 */
+#endif
+#ifdef HAVE_WNR
+ "-q <file> Whitewood config file, defaults\n", /* 48 */
+#endif
+ "-H <arg> Internal tests"
+ " [defCipherList, exitWithRet, verifyFail, useSupCurve,\n", /* 49 */
+ " loadSSL, disallowETM]\n", /* 50 */
+#ifdef WOLFSSL_TLS13
+ "-J Use HelloRetryRequest to choose group for KE\n", /* 51 */
+ "-K Key Exchange for PSK not using (EC)DHE\n", /* 52 */
+ "-I Update keys and IVs before sending data\n", /* 53 */
+#ifndef NO_DH
+ "-y Key Share with FFDHE named groups only\n", /* 54 */
+#endif
+#ifdef HAVE_ECC
+ "-Y Key Share with ECC named groups only\n", /* 55 */
+#endif
+#endif /* WOLFSSL_TLS13 */
+#ifdef HAVE_CURVE25519
+ "-t Use X25519 for key exchange\n", /* 56 */
+#endif
+#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_POST_HANDSHAKE_AUTH)
+ "-Q Support requesting certificate post-handshake\n", /* 57 */
+#endif
+#ifdef WOLFSSL_EARLY_DATA
+ "-0 Early data sent to server (0-RTT handshake)\n", /* 58 */
+#endif
+#ifdef WOLFSSL_MULTICAST
+ "-3 <grpid> Multicast, grpid < 256\n", /* 59 */
+#endif
+ "-1 <num> Display a result by specified language.\n"
+ " 0: English, 1: Japanese\n", /* 60 */
+#if !defined(NO_DH) && !defined(HAVE_FIPS) && \
+ !defined(HAVE_SELFTEST) && !defined(WOLFSSL_OLD_PRIME_CHECK)
+ "-2 Disable DH Prime check\n", /* 61 */
+#endif
+#ifdef HAVE_SECURE_RENEGOTIATION
+ "-4 Use resumption for renegotiation\n", /* 62 */
+#endif
+#ifdef HAVE_TRUSTED_CA
+ "-5 Use Trusted CA Key Indication\n", /* 63 */
+#endif
+ "-6 Simulate WANT_WRITE errors on every other IO send\n",
+#ifdef HAVE_CURVE448
+ "-8 Use X448 for key exchange\n", /* 66 */
+#endif
+#if defined(OPENSSL_ALL) && defined(WOLFSSL_CERT_GEN) && \
+ (defined(WOLFSSL_CERT_REQ) || defined(WOLFSSL_CERT_EXT)) && \
+ !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR)
+ "-9 Use hash dir look up for certificate loading\n"
+ " loading from <wolfSSL home>/certs folder\n"
+ " files in the folder would have the form \"hash.N\" file name\n"
+ " e.g symbolic link to the file at certs folder\n"
+ " ln -s ca-cert.pem `openssl x509 -in ca-cert.pem -hash -noout`.0\n",
+ /* 67 */
+#endif
+#if defined(WOLFSSL_WOLFSENTRY_HOOKS) && !defined(NO_FILESYSTEM) && \
+ !defined(WOLFSENTRY_NO_JSON)
+ "--wolfsentry-config <file> Path for JSON wolfSentry config\n",
+ /* 68 */
+#endif
+#ifndef WOLFSSL_TLS13
+ "-7 Set minimum downgrade protocol version [0-3] "
+ " SSLv3(0) - TLS1.2(3)\n",
+#else
+ "-7 Set minimum downgrade protocol version [0-4] "
+ " SSLv3(0) - TLS1.3(4)\n", /* 69 */
+#endif
+ NULL,
+ },
+#ifndef NO_MULTIBYTE_PRINT
+ /* Japanese */
+ {
+ " 注意 : 全てのファイルは wolfSSL ホーム・ディレクトリからの相対です。"
+ "\n", /* 0 */
+ "RSAの最大ビットは次のように設定されています: ", /* 1 */
+#ifdef NO_RSA
+ "RSAはサポートされていません。\n", /* 2 */
+#elif defined(WOLFSSL_SP_MATH) /* case of SP math only */
+#ifndef WOLFSSL_SP_NO_3072
+ "3072\n", /* 2 */
+#elif !defined(WOLFSSL_SP_NO_2048)
+ "2048\n", /* 2 */
+#else
+ "0\n", /* 2 */
+#endif
+#elif defined(USE_FAST_MATH)
+#else
+ "無限\n", /* 2 */
+#endif
+ "-? <num> ヘルプ, 使い方を表示\n"
+ " 0: 英語、 1: 日本語\n"
+ "--ヘルプ 使い方を表示, 日本語で\n", /* 3 */
+ "-h <host> 接続先ホスト, 既定値", /* 4 */
+ "-p <num> 接続先ポート, 0は無効, 既定値", /* 5 */
+
+#ifndef WOLFSSL_TLS13
+ "-v <num> SSL バージョン [0-3], SSLv3(0) - TLS1.2(3)),"
+ " 既定値", /* 6 */
+ "-V 有効な ssl バージョン番号を出力, SSLv3(0) -"
+ " TLS1.2(3)\n", /* 7 */
+#else
+ "-v <num> SSL バージョン [0-4], SSLv3(0) - TLS1.3(4)),"
+ " 既定値", /* 6 */
+ "-V 有効な ssl バージョン番号を出力, SSLv3(0) -"
+ " TLS1.3(4)\n", /* 7 */
+#endif
+ "-l <str> 暗号スイートリスト (区切り文字 :)\n", /* 8 */
+#ifndef NO_CERTS
+ "-c <file> 証明書ファイル, 既定値", /* 9 */
+ "-k <file> 鍵ファイル, 既定値", /* 10 */
+ "-A <file> 認証局ファイル, 既定値", /* 11 */
+#endif
+#ifndef NO_DH
+ "-Z <num> 最小 DH 鍵 ビット, 既定値", /* 12 */
+#endif
+ "-b <num> ベンチマーク <num> 接続及び結果出力する\n", /* 13 */
+#ifdef HAVE_ALPN
+ "-L <str> アプリケーション層プロトコルネゴシエーションを行う"
+ " ({C,F}:<list>)\n", /* 14 */
+#endif
+ "-B <num> <num> バイトを用いてのベンチマーク・スループット測定"
+ "と結果を出力する\n", /* 15 */
+#ifndef NO_PSK
+ "-s 事前共有鍵を使用する\n", /* 16 */
+#endif
+ "-d ピア確認を無効とする\n", /* 17 */
+ "-D 日付エラー用コールバック例の上書きを行う\n", /* 18 */
+ "-e 利用可能な全ての暗号スイートをリスト, \n", /* 19 */
+ "-g サーバーへ HTTP GET を送信\n", /* 20 */
+ "-u UDP DTLSを使用する。-v 2 を追加指定すると"
+ " DTLSv1, -v 3 を追加指定すると DTLSv1.2 (既定値)\n", /* 21 */
+#ifdef WOLFSSL_SCTP
+ "-G SCTP DTLSを使用する。-v 2 を追加指定すると"
+ " DTLSv1, -v 3 を追加指定すると DTLSv1.2 (既定値)\n", /* 22 */
+#endif
+#ifndef NO_CERTS
+ "-m 証明書内のドメイン名一致を確認する\n", /* 23 */
+#endif
+ "-N ノンブロッキング・ソケットを使用する\n", /* 24 */
+#ifndef NO_SESSION_CACHE
+ "-r セッションを継続する\n", /* 25 */
+#endif
+ "-w 双方向シャットダウンを待つ\n", /* 26 */
+ "-M <prot> STARTTLSを使用する, <prot>プロトコル(smtp)を"
+ "使用する\n", /* 27 */
+#ifdef HAVE_SECURE_RENEGOTIATION
+ "-R セキュアな再ネゴシエーションを許可する\n", /* 28 */
+ "-i <str> クライアント主導のネゴシエーションを強制する\n", /* 29 */
+#endif
+ "-f より少ないパケット/グループメッセージを使用する\n",/* 30 */
+#ifndef NO_CERTS
+ "-x クライアントの証明書/鍵のロードを無効する\n", /* 31 */
+#endif
+ "-X 外部テスト・ケースにより動作する\n", /* 32 */
+ "-j コールバック・オーバーライドの検証を使用する\n", /* 33 */
+#ifdef SHOW_SIZES
+ "-z 構造体のサイズを表示する\n", /* 34 */
+#endif
+#ifdef HAVE_SNI
+ "-S <str> ホスト名表示を使用する\n", /* 35 */
+#endif
+#ifdef HAVE_MAX_FRAGMENT
+ "-F <num> 最大フラグメント長[1-6]を設定する\n", /* 36 */
+#endif
+#ifdef HAVE_TRUNCATED_HMAC
+ "-T Truncated HMACを使用する\n", /* 37 */
+#endif
+#ifdef HAVE_EXTENDED_MASTER
+ "-n マスターシークレット拡張を無効にする\n", /* 38 */
+#endif
+#ifdef HAVE_OCSP
+ "-o OCSPルックアップをピア証明書で実施する\n", /* 39 */
+ "-O <url> OCSPルックアップを、<url>を使用し"
+ "応答者として実施する\n", /* 40 */
+#endif
+#if defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
+ || defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
+ "-W <num> OCSP Staplingを使用する"
+ " (1 v1, 2 v2, 3 v2 multi)\n", /* 41 */
+ " With 'm' at end indicates MUST staple\n", /* 42 */
+#endif
+#if defined(ATOMIC_USER) && !defined(WOLFSSL_AEAD_ONLY)
+ "-U アトミック・ユーザー記録の"
+ "コールバックを利用する\n", /* 43 */
+#endif
+#ifdef HAVE_PK_CALLBACKS
+ "-P 公開鍵コールバック\n", /* 44 */
+#endif
+#ifdef HAVE_ANON
+ "-a 匿名クライアント\n", /* 45 */
+#endif
+#ifdef HAVE_CRL
+ "-C CRLを無効\n", /* 46 */
+#endif
+#ifdef WOLFSSL_TRUST_PEER_CERT
+ "-E <file> 信頼出来るピアの証明書ロードの為のパス\n", /* 47 */
+#endif
+#ifdef HAVE_WNR
+ "-q <file> Whitewood コンフィグファイル, 既定値\n", /* 48 */
+#endif
+ "-H <arg> 内部テスト"
+ " [defCipherList, exitWithRet, verifyFail, useSupCurve,\n", /* 49 */
+ " loadSSL, disallowETM]\n", /* 50 */
+#ifdef WOLFSSL_TLS13
+ "-J HelloRetryRequestをKEのグループ選択に使用する\n", /* 51 */
+ "-K 鍵交換にPSKを使用、(EC)DHEは使用しない\n", /* 52 */
+ "-I データ送信前に、鍵とIVを更新する\n", /* 53 */
+#ifndef NO_DH
+ "-y FFDHE名前付きグループとの鍵共有のみ\n", /* 54 */
+#endif
+#ifdef HAVE_ECC
+ "-Y ECC名前付きグループとの鍵共有のみ\n", /* 55 */
+#endif
+#endif /* WOLFSSL_TLS13 */
+#ifdef HAVE_CURVE25519
+ "-t X25519を鍵交換に使用する\n", /* 56 */
+#endif
+#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_POST_HANDSHAKE_AUTH)
+ "-Q ポストハンドシェークの証明要求をサポートする\n", /* 57 */
+#endif
+#ifdef WOLFSSL_EARLY_DATA
+ "-0 Early data をサーバーへ送信する"
+ "(0-RTTハンドシェイク)\n", /* 58 */
+#endif
+#ifdef WOLFSSL_MULTICAST
+ "-3 <grpid> マルチキャスト, grpid < 256\n", /* 59 */
+#endif
+ "-1 <num> 指定された言語で結果を表示します。\n"
+ " 0: 英語、 1: 日本語\n", /* 60 */
+#if !defined(NO_DH) && !defined(HAVE_FIPS) && \
+ !defined(HAVE_SELFTEST) && !defined(WOLFSSL_OLD_PRIME_CHECK)
+ "-2 DHプライム番号チェックを無効にする\n", /* 61 */
+#endif
+#ifdef HAVE_SECURE_RENEGOTIATION
+ "-4 再交渉に再開を使用\n", /* 62 */
+#endif
+#ifdef HAVE_TRUSTED_CA
+ "-5 信頼できる認証局の鍵表示を使用する\n", /* 63 */
+#endif
+ "-6 WANT_WRITE エラーを全てのIO 送信でシュミレートします\n",
+#ifdef HAVE_CURVE448
+ "-8 Use X448 for key exchange\n", /* 66 */
+#endif
+#if defined(OPENSSL_ALL) && defined(WOLFSSL_CERT_GEN) && \
+ (defined(WOLFSSL_CERT_REQ) || defined(WOLFSSL_CERT_EXT)) && \
+ !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR)
+ "-9 証明書の読み込みに hash dir 機能を使用する\n"
+ " <wolfSSL home>/certs フォルダーからロードします\n"
+ " フォルダー中のファイルは、\"hash.N\"[N:0-9]名である必要があります\n"
+ " 以下の例ではca-cert.pemにシンボリックリンクを設定します\n"
+ " ln -s ca-cert.pem `openssl x509 -in ca-cert.pem -hash -noout`.0\n",
+ /* 67 */
+#endif
+#if defined(WOLFSSL_WOLFSENTRY_HOOKS) && !defined(NO_FILESYSTEM) && \
+ !defined(WOLFSENTRY_NO_JSON)
+ "--wolfsentry-config <file> wolfSentry コンフィグファイル\n",
+ /* 68 */
+#endif
+#ifndef WOLFSSL_TLS13
+ "-7 最小ダウングレード可能なプロトコルバージョンを設定します [0-3] "
+ " SSLv3(0) - TLS1.2(3)\n",
+#else
+ "-7 最小ダウングレード可能なプロトコルバージョンを設定します [0-4] "
+ " SSLv3(0) - TLS1.3(4)\n", /* 69 */
+#endif
+ NULL,
+ },
+#endif
+
+};
+
+static void Usage(void)
+{
+ int msgid = 0;
+ const char** msg = client_usage_msg[lng_index];
+
+ printf("%s%s%s", "wolfSSL client ", LIBWOLFSSL_VERSION_STRING,
+ msg[msgid]);
+
+ /* print out so that scripts can know what the max supported key size is */
+ printf("%s", msg[++msgid]);
+#ifdef NO_RSA
+ printf("%s", msg[++msgid]);
+#elif defined(WOLFSSL_SP_MATH) /* case of SP math only */
+ #ifndef WOLFSSL_SP_NO_3072
+ printf("%s", msg[++msgid]);
+ #elif !defined(WOLFSSL_SP_NO_2048)
+ printf("%s", msg[++msgid]);
+ #else
+ printf("%s", msg[++msgid]);
+ #endif
+#elif defined(USE_FAST_MATH)
+ #if !defined(WOLFSSL_SP_MATH_ALL) && !defined(WOLFSSL_SP_MATH)
+ printf("%d\n", FP_MAX_BITS/2);
+ #else
+ printf("%d\n", SP_INT_MAX_BITS/2);
+ #endif
+#else
+ /* normal math has unlimited max size */
+ printf("%s", msg[++msgid]);
+#endif
+
+ printf("%s", msg[++msgid]); /* ? */
+ printf("%s %s\n", msg[++msgid], wolfSSLIP); /* -h */
+ printf("%s %d\n", msg[++msgid], wolfSSLPort); /* -p */
+#ifndef WOLFSSL_TLS13
+ printf("%s %d\n", msg[++msgid], CLIENT_DEFAULT_VERSION); /* -v */
+ printf("%s", msg[++msgid]); /* -V */
+#else
+ printf("%s %d\n", msg[++msgid], CLIENT_DEFAULT_VERSION); /* -v */
+ printf("%s", msg[++msgid]); /* -V */
+#endif
+ printf("%s", msg[++msgid]); /* -l */
+#ifndef NO_CERTS
+ printf("%s %s\n", msg[++msgid], cliCertFile); /* -c */
+ printf("%s %s\n", msg[++msgid], cliKeyFile); /* -k */
+ printf("%s %s\n", msg[++msgid], caCertFile); /* -A */
+#endif
+#ifndef NO_DH
+ printf("%s %d\n", msg[++msgid], DEFAULT_MIN_DHKEY_BITS);
+#endif
+ printf("%s", msg[++msgid]); /* -b */
+#ifdef HAVE_ALPN
+ printf("%s", msg[++msgid]); /* -L <str> */
+#endif
+ printf("%s", msg[++msgid]); /* -B <num> */
+#ifndef NO_PSK
+ printf("%s", msg[++msgid]); /* -s */
+#endif
+ printf("%s", msg[++msgid]); /* -d */
+ printf("%s", msg[++msgid]); /* -D */
+ printf("%s", msg[++msgid]); /* -e */
+ printf("%s", msg[++msgid]); /* -g */
+ printf("%s", msg[++msgid]); /* -u */
+#ifdef WOLFSSL_SCTP
+ printf("%s", msg[++msgid]); /* -G */
+#endif
+#ifndef NO_CERTS
+ printf("%s", msg[++msgid]); /* -m */
+#endif
+ printf("%s", msg[++msgid]); /* -N */
+#ifndef NO_SESSION_CACHE
+ printf("%s", msg[++msgid]); /* -r */
+#endif
+ printf("%s", msg[++msgid]); /* -w */
+ printf("%s", msg[++msgid]); /* -M */
+#ifdef HAVE_SECURE_RENEGOTIATION
+ printf("%s", msg[++msgid]); /* -R */
+ printf("%s", msg[++msgid]); /* -i */
+#endif
+ printf("%s", msg[++msgid]); /* -f */
+#ifndef NO_CERTS
+ printf("%s", msg[++msgid]); /* -x */
+#endif
+ printf("%s", msg[++msgid]); /* -X */
+ printf("%s", msg[++msgid]); /* -j */
+#ifdef SHOW_SIZES
+ printf("%s", msg[++msgid]); /* -z */
+#endif
+#ifdef HAVE_SNI
+ printf("%s", msg[++msgid]); /* -S */
+#endif
+#ifdef HAVE_MAX_FRAGMENT
+ printf("%s", msg[++msgid]); /* -F */
+#endif
+#ifdef HAVE_TRUNCATED_HMAC
+ printf("%s", msg[++msgid]); /* -T */
+#endif
+#ifdef HAVE_EXTENDED_MASTER
+ printf("%s", msg[++msgid]); /* -n */
+#endif
+#ifdef HAVE_OCSP
+ printf("%s", msg[++msgid]); /* -o */
+ printf("%s", msg[++msgid]); /* -O */
+#endif
+#if defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
+ || defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
+ printf("%s", msg[++msgid]); /* -W */
+ printf("%s", msg[++msgid]); /* note for -W */
+#endif
+#if defined(ATOMIC_USER) && !defined(WOLFSSL_AEAD_ONLY)
+ printf("%s", msg[++msgid]); /* -U */
+#endif
+#ifdef HAVE_PK_CALLBACKS
+ printf("%s", msg[++msgid]); /* -P */
+#endif
+#ifdef HAVE_ANON
+ printf("%s", msg[++msgid]); /* -a */
+#endif
+#ifdef HAVE_CRL
+ printf("%s", msg[++msgid]); /* -C */
+#endif
+#ifdef WOLFSSL_TRUST_PEER_CERT
+ printf("%s", msg[++msgid]); /* -E */
+#endif
+#ifdef HAVE_WNR
+ printf("%s %s\n", msg[++msgid], wnrConfig); /* -q */
+#endif
+ printf("%s", msg[++msgid]); /* -H */
+ printf("%s", msg[++msgid]); /* more -H options */
+#ifdef WOLFSSL_TLS13
+ printf("%s", msg[++msgid]); /* -J */
+ printf("%s", msg[++msgid]); /* -K */
+ printf("%s", msg[++msgid]); /* -I */
+#ifndef NO_DH
+ printf("%s", msg[++msgid]); /* -y */
+#endif
+#ifdef HAVE_ECC
+ printf("%s", msg[++msgid]); /* -Y */
+#endif
+#endif /* WOLFSSL_TLS13 */
+#ifdef HAVE_CURVE25519
+ printf("%s", msg[++msgid]); /* -t */
+#endif
+#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_POST_HANDSHAKE_AUTH)
+ printf("%s", msg[++msgid]); /* -Q */
+#endif
+#ifdef WOLFSSL_EARLY_DATA
+ printf("%s", msg[++msgid]); /* -0 */
+#endif
+#ifdef WOLFSSL_MULTICAST
+ printf("%s", msg[++msgid]); /* -3 */
+#endif
+ printf("%s", msg[++msgid]); /* -1 */
+#if !defined(NO_DH) && !defined(HAVE_FIPS) && \
+ !defined(HAVE_SELFTEST) && !defined(WOLFSSL_OLD_PRIME_CHECK)
+ printf("%s", msg[++msgid]); /* -2 */
+#endif
+#ifdef HAVE_SECURE_RENEGOTIATION
+ printf("%s", msg[++msgid]); /* -4 */
+#endif
+#ifdef HAVE_TRUSTED_CA
+ printf("%s", msg[++msgid]); /* -5 */
+#endif
+ printf("%s", msg[++msgid]); /* -6 */
+#ifdef HAVE_CURVE448
+ printf("%s", msg[++msgid]); /* -8 */
+#endif
+#if defined(OPENSSL_ALL) && defined(WOLFSSL_CERT_GEN) && \
+ (defined(WOLFSSL_CERT_REQ) || defined(WOLFSSL_CERT_EXT)) && \
+ !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR)
+ printf("%s", msg[++msgid]); /* -9 */
+#endif
+#if defined(WOLFSSL_WOLFSENTRY_HOOKS) && !defined(NO_FILESYSTEM) && \
+ !defined(WOLFSENTRY_NO_JSON)
+ printf("%s", msg[++msgid]); /* --wolfsentry-config */
+#endif
+ printf("%s", msg[++msgid]); /* -7 */
+}
+
+THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
+{
+ SOCKET_T sockfd = WOLFSSL_SOCKET_INVALID;
+
+ wolfSSL_method_func method = NULL;
+ WOLFSSL_CTX* ctx = 0;
+ WOLFSSL* ssl = 0;
+
+#ifdef WOLFSSL_WOLFSENTRY_HOOKS
+ wolfsentry_errcode_t wolfsentry_ret;
+#endif
+
+ WOLFSSL* sslResume = 0;
+ WOLFSSL_SESSION* session = 0;
+ byte* flatSession = NULL;
+ int flatSessionSz = 0;
+
+ char msg[CLI_MSG_SZ];
+ int msgSz = 0;
+ char reply[CLI_REPLY_SZ];
+
+ word16 port = wolfSSLPort;
+ char* host = (char*)wolfSSLIP;
+ const char* domain = "localhost"; /* can't default to www.wolfssl.com
+ because can't tell if we're really
+ going there to detect old chacha-poly
+ */
+#ifndef WOLFSSL_VXWORKS
+ int ch;
+ static const struct mygetopt_long_config long_options[] = {
+#if defined(WOLFSSL_WOLFSENTRY_HOOKS) && !defined(NO_FILESYSTEM) && \
+ !defined(WOLFSENTRY_NO_JSON)
+ { "wolfsentry-config", 1, 256 },
+#endif
+ { "help", 0, 257 },
+ { "ヘルプ", 0, 258 },
+ { 0, 0, 0 }
+ };
+#endif
+ int version = CLIENT_INVALID_VERSION;
+ int minVersion = CLIENT_INVALID_VERSION;
+ int usePsk = 0;
+ int useAnon = 0;
+ int sendGET = 0;
+ int benchmark = 0;
+ int block = TEST_BUFFER_SIZE;
+ size_t throughput = 0;
+ int doDTLS = 0;
+ int dtlsUDP = 0;
+#if (defined(WOLFSSL_SCTP) || defined(WOLFSSL_DTLS_MTU)) && \
+ defined(WOLFSSL_DTLS)
+ int dtlsMTU = 0;
+#endif
+ int dtlsSCTP = 0;
+ int doMcast = 0;
+ int matchName = 0;
+ int doPeerCheck = 1;
+ int nonBlocking = 0;
+ int simulateWantWrite = 0;
+ int resumeSession = 0;
+ int wc_shutdown = 0;
+ int disableCRL = 0;
+ int externalTest = 0;
+ int ret;
+ int err = 0;
+ int scr = 0; /* allow secure renegotiation */
+ int forceScr = 0; /* force client initiated scr */
+ int scrAppData = 0;
+ int resumeScr = 0; /* use resumption for renegotiation */
+#ifndef WOLFSSL_NO_CLIENT_AUTH
+ int useClientCert = 1;
+#else
+ int useClientCert = 0;
+#endif
+ int fewerPackets = 0;
+ int atomicUser = 0;
+#ifdef HAVE_PK_CALLBACKS
+ int pkCallbacks = 0;
+ PkCbInfo pkCbInfo;
+#endif
+ int minDhKeyBits = DEFAULT_MIN_DHKEY_BITS;
+ char* alpnList = NULL;
+ unsigned char alpn_opt = 0;
+ char* cipherList = NULL;
+ int useDefCipherList = 0;
+ const char* verifyCert;
+ const char* ourCert;
+ const char* ourKey;
+
+ int doSTARTTLS = 0;
+ char* starttlsProt = NULL;
+ int useVerifyCb = 0;
+ int useSupCurve = 0;
+
+#ifdef WOLFSSL_TRUST_PEER_CERT
+ const char* trustCert = NULL;
+#endif
+
+#ifdef HAVE_SNI
+ char* sniHostName = NULL;
+#endif
+#ifdef HAVE_TRUSTED_CA
+ int trustedCaKeyId = 0;
+#endif
+#ifdef HAVE_MAX_FRAGMENT
+ byte maxFragment = 0;
+#endif
+#ifdef HAVE_TRUNCATED_HMAC
+ byte truncatedHMAC = 0;
+#endif
+#if defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
+ || defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
+ byte statusRequest = 0;
+ byte mustStaple = 0;
+#endif
+#ifdef HAVE_EXTENDED_MASTER
+ byte disableExtMasterSecret = 0;
+#endif
+ int helloRetry = 0;
+ int onlyKeyShare = 0;
+#ifdef WOLFSSL_TLS13
+ int noPskDheKe = 0;
+ int postHandAuth = 0;
+#endif
+ int updateKeysIVs = 0;
+ int earlyData = 0;
+#ifdef WOLFSSL_MULTICAST
+ byte mcastID = 0;
+#endif
+#if !defined(NO_DH) && !defined(HAVE_FIPS) && \
+ !defined(HAVE_SELFTEST) && !defined(WOLFSSL_OLD_PRIME_CHECK)
+ int doDhKeyCheck = 1;
+#endif
+
+#ifdef HAVE_OCSP
+ int useOcsp = 0;
+ char* ocspUrl = NULL;
+#endif
+ int useX25519 = 0;
+ int useX448 = 0;
+ int exitWithRet = 0;
+ int loadCertKeyIntoSSLObj = 0;
+
+#ifdef HAVE_ENCRYPT_THEN_MAC
+ int disallowETM = 0;
+#endif
+
+#ifdef HAVE_WNR
+ const char* wnrConfigFile = wnrConfig;
+#endif
+#if defined(OPENSSL_ALL) && defined(WOLFSSL_CERT_GEN) && \
+ (defined(WOLFSSL_CERT_REQ) || defined(WOLFSSL_CERT_EXT)) && \
+ !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR)
+ int useCertFolder = 0;
+#endif
+ char buffer[WOLFSSL_MAX_ERROR_SZ];
+
+ int argc = ((func_args*)args)->argc;
+ char** argv = ((func_args*)args)->argv;
+
+
+#ifdef WOLFSSL_STATIC_MEMORY
+ #if (defined(HAVE_ECC) && !defined(ALT_ECC_SIZE)) \
+ || defined(SESSION_CERTS)
+ /* big enough to handle most cases including session certs */
+ byte memory[320000];
+ #else
+ byte memory[80000];
+ #endif
+ byte memoryIO[34500]; /* max for IO buffer (TLS packet can be 16k) */
+ WOLFSSL_MEM_CONN_STATS ssl_stats;
+ #ifdef DEBUG_WOLFSSL
+ WOLFSSL_MEM_STATS mem_stats;
+ #endif
+ WOLFSSL_HEAP_HINT *heap = NULL;
+#endif
+
+ ((func_args*)args)->return_code = -1; /* error state */
+
+#ifndef NO_RSA
+ verifyCert = caCertFile;
+ ourCert = cliCertFile;
+ ourKey = cliKeyFile;
+#else
+ #ifdef HAVE_ECC
+ verifyCert = caEccCertFile;
+ ourCert = cliEccCertFile;
+ ourKey = cliEccKeyFile;
+ #elif defined(HAVE_ED25519)
+ verifyCert = caEdCertFile;
+ ourCert = cliEdCertFile;
+ ourKey = cliEdKeyFile;
+ #elif defined(HAVE_ED448)
+ verifyCert = caEd448CertFile;
+ ourCert = cliEd448CertFile;
+ ourKey = cliEd448KeyFile;
+ #else
+ verifyCert = NULL;
+ ourCert = NULL;
+ ourKey = NULL;
+ #endif
+#endif
+
+ (void)session;
+ (void)flatSession;
+ (void)flatSessionSz;
+ (void)sslResume;
+ (void)atomicUser;
+ (void)scr;
+ (void)forceScr;
+ (void)scrAppData;
+ (void)resumeScr;
+ (void)ourKey;
+ (void)ourCert;
+ (void)verifyCert;
+ (void)useClientCert;
+ (void)disableCRL;
+ (void)minDhKeyBits;
+ (void)alpnList;
+ (void)alpn_opt;
+ (void)updateKeysIVs;
+ (void)earlyData;
+ (void)useX25519;
+ (void)useX448;
+ (void)helloRetry;
+ (void)onlyKeyShare;
+ (void)useSupCurve;
+ (void)loadCertKeyIntoSSLObj;
+
+ StackTrap();
+
+ /* Reinitialize the global myVerifyAction. */
+ myVerifyAction = VERIFY_OVERRIDE_ERROR;
+
+#ifndef WOLFSSL_VXWORKS
+ /* Not used: All used */
+ while ((ch = mygetopt_long(argc, argv, "?:"
+ "ab:c:defgh:i;jk:l:mnop:q:rstu;v:wxyz"
+ "A:B:CDE:F:GH:IJKL:M:NO:PQRS:TUVW:XYZ:"
+ "01:23:4567:89"
+ "@#", long_options, 0)) != -1) {
+ switch (ch) {
+ case '?' :
+ if(myoptarg!=NULL) {
+ lng_index = atoi(myoptarg);
+ if(lng_index<0||lng_index>1){
+ lng_index = 0;
+ }
+ }
+ Usage();
+ XEXIT_T(EXIT_SUCCESS);
+
+ case 257 :
+ lng_index = 0;
+ Usage();
+ XEXIT_T(EXIT_SUCCESS);
+
+ case 258 :
+ lng_index = 1;
+ Usage();
+ XEXIT_T(EXIT_SUCCESS);
+
+ case 'g' :
+ sendGET = 1;
+ break;
+
+ case 'd' :
+ doPeerCheck = 0;
+ break;
+
+ case 'e' :
+ ShowCiphers();
+ XEXIT_T(EXIT_SUCCESS);
+
+ case 'D' :
+ myVerifyAction = VERIFY_OVERRIDE_DATE_ERR;
+ break;
+
+ case 'C' :
+ #ifdef HAVE_CRL
+ disableCRL = 1;
+ #endif
+ break;
+
+ case 'u' :
+ doDTLS = 1;
+ dtlsUDP = 1;
+ #if (defined(WOLFSSL_SCTP) || defined(WOLFSSL_DTLS_MTU)) && \
+ defined(WOLFSSL_DTLS)
+ dtlsMTU = atoi(myoptarg);
+ #endif
+ break;
+
+ case 'G' :
+ #ifdef WOLFSSL_SCTP
+ doDTLS = 1;
+ dtlsSCTP = 1;
+ #endif
+ break;
+
+ case 's' :
+ usePsk = 1;
+ break;
+
+ #ifdef WOLFSSL_TRUST_PEER_CERT
+ case 'E' :
+ trustCert = myoptarg;
+ break;
+ #endif
+
+ case 'm' :
+ matchName = 1;
+ break;
+
+ case 'x' :
+ useClientCert = 0;
+ break;
+
+ case 'X' :
+ externalTest = 1;
+ break;
+
+ case 'f' :
+ fewerPackets = 1;
+ break;
+
+ case 'U' :
+ #if defined(ATOMIC_USER) && !defined(WOLFSSL_AEAD_ONLY)
+ atomicUser = 1;
+ #endif
+ break;
+
+ case 'P' :
+ #ifdef HAVE_PK_CALLBACKS
+ pkCallbacks = 1;
+ #endif
+ break;
+
+ case 'h' :
+ host = myoptarg;
+ domain = myoptarg;
+ break;
+
+ case 'p' :
+ port = (word16)atoi(myoptarg);
+ #if !defined(NO_MAIN_DRIVER) || defined(USE_WINDOWS_API)
+ if (port == 0)
+ err_sys("port number cannot be 0");
+ #endif
+ break;
+
+ case 'v' :
+ if (myoptarg[0] == 'd') {
+ version = CLIENT_DOWNGRADE_VERSION;
+ break;
+ }
+ #if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EITHER_SIDE)
+ else if (myoptarg[0] == 'e') {
+ version = EITHER_DOWNGRADE_VERSION;
+ #ifndef NO_CERTS
+ loadCertKeyIntoSSLObj = 1;
+ #endif
+ break;
+ }
+ #endif
+ version = atoi(myoptarg);
+ if (version < 0 || version > 4) {
+ Usage();
+ XEXIT_T(MY_EX_USAGE);
+ }
+ break;
+
+ case 'V' :
+ ShowVersions();
+ XEXIT_T(EXIT_SUCCESS);
+
+ case 'l' :
+ cipherList = myoptarg;
+ break;
+
+ case 'H' :
+ if (XSTRNCMP(myoptarg, "defCipherList", 13) == 0) {
+ printf("Using default cipher list for testing\n");
+ useDefCipherList = 1;
+ }
+ else if (XSTRNCMP(myoptarg, "exitWithRet", 11) == 0) {
+ printf("Skip exit() for testing\n");
+ exitWithRet = 1;
+ }
+ else if (XSTRNCMP(myoptarg, "verifyFail", 10) == 0) {
+ printf("Verify should fail\n");
+ myVerifyAction = VERIFY_FORCE_FAIL;
+ }
+ else if (XSTRNCMP(myoptarg, "verifyInfo", 10) == 0) {
+ printf("Verify should not override error\n");
+ myVerifyAction = VERIFY_USE_PREVERFIY;
+ }
+ else if (XSTRNCMP(myoptarg, "useSupCurve", 11) == 0) {
+ printf("Attempting to test use supported curve\n");
+ #if defined(HAVE_ECC) && defined(HAVE_SUPPORTED_CURVES)
+ useSupCurve = 1;
+ #else
+ printf("Supported curves not compiled in!\n");
+ #endif
+ }
+ else if (XSTRNCMP(myoptarg, "loadSSL", 7) == 0) {
+ printf("Load cert/key into wolfSSL object\n");
+ #ifndef NO_CERTS
+ loadCertKeyIntoSSLObj = 1;
+ #else
+ printf("Certs turned off with NO_CERTS!\n");
+ #endif
+ }
+ else if (XSTRNCMP(myoptarg, "disallowETM", 7) == 0) {
+ printf("Disallow Encrypt-Then-MAC\n");
+ #ifdef HAVE_ENCRYPT_THEN_MAC
+ disallowETM = 1;
+ #endif
+ }
+ else {
+ Usage();
+ XEXIT_T(MY_EX_USAGE);
+ }
+ break;
+
+ case 'A' :
+ verifyCert = myoptarg;
+ break;
+
+ case 'c' :
+ ourCert = myoptarg;
+ break;
+
+ case 'k' :
+ ourKey = myoptarg;
+ break;
+
+ case 'Z' :
+ #ifndef NO_DH
+ minDhKeyBits = atoi(myoptarg);
+ if (minDhKeyBits <= 0 || minDhKeyBits > 16000) {
+ Usage();
+ XEXIT_T(MY_EX_USAGE);
+ }
+ #endif
+ break;
+
+ case 'b' :
+ benchmark = atoi(myoptarg);
+ if (benchmark < 0 || benchmark > 1000000) {
+ Usage();
+ XEXIT_T(MY_EX_USAGE);
+ }
+ break;
+
+ case 'B' :
+ throughput = atol(myoptarg);
+ for (; *myoptarg != '\0'; myoptarg++) {
+ if (*myoptarg == ',') {
+ block = atoi(myoptarg + 1);
+ break;
+ }
+ }
+ if (throughput == 0 || block <= 0) {
+ Usage();
+ XEXIT_T(MY_EX_USAGE);
+ }
+ break;
+
+ case 'N' :
+ nonBlocking = 1;
+ break;
+
+ case 'r' :
+ resumeSession = 1;
+ break;
+
+ case 'w' :
+ wc_shutdown = 1;
+ break;
+
+ case 'R' :
+ #ifdef HAVE_SECURE_RENEGOTIATION
+ scr = 1;
+ #endif
+ break;
+
+ case 'i' :
+ #ifdef HAVE_SECURE_RENEGOTIATION
+ scr = 1;
+ forceScr = 1;
+ if (XSTRNCMP(myoptarg, "scr-app-data", 12) == 0) {
+ scrAppData = 1;
+ }
+ #endif
+ break;
+
+ case 'z' :
+ #ifndef WOLFSSL_LEANPSK
+ wolfSSL_GetObjectSize();
+ #endif
+ break;
+
+ case 'S' :
+ if (XSTRNCMP(myoptarg, "check", 5) == 0) {
+ #ifdef HAVE_SNI
+ printf("SNI is: ON\n");
+ #else
+ printf("SNI is: OFF\n");
+ #endif
+ XEXIT_T(EXIT_SUCCESS);
+ }
+ #ifdef HAVE_SNI
+ sniHostName = myoptarg;
+ #endif
+ break;
+
+ case 'F' :
+ #ifdef HAVE_MAX_FRAGMENT
+ maxFragment = atoi(myoptarg);
+ if (maxFragment < WOLFSSL_MFL_MIN ||
+ maxFragment > WOLFSSL_MFL_MAX) {
+ Usage();
+ XEXIT_T(MY_EX_USAGE);
+ }
+ #endif
+ break;
+
+ case 'T' :
+ #ifdef HAVE_TRUNCATED_HMAC
+ truncatedHMAC = 1;
+ #endif
+ break;
+
+ case 'n' :
+ #ifdef HAVE_EXTENDED_MASTER
+ disableExtMasterSecret = 1;
+ #endif
+ break;
+
+ case 'W' :
+ #if defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
+ || defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
+ {
+ word32 myoptargSz;
+
+ statusRequest = atoi(myoptarg);
+ if (statusRequest > OCSP_STAPLING_OPT_MAX) {
+ Usage();
+ XEXIT_T(MY_EX_USAGE);
+ }
+
+ myoptargSz = (word32)XSTRLEN(myoptarg);
+ if (myoptargSz > 0 &&
+ XTOUPPER(myoptarg[myoptargSz-1]) == 'M') {
+ mustStaple = 1;
+ }
+ }
+ #endif
+ break;
+
+ case 'o' :
+ #ifdef HAVE_OCSP
+ useOcsp = 1;
+ #endif
+ break;
+
+ case 'O' :
+ #ifdef HAVE_OCSP
+ useOcsp = 1;
+ ocspUrl = myoptarg;
+ #endif
+ break;
+
+ case 'a' :
+ #ifdef HAVE_ANON
+ useAnon = 1;
+ #endif
+ break;
+
+ case 'L' :
+ #ifdef HAVE_ALPN
+ alpnList = myoptarg;
+
+ if (alpnList[0] == 'C' && alpnList[1] == ':')
+ alpn_opt = WOLFSSL_ALPN_CONTINUE_ON_MISMATCH;
+ else if (alpnList[0] == 'F' && alpnList[1] == ':')
+ alpn_opt = WOLFSSL_ALPN_FAILED_ON_MISMATCH;
+ else {
+ Usage();
+ XEXIT_T(MY_EX_USAGE);
+ }
+
+ alpnList += 2;
+
+ #endif
+ break;
+
+ case 'M' :
+ doSTARTTLS = 1;
+ starttlsProt = myoptarg;
+
+ if (XSTRNCMP(starttlsProt, "smtp", 4) != 0) {
+ Usage();
+ XEXIT_T(MY_EX_USAGE);
+ }
+
+ break;
+
+ case 'q' :
+ #ifdef HAVE_WNR
+ wnrConfigFile = myoptarg;
+ #endif
+ break;
+
+ case 'J' :
+ #ifdef WOLFSSL_TLS13
+ helloRetry = 1;
+ #endif
+ break;
+
+ case 'K' :
+ #ifdef WOLFSSL_TLS13
+ noPskDheKe = 1;
+ #endif
+ break;
+
+ case 'I' :
+ #ifdef WOLFSSL_TLS13
+ updateKeysIVs = 1;
+ #endif
+ break;
+
+ case 'y' :
+ #if defined(WOLFSSL_TLS13) && \
+ defined(HAVE_SUPPORTED_CURVES) && !defined(NO_DH)
+ onlyKeyShare = 1;
+ #endif
+ break;
+
+ case 'Y' :
+ #if defined(WOLFSSL_TLS13) && \
+ defined(HAVE_SUPPORTED_CURVES) && defined(HAVE_ECC)
+ onlyKeyShare = 2;
+ #endif
+ break;
+
+ case 'j' :
+ useVerifyCb = 1;
+ break;
+
+ case 't' :
+ #ifdef HAVE_CURVE25519
+ useX25519 = 1;
+ #ifdef HAVE_ECC
+ useSupCurve = 1;
+ #if defined(WOLFSSL_TLS13) && \
+ defined(HAVE_SUPPORTED_CURVES)
+ onlyKeyShare = 2;
+ #endif
+ #endif
+ #endif
+ break;
+
+ case 'Q' :
+ #if defined(WOLFSSL_TLS13) && \
+ defined(WOLFSSL_POST_HANDSHAKE_AUTH)
+ postHandAuth = 1;
+ #endif
+ break;
+
+ case '0' :
+ #ifdef WOLFSSL_EARLY_DATA
+ earlyData = 1;
+ #endif
+ break;
+
+ case '1' :
+ lng_index = atoi(myoptarg);
+ if(lng_index<0||lng_index>1){
+ lng_index = 0;
+ }
+ break;
+
+ case '2' :
+ #if !defined(NO_DH) && !defined(HAVE_FIPS) && \
+ !defined(HAVE_SELFTEST) && !defined(WOLFSSL_OLD_PRIME_CHECK)
+ doDhKeyCheck = 0;
+ #endif
+ break;
+
+ case '3' :
+ #ifdef WOLFSSL_MULTICAST
+ doMcast = 1;
+ mcastID = (byte)(atoi(myoptarg) & 0xFF);
+ #endif
+ break;
+
+ case '4' :
+ #ifdef HAVE_SECURE_RENEGOTIATION
+ scr = 1;
+ forceScr = 1;
+ resumeScr = 1;
+ #endif
+ break;
+
+ case '5' :
+ #ifdef HAVE_TRUSTED_CA
+ trustedCaKeyId = 1;
+ #endif /* HAVE_TRUSTED_CA */
+ break;
+
+ case '6' :
+ nonBlocking = 1;
+ simulateWantWrite = 1;
+ break;
+ case '7' :
+ minVersion = atoi(myoptarg);
+ if (minVersion < 0 || minVersion > 4) {
+ Usage();
+ XEXIT_T(MY_EX_USAGE);
+ }
+ break;
+ case '8' :
+ #ifdef HAVE_CURVE448
+ useX448 = 1;
+ #ifdef HAVE_ECC
+ useSupCurve = 1;
+ #if defined(WOLFSSL_TLS13) && \
+ defined(HAVE_SUPPORTED_CURVES)
+ onlyKeyShare = 2;
+ #endif
+ #endif
+ #endif
+ break;
+ case '9' :
+#if defined(OPENSSL_ALL) && defined(WOLFSSL_CERT_GEN) && \
+ (defined(WOLFSSL_CERT_REQ) || defined(WOLFSSL_CERT_EXT)) && \
+ !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR)
+ useCertFolder = 1;
+#endif
+ break;
+ case '@' :
+ {
+#ifdef HAVE_WC_INTROSPECTION
+ const char *conf_args = wolfSSL_configure_args();
+ if (conf_args) {
+ puts(conf_args);
+ XEXIT_T(EXIT_SUCCESS);
+ } else {
+ fputs("configure args not compiled in.\n",stderr);
+ XEXIT_T(MY_EX_USAGE);
+ }
+#else
+ fputs("compiled without BUILD_INTROSPECTION.\n",stderr);
+ XEXIT_T(MY_EX_USAGE);
+#endif
+ }
+
+ case '#' :
+ {
+#ifdef HAVE_WC_INTROSPECTION
+ const char *cflags = wolfSSL_global_cflags();
+ if (cflags) {
+ puts(cflags);
+ XEXIT_T(EXIT_SUCCESS);
+ } else {
+ fputs("CFLAGS not compiled in.\n",stderr);
+ XEXIT_T(MY_EX_USAGE);
+ }
+#else
+ fputs("compiled without BUILD_INTROSPECTION.\n",stderr);
+ XEXIT_T(MY_EX_USAGE);
+#endif
+ }
+
+#ifdef WOLFSSL_WOLFSENTRY_HOOKS
+ case 256:
+#if !defined(NO_FILESYSTEM) && !defined(WOLFSENTRY_NO_JSON)
+ wolfsentry_config_path = myoptarg;
+#endif
+ break;
+#endif
+
+ default:
+ Usage();
+ XEXIT_T(MY_EX_USAGE);
+ }
+ }
+
+ myoptind = 0; /* reset for test cases */
+#endif /* !WOLFSSL_VXWORKS */
+
+ if (externalTest) {
+ /* detect build cases that wouldn't allow test against wolfssl.com */
+ int done = 0;
+
+ #ifdef NO_RSA
+ done += 1; /* require RSA for external tests */
+ #endif
+
+ if (!XSTRNCMP(domain, "www.globalsign.com", 14)) {
+ /* www.globalsign.com does not respond to ipv6 ocsp requests */
+ #if defined(TEST_IPV6) && defined(HAVE_OCSP)
+ done += 1;
+ #endif
+
+ /* www.globalsign.com has limited supported cipher suites */
+ #if defined(NO_AES) && defined(HAVE_OCSP)
+ done += 1;
+ #endif
+
+ /* www.globalsign.com only supports static RSA or ECDHE with AES */
+ /* We cannot expect users to have on static RSA so test for ECC only
+ * as some users will most likely be on 32-bit systems where ECC
+ * is not enabled by default */
+ #if defined(HAVE_OCSP) && !defined(HAVE_ECC)
+ done += 1;
+ #endif
+ }
+
+ #ifndef NO_PSK
+ if (usePsk) {
+ done += 1; /* don't perform external tests if PSK is enabled */
+ }
+ #endif
+
+ #ifdef NO_SHA
+ done += 1; /* external cert chain most likely has SHA */
+ #endif
+
+ #if !defined(HAVE_ECC) && !defined(WOLFSSL_STATIC_RSA) \
+ || ( defined(HAVE_ECC) && !defined(HAVE_SUPPORTED_CURVES) \
+ && !defined(WOLFSSL_STATIC_RSA) )
+ /* google needs ECDHE+Supported Curves or static RSA */
+ if (!XSTRNCMP(domain, "www.google.com", 14))
+ done += 1;
+ #endif
+
+ #if !defined(HAVE_ECC) && !defined(WOLFSSL_STATIC_RSA)
+ /* wolfssl needs ECDHE or static RSA */
+ if (!XSTRNCMP(domain, "www.wolfssl.com", 15))
+ done += 1;
+ #endif
+
+ #if !defined(WOLFSSL_SHA384)
+ if (!XSTRNCMP(domain, "www.wolfssl.com", 15)) {
+ /* wolfssl need sha384 for cert chain verify */
+ done += 1;
+ }
+ #endif
+
+ #if !defined(HAVE_AESGCM) && defined(NO_AES) && \
+ !(defined(HAVE_CHACHA) && defined(HAVE_POLY1305))
+ /* need at least one of these for external tests */
+ done += 1;
+ #endif
+
+ #if defined(HAVE_QSH)
+ /*currently google server rejects client hello with QSH extension.*/
+ done += 1;
+ #endif
+
+ /* For the external test, if we disable AES, GoDaddy will reject the
+ * connection. They only currently support AES suites, RC4 and 3DES
+ * suites. With AES disabled we only offer PolyChacha suites. */
+ #if defined(NO_AES) && !defined(HAVE_AESGCM)
+ if (!XSTRNCMP(domain, "www.wolfssl.com", 15)) {
+ done += 1;
+ }
+ #endif
+
+ if (done) {
+ printf("external test can't be run in this mode\n");
+
+ ((func_args*)args)->return_code = 0;
+ XEXIT_T(EXIT_SUCCESS);
+ }
+ }
+
+ /* sort out DTLS versus TLS versions */
+ if (version == CLIENT_INVALID_VERSION) {
+ if (doDTLS)
+ version = CLIENT_DTLS_DEFAULT_VERSION;
+ else
+ version = CLIENT_DEFAULT_VERSION;
+ }
+ else {
+ if (doDTLS) {
+ if (version == 3)
+ version = -2;
+ #if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EITHER_SIDE)
+ else if (version == EITHER_DOWNGRADE_VERSION)
+ version = -3;
+ #endif
+ else
+ version = -1;
+ }
+ }
+
+#ifdef HAVE_WNR
+ if (wc_InitNetRandom(wnrConfigFile, NULL, 5000) != 0)
+ err_sys("can't load whitewood net random config file");
+#endif
+
+ switch (version) {
+#ifndef NO_OLD_TLS
+ #ifdef WOLFSSL_ALLOW_SSLV3
+ case 0:
+ method = wolfSSLv3_client_method_ex;
+ break;
+ #endif
+
+ #ifndef NO_TLS
+ #ifdef WOLFSSL_ALLOW_TLSV10
+ case 1:
+ method = wolfTLSv1_client_method_ex;
+ break;
+ #endif
+
+ case 2:
+ method = wolfTLSv1_1_client_method_ex;
+ break;
+ #endif /* !NO_TLS */
+#endif /* !NO_OLD_TLS */
+
+#ifndef NO_TLS
+ #ifndef WOLFSSL_NO_TLS12
+ case 3:
+ method = wolfTLSv1_2_client_method_ex;
+ break;
+ #endif
+
+ #ifdef WOLFSSL_TLS13
+ case 4:
+ method = wolfTLSv1_3_client_method_ex;
+ break;
+ #endif
+
+ case CLIENT_DOWNGRADE_VERSION:
+ method = wolfSSLv23_client_method_ex;
+ break;
+ #if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EITHER_SIDE)
+ case EITHER_DOWNGRADE_VERSION:
+ method = wolfSSLv23_method_ex;
+ break;
+ #endif
+#endif /* NO_TLS */
+
+#ifdef WOLFSSL_DTLS
+ #ifndef NO_OLD_TLS
+ case -1:
+ method = wolfDTLSv1_client_method_ex;
+ break;
+ #endif
+
+ #ifndef WOLFSSL_NO_TLS12
+ case -2:
+ method = wolfDTLSv1_2_client_method_ex;
+ break;
+ #endif
+ #if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EITHER_SIDE)
+ case -3:
+ method = wolfDTLSv1_2_method_ex;
+ break;
+ #endif
+#endif
+
+ default:
+ err_sys("Bad SSL version");
+ break;
+ }
+
+ if (method == NULL)
+ err_sys("unable to get method");
+
+
+#ifdef WOLFSSL_STATIC_MEMORY
+ #ifdef DEBUG_WOLFSSL
+ /* print off helper buffer sizes for use with static memory
+ * printing to stderr in case of debug mode turned on */
+ fprintf(stderr, "static memory management size = %d\n",
+ wolfSSL_MemoryPaddingSz());
+ fprintf(stderr, "calculated optimum general buffer size = %d\n",
+ wolfSSL_StaticBufferSz(memory, sizeof(memory), 0));
+ fprintf(stderr, "calculated optimum IO buffer size = %d\n",
+ wolfSSL_StaticBufferSz(memoryIO, sizeof(memoryIO),
+ WOLFMEM_IO_POOL_FIXED));
+ #endif /* DEBUG_WOLFSSL */
+
+ if (wc_LoadStaticMemory(&heap, memory, sizeof(memory), WOLFMEM_GENERAL, 1)
+ != 0) {
+ err_sys("unable to load static memory");
+ }
+
+ ctx = wolfSSL_CTX_new_ex(method(heap), heap);
+ if (ctx == NULL)
+ err_sys("unable to get ctx");
+
+ if (wolfSSL_CTX_load_static_memory(&ctx, NULL, memoryIO, sizeof(memoryIO),
+ WOLFMEM_IO_POOL_FIXED | WOLFMEM_TRACK_STATS, 1) != WOLFSSL_SUCCESS) {
+ err_sys("unable to load static memory");
+ }
+#else
+ if (method != NULL) {
+ ctx = wolfSSL_CTX_new(method(NULL));
+ if (ctx == NULL)
+ err_sys("unable to get ctx");
+ }
+#endif
+ if (minVersion != CLIENT_INVALID_VERSION) {
+ wolfSSL_CTX_SetMinVersion(ctx, minVersion);
+ }
+ if (simulateWantWrite) {
+ #ifdef USE_WOLFSSL_IO
+ wolfSSL_CTX_SetIOSend(ctx, SimulateWantWriteIOSendCb);
+ #endif
+ }
+
+#ifdef SINGLE_THREADED
+ if (wolfSSL_CTX_new_rng(ctx) != WOLFSSL_SUCCESS) {
+ wolfSSL_CTX_free(ctx); ctx = NULL;
+ err_sys("Single Threaded new rng at CTX failed");
+ }
+#endif
+
+
+
+#ifdef WOLFSSL_WOLFSENTRY_HOOKS
+ if (wolfsentry_setup(&wolfsentry, wolfsentry_config_path,
+ WOLFSENTRY_ROUTE_FLAG_DIRECTION_OUT) < 0) {
+ err_sys("unable to initialize wolfSentry");
+ }
+
+ if (wolfSSL_CTX_set_ConnectFilter(
+ ctx,
+ (NetworkFilterCallback_t)wolfSentry_NetworkFilterCallback,
+ wolfsentry) < 0) {
+ err_sys("unable to install wolfSentry_NetworkFilterCallback");
+ }
+#endif
+
+ if (cipherList && !useDefCipherList) {
+ if (wolfSSL_CTX_set_cipher_list(ctx, cipherList) != WOLFSSL_SUCCESS) {
+ wolfSSL_CTX_free(ctx); ctx = NULL;
+ err_sys("client can't set cipher list 1");
+ }
+ }
+
+#ifdef WOLFSSL_LEANPSK
+ if (!usePsk) {
+ usePsk = 1;
+ }
+#endif
+
+#if defined(NO_RSA) && !defined(HAVE_ECC) && !defined(HAVE_ED25519) && \
+ !defined(HAVE_ED448)
+ if (!usePsk) {
+ usePsk = 1;
+ }
+#endif
+
+ if (fewerPackets)
+ wolfSSL_CTX_set_group_messages(ctx);
+#if (defined(WOLFSSL_SCTP) || defined(WOLFSSL_DTLS_MTU)) && \
+ defined(WOLFSSL_DTLS)
+ if (dtlsMTU)
+ wolfSSL_CTX_dtls_set_mtu(ctx, dtlsMTU);
+#endif
+
+#ifndef NO_DH
+ if (wolfSSL_CTX_SetMinDhKey_Sz(ctx, (word16)minDhKeyBits)
+ != WOLFSSL_SUCCESS) {
+ err_sys("Error setting minimum DH key size");
+ }
+#endif
+
+ if (usePsk) {
+#ifndef NO_PSK
+ const char *defaultCipherList = cipherList;
+
+ wolfSSL_CTX_set_psk_client_callback(ctx, my_psk_client_cb);
+#ifdef WOLFSSL_TLS13
+ #if !defined(WOLFSSL_PSK_TLS13_CB) && !defined(WOLFSSL_PSK_ONE_ID)
+ wolfSSL_CTX_set_psk_client_cs_callback(ctx, my_psk_client_cs_cb);
+ #else
+ wolfSSL_CTX_set_psk_client_tls13_callback(ctx, my_psk_client_tls13_cb);
+ #endif
+#endif
+ if (defaultCipherList == NULL) {
+ #if defined(HAVE_AESGCM) && !defined(NO_DH)
+ #ifdef WOLFSSL_TLS13
+ defaultCipherList = "TLS13-AES128-GCM-SHA256"
+ #ifndef WOLFSSL_NO_TLS12
+ ":DHE-PSK-AES128-GCM-SHA256"
+ #endif
+ ;
+ #else
+ defaultCipherList = "DHE-PSK-AES128-GCM-SHA256";
+ #endif
+ #elif defined(HAVE_AESGCM) && defined(WOLFSSL_TLS13)
+ defaultCipherList = "TLS13-AES128-GCM-SHA256"
+ #ifndef WOLFSSL_NO_TLS12
+ ":PSK-AES128-GCM-SHA256"
+ #endif
+ ;
+ #elif defined(HAVE_NULL_CIPHER)
+ defaultCipherList = "PSK-NULL-SHA256";
+ #else
+ defaultCipherList = "PSK-AES128-CBC-SHA256";
+ #endif
+ if (wolfSSL_CTX_set_cipher_list(ctx, defaultCipherList)
+ !=WOLFSSL_SUCCESS) {
+ wolfSSL_CTX_free(ctx); ctx = NULL;
+ err_sys("client can't set cipher list 2");
+ }
+ }
+ wolfSSL_CTX_set_psk_callback_ctx(ctx, (void*)defaultCipherList);
+#endif
+ if (useClientCert) {
+ useClientCert = 0;
+ }
+ }
+
+ if (useAnon) {
+#ifdef HAVE_ANON
+ if (cipherList == NULL || (cipherList && useDefCipherList)) {
+ const char* defaultCipherList;
+ wolfSSL_CTX_allow_anon_cipher(ctx);
+ defaultCipherList = "ADH-AES256-GCM-SHA384:"
+ "ADH-AES128-SHA";
+ if (wolfSSL_CTX_set_cipher_list(ctx,defaultCipherList)
+ != WOLFSSL_SUCCESS) {
+ wolfSSL_CTX_free(ctx); ctx = NULL;
+ err_sys("client can't set cipher list 4");
+ }
+ }
+#endif
+ if (useClientCert) {
+ useClientCert = 0;
+ }
+ }
+
+#ifdef WOLFSSL_SCTP
+ if (dtlsSCTP)
+ wolfSSL_CTX_dtls_set_sctp(ctx);
+#endif
+
+#ifdef WOLFSSL_ENCRYPTED_KEYS
+ wolfSSL_CTX_set_default_passwd_cb(ctx, PasswordCallBack);
+#endif
+
+#ifdef WOLFSSL_SNIFFER
+ if (cipherList == NULL && version < 4) {
+ /* static RSA or ECC cipher suites */
+ const char* staticCipherList = "AES128-SHA:ECDH-ECDSA-AES128-SHA";
+ if (wolfSSL_CTX_set_cipher_list(ctx, staticCipherList) != WOLFSSL_SUCCESS) {
+ wolfSSL_CTX_free(ctx); ctx = NULL;
+ err_sys("client can't set cipher list 3");
+ }
+ }
+#endif
+
+#ifdef HAVE_OCSP
+ if (useOcsp) {
+ #if defined(HAVE_IO_TIMEOUT) && defined(HAVE_HTTP_CLIENT)
+ wolfIO_SetTimeout(DEFAULT_TIMEOUT_SEC);
+ #endif
+
+ if (ocspUrl != NULL) {
+ wolfSSL_CTX_SetOCSP_OverrideURL(ctx, ocspUrl);
+ wolfSSL_CTX_EnableOCSP(ctx, WOLFSSL_OCSP_NO_NONCE
+ | WOLFSSL_OCSP_URL_OVERRIDE);
+ }
+ else {
+ wolfSSL_CTX_EnableOCSP(ctx, WOLFSSL_OCSP_CHECKALL);
+ }
+
+ #ifdef WOLFSSL_NONBLOCK_OCSP
+ wolfSSL_CTX_SetOCSP_Cb(ctx, OCSPIOCb, OCSPRespFreeCb, NULL);
+ #endif
+ }
+#endif
+
+#ifdef USER_CA_CB
+ wolfSSL_CTX_SetCACb(ctx, CaCb);
+#endif
+
+#if defined(HAVE_EXT_CACHE) && !defined(NO_SESSION_CACHE)
+ wolfSSL_CTX_sess_set_get_cb(ctx, mySessGetCb);
+ wolfSSL_CTX_sess_set_new_cb(ctx, mySessNewCb);
+ wolfSSL_CTX_sess_set_remove_cb(ctx, mySessRemCb);
+#endif
+
+#ifndef NO_CERTS
+ if (useClientCert && !loadCertKeyIntoSSLObj){
+ #ifdef NO_FILESYSTEM
+ if (wolfSSL_CTX_use_certificate_chain_buffer(ctx, client_cert_der_2048,
+ sizeof_client_cert_der_2048) != WOLFSSL_SUCCESS)
+ err_sys("can't load client cert buffer");
+ #elif !defined(TEST_LOAD_BUFFER)
+ if (wolfSSL_CTX_use_certificate_chain_file(ctx, ourCert)
+ != WOLFSSL_SUCCESS) {
+ wolfSSL_CTX_free(ctx); ctx = NULL;
+ err_sys("can't load client cert file, check file and run from"
+ " wolfSSL home dir");
+ }
+ #else
+ load_buffer(ctx, ourCert, WOLFSSL_CERT_CHAIN);
+ #endif
+ }
+
+ #ifdef HAVE_PK_CALLBACKS
+ pkCbInfo.ourKey = ourKey;
+ #endif
+ if (useClientCert && !loadCertKeyIntoSSLObj
+ #if defined(HAVE_PK_CALLBACKS) && defined(TEST_PK_PRIVKEY)
+ && !pkCallbacks
+ #endif
+ ) {
+ #ifdef NO_FILESYSTEM
+ if (wolfSSL_CTX_use_PrivateKey_buffer(ctx, client_key_der_2048,
+ sizeof_client_key_der_2048, SSL_FILETYPE_ASN1) != WOLFSSL_SUCCESS)
+ err_sys("can't load client private key buffer");
+ #elif !defined(TEST_LOAD_BUFFER)
+ if (wolfSSL_CTX_use_PrivateKey_file(ctx, ourKey, WOLFSSL_FILETYPE_PEM)
+ != WOLFSSL_SUCCESS) {
+ wolfSSL_CTX_free(ctx); ctx = NULL;
+ err_sys("can't load client private key file, check file and run "
+ "from wolfSSL home dir");
+ }
+ #else
+ load_buffer(ctx, ourKey, WOLFSSL_KEY);
+ #endif
+ }
+
+ if (!usePsk && !useAnon && !useVerifyCb && myVerifyAction != VERIFY_FORCE_FAIL) {
+ #if defined(OPENSSL_ALL) && defined(WOLFSSL_CERT_GEN) && \
+ (defined(WOLFSSL_CERT_REQ) || defined(WOLFSSL_CERT_EXT)) && \
+ !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR)
+ if (useCertFolder) {
+ WOLFSSL_X509_STORE *store;
+ WOLFSSL_X509_LOOKUP *lookup;
+
+ store = wolfSSL_CTX_get_cert_store(ctx);
+ if (store == NULL) {
+ wolfSSL_CTX_free(ctx); ctx = NULL;
+ err_sys("can't get WOLFSSL_X509_STORE");
+ }
+ lookup = wolfSSL_X509_STORE_add_lookup(store, X509_LOOKUP_hash_dir());
+ if (lookup == NULL) {
+ wolfSSL_CTX_free(ctx); ctx = NULL;
+ err_sys("can't add lookup");
+ }
+ if (wolfSSL_X509_LOOKUP_ctrl(lookup, WOLFSSL_X509_L_ADD_DIR, caCertFolder,
+ X509_FILETYPE_PEM, NULL) != WOLFSSL_SUCCESS) {
+ err_sys("X509_LOOKUP_ctrl w/ L_ADD_DIR failed");
+ }
+ } else {
+ #endif
+ #ifdef NO_FILESYSTEM
+ if (wolfSSL_CTX_load_verify_buffer(ctx, ca_cert_der_2048,
+ sizeof_ca_cert_der_2048, SSL_FILETYPE_ASN1) != WOLFSSL_SUCCESS) {
+ wolfSSL_CTX_free(ctx); ctx = NULL;
+ err_sys("can't load ca buffer, Please run from wolfSSL home dir");
+ }
+ #elif !defined(TEST_LOAD_BUFFER)
+ unsigned int verify_flags = 0;
+ #ifdef TEST_BEFORE_DATE
+ verify_flags |= WOLFSSL_LOAD_FLAG_DATE_ERR_OKAY;
+ #endif
+ if (wolfSSL_CTX_load_verify_locations_ex(ctx, verifyCert, 0, verify_flags)
+ != WOLFSSL_SUCCESS) {
+ wolfSSL_CTX_free(ctx); ctx = NULL;
+ err_sys("can't load ca file, Please run from wolfSSL home dir");
+ }
+ #else
+ load_buffer(ctx, verifyCert, WOLFSSL_CA);
+ #endif /* !NO_FILESYSTEM */
+
+ #ifdef HAVE_ECC
+ /* load ecc verify too, echoserver uses it by default w/ ecc */
+ #ifdef NO_FILESYSTEM
+ if (wolfSSL_CTX_load_verify_buffer(ctx, ca_ecc_cert_der_256,
+ sizeof_ca_ecc_cert_der_256, SSL_FILETYPE_ASN1) != WOLFSSL_SUCCESS) {
+ wolfSSL_CTX_free(ctx); ctx = NULL;
+ err_sys("can't load ecc ca buffer");
+ }
+ #elif !defined(TEST_LOAD_BUFFER)
+ if (wolfSSL_CTX_load_verify_locations_ex(ctx, eccCertFile, 0, verify_flags)
+ != WOLFSSL_SUCCESS) {
+ wolfSSL_CTX_free(ctx); ctx = NULL;
+ err_sys("can't load ecc ca file, Please run from wolfSSL home dir");
+ }
+ #else
+ load_buffer(ctx, eccCertFile, WOLFSSL_CA);
+ #endif /* !TEST_LOAD_BUFFER */
+ #endif /* HAVE_ECC */
+ #if defined(WOLFSSL_TRUST_PEER_CERT) && !defined(NO_FILESYSTEM)
+ if (trustCert) {
+ if ((ret = wolfSSL_CTX_trust_peer_cert(ctx, trustCert,
+ WOLFSSL_FILETYPE_PEM)) != WOLFSSL_SUCCESS) {
+ wolfSSL_CTX_free(ctx); ctx = NULL;
+ err_sys("can't load trusted peer cert file");
+ }
+ }
+ #endif /* WOLFSSL_TRUST_PEER_CERT && !NO_FILESYSTEM */
+ #if defined(OPENSSL_ALL) && defined(WOLFSSL_CERT_GEN) && \
+ (defined(WOLFSSL_CERT_REQ) || defined(WOLFSSL_CERT_EXT)) && \
+ !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR)
+ }
+ #endif
+ }
+ if (useVerifyCb || myVerifyAction == VERIFY_FORCE_FAIL ||
+ myVerifyAction == VERIFY_USE_PREVERFIY) {
+ wolfSSL_CTX_set_verify(ctx, WOLFSSL_VERIFY_PEER, myVerify);
+ }
+ else if (!usePsk && !useAnon && doPeerCheck == 0) {
+ wolfSSL_CTX_set_verify(ctx, WOLFSSL_VERIFY_NONE, 0);
+ }
+ else if (!usePsk && !useAnon && myVerifyAction == VERIFY_OVERRIDE_DATE_ERR) {
+ wolfSSL_CTX_set_verify(ctx, WOLFSSL_VERIFY_PEER, myVerify);
+ }
+#endif /* !NO_CERTS */
+
+#ifdef WOLFSSL_ASYNC_CRYPT
+ ret = wolfAsync_DevOpen(&devId);
+ if (ret < 0) {
+ printf("Async device open failed\nRunning without async\n");
+ }
+ wolfSSL_CTX_SetDevId(ctx, devId);
+#endif /* WOLFSSL_ASYNC_CRYPT */
+
+#ifdef HAVE_SNI
+ if (sniHostName) {
+ if (wolfSSL_CTX_UseSNI(ctx, WOLFSSL_SNI_HOST_NAME, sniHostName,
+ (word16) XSTRLEN(sniHostName)) != WOLFSSL_SUCCESS) {
+ wolfSSL_CTX_free(ctx); ctx = NULL;
+ err_sys("UseSNI failed");
+ }
+ }
+#endif
+#ifdef HAVE_MAX_FRAGMENT
+ if (maxFragment)
+ if (wolfSSL_CTX_UseMaxFragment(ctx, maxFragment) != WOLFSSL_SUCCESS) {
+ wolfSSL_CTX_free(ctx); ctx = NULL;
+ err_sys("UseMaxFragment failed");
+ }
+#endif
+#ifdef HAVE_TRUNCATED_HMAC
+ if (truncatedHMAC)
+ if (wolfSSL_CTX_UseTruncatedHMAC(ctx) != WOLFSSL_SUCCESS) {
+ wolfSSL_CTX_free(ctx); ctx = NULL;
+ err_sys("UseTruncatedHMAC failed");
+ }
+#endif
+#ifdef HAVE_SESSION_TICKET
+ if (wolfSSL_CTX_UseSessionTicket(ctx) != WOLFSSL_SUCCESS) {
+ wolfSSL_CTX_free(ctx); ctx = NULL;
+ err_sys("UseSessionTicket failed");
+ }
+#endif
+#ifdef HAVE_EXTENDED_MASTER
+ if (disableExtMasterSecret)
+ if (wolfSSL_CTX_DisableExtendedMasterSecret(ctx) != WOLFSSL_SUCCESS) {
+ wolfSSL_CTX_free(ctx); ctx = NULL;
+ err_sys("DisableExtendedMasterSecret failed");
+ }
+#endif
+#if defined(HAVE_SUPPORTED_CURVES)
+ #if defined(HAVE_CURVE25519)
+ if (useX25519) {
+ if (wolfSSL_CTX_UseSupportedCurve(ctx, WOLFSSL_ECC_X25519)
+ != WOLFSSL_SUCCESS) {
+ err_sys("unable to support X25519");
+ }
+ }
+ #endif /* HAVE_CURVE25519 */
+ #if defined(HAVE_CURVE448)
+ if (useX448) {
+ if (wolfSSL_CTX_UseSupportedCurve(ctx, WOLFSSL_ECC_X448)
+ != WOLFSSL_SUCCESS) {
+ err_sys("unable to support X448");
+ }
+ }
+ #endif /* HAVE_CURVE448 */
+ #ifdef HAVE_ECC
+ if (useSupCurve) {
+ #if !defined(NO_ECC_SECP) && \
+ (defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES))
+ if (wolfSSL_CTX_UseSupportedCurve(ctx, WOLFSSL_ECC_SECP384R1)
+ != WOLFSSL_SUCCESS) {
+ err_sys("unable to support secp384r1");
+ }
+ #endif
+ #if !defined(NO_ECC_SECP) && \
+ (!defined(NO_ECC256) || defined(HAVE_ALL_CURVES))
+ if (wolfSSL_CTX_UseSupportedCurve(ctx, WOLFSSL_ECC_SECP256R1)
+ != WOLFSSL_SUCCESS) {
+ err_sys("unable to support secp256r1");
+ }
+ #endif
+ }
+ #endif /* HAVE_ECC */
+ #ifdef HAVE_FFDHE_2048
+ if (useSupCurve) {
+ if (wolfSSL_CTX_UseSupportedCurve(ctx, WOLFSSL_FFDHE_2048)
+ != WOLFSSL_SUCCESS) {
+ err_sys("unable to support FFDHE 2048");
+ }
+ }
+ #endif
+#endif /* HAVE_SUPPORTED_CURVES */
+
+#ifdef WOLFSSL_TLS13
+ if (noPskDheKe)
+ wolfSSL_CTX_no_dhe_psk(ctx);
+#endif
+#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_POST_HANDSHAKE_AUTH)
+ if (postHandAuth)
+ wolfSSL_CTX_allow_post_handshake_auth(ctx);
+#endif
+
+ if (benchmark) {
+ ((func_args*)args)->return_code =
+ ClientBenchmarkConnections(ctx, host, port, dtlsUDP, dtlsSCTP,
+ benchmark, resumeSession, useX25519,
+ useX448, helloRetry, onlyKeyShare,
+ version, earlyData);
+ wolfSSL_CTX_free(ctx); ctx = NULL;
+ XEXIT_T(EXIT_SUCCESS);
+ }
+
+ if (throughput) {
+ ((func_args*)args)->return_code =
+ ClientBenchmarkThroughput(ctx, host, port, dtlsUDP, dtlsSCTP,
+ block, throughput, useX25519, useX448,
+ exitWithRet, version, onlyKeyShare);
+ wolfSSL_CTX_free(ctx); ctx = NULL;
+ if (!exitWithRet)
+ XEXIT_T(EXIT_SUCCESS);
+ else
+ goto exit;
+ }
+
+ #if defined(WOLFSSL_MDK_ARM)
+ wolfSSL_CTX_set_verify(ctx, WOLFSSL_VERIFY_NONE, 0);
+ #endif
+
+ #if defined(OPENSSL_EXTRA)
+ if (wolfSSL_CTX_get_read_ahead(ctx) != 0) {
+ wolfSSL_CTX_free(ctx); ctx = NULL;
+ err_sys("bad read ahead default value");
+ }
+ if (wolfSSL_CTX_set_read_ahead(ctx, 1) != WOLFSSL_SUCCESS) {
+ wolfSSL_CTX_free(ctx); ctx = NULL;
+ err_sys("error setting read ahead value");
+ }
+ #endif
+
+#if defined(WOLFSSL_STATIC_MEMORY) && defined(DEBUG_WOLFSSL)
+ fprintf(stderr, "Before creating SSL\n");
+ if (wolfSSL_CTX_is_static_memory(ctx, &mem_stats) != 1)
+ err_sys("ctx not using static memory");
+ if (wolfSSL_PrintStats(&mem_stats) != 1) /* function in test.h */
+ err_sys("error printing out memory stats");
+#endif
+
+ if (doMcast) {
+#ifdef WOLFSSL_MULTICAST
+ wolfSSL_CTX_mcast_set_member_id(ctx, mcastID);
+ if (wolfSSL_CTX_set_cipher_list(ctx, "WDM-NULL-SHA256")
+ != WOLFSSL_SUCCESS) {
+ wolfSSL_CTX_free(ctx); ctx = NULL;
+ err_sys("Couldn't set multicast cipher list.");
+ }
+#endif
+ }
+
+#ifdef HAVE_PK_CALLBACKS
+ if (pkCallbacks)
+ SetupPkCallbacks(ctx);
+#endif
+
+ ssl = wolfSSL_new(ctx);
+ if (ssl == NULL) {
+ wolfSSL_CTX_free(ctx); ctx = NULL;
+ err_sys("unable to get SSL object");
+ }
+
+#ifndef NO_PSK
+ if (usePsk) {
+ #if defined(OPENSSL_EXTRA) && defined(WOLFSSL_TLS13) && defined(TEST_PSK_USE_SESSION)
+ SSL_set_psk_use_session_callback(ssl, my_psk_use_session_cb);
+ #endif
+ }
+#endif
+
+#ifndef NO_CERTS
+ if (useClientCert && loadCertKeyIntoSSLObj){
+ #ifdef NO_FILESYSTEM
+ if (wolfSSL_use_certificate_buffer(ssl, client_cert_der_2048,
+ sizeof_client_cert_der_2048, SSL_FILETYPE_ASN1) != WOLFSSL_SUCCESS) {
+ wolfSSL_CTX_free(ctx); ctx = NULL;
+ err_sys("can't load client cert buffer");
+ }
+ #elif !defined(TEST_LOAD_BUFFER)
+ if (wolfSSL_use_certificate_chain_file(ssl, ourCert)
+ != WOLFSSL_SUCCESS) {
+ wolfSSL_CTX_free(ctx); ctx = NULL;
+ err_sys("can't load client cert file, check file and run from"
+ " wolfSSL home dir");
+ }
+ #else
+ load_ssl_buffer(ssl, ourCert, WOLFSSL_CERT_CHAIN);
+ #endif
+ }
+
+ if (loadCertKeyIntoSSLObj
+ #if defined(HAVE_PK_CALLBACKS) && defined(TEST_PK_PRIVKEY)
+ && !pkCallbacks
+ #endif
+ ) {
+ #ifdef NO_FILESYSTEM
+ if (wolfSSL_CTX_use_PrivateKey_buffer(ctx, client_key_der_2048,
+ sizeof_client_key_der_2048, SSL_FILETYPE_ASN1) != WOLFSSL_SUCCESS)
+ err_sys("can't load client private key buffer");
+ #elif !defined(TEST_LOAD_BUFFER)
+ if (wolfSSL_use_PrivateKey_file(ssl, ourKey, WOLFSSL_FILETYPE_PEM)
+ != WOLFSSL_SUCCESS) {
+ wolfSSL_CTX_free(ctx); ctx = NULL;
+ err_sys("can't load client private key file, check file and run "
+ "from wolfSSL home dir");
+ }
+ #else
+ load_ssl_buffer(ssl, ourKey, WOLFSSL_KEY);
+ #endif
+ }
+#endif /* !NO_CERTS */
+
+#ifdef OPENSSL_EXTRA
+ wolfSSL_KeepArrays(ssl);
+#endif
+
+#if defined(WOLFSSL_STATIC_MEMORY) && defined(DEBUG_WOLFSSL)
+ fprintf(stderr, "After creating SSL\n");
+ if (wolfSSL_CTX_is_static_memory(ctx, &mem_stats) != 1)
+ err_sys("ctx not using static memory");
+ if (wolfSSL_PrintStats(&mem_stats) != 1) /* function in test.h */
+ err_sys("error printing out memory stats");
+#endif
+
+#if defined(WOLFSSL_TLS13) && defined(HAVE_SUPPORTED_CURVES)
+ if (!helloRetry && version >= 4) {
+ SetKeyShare(ssl, onlyKeyShare, useX25519, useX448, 0);
+ }
+ else {
+ wolfSSL_NoKeyShares(ssl);
+ }
+#endif
+
+ if (doMcast) {
+#ifdef WOLFSSL_MULTICAST
+ /* DTLS multicast secret for testing only */
+ #define CLI_SRV_RANDOM_SZ 32 /* RAN_LEN (see internal.h) */
+ #define PMS_SZ 512 /* ENCRYPT_LEN (see internal.h) */
+ byte pms[PMS_SZ]; /* pre master secret */
+ byte cr[CLI_SRV_RANDOM_SZ]; /* client random */
+ byte sr[CLI_SRV_RANDOM_SZ]; /* server random */
+ const byte suite[2] = {0, 0xfe}; /* WDM_WITH_NULL_SHA256 */
+
+ XMEMSET(pms, 0x23, sizeof(pms));
+ XMEMSET(cr, 0xA5, sizeof(cr));
+ XMEMSET(sr, 0x5A, sizeof(sr));
+
+ if (wolfSSL_set_secret(ssl, 1, pms, sizeof(pms), cr, sr, suite)
+ != WOLFSSL_SUCCESS) {
+ wolfSSL_CTX_free(ctx); ctx = NULL;
+ err_sys("unable to set mcast secret");
+ }
+#endif
+ }
+
+ #ifdef HAVE_SESSION_TICKET
+ wolfSSL_set_SessionTicket_cb(ssl, sessionTicketCB, (void*)"initial session");
+ #endif
+
+#ifdef HAVE_TRUSTED_CA
+ if (trustedCaKeyId) {
+ if (wolfSSL_UseTrustedCA(ssl, WOLFSSL_TRUSTED_CA_PRE_AGREED,
+ NULL, 0) != WOLFSSL_SUCCESS) {
+ err_sys("UseTrustedCA failed");
+ }
+ }
+#endif
+#ifdef HAVE_ALPN
+ if (alpnList != NULL) {
+ printf("ALPN accepted protocols list : %s\n", alpnList);
+ wolfSSL_UseALPN(ssl, alpnList, (word32)XSTRLEN(alpnList), alpn_opt);
+ }
+#endif
+
+#if defined(HAVE_CERTIFICATE_STATUS_REQUEST) || \
+ defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
+ if (statusRequest) {
+ if (version == 4 &&
+ (statusRequest == OCSP_STAPLINGV2 || \
+ statusRequest == OCSP_STAPLINGV2_MULTI)) {
+ err_sys("Cannot use OCSP Stapling V2 with TLSv1.3");
+ }
+
+ if (wolfSSL_CTX_EnableOCSPStapling(ctx) != WOLFSSL_SUCCESS)
+ err_sys("can't enable OCSP Stapling Certificate Manager");
+ if (mustStaple) {
+ if (wolfSSL_CTX_EnableOCSPMustStaple(ctx) != WOLFSSL_SUCCESS)
+ err_sys("can't enable OCSP Must Staple");
+ }
+
+ switch (statusRequest) {
+ #ifdef HAVE_CERTIFICATE_STATUS_REQUEST
+ case OCSP_STAPLING:
+ if (wolfSSL_UseOCSPStapling(ssl, WOLFSSL_CSR_OCSP,
+ WOLFSSL_CSR_OCSP_USE_NONCE) != WOLFSSL_SUCCESS) {
+ wolfSSL_free(ssl); ssl = NULL;
+ wolfSSL_CTX_free(ctx); ctx = NULL;
+ err_sys("UseCertificateStatusRequest failed");
+ }
+ break;
+ #endif
+ #ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2
+ case OCSP_STAPLINGV2:
+ if (wolfSSL_UseOCSPStaplingV2(ssl,
+ WOLFSSL_CSR2_OCSP, WOLFSSL_CSR2_OCSP_USE_NONCE)
+ != WOLFSSL_SUCCESS) {
+ wolfSSL_free(ssl); ssl = NULL;
+ wolfSSL_CTX_free(ctx); ctx = NULL;
+ err_sys("UseCertificateStatusRequest failed");
+ }
+ break;
+ case OCSP_STAPLINGV2_MULTI:
+ if (wolfSSL_UseOCSPStaplingV2(ssl,
+ WOLFSSL_CSR2_OCSP_MULTI, 0)
+ != WOLFSSL_SUCCESS) {
+ wolfSSL_free(ssl); ssl = NULL;
+ wolfSSL_CTX_free(ctx); ctx = NULL;
+ err_sys("UseCertificateStatusRequest failed");
+ }
+ break;
+ #endif
+ default:
+ err_sys("Invalid OCSP Stapling option");
+ }
+
+ wolfSSL_CTX_EnableOCSP(ctx, 0);
+ }
+#endif
+
+#if !defined(NO_DH) && !defined(WOLFSSL_OLD_PRIME_CHECK) && \
+ !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)
+ if (!doDhKeyCheck)
+ wolfSSL_SetEnableDhKeyTest(ssl, 0);
+#endif
+
+#ifdef HAVE_ENCRYPT_THEN_MAC
+ if (disallowETM)
+ wolfSSL_AllowEncryptThenMac(ssl, 0);
+#endif
+
+
+ tcp_connect(&sockfd, host, port, dtlsUDP, dtlsSCTP, ssl);
+ if (wolfSSL_set_fd(ssl, sockfd) != WOLFSSL_SUCCESS) {
+ wolfSSL_free(ssl); ssl = NULL;
+ wolfSSL_CTX_free(ctx); ctx = NULL;
+ err_sys("error in setting fd");
+ }
+
+ /* STARTTLS */
+ if (doSTARTTLS) {
+ if (StartTLS_Init(&sockfd) != WOLFSSL_SUCCESS) {
+ wolfSSL_free(ssl); ssl = NULL;
+ wolfSSL_CTX_free(ctx); ctx = NULL;
+ err_sys("error during STARTTLS protocol");
+ }
+ }
+
+#ifdef HAVE_CRL
+ if (disableCRL == 0 && !useVerifyCb) {
+ #if defined(HAVE_IO_TIMEOUT) && defined(HAVE_HTTP_CLIENT)
+ wolfIO_SetTimeout(DEFAULT_TIMEOUT_SEC);
+ #endif
+
+ if (wolfSSL_EnableCRL(ssl, WOLFSSL_CRL_CHECKALL) != WOLFSSL_SUCCESS) {
+ wolfSSL_free(ssl); ssl = NULL;
+ wolfSSL_CTX_free(ctx); ctx = NULL;
+ err_sys("can't enable crl check");
+ }
+ if (wolfSSL_LoadCRL(ssl, crlPemDir, WOLFSSL_FILETYPE_PEM, 0)
+ != WOLFSSL_SUCCESS) {
+ wolfSSL_free(ssl); ssl = NULL;
+ wolfSSL_CTX_free(ctx); ctx = NULL;
+ err_sys("can't load crl, check crlfile and date validity");
+ }
+ if (wolfSSL_SetCRL_Cb(ssl, CRL_CallBack) != WOLFSSL_SUCCESS) {
+ wolfSSL_free(ssl); ssl = NULL;
+ wolfSSL_CTX_free(ctx); ctx = NULL;
+ err_sys("can't set crl callback");
+ }
+ }
+#endif
+#ifdef HAVE_SECURE_RENEGOTIATION
+ if (scr) {
+ if (wolfSSL_UseSecureRenegotiation(ssl) != WOLFSSL_SUCCESS) {
+ wolfSSL_free(ssl); ssl = NULL;
+ wolfSSL_CTX_free(ctx); ctx = NULL;
+ err_sys("can't enable secure renegotiation");
+ }
+ }
+#endif
+#if defined(ATOMIC_USER) && !defined(WOLFSSL_AEAD_ONLY)
+ if (atomicUser)
+ SetupAtomicUser(ctx, ssl);
+#endif
+#ifdef HAVE_PK_CALLBACKS
+ if (pkCallbacks)
+ SetupPkCallbackContexts(ssl, &pkCbInfo);
+#endif
+ if (matchName && doPeerCheck)
+ wolfSSL_check_domain_name(ssl, domain);
+#ifndef WOLFSSL_CALLBACKS
+ if (nonBlocking) {
+#ifdef WOLFSSL_DTLS
+ if (doDTLS) {
+ wolfSSL_dtls_set_using_nonblock(ssl, 1);
+ }
+#endif
+ tcp_set_nonblocking(&sockfd);
+ ret = NonBlockingSSL_Connect(ssl);
+ }
+ else {
+#ifdef WOLFSSL_EARLY_DATA
+ if (usePsk && earlyData)
+ EarlyData(ctx, ssl, kEarlyMsg, sizeof(kEarlyMsg)-1, buffer);
+#endif
+ do {
+ err = 0; /* reset error */
+ ret = wolfSSL_connect(ssl);
+ if (ret != WOLFSSL_SUCCESS) {
+ err = wolfSSL_get_error(ssl, 0);
+ #ifdef WOLFSSL_ASYNC_CRYPT
+ if (err == WC_PENDING_E) {
+ ret = wolfSSL_AsyncPoll(ssl, WOLF_POLL_FLAG_CHECK_HW);
+ if (ret < 0) break;
+ }
+ #endif
+ }
+ } while (err == WC_PENDING_E);
+ }
+#else
+ timeoutConnect.tv_sec = DEFAULT_TIMEOUT_SEC;
+ timeoutConnect.tv_usec = 0;
+ ret = NonBlockingSSL_Connect(ssl); /* will keep retrying on timeout */
+#endif
+ if (ret != WOLFSSL_SUCCESS) {
+ err = wolfSSL_get_error(ssl, 0);
+ printf("wolfSSL_connect error %d, %s\n", err,
+ wolfSSL_ERR_error_string(err, buffer));
+
+ /* cleanup */
+ wolfSSL_free(ssl); ssl = NULL;
+ wolfSSL_CTX_free(ctx); ctx = NULL;
+ CloseSocket(sockfd);
+
+ if (!exitWithRet)
+ err_sys("wolfSSL_connect failed");
+ /* see note at top of README */
+ /* if you're getting an error here */
+
+ ((func_args*)args)->return_code = err;
+ goto exit;
+ }
+
+ showPeerEx(ssl, lng_index);
+
+ /* if the caller requested a particular cipher, check here that either
+ * a canonical name of the established cipher matches the requested
+ * cipher name, or the requested cipher name is marked as an alias
+ * that matches the established cipher.
+ */
+ if (cipherList && !useDefCipherList && (! XSTRSTR(cipherList, ":"))) {
+ WOLFSSL_CIPHER* established_cipher = wolfSSL_get_current_cipher(ssl);
+ byte requested_cipherSuite0, requested_cipherSuite;
+ int requested_cipherFlags;
+ if (established_cipher &&
+ /* don't test for pseudo-ciphers like "ALL" and "DEFAULT". */
+ (wolfSSL_get_cipher_suite_from_name(cipherList,
+ &requested_cipherSuite0,
+ &requested_cipherSuite,
+ &requested_cipherFlags) == 0)) {
+ word32 established_cipher_id =
+ wolfSSL_CIPHER_get_id(established_cipher);
+ byte established_cipherSuite0 = (established_cipher_id >> 8) & 0xff;
+ byte established_cipherSuite = established_cipher_id & 0xff;
+ const char *established_cipher_name =
+ wolfSSL_get_cipher_name_from_suite(established_cipherSuite0,
+ established_cipherSuite);
+ const char *established_cipher_name_iana =
+ wolfSSL_get_cipher_name_iana_from_suite(established_cipherSuite0,
+ established_cipherSuite);
+
+ if (established_cipher_name == NULL)
+ err_sys("error looking up name of established cipher");
+
+ if (strcmp(cipherList, established_cipher_name) &&
+ ((established_cipher_name_iana == NULL) ||
+ strcmp(cipherList, established_cipher_name_iana))) {
+ if (! (requested_cipherFlags & WOLFSSL_CIPHER_SUITE_FLAG_NAMEALIAS))
+ err_sys("Unexpected mismatch between names of requested and established ciphers.");
+ else if ((requested_cipherSuite0 != established_cipherSuite0) ||
+ (requested_cipherSuite != established_cipherSuite))
+ err_sys("Mismatch between IDs of requested and established ciphers.");
+ }
+ }
+ }
+
+#if defined(HAVE_OCSP) && !defined(NO_ASN_TIME)
+#ifdef HAVE_STRFTIME
+ {
+ struct tm tm;
+ char date[32];
+ ret = wolfSSL_get_ocsp_producedDate_tm(ssl, &tm);
+ if ((ret == 0) && (strftime(date, sizeof date, "%Y-%m-%d %H:%M:%S %z", &tm) > 0))
+ printf("OCSP response timestamp: %s\n", date);
+ }
+#else
+ {
+ byte date[MAX_DATE_SIZE];
+ int asn_date_format;
+ ret = wolfSSL_get_ocsp_producedDate(ssl, date, sizeof date, &asn_date_format);
+ if (ret == 0)
+ printf("OCSP response timestamp: %s (ASN.1 type %d)\n", (char *)date, asn_date_format);
+ }
+#endif
+#endif
+
+#if defined(OPENSSL_EXTRA) || defined(HAVE_SECRET_CALLBACK)
+ printf("Session timeout set to %ld seconds\n", wolfSSL_get_timeout(ssl));
+ {
+ byte* rnd;
+ byte* pt;
+ size_t size;
+
+ /* get size of buffer then print */
+ size = wolfSSL_get_client_random(NULL, NULL, 0);
+ if (size == 0) {
+ wolfSSL_free(ssl); ssl = NULL;
+ wolfSSL_CTX_free(ctx); ctx = NULL;
+ err_sys("error getting client random buffer size");
+ }
+
+ rnd = (byte*)XMALLOC(size, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+ if (rnd == NULL) {
+ wolfSSL_free(ssl); ssl = NULL;
+ wolfSSL_CTX_free(ctx); ctx = NULL;
+ err_sys("error creating client random buffer");
+ }
+
+ size = wolfSSL_get_client_random(ssl, rnd, size);
+ if (size == 0) {
+ XFREE(rnd, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+ wolfSSL_free(ssl); ssl = NULL;
+ wolfSSL_CTX_free(ctx); ctx = NULL;
+ err_sys("error getting client random buffer");
+ }
+
+ printf("Client Random : ");
+ for (pt = rnd; pt < rnd + size; pt++) printf("%02X", *pt);
+ printf("\n");
+ XFREE(rnd, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+
+ }
+#endif
+
+#if defined(OPENSSL_ALL) || (defined(OPENSSL_EXTRA) && (defined(HAVE_STUNNEL) || \
+ defined(WOLFSSL_NGINX) || defined(HAVE_LIGHTY) || \
+ defined(WOLFSSL_HAPROXY) || defined(WOLFSSL_OPENSSH)))
+#if !defined(NO_SESSION_CACHE) && \
+ (defined(HAVE_SESSION_TICKET) || defined(SESSION_CERTS)) && \
+ !defined(NO_FILESYSTEM)
+ #ifndef NO_BIO
+ /* print out session to stdout */
+ {
+ WOLFSSL_BIO* bio = wolfSSL_BIO_new_fp(stdout, BIO_NOCLOSE);
+ if (bio != NULL) {
+ if (wolfSSL_SESSION_print(bio, wolfSSL_get_session(ssl)) !=
+ WOLFSSL_SUCCESS) {
+ wolfSSL_BIO_printf(bio, "BIO error printing session\n");
+ }
+ }
+ wolfSSL_BIO_free(bio);
+ }
+ #endif /* !NO_BIO */
+#endif
+#endif
+
+ if (doSTARTTLS && starttlsProt != NULL) {
+ if (XSTRNCMP(starttlsProt, "smtp", 4) == 0) {
+ if (SMTP_Shutdown(ssl, wc_shutdown) != WOLFSSL_SUCCESS) {
+ wolfSSL_free(ssl); ssl = NULL;
+ wolfSSL_CTX_free(ctx); ctx = NULL;
+ err_sys("error closing STARTTLS connection");
+ }
+ }
+
+ wolfSSL_free(ssl); ssl = NULL;
+ CloseSocket(sockfd);
+
+ wolfSSL_CTX_free(ctx); ctx = NULL;
+
+ ((func_args*)args)->return_code = 0;
+ return 0;
+ }
+
+#ifdef HAVE_ALPN
+ if (alpnList != NULL) {
+ char *protocol_name = NULL;
+ word16 protocol_nameSz = 0;
+
+ err = wolfSSL_ALPN_GetProtocol(ssl, &protocol_name, &protocol_nameSz);
+ if (err == WOLFSSL_SUCCESS)
+ printf("Received ALPN protocol : %s (%d)\n",
+ protocol_name, protocol_nameSz);
+ else if (err == WOLFSSL_ALPN_NOT_FOUND)
+ printf("No ALPN response received (no match with server)\n");
+ else
+ printf("Getting ALPN protocol name failed\n");
+ }
+#endif
+
+#ifdef HAVE_SECURE_RENEGOTIATION
+ if (scr && forceScr) {
+ if (nonBlocking) {
+ if (!resumeScr) {
+ if ((ret = wolfSSL_Rehandshake(ssl)) != WOLFSSL_SUCCESS) {
+ err = wolfSSL_get_error(ssl, 0);
+ if (err == WOLFSSL_ERROR_WANT_READ ||
+ err == WOLFSSL_ERROR_WANT_WRITE) {
+ if (scrAppData) {
+ ret = ClientWrite(ssl,
+ "msg sent during renegotiation",
+ sizeof("msg sent during renegotiation") - 1,
+ "", 1);
+ }
+ else {
+ ret = 0;
+ }
+ if (ret != 0) {
+ ret = WOLFSSL_FAILURE;
+ }
+ else {
+ do {
+ if (err == APP_DATA_READY) {
+ if ((ret = wolfSSL_read(ssl, reply,
+ sizeof(reply)-1)) < 0) {
+ err_sys("APP DATA should be present "
+ "but error returned");
+ }
+ printf("Received message during "
+ "renegotiation: %s\n", reply);
+ }
+ err = 0;
+ if ((ret = wolfSSL_connect(ssl))
+ != WOLFSSL_SUCCESS) {
+ err = wolfSSL_get_error(ssl, ret);
+ }
+ } while (ret != WOLFSSL_SUCCESS &&
+ (err == WOLFSSL_ERROR_WANT_READ ||
+ err == WOLFSSL_ERROR_WANT_WRITE ||
+ err == APP_DATA_READY));
+ }
+
+ if (ret != WOLFSSL_SUCCESS) {
+ err = wolfSSL_get_error(ssl, 0);
+ printf("wolfSSL_Rehandshake error %d, %s\n", err,
+ wolfSSL_ERR_error_string(err, buffer));
+ wolfSSL_free(ssl); ssl = NULL;
+ wolfSSL_CTX_free(ctx); ctx = NULL;
+ err_sys("non-blocking wolfSSL_Rehandshake failed");
+ }
+ printf("NON-BLOCKING RENEGOTIATION SUCCESSFUL\n");
+ }
+ else {
+ printf("wolfSSL_Rehandshake error %d, %s\n", err,
+ wolfSSL_ERR_error_string(err, buffer));
+ wolfSSL_free(ssl); ssl = NULL;
+ wolfSSL_CTX_free(ctx); ctx = NULL;
+ err_sys("non-blocking wolfSSL_Rehandshake failed");
+ }
+ }
+ }
+ else {
+ printf("not doing secure resumption with non-blocking");
+ }
+ } else {
+ if (!resumeScr) {
+ printf("Beginning secure renegotiation.\n");
+ if ((ret = wolfSSL_Rehandshake(ssl)) != WOLFSSL_SUCCESS) {
+ err = wolfSSL_get_error(ssl, 0);
+#ifdef WOLFSSL_ASYNC_CRYPT
+ while (err == WC_PENDING_E) {
+ err = 0;
+ ret = wolfSSL_negotiate(ssl);
+ if (ret != WOLFSSL_SUCCESS) {
+ err = wolfSSL_get_error(ssl, 0);
+ if (err == WC_PENDING_E) {
+ ret = wolfSSL_AsyncPoll(ssl, WOLF_POLL_FLAG_CHECK_HW);
+ if (ret < 0) break;
+ }
+ }
+ }
+#endif
+ if (ret != WOLFSSL_SUCCESS) {
+ printf("err = %d, %s\n", err,
+ wolfSSL_ERR_error_string(err, buffer));
+ wolfSSL_free(ssl); ssl = NULL;
+ wolfSSL_CTX_free(ctx); ctx = NULL;
+ err_sys("wolfSSL_Rehandshake failed");
+ }
+ }
+ else {
+ printf("RENEGOTIATION SUCCESSFUL\n");
+ }
+ }
+ else {
+ printf("Beginning secure resumption.\n");
+ if ((ret = wolfSSL_SecureResume(ssl)) != WOLFSSL_SUCCESS) {
+ err = wolfSSL_get_error(ssl, 0);
+#ifdef WOLFSSL_ASYNC_CRYPT
+ while (err == WC_PENDING_E) {
+ err = 0;
+ ret = wolfSSL_negotiate(ssl);
+ if (ret != WOLFSSL_SUCCESS) {
+ err = wolfSSL_get_error(ssl, 0);
+ if (err == WC_PENDING_E) {
+ ret = wolfSSL_AsyncPoll(ssl, WOLF_POLL_FLAG_CHECK_HW);
+ if (ret < 0) break;
+ }
+ }
+ }
+#endif
+ if (ret != WOLFSSL_SUCCESS) {
+ printf("err = %d, %s\n", err,
+ wolfSSL_ERR_error_string(err, buffer));
+ wolfSSL_free(ssl); ssl = NULL;
+ wolfSSL_CTX_free(ctx); ctx = NULL;
+ err_sys("wolfSSL_SecureResume failed");
+ }
+ }
+ else {
+ printf("SECURE RESUMPTION SUCCESSFUL\n");
+ }
+ }
+ }
+ }
+#endif /* HAVE_SECURE_RENEGOTIATION */
+
+ XMEMSET(msg, 0, sizeof(msg));
+ if (sendGET) {
+ printf("SSL connect ok, sending GET...\n");
+
+ msgSz = (int)XSTRLEN(kHttpGetMsg);
+ XMEMCPY(msg, kHttpGetMsg, msgSz);
+ }
+ else {
+ msgSz = (int)XSTRLEN(kHelloMsg);
+ XMEMCPY(msg, kHelloMsg, msgSz);
+ }
+
+/* allow some time for exporting the session */
+#ifdef WOLFSSL_SESSION_EXPORT_DEBUG
+ TEST_DELAY();
+#endif /* WOLFSSL_SESSION_EXPORT_DEBUG */
+
+#ifdef WOLFSSL_TLS13
+ if (updateKeysIVs)
+ wolfSSL_update_keys(ssl);
+#endif
+
+ err = ClientWrite(ssl, msg, msgSz, "", exitWithRet);
+ if (exitWithRet && (err != 0)) {
+ ((func_args*)args)->return_code = err;
+ wolfSSL_free(ssl); ssl = NULL;
+ wolfSSL_CTX_free(ctx); ctx = NULL;
+ goto exit;
+ }
+
+ err = ClientRead(ssl, reply, sizeof(reply)-1, 1, "", exitWithRet);
+ if (exitWithRet && (err != 0)) {
+ ((func_args*)args)->return_code = err;
+ wolfSSL_free(ssl); ssl = NULL;
+ wolfSSL_CTX_free(ctx); ctx = NULL;
+ goto exit;
+ }
+
+#if defined(WOLFSSL_TLS13)
+ if (updateKeysIVs || postHandAuth)
+ (void)ClientWrite(ssl, msg, msgSz, "", 0);
+#endif
+
+#ifndef NO_SESSION_CACHE
+ if (resumeSession) {
+ session = wolfSSL_get_session(ssl);
+ }
+#endif
+
+#if !defined(NO_SESSION_CACHE) && (defined(OPENSSL_EXTRA) || \
+ defined(HAVE_EXT_CACHE))
+ if (session != NULL && resumeSession) {
+ flatSessionSz = wolfSSL_i2d_SSL_SESSION(session, NULL);
+ if (flatSessionSz != 0) {
+ int checkSz = wolfSSL_i2d_SSL_SESSION(session, &flatSession);
+ if (flatSession == NULL)
+ err_sys("error creating flattened session buffer");
+ if (checkSz != flatSessionSz) {
+ XFREE(flatSession, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+ err_sys("flat session size check failure");
+ }
+ }
+ }
+#endif
+
+ if (dtlsUDP == 0) { /* don't send alert after "break" command */
+ ret = wolfSSL_shutdown(ssl);
+ if (wc_shutdown && ret == WOLFSSL_SHUTDOWN_NOT_DONE) {
+ if (tcp_select(sockfd, DEFAULT_TIMEOUT_SEC) == TEST_RECV_READY) {
+ ret = wolfSSL_shutdown(ssl); /* bidirectional shutdown */
+ if (ret == WOLFSSL_SUCCESS)
+ printf("Bidirectional shutdown complete\n");
+ }
+ if (ret != WOLFSSL_SUCCESS)
+ printf("Bidirectional shutdown failed\n");
+ }
+ }
+#if defined(ATOMIC_USER) && !defined(WOLFSSL_AEAD_ONLY)
+ if (atomicUser)
+ FreeAtomicUser(ssl);
+#endif
+
+ /* display collected statistics */
+#ifdef WOLFSSL_STATIC_MEMORY
+ if (wolfSSL_is_static_memory(ssl, &ssl_stats) != 1)
+ err_sys("static memory was not used with ssl");
+
+ fprintf(stderr, "\nprint off SSL memory stats\n");
+ fprintf(stderr, "*** This is memory state before wolfSSL_free is called\n");
+ fprintf(stderr, "peak connection memory = %d\n", ssl_stats.peakMem);
+ fprintf(stderr, "current memory in use = %d\n", ssl_stats.curMem);
+ fprintf(stderr, "peak connection allocs = %d\n", ssl_stats.peakAlloc);
+ fprintf(stderr, "current connection allocs = %d\n", ssl_stats.curAlloc);
+ fprintf(stderr, "total connection allocs = %d\n", ssl_stats.totalAlloc);
+ fprintf(stderr, "total connection frees = %d\n\n", ssl_stats.totalFr);
+#endif
+
+ wolfSSL_free(ssl); ssl = NULL;
+ CloseSocket(sockfd);
+
+#ifndef NO_SESSION_CACHE
+ if (resumeSession) {
+ sslResume = wolfSSL_new(ctx);
+ if (sslResume == NULL) {
+ wolfSSL_CTX_free(ctx); ctx = NULL;
+ err_sys("unable to get SSL object");
+ }
+
+#if !defined(NO_DH) && !defined(WOLFSSL_OLD_PRIME_CHECK) && \
+ !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)
+ if (!doDhKeyCheck)
+ wolfSSL_SetEnableDhKeyTest(sslResume, 0);
+#endif
+
+ if (dtlsUDP) {
+ TEST_DELAY();
+ }
+ tcp_connect(&sockfd, host, port, dtlsUDP, dtlsSCTP, sslResume);
+ if (wolfSSL_set_fd(sslResume, sockfd) != WOLFSSL_SUCCESS) {
+ wolfSSL_free(sslResume); sslResume = NULL;
+ wolfSSL_CTX_free(ctx); ctx = NULL;
+ err_sys("error in setting fd");
+ }
+#ifdef HAVE_ALPN
+ if (alpnList != NULL) {
+ printf("ALPN accepted protocols list : %s\n", alpnList);
+ wolfSSL_UseALPN(sslResume, alpnList, (word32)XSTRLEN(alpnList),
+ alpn_opt);
+ }
+#endif
+#ifdef HAVE_SECURE_RENEGOTIATION
+ if (scr) {
+ if (wolfSSL_UseSecureRenegotiation(sslResume) != WOLFSSL_SUCCESS) {
+ wolfSSL_free(sslResume); sslResume = NULL;
+ wolfSSL_CTX_free(ctx); ctx = NULL;
+ err_sys("can't enable secure renegotiation");
+ }
+ }
+#endif
+
+#if defined(OPENSSL_EXTRA) && defined(HAVE_EXT_CACHE)
+ if (flatSession) {
+ const byte* constFlatSession = flatSession;
+ session = wolfSSL_d2i_SSL_SESSION(NULL,
+ &constFlatSession, flatSessionSz);
+ }
+#endif
+
+ wolfSSL_set_session(sslResume, session);
+
+#if defined(OPENSSL_EXTRA) && defined(HAVE_EXT_CACHE)
+ if (flatSession) {
+ XFREE(flatSession, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+ wolfSSL_SESSION_free(session);
+ }
+#endif
+#ifdef HAVE_SESSION_TICKET
+ wolfSSL_set_SessionTicket_cb(sslResume, sessionTicketCB,
+ (void*)"resumed session");
+#endif
+
+#ifndef WOLFSSL_CALLBACKS
+ if (nonBlocking) {
+#ifdef WOLFSSL_DTLS
+ if (doDTLS) {
+ wolfSSL_dtls_set_using_nonblock(sslResume, 1);
+ }
+#endif
+ tcp_set_nonblocking(&sockfd);
+ ret = NonBlockingSSL_Connect(sslResume);
+ }
+ else {
+ #ifdef WOLFSSL_EARLY_DATA
+ #ifndef HAVE_SESSION_TICKET
+ if (!usePsk) {
+ }
+ else
+ #endif
+ if (earlyData) {
+ EarlyData(ctx, sslResume, kEarlyMsg, sizeof(kEarlyMsg)-1, buffer);
+ }
+ #endif
+ do {
+ err = 0; /* reset error */
+ ret = wolfSSL_connect(sslResume);
+ if (ret != WOLFSSL_SUCCESS) {
+ err = wolfSSL_get_error(sslResume, 0);
+ #ifdef WOLFSSL_ASYNC_CRYPT
+ if (err == WC_PENDING_E) {
+ ret = wolfSSL_AsyncPoll(sslResume,
+ WOLF_POLL_FLAG_CHECK_HW);
+ if (ret < 0) break;
+ }
+ #endif
+ }
+ } while (err == WC_PENDING_E);
+ }
+#else
+ timeoutConnect.tv_sec = DEFAULT_TIMEOUT_SEC;
+ timeoutConnect.tv_usec = 0;
+ ret = NonBlockingSSL_Connect(sslResume); /* will keep retrying on timeout */
+#endif
+ if (ret != WOLFSSL_SUCCESS) {
+ printf("wolfSSL_connect resume error %d, %s\n", err,
+ wolfSSL_ERR_error_string(err, buffer));
+ wolfSSL_free(sslResume); sslResume = NULL;
+ wolfSSL_CTX_free(ctx); ctx = NULL;
+ err_sys("wolfSSL_connect resume failed");
+ }
+
+ showPeerEx(sslResume, lng_index);
+
+ if (wolfSSL_session_reused(sslResume))
+ printf("reused session id\n");
+ else
+ printf("didn't reuse session id!!!\n");
+
+#ifdef HAVE_ALPN
+ if (alpnList != NULL) {
+ char *protocol_name = NULL;
+ word16 protocol_nameSz = 0;
+
+ printf("Sending ALPN accepted list : %s\n", alpnList);
+ err = wolfSSL_ALPN_GetProtocol(sslResume, &protocol_name,
+ &protocol_nameSz);
+ if (err == WOLFSSL_SUCCESS)
+ printf("Received ALPN protocol : %s (%d)\n",
+ protocol_name, protocol_nameSz);
+ else if (err == WOLFSSL_ALPN_NOT_FOUND)
+ printf("Not received ALPN response (no match with server)\n");
+ else
+ printf("Getting ALPN protocol name failed\n");
+ }
+#endif
+
+ /* allow some time for exporting the session */
+ #ifdef WOLFSSL_SESSION_EXPORT_DEBUG
+ TEST_DELAY();
+ #endif /* WOLFSSL_SESSION_EXPORT_DEBUG */
+
+#ifdef HAVE_SECURE_RENEGOTIATION
+ if (scr && forceScr) {
+ if (nonBlocking) {
+ printf("not doing secure renegotiation on example with"
+ " nonblocking yet\n");
+ } else {
+ if (!resumeScr) {
+ printf("Beginning secure renegotiation.\n");
+ if (wolfSSL_Rehandshake(sslResume) != WOLFSSL_SUCCESS) {
+ err = wolfSSL_get_error(sslResume, 0);
+ printf("err = %d, %s\n", err,
+ wolfSSL_ERR_error_string(err, buffer));
+ wolfSSL_free(sslResume); sslResume = NULL;
+ wolfSSL_CTX_free(ctx); ctx = NULL;
+ err_sys("wolfSSL_Rehandshake failed");
+ }
+ else {
+ printf("RENEGOTIATION SUCCESSFUL\n");
+ }
+ }
+ else {
+ printf("Beginning secure resumption.\n");
+ if (wolfSSL_SecureResume(sslResume) != WOLFSSL_SUCCESS) {
+ err = wolfSSL_get_error(sslResume, 0);
+ printf("err = %d, %s\n", err,
+ wolfSSL_ERR_error_string(err, buffer));
+ wolfSSL_free(sslResume); sslResume = NULL;
+ wolfSSL_CTX_free(ctx); ctx = NULL;
+ err_sys("wolfSSL_SecureResume failed");
+ }
+ else {
+ printf("SECURE RESUMPTION SUCCESSFUL\n");
+ }
+ }
+ }
+ }
+#endif /* HAVE_SECURE_RENEGOTIATION */
+
+ XMEMSET(msg, 0, sizeof(msg));
+ if (sendGET) {
+ msgSz = (int)XSTRLEN(kHttpGetMsg);
+ XMEMCPY(msg, kHttpGetMsg, msgSz);
+ }
+ else {
+ msgSz = (int)XSTRLEN(kResumeMsg);
+ XMEMCPY(msg, kResumeMsg, msgSz);
+ }
+ (void)ClientWrite(sslResume, msg, msgSz, " resume", 0);
+
+ (void)ClientRead(sslResume, reply, sizeof(reply)-1, sendGET,
+ "Server resume: ", 0);
+
+ ret = wolfSSL_shutdown(sslResume);
+ if (wc_shutdown && ret == WOLFSSL_SHUTDOWN_NOT_DONE)
+ wolfSSL_shutdown(sslResume); /* bidirectional shutdown */
+
+ /* display collected statistics */
+ #ifdef WOLFSSL_STATIC_MEMORY
+ if (wolfSSL_is_static_memory(sslResume, &ssl_stats) != 1)
+ err_sys("static memory was not used with ssl");
+
+ fprintf(stderr, "\nprint off SSLresume memory stats\n");
+ fprintf(stderr, "*** This is memory state before wolfSSL_free is called\n");
+ fprintf(stderr, "peak connection memory = %d\n", ssl_stats.peakMem);
+ fprintf(stderr, "current memory in use = %d\n", ssl_stats.curMem);
+ fprintf(stderr, "peak connection allocs = %d\n", ssl_stats.peakAlloc);
+ fprintf(stderr, "current connection allocs = %d\n", ssl_stats.curAlloc);
+ fprintf(stderr, "total connection allocs = %d\n", ssl_stats.totalAlloc);
+ fprintf(stderr, "total connection frees = %d\n\n", ssl_stats.totalFr);
+ #endif
+
+ wolfSSL_free(sslResume); sslResume = NULL;
+ CloseSocket(sockfd);
+ }
+#endif /* !NO_SESSION_CACHE */
+
+ wolfSSL_CTX_free(ctx); ctx = NULL;
+
+ ((func_args*)args)->return_code = 0;
+
+exit:
+
+#ifdef WOLFSSL_WOLFSENTRY_HOOKS
+ wolfsentry_ret = wolfsentry_shutdown(&wolfsentry);
+ if (wolfsentry_ret < 0) {
+ fprintf(stderr,
+ "wolfsentry_shutdown() returned " WOLFSENTRY_ERROR_FMT "\n",
+ WOLFSENTRY_ERROR_FMT_ARGS(wolfsentry_ret));
+ }
+#endif
+
+#ifdef WOLFSSL_ASYNC_CRYPT
+ wolfAsync_DevClose(&devId);
+#endif
+
+#if defined(HAVE_ECC) && defined(FP_ECC) && defined(HAVE_THREAD_LS) \
+ && defined(HAVE_STACK_SIZE)
+ wc_ecc_fp_free(); /* free per thread cache */
+#endif
+
+ /* There are use cases when these assignments are not read. To avoid
+ * potential confusion those warnings have been handled here.
+ */
+ (void) useClientCert;
+ (void) verifyCert;
+ (void) ourCert;
+ (void) ourKey;
+ (void) useVerifyCb;
+
+#if !defined(WOLFSSL_TIRTOS)
+ return 0;
+#endif
+}
+
+#endif /* !NO_WOLFSSL_CLIENT */
+
+
+/* so overall tests can pull in test function */
+#ifndef NO_MAIN_DRIVER
+
+ int main(int argc, char** argv)
+ {
+ func_args args;
+
+
+ StartTCP();
+
+ args.argc = argc;
+ args.argv = argv;
+ args.return_code = 0;
+
+#if defined(DEBUG_WOLFSSL) && !defined(WOLFSSL_MDK_SHELL) && !defined(STACK_TRAP)
+ wolfSSL_Debugging_ON();
+#endif
+ wolfSSL_Init();
+ ChangeToWolfRoot();
+
+#ifndef NO_WOLFSSL_CLIENT
+#ifdef HAVE_STACK_SIZE
+ StackSizeCheck(&args, client_test);
+#else
+ client_test(&args);
+#endif
+#else
+ printf("Client not compiled in!\n");
+#endif
+ wolfSSL_Cleanup();
+
+#ifdef HAVE_WNR
+ if (wc_FreeNetRandom() < 0)
+ err_sys("Failed to free netRandom context");
+#endif /* HAVE_WNR */
+
+ return args.return_code;
+ }
+
+ int myoptind = 0;
+ char* myoptarg = NULL;
+
+#endif /* NO_MAIN_DRIVER */
diff --git a/ap/lib/libwolfssl/install/share/doc/wolfssl/example/echoclient.c b/ap/lib/libwolfssl/install/share/doc/wolfssl/example/echoclient.c
new file mode 100644
index 0000000..105b024
--- /dev/null
+++ b/ap/lib/libwolfssl/install/share/doc/wolfssl/example/echoclient.c
@@ -0,0 +1,409 @@
+/* echoclient.c
+ *
+ * Copyright (C) 2006-2021 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL.
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
+ */
+
+
+#ifdef HAVE_CONFIG_H
+ #include <config.h>
+#endif
+
+#include <cyassl/ctaocrypt/settings.h>
+/* let's use cyassl layer AND cyassl openssl layer */
+#include <cyassl/ssl.h>
+#include <cyassl/openssl/ssl.h>
+#ifdef CYASSL_DTLS
+ #include <cyassl/error-ssl.h>
+#endif
+
+#if defined(WOLFSSL_MDK_ARM) || defined(WOLFSSL_KEIL_TCP_NET)
+ #include <stdio.h>
+ #include <string.h>
+ #include "cmsis_os.h"
+ #include "rl_fs.h"
+ #include "rl_net.h"
+ #include "wolfssl_MDK_ARM.h"
+#endif
+
+#include <cyassl/test.h>
+
+#include <examples/echoclient/echoclient.h>
+
+#ifndef NO_WOLFSSL_CLIENT
+
+
+#ifdef NO_FILESYSTEM
+#ifdef NO_RSA
+#error currently the example only tries to load in a RSA buffer
+#endif
+#undef USE_CERT_BUFFERS_2048
+#define USE_CERT_BUFFERS_2048
+#include <wolfssl/certs_test.h>
+#endif
+
+#ifdef WOLFSSL_ASYNC_CRYPT
+ static int devId = INVALID_DEVID;
+#endif
+
+
+void echoclient_test(void* args)
+{
+ SOCKET_T sockfd = 0;
+
+ FILE* fin = stdin ;
+ FILE* fout = stdout;
+
+#ifndef WOLFSSL_MDK_SHELL
+ int inCreated = 0;
+ int outCreated = 0;
+#endif
+
+ char msg[1024];
+ char reply[1024+1];
+
+ SSL_METHOD* method = 0;
+ SSL_CTX* ctx = 0;
+ SSL* ssl = 0;
+
+ int ret = 0, err = 0;
+ int doDTLS = 0;
+ int doPSK = 0;
+ int sendSz;
+#ifndef WOLFSSL_MDK_SHELL
+ int argc = 0;
+ char** argv = 0;
+#endif
+ word16 port;
+ char buffer[CYASSL_MAX_ERROR_SZ];
+
+ ((func_args*)args)->return_code = -1; /* error state */
+
+#ifndef WOLFSSL_MDK_SHELL
+ argc = ((func_args*)args)->argc;
+ argv = ((func_args*)args)->argv;
+
+ if (argc >= 2) {
+ fin = fopen(argv[1], "r");
+ inCreated = 1;
+ }
+ if (argc >= 3) {
+ fout = fopen(argv[2], "w");
+ outCreated = 1;
+ }
+#endif
+
+ if (!fin) err_sys("can't open input file");
+ if (!fout) err_sys("can't open output file");
+
+#ifdef CYASSL_DTLS
+ doDTLS = 1;
+#endif
+
+#ifdef CYASSL_LEANPSK
+ doPSK = 1;
+#endif
+#if defined(NO_RSA) && !defined(HAVE_ECC) && !defined(HAVE_ED25519) && \
+ !defined(HAVE_ED448)
+ doPSK = 1;
+#endif
+ (void)doPSK;
+
+#if defined(NO_MAIN_DRIVER) && !defined(USE_WINDOWS_API) && !defined(WOLFSSL_MDK_SHELL)
+ port = ((func_args*)args)->signal->port;
+#else
+ port = yasslPort;
+#endif
+
+#if defined(CYASSL_DTLS)
+ method = DTLSv1_2_client_method();
+#elif !defined(NO_TLS)
+ #if defined(WOLFSSL_TLS13) && defined(WOLFSSL_SNIFFER)
+ method = CyaTLSv1_2_client_method();
+ #else
+ method = CyaSSLv23_client_method();
+ #endif
+#elif defined(WOLFSSL_ALLOW_SSLV3)
+ method = SSLv3_client_method();
+#else
+ #error "no valid client method type"
+#endif
+ ctx = SSL_CTX_new(method);
+
+#ifndef NO_FILESYSTEM
+ #ifndef NO_RSA
+ if (SSL_CTX_load_verify_locations(ctx, caCertFile, 0) != WOLFSSL_SUCCESS)
+ err_sys("can't load ca file, Please run from wolfSSL home dir");
+ #endif
+ #ifdef HAVE_ECC
+ if (SSL_CTX_load_verify_locations(ctx, caEccCertFile, 0) != WOLFSSL_SUCCESS)
+ err_sys("can't load ca file, Please run from wolfSSL home dir");
+ #elif defined(HAVE_ED25519)
+ if (SSL_CTX_load_verify_locations(ctx, caEdCertFile, 0) != WOLFSSL_SUCCESS)
+ err_sys("can't load ca file, Please run from wolfSSL home dir");
+ #elif defined(HAVE_ED448)
+ if (SSL_CTX_load_verify_locations(ctx, caEd448CertFile, 0) != WOLFSSL_SUCCESS)
+ err_sys("can't load ca file, Please run from wolfSSL home dir");
+ #endif
+#elif !defined(NO_CERTS)
+ if (!doPSK)
+ if (wolfSSL_CTX_load_verify_buffer(ctx, ca_cert_der_2048,
+ sizeof_ca_cert_der_2048, WOLFSSL_FILETYPE_ASN1) != WOLFSSL_SUCCESS)
+ err_sys("can't load ca buffer");
+#endif
+
+#if defined(CYASSL_SNIFFER)
+ /* Only set if not running testsuite */
+ if (XSTRSTR(argv[0], "testsuite") != 0) {
+ /* don't use EDH, can't sniff tmp keys */
+ SSL_CTX_set_cipher_list(ctx, "AES256-SHA");
+ }
+#endif
+#ifndef NO_PSK
+ if (doPSK) {
+ const char *defaultCipherList;
+
+ CyaSSL_CTX_set_psk_client_callback(ctx, my_psk_client_cb);
+ #ifdef HAVE_NULL_CIPHER
+ defaultCipherList = "PSK-NULL-SHA256";
+ #elif defined(HAVE_AESGCM) && !defined(NO_DH)
+ #ifdef WOLFSSL_TLS13
+ defaultCipherList = "TLS13-AES128-GCM-SHA256"
+ #ifndef WOLFSSL_NO_TLS12
+ ":DHE-PSK-AES128-GCM-SHA256"
+ #endif
+ ;
+ #else
+ defaultCipherList = "DHE-PSK-AES128-GCM-SHA256";
+ #endif
+ #elif defined(HAVE_AESGCM) && defined(WOLFSSL_TLS13)
+ defaultCipherList = "TLS13-AES128-GCM-SHA256"
+ #ifndef WOLFSSL_NO_TLS12
+ ":DHE-PSK-AES128-GCM-SHA256"
+ #endif
+ ;
+ #else
+ defaultCipherList = "PSK-AES128-CBC-SHA256";
+ #endif
+ if (CyaSSL_CTX_set_cipher_list(ctx,defaultCipherList) !=WOLFSSL_SUCCESS)
+ err_sys("client can't set cipher list 2");
+ wolfSSL_CTX_set_psk_callback_ctx(ctx, (void*)defaultCipherList);
+ }
+#endif
+
+#ifdef WOLFSSL_ENCRYPTED_KEYS
+ SSL_CTX_set_default_passwd_cb(ctx, PasswordCallBack);
+#endif
+
+#if defined(WOLFSSL_MDK_ARM)
+ CyaSSL_CTX_set_verify(ctx, WOLFSSL_VERIFY_NONE, 0);
+#endif
+
+#ifdef WOLFSSL_ASYNC_CRYPT
+ ret = wolfAsync_DevOpen(&devId);
+ if (ret < 0) {
+ printf("Async device open failed\nRunning without async\n");
+ }
+ wolfSSL_CTX_SetDevId(ctx, devId);
+#endif /* WOLFSSL_ASYNC_CRYPT */
+
+ ssl = SSL_new(ctx);
+ tcp_connect(&sockfd, yasslIP, port, doDTLS, 0, ssl);
+
+ SSL_set_fd(ssl, sockfd);
+#if defined(USE_WINDOWS_API) && defined(CYASSL_DTLS) && defined(NO_MAIN_DRIVER)
+ /* let echoserver bind first, TODO: add Windows signal like pthreads does */
+ Sleep(100);
+#endif
+
+ do {
+ err = 0; /* Reset error */
+ ret = SSL_connect(ssl);
+ if (ret != WOLFSSL_SUCCESS) {
+ err = SSL_get_error(ssl, 0);
+ #ifdef WOLFSSL_ASYNC_CRYPT
+ if (err == WC_PENDING_E) {
+ ret = wolfSSL_AsyncPoll(ssl, WOLF_POLL_FLAG_CHECK_HW);
+ if (ret < 0) break;
+ }
+ #endif
+ }
+ } while (err == WC_PENDING_E);
+ if (ret != WOLFSSL_SUCCESS) {
+ printf("SSL_connect error %d, %s\n", err,
+ ERR_error_string(err, buffer));
+ err_sys("SSL_connect failed");
+ }
+
+ while (fgets(msg, sizeof(msg), fin) != 0) {
+
+ sendSz = (int)XSTRLEN(msg);
+
+ do {
+ err = 0; /* reset error */
+ ret = SSL_write(ssl, msg, sendSz);
+ if (ret <= 0) {
+ err = SSL_get_error(ssl, 0);
+ #ifdef WOLFSSL_ASYNC_CRYPT
+ if (err == WC_PENDING_E) {
+ ret = wolfSSL_AsyncPoll(ssl, WOLF_POLL_FLAG_CHECK_HW);
+ if (ret < 0) break;
+ }
+ #endif
+ }
+ } while (err == WC_PENDING_E);
+ if (ret != sendSz) {
+ printf("SSL_write msg error %d, %s\n", err,
+ ERR_error_string(err, buffer));
+ err_sys("SSL_write failed");
+ }
+
+ if (strncmp(msg, "quit", 4) == 0) {
+ fputs("sending server shutdown command: quit!\n", fout);
+ break;
+ }
+
+ if (strncmp(msg, "break", 5) == 0) {
+ fputs("sending server session close: break!\n", fout);
+ break;
+ }
+
+ #ifndef WOLFSSL_MDK_SHELL
+ while (sendSz)
+ #endif
+ {
+ do {
+ err = 0; /* reset error */
+ ret = SSL_read(ssl, reply, sizeof(reply)-1);
+ if (ret <= 0) {
+ err = SSL_get_error(ssl, 0);
+ #ifdef WOLFSSL_ASYNC_CRYPT
+ if (err == WC_PENDING_E) {
+ ret = wolfSSL_AsyncPoll(ssl, WOLF_POLL_FLAG_CHECK_HW);
+ if (ret < 0) break;
+ }
+ #endif
+ }
+ } while (err == WC_PENDING_E);
+ if (ret > 0) {
+ reply[ret] = 0;
+ fputs(reply, fout);
+ fflush(fout) ;
+ sendSz -= ret;
+ }
+#ifdef CYASSL_DTLS
+ else if (wolfSSL_dtls(ssl) && err == DECRYPT_ERROR) {
+ /* This condition is OK. The packet should be dropped
+ * silently when there is a decrypt or MAC error on
+ * a DTLS record. */
+ sendSz = 0;
+ }
+#endif
+ else {
+ printf("SSL_read msg error %d, %s\n", err,
+ ERR_error_string(err, buffer));
+ err_sys("SSL_read failed");
+
+ #ifndef WOLFSSL_MDK_SHELL
+ break;
+ #endif
+ }
+ }
+ }
+
+
+#ifdef CYASSL_DTLS
+ strncpy(msg, "break", 6);
+ sendSz = (int)strlen(msg);
+ /* try to tell server done */
+ do {
+ err = 0; /* reset error */
+ ret = SSL_write(ssl, msg, sendSz);
+ if (ret <= 0) {
+ err = SSL_get_error(ssl, 0);
+ #ifdef WOLFSSL_ASYNC_CRYPT
+ if (err == WC_PENDING_E) {
+ ret = wolfSSL_AsyncPoll(ssl, WOLF_POLL_FLAG_CHECK_HW);
+ if (ret < 0) break;
+ }
+ #endif
+ }
+ } while (err == WC_PENDING_E);
+#else
+ SSL_shutdown(ssl);
+#endif
+
+ SSL_free(ssl);
+ SSL_CTX_free(ctx);
+
+#ifdef WOLFSSL_ASYNC_CRYPT
+ wolfAsync_DevClose(&devId);
+#endif
+
+ fflush(fout);
+#ifndef WOLFSSL_MDK_SHELL
+ if (inCreated) fclose(fin);
+ if (outCreated) fclose(fout);
+#endif
+
+ CloseSocket(sockfd);
+ ((func_args*)args)->return_code = 0;
+}
+
+#endif /* !NO_WOLFSSL_CLIENT */
+
+/* so overall tests can pull in test function */
+#ifndef NO_MAIN_DRIVER
+
+ int main(int argc, char** argv)
+ {
+ func_args args;
+
+#ifdef HAVE_WNR
+ if (wc_InitNetRandom(wnrConfig, NULL, 5000) != 0)
+ err_sys("Whitewood netRandom global config failed");
+#endif
+
+ StartTCP();
+
+ args.argc = argc;
+ args.argv = argv;
+ args.return_code = 0;
+
+ CyaSSL_Init();
+#if defined(DEBUG_CYASSL) && !defined(WOLFSSL_MDK_SHELL)
+ CyaSSL_Debugging_ON();
+#endif
+#ifndef CYASSL_TIRTOS
+ ChangeToWolfRoot();
+#endif
+#ifndef NO_WOLFSSL_CLIENT
+ echoclient_test(&args);
+#endif
+
+ CyaSSL_Cleanup();
+
+#ifdef HAVE_WNR
+ if (wc_FreeNetRandom() < 0)
+ err_sys("Failed to free netRandom context");
+#endif /* HAVE_WNR */
+
+ return args.return_code;
+ }
+
+#endif /* NO_MAIN_DRIVER */
diff --git a/ap/lib/libwolfssl/install/share/doc/wolfssl/example/echoserver.c b/ap/lib/libwolfssl/install/share/doc/wolfssl/example/echoserver.c
new file mode 100644
index 0000000..fc36a26
--- /dev/null
+++ b/ap/lib/libwolfssl/install/share/doc/wolfssl/example/echoserver.c
@@ -0,0 +1,576 @@
+/* echoserver.c
+ *
+ * Copyright (C) 2006-2021 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL.
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
+ */
+
+
+#ifdef HAVE_CONFIG_H
+ #include <config.h>
+#endif
+
+#include <cyassl/ssl.h> /* name change portability layer */
+#include <cyassl/ctaocrypt/settings.h>
+#ifdef HAVE_ECC
+ #include <cyassl/ctaocrypt/ecc.h> /* ecc_fp_free */
+#endif
+
+#if defined(WOLFSSL_MDK_ARM) || defined(WOLFSSL_KEIL_TCP_NET)
+ #include <stdio.h>
+ #include <string.h>
+ #include "cmsis_os.h"
+ #include "rl_fs.h"
+ #include "rl_net.h"
+ #include "wolfssl_MDK_ARM.h"
+#endif
+
+#include <cyassl/ssl.h>
+#include <cyassl/test.h>
+
+#ifndef NO_MAIN_DRIVER
+ #define ECHO_OUT
+#endif
+
+#include "examples/echoserver/echoserver.h"
+
+#ifndef NO_WOLFSSL_SERVER
+
+#ifdef NO_FILESYSTEM
+#ifdef NO_RSA
+#error currently the example only tries to load in a RSA buffer
+#endif
+#undef USE_CERT_BUFFERS_2048
+#define USE_CERT_BUFFERS_2048
+#include <wolfssl/certs_test.h>
+#endif
+
+#ifdef WOLFSSL_ASYNC_CRYPT
+ static int devId = INVALID_DEVID;
+#endif
+
+#define SVR_COMMAND_SIZE 256
+
+static void SignalReady(void* args, word16 port)
+{
+#if defined(_POSIX_THREADS) && defined(NO_MAIN_DRIVER) && !defined(__MINGW32__)
+ /* signal ready to tcp_accept */
+ func_args* server_args = (func_args*)args;
+ tcp_ready* ready = server_args->signal;
+ pthread_mutex_lock(&ready->mutex);
+ ready->ready = 1;
+ ready->port = port;
+ pthread_cond_signal(&ready->cond);
+ pthread_mutex_unlock(&ready->mutex);
+#endif
+ (void)args;
+ (void)port;
+}
+
+
+THREAD_RETURN CYASSL_THREAD echoserver_test(void* args)
+{
+ SOCKET_T sockfd = 0;
+ CYASSL_METHOD* method = 0;
+ CYASSL_CTX* ctx = 0;
+
+ int ret = 0;
+ int doDTLS = 0;
+ int doPSK;
+ int outCreated = 0;
+ int shutDown = 0;
+ int useAnyAddr = 0;
+ word16 port;
+ int argc = ((func_args*)args)->argc;
+ char** argv = ((func_args*)args)->argv;
+ char buffer[CYASSL_MAX_ERROR_SZ];
+
+#ifdef ECHO_OUT
+ FILE* fout = stdout;
+ if (argc >= 2) {
+ fout = fopen(argv[1], "w");
+ outCreated = 1;
+ }
+ if (!fout) err_sys("can't open output file");
+#endif
+ (void)outCreated;
+ (void)argc;
+ (void)argv;
+
+ ((func_args*)args)->return_code = -1; /* error state */
+
+#ifdef CYASSL_DTLS
+ doDTLS = 1;
+#endif
+
+#if (defined(NO_RSA) && !defined(HAVE_ECC) && !defined(HAVE_ED25519) && \
+ !defined(HAVE_ED448)) || defined(CYASSL_LEANPSK)
+ doPSK = 1;
+#else
+ doPSK = 0;
+#endif
+
+#if defined(NO_MAIN_DRIVER) && !defined(CYASSL_SNIFFER) && \
+ !defined(WOLFSSL_MDK_SHELL) && !defined(CYASSL_TIRTOS) && \
+ !defined(USE_WINDOWS_API)
+ /* Let tcp_listen assign port */
+ port = 0;
+#else
+ /* Use default port */
+ port = wolfSSLPort;
+#endif
+
+#if defined(USE_ANY_ADDR)
+ useAnyAddr = 1;
+#endif
+
+#ifdef CYASSL_TIRTOS
+ fdOpenSession(Task_self());
+#endif
+
+ tcp_listen(&sockfd, &port, useAnyAddr, doDTLS, 0);
+
+#if defined(CYASSL_DTLS)
+ method = CyaDTLSv1_2_server_method();
+#elif !defined(NO_TLS)
+ #if (defined(WOLFSSL_TLS13) && defined(WOLFSSL_SNIFFER)) || \
+ defined(HAVE_NTRU)
+ method = CyaTLSv1_2_server_method();
+ #else
+ method = CyaSSLv23_server_method();
+ #endif
+#elif defined(WOLFSSL_ALLOW_SSLV3)
+ method = CyaSSLv3_server_method();
+#else
+ #error "no valid server method built in"
+#endif
+ ctx = CyaSSL_CTX_new(method);
+ /* CyaSSL_CTX_set_session_cache_mode(ctx, WOLFSSL_SESS_CACHE_OFF); */
+
+#ifdef WOLFSSL_ENCRYPTED_KEYS
+ CyaSSL_CTX_set_default_passwd_cb(ctx, PasswordCallBack);
+#endif
+
+#if defined(HAVE_SESSION_TICKET) && defined(WOLFSSL_NO_DEF_TICKET_ENC_CB) && \
+ ((defined(HAVE_CHACHA) && defined(HAVE_POLY1305)) || defined(HAVE_AESGCM))
+ if (TicketInit() != 0)
+ err_sys("unable to setup Session Ticket Key context");
+ wolfSSL_CTX_set_TicketEncCb(ctx, myTicketEncCb);
+#endif
+
+#ifndef NO_FILESYSTEM
+ if (doPSK == 0) {
+ #if defined(HAVE_NTRU) && defined(WOLFSSL_STATIC_RSA)
+ /* ntru */
+ if (CyaSSL_CTX_use_certificate_file(ctx, ntruCertFile, WOLFSSL_FILETYPE_PEM)
+ != WOLFSSL_SUCCESS)
+ err_sys("can't load ntru cert file, "
+ "Please run from wolfSSL home dir");
+
+ if (CyaSSL_CTX_use_NTRUPrivateKey_file(ctx, ntruKeyFile)
+ != WOLFSSL_SUCCESS)
+ err_sys("can't load ntru key file, "
+ "Please run from wolfSSL home dir");
+ #elif defined(HAVE_ECC) && !defined(CYASSL_SNIFFER)
+ /* ecc */
+ if (CyaSSL_CTX_use_certificate_file(ctx, eccCertFile, WOLFSSL_FILETYPE_PEM)
+ != WOLFSSL_SUCCESS)
+ err_sys("can't load server cert file, "
+ "Please run from wolfSSL home dir");
+
+ if (CyaSSL_CTX_use_PrivateKey_file(ctx, eccKeyFile, WOLFSSL_FILETYPE_PEM)
+ != WOLFSSL_SUCCESS)
+ err_sys("can't load server key file, "
+ "Please run from wolfSSL home dir");
+ #elif defined(HAVE_ED25519) && !defined(CYASSL_SNIFFER)
+ /* ed25519 */
+ if (CyaSSL_CTX_use_certificate_chain_file(ctx, edCertFile)
+ != WOLFSSL_SUCCESS)
+ err_sys("can't load server cert file, "
+ "Please run from wolfSSL home dir");
+
+ if (CyaSSL_CTX_use_PrivateKey_file(ctx, edKeyFile, WOLFSSL_FILETYPE_PEM)
+ != WOLFSSL_SUCCESS)
+ err_sys("can't load server key file, "
+ "Please run from wolfSSL home dir");
+ #elif defined(HAVE_ED448) && !defined(CYASSL_SNIFFER)
+ /* ed448 */
+ if (CyaSSL_CTX_use_certificate_chain_file(ctx, ed448CertFile)
+ != WOLFSSL_SUCCESS)
+ err_sys("can't load server cert file, "
+ "Please run from wolfSSL home dir");
+
+ if (CyaSSL_CTX_use_PrivateKey_file(ctx, ed448KeyFile,
+ WOLFSSL_FILETYPE_PEM) != WOLFSSL_SUCCESS)
+ err_sys("can't load server key file, "
+ "Please run from wolfSSL home dir");
+ #elif defined(NO_CERTS)
+ /* do nothing, just don't load cert files */
+ #else
+ /* normal */
+ if (CyaSSL_CTX_use_certificate_file(ctx, svrCertFile, WOLFSSL_FILETYPE_PEM)
+ != WOLFSSL_SUCCESS)
+ err_sys("can't load server cert file, "
+ "Please run from wolfSSL home dir");
+
+ if (CyaSSL_CTX_use_PrivateKey_file(ctx, svrKeyFile, WOLFSSL_FILETYPE_PEM)
+ != WOLFSSL_SUCCESS)
+ err_sys("can't load server key file, "
+ "Please run from wolfSSL home dir");
+ #endif
+ } /* doPSK */
+#elif !defined(NO_CERTS)
+ if (!doPSK) {
+ if (CyaSSL_CTX_use_certificate_buffer(ctx, server_cert_der_2048,
+ sizeof_server_cert_der_2048, WOLFSSL_FILETYPE_ASN1)
+ != WOLFSSL_SUCCESS)
+ err_sys("can't load server cert buffer");
+
+ if (CyaSSL_CTX_use_PrivateKey_buffer(ctx, server_key_der_2048,
+ sizeof_server_key_der_2048, WOLFSSL_FILETYPE_ASN1)
+ != WOLFSSL_SUCCESS)
+ err_sys("can't load server key buffer");
+ }
+#endif
+
+#if defined(CYASSL_SNIFFER)
+ /* Only set if not running testsuite */
+ if (XSTRSTR(argv[0], "testsuite") != 0) {
+ /* don't use EDH, can't sniff tmp keys */
+ CyaSSL_CTX_set_cipher_list(ctx, "AES256-SHA");
+ }
+#endif
+
+ if (doPSK) {
+#ifndef NO_PSK
+ const char *defaultCipherList;
+
+ CyaSSL_CTX_set_psk_server_callback(ctx, my_psk_server_cb);
+ CyaSSL_CTX_use_psk_identity_hint(ctx, "cyassl server");
+ #ifdef HAVE_NULL_CIPHER
+ defaultCipherList = "PSK-NULL-SHA256";
+ #elif defined(HAVE_AESGCM) && !defined(NO_DH)
+ #ifdef WOLFSSL_TLS13
+ defaultCipherList = "TLS13-AES128-GCM-SHA256"
+ #ifndef WOLFSSL_NO_TLS12
+ ":DHE-PSK-AES128-GCM-SHA256"
+ #endif
+ ;
+ #else
+ defaultCipherList = "DHE-PSK-AES128-GCM-SHA256";
+ #endif
+ #elif defined(HAVE_AESGCM) && defined(WOLFSSL_TLS13)
+ defaultCipherList = "TLS13-AES128-GCM-SHA256"
+ #ifndef WOLFSSL_NO_TLS12
+ ":PSK-AES128-GCM-SHA256"
+ #endif
+ ;
+ #else
+ defaultCipherList = "PSK-AES128-CBC-SHA256";
+ #endif
+ if (CyaSSL_CTX_set_cipher_list(ctx, defaultCipherList) != WOLFSSL_SUCCESS)
+ err_sys("server can't set cipher list 2");
+ wolfSSL_CTX_set_psk_callback_ctx(ctx, (void*)defaultCipherList);
+#endif
+ }
+
+#ifdef WOLFSSL_ASYNC_CRYPT
+ ret = wolfAsync_DevOpen(&devId);
+ if (ret < 0) {
+ printf("Async device open failed\nRunning without async\n");
+ }
+ wolfSSL_CTX_SetDevId(ctx, devId);
+#endif /* WOLFSSL_ASYNC_CRYPT */
+
+ SignalReady(args, port);
+
+ while (!shutDown) {
+ CYASSL* ssl = NULL;
+ CYASSL* write_ssl = NULL; /* may have separate w/ HAVE_WRITE_DUP */
+ char command[SVR_COMMAND_SIZE+1];
+ int echoSz = 0;
+ int clientfd;
+ int firstRead = 1;
+ int gotFirstG = 0;
+ int err = 0;
+ SOCKADDR_IN_T client;
+ socklen_t client_len = sizeof(client);
+#ifndef CYASSL_DTLS
+ clientfd = accept(sockfd, (struct sockaddr*)&client,
+ (ACCEPT_THIRD_T)&client_len);
+#else
+ clientfd = sockfd;
+ {
+ /* For DTLS, peek at the next datagram so we can get the client's
+ * address and set it into the ssl object later to generate the
+ * cookie. */
+ int n;
+ byte b[1500];
+ n = (int)recvfrom(clientfd, (char*)b, sizeof(b), MSG_PEEK,
+ (struct sockaddr*)&client, &client_len);
+ if (n <= 0)
+ err_sys("recvfrom failed");
+ }
+#endif
+ if (WOLFSSL_SOCKET_IS_INVALID(clientfd)) err_sys("tcp accept failed");
+
+ ssl = CyaSSL_new(ctx);
+ if (ssl == NULL) err_sys("SSL_new failed");
+ CyaSSL_set_fd(ssl, clientfd);
+ #ifdef CYASSL_DTLS
+ wolfSSL_dtls_set_peer(ssl, &client, client_len);
+ #endif
+ #if !defined(NO_FILESYSTEM) && !defined(NO_DH) && !defined(NO_ASN)
+ CyaSSL_SetTmpDH_file(ssl, dhParamFile, WOLFSSL_FILETYPE_PEM);
+ #elif !defined(NO_DH)
+ SetDH(ssl); /* will repick suites with DHE, higher than PSK */
+ #endif
+
+ do {
+ err = 0; /* Reset error */
+ ret = CyaSSL_accept(ssl);
+ if (ret != WOLFSSL_SUCCESS) {
+ err = CyaSSL_get_error(ssl, 0);
+ #ifdef WOLFSSL_ASYNC_CRYPT
+ if (err == WC_PENDING_E) {
+ ret = wolfSSL_AsyncPoll(ssl, WOLF_POLL_FLAG_CHECK_HW);
+ if (ret < 0) break;
+ }
+ #endif
+ }
+ } while (err == WC_PENDING_E);
+ if (ret != WOLFSSL_SUCCESS) {
+ printf("SSL_accept error = %d, %s\n", err,
+ CyaSSL_ERR_error_string(err, buffer));
+ printf("SSL_accept failed\n");
+ CyaSSL_free(ssl);
+ CloseSocket(clientfd);
+ continue;
+ }
+#if defined(PEER_INFO)
+ showPeer(ssl);
+#endif
+
+#ifdef HAVE_WRITE_DUP
+ write_ssl = wolfSSL_write_dup(ssl);
+ if (write_ssl == NULL) {
+ printf("wolfSSL_write_dup failed\n");
+ CyaSSL_free(ssl);
+ CloseSocket(clientfd);
+ continue;
+ }
+#else
+ write_ssl = ssl;
+#endif
+
+ while (1) {
+ do {
+ err = 0; /* reset error */
+ ret = CyaSSL_read(ssl, command, sizeof(command)-1);
+ if (ret <= 0) {
+ err = CyaSSL_get_error(ssl, 0);
+ #ifdef WOLFSSL_ASYNC_CRYPT
+ if (err == WC_PENDING_E) {
+ ret = wolfSSL_AsyncPoll(ssl, WOLF_POLL_FLAG_CHECK_HW);
+ if (ret < 0) break;
+ }
+ #endif
+ }
+ } while (err == WC_PENDING_E);
+ if (ret <= 0) {
+ if (err != WOLFSSL_ERROR_WANT_READ && err != WOLFSSL_ERROR_ZERO_RETURN){
+ printf("SSL_read echo error %d, %s!\n", err,
+ CyaSSL_ERR_error_string(err, buffer));
+ }
+ break;
+ }
+
+ echoSz = ret;
+
+ if (firstRead == 1) {
+ firstRead = 0; /* browser may send 1 byte 'G' to start */
+ if (echoSz == 1 && command[0] == 'G') {
+ gotFirstG = 1;
+ continue;
+ }
+ }
+ else if (gotFirstG == 1 && strncmp(command, "ET /", 4) == 0) {
+ strncpy(command, "GET", 4);
+ /* fall through to normal GET */
+ }
+
+ if ( strncmp(command, "quit", 4) == 0) {
+ printf("client sent quit command: shutting down!\n");
+ shutDown = 1;
+ break;
+ }
+ if ( strncmp(command, "break", 5) == 0) {
+ printf("client sent break command: closing session!\n");
+ break;
+ }
+#ifdef PRINT_SESSION_STATS
+ if ( strncmp(command, "printstats", 10) == 0) {
+ CyaSSL_PrintSessionStats();
+ break;
+ }
+#endif
+ if (strncmp(command, "GET", 3) == 0) {
+ const char resp[] =
+ "HTTP/1.0 200 ok\r\nContent-type: text/html\r\n\r\n"
+ "<html><body BGCOLOR=\"#ffffff\"><pre>\r\n"
+ "greetings from wolfSSL\r\n</pre></body></html>\r\n\r\n";
+
+ echoSz = (int)strlen(resp) + 1;
+ if (echoSz > (int)sizeof(command)) {
+ /* Internal error. */
+ err_sys("HTTP response greater than buffer.");
+ }
+ strncpy(command, resp, sizeof(command));
+
+ do {
+ err = 0; /* reset error */
+ ret = CyaSSL_write(write_ssl, command, echoSz);
+ if (ret <= 0) {
+ err = CyaSSL_get_error(write_ssl, 0);
+ #ifdef WOLFSSL_ASYNC_CRYPT
+ if (err == WC_PENDING_E) {
+ ret = wolfSSL_AsyncPoll(write_ssl, WOLF_POLL_FLAG_CHECK_HW);
+ if (ret < 0) break;
+ }
+ #endif
+ }
+ } while (err == WC_PENDING_E);
+ if (ret != echoSz) {
+ printf("SSL_write get error = %d, %s\n", err,
+ CyaSSL_ERR_error_string(err, buffer));
+ err_sys("SSL_write get failed");
+ }
+ break;
+ }
+ command[echoSz] = 0;
+
+ #ifdef ECHO_OUT
+ fputs(command, fout);
+ #endif
+
+ do {
+ err = 0; /* reset error */
+ ret = CyaSSL_write(write_ssl, command, echoSz);
+ if (ret <= 0) {
+ err = CyaSSL_get_error(write_ssl, 0);
+ #ifdef WOLFSSL_ASYNC_CRYPT
+ if (err == WC_PENDING_E) {
+ ret = wolfSSL_AsyncPoll(write_ssl, WOLF_POLL_FLAG_CHECK_HW);
+ if (ret < 0) break;
+ }
+ #endif
+ }
+ } while (err == WC_PENDING_E);
+
+ if (ret != echoSz) {
+ printf("SSL_write echo error = %d, %s\n", err,
+ CyaSSL_ERR_error_string(err, buffer));
+ err_sys("SSL_write echo failed");
+ }
+ }
+#ifndef CYASSL_DTLS
+ CyaSSL_shutdown(ssl);
+#endif
+#ifdef HAVE_WRITE_DUP
+ CyaSSL_free(write_ssl);
+#endif
+ CyaSSL_free(ssl);
+ CloseSocket(clientfd);
+#ifdef CYASSL_DTLS
+ tcp_listen(&sockfd, &port, useAnyAddr, doDTLS, 0);
+ SignalReady(args, port);
+#endif
+ }
+
+ CloseSocket(sockfd);
+ CyaSSL_CTX_free(ctx);
+
+#ifdef ECHO_OUT
+ if (outCreated)
+ fclose(fout);
+#endif
+
+ ((func_args*)args)->return_code = 0;
+
+#if defined(NO_MAIN_DRIVER) && defined(HAVE_ECC) && defined(FP_ECC) \
+ && defined(HAVE_THREAD_LS)
+ ecc_fp_free(); /* free per thread cache */
+#endif
+
+#ifdef CYASSL_TIRTOS
+ fdCloseSession(Task_self());
+#endif
+
+#if defined(HAVE_SESSION_TICKET) && defined(WOLFSSL_NO_DEF_TICKET_ENC_CB) && \
+ ((defined(HAVE_CHACHA) && defined(HAVE_POLY1305)) || defined(HAVE_AESGCM))
+ TicketCleanup();
+#endif
+
+#ifdef WOLFSSL_ASYNC_CRYPT
+ wolfAsync_DevClose(&devId);
+#endif
+
+#ifndef CYASSL_TIRTOS
+ return 0;
+#endif
+}
+
+#endif /* !NO_WOLFSSL_SERVER */
+
+
+/* so overall tests can pull in test function */
+#ifndef NO_MAIN_DRIVER
+
+ int main(int argc, char** argv)
+ {
+ func_args args;
+
+#ifdef HAVE_WNR
+ if (wc_InitNetRandom(wnrConfig, NULL, 5000) != 0)
+ err_sys("Whitewood netRandom global config failed");
+#endif
+
+ StartTCP();
+
+ args.argc = argc;
+ args.argv = argv;
+ args.return_code = 0;
+
+ CyaSSL_Init();
+#if defined(DEBUG_CYASSL) && !defined(CYASSL_MDK_SHELL)
+ CyaSSL_Debugging_ON();
+#endif
+ ChangeToWolfRoot();
+#ifndef NO_WOLFSSL_SERVER
+ echoserver_test(&args);
+#endif
+ CyaSSL_Cleanup();
+
+#ifdef HAVE_WNR
+ if (wc_FreeNetRandom() < 0)
+ err_sys("Failed to free netRandom context");
+#endif /* HAVE_WNR */
+
+ return args.return_code;
+ }
+
+#endif /* NO_MAIN_DRIVER */
diff --git a/ap/lib/libwolfssl/install/share/doc/wolfssl/example/sctp-client-dtls.c b/ap/lib/libwolfssl/install/share/doc/wolfssl/example/sctp-client-dtls.c
new file mode 100644
index 0000000..8022e50
--- /dev/null
+++ b/ap/lib/libwolfssl/install/share/doc/wolfssl/example/sctp-client-dtls.c
@@ -0,0 +1,130 @@
+/* sctp-client-dtls.c
+ *
+ * Copyright (C) 2006-2021 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL.
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
+ */
+
+
+/* wolfssl */
+#ifndef WOLFSSL_USER_SETTINGS
+ #include <wolfssl/options.h>
+#endif
+#include <wolfssl/wolfcrypt/settings.h>
+#include <wolfssl/ssl.h>
+
+#if defined(WOLFSSL_SCTP) && defined(WOLFSSL_DTLS)
+/* sctp */
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <arpa/inet.h>
+#include <netinet/in.h>
+
+/* std */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#define cacert "./certs/ca-cert.pem"
+
+static int err_sys(const char* msg)
+{
+ perror(msg);
+ exit(EXIT_FAILURE);
+}
+#endif /* WOLFSSL_SCTP && WOLFSSL_DTLS */
+
+int main()
+{
+#if defined(WOLFSSL_SCTP) && defined(WOLFSSL_DTLS)
+ int sd = socket(PF_INET, SOCK_STREAM, IPPROTO_SCTP);
+
+ if (sd < 0)
+ err_sys("sctp socket error");
+
+ struct sockaddr_in sa;
+ memset(&sa, 0, sizeof(sa));
+ sa.sin_family = AF_INET;
+ sa.sin_addr.s_addr = inet_addr("127.0.0.1");
+ sa.sin_port = htons(12345);
+
+ int ret = connect(sd, (struct sockaddr*)&sa, sizeof(sa));
+ if (ret < 0)
+ err_sys("sctp connect error");
+
+ const char* response = "hello there";
+ char buffer[80];
+
+ WOLFSSL_CTX* ctx = wolfSSL_CTX_new(wolfDTLSv1_2_client_method());
+ if (ctx == NULL)
+ err_sys("ctx new dtls client failed");
+
+ ret = wolfSSL_CTX_dtls_set_sctp(ctx);
+ if (ret != WOLFSSL_SUCCESS)
+ err_sys("set sctp mode failed");
+
+ ret = wolfSSL_CTX_load_verify_locations(ctx, cacert, NULL);
+ if (ret != WOLFSSL_SUCCESS)
+ err_sys("ca cert error");
+
+ WOLFSSL* ssl = wolfSSL_new(ctx);
+ if (ssl == NULL)
+ err_sys("ssl new dtls client failed");
+
+ wolfSSL_set_fd(ssl, sd);
+
+ ret = wolfSSL_connect(ssl);
+ if (ret != WOLFSSL_SUCCESS)
+ err_sys("ssl connect failed");
+
+ printf("TLS version is %s\n", wolfSSL_get_version(ssl));
+ printf("Cipher Suite is %s\n",
+ wolfSSL_CIPHER_get_name(wolfSSL_get_current_cipher(ssl)));
+
+ wolfSSL_write(ssl, response, (int)strlen(response));
+ int got = wolfSSL_read(ssl, buffer, sizeof(buffer));
+ if (got > 0) {
+ buffer[got] = 0;
+ printf("server said: %s\n", buffer);
+ }
+
+ unsigned char bigBuf[4096];
+ unsigned int i;
+
+ for (i = 0; i < (int)sizeof(bigBuf); i++)
+ bigBuf[i] = (unsigned char)(i & 0xFF);
+ wolfSSL_write(ssl, bigBuf, sizeof(bigBuf));
+ memset(bigBuf, 0, sizeof(bigBuf));
+
+ wolfSSL_read(ssl, bigBuf, sizeof(bigBuf));
+ for (i = 0; i < sizeof(bigBuf); i++) {
+ if (bigBuf[i] != (unsigned char)(i & 0xFF)) {
+ printf("big message check fail\n");
+ break;
+ }
+ }
+
+ wolfSSL_shutdown(ssl);
+ wolfSSL_free(ssl);
+ wolfSSL_CTX_free(ctx);
+
+ close(sd);
+#endif /* WOLFSSL_SCTP && WOLFSSL_DTLS */
+
+ return 0;
+}
diff --git a/ap/lib/libwolfssl/install/share/doc/wolfssl/example/sctp-client.c b/ap/lib/libwolfssl/install/share/doc/wolfssl/example/sctp-client.c
new file mode 100644
index 0000000..9a55cd2
--- /dev/null
+++ b/ap/lib/libwolfssl/install/share/doc/wolfssl/example/sctp-client.c
@@ -0,0 +1,72 @@
+/* sctp-client.c
+ *
+ * Copyright (C) 2006-2021 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL.
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
+ */
+
+#ifndef WOLFSSL_USER_SETTINGS
+ #include <wolfssl/options.h>
+#endif
+#include <wolfssl/wolfcrypt/settings.h>
+
+#ifdef WOLFSSL_SCTP
+
+/* sctp */
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <arpa/inet.h>
+#include <netinet/in.h>
+
+/* std */
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#endif /* WOLFSSL_SCTP */
+
+int main()
+{
+#ifdef WOLFSSL_SCTP
+ int sd = socket(PF_INET, SOCK_STREAM, IPPROTO_SCTP);
+
+ if (sd < 0)
+ perror("sctp socket error");
+
+ struct sockaddr_in sa;
+ memset(&sa, 0, sizeof(sa));
+ sa.sin_family = AF_INET;
+ sa.sin_addr.s_addr = inet_addr("127.0.0.1");
+ sa.sin_port = htons(12345);
+
+ int ret = connect(sd, (struct sockaddr*)&sa, sizeof(sa));
+ if (ret < 0)
+ perror("sctp connect error");
+
+ const char* msg = "hello sctp";
+ char buffer[80];
+
+ send(sd, msg, strlen(msg), 0);
+ int got = (int)recv(sd, buffer, sizeof(buffer), 0);
+ if (got > 0) {
+ buffer[got] = 0;
+ printf("server said: %s\n", buffer);
+ }
+
+ close(sd);
+#endif /* WOLFSSL_SCTP */
+ return 0;
+}
diff --git a/ap/lib/libwolfssl/install/share/doc/wolfssl/example/sctp-server-dtls.c b/ap/lib/libwolfssl/install/share/doc/wolfssl/example/sctp-server-dtls.c
new file mode 100644
index 0000000..5d14ca8
--- /dev/null
+++ b/ap/lib/libwolfssl/install/share/doc/wolfssl/example/sctp-server-dtls.c
@@ -0,0 +1,128 @@
+/* sctp-server-dtls.c
+ *
+ * Copyright (C) 2006-2021 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL.
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
+ */
+
+/* wolfssl */
+#ifndef WOLFSSL_USER_SETTINGS
+ #include <wolfssl/options.h>
+#endif
+#include <wolfssl/wolfcrypt/settings.h>
+#include <wolfssl/ssl.h>
+
+#if defined(WOLFSSL_SCTP) && defined(WOLFSSL_DTLS)
+/* sctp */
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+
+/* std */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+
+#define key "./certs/server-key.pem"
+#define cert "./certs/server-cert.pem"
+
+static int err_sys(const char* msg)
+{
+ perror(msg);
+ exit(EXIT_FAILURE);
+}
+#endif /* WOLFSSL_SCTP && WOLFSSL_DTLS */
+
+int main()
+{
+#if defined(WOLFSSL_SCTP) && defined(WOLFSSL_DTLS)
+ int sd = socket(PF_INET, SOCK_STREAM, IPPROTO_SCTP);
+
+ if (sd < 0)
+ err_sys("sctp socket error");
+
+ struct sockaddr_in sa;
+ memset(&sa, 0, sizeof(sa));
+ sa.sin_family = AF_INET;
+ sa.sin_addr.s_addr = htonl(INADDR_ANY);
+ sa.sin_port = htons(12345);
+
+ int ret = bind(sd, (struct sockaddr*)&sa, sizeof(sa));
+ if (ret < 0)
+ err_sys("sctp bind error");
+
+ listen(sd, 3);
+
+ int client_sd = accept(sd, NULL, NULL);
+ if (client_sd < 0)
+ err_sys("sctp accept error");
+
+ const char* response = "well hello to you";
+ char buffer[80];
+
+ WOLFSSL_CTX* ctx = wolfSSL_CTX_new(wolfDTLSv1_2_server_method());
+ if (ctx == NULL)
+ err_sys("ctx new dtls server failed");
+
+ ret = wolfSSL_CTX_dtls_set_sctp(ctx);
+ if (ret != WOLFSSL_SUCCESS)
+ err_sys("set sctp mode failed");
+
+ ret = wolfSSL_CTX_use_PrivateKey_file(ctx, key, WOLFSSL_FILETYPE_PEM);
+ if (ret != WOLFSSL_SUCCESS)
+ err_sys("use private key error");
+
+ ret = wolfSSL_CTX_use_certificate_file(ctx, cert, WOLFSSL_FILETYPE_PEM);
+ if (ret != WOLFSSL_SUCCESS)
+ err_sys("use cert error");
+
+ WOLFSSL* ssl = wolfSSL_new(ctx);
+ if (ssl == NULL)
+ err_sys("ssl new dtls server failed");
+
+ wolfSSL_set_fd(ssl, client_sd);
+
+ ret = wolfSSL_accept(ssl);
+ if (ret != WOLFSSL_SUCCESS)
+ err_sys("ssl accept failed");
+
+ printf("TLS version is %s\n", wolfSSL_get_version(ssl));
+ printf("Cipher Suite is %s\n",
+ wolfSSL_CIPHER_get_name(wolfSSL_get_current_cipher(ssl)));
+
+ int got = wolfSSL_read(ssl, buffer, sizeof(buffer));
+ if (got > 0) {
+ buffer[got] = 0;
+ printf("client said: %s\n", buffer);
+ }
+ wolfSSL_write(ssl, response, (int)strlen(response));
+
+ unsigned char bigBuf[4096];
+
+ wolfSSL_read(ssl, bigBuf, sizeof(bigBuf));
+ wolfSSL_write(ssl, bigBuf, sizeof(bigBuf));
+
+ wolfSSL_shutdown(ssl);
+ wolfSSL_free(ssl);
+ wolfSSL_CTX_free(ctx);
+
+ close(sd);
+#endif /* WOLFSSL_SCTP && WOLFSSL_DTLS */
+ return 0;
+}
diff --git a/ap/lib/libwolfssl/install/share/doc/wolfssl/example/sctp-server.c b/ap/lib/libwolfssl/install/share/doc/wolfssl/example/sctp-server.c
new file mode 100644
index 0000000..75034ca
--- /dev/null
+++ b/ap/lib/libwolfssl/install/share/doc/wolfssl/example/sctp-server.c
@@ -0,0 +1,77 @@
+/* sctp-server.c
+ *
+ * Copyright (C) 2006-2021 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL.
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
+ */
+
+#ifndef WOLFSSL_USER_SETTINGS
+ #include <wolfssl/options.h>
+#endif
+#include <wolfssl/wolfcrypt/settings.h>
+
+#ifdef WOLFSSL_SCTP
+/* sctp */
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+
+/* std */
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#endif /* WOLFSSL_SCTP */
+
+int main()
+{
+#ifdef WOLFSSL_SCTP
+ int sd = socket(PF_INET, SOCK_STREAM, IPPROTO_SCTP);
+
+ if (sd < 0)
+ perror("sctp socket error");
+
+ struct sockaddr_in sa;
+ memset(&sa, 0, sizeof(sa));
+ sa.sin_family = AF_INET;
+ sa.sin_addr.s_addr = htonl(INADDR_ANY);
+ sa.sin_port = htons(12345);
+
+ int ret = bind(sd, (struct sockaddr*)&sa, sizeof(sa));
+ if (ret < 0)
+ perror("sctp bind error");
+
+ listen(sd, 3);
+
+ int client_sd = accept(sd, NULL, NULL);
+ if (client_sd < 0)
+ perror("sctp accept error");
+
+ const char* response = "hi there";
+ char buffer[80];
+
+ int got = (int)recv(client_sd, buffer, sizeof(buffer), 0);
+ if (got > 0) {
+ buffer[got] = 0;
+ printf("client said: %s\n", buffer);
+ }
+ send(client_sd, response, strlen(response), 0);
+
+
+ close(sd);
+#endif /* WOLFSSL_SCTP */
+ return 0;
+}
diff --git a/ap/lib/libwolfssl/install/share/doc/wolfssl/example/server.c b/ap/lib/libwolfssl/install/share/doc/wolfssl/example/server.c
new file mode 100644
index 0000000..c787c2c
--- /dev/null
+++ b/ap/lib/libwolfssl/install/share/doc/wolfssl/example/server.c
@@ -0,0 +1,3164 @@
+/* server.c
+ *
+ * Copyright (C) 2006-2021 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL.
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
+ */
+
+
+#ifdef HAVE_CONFIG_H
+ #include <config.h>
+#endif
+
+#ifndef WOLFSSL_USER_SETTINGS
+ #include <wolfssl/options.h>
+#endif
+#include <wolfssl/wolfcrypt/settings.h>
+
+#include <wolfssl/ssl.h> /* name change portability layer */
+
+#ifdef HAVE_ECC
+ #include <wolfssl/wolfcrypt/ecc.h> /* wc_ecc_fp_free */
+#endif
+
+#ifdef WOLFSSL_WOLFSENTRY_HOOKS
+#include <wolfsentry/wolfsentry.h>
+#if !defined(NO_FILESYSTEM) && !defined(WOLFSENTRY_NO_JSON)
+static const char *wolfsentry_config_path = NULL;
+#endif
+#endif /* WOLFSSL_WOLFSENTRY_HOOKS */
+
+#if defined(WOLFSSL_MDK_ARM) || defined(WOLFSSL_KEIL_TCP_NET)
+ #include <stdio.h>
+ #include <string.h>
+ #include "rl_fs.h"
+ #include "rl_net.h"
+#endif
+
+#ifdef NO_FILESYSTEM
+ #ifdef NO_RSA
+ #error currently the example only tries to load in a RSA buffer
+ #endif
+ #undef USE_CERT_BUFFERS_2048
+ #define USE_CERT_BUFFERS_2048
+ #include <wolfssl/certs_test.h>
+#endif
+
+#include <wolfssl/openssl/ssl.h>
+#include <wolfssl/test.h>
+#include <wolfssl/error-ssl.h>
+
+#include "examples/server/server.h"
+
+#ifndef NO_WOLFSSL_SERVER
+
+#ifdef WOLFSSL_ASYNC_CRYPT
+ static int devId = INVALID_DEVID;
+#endif
+
+#define DEFAULT_TIMEOUT_SEC 2
+
+/* Note on using port 0: if the server uses port 0 to bind an ephemeral port
+ * number and is using the ready file for scripted testing, the code in
+ * test.h will write the actual port number into the ready file for use
+ * by the client. */
+
+#ifndef WOLFSSL_ALT_TEST_STRINGS
+static const char kReplyMsg[] = "I hear you fa shizzle!";
+#else
+static const char kReplyMsg[] = "I hear you fa shizzle!\n";
+#endif
+
+static const char kHttpServerMsg[] =
+ "HTTP/1.1 200 OK\r\n"
+ "Content-Type: text/html\r\n"
+ "Connection: close\r\n"
+ "Content-Length: 141\r\n"
+ "\r\n"
+ "<html>\r\n"
+ "<head>\r\n"
+ "<title>Welcome to wolfSSL!</title>\r\n"
+ "</head>\r\n"
+ "<body>\r\n"
+ "<p>wolfSSL has successfully performed handshake!</p>\r\n"
+ "</body>\r\n"
+ "</html>\r\n";
+
+/* Read needs to be largest of the client.c message strings (29) */
+#define SRV_READ_SZ 32
+
+
+int runWithErrors = 0; /* Used with -x flag to run err_sys vs. print errors */
+int catastrophic = 0; /* Use with -x flag to still exit when an error is
+ * considered catastrophic EG the servers own cert failing
+ * to load would be catastrophic since there would be no
+ * cert to send to clients attempting to connect. The
+ * server should error out completely in that case
+ */
+static int lng_index = 0;
+
+#ifdef WOLFSSL_CALLBACKS
+ #if !defined(NO_OLD_TIMEVAL_NAME)
+ Timeval srvTo;
+ #else
+ WOLFSSL_TIMEVAL srvTo;
+ #endif
+ static int srvHandShakeCB(HandShakeInfo* info)
+ {
+ (void)info;
+ return 0;
+ }
+
+ static int srvTimeoutCB(TimeoutInfo* info)
+ {
+ (void)info;
+ return 0;
+ }
+
+#endif
+
+#ifndef NO_HANDSHAKE_DONE_CB
+ static int myHsDoneCb(WOLFSSL* ssl, void* user_ctx)
+ {
+ (void)user_ctx;
+ (void)ssl;
+
+ /* printf("Notified HandShake done\n"); */
+
+ /* return negative number to end TLS connection now */
+ return 0;
+ }
+#endif
+
+static void err_sys_ex(int out, const char* msg)
+{
+ if (out == 1) { /* if server is running w/ -x flag, print error w/o exit */
+ printf("wolfSSL error: %s\n", msg);
+ printf("Continuing server execution...\n\n");
+ } else {
+ err_sys(msg);
+ }
+}
+
+
+#if defined(WOLFSSL_DTLS) && defined(USE_WOLFSSL_IO)
+
+/* Translates return codes returned from
+ * send() and recv() if need be.
+ */
+static WC_INLINE int TranslateReturnCode(int old, int sd)
+{
+ (void)sd;
+
+#if defined(FREESCALE_MQX) || defined(FREESCALE_KSDK_MQX)
+ if (old == 0) {
+ errno = SOCKET_EWOULDBLOCK;
+ return -1; /* convert to BSD style wouldblock as error */
+ }
+
+ if (old < 0) {
+ errno = RTCS_geterror(sd);
+ if (errno == RTCSERR_TCP_CONN_CLOSING)
+ return 0; /* convert to BSD style closing */
+ if (errno == RTCSERR_TCP_CONN_RLSD)
+ errno = SOCKET_ECONNRESET;
+ if (errno == RTCSERR_TCP_TIMED_OUT)
+ errno = SOCKET_EAGAIN;
+ }
+#endif
+
+ return old;
+}
+
+static WC_INLINE int wolfSSL_LastError(void)
+{
+#ifdef USE_WINDOWS_API
+ return WSAGetLastError();
+#elif defined(EBSNET)
+ return xn_getlasterror();
+#else
+ return errno;
+#endif
+}
+
+/* wolfSSL Sock Addr */
+struct WOLFSSL_TEST_SOCKADDR {
+ unsigned int sz; /* sockaddr size */
+ SOCKADDR_IN_T sa; /* pointer to the sockaddr_in or sockaddr_in6 */
+};
+
+typedef struct WOLFSSL_TEST_DTLS_CTX {
+ struct WOLFSSL_TEST_SOCKADDR peer;
+ int rfd;
+ int wfd;
+ int failOnce;
+ word32 blockSeq;
+} WOLFSSL_TEST_DTLS_CTX;
+
+
+static WC_INLINE int PeekSeq(const char* buf, word32* seq)
+{
+ const char* c = buf + 3;
+
+ if ((c[0] | c[1] | c[2] | c[3]) == 0) {
+ *seq = (c[4] << 24) | (c[5] << 16) | (c[6] << 8) | c[7];
+ return 1;
+ }
+
+ return 0;
+}
+
+
+/* The send embedded callback
+ * return : nb bytes sent, or error
+ */
+static int TestEmbedSendTo(WOLFSSL* ssl, char *buf, int sz, void *ctx)
+{
+ WOLFSSL_TEST_DTLS_CTX* dtlsCtx = (WOLFSSL_TEST_DTLS_CTX*)ctx;
+ int sd = dtlsCtx->wfd;
+ int sent;
+ int err;
+
+ (void)ssl;
+
+ WOLFSSL_ENTER("TestEmbedSendTo()");
+
+ if (dtlsCtx->failOnce) {
+ word32 seq = 0;
+
+ if (PeekSeq(buf, &seq) && seq == dtlsCtx->blockSeq) {
+ dtlsCtx->failOnce = 0;
+ WOLFSSL_MSG("Forcing WANT_WRITE");
+ return WOLFSSL_CBIO_ERR_WANT_WRITE;
+ }
+ }
+
+ sent = (int)sendto(sd, buf, sz, 0, (const SOCKADDR*)&dtlsCtx->peer.sa,
+ dtlsCtx->peer.sz);
+
+ sent = TranslateReturnCode(sent, sd);
+
+ if (sent < 0) {
+ err = wolfSSL_LastError();
+ WOLFSSL_MSG("Embed Send To error");
+
+ if (err == SOCKET_EWOULDBLOCK || err == SOCKET_EAGAIN) {
+ WOLFSSL_MSG("\tWould Block");
+ return WOLFSSL_CBIO_ERR_WANT_WRITE;
+ }
+ else if (err == SOCKET_ECONNRESET) {
+ WOLFSSL_MSG("\tConnection reset");
+ return WOLFSSL_CBIO_ERR_CONN_RST;
+ }
+ else if (err == SOCKET_EINTR) {
+ WOLFSSL_MSG("\tSocket interrupted");
+ return WOLFSSL_CBIO_ERR_ISR;
+ }
+ else if (err == SOCKET_EPIPE) {
+ WOLFSSL_MSG("\tSocket EPIPE");
+ return WOLFSSL_CBIO_ERR_CONN_CLOSE;
+ }
+ else {
+ WOLFSSL_MSG("\tGeneral error");
+ return WOLFSSL_CBIO_ERR_GENERAL;
+ }
+ }
+
+ return sent;
+}
+#endif /* WOLFSSL_DTLS && USE_WOLFSSL_IO */
+
+static int NonBlockingSSL_Accept(SSL* ssl)
+{
+#ifndef WOLFSSL_CALLBACKS
+ int ret = SSL_accept(ssl);
+#else
+ int ret = wolfSSL_accept_ex(ssl, srvHandShakeCB, srvTimeoutCB, srvTo);
+#endif
+ int error = SSL_get_error(ssl, 0);
+ SOCKET_T sockfd = (SOCKET_T)SSL_get_fd(ssl);
+ int select_ret = 0;
+
+ while (ret != WOLFSSL_SUCCESS &&
+ (error == WOLFSSL_ERROR_WANT_READ || error == WOLFSSL_ERROR_WANT_WRITE
+ #ifdef WOLFSSL_ASYNC_CRYPT
+ || error == WC_PENDING_E
+ #endif
+ )) {
+ int currTimeout = 1;
+
+ if (error == WOLFSSL_ERROR_WANT_READ) {
+ /* printf("... server would read block\n"); */
+ }
+ else if (error == WOLFSSL_ERROR_WANT_WRITE) {
+ /* printf("... server would write block\n"); */
+ }
+
+ #ifdef WOLFSSL_ASYNC_CRYPT
+ if (error == WC_PENDING_E) {
+ ret = wolfSSL_AsyncPoll(ssl, WOLF_POLL_FLAG_CHECK_HW);
+ if (ret < 0) break;
+ }
+ else
+ #endif
+ {
+ if (error == WOLFSSL_ERROR_WANT_WRITE)
+ {
+ select_ret = tcp_select_tx(sockfd, currTimeout);
+ }
+ else {
+ #ifdef WOLFSSL_DTLS
+ currTimeout = wolfSSL_dtls_get_current_timeout(ssl);
+ #endif
+ select_ret = tcp_select(sockfd, currTimeout);
+ }
+ }
+
+ if ((select_ret == TEST_RECV_READY) || (select_ret == TEST_SEND_READY)
+ || (select_ret == TEST_ERROR_READY)
+ #ifdef WOLFSSL_ASYNC_CRYPT
+ || error == WC_PENDING_E
+ #endif
+ ) {
+ #ifndef WOLFSSL_CALLBACKS
+ ret = SSL_accept(ssl);
+ #else
+ ret = wolfSSL_accept_ex(ssl,
+ srvHandShakeCB, srvTimeoutCB, srvTo);
+ #endif
+ error = SSL_get_error(ssl, 0);
+ }
+ else if (select_ret == TEST_TIMEOUT && !wolfSSL_dtls(ssl)) {
+ error = WOLFSSL_ERROR_WANT_READ;
+ }
+ #ifdef WOLFSSL_DTLS
+ else if (select_ret == TEST_TIMEOUT && wolfSSL_dtls(ssl) &&
+ wolfSSL_dtls_got_timeout(ssl) >= 0) {
+ error = WOLFSSL_ERROR_WANT_READ;
+ }
+ #endif
+ else {
+ error = WOLFSSL_FATAL_ERROR;
+ }
+ }
+
+ return ret;
+}
+
+/* Echo number of bytes specified by -B arg */
+int ServerEchoData(SSL* ssl, int clientfd, int echoData, int block,
+ size_t throughput)
+{
+ int ret = 0, err;
+ double start = 0, rx_time = 0, tx_time = 0;
+ int select_ret, len, rx_pos;
+ size_t xfer_bytes = 0;
+ char* buffer;
+
+ buffer = (char*)malloc(block);
+ if (!buffer) {
+ err_sys_ex(runWithErrors, "Server buffer malloc failed");
+ }
+
+ while ((echoData && throughput == 0) ||
+ (!echoData && xfer_bytes < throughput))
+ {
+ select_ret = tcp_select(clientfd, 1); /* Timeout=1 second */
+ if (select_ret == TEST_RECV_READY) {
+
+ if (throughput)
+ len = min(block, (int)(throughput - xfer_bytes));
+ else
+ len = block;
+ rx_pos = 0;
+
+ if (throughput) {
+ start = current_time(1);
+ }
+
+ /* Read data */
+ while (rx_pos < len) {
+ ret = SSL_read(ssl, &buffer[rx_pos], len - rx_pos);
+ if (ret < 0) {
+ err = SSL_get_error(ssl, 0);
+ #ifdef WOLFSSL_ASYNC_CRYPT
+ if (err == WC_PENDING_E) {
+ ret = wolfSSL_AsyncPoll(ssl, WOLF_POLL_FLAG_CHECK_HW);
+ if (ret < 0) break;
+ }
+ else
+ #endif
+ if (err != WOLFSSL_ERROR_WANT_READ &&
+ err != WOLFSSL_ERROR_ZERO_RETURN &&
+ err != APP_DATA_READY) {
+ printf("SSL_read echo error %d\n", err);
+ err_sys_ex(runWithErrors, "SSL_read failed");
+ break;
+ }
+ if (err == WOLFSSL_ERROR_ZERO_RETURN) {
+ free(buffer);
+ return WOLFSSL_ERROR_ZERO_RETURN;
+ }
+ }
+ else {
+ rx_pos += ret;
+ if (!throughput)
+ break;
+ }
+ }
+ if (throughput) {
+ rx_time += current_time(0) - start;
+ start = current_time(1);
+ }
+
+ /* Write data */
+ do {
+ err = 0; /* reset error */
+ ret = SSL_write(ssl, buffer, min(len, rx_pos));
+ if (ret <= 0) {
+ err = SSL_get_error(ssl, 0);
+ #ifdef WOLFSSL_ASYNC_CRYPT
+ if (err == WC_PENDING_E) {
+ ret = wolfSSL_AsyncPoll(ssl, WOLF_POLL_FLAG_CHECK_HW);
+ if (ret < 0) break;
+ }
+ #endif
+ }
+ } while (err == WC_PENDING_E);
+ if (ret != (int)min(len, rx_pos)) {
+ printf("SSL_write echo error %d\n", err);
+ err_sys_ex(runWithErrors, "SSL_write failed");
+ }
+
+ if (throughput) {
+ tx_time += current_time(0) - start;
+ }
+
+ xfer_bytes += len;
+ }
+ }
+
+ free(buffer);
+
+ if (throughput) {
+ printf(
+ #if !defined(__MINGW32__)
+ "wolfSSL Server Benchmark %zu bytes\n"
+ #else
+ "wolfSSL Server Benchmark %d bytes\n"
+ #endif
+ "\tRX %8.3f ms (%8.3f MBps)\n"
+ "\tTX %8.3f ms (%8.3f MBps)\n",
+ #if !defined(__MINGW32__)
+ throughput,
+ #else
+ (int)throughput,
+ #endif
+ rx_time * 1000, throughput / rx_time / 1024 / 1024,
+ tx_time * 1000, throughput / tx_time / 1024 / 1024
+ );
+ }
+
+ return 0;
+}
+
+static void ServerRead(WOLFSSL* ssl, char* input, int inputLen)
+{
+ int ret, err;
+ char buffer[WOLFSSL_MAX_ERROR_SZ];
+
+ /* Read data */
+ do {
+ err = 0; /* reset error */
+ ret = SSL_read(ssl, input, inputLen);
+ if (ret < 0) {
+ err = SSL_get_error(ssl, ret);
+
+ #ifdef HAVE_SECURE_RENEGOTIATION
+ if (err == APP_DATA_READY) {
+ /* If we receive a message during renegotiation
+ * then just print it. We return the message sent
+ * after the renegotiation. */
+ ret = SSL_read(ssl, input, inputLen);
+ if (ret >= 0) {
+ /* null terminate message */
+ input[ret] = '\0';
+ printf("Client message received during "
+ "secure renegotiation: %s\n", input);
+ err = WOLFSSL_ERROR_WANT_READ;
+ }
+ else {
+ err = SSL_get_error(ssl, ret);
+ }
+ }
+ #endif
+ #ifdef WOLFSSL_ASYNC_CRYPT
+ if (err == WC_PENDING_E) {
+ ret = wolfSSL_AsyncPoll(ssl, WOLF_POLL_FLAG_CHECK_HW);
+ if (ret < 0) break;
+ }
+ else
+ #endif
+ #ifdef WOLFSSL_DTLS
+ if (wolfSSL_dtls(ssl) && err == DECRYPT_ERROR) {
+ printf("Dropped client's message due to a bad MAC\n");
+ }
+ else
+ #endif
+ if (err != WOLFSSL_ERROR_WANT_READ
+ #ifdef HAVE_SECURE_RENEGOTIATION
+ && err != APP_DATA_READY
+ #endif
+ ) {
+ printf("SSL_read input error %d, %s\n", err,
+ ERR_error_string(err, buffer));
+ err_sys_ex(runWithErrors, "SSL_read failed");
+ }
+ }
+ else if (SSL_get_error(ssl, 0) == 0 &&
+ tcp_select(SSL_get_fd(ssl), 0) == TEST_RECV_READY) {
+ err = WOLFSSL_ERROR_WANT_READ;
+ }
+ } while (err == WC_PENDING_E || err == WOLFSSL_ERROR_WANT_READ);
+ if (ret > 0) {
+ /* null terminate message */
+ input[ret] = '\0';
+ printf("Client message: %s\n", input);
+ }
+}
+
+static void ServerWrite(WOLFSSL* ssl, const char* output, int outputLen)
+{
+ int ret, err;
+ char buffer[WOLFSSL_MAX_ERROR_SZ];
+ int len;
+
+#ifdef OPENSSL_ALL
+ /* Fuzz testing expects reply split over two msgs when TLSv1.0 or below */
+ if (wolfSSL_GetVersion(ssl) <= WOLFSSL_TLSV1)
+ len = outputLen / 2;
+ else
+#endif
+ len = outputLen;
+
+ do {
+ err = 0; /* reset error */
+ ret = SSL_write(ssl, output, len);
+ if (ret <= 0) {
+ err = SSL_get_error(ssl, 0);
+
+ #ifdef WOLFSSL_ASYNC_CRYPT
+ if (err == WC_PENDING_E) {
+ ret = wolfSSL_AsyncPoll(ssl, WOLF_POLL_FLAG_CHECK_HW);
+ if (ret < 0) break;
+ }
+ #endif
+ }
+ else if (ret != outputLen) {
+ output += ret;
+ len = (outputLen -= ret);
+ err = WOLFSSL_ERROR_WANT_WRITE;
+ }
+ } while (err == WC_PENDING_E || err == WOLFSSL_ERROR_WANT_WRITE);
+ if (ret != outputLen) {
+ printf("SSL_write msg error %d, %s\n", err,
+ ERR_error_string(err, buffer));
+ err_sys_ex(runWithErrors, "SSL_write failed");
+ }
+}
+
+#if defined(WOLFSSL_TLS13) && defined(HAVE_SUPPORTED_CURVES)
+#define MAX_GROUP_NUMBER 4
+static void SetKeyShare(WOLFSSL* ssl, int onlyKeyShare, int useX25519,
+ int useX448)
+{
+ int ret;
+ int groups[MAX_GROUP_NUMBER] = {0};
+ int count = 0;
+
+ (void)useX25519;
+ (void)useX448;
+
+ WOLFSSL_START(WC_FUNC_CLIENT_KEY_EXCHANGE_SEND);
+ if (onlyKeyShare == 2) {
+ if (useX25519) {
+ #ifdef HAVE_CURVE25519
+ do {
+ ret = wolfSSL_UseKeyShare(ssl, WOLFSSL_ECC_X25519);
+ if (ret == WOLFSSL_SUCCESS)
+ groups[count++] = WOLFSSL_ECC_X25519;
+ #ifdef WOLFSSL_ASYNC_CRYPT
+ else if (ret == WC_PENDING_E)
+ wolfSSL_AsyncPoll(ssl, WOLF_POLL_FLAG_CHECK_HW);
+ #endif
+ else
+ err_sys("unable to use curve x25519");
+ } while (ret == WC_PENDING_E);
+ #endif
+ }
+ else if (useX448) {
+ #ifdef HAVE_CURVE448
+ do {
+ ret = wolfSSL_UseKeyShare(ssl, WOLFSSL_ECC_X448);
+ if (ret == WOLFSSL_SUCCESS)
+ groups[count++] = WOLFSSL_ECC_X448;
+ #ifdef WOLFSSL_ASYNC_CRYPT
+ else if (ret == WC_PENDING_E)
+ wolfSSL_AsyncPoll(ssl, WOLF_POLL_FLAG_CHECK_HW);
+ #endif
+ else
+ err_sys("unable to use curve x448");
+ } while (ret == WC_PENDING_E);
+ #endif
+ }
+ else {
+ #ifdef HAVE_ECC
+ #if !defined(NO_ECC256) || defined(HAVE_ALL_CURVES)
+ do {
+ ret = wolfSSL_UseKeyShare(ssl, WOLFSSL_ECC_SECP256R1);
+ if (ret == WOLFSSL_SUCCESS)
+ groups[count++] = WOLFSSL_ECC_SECP256R1;
+ #ifdef WOLFSSL_ASYNC_CRYPT
+ else if (ret == WC_PENDING_E)
+ wolfSSL_AsyncPoll(ssl, WOLF_POLL_FLAG_CHECK_HW);
+ #endif
+ else
+ err_sys("unable to use curve secp256r1");
+ } while (ret == WC_PENDING_E);
+ #endif
+ #endif
+ }
+ }
+ if (onlyKeyShare == 1) {
+ #ifdef HAVE_FFDHE_2048
+ do {
+ ret = wolfSSL_UseKeyShare(ssl, WOLFSSL_FFDHE_2048);
+ if (ret == WOLFSSL_SUCCESS)
+ groups[count++] = WOLFSSL_FFDHE_2048;
+ #ifdef WOLFSSL_ASYNC_CRYPT
+ else if (ret == WC_PENDING_E)
+ wolfSSL_AsyncPoll(ssl, WOLF_POLL_FLAG_CHECK_HW);
+ #endif
+ else
+ err_sys("unable to use DH 2048-bit parameters");
+ } while (ret == WC_PENDING_E);
+ #endif
+ }
+ if (count >= MAX_GROUP_NUMBER)
+ err_sys("example group array size error");
+ if (count > 0) {
+ if (wolfSSL_set_groups(ssl, groups, count) != WOLFSSL_SUCCESS)
+ err_sys("unable to set groups");
+ }
+ WOLFSSL_END(WC_FUNC_CLIENT_KEY_EXCHANGE_SEND);
+}
+#endif /* WOLFSSL_TLS13 && HAVE_SUPPORTED_CURVES */
+
+
+/* when adding new option, please follow the steps below: */
+/* 1. add new option message in English section */
+/* 2. increase the number of the second column */
+/* 3. increase the array dimension */
+/* 4. add the same message into Japanese section */
+/* (will be translated later) */
+/* 5. add printf() into suitable position of Usage() */
+static const char* server_usage_msg[][59] = {
+ /* English */
+ {
+ " NOTE: All files relative to wolfSSL home dir\n", /* 0 */
+ "-? <num> Help, print this usage\n"
+ " 0: English, 1: Japanese\n"
+ "--help Help, in English\n", /* 1 */
+ "-p <num> Port to listen on, not 0, default", /* 2 */
+#ifndef WOLFSSL_TLS13
+ "-v <num> SSL version [0-3], SSLv3(0) - TLS1.2(3)), default", /* 3 */
+#else
+ "-v <num> SSL version [0-4], SSLv3(0) - TLS1.3(4)), default", /* 3 */
+#endif
+ "-l <str> Cipher suite list (: delimited)\n", /* 4 */
+ "-c <file> Certificate file, default", /* 5 */
+ "-k <file> Key file, default", /* 6 */
+ "-A <file> Certificate Authority file, default", /* 7 */
+ "-R <file> Create Ready file for external monitor"
+ " default none\n", /* 8 */
+#ifndef NO_DH
+ "-D <file> Diffie-Hellman Params file, default", /* 9 */
+ "-Z <num> Minimum DH key bits, default", /* 10 */
+#endif
+#ifdef HAVE_ALPN
+ "-L <str> Application-Layer Protocol Negotiation"
+ " ({C,F}:<list>)\n", /* 11 */
+#endif
+ "-d Disable client cert check\n", /* 12 */
+ "-b Bind to any interface instead of localhost only\n",/* 13 */
+ "-s Use pre Shared keys\n", /* 14 */
+ "-u Use UDP DTLS,"
+ " add -v 2 for DTLSv1, -v 3 for DTLSv1.2 (default)\n", /* 15 */
+#ifdef WOLFSSL_SCTP
+ "-G Use SCTP DTLS,"
+ " add -v 2 for DTLSv1, -v 3 for DTLSv1.2 (default)\n", /* 16 */
+#endif
+ "-f Fewer packets/group messages\n", /* 17 */
+ "-r Allow one client Resumption\n", /* 18 */
+ "-N Use Non-blocking sockets\n", /* 19 */
+ "-S <str> Use Host Name Indication\n", /* 20 */
+ "-w Wait for bidirectional shutdown\n", /* 21 */
+#ifdef HAVE_OCSP
+ "-o Perform OCSP lookup on peer certificate\n", /* 22 */
+ "-O <url> Perform OCSP lookup using <url> as responder\n", /* 23 */
+#endif
+#ifdef HAVE_PK_CALLBACKS
+ "-P Public Key Callbacks\n", /* 24 */
+#endif
+#ifdef HAVE_ANON
+ "-a Anonymous server\n", /* 25 */
+#endif
+#ifndef NO_PSK
+ "-I Do not send PSK identity hint\n", /* 26 */
+#endif
+ "-x Print server errors but do not close connection\n",/* 27 */
+ "-i Loop indefinitely (allow repeated connections)\n", /* 28 */
+ "-e Echo data mode (return raw bytes received)\n", /* 29 */
+#ifdef HAVE_NTRU
+ "-n Use NTRU key (needed for NTRU suites)\n", /* 30 */
+#endif
+ "-B <num> Benchmark throughput"
+ " using <num> bytes and print stats\n", /* 31 */
+#ifdef HAVE_CRL
+ "-V Disable CRL\n", /* 32 */
+#endif
+#ifdef WOLFSSL_TRUST_PEER_CERT
+ "-E <file> Path to load trusted peer cert\n", /* 33 */
+#endif
+#ifdef HAVE_WNR
+ "-q <file> Whitewood config file, default", /* 34 */
+#endif
+ "-g Return basic HTML web page\n", /* 35 */
+ "-C <num> The number of connections to accept, default: 1\n",/* 36 */
+ "-H <arg> Internal tests"
+ " [defCipherList, exitWithRet, verifyFail, useSupCurve,\n", /* 37 */
+ " loadSSL, disallowETM]\n", /* 38 */
+#ifdef WOLFSSL_TLS13
+ "-U Update keys and IVs before sending\n", /* 39 */
+ "-K Key Exchange for PSK not using (EC)DHE\n", /* 40 */
+#ifndef NO_DH
+ "-y Pre-generate Key Share using FFDHE_2048 only\n", /* 41 */
+#endif
+#ifdef HAVE_ECC
+ "-Y Pre-generate Key Share using P-256 only \n", /* 42 */
+#endif
+#ifdef HAVE_CURVE25519
+ "-t Pre-generate Key share using Curve25519 only\n", /* 43 */
+#endif
+#endif /* WOLFSSL_TLS13 */
+#ifdef HAVE_SESSION_TICKET
+#if defined(WOLFSSL_NO_TLS12) && defined(NO_OLD_TLS)
+ "-T Do not generate session ticket\n", /* 44 */
+#else
+ "-T [aon] Do not generate session ticket\n", /* 44 */
+ " No option affects TLS 1.3 only, 'a' affects all"
+ " protocol versions,\n", /* 45 */
+ " 'o' affects TLS 1.2 and below only\n", /* 46 */
+ " 'n' affects TLS 1.3 only\n", /* 47 */
+#endif
+#endif
+#ifdef WOLFSSL_TLS13
+ "-F Send alert if no mutual authentication\n", /* 48 */
+#ifdef WOLFSSL_POST_HANDSHAKE_AUTH
+ "-Q Request certificate from client post-handshake\n", /* 49 */
+#endif
+#ifdef WOLFSSL_SEND_HRR_COOKIE
+ "-J Server sends Cookie Extension containing state\n", /* 50 */
+#endif
+#endif /* WOLFSSL_TLS13 */
+#ifdef WOLFSSL_EARLY_DATA
+ "-0 Early data read from client (0-RTT handshake)\n", /* 51 */
+#endif
+#ifdef WOLFSSL_MULTICAST
+ "-3 <grpid> Multicast, grpid < 256\n", /* 52 */
+#endif
+ "-1 <num> Display a result by specified language."
+ "\n 0: English, 1: Japanese\n", /* 53 */
+#ifdef HAVE_TRUSTED_CA
+ "-5 Use Trusted CA Key Indication\n", /* 54 */
+#endif
+ "-6 Simulate WANT_WRITE errors on every other IO send\n",
+ /* 55 */
+#ifdef HAVE_CURVE448
+ "-8 Pre-generate Key share using Curve448 only\n", /* 56 */
+#endif
+#if defined(OPENSSL_ALL) && defined(WOLFSSL_CERT_GEN) && \
+ (defined(WOLFSSL_CERT_REQ) || defined(WOLFSSL_CERT_EXT)) && \
+ !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR)
+ "-9 Use hash dir look up for certificate loading\n"
+ " loading from <wolfSSL home>/certs folder\n"
+ " files in the folder would have the form \"hash.N\" file name\n"
+ " e.g symbolic link to the file at certs folder\n"
+ " ln -s client-ca.pem `openssl x509 -in client-ca.pem -hash -noout`.0\n",
+ /* 57 */
+#endif
+#if defined(WOLFSSL_WOLFSENTRY_HOOKS) && !defined(NO_FILESYSTEM) && !defined(WOLFSENTRY_NO_JSON)
+ "--wolfsentry-config <file> Path for JSON wolfSentry config\n",
+ /* 58 */
+#endif
+
+#ifndef WOLFSSL_TLS13
+ "-7 Set minimum downgrade protocol version [0-3] "
+ " SSLv3(0) - TLS1.2(3)\n",
+#else
+ "-7 Set minimum downgrade protocol version [0-4] "
+ " SSLv3(0) - TLS1.3(4)\n", /* 59 */
+#endif
+ NULL,
+ },
+#ifndef NO_MULTIBYTE_PRINT
+ /* Japanese */
+ {
+ " 注意 : 全てのファイルは"
+ " wolfSSL ホーム・ディレクトリからの相対です。\n", /* 0 */
+ "-? <num> ヘルプ, 使い方を表示\n"
+ " 0: 英語、 1: 日本語\n"
+ "--ヘルプ 使い方を表示, 日本語で\n", /* 1 */
+ "-p <num> 接続先ポート, 0は無効, 既定値", /* 2 */
+#ifndef WOLFSSL_TLS13
+ "-v <num> SSL バージョン [0-3], SSLv3(0) - TLS1.2(3)),"
+ " 既定値", /* 3 */
+#else
+ "-v <num> SSL バージョン [0-4], SSLv3(0) - TLS1.3(4)),"
+ " 既定値", /* 3 */
+#endif
+ "-l <str> 暗号スイートリスト (区切り文字 :)\n", /* 4 */
+ "-c <file> 証明書ファイル, 既定値", /* 5 */
+ "-k <file> 鍵ファイル, 既定値", /* 6 */
+ "-A <file> 認証局ファイル, 既定値", /* 7 */
+ "-R <file> 外部モニタ用の準備完了ファイルを作成する。"
+ "既定値 なし\n", /* 8 */
+#ifndef NO_DH
+ "-D <file> ディフィー・ヘルマンのパラメータファイル,"
+ " 既定値", /* 9 */
+ "-Z <num> 最小 DH 鍵 ビット, 既定値", /* 10 */
+#endif
+#ifdef HAVE_ALPN
+ "-L <str> アプリケーション層プロトコルネゴシエーションを行う"
+ " ({C,F}:<list>)\n", /* 11 */
+#endif
+ "-d クライアント認証を無効とする\n", /* 12 */
+ "-b ローカルホスト以外のインターフェースへも"
+ "バインドする\n", /* 13 */
+ "-s 事前共有鍵を使用する\n", /* 14 */
+ "-u UDP DTLSを使用する。-v 2 を追加指定すると"
+ " DTLSv1, -v 3 を追加指定すると DTLSv1.2 (既定値)\n", /* 15 */
+#ifdef WOLFSSL_SCTP
+ "-G SCTP DTLSを使用する。-v 2 を追加指定すると"
+ " DTLSv1, -v 3 を追加指定すると DTLSv1.2 (既定値)\n", /* 16 */
+#endif
+ "-f より少ないパケット/グループメッセージを使用する\n",/* 17 */
+ "-r クライアントの再開を許可する\n", /* 18 */
+ "-N ノンブロッキング・ソケットを使用する\n", /* 19 */
+ "-S <str> ホスト名表示を使用する\n", /* 20 */
+ "-w 双方向シャットダウンを待つ\n", /* 21 */
+#ifdef HAVE_OCSP
+ "-o OCSPルックアップをピア証明書で実施する\n", /* 22 */
+ "-O <url> OCSPルックアップを、"
+ "<url>を使用し応答者として実施する\n", /* 23 */
+#endif
+#ifdef HAVE_PK_CALLBACKS
+ "-P 公開鍵コールバック\n", /* 24 */
+#endif
+#ifdef HAVE_ANON
+ "-a 匿名サーバー\n", /* 25 */
+#endif
+#ifndef NO_PSK
+ "-I PSKアイデンティティのヒントを送信しない\n", /* 26 */
+#endif
+ "-x サーバーエラーを出力するが接続を切断しない\n", /* 27 */
+ "-i 無期限にループする(繰り返し接続を許可)\n", /* 28 */
+ "-e エコー・データモード"
+ "(受け取ったバイトデータを返す)\n", /* 29 */
+#ifdef HAVE_NTRU
+ "-n NTRU鍵を使用する(NTRUスイートに必要)\n", /* 30 */
+#endif
+ "-B <num> <num> バイトを用いてのベンチマーク・スループット"
+ "測定と結果を出力する\n", /* 31 */
+#ifdef HAVE_CRL
+ "-V CRLを無効とする\n", /* 32 */
+#endif
+#ifdef WOLFSSL_TRUST_PEER_CERT
+ "-E <file> 信頼出来るピアの証明書ロードの為のパス\n\n", /* 33 */
+#endif
+#ifdef HAVE_WNR
+ "-q <file> Whitewood コンフィグファイル, 既定値", /* 34 */
+#endif
+ "-g 基本的な Web ページを返す\n", /* 35 */
+ "-C <num> アクセプト可能な接続数を指定する。既定値: 1\n", /* 36 */
+ "-H <arg> 内部テスト"
+ " [defCipherList, exitWithRet, verifyFail, useSupCurve,\n", /* 37 */
+ " loadSSL, disallowETM]\n", /* 38 */
+#ifdef WOLFSSL_TLS13
+ "-U データ送信前に、鍵とIVを更新する\n", /* 39 */
+ "-K 鍵交換にPSKを使用、(EC)DHEは使用しない\n", /* 40 */
+#ifndef NO_DH
+ "-y FFDHE_2048のみを使用して鍵共有を事前生成する\n", /* 41 */
+#endif
+#ifdef HAVE_ECC
+ "-Y P-256のみを使用したキー共有の事前生成\n", /* 42 */
+#endif
+#ifdef HAVE_CURVE25519
+ "-t Curve25519のみを使用して鍵共有を事前生成する\n", /* 43 */
+#endif
+#endif /* WOLFSSL_TLS13 */
+#if defined(WOLFSSL_NO_TLS12) && defined(NO_OLD_TLS)
+ "-T セッションチケットを生成しない\n", /* 44 */
+#else
+ "-T [aon] セッションチケットを生成しない\n", /* 44 */
+ " No option affects TLS 1.3 only, 'a' affects all"
+ " protocol versions,\n", /* 45 */
+ " 'o' affects TLS 1.2 and below only\n", /* 46 */
+ " 'n' affects TLS 1.3 only\n", /* 47 */
+#endif
+#ifdef WOLFSSL_TLS13
+ "-F Send alert if no mutual authentication\n", /* 48 */
+#ifdef WOLFSSL_POST_HANDSHAKE_AUTH
+ "-Q クライアントのポストハンドシェイクから"
+ "証明書を要求する\n", /* 49 */
+#endif
+#ifdef WOLFSSL_SEND_HRR_COOKIE
+ "-J サーバーの状態を含むTLS Cookie 拡張を送信する\n", /* 50 */
+#endif
+#endif /* WOLFSSL_TLS13 */
+#ifdef WOLFSSL_EARLY_DATA
+ "-0 クライアントからの Early Data 読み取り"
+ "(0-RTTハンドシェイク)\n", /* 51 */
+#endif
+#ifdef WOLFSSL_MULTICAST
+ "-3 <grpid> マルチキャスト, grpid < 256\n", /* 52 */
+#endif
+ "-1 <num> 指定された言語で結果を表示します。"
+ "\n 0: 英語、 1: 日本語\n", /* 53 */
+#ifdef HAVE_TRUSTED_CA
+ "-5 信頼できる認証局の鍵表示を使用する\n", /* 54 */
+#endif
+ "-6 Simulate WANT_WRITE errors on every other IO send\n",
+ /* 55 */
+#ifdef HAVE_CURVE448
+ "-8 Pre-generate Key share using Curve448 only\n", /* 56 */
+#endif
+#if defined(OPENSSL_ALL) && defined(WOLFSSL_CERT_GEN) && \
+ (defined(WOLFSSL_CERT_REQ) || defined(WOLFSSL_CERT_EXT)) && \
+ !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR)
+ "-9 証明書の読み込みに hash dir 機能を使用する\n"
+ " <wolfSSL home>/certs フォルダーからロードします\n"
+ " フォルダー中のファイルは、\"hash.N\"[N:0-9]名である必要があります\n"
+ " 以下の例ではca-cert.pemにシンボリックリンクを設定します\n"
+ " ln -s client-ca.pem `openssl x509 -in client-ca.pem -hash -noout`.0\n",
+ /* 57 */
+#endif
+#if defined(WOLFSSL_WOLFSENTRY_HOOKS) && !defined(NO_FILESYSTEM) && !defined(WOLFSENTRY_NO_JSON)
+ "--wolfsentry-config <file> wolfSentry コンフィグファイル\n",
+ /* 58 */
+#endif
+#ifndef WOLFSSL_TLS13
+ "-7 最小ダウングレード可能なプロトコルバージョンを設定します [0-3] "
+ " SSLv3(0) - TLS1.2(3)\n",
+#else
+ "-7 最小ダウングレード可能なプロトコルバージョンを設定します [0-4] "
+ " SSLv3(0) - TLS1.3(4)\n", /* 59 */
+#endif
+ NULL,
+ },
+#endif
+};
+
+static void Usage(void)
+{
+ int msgId = 0;
+ const char** msg = server_usage_msg[lng_index];
+
+ printf("%s%s%s", "server ", LIBWOLFSSL_VERSION_STRING,
+ msg[msgId]);
+ printf("%s", msg[++msgId]); /* ? */
+ printf("%s %d\n", msg[++msgId], wolfSSLPort); /* -p */
+#ifndef WOLFSSL_TLS13
+ printf("%s %d\n", msg[++msgId], SERVER_DEFAULT_VERSION); /* -v */
+#else
+ printf("%s %d\n", msg[++msgId], SERVER_DEFAULT_VERSION); /* -v */
+#endif
+ printf("%s", msg[++msgId]); /* -l */
+ printf("%s %s\n", msg[++msgId], svrCertFile); /* -c */
+ printf("%s %s\n", msg[++msgId], svrKeyFile); /* -k */
+ printf("%s %s\n", msg[++msgId], cliCertFile); /* -A */
+ printf("%s", msg[++msgId]); /* -R */
+#ifndef NO_DH
+ printf("%s %s\n", msg[++msgId], dhParamFile); /* -D */
+ printf("%s %d\n", msg[++msgId], DEFAULT_MIN_DHKEY_BITS);/* -Z */
+#endif
+#ifdef HAVE_ALPN
+ printf("%s", msg[++msgId]); /* -L */
+#endif
+ printf("%s", msg[++msgId]); /* -d */
+ printf("%s", msg[++msgId]); /* -b */
+ printf("%s", msg[++msgId]); /* -s */
+ printf("%s", msg[++msgId]); /* -u */
+#ifdef WOLFSSL_SCTP
+ printf("%s", msg[++msgId]); /* -G */
+#endif
+ printf("%s", msg[++msgId]); /* -f */
+ printf("%s", msg[++msgId]); /* -r */
+ printf("%s", msg[++msgId]); /* -N */
+ printf("%s", msg[++msgId]); /* -S */
+ printf("%s", msg[++msgId]); /* -w */
+#ifdef HAVE_SECURE_RENEGOTIATION
+ printf("-M Allow Secure Renegotiation\n");
+ printf("-m Force Server Initiated Secure Renegotiation\n");
+#endif /* HAVE_SECURE_RENEGOTIATION */
+#ifdef HAVE_OCSP
+ printf("%s", msg[++msgId]); /* -o */
+ printf("%s", msg[++msgId]); /* -O */
+#endif
+#ifdef HAVE_PK_CALLBACKS
+ printf("%s", msg[++msgId]); /* -P */
+#endif
+#ifdef HAVE_ANON
+ printf("%s", msg[++msgId]); /* -a */
+#endif
+#ifndef NO_PSK
+ printf("%s", msg[++msgId]); /* -I */
+#endif
+ printf("%s", msg[++msgId]); /* -x */
+ printf("%s", msg[++msgId]); /* -i */
+ printf("%s", msg[++msgId]); /* -e */
+#ifdef HAVE_NTRU
+ printf("%s", msg[++msgId]); /* -n */
+#endif
+ printf("%s", msg[++msgId]); /* -B */
+#ifdef HAVE_CRL
+ printf("%s", msg[++msgId]); /* -V */
+#endif
+#ifdef WOLFSSL_TRUST_PEER_CERT
+ printf("%s", msg[++msgId]); /* -E */
+#endif
+#ifdef HAVE_WNR
+ printf("%s %s\n", msg[++msgId], wnrConfig); /* -q */
+#endif
+ printf("%s", msg[++msgId]); /* -g */
+ printf("%s", msg[++msgId]); /* -C */
+ printf("%s", msg[++msgId]); /* -H */
+ printf("%s", msg[++msgId]); /* more -H options */
+#ifdef WOLFSSL_TLS13
+ printf("%s", msg[++msgId]); /* -U */
+ printf("%s", msg[++msgId]); /* -K */
+#ifndef NO_DH
+ printf("%s", msg[++msgId]); /* -y */
+#endif
+#ifdef HAVE_ECC
+ printf("%s", msg[++msgId]); /* -Y */
+#endif
+#ifdef HAVE_CURVE25519
+ printf("%s", msg[++msgId]); /* -t */
+#endif
+#endif /* WOLFSSL_TLS13 */
+#ifdef HAVE_SESSION_TICKET
+ printf("%s", msg[++msgId]); /* -T */
+ #if !defined(WOLFSSL_NO_TLS12) || !defined(NO_OLD_TLS)
+ printf("%s", msg[++msgId]); /* -T */
+ printf("%s", msg[++msgId]); /* -T */
+ printf("%s", msg[++msgId]); /* -T */
+ #endif
+#endif
+#ifdef WOLFSSL_TLS13
+ printf("%s", msg[++msgId]); /* -F */
+#ifdef WOLFSSL_POST_HANDSHAKE_AUTH
+ printf("%s", msg[++msgId]); /* -Q */
+#endif
+#ifdef WOLFSSL_SEND_HRR_COOKIE
+ printf("%s", msg[++msgId]); /* -J */
+#endif
+#endif /* WOLFSSL_TLS13 */
+#ifdef WOLFSSL_EARLY_DATA
+ printf("%s", msg[++msgId]); /* -0 */
+#endif
+#if !defined(NO_DH) && !defined(HAVE_FIPS) && \
+ !defined(HAVE_SELFTEST) && !defined(WOLFSSL_OLD_PRIME_CHECK)
+ printf("-2 Disable DH Prime check\n");
+#endif
+#ifdef WOLFSSL_DTLS
+ printf("-4 <seq> DTLS fake would-block for message seq\n");
+#endif
+#ifdef WOLFSSL_MULTICAST
+ printf("%s", msg[++msgId]); /* -3 */
+#endif
+ printf("%s", msg[++msgId]); /* -1 */
+#ifdef HAVE_TRUSTED_CA
+ printf("%s", msg[++msgId]); /* -5 */
+#endif /* HAVE_TRUSTED_CA */
+ printf("%s", msg[++msgId]); /* -6 */
+#ifdef HAVE_CURVE448
+ printf("%s", msg[++msgId]); /* -8 */
+#endif
+#if defined(OPENSSL_ALL) && defined(WOLFSSL_CERT_GEN) && \
+ (defined(WOLFSSL_CERT_REQ) || defined(WOLFSSL_CERT_EXT)) && \
+ !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR)
+ printf("%s", msg[++msgId]); /* -9 */
+#endif
+#if defined(WOLFSSL_WOLFSENTRY_HOOKS) && !defined(NO_FILESYSTEM) && \
+ !defined(WOLFSENTRY_NO_JSON)
+ printf("%s", msg[++msgId]); /* --wolfsentry-config */
+#endif
+ printf("%s", msg[++msgId]); /* -7 */
+}
+
+THREAD_RETURN WOLFSSL_THREAD server_test(void* args)
+{
+ SOCKET_T sockfd = WOLFSSL_SOCKET_INVALID;
+ SOCKET_T clientfd = WOLFSSL_SOCKET_INVALID;
+ SOCKADDR_IN_T client_addr;
+ socklen_t client_len;
+
+ wolfSSL_method_func method = NULL;
+ SSL_CTX* ctx = 0;
+ SSL* ssl = 0;
+#ifdef WOLFSSL_WOLFSENTRY_HOOKS
+ wolfsentry_errcode_t wolfsentry_ret;
+#endif
+ int minVersion = SERVER_INVALID_VERSION;
+ int useWebServerMsg = 0;
+ char input[SRV_READ_SZ];
+#ifndef WOLFSSL_VXWORKS
+ int ch;
+ static const struct mygetopt_long_config long_options[] = {
+#if defined(WOLFSSL_WOLFSENTRY_HOOKS) && !defined(NO_FILESYSTEM) && \
+ !defined(WOLFSENTRY_NO_JSON)
+ { "wolfsentry-config", 1, 256 },
+#endif
+ { "help", 0, 257 },
+ { "ヘルプ", 0, 258 },
+ { 0, 0, 0 }
+ };
+#endif
+ int version = SERVER_DEFAULT_VERSION;
+#ifndef WOLFSSL_NO_CLIENT_AUTH
+ int doCliCertCheck = 1;
+#else
+ int doCliCertCheck = 0;
+#endif
+#ifdef HAVE_CRL
+ int disableCRL = 0;
+#endif
+ int useAnyAddr = 0;
+ word16 port = wolfSSLPort;
+ int usePsk = 0;
+ int usePskPlus = 0;
+ int useAnon = 0;
+ int doDTLS = 0;
+ int dtlsUDP = 0;
+#if (defined(WOLFSSL_SCTP) || defined(WOLFSSL_DTLS_MTU)) && \
+ defined(WOLFSSL_DTLS)
+ int dtlsMTU = 0;
+#endif
+ int dtlsSCTP = 0;
+ int doMcast = 0;
+#if defined(WOLFSSL_DTLS) && defined(USE_WOLFSSL_IO)
+ int doBlockSeq = 0;
+ WOLFSSL_TEST_DTLS_CTX dtlsCtx;
+#endif
+ int needDH = 0;
+ int useNtruKey = 0;
+ int nonBlocking = 0;
+ int simulateWantWrite = 0;
+ int fewerPackets = 0;
+#ifdef HAVE_PK_CALLBACKS
+ int pkCallbacks = 0;
+ PkCbInfo pkCbInfo;
+#endif
+ int wc_shutdown = 0;
+ int resume = 0;
+ int resumeCount = 0;
+ int loops = 1;
+ int cnt = 0;
+ int echoData = 0;
+ int block = TEST_BUFFER_SIZE;
+ size_t throughput = 0;
+ int minDhKeyBits = DEFAULT_MIN_DHKEY_BITS;
+ short minRsaKeyBits = DEFAULT_MIN_RSAKEY_BITS;
+ short minEccKeyBits = DEFAULT_MIN_ECCKEY_BITS;
+ int doListen = 1;
+ int crlFlags = 0;
+ int ret;
+ int err = 0;
+ char* serverReadyFile = NULL;
+ char* alpnList = NULL;
+ unsigned char alpn_opt = 0;
+ char* cipherList = NULL;
+ int useDefCipherList = 0;
+ const char* verifyCert;
+ const char* ourCert;
+ const char* ourKey;
+ const char* ourDhParam = dhParamFile;
+ tcp_ready* readySignal = NULL;
+ int argc = ((func_args*)args)->argc;
+ char** argv = ((func_args*)args)->argv;
+
+#ifdef WOLFSSL_TRUST_PEER_CERT
+ const char* trustCert = NULL;
+#endif
+
+#ifndef NO_PSK
+ int sendPskIdentityHint = 1;
+#endif
+
+#ifdef HAVE_SNI
+ char* sniHostName = NULL;
+#endif
+
+#ifdef HAVE_TRUSTED_CA
+ int trustedCaKeyId = 0;
+#endif /* HAVE_TRUSTED_CA */
+
+#ifdef HAVE_OCSP
+ int useOcsp = 0;
+ char* ocspUrl = NULL;
+#endif
+
+#ifdef HAVE_WNR
+ const char* wnrConfigFile = wnrConfig;
+#endif
+ char buffer[WOLFSSL_MAX_ERROR_SZ];
+#ifdef WOLFSSL_TLS13
+ int noPskDheKe = 0;
+#endif
+ int updateKeysIVs = 0;
+#ifndef NO_CERTS
+ int mutualAuth = 0;
+#endif
+ int postHandAuth = 0;
+#ifdef WOLFSSL_EARLY_DATA
+ int earlyData = 0;
+#endif
+#ifdef HAVE_SECURE_RENEGOTIATION
+ int scr = 0;
+ int forceScr = 0;
+#endif /* HAVE_SECURE_RENEGOTIATION */
+#ifdef WOLFSSL_SEND_HRR_COOKIE
+ int hrrCookie = 0;
+#endif
+ byte mcastID = 0;
+#if !defined(NO_DH) && !defined(HAVE_FIPS) && \
+ !defined(HAVE_SELFTEST) && !defined(WOLFSSL_OLD_PRIME_CHECK)
+ int doDhKeyCheck = 1;
+#endif
+
+#ifdef WOLFSSL_STATIC_MEMORY
+ #if (defined(HAVE_ECC) && !defined(ALT_ECC_SIZE)) \
+ || defined(SESSION_CERTS)
+ /* big enough to handle most cases including session certs */
+ byte memory[239936];
+ #else
+ byte memory[80000];
+ #endif
+ byte memoryIO[34500]; /* max for IO buffer (TLS packet can be 16k) */
+ WOLFSSL_MEM_CONN_STATS ssl_stats;
+ #ifdef DEBUG_WOLFSSL
+ WOLFSSL_MEM_STATS mem_stats;
+ #endif
+#endif
+#if defined(WOLFSSL_TLS13) && defined(HAVE_SUPPORTED_CURVES)
+ int onlyKeyShare = 0;
+#endif
+#if defined(HAVE_SESSION_TICKET)
+#ifdef WOLFSSL_TLS13
+ int noTicketTls13 = 0;
+#endif
+#if !defined(WOLFSSL_NO_TLS12) || !defined(NO_OLD_TLS)
+ int noTicketTls12 = 0;
+#endif
+#endif
+ int useX25519 = 0;
+ int useX448 = 0;
+ int exitWithRet = 0;
+ int loadCertKeyIntoSSLObj = 0;
+
+#ifdef HAVE_ENCRYPT_THEN_MAC
+ int disallowETM = 0;
+#endif
+#if defined(OPENSSL_ALL) && defined(WOLFSSL_CERT_GEN) && \
+ (defined(WOLFSSL_CERT_REQ) || defined(WOLFSSL_CERT_EXT)) && \
+ !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR)
+ int useCertFolder = 0;
+#endif
+
+ ((func_args*)args)->return_code = -1; /* error state */
+
+#ifndef NO_RSA
+ verifyCert = cliCertFile;
+ ourCert = svrCertFile;
+ ourKey = svrKeyFile;
+#else
+ #ifdef HAVE_ECC
+ verifyCert = cliEccCertFile;
+ ourCert = eccCertFile;
+ ourKey = eccKeyFile;
+ #elif defined(HAVE_ED25519)
+ verifyCert = cliEdCertFile;
+ ourCert = edCertFile;
+ ourKey = edKeyFile;
+ #elif defined(HAVE_ED448)
+ verifyCert = cliEd448CertFile;
+ ourCert = ed448CertFile;
+ ourKey = ed448KeyFile;
+ #else
+ verifyCert = NULL;
+ ourCert = NULL;
+ ourKey = NULL;
+ #endif
+#endif
+
+ (void)needDH;
+ (void)ourKey;
+ (void)ourCert;
+ (void)ourDhParam;
+ (void)verifyCert;
+ (void)useNtruKey;
+ (void)doCliCertCheck;
+ (void)minDhKeyBits;
+ (void)minRsaKeyBits;
+ (void)minEccKeyBits;
+ (void)alpnList;
+ (void)alpn_opt;
+ (void)crlFlags;
+ (void)readySignal;
+ (void)updateKeysIVs;
+#ifndef NO_CERTS
+ (void)mutualAuth;
+#endif
+ (void)postHandAuth;
+ (void)mcastID;
+ (void)loadCertKeyIntoSSLObj;
+ (void)nonBlocking;
+
+#ifdef WOLFSSL_TIRTOS
+ fdOpenSession(Task_self());
+#endif
+
+#ifdef WOLFSSL_VXWORKS
+ useAnyAddr = 1;
+#else
+
+ /* Reinitialize the global myVerifyAction. */
+ myVerifyAction = VERIFY_OVERRIDE_ERROR;
+
+ /* Not Used: h, z, W, X, 7 */
+ while ((ch = mygetopt_long(argc, argv, "?:"
+ "abc:defgijk:l:mnop:q:rstu;v:wxy"
+ "A:B:C:D:E:FGH:IJKL:MNO:PQR:S:T;UVYZ:"
+ "01:23:4:5689"
+ "@#", long_options, 0)) != -1) {
+ switch (ch) {
+ case '?' :
+ if(myoptarg!=NULL) {
+ lng_index = atoi(myoptarg);
+ if(lng_index<0||lng_index>1){
+ lng_index = 0;
+ }
+ }
+ Usage();
+ XEXIT_T(EXIT_SUCCESS);
+
+ case 257 :
+ lng_index = 0;
+ Usage();
+ XEXIT_T(EXIT_SUCCESS);
+
+ case 258 :
+ lng_index = 1;
+ Usage();
+ XEXIT_T(EXIT_SUCCESS);
+
+ case 'x' :
+ runWithErrors = 1;
+ break;
+
+ case 'd' :
+ doCliCertCheck = 0;
+ break;
+
+ case 'V' :
+ #ifdef HAVE_CRL
+ disableCRL = 1;
+ #endif
+ break;
+
+ case 'b' :
+ useAnyAddr = 1;
+ break;
+
+ case 's' :
+ usePsk = 1;
+ break;
+
+ case 'j' :
+ usePskPlus = 1;
+ break;
+
+ case 'n' :
+ useNtruKey = 1;
+ break;
+
+ case 'u' :
+ doDTLS = 1;
+ dtlsUDP = 1;
+ #if (defined(WOLFSSL_SCTP) || defined(WOLFSSL_DTLS_MTU)) && \
+ defined(WOLFSSL_DTLS)
+ dtlsMTU = atoi(myoptarg);
+ #endif
+ break;
+
+ case 'G' :
+ #ifdef WOLFSSL_SCTP
+ doDTLS = 1;
+ dtlsSCTP = 1;
+ #endif
+ break;
+
+ case 'f' :
+ fewerPackets = 1;
+ break;
+
+ case 'R' :
+ serverReadyFile = myoptarg;
+ break;
+
+ case 'r' :
+ #ifndef NO_SESSION_CACHE
+ resume = 1;
+ #endif
+ break;
+
+ case 'P' :
+ #ifdef HAVE_PK_CALLBACKS
+ pkCallbacks = 1;
+ #endif
+ break;
+
+ case 'p' :
+ port = (word16)atoi(myoptarg);
+ break;
+
+ case 'w' :
+ wc_shutdown = 1;
+ break;
+
+ case 'v' :
+ if (myoptarg[0] == 'd') {
+ version = SERVER_DOWNGRADE_VERSION;
+ break;
+ }
+ #if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EITHER_SIDE)
+ else if (myoptarg[0] == 'e') {
+ version = EITHER_DOWNGRADE_VERSION;
+ #ifndef NO_CERTS
+ loadCertKeyIntoSSLObj = 1;
+ #endif
+ break;
+ }
+ #endif
+ version = atoi(myoptarg);
+ if (version < 0 || version > 4) {
+ Usage();
+ XEXIT_T(MY_EX_USAGE);
+ }
+ break;
+
+ case 'l' :
+ cipherList = myoptarg;
+ break;
+
+ case 'H' :
+ if (XSTRNCMP(myoptarg, "defCipherList", 13) == 0) {
+ printf("Using default cipher list for testing\n");
+ useDefCipherList = 1;
+ }
+ else if (XSTRNCMP(myoptarg, "exitWithRet", 11) == 0) {
+ printf("Skip exit() for testing\n");
+ exitWithRet = 1;
+ }
+ else if (XSTRNCMP(myoptarg, "verifyFail", 10) == 0) {
+ printf("Verify should fail\n");
+ myVerifyAction = VERIFY_FORCE_FAIL;
+ }
+ else if (XSTRNCMP(myoptarg, "verifyInfo", 10) == 0) {
+ printf("Verify should use preverify (just show info)\n");
+ myVerifyAction = VERIFY_USE_PREVERFIY;
+ }
+ else if (XSTRNCMP(myoptarg, "loadSSL", 7) == 0) {
+ printf("Also load cert/key into wolfSSL object\n");
+ #ifndef NO_CERTS
+ loadCertKeyIntoSSLObj = 2;
+ #endif
+ }
+ else if (XSTRNCMP(myoptarg, "loadSSLOnly", 11) == 0) {
+ printf("Only load cert/key into wolfSSL object\n");
+ #ifndef NO_CERTS
+ loadCertKeyIntoSSLObj = 1;
+ #endif
+ }
+ else if (XSTRNCMP(myoptarg, "disallowETM", 11) == 0) {
+ printf("Disallow Encrypt-Then-MAC\n");
+ #ifdef HAVE_ENCRYPT_THEN_MAC
+ disallowETM = 1;
+ #endif
+ }
+ else if (XSTRNCMP(myoptarg, "overrideDateErr", 15) == 0) {
+ #if !defined(NO_FILESYSTEM) && !defined(NO_CERTS)
+ myVerifyAction = VERIFY_OVERRIDE_DATE_ERR;
+ #endif
+ }
+ else {
+ Usage();
+ XEXIT_T(MY_EX_USAGE);
+ }
+ break;
+
+ case 'A' :
+ verifyCert = myoptarg;
+ break;
+
+ case 'c' :
+ ourCert = myoptarg;
+ break;
+
+ case 'k' :
+ ourKey = myoptarg;
+ break;
+
+ case 'D' :
+ #ifndef NO_DH
+ ourDhParam = myoptarg;
+ #endif
+ break;
+
+ case 'Z' :
+ #ifndef NO_DH
+ minDhKeyBits = atoi(myoptarg);
+ if (minDhKeyBits <= 0 || minDhKeyBits > 16000) {
+ Usage();
+ XEXIT_T(MY_EX_USAGE);
+ }
+ #endif
+ break;
+
+ case 'N':
+ nonBlocking = 1;
+ break;
+
+ case 'S' :
+ #ifdef HAVE_SNI
+ sniHostName = myoptarg;
+ #endif
+ break;
+
+ case 'o' :
+ #ifdef HAVE_OCSP
+ useOcsp = 1;
+ #endif
+ break;
+
+ case 'O' :
+ #ifdef HAVE_OCSP
+ useOcsp = 1;
+ ocspUrl = myoptarg;
+ #endif
+ break;
+
+ case 'a' :
+ #ifdef HAVE_ANON
+ useAnon = 1;
+ #endif
+ break;
+ case 'I':
+ #ifndef NO_PSK
+ sendPskIdentityHint = 0;
+ #endif
+ break;
+
+ case 'L' :
+ #ifdef HAVE_ALPN
+ alpnList = myoptarg;
+
+ if (alpnList[0] == 'C' && alpnList[1] == ':')
+ alpn_opt = WOLFSSL_ALPN_CONTINUE_ON_MISMATCH;
+ else if (alpnList[0] == 'F' && alpnList[1] == ':')
+ alpn_opt = WOLFSSL_ALPN_FAILED_ON_MISMATCH;
+ else {
+ Usage();
+ XEXIT_T(MY_EX_USAGE);
+ }
+
+ alpnList += 2;
+
+ #endif
+ break;
+
+ case 'i' :
+ loops = -1;
+ break;
+
+ case 'C' :
+ loops = atoi(myoptarg);
+ if (loops <= 0) {
+ Usage();
+ XEXIT_T(MY_EX_USAGE);
+ }
+ break;
+
+ case 'e' :
+ echoData = 1;
+ break;
+
+ case 'B':
+ throughput = atol(myoptarg);
+ for (; *myoptarg != '\0'; myoptarg++) {
+ if (*myoptarg == ',') {
+ block = atoi(myoptarg + 1);
+ break;
+ }
+ }
+ if (throughput == 0 || block <= 0) {
+ Usage();
+ XEXIT_T(MY_EX_USAGE);
+ }
+ break;
+
+ #ifdef WOLFSSL_TRUST_PEER_CERT
+ case 'E' :
+ trustCert = myoptarg;
+ break;
+ #endif
+
+ case 'q' :
+ #ifdef HAVE_WNR
+ wnrConfigFile = myoptarg;
+ #endif
+ break;
+
+ case 'g' :
+ useWebServerMsg = 1;
+ break;
+
+ case 'y' :
+ #if defined(WOLFSSL_TLS13) && defined(HAVE_SUPPORTED_CURVES) \
+ && !defined(NO_DH)
+ onlyKeyShare = 1;
+ #endif
+ break;
+
+ case 'Y' :
+ #if defined(WOLFSSL_TLS13) && defined(HAVE_SUPPORTED_CURVES) \
+ && defined(HAVE_ECC)
+ onlyKeyShare = 2;
+ #endif
+ break;
+
+ case 't' :
+ #ifdef HAVE_CURVE25519
+ useX25519 = 1;
+ #if defined(WOLFSSL_TLS13) && defined(HAVE_SUPPORTED_CURVES)
+ onlyKeyShare = 2;
+ #endif
+ #endif
+ break;
+
+ case 'K' :
+ #ifdef WOLFSSL_TLS13
+ noPskDheKe = 1;
+ #endif
+ break;
+
+ case 'T' :
+ #if defined(HAVE_SESSION_TICKET)
+ if (XSTRLEN(myoptarg) == 0) {
+ #if defined(WOLFSSL_TLS13)
+ noTicketTls13 = 1;
+ #endif
+ }
+ #if !defined(WOLFSSL_NO_TLS12) || !defined(NO_OLD_TLS)
+ else if (XSTRNCMP(myoptarg, "a", 2) == 0) {
+ noTicketTls12 = 1;
+ #if defined(WOLFSSL_TLS13)
+ noTicketTls13 = 1;
+ #endif
+ }
+ else if (XSTRNCMP(myoptarg, "o", 2) == 0) {
+ noTicketTls12 = 1;
+ }
+ else if (XSTRNCMP(myoptarg, "n", 2) == 0) {
+ #if defined(WOLFSSL_TLS13)
+ noTicketTls13 = 1;
+ #endif
+ }
+ #endif
+ else {
+ Usage();
+ XEXIT_T(MY_EX_USAGE);
+ }
+ #endif
+ break;
+
+ case 'U' :
+ #ifdef WOLFSSL_TLS13
+ updateKeysIVs = 1;
+ #endif
+ break;
+
+ #ifndef NO_CERTS
+ case 'F' :
+ mutualAuth = 1;
+ break;
+ #endif
+
+ case 'Q' :
+ #if defined(WOLFSSL_TLS13) && defined(WOLFSSL_POST_HANDSHAKE_AUTH)
+ postHandAuth = 1;
+ doCliCertCheck = 0;
+ #endif
+ break;
+
+ case 'J' :
+ #ifdef WOLFSSL_SEND_HRR_COOKIE
+ hrrCookie = 1;
+ #endif
+ break;
+
+ case 'M' :
+ #ifdef HAVE_SECURE_RENEGOTIATION
+ scr = 1;
+ #endif /* HAVE_SECURE_RENEGOTIATION */
+ break;
+
+ case 'm' :
+ #ifdef HAVE_SECURE_RENEGOTIATION
+ scr = 1;
+ forceScr = 1;
+ #endif /* HAVE_SECURE_RENEGOTIATION */
+ break;
+
+ case '0' :
+ #ifdef WOLFSSL_EARLY_DATA
+ earlyData = 1;
+ #endif
+ break;
+
+ case '1' :
+ lng_index = atoi(myoptarg);
+ if(lng_index<0||lng_index>1){
+ lng_index = 0;
+ }
+ break;
+
+ case '2' :
+ #if !defined(NO_DH) && !defined(HAVE_FIPS) && \
+ !defined(HAVE_SELFTEST) && !defined(WOLFSSL_OLD_PRIME_CHECK)
+ doDhKeyCheck = 0;
+ #endif
+ break;
+
+ case '3' :
+ #ifdef WOLFSSL_MULTICAST
+ doMcast = 1;
+ mcastID = (byte)(atoi(myoptarg) & 0xFF);
+ #endif
+ break;
+
+ case '4' :
+ #if defined(WOLFSSL_DTLS) && defined(USE_WOLFSSL_IO)
+ XMEMSET(&dtlsCtx, 0, sizeof(dtlsCtx));
+ doBlockSeq = 1;
+ dtlsCtx.blockSeq = atoi(myoptarg);
+ #endif
+ break;
+
+ case '5' :
+ #ifdef HAVE_TRUSTED_CA
+ trustedCaKeyId = 1;
+ #endif /* HAVE_TRUSTED_CA */
+ break;
+
+ case '6' :
+ nonBlocking = 1;
+ simulateWantWrite = 1;
+ break;
+ case '7' :
+ minVersion = atoi(myoptarg);
+ if (minVersion < 0 || minVersion > 4) {
+ Usage();
+ XEXIT_T(MY_EX_USAGE);
+ }
+ break;
+ case '8' :
+ #ifdef HAVE_CURVE448
+ useX448 = 1;
+ #if defined(WOLFSSL_TLS13) && defined(HAVE_SUPPORTED_CURVES)
+ onlyKeyShare = 2;
+ #endif
+ #endif
+ break;
+ case '9' :
+#if defined(OPENSSL_ALL) && defined(WOLFSSL_CERT_GEN) && \
+ (defined(WOLFSSL_CERT_REQ) || defined(WOLFSSL_CERT_EXT)) && \
+ !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR)
+ useCertFolder = 1;
+ break;
+#endif
+ case '@' :
+ {
+#ifdef HAVE_WC_INTROSPECTION
+ const char *conf_args = wolfSSL_configure_args();
+ if (conf_args) {
+ puts(conf_args);
+ XEXIT_T(EXIT_SUCCESS);
+ } else {
+ fputs("configure args not compiled in.\n",stderr);
+ XEXIT_T(MY_EX_USAGE);
+ }
+#else
+ fputs("compiled without BUILD_INTROSPECTION.\n",stderr);
+ XEXIT_T(MY_EX_USAGE);
+#endif
+ }
+
+ case '#' :
+ {
+#ifdef HAVE_WC_INTROSPECTION
+ const char *cflags = wolfSSL_global_cflags();
+ if (cflags) {
+ puts(cflags);
+ XEXIT_T(EXIT_SUCCESS);
+ } else {
+ fputs("CFLAGS not compiled in.\n",stderr);
+ XEXIT_T(MY_EX_USAGE);
+ }
+#else
+ fputs("compiled without BUILD_INTROSPECTION.\n",stderr);
+ XEXIT_T(MY_EX_USAGE);
+#endif
+ }
+
+#ifdef WOLFSSL_WOLFSENTRY_HOOKS
+ case 256:
+#if !defined(NO_FILESYSTEM) && !defined(WOLFSENTRY_NO_JSON)
+ wolfsentry_config_path = myoptarg;
+#endif
+ break;
+#endif
+
+ default:
+ Usage();
+ XEXIT_T(MY_EX_USAGE);
+ }
+ }
+
+ myoptind = 0; /* reset for test cases */
+#endif /* !WOLFSSL_VXWORKS */
+
+ /* Can only use DTLS over UDP or SCTP, can't do both. */
+ if (dtlsUDP && dtlsSCTP) {
+ err_sys_ex(runWithErrors, "Cannot use DTLS with both UDP and SCTP.");
+ }
+
+ /* sort out DTLS versus TLS versions */
+ if (version == CLIENT_INVALID_VERSION) {
+ if (doDTLS)
+ version = CLIENT_DTLS_DEFAULT_VERSION;
+ else
+ version = CLIENT_DEFAULT_VERSION;
+ }
+ else {
+ if (doDTLS) {
+ if (version == 3)
+ version = -2;
+ #if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EITHER_SIDE)
+ else if (version == EITHER_DOWNGRADE_VERSION)
+ version = -3;
+ #endif
+ else
+ version = -1;
+ }
+ }
+
+#ifdef HAVE_WNR
+ if (wc_InitNetRandom(wnrConfigFile, NULL, 5000) != 0)
+ err_sys_ex(runWithErrors, "can't load whitewood net random config "
+ "file");
+#endif
+
+ switch (version) {
+#ifndef NO_OLD_TLS
+ #ifdef WOLFSSL_ALLOW_SSLV3
+ case 0:
+ method = wolfSSLv3_server_method_ex;
+ break;
+ #endif
+
+ #ifndef NO_TLS
+ #ifdef WOLFSSL_ALLOW_TLSV10
+ case 1:
+ method = wolfTLSv1_server_method_ex;
+ break;
+ #endif
+
+ case 2:
+ method = wolfTLSv1_1_server_method_ex;
+ break;
+ #endif /* !NO_TLS */
+#endif /* !NO_OLD_TLS */
+
+#ifndef NO_TLS
+ #ifndef WOLFSSL_NO_TLS12
+ case 3:
+ method = wolfTLSv1_2_server_method_ex;
+ break;
+ #endif
+
+ #ifdef WOLFSSL_TLS13
+ case 4:
+ method = wolfTLSv1_3_server_method_ex;
+ break;
+ #endif
+
+ case SERVER_DOWNGRADE_VERSION:
+ method = wolfSSLv23_server_method_ex;
+ break;
+ #if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EITHER_SIDE)
+ case EITHER_DOWNGRADE_VERSION:
+ method = wolfSSLv23_method_ex;
+ break;
+ #endif
+#endif /* NO_TLS */
+
+#ifdef WOLFSSL_DTLS
+ #ifndef NO_OLD_TLS
+ case -1:
+ method = wolfDTLSv1_server_method_ex;
+ break;
+ #endif
+
+ #ifndef WOLFSSL_NO_TLS12
+ case -2:
+ method = wolfDTLSv1_2_server_method_ex;
+ break;
+ #endif
+ #if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EITHER_SIDE)
+ case -3:
+ method = wolfDTLSv1_2_method_ex;
+ break;
+ #endif
+#endif
+
+ default:
+ err_sys_ex(runWithErrors, "Bad SSL version");
+ }
+
+ if (method == NULL)
+ err_sys_ex(runWithErrors, "unable to get method");
+
+#ifdef WOLFSSL_STATIC_MEMORY
+ #ifdef DEBUG_WOLFSSL
+ /* print off helper buffer sizes for use with static memory
+ * printing to stderr in case of debug mode turned on */
+ fprintf(stderr, "static memory management size = %d\n",
+ wolfSSL_MemoryPaddingSz());
+ fprintf(stderr, "calculated optimum general buffer size = %d\n",
+ wolfSSL_StaticBufferSz(memory, sizeof(memory), 0));
+ fprintf(stderr, "calculated optimum IO buffer size = %d\n",
+ wolfSSL_StaticBufferSz(memoryIO, sizeof(memoryIO),
+ WOLFMEM_IO_POOL_FIXED));
+ #endif /* DEBUG_WOLFSSL */
+
+ if (wolfSSL_CTX_load_static_memory(&ctx, method, memory, sizeof(memory),0,1)
+ != WOLFSSL_SUCCESS)
+ err_sys_ex(catastrophic, "unable to load static memory and create ctx");
+
+ /* load in a buffer for IO */
+ if (wolfSSL_CTX_load_static_memory(&ctx, NULL, memoryIO, sizeof(memoryIO),
+ WOLFMEM_IO_POOL_FIXED | WOLFMEM_TRACK_STATS, 1)
+ != WOLFSSL_SUCCESS)
+ err_sys_ex(catastrophic, "unable to load static memory and create ctx");
+#else
+ if (method != NULL) {
+ ctx = SSL_CTX_new(method(NULL));
+ }
+#endif /* WOLFSSL_STATIC_MEMORY */
+ if (ctx == NULL)
+ err_sys_ex(catastrophic, "unable to get ctx");
+
+ if (minVersion != SERVER_INVALID_VERSION) {
+ wolfSSL_CTX_SetMinVersion(ctx, minVersion);
+ }
+
+#ifdef WOLFSSL_WOLFSENTRY_HOOKS
+ if (wolfsentry_setup(&wolfsentry, wolfsentry_config_path,
+ WOLFSENTRY_ROUTE_FLAG_DIRECTION_IN) < 0) {
+ err_sys("unable to initialize wolfSentry");
+ }
+
+ if (wolfSSL_CTX_set_AcceptFilter(
+ ctx,
+ (NetworkFilterCallback_t)wolfSentry_NetworkFilterCallback,
+ wolfsentry) < 0) {
+ err_sys_ex(catastrophic,
+ "unable to install wolfSentry_NetworkFilterCallback");
+ }
+#endif
+
+ if (simulateWantWrite)
+ {
+ #ifdef USE_WOLFSSL_IO
+ wolfSSL_CTX_SetIOSend(ctx, SimulateWantWriteIOSendCb);
+ #endif
+ }
+
+#if defined(HAVE_SESSION_TICKET) && defined(WOLFSSL_NO_DEF_TICKET_ENC_CB) && \
+ ((defined(HAVE_CHACHA) && defined(HAVE_POLY1305)) || defined(HAVE_AESGCM))
+ if (TicketInit() != 0)
+ err_sys_ex(catastrophic, "unable to setup Session Ticket Key context");
+ wolfSSL_CTX_set_TicketEncCb(ctx, myTicketEncCb);
+#endif
+
+#if defined(WOLFSSL_SNIFFER) && defined(WOLFSSL_STATIC_EPHEMERAL)
+ /* used for testing only to set a static/fixed ephemeral key
+ for use with the sniffer */
+#if defined(HAVE_ECC) && !defined(NO_ECC_SECP) && \
+ (!defined(NO_ECC256) || defined(HAVE_ALL_CURVES))
+ ret = wolfSSL_CTX_set_ephemeral_key(ctx, WC_PK_TYPE_ECDH,
+ "./certs/statickeys/ecc-secp256r1.pem", 0, WOLFSSL_FILETYPE_PEM);
+ if (ret != 0) {
+ err_sys_ex(runWithErrors, "error loading static ECDH key");
+ }
+ {
+ const byte* key = NULL;
+ word32 keySz = 0;
+ /* example for getting pointer to loaded static ephemeral key */
+ wolfSSL_CTX_get_ephemeral_key(ctx, WC_PK_TYPE_ECDH, &key, &keySz);
+ (void)key;
+ (void)keySz;
+ }
+#endif
+#ifndef NO_DH
+ ret = wolfSSL_CTX_set_ephemeral_key(ctx, WC_PK_TYPE_DH,
+ "./certs/statickeys/dh-ffdhe2048.pem", 0, WOLFSSL_FILETYPE_PEM);
+ if (ret != 0) {
+ err_sys_ex(runWithErrors, "error loading static DH key");
+ }
+#endif
+#endif /* WOLFSSL_SNIFFER && WOLFSSL_STATIC_EPHEMERAL */
+
+ if (cipherList && !useDefCipherList) {
+ if (SSL_CTX_set_cipher_list(ctx, cipherList) != WOLFSSL_SUCCESS)
+ err_sys_ex(runWithErrors, "server can't set custom cipher list");
+ }
+
+#ifdef WOLFSSL_LEANPSK
+ if (!usePsk) {
+ usePsk = 1;
+ }
+#endif
+
+#if defined(NO_RSA) && !defined(HAVE_ECC) && !defined(HAVE_ED25519) && \
+ !defined(HAVE_ED448)
+ if (!usePsk) {
+ usePsk = 1;
+ }
+#endif
+
+ if (fewerPackets)
+ wolfSSL_CTX_set_group_messages(ctx);
+#if (defined(WOLFSSL_SCTP) || defined(WOLFSSL_DTLS_MTU)) && \
+ defined(WOLFSSL_DTLS)
+ if (dtlsMTU)
+ wolfSSL_CTX_dtls_set_mtu(ctx, dtlsMTU);
+#endif
+
+#ifdef WOLFSSL_SCTP
+ if (dtlsSCTP)
+ wolfSSL_CTX_dtls_set_sctp(ctx);
+#endif
+
+#ifdef WOLFSSL_ENCRYPTED_KEYS
+ SSL_CTX_set_default_passwd_cb(ctx, PasswordCallBack);
+#endif
+
+#if !defined(NO_CERTS)
+ if ((!usePsk || usePskPlus) && !useAnon && !(loadCertKeyIntoSSLObj == 1)) {
+ #ifdef NO_FILESYSTEM
+ if (wolfSSL_CTX_use_certificate_chain_buffer(ctx, server_cert_der_2048,
+ sizeof_server_cert_der_2048) != WOLFSSL_SUCCESS)
+ err_sys_ex(catastrophic, "can't load server cert buffer");
+ #elif !defined(TEST_LOAD_BUFFER)
+ if (SSL_CTX_use_certificate_chain_file(ctx, ourCert)
+ != WOLFSSL_SUCCESS)
+ err_sys_ex(catastrophic, "can't load server cert file, check file "
+ "and run from wolfSSL home dir");
+ #else
+ /* loads cert chain file using buffer API */
+ load_buffer(ctx, ourCert, WOLFSSL_CERT_CHAIN);
+ #endif
+ }
+#endif
+
+#ifndef NO_DH
+ if (wolfSSL_CTX_SetMinDhKey_Sz(ctx, (word16)minDhKeyBits)
+ != WOLFSSL_SUCCESS) {
+ err_sys_ex(runWithErrors, "Error setting minimum DH key size");
+ }
+#endif
+#ifndef NO_RSA
+ if (wolfSSL_CTX_SetMinRsaKey_Sz(ctx, minRsaKeyBits) != WOLFSSL_SUCCESS){
+ err_sys_ex(runWithErrors, "Error setting minimum RSA key size");
+ }
+#endif
+#ifdef HAVE_ECC
+ if (wolfSSL_CTX_SetMinEccKey_Sz(ctx, minEccKeyBits) != WOLFSSL_SUCCESS){
+ err_sys_ex(runWithErrors, "Error setting minimum ECC key size");
+ }
+#endif
+
+#ifdef HAVE_NTRU
+ if (useNtruKey) {
+ if (wolfSSL_CTX_use_NTRUPrivateKey_file(ctx, ourKey)
+ != WOLFSSL_SUCCESS)
+ err_sys_ex(catastrophic, "can't load ntru key file, "
+ "Please run from wolfSSL home dir");
+ }
+#endif
+#if !defined(NO_CERTS)
+ #ifdef HAVE_PK_CALLBACKS
+ pkCbInfo.ourKey = ourKey;
+ #endif
+ if (!useNtruKey && (!usePsk || usePskPlus) && !useAnon
+ && !(loadCertKeyIntoSSLObj == 1)
+ #if defined(HAVE_PK_CALLBACKS) && defined(TEST_PK_PRIVKEY)
+ && !pkCallbacks
+ #endif /* HAVE_PK_CALLBACKS && TEST_PK_PRIVKEY */
+ ) {
+ #ifdef NO_FILESYSTEM
+ if (wolfSSL_CTX_use_PrivateKey_buffer(ctx, server_key_der_2048,
+ sizeof_server_key_der_2048, SSL_FILETYPE_ASN1) != WOLFSSL_SUCCESS)
+ err_sys_ex(catastrophic, "can't load server private key buffer");
+ #elif !defined(TEST_LOAD_BUFFER)
+ if (SSL_CTX_use_PrivateKey_file(ctx, ourKey, WOLFSSL_FILETYPE_PEM)
+ != WOLFSSL_SUCCESS)
+ err_sys_ex(catastrophic, "can't load server private key file, "
+ "check file and run from wolfSSL home dir");
+ #else
+ /* loads private key file using buffer API */
+ load_buffer(ctx, ourKey, WOLFSSL_KEY);
+ #endif
+ }
+#endif
+
+ if (usePsk || usePskPlus) {
+#ifndef NO_PSK
+ const char *defaultCipherList = cipherList;
+
+ SSL_CTX_set_psk_server_callback(ctx, my_psk_server_cb);
+ #ifdef WOLFSSL_TLS13
+ wolfSSL_CTX_set_psk_server_tls13_callback(ctx, my_psk_server_tls13_cb);
+ #endif
+ if (sendPskIdentityHint == 1)
+ SSL_CTX_use_psk_identity_hint(ctx, "cyassl server");
+
+ if (defaultCipherList == NULL && !usePskPlus) {
+ #if defined(HAVE_AESGCM) && !defined(NO_DH)
+ #ifdef WOLFSSL_TLS13
+ defaultCipherList = "TLS13-AES128-GCM-SHA256"
+ #ifndef WOLFSSL_NO_TLS12
+ ":DHE-PSK-AES128-GCM-SHA256"
+ #endif
+ ;
+ #else
+ defaultCipherList = "DHE-PSK-AES128-GCM-SHA256";
+ #endif
+ needDH = 1;
+ #elif defined(HAVE_AESGCM) && defined(WOLFSSL_TLS13)
+ defaultCipherList = "TLS13-AES128-GCM-SHA256"
+ #ifndef WOLFSSL_NO_TLS12
+ ":PSK-AES128-GCM-SHA256"
+ #endif
+ ;
+ #elif defined(HAVE_NULL_CIPHER)
+ defaultCipherList = "PSK-NULL-SHA256";
+ #else
+ defaultCipherList = "PSK-AES128-CBC-SHA256";
+ #endif
+ if (SSL_CTX_set_cipher_list(ctx, defaultCipherList)
+ != WOLFSSL_SUCCESS)
+ err_sys_ex(runWithErrors, "server can't set cipher list 2");
+ }
+ wolfSSL_CTX_set_psk_callback_ctx(ctx, (void*)defaultCipherList);
+#endif /* !NO_PSK */
+ }
+#ifndef NO_CERTS
+ if (mutualAuth)
+ wolfSSL_CTX_mutual_auth(ctx, 1);
+#endif
+
+
+#ifdef HAVE_ECC
+ /* Use ECDHE key size that matches long term key.
+ * Zero means use ctx->privateKeySz.
+ * Default ECDHE_SIZE is 32 bytes
+ */
+ if (wolfSSL_CTX_SetTmpEC_DHE_Sz(ctx, 0) != WOLFSSL_SUCCESS){
+ err_sys_ex(runWithErrors, "Error setting ECDHE size");
+ }
+#endif
+
+ if (useAnon) {
+#ifdef HAVE_ANON
+ wolfSSL_CTX_allow_anon_cipher(ctx);
+ if (cipherList == NULL || (cipherList && useDefCipherList)) {
+ const char* defaultCipherList;
+ defaultCipherList = "ADH-AES256-GCM-SHA384:"
+ "ADH-AES128-SHA";
+ if (SSL_CTX_set_cipher_list(ctx, defaultCipherList)
+ != WOLFSSL_SUCCESS)
+ err_sys_ex(runWithErrors, "server can't set cipher list 4");
+ }
+#endif
+ }
+
+#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS)
+ /* if not using PSK, verify peer with certs
+ if using PSK Plus then verify peer certs except PSK suites */
+ if (doCliCertCheck && (usePsk == 0 || usePskPlus) && useAnon == 0) {
+ unsigned int verify_flags = 0;
+ SSL_CTX_set_verify(ctx, WOLFSSL_VERIFY_PEER |
+ (usePskPlus ? WOLFSSL_VERIFY_FAIL_EXCEPT_PSK :
+ WOLFSSL_VERIFY_FAIL_IF_NO_PEER_CERT),
+ (myVerifyAction == VERIFY_OVERRIDE_DATE_ERR ||
+ myVerifyAction == VERIFY_FORCE_FAIL) ? myVerify : NULL);
+
+ #ifdef TEST_BEFORE_DATE
+ verify_flags |= WOLFSSL_LOAD_FLAG_DATE_ERR_OKAY;
+ #endif
+ #if defined(OPENSSL_ALL) && defined(WOLFSSL_CERT_GEN) && \
+ (defined(WOLFSSL_CERT_REQ) || defined(WOLFSSL_CERT_EXT)) && \
+ !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR)
+ if (useCertFolder) {
+ WOLFSSL_X509_STORE *store;
+ WOLFSSL_X509_LOOKUP *lookup;
+
+ store = wolfSSL_CTX_get_cert_store(ctx);
+ if (store == NULL) {
+ wolfSSL_CTX_free(ctx); ctx = NULL;
+ err_sys("can't get WOLFSSL_X509_STORE");
+ }
+ lookup = wolfSSL_X509_STORE_add_lookup(store, X509_LOOKUP_hash_dir());
+ if (lookup == NULL) {
+ wolfSSL_CTX_free(ctx); ctx = NULL;
+ err_sys("can't add lookup");
+ }
+ if (wolfSSL_X509_LOOKUP_ctrl(lookup, WOLFSSL_X509_L_ADD_DIR, caCertFolder,
+ X509_FILETYPE_PEM, NULL) != WOLFSSL_SUCCESS) {
+ err_sys("X509_LOOKUP_ctrl w/ L_ADD_DIR failed");
+ }
+ } else {
+ #endif
+ if (wolfSSL_CTX_load_verify_locations_ex(ctx, verifyCert, 0,
+ verify_flags) != WOLFSSL_SUCCESS) {
+ err_sys_ex(catastrophic,
+ "can't load ca file, Please run from wolfSSL home dir");
+ }
+ #ifdef WOLFSSL_TRUST_PEER_CERT
+ if (trustCert) {
+ if ((ret = wolfSSL_CTX_trust_peer_cert(ctx, trustCert,
+ WOLFSSL_FILETYPE_PEM))
+ != WOLFSSL_SUCCESS) {
+ err_sys_ex(runWithErrors, "can't load trusted peer cert file");
+ }
+ }
+ #endif /* WOLFSSL_TRUST_PEER_CERT */
+ #if defined(OPENSSL_ALL) && defined(WOLFSSL_CERT_GEN) && \
+ (defined(WOLFSSL_CERT_REQ) || defined(WOLFSSL_CERT_EXT)) && \
+ !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR)
+ }
+ #endif
+ }
+#endif
+
+#ifdef WOLFSSL_SNIFFER
+ if (cipherList == NULL && version < 4) {
+ /* static RSA or static ECC cipher suites */
+ const char* staticCipherList = "AES128-SHA:ECDH-ECDSA-AES128-SHA";
+ if (SSL_CTX_set_cipher_list(ctx, staticCipherList) != WOLFSSL_SUCCESS) {
+ err_sys_ex(runWithErrors, "server can't set cipher list 3");
+ }
+ }
+#endif
+
+#ifdef HAVE_SNI
+ if (sniHostName)
+ if (wolfSSL_CTX_UseSNI(ctx, WOLFSSL_SNI_HOST_NAME, sniHostName,
+ (word16) XSTRLEN(sniHostName)) != WOLFSSL_SUCCESS)
+ err_sys_ex(runWithErrors, "UseSNI failed");
+#endif
+
+#ifdef USE_WINDOWS_API
+ if (port == 0) {
+ /* Generate random port for testing */
+ port = GetRandomPort();
+ }
+#endif /* USE_WINDOWS_API */
+
+#ifdef WOLFSSL_ASYNC_CRYPT
+ ret = wolfAsync_DevOpen(&devId);
+ if (ret < 0) {
+ printf("Async device open failed\nRunning without async\n");
+ }
+ wolfSSL_CTX_SetDevId(ctx, devId);
+#endif /* WOLFSSL_ASYNC_CRYPT */
+
+#ifdef WOLFSSL_TLS13
+ if (noPskDheKe)
+ wolfSSL_CTX_no_dhe_psk(ctx);
+#endif
+#ifdef HAVE_SESSION_TICKET
+#ifdef WOLFSSL_TLS13
+ if (noTicketTls13)
+ wolfSSL_CTX_no_ticket_TLSv13(ctx);
+#endif
+#if !defined(WOLFSSL_NO_TLS12) || !defined(NO_OLD_TLS)
+ if (noTicketTls12)
+ wolfSSL_CTX_NoTicketTLSv12(ctx);
+#endif
+#endif
+
+ while (1) {
+ /* allow resume option */
+ if (resumeCount > 1) {
+ if (dtlsUDP == 0) {
+ client_len = sizeof client_addr;
+ clientfd = accept(sockfd, (struct sockaddr*)&client_addr,
+ (ACCEPT_THIRD_T)&client_len);
+ }
+ else {
+ tcp_listen(&sockfd, &port, useAnyAddr, dtlsUDP, dtlsSCTP);
+ clientfd = sockfd;
+ }
+ if (WOLFSSL_SOCKET_IS_INVALID(clientfd)) {
+ err_sys_ex(runWithErrors, "tcp accept failed");
+ }
+ }
+#if defined(WOLFSSL_STATIC_MEMORY) && defined(DEBUG_WOLFSSL)
+ fprintf(stderr, "Before creating SSL\n");
+ if (wolfSSL_CTX_is_static_memory(ctx, &mem_stats) != 1)
+ err_sys_ex(runWithErrors, "ctx not using static memory");
+ if (wolfSSL_PrintStats(&mem_stats) != 1) /* function in test.h */
+ err_sys_ex(runWithErrors, "error printing out memory stats");
+#endif
+
+ if (doMcast) {
+#ifdef WOLFSSL_MULTICAST
+ wolfSSL_CTX_mcast_set_member_id(ctx, mcastID);
+ if (wolfSSL_CTX_set_cipher_list(ctx, "WDM-NULL-SHA256")
+ != WOLFSSL_SUCCESS)
+ err_sys("Couldn't set multicast cipher list.");
+#endif
+ }
+
+ if (doDTLS && dtlsUDP) {
+#if defined(WOLFSSL_DTLS) && defined(USE_WOLFSSL_IO)
+ if (doBlockSeq) {
+ wolfSSL_CTX_SetIOSend(ctx, TestEmbedSendTo);
+ }
+#endif
+ }
+
+#ifdef HAVE_PK_CALLBACKS
+ if (pkCallbacks)
+ SetupPkCallbacks(ctx);
+#endif
+
+ ssl = SSL_new(ctx);
+ if (ssl == NULL)
+ err_sys_ex(catastrophic, "unable to create an SSL object");
+ #ifdef OPENSSL_EXTRA
+ wolfSSL_KeepArrays(ssl);
+ #endif
+
+ /* Support for loading private key and cert using WOLFSSL object */
+#if !defined(NO_CERTS)
+ if ((!usePsk || usePskPlus) && !useAnon && loadCertKeyIntoSSLObj) {
+ #ifdef NO_FILESYSTEM
+ if (wolfSSL_use_certificate_chain_buffer(ssl, server_cert_der_2048,
+ sizeof_server_cert_der_2048) != WOLFSSL_SUCCESS)
+ err_sys_ex(catastrophic, "can't load server cert buffer");
+ #elif !defined(TEST_LOAD_BUFFER)
+ if (SSL_use_certificate_chain_file(ssl, ourCert)
+ != WOLFSSL_SUCCESS)
+ err_sys_ex(catastrophic, "can't load server cert file, check file "
+ "and run from wolfSSL home dir");
+ #else
+ /* loads cert chain file using buffer API */
+ load_ssl_buffer(ssl, ourCert, WOLFSSL_CERT_CHAIN);
+ #endif
+ }
+
+ if (!useNtruKey && (!usePsk || usePskPlus) && !useAnon &&
+ loadCertKeyIntoSSLObj
+ #if defined(HAVE_PK_CALLBACKS) && defined(TEST_PK_PRIVKEY)
+ && !pkCallbacks
+ #endif /* HAVE_PK_CALLBACKS && TEST_PK_PRIVKEY */
+ ) {
+ #if defined(NO_FILESYSTEM)
+ if (wolfSSL_use_PrivateKey_buffer(ssl, server_key_der_2048,
+ sizeof_server_key_der_2048, SSL_FILETYPE_ASN1) != WOLFSSL_SUCCESS)
+ err_sys_ex(catastrophic, "can't load server private key buffer");
+ #elif !defined(TEST_LOAD_BUFFER)
+ if (SSL_use_PrivateKey_file(ssl, ourKey, WOLFSSL_FILETYPE_PEM)
+ != WOLFSSL_SUCCESS)
+ err_sys_ex(catastrophic, "can't load server private key file, check"
+ "file and run from wolfSSL home dir");
+ #else
+ /* loads private key file using buffer API */
+ load_ssl_buffer(ssl, ourKey, WOLFSSL_KEY);
+ #endif
+ }
+#endif /* !NO_CERTS */
+
+#ifdef WOLFSSL_SEND_HRR_COOKIE
+ if (hrrCookie && wolfSSL_send_hrr_cookie(ssl, NULL, 0)
+ != WOLFSSL_SUCCESS) {
+ err_sys("unable to set use of cookie with HRR msg");
+ }
+#endif
+
+#if defined(WOLFSSL_STATIC_MEMORY) && defined(DEBUG_WOLFSSL)
+ fprintf(stderr, "After creating SSL\n");
+ if (wolfSSL_CTX_is_static_memory(ctx, &mem_stats) != 1)
+ err_sys_ex(runWithErrors, "ctx not using static memory");
+ if (wolfSSL_PrintStats(&mem_stats) != 1) /* function in test.h */
+ err_sys_ex(runWithErrors, "error printing out memory stats");
+#endif
+
+ if (doMcast) {
+#ifdef WOLFSSL_MULTICAST
+ /* DTLS multicast secret for testing only */
+ #define CLI_SRV_RANDOM_SZ 32 /* RAN_LEN (see internal.h) */
+ #define PMS_SZ 512 /* ENCRYPT_LEN (see internal.h) */
+ byte pms[PMS_SZ]; /* pre master secret */
+ byte cr[CLI_SRV_RANDOM_SZ]; /* client random */
+ byte sr[CLI_SRV_RANDOM_SZ]; /* server random */
+ const byte suite[2] = {0, 0xfe}; /* WDM_WITH_NULL_SHA256 */
+
+ XMEMSET(pms, 0x23, sizeof(pms));
+ XMEMSET(cr, 0xA5, sizeof(cr));
+ XMEMSET(sr, 0x5A, sizeof(sr));
+
+ if (wolfSSL_set_secret(ssl, 1, pms, sizeof(pms), cr, sr, suite)
+ != WOLFSSL_SUCCESS) {
+ err_sys("unable to set mcast secret");
+ }
+#endif
+ }
+
+#ifdef HAVE_SECURE_RENEGOTIATION
+ if (scr) {
+ if (wolfSSL_UseSecureRenegotiation(ssl) != WOLFSSL_SUCCESS) {
+ err_sys_ex(runWithErrors, "can't enable secure renegotiation");
+ }
+ }
+#endif /* HAVE_SECURE_RENEGOTIATION */
+
+#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS)
+ #if defined(WOLFSSL_TLS13) && defined(WOLFSSL_POST_HANDSHAKE_AUTH)
+ if (postHandAuth) {
+ unsigned int verify_flags = 0;
+
+ SSL_set_verify(ssl, WOLFSSL_VERIFY_PEER |
+ ((usePskPlus) ? WOLFSSL_VERIFY_FAIL_EXCEPT_PSK :
+ WOLFSSL_VERIFY_FAIL_IF_NO_PEER_CERT), 0);
+
+ #ifdef TEST_BEFORE_DATE
+ verify_flags |= WOLFSSL_LOAD_FLAG_DATE_ERR_OKAY;
+ #endif
+
+ if (wolfSSL_CTX_load_verify_locations_ex(ctx, verifyCert, 0,
+ verify_flags)
+ != WOLFSSL_SUCCESS) {
+ err_sys_ex(runWithErrors, "can't load ca file, Please run from "
+ "wolfSSL home dir");
+ }
+ #ifdef WOLFSSL_TRUST_PEER_CERT
+ if (trustCert) {
+ if ((ret = wolfSSL_trust_peer_cert(ssl, trustCert,
+ WOLFSSL_FILETYPE_PEM)) != WOLFSSL_SUCCESS) {
+ err_sys_ex(runWithErrors, "can't load trusted peer cert "
+ "file");
+ }
+ }
+ #endif /* WOLFSSL_TRUST_PEER_CERT */
+ }
+ #endif
+#endif
+
+
+#ifndef NO_HANDSHAKE_DONE_CB
+ wolfSSL_SetHsDoneCb(ssl, myHsDoneCb, NULL);
+#endif
+#ifdef HAVE_CRL
+ if (!disableCRL) {
+#ifdef HAVE_CRL_MONITOR
+ crlFlags = WOLFSSL_CRL_MONITOR | WOLFSSL_CRL_START_MON;
+#endif
+ if (wolfSSL_EnableCRL(ssl, 0) != WOLFSSL_SUCCESS)
+ err_sys_ex(runWithErrors, "unable to enable CRL");
+ if (wolfSSL_LoadCRL(ssl, crlPemDir, WOLFSSL_FILETYPE_PEM, crlFlags)
+ != WOLFSSL_SUCCESS)
+ err_sys_ex(runWithErrors, "unable to load CRL");
+ if (wolfSSL_SetCRL_Cb(ssl, CRL_CallBack) != WOLFSSL_SUCCESS)
+ err_sys_ex(runWithErrors, "unable to set CRL callback url");
+ }
+#endif
+#ifdef HAVE_OCSP
+ if (useOcsp) {
+ if (ocspUrl != NULL) {
+ wolfSSL_CTX_SetOCSP_OverrideURL(ctx, ocspUrl);
+ wolfSSL_CTX_EnableOCSP(ctx, WOLFSSL_OCSP_NO_NONCE
+ | WOLFSSL_OCSP_URL_OVERRIDE);
+ }
+ else
+ wolfSSL_CTX_EnableOCSP(ctx, WOLFSSL_OCSP_NO_NONCE);
+ }
+#ifndef NO_RSA
+ /* All the OSCP Stapling test certs are RSA. */
+#if defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
+ || defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
+ { /* scope start */
+ const char* ca1 = "certs/ocsp/intermediate1-ca-cert.pem";
+ const char* ca2 = "certs/ocsp/intermediate2-ca-cert.pem";
+ const char* ca3 = "certs/ocsp/intermediate3-ca-cert.pem";
+ int fails = 0;
+
+ if (wolfSSL_CTX_EnableOCSPStapling(ctx) != WOLFSSL_SUCCESS) {
+ err_sys_ex(catastrophic, "can't enable OCSP Stapling "
+ "Certificate Manager");
+ }
+ if (SSL_CTX_load_verify_locations(ctx, ca1, 0) != WOLFSSL_SUCCESS) {
+ fails++;
+ err_sys_ex(runWithErrors, "can't load ca file, Please run from "
+ "wolfSSL home dir");
+ }
+ if (SSL_CTX_load_verify_locations(ctx, ca2, 0) != WOLFSSL_SUCCESS) {
+ fails++;
+ err_sys_ex(runWithErrors, "can't load ca file, Please run from "
+ "wolfSSL home dir");
+ }
+ if (SSL_CTX_load_verify_locations(ctx, ca3, 0) != WOLFSSL_SUCCESS) {
+ fails++;
+ err_sys_ex(runWithErrors, "can't load ca file, Please run from "
+ "wolfSSL home dir");
+ }
+ if (fails > 2) {
+ err_sys_ex(catastrophic, "Failed to load any intermediates for "
+ "OCSP stapling test");
+ }
+ } /* scope end */
+#endif /* HAVE_CERTIFICATE_STATUS_REQUEST HAVE_CERTIFICATE_STATUS_REQUEST_V2 */
+#endif /* NO_RSA */
+#endif /* HAVE_OCSP */
+
+#ifdef HAVE_PK_CALLBACKS
+ if (pkCallbacks)
+ SetupPkCallbackContexts(ssl, &pkCbInfo);
+#endif
+
+ #if defined(WOLFSSL_TLS13) && defined(HAVE_SUPPORTED_CURVES)
+ if (version >= 4) {
+ SetKeyShare(ssl, onlyKeyShare, useX25519, useX448);
+ }
+ #endif
+
+ #ifdef HAVE_ENCRYPT_THEN_MAC
+ if (disallowETM)
+ wolfSSL_AllowEncryptThenMac(ssl, 0);
+ #endif
+
+
+ /* do accept */
+ readySignal = ((func_args*)args)->signal;
+ if (readySignal) {
+ readySignal->srfName = serverReadyFile;
+ }
+
+ client_len = sizeof client_addr;
+ tcp_accept(&sockfd, &clientfd, (func_args*)args, port, useAnyAddr,
+ dtlsUDP, dtlsSCTP, serverReadyFile ? 1 : 0, doListen,
+ &client_addr, &client_len);
+
+ doListen = 0; /* Don't listen next time */
+
+ if (port == 0) {
+ port = readySignal->port;
+ }
+
+ if (SSL_set_fd(ssl, clientfd) != WOLFSSL_SUCCESS) {
+ err_sys_ex(catastrophic, "error in setting fd");
+ }
+
+#ifdef HAVE_TRUSTED_CA
+ if (trustedCaKeyId) {
+ if (wolfSSL_UseTrustedCA(ssl, WOLFSSL_TRUSTED_CA_PRE_AGREED,
+ NULL, 0) != WOLFSSL_SUCCESS) {
+ err_sys_ex(runWithErrors, "UseTrustedCA failed");
+ }
+ }
+#endif /* HAVE_TRUSTED_CA */
+
+#ifdef HAVE_ALPN
+ if (alpnList != NULL) {
+ printf("ALPN accepted protocols list : %s\n", alpnList);
+ wolfSSL_UseALPN(ssl, alpnList, (word32)XSTRLEN(alpnList), alpn_opt);
+ }
+#endif
+
+#if defined(WOLFSSL_DTLS) && defined(USE_WOLFSSL_IO)
+ if (doDTLS && dtlsUDP) {
+ byte b[1500];
+ int n;
+
+ client_len = sizeof client_addr;
+
+ /* For DTLS, peek at the next datagram so we can get the client's
+ * address and set it into the ssl object later to generate the
+ * cookie. */
+ n = (int)recvfrom(clientfd, (char*)b, sizeof(b), MSG_PEEK,
+ (struct sockaddr*)&client_addr, &client_len);
+ if (n <= 0)
+ err_sys_ex(runWithErrors, "recvfrom failed");
+
+ if (doBlockSeq) {
+ XMEMCPY(&dtlsCtx.peer.sa, &client_addr, client_len);
+ dtlsCtx.peer.sz = client_len;
+ dtlsCtx.wfd = clientfd;
+ dtlsCtx.failOnce = 1;
+
+ wolfSSL_SetIOWriteCtx(ssl, &dtlsCtx);
+ }
+ else {
+ wolfSSL_dtls_set_peer(ssl, &client_addr, client_len);
+ }
+ }
+#endif
+
+#ifdef WOLFSSL_WOLFSENTRY_HOOKS
+ {
+ SOCKADDR_IN_T local_addr;
+ socklen_t local_len = sizeof(local_addr);
+ getsockname(clientfd, (struct sockaddr *)&local_addr,
+ (socklen_t *)&local_len);
+
+ if (((struct sockaddr *)&client_addr)->sa_family !=
+ ((struct sockaddr *)&local_addr)->sa_family)
+ err_sys_ex(catastrophic,
+ "client_addr.sa_family != local_addr.sa_family");
+
+ if (wolfsentry_store_endpoints(
+ ssl, &client_addr, &local_addr,
+ dtlsUDP ? IPPROTO_UDP : IPPROTO_TCP,
+ WOLFSENTRY_ROUTE_FLAG_DIRECTION_IN, NULL) != WOLFSSL_SUCCESS)
+ err_sys_ex(catastrophic,
+ "error in wolfsentry_store_endpoints()");
+ }
+#endif /* WOLFSSL_WOLFSENTRY_HOOKS */
+
+ if ((usePsk == 0 || usePskPlus) || useAnon == 1 || cipherList != NULL
+ || needDH == 1) {
+ #if !defined(NO_FILESYSTEM) && !defined(NO_DH) && !defined(NO_ASN)
+ wolfSSL_SetTmpDH_file(ssl, ourDhParam, WOLFSSL_FILETYPE_PEM);
+ #elif !defined(NO_DH)
+ SetDH(ssl); /* repick suites with DHE, higher priority than
+ * PSK */
+ #endif
+#if !defined(NO_DH) && !defined(WOLFSSL_OLD_PRIME_CHECK) && \
+ !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)
+ if (!doDhKeyCheck)
+ wolfSSL_SetEnableDhKeyTest(ssl, 0);
+#endif
+ }
+
+#ifndef WOLFSSL_CALLBACKS
+ if (nonBlocking) {
+ #ifdef WOLFSSL_DTLS
+ if (doDTLS) {
+ wolfSSL_dtls_set_using_nonblock(ssl, 1);
+ }
+ #endif
+ tcp_set_nonblocking(&clientfd);
+
+ ret = NonBlockingSSL_Accept(ssl);
+ }
+ else {
+ #ifdef WOLFSSL_EARLY_DATA
+ if (earlyData) {
+ do {
+ int len;
+ err = 0; /* reset error */
+ ret = wolfSSL_read_early_data(ssl, input, sizeof(input)-1,
+ &len);
+ if (ret != WOLFSSL_SUCCESS) {
+ err = SSL_get_error(ssl, 0);
+ #ifdef WOLFSSL_ASYNC_CRYPT
+ if (err == WC_PENDING_E) {
+ ret = wolfSSL_AsyncPoll(ssl,
+ WOLF_POLL_FLAG_CHECK_HW);
+ if (ret < 0) break;
+ }
+ #endif
+ }
+ if (ret > 0) {
+ input[ret] = 0; /* null terminate message */
+ printf("Early Data Client message: %s\n", input);
+ }
+ } while (err == WC_PENDING_E || ret > 0);
+ }
+ #endif
+ do {
+ err = 0; /* reset error */
+ ret = SSL_accept(ssl);
+#ifdef WOLFSSL_EARLY_DATA
+ EarlyDataStatus(ssl);
+#endif
+ if (ret != WOLFSSL_SUCCESS) {
+ err = SSL_get_error(ssl, 0);
+ #ifdef WOLFSSL_ASYNC_CRYPT
+ if (err == WC_PENDING_E) {
+ ret = wolfSSL_AsyncPoll(ssl, WOLF_POLL_FLAG_CHECK_HW);
+ if (ret < 0) break;
+ }
+ #endif
+ }
+ } while (err == WC_PENDING_E);
+ }
+#else
+ ret = NonBlockingSSL_Accept(ssl);
+#endif
+ if (ret != WOLFSSL_SUCCESS) {
+ err = SSL_get_error(ssl, 0);
+ printf("SSL_accept error %d, %s\n", err,
+ ERR_error_string(err, buffer));
+ if (!exitWithRet) {
+ err_sys_ex(runWithErrors, "SSL_accept failed");
+ } else {
+ /* cleanup */
+ SSL_free(ssl); ssl = NULL;
+ SSL_CTX_free(ctx); ctx = NULL;
+ CloseSocket(clientfd);
+ CloseSocket(sockfd);
+ ((func_args*)args)->return_code = err;
+ goto exit;
+ }
+ }
+
+ showPeerEx(ssl, lng_index);
+ if (SSL_state(ssl) != 0) {
+ err_sys_ex(runWithErrors, "SSL in error state");
+ }
+
+ /* if the caller requested a particular cipher, check here that either
+ * a canonical name of the established cipher matches the requested
+ * cipher name, or the requested cipher name is marked as an alias
+ * that matches the established cipher.
+ */
+ if (cipherList && !useDefCipherList && (! XSTRSTR(cipherList, ":"))) {
+ WOLFSSL_CIPHER* established_cipher = wolfSSL_get_current_cipher(ssl);
+ byte requested_cipherSuite0, requested_cipherSuite;
+ int requested_cipherFlags;
+ if (established_cipher &&
+ /* don't test for pseudo-ciphers like "ALL" and "DEFAULT". */
+ (wolfSSL_get_cipher_suite_from_name(cipherList,
+ &requested_cipherSuite0,
+ &requested_cipherSuite,
+ &requested_cipherFlags) == 0)) {
+ word32 established_cipher_id = wolfSSL_CIPHER_get_id(established_cipher);
+ byte established_cipherSuite0 = (established_cipher_id >> 8) & 0xff;
+ byte established_cipherSuite = established_cipher_id & 0xff;
+ const char *established_cipher_name =
+ wolfSSL_get_cipher_name_from_suite(established_cipherSuite0,
+ established_cipherSuite);
+ const char *established_cipher_name_iana =
+ wolfSSL_get_cipher_name_iana_from_suite(established_cipherSuite0,
+ established_cipherSuite);
+
+ if (established_cipher_name == NULL)
+ err_sys_ex(catastrophic, "error looking up name of established cipher");
+
+ if (strcmp(cipherList, established_cipher_name) &&
+ ((established_cipher_name_iana == NULL) ||
+ strcmp(cipherList, established_cipher_name_iana))) {
+ if (! (requested_cipherFlags & WOLFSSL_CIPHER_SUITE_FLAG_NAMEALIAS))
+ err_sys_ex(
+ catastrophic,
+ "Unexpected mismatch between names of requested and established ciphers.");
+ else if ((requested_cipherSuite0 != established_cipherSuite0) ||
+ (requested_cipherSuite != established_cipherSuite))
+ err_sys_ex(
+ catastrophic,
+ "Mismatch between IDs of requested and established ciphers.");
+ }
+ }
+ }
+
+#if defined(OPENSSL_EXTRA) || defined(HAVE_SECRET_CALLBACK)
+ {
+ byte* rnd = NULL;
+ byte* pt;
+ size_t size;
+
+ /* get size of buffer then print */
+ size = wolfSSL_get_server_random(NULL, NULL, 0);
+ if (size == 0) {
+ err_sys_ex(runWithErrors, "error getting server random buffer "
+ "size");
+ }
+ else {
+ rnd = (byte*)XMALLOC(size, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+ }
+
+ if (rnd == NULL) {
+ err_sys_ex(runWithErrors, "error creating server random buffer");
+ }
+
+ size = wolfSSL_get_server_random(ssl, rnd, size);
+ if (size == 0) {
+ if (rnd) {
+ XFREE(rnd, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+ rnd = NULL;
+ }
+ err_sys_ex(runWithErrors, "error getting server random buffer");
+ }
+
+ if (rnd) {
+ printf("Server Random : ");
+ for (pt = rnd; pt < rnd + size; pt++) printf("%02X", *pt);
+ printf("\n");
+
+ XFREE(rnd, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+ rnd = NULL;
+ }
+ }
+#endif
+
+#ifdef HAVE_ALPN
+ if (alpnList != NULL) {
+ char *protocol_name = NULL, *list = NULL;
+ word16 protocol_nameSz = 0, listSz = 0;
+
+ err = wolfSSL_ALPN_GetProtocol(ssl, &protocol_name,
+ &protocol_nameSz);
+ if (err == WOLFSSL_SUCCESS)
+ printf("Sent ALPN protocol : %s (%d)\n",
+ protocol_name, protocol_nameSz);
+ else if (err == WOLFSSL_ALPN_NOT_FOUND)
+ printf("No ALPN response sent (no match)\n");
+ else
+ printf("Getting ALPN protocol name failed\n");
+
+ err = wolfSSL_ALPN_GetPeerProtocol(ssl, &list, &listSz);
+ if (err == WOLFSSL_SUCCESS)
+ printf("List of protocol names sent by Client: %s (%d)\n",
+ list, listSz);
+ else
+ printf("Get list of client's protocol name failed\n");
+
+ free(list);
+ }
+#endif
+
+ if (echoData == 0 && throughput == 0) {
+ ServerRead(ssl, input, sizeof(input)-1);
+ err = SSL_get_error(ssl, 0);
+ }
+
+#if defined(HAVE_SECURE_RENEGOTIATION) && \
+ defined(HAVE_SERVER_RENEGOTIATION_INFO)
+ if (scr && forceScr) {
+ if (nonBlocking) {
+ if ((ret = wolfSSL_Rehandshake(ssl)) != WOLFSSL_SUCCESS) {
+ err = wolfSSL_get_error(ssl, 0);
+ if (err == WOLFSSL_ERROR_WANT_READ ||
+ err == WOLFSSL_ERROR_WANT_WRITE) {
+ do {
+ if (err == APP_DATA_READY) {
+ if ((ret = wolfSSL_read(ssl, input, sizeof(input)-1)) < 0) {
+ err_sys("APP DATA should be present but error returned");
+ }
+ printf("Received message: %s\n", input);
+ }
+ err = 0;
+ if ((ret = wolfSSL_accept(ssl)) != WOLFSSL_SUCCESS) {
+ err = wolfSSL_get_error(ssl, ret);
+ }
+ } while (ret != WOLFSSL_SUCCESS &&
+ (err == WOLFSSL_ERROR_WANT_READ ||
+ err == WOLFSSL_ERROR_WANT_WRITE ||
+ err == APP_DATA_READY));
+
+ if (ret != WOLFSSL_SUCCESS) {
+ err = wolfSSL_get_error(ssl, 0);
+ printf("wolfSSL_Rehandshake error %d, %s\n", err,
+ wolfSSL_ERR_error_string(err, buffer));
+ wolfSSL_free(ssl); ssl = NULL;
+ wolfSSL_CTX_free(ctx); ctx = NULL;
+ err_sys("non-blocking wolfSSL_Rehandshake failed");
+ }
+ printf("NON-BLOCKING RENEGOTIATION SUCCESSFUL\n");
+ }
+ else {
+ printf("wolfSSL_Rehandshake error %d, %s\n", err,
+ wolfSSL_ERR_error_string(err, buffer));
+ wolfSSL_free(ssl); ssl = NULL;
+ wolfSSL_CTX_free(ctx); ctx = NULL;
+ err_sys("non-blocking wolfSSL_Rehandshake failed");
+ }
+ }
+ } else {
+ if ((ret = wolfSSL_Rehandshake(ssl)) != WOLFSSL_SUCCESS) {
+#ifdef WOLFSSL_ASYNC_CRYPT
+ err = wolfSSL_get_error(ssl, 0);
+ while (err == WC_PENDING_E) {
+ err = 0;
+ ret = wolfSSL_negotiate(ssl);
+ if (ret != WOLFSSL_SUCCESS) {
+ err = wolfSSL_get_error(ssl, 0);
+ if (err == WC_PENDING_E) {
+ ret = wolfSSL_AsyncPoll(ssl, WOLF_POLL_FLAG_CHECK_HW);
+ if (ret < 0) break;
+ }
+ }
+ }
+ if (ret != WOLFSSL_SUCCESS)
+#endif
+ printf("not doing secure renegotiation\n");
+ }
+ else {
+ printf("RENEGOTIATION SUCCESSFUL\n");
+ }
+ }
+ }
+#endif /* HAVE_SECURE_RENEGOTIATION */
+
+ if (err == 0 && echoData == 0 && throughput == 0) {
+ const char* write_msg;
+ int write_msg_sz;
+
+#ifdef WOLFSSL_TLS13
+ if (updateKeysIVs)
+ wolfSSL_update_keys(ssl);
+#endif
+#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_POST_HANDSHAKE_AUTH)
+ if (postHandAuth)
+ wolfSSL_request_certificate(ssl);
+#endif
+
+ /* Write data */
+ if (!useWebServerMsg) {
+ write_msg = kReplyMsg;
+ write_msg_sz = (int)XSTRLEN(kReplyMsg);
+ }
+ else {
+ write_msg = kHttpServerMsg;
+ write_msg_sz = (int)XSTRLEN(kHttpServerMsg);
+ }
+ ServerWrite(ssl, write_msg, write_msg_sz);
+
+#ifdef WOLFSSL_TLS13
+ if (updateKeysIVs || postHandAuth)
+ ServerRead(ssl, input, sizeof(input)-1);
+#endif
+ }
+ else if (err == 0 || err == WOLFSSL_ERROR_ZERO_RETURN) {
+ err = ServerEchoData(ssl, clientfd, echoData, block, throughput);
+ if (err != 0) {
+ SSL_free(ssl); ssl = NULL;
+ SSL_CTX_free(ctx); ctx = NULL;
+ CloseSocket(clientfd);
+ CloseSocket(sockfd);
+ ((func_args*)args)->return_code = err;
+ goto exit;
+ }
+ }
+
+#if defined(WOLFSSL_MDK_SHELL) && defined(HAVE_MDK_RTX)
+ os_dly_wait(500) ;
+#elif defined (WOLFSSL_TIRTOS)
+ Task_yield();
+#endif
+
+ if (dtlsUDP == 0) {
+ ret = SSL_shutdown(ssl);
+ if (wc_shutdown && ret == WOLFSSL_SHUTDOWN_NOT_DONE) {
+ ret = SSL_shutdown(ssl); /* bidirectional shutdown */
+ if (ret == WOLFSSL_SUCCESS)
+ printf("Bidirectional shutdown complete\n");
+ }
+ }
+
+ /* display collected statistics */
+#ifdef WOLFSSL_STATIC_MEMORY
+ if (wolfSSL_is_static_memory(ssl, &ssl_stats) != 1)
+ err_sys_ex(runWithErrors, "static memory was not used with ssl");
+
+ fprintf(stderr, "\nprint off SSL memory stats\n");
+ fprintf(stderr, "*** This is memory state before wolfSSL_free is "
+ "called\n");
+ fprintf(stderr, "peak connection memory = %d\n", ssl_stats.peakMem);
+ fprintf(stderr, "current memory in use = %d\n", ssl_stats.curMem);
+ fprintf(stderr, "peak connection allocs = %d\n", ssl_stats.peakAlloc);
+ fprintf(stderr, "current connection allocs = %d\n",ssl_stats.curAlloc);
+ fprintf(stderr, "total connection allocs = %d\n",
+ ssl_stats.totalAlloc);
+ fprintf(stderr, "total connection frees = %d\n\n",
+ ssl_stats.totalFr);
+
+#endif
+ SSL_free(ssl); ssl = NULL;
+
+ CloseSocket(clientfd);
+
+ if (resume == 1 && resumeCount == 0) {
+ resumeCount++; /* only do one resume for testing */
+ continue;
+ }
+ resumeCount = 0;
+
+ cnt++;
+ if (loops > 0 && --loops == 0) {
+ break; /* out of while loop, done with normal and resume option */
+ }
+ } /* while(1) */
+
+ WOLFSSL_TIME(cnt);
+ (void)cnt;
+
+#if defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
+ || defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
+ wolfSSL_CTX_DisableOCSPStapling(ctx);
+#endif
+
+ CloseSocket(sockfd);
+ SSL_CTX_free(ctx); ctx = NULL;
+
+ ((func_args*)args)->return_code = 0;
+
+exit:
+
+#ifdef WOLFSSL_WOLFSENTRY_HOOKS
+ wolfsentry_ret = wolfsentry_shutdown(&wolfsentry);
+ if (wolfsentry_ret < 0) {
+ fprintf(stderr,
+ "wolfsentry_shutdown() returned " WOLFSENTRY_ERROR_FMT "\n",
+ WOLFSENTRY_ERROR_FMT_ARGS(wolfsentry_ret));
+ }
+#endif
+
+#if defined(HAVE_ECC) && defined(FP_ECC) && defined(HAVE_THREAD_LS) \
+ && (defined(NO_MAIN_DRIVER) || defined(HAVE_STACK_SIZE))
+ wc_ecc_fp_free(); /* free per thread cache */
+#endif
+
+#ifdef WOLFSSL_TIRTOS
+ fdCloseSession(Task_self());
+#endif
+
+#if defined(HAVE_SESSION_TICKET) && defined(WOLFSSL_NO_DEF_TICKET_ENC_CB) && \
+ ((defined(HAVE_CHACHA) && defined(HAVE_POLY1305)) || defined(HAVE_AESGCM))
+ TicketCleanup();
+#endif
+
+#ifdef WOLFSSL_ASYNC_CRYPT
+ wolfAsync_DevClose(&devId);
+#endif
+
+ /* There are use cases when these assignments are not read. To avoid
+ * potential confusion those warnings have been handled here.
+ */
+ (void) ourKey;
+ (void) verifyCert;
+ (void) doCliCertCheck;
+ (void) useNtruKey;
+ (void) ourDhParam;
+ (void) ourCert;
+ (void) useX25519;
+ (void) useX448;
+#ifdef HAVE_SECURE_RENEGOTIATION
+ (void) forceScr;
+#endif
+#ifndef WOLFSSL_TIRTOS
+ return 0;
+#endif
+}
+
+#endif /* !NO_WOLFSSL_SERVER */
+
+
+/* so overall tests can pull in test function */
+#ifndef NO_MAIN_DRIVER
+
+ int main(int argc, char** argv)
+ {
+ func_args args;
+ tcp_ready ready;
+
+ StartTCP();
+
+ args.argc = argc;
+ args.argv = argv;
+ args.signal = &ready;
+ args.return_code = 0;
+ InitTcpReady(&ready);
+
+#if defined(DEBUG_WOLFSSL) && !defined(WOLFSSL_MDK_SHELL)
+ wolfSSL_Debugging_ON();
+#endif
+ wolfSSL_Init();
+ ChangeToWolfRoot();
+
+#ifndef NO_WOLFSSL_SERVER
+#ifdef HAVE_STACK_SIZE
+ StackSizeCheck(&args, server_test);
+#else
+ server_test(&args);
+#endif
+#else
+ printf("Server not compiled in!\n");
+#endif
+
+ wolfSSL_Cleanup();
+ FreeTcpReady(&ready);
+
+#ifdef HAVE_WNR
+ if (wc_FreeNetRandom() < 0)
+ err_sys_ex(runWithErrors, "Failed to free netRandom context");
+#endif /* HAVE_WNR */
+
+ return args.return_code;
+ }
+
+ int myoptind = 0;
+ char* myoptarg = NULL;
+
+#endif /* NO_MAIN_DRIVER */
diff --git a/ap/lib/libwolfssl/install/share/doc/wolfssl/example/tls_bench.c b/ap/lib/libwolfssl/install/share/doc/wolfssl/example/tls_bench.c
new file mode 100644
index 0000000..fcbdd66
--- /dev/null
+++ b/ap/lib/libwolfssl/install/share/doc/wolfssl/example/tls_bench.c
@@ -0,0 +1,1953 @@
+/* tls_bench.c
+ *
+ * Copyright (C) 2006-2021 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL.
+ *
+ * wolfSSL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfSSL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
+ */
+
+
+/*
+Example gcc build statement
+gcc -lwolfssl -lpthread -o tls_bench tls_bench.c
+./tls_bench
+
+Or
+
+#include <examples/benchmark/tls_bench.h>
+bench_tls(args);
+*/
+
+
+#ifdef HAVE_CONFIG_H
+ #include <config.h>
+#endif
+#ifndef WOLFSSL_USER_SETTINGS
+ #include <wolfssl/options.h>
+#endif
+#include <wolfssl/wolfcrypt/settings.h>
+#include <wolfssl/ssl.h>
+#include <wolfssl/wolfcrypt/hash.h> /* WC_MAX_DIGEST_SIZE */
+#include <wolfssl/test.h>
+#include <wolfssl/wolfio.h>
+#include <examples/benchmark/tls_bench.h>
+
+/* force certificate test buffers to be included via headers */
+#undef USE_CERT_BUFFERS_2048
+#define USE_CERT_BUFFERS_2048
+#undef USE_CERT_BUFFERS_256
+#define USE_CERT_BUFFERS_256
+#include <wolfssl/certs_test.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/time.h>
+#include <errno.h>
+
+/* For testing no pthread support */
+#if 0
+ #undef HAVE_PTHREAD
+#endif
+
+/* PTHREAD requires server and client enabled */
+#if defined(HAVE_PTHREAD) && (defined(NO_WOLFSSL_CLIENT) || defined(NO_WOLFSSL_SERVER))
+ #undef HAVE_PTHREAD
+#endif
+
+#ifdef HAVE_PTHREAD
+ #include <pthread.h>
+#endif
+
+#if 0
+#define BENCH_USE_NONBLOCK
+#endif
+
+/* Defaults for configuration parameters */
+#define BENCH_DEFAULT_HOST "localhost"
+#define BENCH_DEFAULT_PORT 11112
+#define NUM_THREAD_PAIRS 1 /* Thread pairs of server/client */
+#ifndef BENCH_RUNTIME_SEC
+ #ifdef BENCH_EMBEDDED
+ #define BENCH_RUNTIME_SEC 15
+ #else
+ #define BENCH_RUNTIME_SEC 1
+ #endif
+#endif
+/* TLS packet size */
+#ifndef TEST_PACKET_SIZE
+ #ifdef BENCH_EMBEDDED
+ #define TEST_PACKET_SIZE (2 * 1024)
+ #else
+ #define TEST_PACKET_SIZE (16 * 1024)
+ #endif
+#endif
+/* Total bytes to benchmark per connection */
+#ifndef TEST_MAX_SIZE
+ #ifdef BENCH_EMBEDDED
+ #define TEST_MAX_SIZE (16 * 1024)
+ #else
+ #define TEST_MAX_SIZE (128 * 1024)
+ #endif
+#endif
+
+#ifdef WOLFSSL_DTLS
+ #ifdef BENCH_EMBEDDED
+ /* WOLFSSL_MAX_MTU in internal.h */
+ #define TEST_DTLS_PACKET_SIZE (1500)
+ #else
+ /* MAX_UDP_SIZE in interna.h */
+ #define TEST_DTLS_PACKET_SIZE (8092)
+ #endif
+#endif
+
+/* In memory transfer buffer maximum size */
+/* Must be large enough to handle max TLS packet size plus max TLS header MAX_MSG_EXTRA */
+#define MEM_BUFFER_SZ (TEST_PACKET_SIZE + 38 + WC_MAX_DIGEST_SIZE)
+#define SHOW_VERBOSE 0 /* Default output is tab delimited format */
+
+#if (!defined(NO_WOLFSSL_CLIENT) || !defined(NO_WOLFSSL_SERVER)) && \
+ !defined(WOLFCRYPT_ONLY) && defined(USE_WOLFSSL_IO)
+
+/* shutdown message - nice signal to server, we are done */
+static const char* kShutdown = "shutdown";
+
+#ifndef NO_WOLFSSL_CLIENT
+PEDANTIC_EXTENSION static const char* kTestStr =
+"Biodiesel cupidatat marfa, cliche aute put a bird on it incididunt elit\n"
+"polaroid. Sunt tattooed bespoke reprehenderit. Sint twee organic id\n"
+"marfa. Commodo veniam ad esse gastropub. 3 wolf moon sartorial vero,\n"
+"plaid delectus biodiesel squid +1 vice. Post-ironic keffiyeh leggings\n"
+"selfies cray fap hoodie, forage anim. Carles cupidatat shoreditch, VHS\n"
+"small batch meggings kogi dolore food truck bespoke gastropub.\n"
+"\n"
+"Terry richardson adipisicing actually typewriter tumblr, twee whatever\n"
+"four loko you probably haven't heard of them high life. Messenger bag\n"
+"whatever tattooed deep v mlkshk. Brooklyn pinterest assumenda chillwave\n"
+"et, banksy ullamco messenger bag umami pariatur direct trade forage.\n"
+"Typewriter culpa try-hard, pariatur sint brooklyn meggings. Gentrify\n"
+"food truck next level, tousled irony non semiotics PBR ethical anim cred\n"
+"readymade. Mumblecore brunch lomo odd future, portland organic terry\n"
+"richardson elit leggings adipisicing ennui raw denim banjo hella. Godard\n"
+"mixtape polaroid, pork belly readymade organic cray typewriter helvetica\n"
+"four loko whatever street art yr farm-to-table.\n"
+"\n"
+"Vinyl keytar vice tofu. Locavore you probably haven't heard of them pug\n"
+"pickled, hella tonx labore truffaut DIY mlkshk elit cosby sweater sint\n"
+"et mumblecore. Elit swag semiotics, reprehenderit DIY sartorial nisi ugh\n"
+"nesciunt pug pork belly wayfarers selfies delectus. Ethical hoodie\n"
+"seitan fingerstache kale chips. Terry richardson artisan williamsburg,\n"
+"eiusmod fanny pack irony tonx ennui lo-fi incididunt tofu YOLO\n"
+"readymade. 8-bit sed ethnic beard officia. Pour-over iphone DIY butcher,\n"
+"ethnic art party qui letterpress nisi proident jean shorts mlkshk\n"
+"locavore.\n"
+"\n"
+"Narwhal flexitarian letterpress, do gluten-free voluptate next level\n"
+"banh mi tonx incididunt carles DIY. Odd future nulla 8-bit beard ut\n"
+"cillum pickled velit, YOLO officia you probably haven't heard of them\n"
+"trust fund gastropub. Nisi adipisicing tattooed, Austin mlkshk 90's\n"
+"small batch american apparel. Put a bird on it cosby sweater before they\n"
+"sold out pork belly kogi hella. Street art mollit sustainable polaroid,\n"
+"DIY ethnic ea pug beard dreamcatcher cosby sweater magna scenester nisi.\n"
+"Sed pork belly skateboard mollit, labore proident eiusmod. Sriracha\n"
+"excepteur cosby sweater, anim deserunt laborum eu aliquip ethical et\n"
+"neutra PBR selvage.\n"
+"\n"
+"Raw denim pork belly truffaut, irony plaid sustainable put a bird on it\n"
+"next level jean shorts exercitation. Hashtag keytar whatever, nihil\n"
+"authentic aliquip disrupt laborum. Tattooed selfies deserunt trust fund\n"
+"wayfarers. 3 wolf moon synth church-key sartorial, gastropub leggings\n"
+"tattooed. Labore high life commodo, meggings raw denim fingerstache pug\n"
+"trust fund leggings seitan forage. Nostrud ullamco duis, reprehenderit\n"
+"incididunt flannel sustainable helvetica pork belly pug banksy you\n"
+"probably haven't heard of them nesciunt farm-to-table. Disrupt nostrud\n"
+"mollit magna, sriracha sartorial helvetica.\n"
+"\n"
+"Nulla kogi reprehenderit, skateboard sustainable duis adipisicing viral\n"
+"ad fanny pack salvia. Fanny pack trust fund you probably haven't heard\n"
+"of them YOLO vice nihil. Keffiyeh cray lo-fi pinterest cardigan aliqua,\n"
+"reprehenderit aute. Culpa tousled williamsburg, marfa lomo actually anim\n"
+"skateboard. Iphone aliqua ugh, semiotics pariatur vero readymade\n"
+"organic. Marfa squid nulla, in laborum disrupt laboris irure gastropub.\n"
+"Veniam sunt food truck leggings, sint vinyl fap.\n"
+"\n"
+"Hella dolore pork belly, truffaut carles you probably haven't heard of\n"
+"them PBR helvetica in sapiente. Fashion axe ugh bushwick american\n"
+"apparel. Fingerstache sed iphone, jean shorts blue bottle nisi bushwick\n"
+"flexitarian officia veniam plaid bespoke fap YOLO lo-fi. Blog\n"
+"letterpress mumblecore, food truck id cray brooklyn cillum ad sed.\n"
+"Assumenda chambray wayfarers vinyl mixtape sustainable. VHS vinyl\n"
+"delectus, culpa williamsburg polaroid cliche swag church-key synth kogi\n"
+"magna pop-up literally. Swag thundercats ennui shoreditch vegan\n"
+"pitchfork neutra truffaut etsy, sed single-origin coffee craft beer.\n"
+"\n"
+"Odio letterpress brooklyn elit. Nulla single-origin coffee in occaecat\n"
+"meggings. Irony meggings 8-bit, chillwave lo-fi adipisicing cred\n"
+"dreamcatcher veniam. Put a bird on it irony umami, trust fund bushwick\n"
+"locavore kale chips. Sriracha swag thundercats, chillwave disrupt\n"
+"tousled beard mollit mustache leggings portland next level. Nihil esse\n"
+"est, skateboard art party etsy thundercats sed dreamcatcher ut iphone\n"
+"swag consectetur et. Irure skateboard banjo, nulla deserunt messenger\n"
+"bag dolor terry richardson sapiente.\n";
+#endif
+
+#if !defined(NO_DH)
+
+#define MIN_DHKEY_BITS 1024
+
+#if !defined(NO_WOLFSSL_SERVER)
+/* dh2048 p */
+static const unsigned char dhp[] =
+{
+ 0xb0, 0xa1, 0x08, 0x06, 0x9c, 0x08, 0x13, 0xba, 0x59, 0x06, 0x3c, 0xbc, 0x30,
+ 0xd5, 0xf5, 0x00, 0xc1, 0x4f, 0x44, 0xa7, 0xd6, 0xef, 0x4a, 0xc6, 0x25, 0x27,
+ 0x1c, 0xe8, 0xd2, 0x96, 0x53, 0x0a, 0x5c, 0x91, 0xdd, 0xa2, 0xc2, 0x94, 0x84,
+ 0xbf, 0x7d, 0xb2, 0x44, 0x9f, 0x9b, 0xd2, 0xc1, 0x8a, 0xc5, 0xbe, 0x72, 0x5c,
+ 0xa7, 0xe7, 0x91, 0xe6, 0xd4, 0x9f, 0x73, 0x07, 0x85, 0x5b, 0x66, 0x48, 0xc7,
+ 0x70, 0xfa, 0xb4, 0xee, 0x02, 0xc9, 0x3d, 0x9a, 0x4a, 0xda, 0x3d, 0xc1, 0x46,
+ 0x3e, 0x19, 0x69, 0xd1, 0x17, 0x46, 0x07, 0xa3, 0x4d, 0x9f, 0x2b, 0x96, 0x17,
+ 0x39, 0x6d, 0x30, 0x8d, 0x2a, 0xf3, 0x94, 0xd3, 0x75, 0xcf, 0xa0, 0x75, 0xe6,
+ 0xf2, 0x92, 0x1f, 0x1a, 0x70, 0x05, 0xaa, 0x04, 0x83, 0x57, 0x30, 0xfb, 0xda,
+ 0x76, 0x93, 0x38, 0x50, 0xe8, 0x27, 0xfd, 0x63, 0xee, 0x3c, 0xe5, 0xb7, 0xc8,
+ 0x09, 0xae, 0x6f, 0x50, 0x35, 0x8e, 0x84, 0xce, 0x4a, 0x00, 0xe9, 0x12, 0x7e,
+ 0x5a, 0x31, 0xd7, 0x33, 0xfc, 0x21, 0x13, 0x76, 0xcc, 0x16, 0x30, 0xdb, 0x0c,
+ 0xfc, 0xc5, 0x62, 0xa7, 0x35, 0xb8, 0xef, 0xb7, 0xb0, 0xac, 0xc0, 0x36, 0xf6,
+ 0xd9, 0xc9, 0x46, 0x48, 0xf9, 0x40, 0x90, 0x00, 0x2b, 0x1b, 0xaa, 0x6c, 0xe3,
+ 0x1a, 0xc3, 0x0b, 0x03, 0x9e, 0x1b, 0xc2, 0x46, 0xe4, 0x48, 0x4e, 0x22, 0x73,
+ 0x6f, 0xc3, 0x5f, 0xd4, 0x9a, 0xd6, 0x30, 0x07, 0x48, 0xd6, 0x8c, 0x90, 0xab,
+ 0xd4, 0xf6, 0xf1, 0xe3, 0x48, 0xd3, 0x58, 0x4b, 0xa6, 0xb9, 0xcd, 0x29, 0xbf,
+ 0x68, 0x1f, 0x08, 0x4b, 0x63, 0x86, 0x2f, 0x5c, 0x6b, 0xd6, 0xb6, 0x06, 0x65,
+ 0xf7, 0xa6, 0xdc, 0x00, 0x67, 0x6b, 0xbb, 0xc3, 0xa9, 0x41, 0x83, 0xfb, 0xc7,
+ 0xfa, 0xc8, 0xe2, 0x1e, 0x7e, 0xaf, 0x00, 0x3f, 0x93
+};
+
+/* dh2048 g */
+static const unsigned char dhg[] =
+{
+ 0x02,
+};
+#endif /* !NO_WOLFSSL_SERVER */
+#endif /* !NO_DH */
+
+#ifdef HAVE_PTHREAD
+typedef struct {
+ unsigned char buf[MEM_BUFFER_SZ];
+ int write_bytes;
+ int write_idx;
+ int read_bytes;
+ int read_idx;
+
+ pthread_t tid;
+ pthread_mutex_t mutex;
+ pthread_cond_t cond;
+
+ int done;
+} memBuf_t;
+#endif
+
+typedef struct {
+ double connTime;
+ double rxTime;
+ double txTime;
+ int connCount;
+ int rxTotal;
+ int txTotal;
+} stats_t;
+
+typedef struct {
+ int shutdown;
+ int sockFd;
+ int ret;
+} side_t;
+
+typedef struct {
+ const char* cipher;
+ const char* host;
+ word32 port;
+ int packetSize; /* The data payload size in the packet */
+ int maxSize;
+ int runTimeSec;
+ int showPeerInfo;
+ int showVerbose;
+#ifndef NO_WOLFSSL_SERVER
+ int listenFd;
+#endif
+#ifdef WOLFSSL_DTLS
+ int doDTLS;
+ struct sockaddr_in serverAddr;
+ struct sockaddr_in clientAddr;
+#ifdef HAVE_PTHREAD
+ int serverReady;
+ int clientOrserverOnly;
+ pthread_mutex_t dtls_mutex;
+ pthread_cond_t dtls_cond;
+#endif
+#endif
+ side_t client;
+ side_t server;
+
+#ifdef HAVE_PTHREAD
+ int useLocalMem;
+
+ /* client messages to server in memory */
+ memBuf_t to_server;
+
+ /* server messages to client in memory */
+ memBuf_t to_client;
+#endif
+
+ /* server */
+ stats_t server_stats;
+
+ /* client */
+ stats_t client_stats;
+} info_t;
+
+/* Global vars for argument parsing */
+int myoptind = 0;
+char* myoptarg = NULL;
+
+#ifdef WOLFSSL_DTLS
+int DoneHandShake = 0;
+#endif
+
+static double gettime_secs(int reset)
+{
+ struct timeval tv;
+ gettimeofday(&tv, 0);
+ (void)reset;
+
+ return (double)tv.tv_sec + (double)tv.tv_usec / 1000000;
+}
+
+
+#ifdef HAVE_PTHREAD
+/* server send callback */
+static int ServerMemSend(info_t* info, char* buf, int sz)
+{
+ pthread_mutex_lock(&info->to_client.mutex);
+
+#ifndef BENCH_USE_NONBLOCK
+ /* check for overflow */
+ if (info->to_client.write_idx + sz > MEM_BUFFER_SZ) {
+ pthread_mutex_unlock(&info->to_client.mutex);
+ printf("ServerMemSend overflow\n");
+ return -1;
+ }
+#else
+ if (info->to_client.write_idx + sz > MEM_BUFFER_SZ)
+ sz = MEM_BUFFER_SZ - info->to_client.write_idx;
+#endif
+
+ XMEMCPY(&info->to_client.buf[info->to_client.write_idx], buf, sz);
+ info->to_client.write_idx += sz;
+ info->to_client.write_bytes += sz;
+
+ pthread_cond_signal(&info->to_client.cond);
+ pthread_mutex_unlock(&info->to_client.mutex);
+
+#ifdef BENCH_USE_NONBLOCK
+ if (sz == 0)
+ return WOLFSSL_CBIO_ERR_WANT_WRITE;
+#endif
+ return sz;
+}
+
+/* server recv callback */
+static int ServerMemRecv(info_t* info, char* buf, int sz)
+{
+ pthread_mutex_lock(&info->to_server.mutex);
+
+#ifndef BENCH_USE_NONBLOCK
+ while (info->to_server.write_idx - info->to_server.read_idx < sz && !info->to_client.done)
+ pthread_cond_wait(&info->to_server.cond, &info->to_server.mutex);
+#else
+ if (info->to_server.write_idx - info->to_server.read_idx < sz)
+ sz = info->to_server.write_idx - info->to_server.read_idx;
+#endif
+
+ XMEMCPY(buf, &info->to_server.buf[info->to_server.read_idx], sz);
+ info->to_server.read_idx += sz;
+ info->to_server.read_bytes += sz;
+
+ /* if the rx has caught up with pending then reset buffer positions */
+ if (info->to_server.read_bytes == info->to_server.write_bytes) {
+ info->to_server.read_bytes = info->to_server.read_idx = 0;
+ info->to_server.write_bytes = info->to_server.write_idx = 0;
+ }
+
+ pthread_mutex_unlock(&info->to_server.mutex);
+
+ if (info->to_client.done != 0)
+ return -1;
+
+#ifdef BENCH_USE_NONBLOCK
+ if (sz == 0)
+ return WOLFSSL_CBIO_ERR_WANT_READ;
+#endif
+ return sz;
+}
+
+/* client send callback */
+static int ClientMemSend(info_t* info, char* buf, int sz)
+{
+ pthread_mutex_lock(&info->to_server.mutex);
+
+#ifndef BENCH_USE_NONBLOCK
+ /* check for overflow */
+ if (info->to_client.write_idx + sz > MEM_BUFFER_SZ) {
+ printf("ClientMemSend overflow %d %d %d\n", info->to_client.write_idx, sz, MEM_BUFFER_SZ);
+ pthread_mutex_unlock(&info->to_server.mutex);
+ return -1;
+ }
+#else
+ if (info->to_server.write_idx + sz > MEM_BUFFER_SZ)
+ sz = MEM_BUFFER_SZ - info->to_server.write_idx;
+#endif
+
+ XMEMCPY(&info->to_server.buf[info->to_server.write_idx], buf, sz);
+ info->to_server.write_idx += sz;
+ info->to_server.write_bytes += sz;
+
+ pthread_cond_signal(&info->to_server.cond);
+ pthread_mutex_unlock(&info->to_server.mutex);
+
+#ifdef BENCH_USE_NONBLOCK
+ if (sz == 0)
+ return WOLFSSL_CBIO_ERR_WANT_WRITE;
+#endif
+ return sz;
+}
+
+/* client recv callback */
+static int ClientMemRecv(info_t* info, char* buf, int sz)
+{
+ pthread_mutex_lock(&info->to_client.mutex);
+
+#ifndef BENCH_USE_NONBLOCK
+ while (info->to_client.write_idx - info->to_client.read_idx < sz)
+ pthread_cond_wait(&info->to_client.cond, &info->to_client.mutex);
+#else
+ if (info->to_client.write_idx - info->to_client.read_idx < sz)
+ sz = info->to_client.write_idx - info->to_client.read_idx;
+#endif
+
+ XMEMCPY(buf, &info->to_client.buf[info->to_client.read_idx], sz);
+ info->to_client.read_idx += sz;
+ info->to_client.read_bytes += sz;
+
+ /* if the rx has caught up with pending then reset buffer positions */
+ if (info->to_client.read_bytes == info->to_client.write_bytes) {
+ info->to_client.read_bytes = info->to_client.read_idx = 0;
+ info->to_client.write_bytes = info->to_client.write_idx = 0;
+ }
+
+ pthread_mutex_unlock(&info->to_client.mutex);
+
+#ifdef BENCH_USE_NONBLOCK
+ if (sz == 0)
+ return WOLFSSL_CBIO_ERR_WANT_READ;
+#endif
+ return sz;
+}
+#endif /* HAVE_PTHREAD */
+
+static int SocketRecv(int sockFd, char* buf, int sz)
+{
+ int recvd = (int)recv(sockFd, buf, sz, 0);
+ if (recvd == -1) {
+ switch (errno) {
+ #if EAGAIN != SOCKET_EWOULDBLOCK
+ case EAGAIN: /* EAGAIN == EWOULDBLOCK on some systems, but not others */
+ #endif
+ case SOCKET_EWOULDBLOCK:
+ return WOLFSSL_CBIO_ERR_WANT_READ;
+ case SOCKET_ECONNRESET:
+ return WOLFSSL_CBIO_ERR_CONN_RST;
+ case SOCKET_EINTR:
+ return WOLFSSL_CBIO_ERR_ISR;
+ case SOCKET_ECONNREFUSED: /* DTLS case */
+ return WOLFSSL_CBIO_ERR_WANT_READ;
+ case SOCKET_ECONNABORTED:
+ return WOLFSSL_CBIO_ERR_CONN_CLOSE;
+ default:
+ return WOLFSSL_CBIO_ERR_GENERAL;
+ }
+ }
+ else if (recvd == 0) {
+ return WOLFSSL_CBIO_ERR_CONN_CLOSE;
+ }
+ return recvd;
+}
+
+static int SocketSend(int sockFd, char* buf, int sz)
+{
+ int sent = (int)send(sockFd, buf, sz, 0);
+ if (sent == -1) {
+ switch (errno) {
+ #if EAGAIN != SOCKET_EWOULDBLOCK
+ case EAGAIN: /* EAGAIN == EWOULDBLOCK on some systems, but not others */
+ #endif
+ case SOCKET_EWOULDBLOCK:
+ return WOLFSSL_CBIO_ERR_WANT_READ;
+ case SOCKET_ECONNRESET:
+ return WOLFSSL_CBIO_ERR_CONN_RST;
+ case SOCKET_EINTR:
+ return WOLFSSL_CBIO_ERR_ISR;
+ case SOCKET_EPIPE:
+ return WOLFSSL_CBIO_ERR_CONN_CLOSE;
+ default:
+ return WOLFSSL_CBIO_ERR_GENERAL;
+ }
+ }
+ else if (sent == 0) {
+ return 0;
+ }
+ return sent;
+}
+#if defined(WOLFSSL_DTLS) && !defined(NO_WOLFSSL_SERVER)
+static int ReceiveFrom(WOLFSSL *ssl, int sd, char *buf, int sz)
+{
+ int recvd;
+ int dtls_timeout = wolfSSL_dtls_get_current_timeout(ssl);
+ struct sockaddr peer;
+ socklen_t peerSz = 0;
+
+ if (DoneHandShake) dtls_timeout = 0;
+
+ if (!wolfSSL_get_using_nonblock(ssl)) {
+ struct timeval timeout;
+ XMEMSET(&timeout, 0, sizeof(timeout));
+ timeout.tv_sec = dtls_timeout;
+
+ if (setsockopt(sd, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout,
+ sizeof(timeout)) != 0) {
+ printf("setsockopt rcvtimeo failed\n");
+ }
+ }
+
+ recvd = (int)recvfrom(sd, buf, sz, 0, (SOCKADDR*)&peer, &peerSz);
+
+ if (recvd < 0) {
+
+ if (errno == SOCKET_EWOULDBLOCK || errno == SOCKET_EAGAIN) {
+ if (wolfSSL_dtls_get_using_nonblock(ssl)) {
+ return WOLFSSL_CBIO_ERR_WANT_READ;
+ }
+ else {
+ return WOLFSSL_CBIO_ERR_TIMEOUT;
+ }
+ }
+ else if (errno == SOCKET_ECONNRESET) {
+ return WOLFSSL_CBIO_ERR_CONN_RST;
+ }
+ else if (errno == SOCKET_EINTR) {
+ return WOLFSSL_CBIO_ERR_ISR;
+ }
+ else if (errno == SOCKET_ECONNREFUSED) {
+ return WOLFSSL_CBIO_ERR_WANT_READ;
+ }
+ else {
+ return WOLFSSL_CBIO_ERR_GENERAL;
+ }
+ }
+ else {
+ if (recvd == 0) {
+ return WOLFSSL_CBIO_ERR_CONN_CLOSE;
+ }
+ }
+
+ return recvd;
+}
+#endif /* WOLFSSL_DTLS && !NO_WOLFSSL_SERVER */
+
+#if defined(WOLFSSL_DTLS) && !defined(NO_WOLFSSL_CLIENT)
+static int SendTo(int sd, char *buf, int sz, const struct sockaddr *peer,
+ socklen_t peerSz)
+{
+ int sent;
+
+ sent = (int)sendto(sd, buf, sz, 0, peer, peerSz);
+
+ if (sent < 0) {
+ if (errno == SOCKET_EWOULDBLOCK || errno == SOCKET_EAGAIN) {
+ return WOLFSSL_CBIO_ERR_WANT_WRITE;
+ }
+ else if (errno == SOCKET_ECONNRESET) {
+ return WOLFSSL_CBIO_ERR_CONN_RST;
+ }
+ else if (errno == SOCKET_EINTR) {
+ return WOLFSSL_CBIO_ERR_ISR;
+ }
+ else if (errno == SOCKET_EPIPE) {
+ return WOLFSSL_CBIO_ERR_CONN_CLOSE;
+ }
+ else {
+ return WOLFSSL_CBIO_ERR_GENERAL;
+ }
+ }
+
+ return sent;
+}
+
+static int myDoneHsCb(WOLFSSL* ssl, void* user_ctx)
+{
+ (void) ssl;
+ (void) user_ctx;
+
+ DoneHandShake = 1;
+ return 1;
+}
+#endif /* WOLFSSL_DTLS && !NO_WOLFSSL_CLIENT */
+
+#ifndef NO_WOLFSSL_SERVER
+static int ServerSend(WOLFSSL* ssl, char* buf, int sz, void* ctx)
+{
+ info_t* info = (info_t*)ctx;
+ (void)ssl;
+#ifdef HAVE_PTHREAD
+ if (info->useLocalMem)
+ return ServerMemSend(info, buf, sz);
+#endif
+#if defined(WOLFSSL_DTLS) && !defined(NO_WOLFSSL_CLIENT)
+ if (info->doDTLS) {
+ return SendTo(info->server.sockFd, buf, sz,
+ (const struct sockaddr*)&info->clientAddr, sizeof(info->clientAddr));
+ } else
+#endif
+ return SocketSend(info->server.sockFd, buf, sz);
+}
+static int ServerRecv(WOLFSSL* ssl, char* buf, int sz, void* ctx)
+{
+ info_t* info = (info_t*)ctx;
+ (void)ssl;
+#ifdef HAVE_PTHREAD
+ if (info->useLocalMem)
+ return ServerMemRecv(info, buf, sz);
+#endif
+#ifdef WOLFSSL_DTLS
+ if (info->doDTLS) {
+ return ReceiveFrom(ssl, info->server.sockFd, buf, sz);
+ } else
+#endif
+ return SocketRecv(info->server.sockFd, buf, sz);
+}
+#endif /* !NO_WOLFSSL_SERVER */
+
+#ifndef NO_WOLFSSL_CLIENT
+static int ClientSend(WOLFSSL* ssl, char* buf, int sz, void* ctx)
+{
+ info_t* info = (info_t*)ctx;
+ (void)ssl;
+#ifdef HAVE_PTHREAD
+ if (info->useLocalMem)
+ return ClientMemSend(info, buf, sz);
+#endif
+#ifdef WOLFSSL_DTLS
+ if (info->doDTLS) {
+ return SendTo(info->client.sockFd, buf, sz,
+ (const struct sockaddr*)&info->serverAddr, sizeof(info->serverAddr));
+ } else
+#endif
+ return SocketSend(info->client.sockFd, buf, sz);
+}
+static int ClientRecv(WOLFSSL* ssl, char* buf, int sz, void* ctx)
+{
+ info_t* info = (info_t*)ctx;
+ (void)ssl;
+#ifdef HAVE_PTHREAD
+ if (info->useLocalMem)
+ return ClientMemRecv(info, buf, sz);
+#endif
+#if defined(WOLFSSL_DTLS) && !defined(NO_WOLFSSL_SERVER)
+ if (info->doDTLS) {
+ return ReceiveFrom(ssl, info->client.sockFd, buf, sz);
+ } else
+#endif
+ return SocketRecv(info->client.sockFd, buf, sz);
+}
+#endif /* !NO_WOLFSSL_CLIENT */
+
+static void CloseAndCleanupSocket(int* sockFd)
+{
+ if (*sockFd != -1) {
+ close(*sockFd);
+ *sockFd = -1;
+ }
+#ifdef WOLFSSL_DTLS
+ DoneHandShake = 0;
+#endif
+}
+
+#ifdef BENCH_USE_NONBLOCK
+static int SetSocketNonBlocking(int sockFd)
+{
+ int flags = fcntl(sockFd, F_GETFL, 0);
+ if (flags < 0) {
+ printf("fcntl get failed\n");
+ return -1;
+ }
+ flags = fcntl(sockFd, F_SETFL, flags | O_NONBLOCK);
+ if (flags < 0) {
+ printf("fcntl set failed\n");
+ return -1;
+ }
+ return 0;
+}
+#endif
+
+#ifndef NO_WOLFSSL_CLIENT
+static int SetupSocketAndConnect(info_t* info, const char* host,
+ word32 port)
+{
+ struct sockaddr_in servAddr;
+ struct hostent* entry;
+
+ /* Setup server address */
+ XMEMSET(&servAddr, 0, sizeof(servAddr));
+ servAddr.sin_family = AF_INET;
+ servAddr.sin_port = htons(port);
+
+ /* Resolve host */
+ entry = gethostbyname(host);
+ if (entry) {
+ XMEMCPY(&servAddr.sin_addr.s_addr, entry->h_addr_list[0],
+ entry->h_length);
+ }
+ else {
+ servAddr.sin_addr.s_addr = inet_addr(host);
+ }
+
+#ifdef WOLFSSL_DTLS
+ if (info->doDTLS) {
+ /* Create the SOCK_DGRAM socket type is implemented on the User
+ * Datagram Protocol/Internet Protocol(UDP/IP protocol).*/
+ if ((info->client.sockFd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
+ printf("ERROR: failed to create the SOCK_DGRAM socket\n");
+ return -1;
+ }
+ XMEMCPY(&info->serverAddr, &servAddr, sizeof(servAddr));
+ } else {
+#endif
+ /* Create a socket that uses an Internet IPv4 address,
+ * Sets the socket to be stream based (TCP),
+ * 0 means choose the default protocol. */
+ if ((info->client.sockFd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
+ printf("ERROR: failed to create the socket\n");
+ return -1;
+ }
+
+ /* Connect to the server */
+ if (connect(info->client.sockFd, (struct sockaddr*)&servAddr,
+ sizeof(servAddr)) == -1) {
+ printf("ERROR: failed to connect\n");
+ return -1;
+ }
+#ifdef WOLFSSL_DTLS
+ }
+#endif
+
+#ifdef BENCH_USE_NONBLOCK
+ if (SetSocketNonBlocking(info->client.sockFd) != 0) {
+ return -1;
+ }
+#endif
+
+ if (info->showVerbose) {
+ printf("Connected to %s on port %d\n", host, port);
+ }
+
+ return 0;
+}
+
+static int bench_tls_client(info_t* info)
+{
+ byte *writeBuf = NULL, *readBuf = NULL;
+ double start, total = 0;
+ int ret, readBufSz;
+ WOLFSSL_CTX* cli_ctx = NULL;
+ WOLFSSL* cli_ssl = NULL;
+ int haveShownPeerInfo = 0;
+ int tls13 = XSTRNCMP(info->cipher, "TLS13", 5) == 0;
+ int total_sz;
+
+ total = gettime_secs(0);
+
+ /* set up client */
+#ifdef WOLFSSL_DTLS
+ if(info->doDTLS) {
+ if (tls13) return WOLFSSL_SUCCESS;
+ cli_ctx = wolfSSL_CTX_new(wolfDTLSv1_2_client_method());
+ } else
+#endif
+#ifdef WOLFSSL_TLS13
+ if (tls13)
+ cli_ctx = wolfSSL_CTX_new(wolfTLSv1_3_client_method());
+#endif
+ if (!tls13)
+#ifdef WOLFSSL_DTLS
+ if(!info->doDTLS)
+#endif
+#if !defined(WOLFSSL_TLS13)
+ cli_ctx = wolfSSL_CTX_new(wolfSSLv23_client_method());
+#elif !defined(WOLFSSL_NO_TLS12)
+ cli_ctx = wolfSSL_CTX_new(wolfTLSv1_2_client_method());
+#endif
+
+ if (cli_ctx == NULL) {
+ printf("error creating ctx\n");
+ ret = MEMORY_E; goto exit;
+ }
+
+#ifndef NO_CERTS
+#ifdef HAVE_ECC
+ if (XSTRSTR(info->cipher, "ECDSA")) {
+ ret = wolfSSL_CTX_load_verify_buffer(cli_ctx, ca_ecc_cert_der_256,
+ sizeof_ca_ecc_cert_der_256, WOLFSSL_FILETYPE_ASN1);
+ }
+ else
+#endif
+ {
+ ret = wolfSSL_CTX_load_verify_buffer(cli_ctx, ca_cert_der_2048,
+ sizeof_ca_cert_der_2048, WOLFSSL_FILETYPE_ASN1);
+ }
+ if (ret != WOLFSSL_SUCCESS) {
+ printf("error loading CA\n");
+ goto exit;
+ }
+#endif
+
+ wolfSSL_CTX_SetIOSend(cli_ctx, ClientSend);
+ wolfSSL_CTX_SetIORecv(cli_ctx, ClientRecv);
+
+ /* set cipher suite */
+ ret = wolfSSL_CTX_set_cipher_list(cli_ctx, info->cipher);
+ if (ret != WOLFSSL_SUCCESS) {
+ printf("error setting cipher suite\n");
+ goto exit;
+ }
+
+#ifndef NO_DH
+ ret = wolfSSL_CTX_SetMinDhKey_Sz(cli_ctx, MIN_DHKEY_BITS);
+ if (ret != WOLFSSL_SUCCESS) {
+ printf("Error setting minimum DH key size\n");
+ goto exit;
+ }
+#endif
+
+ /* Allocate and initialize a packet sized buffer */
+ writeBuf = (unsigned char*)XMALLOC(info->packetSize, NULL,
+ DYNAMIC_TYPE_TMP_BUFFER);
+ if (writeBuf == NULL) {
+ printf("failed to allocate write memory\n");
+ ret = MEMORY_E; goto exit;
+ }
+
+ /* Allocate read buffer */
+ readBufSz = info->packetSize;
+ readBuf = (unsigned char*)XMALLOC(readBufSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+ if (readBuf == NULL) {
+ printf("failed to allocate read memory\n");
+ ret = MEMORY_E; goto exit;
+ }
+
+ /* BENCHMARK CONNECTIONS LOOP */
+ while (!info->client.shutdown) {
+ int writeSz = info->packetSize;
+ #ifdef BENCH_USE_NONBLOCK
+ int err;
+ #endif
+
+ #ifdef HAVE_PTHREAD
+ if (!info->useLocalMem)
+ #endif
+ {
+ /* Setup socket and connection */
+ ret = SetupSocketAndConnect(info, info->host, info->port);
+ if (ret != 0) goto exit;
+ }
+
+ cli_ssl = wolfSSL_new(cli_ctx);
+ if (cli_ssl == NULL) {
+ printf("error creating client object\n");
+ goto exit;
+ }
+
+#ifdef WOLFSSL_DTLS
+ if (info->doDTLS) {
+ ret = wolfSSL_dtls_set_peer(cli_ssl, &info->serverAddr,
+ sizeof(info->serverAddr));
+ if (ret != WOLFSSL_SUCCESS) {
+ printf("error setting dtls peer\n");
+ goto exit;
+ }
+ ret = wolfSSL_SetHsDoneCb(cli_ssl, myDoneHsCb, NULL);
+ if (ret != WOLFSSL_SUCCESS) {
+ printf("error handshake done callback\n");
+ goto exit;
+ }
+ }
+#endif
+ wolfSSL_SetIOReadCtx(cli_ssl, info);
+ wolfSSL_SetIOWriteCtx(cli_ssl, info);
+
+#if defined(HAVE_PTHREAD) && defined(WOLFSSL_DTLS)
+ /* synchronize with server */
+ if (info->doDTLS && !info->clientOrserverOnly) {
+ pthread_mutex_lock(&info->dtls_mutex);
+ if (info->serverReady != 1) {
+ pthread_cond_wait(&info->dtls_cond, &info->dtls_mutex);
+ }
+ /* for next loop */
+ info->serverReady = 0;
+ pthread_mutex_unlock(&info->dtls_mutex);
+ }
+#endif
+ /* perform connect */
+ start = gettime_secs(1);
+ #ifndef BENCH_USE_NONBLOCK
+ ret = wolfSSL_connect(cli_ssl);
+ #else
+ do
+ {
+ ret = wolfSSL_connect(cli_ssl);
+ err = wolfSSL_get_error(cli_ssl, ret);
+ }
+ while (err == WOLFSSL_ERROR_WANT_READ || err == WOLFSSL_ERROR_WANT_WRITE);
+ #endif
+ start = gettime_secs(0) - start;
+ if (ret != WOLFSSL_SUCCESS) {
+ printf("error connecting client\n");
+ ret = wolfSSL_get_error(cli_ssl, ret);
+ goto exit;
+ }
+ info->client_stats.connTime += start;
+ info->client_stats.connCount++;
+
+ if ((info->showPeerInfo) && (!haveShownPeerInfo)) {
+ haveShownPeerInfo = 1;
+ showPeer(cli_ssl);
+ }
+
+ /* check for run time completion and issue shutdown */
+ if (gettime_secs(0) - total >= info->runTimeSec) {
+ info->client.shutdown = 1;
+
+ writeSz = (int)XSTRLEN(kShutdown) + 1;
+ XMEMCPY(writeBuf, kShutdown, writeSz); /* include null term */
+ if (info->showVerbose) {
+ printf("Sending shutdown\n");
+ }
+
+ ret = wolfSSL_write(cli_ssl, writeBuf, writeSz);
+ if (ret < 0) {
+ printf("error on client write\n");
+ ret = wolfSSL_get_error(cli_ssl, ret);
+ goto exit;
+ }
+ }
+ else {
+ XMEMSET(writeBuf, 0, info->packetSize);
+ XSTRNCPY((char*)writeBuf, kTestStr, info->packetSize);
+ }
+
+ /* write / read echo loop */
+ ret = 0;
+ total_sz = 0;
+ while (ret == 0 && total_sz < info->maxSize && !info->client.shutdown) {
+ /* write test message to server */
+ start = gettime_secs(1);
+ #ifndef BENCH_USE_NONBLOCK
+ ret = wolfSSL_write(cli_ssl, writeBuf, writeSz);
+ #else
+ do {
+ ret = wolfSSL_write(cli_ssl, writeBuf, writeSz);
+ err = wolfSSL_get_error(cli_ssl, ret);
+ }
+ while (err == WOLFSSL_ERROR_WANT_WRITE);
+ #endif
+ info->client_stats.txTime += gettime_secs(0) - start;
+ if (ret < 0) {
+ printf("error on client write\n");
+ ret = wolfSSL_get_error(cli_ssl, ret);
+ goto exit;
+ }
+ info->client_stats.txTotal += ret;
+ total_sz += ret;
+
+ /* read echo of message from server */
+ XMEMSET(readBuf, 0, readBufSz);
+ start = gettime_secs(1);
+ #ifndef BENCH_USE_NONBLOCK
+ ret = wolfSSL_read(cli_ssl, readBuf, readBufSz);
+ #else
+ do {
+ ret = wolfSSL_read(cli_ssl, readBuf, readBufSz);
+ err = wolfSSL_get_error(cli_ssl, ret);
+ }
+ while (err == WOLFSSL_ERROR_WANT_READ);
+ #endif
+ info->client_stats.rxTime += gettime_secs(0) - start;
+ if (ret < 0) {
+ printf("error on client read\n");
+ ret = wolfSSL_get_error(cli_ssl, ret);
+ goto exit;
+ }
+ info->client_stats.rxTotal += ret;
+ ret = 0; /* reset return code */
+
+ /* validate echo */
+ if (XMEMCMP((char*)writeBuf, (char*)readBuf, writeSz) != 0) {
+ printf("echo check failed!\n");
+ ret = wolfSSL_get_error(cli_ssl, ret);
+ goto exit;
+ }
+ }
+
+ CloseAndCleanupSocket(&info->client.sockFd);
+
+ wolfSSL_free(cli_ssl);
+ cli_ssl = NULL;
+ }
+
+exit:
+
+ if (ret != 0 && ret != WOLFSSL_SUCCESS) {
+ printf("Client Error: %d (%s)\n", ret,
+ wolfSSL_ERR_reason_error_string(ret));
+ }
+
+ /* clean up */
+ CloseAndCleanupSocket(&info->client.sockFd);
+ if (cli_ssl != NULL)
+ wolfSSL_free(cli_ssl);
+ if (cli_ctx != NULL)
+ wolfSSL_CTX_free(cli_ctx);
+ XFREE(readBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+ XFREE(writeBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+ info->client.ret = ret;
+
+ return ret;
+}
+
+#ifdef HAVE_PTHREAD
+static void* client_thread(void* args)
+{
+ int ret;
+ info_t* info = (info_t*)args;
+
+ ret = bench_tls_client(info);
+
+ pthread_cond_signal(&info->to_server.cond);
+ info->to_client.done = 1;
+ info->client.ret = ret;
+
+ return NULL;
+}
+#endif /* HAVE_PTHREAD */
+#endif /* !NO_WOLFSSL_CLIENT */
+
+
+#ifndef NO_WOLFSSL_SERVER
+static int SetupSocketAndListen(int* listenFd, word32 port, int doDTLS)
+{
+ struct sockaddr_in servAddr;
+#if defined(_MSC_VER) || defined(__MINGW32__)
+ char optval = 1;
+#else
+ int optval = 1;
+#endif
+#ifndef WOLFSSL_DTLS
+ (void) doDTLS;
+#endif
+ /* Setup server address */
+ XMEMSET(&servAddr, 0, sizeof(servAddr));
+ servAddr.sin_family = AF_INET;
+ servAddr.sin_port = htons(port);
+ servAddr.sin_addr.s_addr = INADDR_ANY;
+
+#ifdef WOLFSSL_DTLS
+ if (doDTLS) {
+ /* Create a socket that is implemented on the User Datagram Protocol/
+ * Interet Protocol(UDP/IP protocol). */
+ if((*listenFd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
+ printf("ERROR: failed to create the socket\n");
+ return -1;
+ }
+ } else
+#endif
+ /* Create a socket that uses an Internet IPv4 address,
+ * Sets the socket to be stream based (TCP),
+ * 0 means choose the default protocol. */
+ if ((*listenFd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
+ printf("ERROR: failed to create the socket\n");
+ return -1;
+ }
+
+ /* allow reuse */
+ if (setsockopt(*listenFd, SOL_SOCKET, SO_REUSEADDR,
+ &optval, sizeof(optval)) == -1) {
+ printf("setsockopt SO_REUSEADDR failed\n");
+ return -1;
+ }
+
+ /* Connect to the server */
+ if (bind(*listenFd, (struct sockaddr*)&servAddr,
+ sizeof(servAddr)) == -1) {
+ printf("ERROR: failed to bind\n");
+ return -1;
+ }
+#ifdef WOLFSSL_DTLS
+ if (!doDTLS)
+#endif
+ if (listen(*listenFd, 5) != 0) {
+ printf("ERROR: failed to listen\n");
+ return -1;
+ }
+
+#ifdef BENCH_USE_NONBLOCK
+ if (SetSocketNonBlocking(*listenFd) != 0) {
+ return -1;
+ }
+#endif
+
+ return 0;
+}
+
+static int SocketWaitClient(info_t* info)
+{
+ int connd;
+ struct sockaddr_in clientAddr;
+ socklen_t size = sizeof(clientAddr);
+#ifdef WOLFSSL_DTLS
+ char msg[64];
+
+ if (info->doDTLS) {
+#ifdef HAVE_PTHREAD
+ if (!info->clientOrserverOnly) {
+ pthread_mutex_lock(&info->dtls_mutex);
+ info->serverReady = 1;
+ pthread_cond_signal(&info->dtls_cond);
+ pthread_mutex_unlock(&info->dtls_mutex);
+ }
+#endif
+ connd = (int)recvfrom(info->listenFd, (char *)msg, sizeof(msg),
+ MSG_PEEK, (struct sockaddr*)&clientAddr, &size);
+ if (connd < -1) {
+ printf("ERROR: failed to accept the connection\n");
+ return -1;
+ }
+ XMEMCPY(&info->clientAddr, &clientAddr, sizeof(clientAddr));
+ info->server.sockFd = info->listenFd;
+ } else {
+#endif
+ if ((connd = accept(info->listenFd, (struct sockaddr*)&clientAddr, &size)) == -1) {
+ if (errno == SOCKET_EWOULDBLOCK)
+ return -2;
+ printf("ERROR: failed to accept the connection\n");
+ return -1;
+ }
+ info->server.sockFd = connd;
+#ifdef WOLFSSL_DTLS
+ }
+#endif
+
+ if (info->showVerbose) {
+ printf("Got client %d\n", connd);
+ }
+
+ return 0;
+}
+static void CloseAndCleanupListenSocket(int* listenFd)
+{
+ if (*listenFd != -1) {
+ close(*listenFd);
+ *listenFd = -1;
+ }
+}
+
+static int bench_tls_server(info_t* info)
+{
+ byte *readBuf = NULL;
+ double start;
+ int ret, len = 0, readBufSz;
+ WOLFSSL_CTX* srv_ctx = NULL;
+ WOLFSSL* srv_ssl = NULL;
+ int tls13 = XSTRNCMP(info->cipher, "TLS13", 5) == 0;
+ int total_sz;
+
+ /* set up server */
+#ifdef WOLFSSL_DTLS
+ if(info->doDTLS) {
+ if(tls13) return WOLFSSL_SUCCESS;
+ srv_ctx = wolfSSL_CTX_new(wolfDTLSv1_2_server_method());
+ } else {
+#endif
+#ifdef WOLFSSL_TLS13
+ if (tls13)
+ srv_ctx = wolfSSL_CTX_new(wolfTLSv1_3_server_method());
+#endif
+ if (!tls13)
+ srv_ctx = wolfSSL_CTX_new(wolfSSLv23_server_method());
+#ifdef WOLFSSL_DTLS
+ }
+#endif
+ if (srv_ctx == NULL) {
+ printf("error creating server ctx\n");
+ ret = MEMORY_E; goto exit;
+ }
+
+#ifndef NO_CERTS
+#ifdef HAVE_ECC
+ if (XSTRSTR(info->cipher, "ECDSA")) {
+ ret = wolfSSL_CTX_use_PrivateKey_buffer(srv_ctx, ecc_key_der_256,
+ sizeof_ecc_key_der_256, WOLFSSL_FILETYPE_ASN1);
+ }
+ else
+#endif
+ {
+ ret = wolfSSL_CTX_use_PrivateKey_buffer(srv_ctx, server_key_der_2048,
+ sizeof_server_key_der_2048, WOLFSSL_FILETYPE_ASN1);
+ }
+ if (ret != WOLFSSL_SUCCESS) {
+ printf("error loading server key\n");
+ goto exit;
+ }
+
+#ifdef HAVE_ECC
+ if (XSTRSTR(info->cipher, "ECDSA")) {
+ ret = wolfSSL_CTX_use_certificate_buffer(srv_ctx, serv_ecc_der_256,
+ sizeof_serv_ecc_der_256, WOLFSSL_FILETYPE_ASN1);
+ }
+ else
+#endif
+ {
+ ret = wolfSSL_CTX_use_certificate_buffer(srv_ctx, server_cert_der_2048,
+ sizeof_server_cert_der_2048, WOLFSSL_FILETYPE_ASN1);
+ }
+ if (ret != WOLFSSL_SUCCESS) {
+ printf("error loading server cert\n");
+ goto exit;
+ }
+#endif /* !NO_CERTS */
+
+ wolfSSL_CTX_SetIOSend(srv_ctx, ServerSend);
+ wolfSSL_CTX_SetIORecv(srv_ctx, ServerRecv);
+
+ /* set cipher suite */
+ ret = wolfSSL_CTX_set_cipher_list(srv_ctx, info->cipher);
+ if (ret != WOLFSSL_SUCCESS) {
+ printf("error setting cipher suite\n");
+ goto exit;
+ }
+
+#ifndef NO_DH
+ ret = wolfSSL_CTX_SetMinDhKey_Sz(srv_ctx, MIN_DHKEY_BITS);
+ if (ret != WOLFSSL_SUCCESS) {
+ printf("Error setting minimum DH key size\n");
+ goto exit;
+ }
+#endif
+
+ /* Allocate read buffer */
+ readBufSz = info->packetSize;
+ readBuf = (unsigned char*)XMALLOC(readBufSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+ if (readBuf == NULL) {
+ printf("failed to allocate read memory\n");
+ ret = MEMORY_E; goto exit;
+ }
+
+ /* BENCHMARK CONNECTIONS LOOP */
+ while (!info->server.shutdown) {
+ #ifdef BENCH_USE_NONBLOCK
+ int err;
+ #endif
+
+ #ifdef HAVE_PTHREAD
+ if (!info->useLocalMem)
+ #endif
+ {
+ /* Accept client connections */
+ ret = SocketWaitClient(info);
+ #ifdef BENCH_USE_NONBLOCK
+ if (ret == -2) {
+ XSLEEP_MS(0);
+ continue;
+ }
+ #endif
+ if (ret != 0) {
+ goto exit;
+ }
+ }
+
+ srv_ssl = wolfSSL_new(srv_ctx);
+ if (srv_ssl == NULL) {
+ printf("error creating server object\n");
+ ret = MEMORY_E; goto exit;
+ }
+#ifdef WOLFSSL_DTLS
+ if (info->doDTLS) {
+ ret = wolfSSL_dtls_set_peer(srv_ssl, &info->clientAddr,
+ sizeof(info->clientAddr));
+ if (ret != WOLFSSL_SUCCESS) {
+ printf("error setting dtls peer\n");
+ goto exit;
+ }
+ }
+#endif
+
+ wolfSSL_SetIOReadCtx(srv_ssl, info);
+ wolfSSL_SetIOWriteCtx(srv_ssl, info);
+ #ifndef NO_DH
+ wolfSSL_SetTmpDH(srv_ssl, dhp, sizeof(dhp), dhg, sizeof(dhg));
+ #endif
+
+ /* accept TLS connection */
+ start = gettime_secs(1);
+ #ifndef BENCH_USE_NONBLOCK
+ ret = wolfSSL_accept(srv_ssl);
+ #else
+ do {
+ ret = wolfSSL_accept(srv_ssl);
+ err = wolfSSL_get_error(srv_ssl, ret);
+ }
+ while (err == WOLFSSL_ERROR_WANT_READ || err == WOLFSSL_ERROR_WANT_WRITE);
+ #endif
+ start = gettime_secs(0) - start;
+ if (ret != WOLFSSL_SUCCESS) {
+ printf("error on server accept\n");
+ ret = wolfSSL_get_error(srv_ssl, ret);
+ goto exit;
+ }
+
+ info->server_stats.connTime += start;
+ info->server_stats.connCount++;
+
+ /* echo loop */
+ ret = 0;
+ total_sz = 0;
+ while (ret == 0 && total_sz < info->maxSize) {
+ double rxTime;
+
+ /* read message from client */
+ XMEMSET(readBuf, 0, readBufSz);
+ start = gettime_secs(1);
+ #ifndef BENCH_USE_NONBLOCK
+ ret = wolfSSL_read(srv_ssl, readBuf, readBufSz);
+ #else
+ do {
+ ret = wolfSSL_read(srv_ssl, readBuf, readBufSz);
+ err = wolfSSL_get_error(srv_ssl, ret);
+ }
+ while (err == WOLFSSL_ERROR_WANT_READ);
+ #endif
+ rxTime = gettime_secs(0) - start;
+
+ /* shutdown signals, no more connections for this cipher */
+ if (XSTRSTR((const char*)readBuf, kShutdown) != NULL) {
+ info->server.shutdown = 1;
+ if (info->showVerbose) {
+ printf("Server shutdown done\n");
+ }
+ ret = 0; /* success */
+ break;
+ }
+
+ info->server_stats.rxTime += rxTime;
+ if (ret < 0) {
+ printf("error on server read\n");
+ ret = wolfSSL_get_error(srv_ssl, ret);
+ goto exit;
+ }
+ info->server_stats.rxTotal += ret;
+ len = ret;
+ total_sz += ret;
+
+ /* write message back to client */
+ start = gettime_secs(1);
+ #ifndef BENCH_USE_NONBLOCK
+ ret = wolfSSL_write(srv_ssl, readBuf, len);
+ #else
+ do {
+ ret = wolfSSL_write(srv_ssl, readBuf, len);
+ err = wolfSSL_get_error(srv_ssl, ret);
+ }
+ while (err == WOLFSSL_ERROR_WANT_WRITE);
+ #endif
+ info->server_stats.txTime += gettime_secs(0) - start;
+ if (ret < 0) {
+ printf("error on server write\n");
+ ret = wolfSSL_get_error(srv_ssl, ret);
+ goto exit;
+ }
+ info->server_stats.txTotal += ret;
+ ret = 0; /* reset return code */
+ }
+
+ CloseAndCleanupSocket(&info->server.sockFd);
+
+ wolfSSL_free(srv_ssl);
+ srv_ssl = NULL;
+#ifdef WOLFSSL_DTLS
+ if (info->doDTLS) {
+ SetupSocketAndListen(&info->listenFd, info->port, info->doDTLS);
+ }
+#endif
+
+ }
+
+exit:
+
+ if (ret != 0 && ret != WOLFSSL_SUCCESS) {
+ printf("Server Error: %d (%s)\n", ret,
+ wolfSSL_ERR_reason_error_string(ret));
+ }
+
+ /* clean up */
+ CloseAndCleanupSocket(&info->server.sockFd);
+ if (srv_ssl != NULL)
+ wolfSSL_free(srv_ssl);
+ if (srv_ctx != NULL)
+ wolfSSL_CTX_free(srv_ctx);
+ XFREE(readBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+ info->server.ret = ret;
+
+ return ret;
+}
+
+#ifdef HAVE_PTHREAD
+static void* server_thread(void* args)
+{
+ int ret = 0;
+ info_t* info = (info_t*)args;
+
+ if (!info->useLocalMem) {
+ /* Setup TLS server listener */
+#ifdef WOLFSSL_DTLS
+ ret = SetupSocketAndListen(&info->listenFd, info->port, info->doDTLS);
+#else
+ ret = SetupSocketAndListen(&info->listenFd, info->port, 0);
+#endif
+ }
+ if (ret == 0) {
+ ret = bench_tls_server(info);
+
+ if (!info->useLocalMem) {
+ CloseAndCleanupListenSocket(&info->listenFd);
+ }
+ }
+
+ pthread_cond_signal(&info->to_client.cond);
+ info->to_server.done = 1;
+ info->server.ret = ret;
+
+ return NULL;
+}
+#endif /* HAVE_PTHREAD */
+#endif /* !NO_WOLFSSL_SERVER */
+
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wformat-nonliteral"
+#endif
+static void print_stats(stats_t* wcStat, const char* desc, const char* cipher, int verbose)
+{
+ const char* formatStr;
+
+ if (verbose) {
+ formatStr = "wolfSSL %s Benchmark on %s:\n"
+ "\tTotal : %9d bytes\n"
+ "\tNum Conns : %9d\n"
+ "\tRx Total : %9.3f ms\n"
+ "\tTx Total : %9.3f ms\n"
+ "\tRx : %9.3f MB/s\n"
+ "\tTx : %9.3f MB/s\n"
+ "\tConnect : %9.3f ms\n"
+ "\tConnect Avg : %9.3f ms\n";
+ }
+ else {
+ formatStr = "%-6s %-33s %11d %9d %9.3f %9.3f %9.3f %9.3f %17.3f %15.3f\n";
+ }
+
+ printf(formatStr,
+ desc,
+ cipher,
+ wcStat->txTotal + wcStat->rxTotal,
+ wcStat->connCount,
+ wcStat->rxTime * 1000,
+ wcStat->txTime * 1000,
+ wcStat->rxTotal / wcStat->rxTime / 1024 / 1024,
+ wcStat->txTotal / wcStat->txTime / 1024 / 1024,
+ wcStat->connTime * 1000,
+ wcStat->connTime * 1000 / wcStat->connCount);
+}
+
+static void Usage(void)
+{
+ printf("tls_bench " LIBWOLFSSL_VERSION_STRING
+ " NOTE: All files relative to wolfSSL home dir\n");
+ printf("-? Help, print this usage\n");
+ printf("-c Run as client only, no threading and uses sockets\n");
+ printf("-s Run as server only, no threading and uses sockets\n");
+ printf("-h Host (default %s)\n", BENCH_DEFAULT_HOST);
+ printf("-P Port (default %d)\n", BENCH_DEFAULT_PORT);
+ printf("-e List Every cipher suite available\n");
+ printf("-i Show peer info\n");
+ printf("-l <str> Cipher suite list (: delimited)\n");
+ printf("-t <num> Time <num> (seconds) to run each test (default %d)\n", BENCH_RUNTIME_SEC);
+ printf("-p <num> The packet size <num> in bytes [1-16kB] (default %d)\n", TEST_PACKET_SIZE);
+#ifdef WOLFSSL_DTLS
+ printf(" In the case of DTLS, [1-8kB] (default %d)\n", TEST_DTLS_PACKET_SIZE);
+#endif
+ printf("-S <num> The total size <num> in bytes (default %d)\n", TEST_MAX_SIZE);
+ printf("-v Show verbose output\n");
+#ifdef DEBUG_WOLFSSL
+ printf("-d Enable debug messages\n");
+#endif
+#ifdef HAVE_PTHREAD
+ printf("-T <num> Number of threaded server/client pairs (default %d)\n", NUM_THREAD_PAIRS);
+ printf("-m Use local memory, not socket\n");
+#endif
+#ifdef WOLFSSL_DTLS
+ printf("-u Use DTLS\n");
+#endif
+}
+
+static void ShowCiphers(void)
+{
+ char ciphers[WOLFSSL_CIPHER_LIST_MAX_SIZE];
+
+ int ret = wolfSSL_get_ciphers(ciphers, (int)sizeof(ciphers));
+
+ if (ret == WOLFSSL_SUCCESS)
+ printf("%s\n", ciphers);
+}
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
+
+int bench_tls(void* args)
+{
+ int ret = 0;
+ info_t *theadInfo = NULL, *info;
+ stats_t cli_comb, srv_comb;
+ int i;
+ char *cipher, *next_cipher, *ciphers = NULL;
+ int argc = 0;
+ char** argv = NULL;
+ int ch;
+
+ /* Vars configured by command line arguments */
+ int argRuntimeSec = BENCH_RUNTIME_SEC;
+ char *argCipherList = NULL;
+ int argTestPacketSize = TEST_PACKET_SIZE;
+ int argTestMaxSize = TEST_MAX_SIZE;
+ int argThreadPairs = NUM_THREAD_PAIRS;
+ int argShowVerbose = SHOW_VERBOSE;
+ int argClientOnly = 0;
+ int argServerOnly = 0;
+ const char* argHost = BENCH_DEFAULT_HOST;
+ int argPort = BENCH_DEFAULT_PORT;
+ int argShowPeerInfo = 0;
+#ifdef HAVE_PTHREAD
+ int doShutdown;
+#endif
+#if !defined(NO_WOLFSSL_SERVER) || defined(HAVE_PTHREAD)
+ int argLocalMem = 0;
+ int listenFd = -1;
+#endif
+#if defined(WOLFSSL_DTLS) && !defined(NO_WOLFSSL_SERVER)
+ int option_p = 0;
+#endif
+#ifdef WOLFSSL_DTLS
+ int doDTLS = 0;
+#endif
+ if (args != NULL) {
+ argc = ((func_args*)args)->argc;
+ argv = ((func_args*)args)->argv;
+ ((func_args*)args)->return_code = -1; /* error state */
+ }
+
+ /* Initialize wolfSSL */
+ wolfSSL_Init();
+
+ /* Parse command line arguments */
+ while ((ch = mygetopt(argc, argv, "?" "udeil:p:t:vT:sch:P:mS:")) != -1) {
+ switch (ch) {
+ case '?' :
+ Usage();
+ goto exit;
+
+ case 's':
+ argServerOnly = 1;
+ break;
+
+ case 'c':
+ argClientOnly = 1;
+ break;
+
+ case 'h':
+ argHost = myoptarg;
+ break;
+
+ case 'P':
+ argPort = atoi(myoptarg);
+ break;
+
+ case 'd' :
+ #ifdef DEBUG_WOLFSSL
+ wolfSSL_Debugging_ON();
+ #endif
+ break;
+
+ case 'e' :
+ ShowCiphers();
+ goto exit;
+
+ case 'i' :
+ argShowPeerInfo = 1;
+ break;
+
+ case 'l' :
+ argCipherList = myoptarg;
+ break;
+
+ case 'p' :
+ argTestPacketSize = atoi(myoptarg);
+ if (argTestPacketSize > (16 * 1024)) {
+ printf("Invalid packet size %d\n", argTestPacketSize);
+ Usage();
+ ret = MY_EX_USAGE; goto exit;
+ }
+ #if defined(WOLFSSL_DTLS) && !defined(NO_WOLFSSL_SERVER)
+ option_p = 1;
+ #endif
+ break;
+
+ case 'S' :
+ argTestMaxSize = atoi(myoptarg);
+ break;
+
+ case 't' :
+ argRuntimeSec = atoi(myoptarg);
+ break;
+
+ case 'v' :
+ argShowVerbose = 1;
+ break;
+
+ case 'T' :
+ #ifdef HAVE_PTHREAD
+ argThreadPairs = atoi(myoptarg);
+ #endif
+ break;
+
+ case 'm':
+ #ifdef HAVE_PTHREAD
+ argLocalMem = 1;
+ #endif
+ break;
+ case 'u':
+ #ifdef WOLFSSL_DTLS
+ doDTLS = 1;
+ #ifdef BENCH_USE_NONBLOCK
+ printf("tls_bench hasn't yet supported DTLS "
+ "non-blocking mode.\n");
+ Usage();
+ ret = MY_EX_USAGE; goto exit;
+ #endif
+ #endif
+ break;
+ default:
+ Usage();
+ ret = MY_EX_USAGE; goto exit;
+ }
+ }
+
+ /* reset for test cases */
+ myoptind = 0;
+
+ if (argCipherList != NULL) {
+ /* Use the list from CL argument */
+ cipher = argCipherList;
+ }
+ else {
+ /* Run for each cipher */
+ ciphers = (char*)XMALLOC(WOLFSSL_CIPHER_LIST_MAX_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+ if (ciphers == NULL) {
+ goto exit;
+ }
+ wolfSSL_get_ciphers(ciphers, WOLFSSL_CIPHER_LIST_MAX_SIZE);
+ cipher = ciphers;
+ }
+
+ /* for server or client side only, only 1 thread is allowed */
+ if (argServerOnly || argClientOnly) {
+ argThreadPairs = 1;
+ }
+#ifndef HAVE_PTHREAD
+ else {
+ printf("Threading is not enabled, so please use -s or -c to indicate side\n");
+ Usage();
+ ret = MY_EX_USAGE; goto exit;
+ }
+#endif
+
+ /* Allocate test info array */
+ theadInfo = (info_t*)XMALLOC(sizeof(info_t) * argThreadPairs, NULL,
+ DYNAMIC_TYPE_TMP_BUFFER);
+ if (theadInfo == NULL) {
+ ret = MEMORY_E; goto exit;
+ }
+ XMEMSET(theadInfo, 0, sizeof(info_t) * argThreadPairs);
+
+#ifndef NO_WOLFSSL_SERVER
+ /* Use same listen socket to avoid timing issues between client and server */
+ if (argServerOnly && !argLocalMem) {
+ /* Setup TLS server listener */
+#ifdef WOLFSSL_DTLS
+ ret = SetupSocketAndListen(&listenFd, argPort, doDTLS);
+#else
+ ret = SetupSocketAndListen(&listenFd, argPort, 0);
+#endif
+ if (ret != 0) goto exit;
+ }
+#endif
+
+#if defined(WOLFSSL_DTLS) && !defined(NO_WOLFSSL_SERVER)
+ if (doDTLS) {
+ if (argLocalMem) {
+ printf("tls_bench hasn't yet supported DTLS with local memory.\n");
+ ret = MY_EX_USAGE; goto exit;
+ }
+ if (option_p && argTestPacketSize > TEST_DTLS_PACKET_SIZE){
+ printf("Invalid packet size %d\n", argTestPacketSize);
+ Usage();
+ ret = MY_EX_USAGE; goto exit;
+ } else {
+ /* argTestPacketSize would be default for tcp packet */
+ if (argTestPacketSize >= TEST_PACKET_SIZE)
+ argTestPacketSize = TEST_DTLS_PACKET_SIZE;
+ }
+ }
+#endif
+ printf("Running TLS Benchmarks...\n");
+
+ /* parse by : */
+ while ((cipher != NULL) && (cipher[0] != '\0')) {
+ next_cipher = strchr(cipher, ':');
+ if (next_cipher != NULL) {
+ cipher[next_cipher - cipher] = '\0';
+ }
+
+ if (argShowVerbose) {
+ printf("Cipher: %s\n", cipher);
+ }
+
+ for (i=0; i<argThreadPairs; i++) {
+ info = &theadInfo[i];
+ XMEMSET(info, 0, sizeof(info_t));
+
+ info->host = argHost;
+ info->port = argPort + i; /* threads must have separate ports */
+ info->cipher = cipher;
+ info->packetSize = argTestPacketSize;
+
+ info->runTimeSec = argRuntimeSec;
+ info->maxSize = argTestMaxSize;
+ info->showPeerInfo = argShowPeerInfo;
+ info->showVerbose = argShowVerbose;
+ #ifndef NO_WOLFSSL_SERVER
+ info->listenFd = listenFd;
+ #endif
+ info->client.sockFd = -1;
+ info->server.sockFd = -1;
+
+ #ifdef WOLFSSL_DTLS
+ info->doDTLS = doDTLS;
+ #ifdef HAVE_PTHREAD
+ info->serverReady = 0;
+ if (argServerOnly || argClientOnly) {
+ info->clientOrserverOnly = 1;
+ }
+ #endif
+ #endif
+ if (argClientOnly) {
+ #ifndef NO_WOLFSSL_CLIENT
+ ret = bench_tls_client(info);
+ #endif
+ }
+ else if (argServerOnly) {
+ #ifndef NO_WOLFSSL_SERVER
+ ret = bench_tls_server(info);
+ #endif
+ }
+ else {
+ #ifdef HAVE_PTHREAD
+ info->useLocalMem = argLocalMem;
+ pthread_mutex_init(&info->to_server.mutex, NULL);
+ pthread_mutex_init(&info->to_client.mutex, NULL);
+ #ifdef WOLFSSL_DTLS
+ pthread_mutex_init(&info->dtls_mutex, NULL);
+ pthread_cond_init(&info->dtls_cond, NULL);
+ #endif
+ pthread_cond_init(&info->to_server.cond, NULL);
+ pthread_cond_init(&info->to_client.cond, NULL);
+
+ pthread_create(&info->to_server.tid, NULL, server_thread, info);
+ pthread_create(&info->to_client.tid, NULL, client_thread, info);
+
+ /* State that we won't be joining this thread */
+ pthread_detach(info->to_server.tid);
+ pthread_detach(info->to_client.tid);
+ #endif
+ }
+ }
+
+ #ifdef HAVE_PTHREAD
+ /* For threading, wait for completion */
+ if (!argClientOnly && !argServerOnly) {
+ /* Wait until threads are marked done */
+ do {
+ doShutdown = 1;
+
+ for (i = 0; i < argThreadPairs; ++i) {
+ info = &theadInfo[i];
+ if (!info->to_client.done || !info->to_server.done) {
+ doShutdown = 0;
+ XSLEEP_MS(1000); /* Allow other threads to run */
+ }
+
+ }
+ } while (!doShutdown);
+ if (argShowVerbose) {
+ printf("Shutdown complete\n");
+ }
+ }
+ #endif /* HAVE_PTHREAD */
+
+ if (argShowVerbose) {
+ /* print results */
+ for (i = 0; i < argThreadPairs; ++i) {
+ info = &theadInfo[i];
+
+ printf("\nThread %d\n", i);
+ #ifndef NO_WOLFSSL_SERVER
+ if (!argClientOnly)
+ print_stats(&info->server_stats, "Server", info->cipher, 1);
+ #endif
+ #ifndef NO_WOLFSSL_CLIENT
+ if (!argServerOnly)
+ print_stats(&info->client_stats, "Client", info->cipher, 1);
+ #endif
+ }
+ }
+
+ /* print combined results for more than one thread */
+ XMEMSET(&cli_comb, 0, sizeof(cli_comb));
+ XMEMSET(&srv_comb, 0, sizeof(srv_comb));
+
+ for (i = 0; i < argThreadPairs; ++i) {
+ info = &theadInfo[i];
+
+ cli_comb.connCount += info->client_stats.connCount;
+ srv_comb.connCount += info->server_stats.connCount;
+
+ cli_comb.connTime += info->client_stats.connTime;
+ srv_comb.connTime += info->server_stats.connTime;
+
+ cli_comb.rxTotal += info->client_stats.rxTotal;
+ srv_comb.rxTotal += info->server_stats.rxTotal;
+
+ cli_comb.rxTime += info->client_stats.rxTime;
+ srv_comb.rxTime += info->server_stats.rxTime;
+
+ cli_comb.txTotal += info->client_stats.txTotal;
+ srv_comb.txTotal += info->server_stats.txTotal;
+
+ cli_comb.txTime += info->client_stats.txTime;
+ srv_comb.txTime += info->server_stats.txTime;
+ }
+
+ if (argShowVerbose) {
+ printf("Totals for %d Threads\n", argThreadPairs);
+ }
+ else {
+ printf("%-6s %-33s %11s %9s %9s %9s %9s %9s %17s %15s\n",
+ "Side", "Cipher", "Total Bytes", "Num Conns", "Rx ms", "Tx ms",
+ "Rx MB/s", "Tx MB/s", "Connect Total ms", "Connect Avg ms");
+ #ifndef NO_WOLFSSL_SERVER
+ if (!argClientOnly)
+ print_stats(&srv_comb, "Server", theadInfo[0].cipher, 0);
+ #endif
+ #ifndef NO_WOLFSSL_CLIENT
+ if (!argServerOnly)
+ print_stats(&cli_comb, "Client", theadInfo[0].cipher, 0);
+ #endif
+ }
+
+ /* target next cipher */
+ cipher = (next_cipher != NULL) ? (next_cipher + 1) : NULL;
+ } /* while */
+
+exit:
+
+#ifndef NO_WOLFSSL_SERVER
+ if (argServerOnly && !argLocalMem) {
+ /* Close server listener */
+ CloseAndCleanupListenSocket(&listenFd);
+ }
+#endif
+
+ /* Cleanup the wolfSSL environment */
+ wolfSSL_Cleanup();
+
+ /* Free theadInfo array */
+ XFREE(theadInfo, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+
+ /* Free cipher list */
+ XFREE(ciphers, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+
+ /* Return reporting a success */
+ if (args)
+ ((func_args*)args)->return_code = ret;
+
+ return ret;
+}
+#endif /* (!NO_WOLFSSL_CLIENT || !NO_WOLFSSL_SERVER) && !WOLFCRYPT_ONLY && USE_WOLFSSL_IO */
+
+#ifndef NO_MAIN_DRIVER
+
+int main(int argc, char** argv)
+{
+ func_args args;
+
+ args.argc = argc;
+ args.argv = argv;
+ args.return_code = 0;
+
+#if (!defined(NO_WOLFSSL_CLIENT) || !defined(NO_WOLFSSL_SERVER)) && \
+ !defined(WOLFCRYPT_ONLY) && defined(USE_WOLFSSL_IO)
+ bench_tls(&args);
+#endif
+
+ return args.return_code;
+}
+
+#endif /* !NO_MAIN_DRIVER */
diff --git a/ap/lib/libwolfssl/install/share/doc/wolfssl/taoCert.txt b/ap/lib/libwolfssl/install/share/doc/wolfssl/taoCert.txt
new file mode 100644
index 0000000..0973def
--- /dev/null
+++ b/ap/lib/libwolfssl/install/share/doc/wolfssl/taoCert.txt
@@ -0,0 +1,176 @@
+
+***** Create a self signed cert ************
+
+1) openssl genrsa 1024 > client-key.pem
+
+2) openssl req -new -x509 -nodes -sha1 -days 1000 -key client-key.pem > client-cert.pem
+
+3) note md5 would be -md5
+
+-- adding metadata to beginning
+
+3) openssl x509 -in client-cert.pem -text > tmp.pem
+
+4) mv tmp.pem client-cert.pem
+
+
+***** Create a CA, signing authority **********
+
+same as self signed, use ca prefix instead of client
+
+
+***** Create a cert signed by CA **************
+
+1) openssl req -newkey rsa:1024 -sha1 -days 1000 -nodes -keyout server-key.pem > server-req.pem
+
+* note if using existing key do: -new -key keyName
+
+2) copy ca-key.pem ca-cert.srl (why ????)
+
+3) openssl x509 -req -in server-req.pem -days 1000 -sha1 -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 > server-cert.pem
+
+
+***** Adding Subject Key ID and Authentication Key ID extensions to a cert *****
+
+Create a config file for OpenSSL with the example contents:
+
+ [skidakid]
+ subjectKeyIdentifier=hash
+ authorityKeyIdentifier=keyid
+
+Add to the openssl command for creating a cert signed by a CA step 3 the
+following options:
+
+ -extfile <file.cnf> -extensions skidakid
+
+anywhere before the redirect. This will add the cert's public key hash as the
+Subject Key Identifier, and the signer's SKID as the Authentication Key ID.
+
+
+***** To create a dsa cert ********************
+
+1) openssl dsaparam 512 > dsa512.param # creates group params
+
+2) openssl gendsa dsa512.param > dsa512.pem # creates private key
+
+3) openssl req -new -x509 -nodes -days 1000 -key dsa512.pem > dsa-cert.pem
+
+
+
+
+***** To convert from PEM to DER **************
+
+a) openssl x509 -in cert.pem -inform PEM -out cert.der -outform DER
+
+to convert rsa private PEM to DER :
+
+b) openssl rsa -in key.pem -outform DER -out key.der
+
+
+**** To encrypt rsa key already in pem **********
+
+a) openssl rsa <server-key.pem.bak -des >server-keyEnc.pem
+
+note location of des, pass = yassl123
+
+
+*** To make a public key from a private key ******
+
+
+openssl rsa -in 1024rsa.priv -pubout -out 1024rsa.pub
+
+
+**** To convert to pkcs8 *******
+
+openssl pkcs8 -nocrypt -topk8 -in server-key.pem -out server-keyPkcs8.pem
+
+
+**** To convert to pkcs8 encrypted *******
+
+openssl pkcs8 -topk8 -in server-key.pem -out server-keyPkcs8Enc.pem
+
+passwd: yassl123
+
+to use PKCS#5 v2 instead of v1.5 which is default add
+
+-v2 des3 # file Pkcs8Enc2
+
+to use PKCS#12 instead use -v1 witch a 12 algo like
+
+-v1 PBE-SHA1-3DES # file Pkcs8Enc12 , see man pkcs8 for more info
+-v1 PBE-SHA1-RC4-128 # no longer file Pkcs8Enc12, arc4 now off by default
+
+
+**** To convert from pkcs8 to traditional ****
+
+openssl pkcs8 -nocrypt -in server-keyPkcs8.pem -out server-key.pem
+
+
+*** DH parameters ***
+
+openssl dhparam 2048 > dh2048.param
+
+to add metadata
+
+openssl dhparam -in dh2048.param -text > dh2048.pem
+
+**** ECC ******
+
+1) make a key
+
+ to see types available do
+ openssl ecparam -list_curves
+
+ make a new key
+ openssl ecparam -genkey -text -name secp256r1 -out ecc-key.pem
+
+ convert to compressed
+ openssl ec -in ecc-key.pem -conv_form compressed -out ecc-key-comp.pem
+
+*** CRL ***
+
+1) create a crl
+
+a) openssl ca -gencrl -crldays 120 -out crl.pem -keyfile ./ca-key.pem -cert ./ca-cert.pem
+
+Error No ./CA root/index.txt so:
+
+b) touch ./CA root/index.txt
+
+a) again
+
+Error No ./CA root/crlnumber so:
+
+c) touch ./CA root/crlnumber
+
+a) again
+
+Error unable to load CRL number
+
+d) add '01' to crlnumber file
+
+a) again
+
+2) view crl file
+
+openssl crl -in crl.pem -text
+
+3) revoke
+
+openssl ca -revoke server-cert.pem -keyfile ./ca-key.pem -cert ./ca-cert.pem
+
+Then regenerate crl with a)
+
+4) verify
+
+openssl verify -CAfile ./ca-cert.pem ./server-cert.pem
+
+OK
+
+Make file with both ca and crl
+
+cat ca-cert.pem crl.pem > ca-crl.pem
+
+openssl verify -CAfile ./ca-crl.pem -crl_check ./ca-cert.pem
+
+revoked