diff --git a/Makefile.am b/Makefile.am index 9dd32a20..0646f9e6 100644 --- a/Makefile.am +++ b/Makefile.am @@ -57,6 +57,7 @@ include tests/genkey_sign_ver/include.am include tests/hash/include.am include tests/bench/include.am include tests/client/include.am +include tests/server/include.am include ide/include.am #####include data/include.am diff --git a/src/client/client.c b/src/client/client.c index f0eb48cc..38c59ea3 100644 --- a/src/client/client.c +++ b/src/client/client.c @@ -2104,6 +2104,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) #if defined(HAVE_PQC) { "pqc", 1, 259 }, #endif + { "disable_stdin_check", 0, 260 }, { 0, 0, 0 } }; #endif @@ -2213,6 +2214,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) int exitWithRet = 0; int loadCertKeyIntoSSLObj = 0; int isIpv6 = 0; + int disable_stdin_chk = 0; #ifdef HAVE_ENCRYPT_THEN_MAC int disallowETM = 0; @@ -2275,6 +2277,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) (void)loadCertKeyIntoSSLObj; (void)usePqc; (void)pqcAlg; + (void)disable_stdin_chk; StackTrap(); /* Reinitialize the global myVerifyAction. */ @@ -2308,6 +2311,10 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) Usage(); XEXIT_T(EXIT_SUCCESS); + case 260 : + disable_stdin_chk = 1; + break; + case 'g' : sendGET = 1; break; @@ -4155,12 +4162,14 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) } #ifndef USE_WINDOWS_API - int stop = checkStdin(); + if (!disable_stdin_chk) { + int stop = checkStdin(); - if(stop){ - wolfSSL_free(ssl); ssl = NULL; - wolfSSL_CTX_free(ctx); ctx = NULL; - goto exit; + if(stop){ + wolfSSL_free(ssl); ssl = NULL; + wolfSSL_CTX_free(ctx); ctx = NULL; + goto exit; + } } #endif diff --git a/src/client/clu_client_setup.c b/src/client/clu_client_setup.c index f658ea39..ee723310 100644 --- a/src/client/clu_client_setup.c +++ b/src/client/clu_client_setup.c @@ -1,6 +1,6 @@ /* clu_client_setup.c * - * Copyright (C) 2006-2021 wolfSSL Inc. + * Copyright (C) 2006-2023 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -34,6 +34,7 @@ static const struct option client_options[] = { {"-starttls", required_argument, 0, WOLFCLU_STARTTLS }, {"-CAfile", required_argument, 0, WOLFCLU_CAFILE }, {"-verify_return_error", no_argument, 0, WOLFCLU_VERIFY_RETURN_ERROR}, + {"-disable_stdin_check", no_argument, 0, WOLFCLU_DISABLE_STDINCHK }, {"-help", no_argument, 0, WOLFCLU_HELP }, {"-h", no_argument, 0, WOLFCLU_HELP }, @@ -53,6 +54,7 @@ static void wolfCLU_ClientHelp(void) WOLFCLU_LOG(WOLFCLU_L0, "\t-starttls "); WOLFCLU_LOG(WOLFCLU_L0, "\t-CAfile "); WOLFCLU_LOG(WOLFCLU_L0, "\t-verify_return_error close connection on verification error"); + WOLFCLU_LOG(WOLFCLU_L0, "\t-disable_stdin_check ") } static const char hostFlag[] = "-h"; @@ -217,6 +219,12 @@ int wolfCLU_Client(int argc, char** argv) } break; + case WOLFCLU_DISABLE_STDINCHK: + if (ret == WOLFCLU_SUCCESS) { + ret = _addClientArg(clientArgv, "--disable_stdin_check", + &clientArgc); + } + break; case WOLFCLU_HELP: wolfCLU_ClientHelp(); return WOLFCLU_SUCCESS; diff --git a/src/clu_main.c b/src/clu_main.c index 663fc174..0109e77c 100644 --- a/src/clu_main.c +++ b/src/clu_main.c @@ -1,6 +1,6 @@ /* clu_main.c * - * Copyright (C) 2006-2021 wolfSSL Inc. + * Copyright (C) 2006-2023 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -65,6 +65,7 @@ static const struct option mode_options[] = { {"pkcs12", no_argument, 0, WOLFCLU_PKCS12 }, {"crl", no_argument, 0, WOLFCLU_CRL }, {"s_client", no_argument, 0, WOLFCLU_CLIENT }, + {"s_server", no_argument, 0, WOLFCLU_SERVER }, {"rand", no_argument, 0, WOLFCLU_RAND }, {"dsaparam", no_argument, 0, WOLFCLU_DSA }, {"dhparam", no_argument, 0, WOLFCLU_DH }, @@ -285,6 +286,10 @@ int main(int argc, char** argv) ret = wolfCLU_Client(argc, argv); break; + case WOLFCLU_SERVER: + ret = wolfCLU_Server(argc, argv); + break; + case WOLFCLU_RAND: ret = wolfCLU_Rand(argc, argv); break; diff --git a/src/include.am b/src/include.am index af99e634..4e7d4531 100644 --- a/src/include.am +++ b/src/include.am @@ -6,41 +6,43 @@ bin_PROGRAMS = wolfssl wolfssl_SOURCES = src/clu_main.c \ src/clu_log.c \ - src/tools/clu_funcs.c \ - src/tools/clu_hex_to_bin.c \ - src/tools/clu_rand.c \ - src/crypto/clu_crypto_setup.c \ - src/crypto/clu_encrypt.c \ - src/crypto/clu_decrypt.c \ - src/crypto/clu_evp_crypto.c \ - src/hash/clu_hash_setup.c \ - src/hash/clu_hash.c \ - src/hash/clu_alg_hash.c \ - src/benchmark/clu_bench_setup.c \ - src/benchmark/clu_benchmark.c \ - src/x509/clu_request_setup.c \ - src/x509/clu_ca_setup.c \ - src/x509/clu_cert_setup.c \ - src/x509/clu_parse.c \ - src/x509/clu_config.c \ - src/x509/clu_x509_sign.c \ - src/genkey/clu_genkey_setup.c \ - src/genkey/clu_genkey.c \ - src/ecparam/clu_ecparam.c \ - src/sign-verify/clu_sign.c \ - src/sign-verify/clu_verify.c \ - src/sign-verify/clu_x509_verify.c \ - src/sign-verify/clu_crl_verify.c \ - src/sign-verify/clu_sign_verify_setup.c \ - src/sign-verify/clu_dgst_setup.c \ - src/certgen/clu_certgen_ed25519.c \ - src/certgen/clu_certgen_rsa.c \ - src/pkey/clu_rsa.c \ - src/pkey/clu_pkey.c \ - src/pkcs/clu_pkcs12.c \ - src/client/client.c \ - src/client/clu_client_setup.c \ - src/dsa/clu_dsa.c \ - src/dh/clu_dh.c + src/tools/clu_funcs.c \ + src/tools/clu_hex_to_bin.c \ + src/tools/clu_rand.c \ + src/crypto/clu_crypto_setup.c \ + src/crypto/clu_encrypt.c \ + src/crypto/clu_decrypt.c \ + src/crypto/clu_evp_crypto.c \ + src/hash/clu_hash_setup.c \ + src/hash/clu_hash.c \ + src/hash/clu_alg_hash.c \ + src/benchmark/clu_bench_setup.c \ + src/benchmark/clu_benchmark.c \ + src/x509/clu_request_setup.c \ + src/x509/clu_ca_setup.c \ + src/x509/clu_cert_setup.c \ + src/x509/clu_parse.c \ + src/x509/clu_config.c \ + src/x509/clu_x509_sign.c \ + src/genkey/clu_genkey_setup.c \ + src/genkey/clu_genkey.c \ + src/ecparam/clu_ecparam.c \ + src/sign-verify/clu_sign.c \ + src/sign-verify/clu_verify.c \ + src/sign-verify/clu_x509_verify.c \ + src/sign-verify/clu_crl_verify.c \ + src/sign-verify/clu_sign_verify_setup.c \ + src/sign-verify/clu_dgst_setup.c \ + src/certgen/clu_certgen_ed25519.c \ + src/certgen/clu_certgen_rsa.c \ + src/pkey/clu_rsa.c \ + src/pkey/clu_pkey.c \ + src/pkcs/clu_pkcs12.c \ + src/client/client.c \ + src/client/clu_client_setup.c \ + src/dsa/clu_dsa.c \ + src/dh/clu_dh.c \ + src/server/server.c \ + src/server/clu_server_setup.c diff --git a/src/server/clu_server_setup.c b/src/server/clu_server_setup.c new file mode 100644 index 00000000..54349ace --- /dev/null +++ b/src/server/clu_server_setup.c @@ -0,0 +1,202 @@ +/* clu_server_setup.c + * + * Copyright (C) 2006-2023 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 + */ + +#include +#include +#include +#include + +#ifndef WOLFCLU_NO_FILESYSTEM + +static const struct option server_options[] = { + {"-port", required_argument, 0, WOLFCLU_PORT }, + {"-key" , required_argument, 0, WOLFCLU_KEYFILE }, + {"-cert", required_argument, 0, WOLFCLU_CERTFILE }, + {"-noVerify", no_argument, 0, WOLFCLU_VERIFY }, + {"-CAfile", required_argument, 0, WOLFCLU_CA }, + {"-version", required_argument, 0, WOLFCLU_VERSION }, + {"-naccept", required_argument, 0, WOLFCLU_ACCEPT }, + {"-www", no_argument, 0, WOLFCLU_WWW }, + {"-readyFile", required_argument, 0, WOLFCLU_READY_FILE }, + {"-help", no_argument, 0, WOLFCLU_HELP }, + {"-h", no_argument, 0, WOLFCLU_HELP }, + {0,0,0,0} +}; + +static const char portFlag[] = "-p"; +static const char keyFileFlag[] = "-k"; +static const char certFileFlag[] = "-c"; +static const char verifyFlag[] = "-d"; +static const char clientCertFlag[] = "-A"; +static const char versionFlag[] = "-v"; +static const char acceptFlag[] = "-C"; +static const char wwwFlag[] = "-g"; +static const char readyFileFlag[] = "-R"; + +static void wolfCLU_ServerHelp(void) +{ + WOLFCLU_LOG(WOLFCLU_L0, "./wolfssl s_server"); + WOLFCLU_LOG(WOLFCLU_L0, "\t-help"); + WOLFCLU_LOG(WOLFCLU_L0, "\t-port <+int>"); + WOLFCLU_LOG(WOLFCLU_L0, "\t\tPort to listen on."); + WOLFCLU_LOG(WOLFCLU_L0, "\t-key "); + WOLFCLU_LOG(WOLFCLU_L0, "\t\tonly PEM can be used."); + WOLFCLU_LOG(WOLFCLU_L0, "\t-cert "); + WOLFCLU_LOG(WOLFCLU_L0, "\t\tonly PEM can be used."); + WOLFCLU_LOG(WOLFCLU_L0, "\t-noVerify"); + WOLFCLU_LOG(WOLFCLU_L0, "\t\tDisable client cert check."); + WOLFCLU_LOG(WOLFCLU_L0, "\t-CAfile "); + WOLFCLU_LOG(WOLFCLU_L0, "\t\tonly PEM can be used."); + WOLFCLU_LOG(WOLFCLU_L0, "\t-version "); + WOLFCLU_LOG(WOLFCLU_L0, "\t\tSSL version [0-4], SSLv3(0) - TLS1.3(4))"); + WOLFCLU_LOG(WOLFCLU_L0, "\t-naccept <+int>"); + WOLFCLU_LOG(WOLFCLU_L0, "\t\tNumber of times to accept.(default 1)"); + WOLFCLU_LOG(WOLFCLU_L0, "\t-www"); + WOLFCLU_LOG(WOLFCLU_L0, "\t\tThe response is in HTML format."); + WOLFCLU_LOG(WOLFCLU_L0, "\t-readyFile "); + WOLFCLU_LOG(WOLFCLU_L0, "\t\tCreate Ready file for external monitor."); +} + +#define MAX_SERVER_ARGS 20 + +/* return WOLFSSL_SUCCESS on success */ +static int _addServerArg(const char** args, const char* in, int* idx) +{ + int ret = WOLFCLU_SUCCESS; + + if (*idx >= MAX_SERVER_ARGS) { + wolfCLU_LogError("Too many server args for array"); + ret = WOLFCLU_FATAL_ERROR; + } + else { + args[*idx] = in; + *idx = *idx + 1; + } + return ret; +} + +#endif /* !WOLFCLU_NO_FILESYSTEM */ + +int wolfCLU_Server(int argc, char** argv) +{ + func_args args; + int ret = WOLFCLU_SUCCESS; + int longIndex = 1; + int option; + + int serverArgc = 0; + const char* serverArgv[MAX_SERVER_ARGS]; + + tcp_ready ready; + InitTcpReady(&ready); + args.signal = &ready; + + ret = _addServerArg(serverArgv, "wolfclu", &serverArgc); + + opterr = 0; + optind = 0; + + while ((option = wolfCLU_GetOpt(argc, argv, "", server_options, &longIndex)) + != -1) { + switch (option) { + case WOLFCLU_PORT: + if (ret == WOLFCLU_SUCCESS) { + ret = _addServerArg(serverArgv, portFlag, &serverArgc); + if (ret == WOLFCLU_SUCCESS) { + ret = _addServerArg(serverArgv, optarg, &serverArgc); + } + } + break; + case WOLFCLU_KEYFILE: + if (ret == WOLFCLU_SUCCESS) { + ret = _addServerArg(serverArgv, keyFileFlag, &serverArgc); + if (ret == WOLFCLU_SUCCESS) { + ret = _addServerArg(serverArgv, optarg, &serverArgc); + } + } + break; + case WOLFCLU_CERTFILE: + if (ret == WOLFCLU_SUCCESS) { + ret = _addServerArg(serverArgv, certFileFlag, &serverArgc); + if (ret == WOLFCLU_SUCCESS) { + ret = _addServerArg(serverArgv, optarg, &serverArgc); + } + } + break; + case WOLFCLU_VERIFY: + if (ret == WOLFCLU_SUCCESS) { + ret = _addServerArg(serverArgv, verifyFlag, &serverArgc); + } + break; + case WOLFCLU_CA: + if (ret == WOLFCLU_SUCCESS) { + ret = _addServerArg(serverArgv, clientCertFlag, &serverArgc); + if (ret == WOLFCLU_SUCCESS) { + ret = _addServerArg(serverArgv, optarg, &serverArgc); + } + } + break; + case WOLFCLU_VERSION: + if (ret == WOLFCLU_SUCCESS) { + ret = _addServerArg(serverArgv, versionFlag, &serverArgc); + if (ret == WOLFCLU_SUCCESS) { + ret = _addServerArg(serverArgv, optarg, &serverArgc); + } + } + break; + case WOLFCLU_ACCEPT: + if (ret == WOLFCLU_SUCCESS) { + ret = _addServerArg(serverArgv, acceptFlag, &serverArgc); + if (ret == WOLFCLU_SUCCESS) { + ret = _addServerArg(serverArgv, optarg, &serverArgc); + } + } + break; + case WOLFCLU_WWW: + if (ret == WOLFCLU_SUCCESS) { + ret = _addServerArg(serverArgv, wwwFlag, &serverArgc); + } + break; + case WOLFCLU_READY_FILE: + if (ret == WOLFCLU_SUCCESS) { + ret = _addServerArg(serverArgv, readyFileFlag, &serverArgc); + if (ret == WOLFCLU_SUCCESS) { + ret = _addServerArg(serverArgv, optarg, &serverArgc); + } + } + break; + case WOLFCLU_HELP: + wolfCLU_ServerHelp(); + goto exit; + } + } + + if (ret == WOLFCLU_SUCCESS) { + args.argv = (char**)serverArgv; + args.argc = serverArgc; + server_test(&args); + } + +exit: + FreeTcpReady(&ready); + + return ret; +} diff --git a/src/server/server.c b/src/server/server.c new file mode 100644 index 00000000..3583454b --- /dev/null +++ b/src/server/server.c @@ -0,0 +1,3810 @@ +/* server.c + * + * Copyright (C) 2006-2023 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 + */ + +/* For simpler wolfSSL TLS client examples, visit + * https://github.com/wolfSSL/wolfssl-examples/tree/master/tls + */ + +#ifdef HAVE_CONFIG_H + #include +#endif + +#ifndef WOLFSSL_USER_SETTINGS + #include +#endif +#include + +#undef TEST_OPENSSL_COEXIST /* can't use this option with this example */ +#include /* name change portability layer */ + +#ifdef HAVE_ECC + #include /* wc_ecc_fp_free */ +#endif + +#ifdef WOLFSSL_WOLFSENTRY_HOOKS +#include +#if !defined(NO_FILESYSTEM) && !defined(WOLFSENTRY_NO_JSON) +static const char *wolfsentry_config_path = NULL; +#endif +#endif /* WOLFSSL_WOLFSENTRY_HOOKS */ + +#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 +#endif + +#include +#include + +#include +#include + +#ifndef NO_WOLFSSL_SERVER + +#if defined(WOLFSSL_TLS13) && ( \ + defined(HAVE_ECC) \ + || defined(HAVE_CURVE25519) \ + || defined(HAVE_CURVE448) \ + || defined(HAVE_FFDHE_2048)) + #define CAN_FORCE_CURVE +#endif +#if defined(CAN_FORCE_CURVE) && defined(HAVE_ECC) +struct group_info { + word16 group; + const char *name; +}; +static struct group_info group_id_to_text[] = { + { WOLFSSL_ECC_SECP160K1, "SECP160K1" }, + { WOLFSSL_ECC_SECP160R1, "SECP160R1" }, + { WOLFSSL_ECC_SECP160R2, "SECP160R2" }, + { WOLFSSL_ECC_SECP192K1, "SECP192K1" }, + { WOLFSSL_ECC_SECP192R1, "SECP192R1" }, + { WOLFSSL_ECC_SECP224K1, "SECP224K1" }, + { WOLFSSL_ECC_SECP224R1, "SECP224R1" }, + { WOLFSSL_ECC_SECP256K1, "SECP256K1" }, + { WOLFSSL_ECC_SECP256R1, "SECP256R1" }, + { WOLFSSL_ECC_SECP384R1, "SECP384R1" }, + { WOLFSSL_ECC_SECP521R1, "SECP521R1" }, + { WOLFSSL_ECC_BRAINPOOLP256R1, "BRAINPOOLP256R1" }, + { WOLFSSL_ECC_BRAINPOOLP384R1, "BRAINPOOLP384R1" }, + { WOLFSSL_ECC_BRAINPOOLP512R1, "BRAINPOOLP512R1" }, + { 0, NULL } +}; +#endif /* CAN_FORCE_CURVE && HAVE_ECC */ + +#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" + "\r\n" + "\r\n" + "Welcome to wolfSSL!\r\n" + "\r\n" + "\r\n" + "

wolfSSL has successfully performed handshake!

\r\n" + "\r\n" + "\r\n"; + +/* Read needs to be largest of the client.c message strings (29) */ +#define SRV_READ_SZ 32 + +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 + +/* + * SSL resource release and error output. + * Immediately after execution of this function, + * the program is expected to terminate with the appropriate error code. + */ +static void release(SSL_CTX* ctx, SSL* ssl, const char* msg){ + if (SSL_is_init_finished(ssl)){ + SSL_shutdown(ssl); + } + SSL_free(ssl); ssl = NULL; + SSL_CTX_free(ctx); ctx = NULL; + fprintf(stderr, "%s\n", 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; + + (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) { + int 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 + )) { + 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 + { + int currTimeout = 1; + + if (error == WOLFSSL_ERROR_WANT_WRITE) + { + select_ret = tcp_select_tx(sockfd, currTimeout); + } + else { + #ifdef WOLFSSL_DTLS + if (wolfSSL_dtls(ssl)) + 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)) { + ret = wolfSSL_dtls_got_timeout(ssl); + if (ret != WOLFSSL_SUCCESS) + error = wolfSSL_get_error(ssl, ret); + else + error = WOLFSSL_ERROR_WANT_READ; + ret = WOLFSSL_FAILURE; /* Reset error so we loop */ + } + #endif + else { + error = WOLFSSL_FATAL_ERROR; + } + } + + return ret; +} + +/* Echo number of bytes specified by -B arg */ +static 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 len, rx_pos; + size_t xfer_bytes = 0; + char* buffer; + + buffer = (char*)malloc(block); + if (!buffer) { + fprintf(stderr, "Server buffer malloc failed\n"); + } + + while ((echoData && throughput == 0) || + (!echoData && xfer_bytes < throughput)) + { + int 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_WANT_WRITE && + err != WOLFSSL_ERROR_ZERO_RETURN && + err != APP_DATA_READY) { + fprintf(stderr, "SSL_read echo error %d\n", err); + fprintf(stderr, "SSL_read failed\n"); + 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)) { + fprintf(stderr, "SSL_write echo error %d\n", err); + fprintf(stderr, "SSL_write failed\n"); + } + + if (throughput) { + tx_time += current_time(0) - start; + } + + xfer_bytes += len; + } + } + + free(buffer); + + if (throughput) { +#ifdef __MINGW32__ +#define SIZE_FMT "%d" +#define SIZE_TYPE int +#else +#define SIZE_FMT "%zu" +#define SIZE_TYPE size_t +#endif + printf( + "wolfSSL Server Benchmark " SIZE_FMT " bytes\n" + "\tRX %8.3f ms (%8.3f MBps)\n" + "\tTX %8.3f ms (%8.3f MBps)\n", + (SIZE_TYPE)throughput, + 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) { + fprintf(stderr, "Dropped client's message due to a bad MAC\n"); + } + else + #endif + if (err != WOLFSSL_ERROR_WANT_READ + && err != WOLFSSL_ERROR_WANT_WRITE /* Can happen during + * handshake */ + #ifdef HAVE_SECURE_RENEGOTIATION + && err != APP_DATA_READY + #endif + ) { + fprintf(stderr, "SSL_read input error %d, %s\n", err, + ERR_error_string(err, buffer)); + fprintf(stderr, "SSL_read failed\n"); + } + } + else if (SSL_get_error(ssl, 0) == 0 && + tcp_select(SSL_get_fd(ssl), 0) == TEST_RECV_READY) { + /* do a peek and check for "pending" */ + #ifdef WOLFSSL_ASYNC_CRYPT + err = 0; + #endif + do { + #ifdef WOLFSSL_ASYNC_CRYPT + if (err == WC_PENDING_E) { + ret = wolfSSL_AsyncPoll(ssl, WOLF_POLL_FLAG_CHECK_HW); + if (ret < 0) break; + } + #endif + ret = wolfSSL_peek(ssl, buffer, 0); + err = SSL_get_error(ssl, ret); + } while (err == WC_PENDING_E + || err == WOLFSSL_ERROR_WANT_READ + || err == WOLFSSL_ERROR_WANT_WRITE); + if (err < 0) { + fprintf(stderr, "wolfSSL_peek failed\n"); + } + if (wolfSSL_pending(ssl)) + err = WOLFSSL_ERROR_WANT_READ; + } + } while (err == WC_PENDING_E + || err == WOLFSSL_ERROR_WANT_READ + || err == WOLFSSL_ERROR_WANT_WRITE); + 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; + 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) { + char buffer[WOLFSSL_MAX_ERROR_SZ]; + fprintf(stderr, "SSL_write msg error %d, %s\n", err, + ERR_error_string(err, buffer)); + fprintf(stderr, "SSL_write failed\n"); + } +} + +#if defined(WOLFSSL_TLS13) && defined(HAVE_SUPPORTED_CURVES) +#define MAX_GROUP_NUMBER 4 +static int SetKeyShare(WOLFSSL* ssl, int onlyKeyShare, int useX25519, + int useX448, int usePqc, char* pqcAlg) +{ + int ret; + int groups[MAX_GROUP_NUMBER] = {0}; + int count = 0; + + (void)useX25519; + (void)useX448; + (void)usePqc; + (void)pqcAlg; + + 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 { + fprintf(stderr, "unable to use curve x25519\n"); + return ret; + } + } 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 { + fprintf(stderr, "unable to use curve x448\n"); + return ret; + } + } while (ret == WC_PENDING_E); + #endif + } + else if (usePqc == 1) { + #ifdef HAVE_PQC + groups[count] = 0; + if (XSTRCMP(pqcAlg, "KYBER_LEVEL1") == 0) { + groups[count] = WOLFSSL_KYBER_LEVEL1; + } + else if (XSTRCMP(pqcAlg, "KYBER_LEVEL3") == 0) { + groups[count] = WOLFSSL_KYBER_LEVEL3; + } + else if (XSTRCMP(pqcAlg, "KYBER_LEVEL5") == 0) { + groups[count] = WOLFSSL_KYBER_LEVEL5; + } + else if (XSTRCMP(pqcAlg, "P256_KYBER_LEVEL1") == 0) { + groups[count] = WOLFSSL_P256_KYBER_LEVEL1; + } + else if (XSTRCMP(pqcAlg, "P384_KYBER_LEVEL3") == 0) { + groups[count] = WOLFSSL_P384_KYBER_LEVEL3; + } + else if (XSTRCMP(pqcAlg, "P521_KYBER_LEVEL5") == 0) { + groups[count] = WOLFSSL_P521_KYBER_LEVEL5; + } + + if (groups[count] == 0) { + fprintf(stderr, "invalid post-quantum KEM specified\n"); + return ret; + } + else { + if (wolfSSL_UseKeyShare(ssl, groups[count]) == WOLFSSL_SUCCESS) { + printf("Using Post-Quantum KEM: %s\n", pqcAlg); + count++; + } + else { + groups[count] = 0; + fprintf(stderr, "unable to use post-quantum algorithm\n"); + return SSL_FATAL_ERROR; + } + } + #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 { + fprintf(stderr, "unable to use curve secp256r1\n"); + return ret; + } + } 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 { + fprintf(stderr, "unable to use DH 2048-bit parameters\n"); + return ret; + } + } while (ret == WC_PENDING_E); + #endif + } + if (count >= MAX_GROUP_NUMBER) { + fprintf(stderr, "example group array size error\n"); + return SSL_FATAL_ERROR; + } + if (count > 0) { + if (wolfSSL_set_groups(ssl, groups, count) != WOLFSSL_SUCCESS) { + fprintf(stderr, "unable to set groups"); + return SSL_FATAL_ERROR; + } + } + WOLFSSL_END(WC_FUNC_CLIENT_KEY_EXCHANGE_SEND); + + return WOLFSSL_SUCCESS; +} +#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[][65] = { + /* English */ + { + " NOTE: All files relative to wolfSSL home dir\n", /* 0 */ + "-? Help, print this usage\n" + " 0: English, 1: Japanese\n" + "--help Help, in English\n", /* 1 */ + "-p Port to listen on, not 0, default", /* 2 */ +#ifndef WOLFSSL_TLS13 + "-v SSL version [0-3], SSLv3(0) - TLS1.2(3)), default", /* 3 */ +#else + "-v SSL version [0-4], SSLv3(0) - TLS1.3(4)), default", /* 3 */ +#endif + "-l Cipher suite list (: delimited)\n", /* 4 */ + "-c Certificate file, default", /* 5 */ + "-k Key file, default", /* 6 */ + "-A Certificate Authority file, default", /* 7 */ + "-R Create Ready file for external monitor" + " default none\n", /* 8 */ +#ifndef NO_DH + "-D Diffie-Hellman Params file, default", /* 9 */ + "-Z Minimum DH key bits, default", /* 10 */ +#endif +#ifdef HAVE_ALPN + "-L Application-Layer Protocol Negotiation" + " ({C,F}:)\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 */ +#ifndef WOLFSSL_DTLS13 + "-u Use UDP DTLS, add -v 2 for DTLSv1, -v 3 for DTLSv1.2" + " (default)\n", /* 15 */ +#else + "-u Use UDP DTLS, add -v 2 for DTLSv1, -v 3 for DTLSv1.2" + " (default), -v 4 for DTLSv1.3\n", /* 15 */ +#endif /* !WOLFSSL_DTLS13 */ +#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 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 Perform OCSP lookup using as responder\n", /* 23 */ +#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 */ + "-B Benchmark throughput" + " using bytes and print stats\n", /* 31 */ +#ifdef HAVE_CRL + "-V Disable CRL\n", /* 32 */ +#endif +#ifdef WOLFSSL_TRUST_PEER_CERT + "-E Path to load trusted peer cert\n", /* 33 */ +#endif + "-g Return basic HTML web page\n", /* 35 */ + "-C The number of connections to accept, default: 1\n",/* 36 */ + "-H 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 [n] Server sends Cookie Extension containing state (n to " + "disable)\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 Multicast, grpid < 256\n", /* 52 */ +#endif + "-1 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 /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 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 +#ifdef HAVE_PQC + "--pqc Key Share with specified post-quantum algorithm only [KYBER_LEVEL1, KYBER_LEVEL3,\n" + " KYBER_LEVEL5, P256_KYBER_LEVEL1, P384_KYBER_LEVEL3, P521_KYBER_LEVEL5] \n", /* 60 */ +#endif +#ifdef WOLFSSL_SRTP + "--srtp (default is SRTP_AES128_CM_SHA1_80)\n", /* 61 */ +#endif +#if defined(WOLFSSL_TLS13) && defined(HAVE_SESSION_TICKET) + "--send-ticket Send a new session ticket during application data\n", + /* 62 */ +#endif +#ifdef CAN_FORCE_CURVE + "--force-curve [] Pre-generate a Key Share using .\n" + " Leave blank to list all curves.\n" + " Note: requires TLS1.3\n", + /* 63 */ +#endif +#ifdef HAVE_SUPPORTED_CURVES + "--onlyPskDheKe Must use DHE key exchange with PSK\n", /* 64 */ +#endif + "\n" + "For simpler wolfSSL TLS server examples, visit\n" + "https://github.com/wolfSSL/wolfssl-examples/tree/master/tls\n", + /* 65 */ + NULL, + }, +#ifndef NO_MULTIBYTE_PRINT + /* Japanese */ + { + " 注意 : 全てのファイルは" + " wolfSSL ホーム・ディレクトリからの相対です。\n", /* 0 */ + "-? ヘルプ, 使い方を表示\n" + " 0: 英語、 1: 日本語\n" + "--ヘルプ 日本語で使い方を表示\n", /* 1 */ + "-p 接続先ポート, 0は無効, 既定値", /* 2 */ +#ifndef WOLFSSL_TLS13 + "-v SSL バージョン [0-3], SSLv3(0) - TLS1.2(3))," + " 既定値", /* 3 */ +#else + "-v SSL バージョン [0-4], SSLv3(0) - TLS1.3(4))," + " 既定値", /* 3 */ +#endif + "-l 暗号スイートリスト (区切り文字 :)\n", /* 4 */ + "-c 証明書ファイル, 既定値", /* 5 */ + "-k 鍵ファイル, 既定値", /* 6 */ + "-A 認証局ファイル, 既定値", /* 7 */ + "-R 外部モニタ用の準備完了ファイルを作成する。" + "既定値 なし\n", /* 8 */ +#ifndef NO_DH + "-D ディフィー・ヘルマンのパラメータファイル," + " 既定値", /* 9 */ + "-Z 最小 DH 鍵 ビット, 既定値", /* 10 */ +#endif +#ifdef HAVE_ALPN + "-L アプリケーション層プロトコルネゴシエーションを行う" + " ({C,F}:)\n", /* 11 */ +#endif + "-d クライアント認証を無効とする\n", /* 12 */ + "-b ローカルホスト以外のインターフェースへも" + "バインドする\n", /* 13 */ + "-s 事前共有鍵を使用する\n", /* 14 */ + "-u UDP DTLSを使用する。\n" + +#ifndef WOLFSSL_DTLS13 + " -v 2 を追加指定するとDTLSv1, " + "-v 3 を追加指定すると DTLSv1.2 (既定値)\n", /* 15 */ +#else + " -v 2 を追加指定するとDTLSv1, " + "-v 3 を追加指定すると DTLSv1.2 (既定値),\n" + " -v 4 を追加指定すると DTLSv1.3\n", /* 15 */ +#endif /* !WOLFSSL_DTLS13 */ +#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 ホスト名表示を使用する\n", /* 20 */ + "-w 双方向シャットダウンを待つ\n", /* 21 */ +#ifdef HAVE_OCSP + "-o OCSPルックアップをピア証明書で実施する\n", /* 22 */ + "-O OCSPルックアップを、" + "を使用し応答者として実施する\n", /* 23 */ +#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 */ + "-B バイトを用いてのベンチマーク・スループット" + "測定と結果を出力する\n", /* 31 */ +#ifdef HAVE_CRL + "-V CRLを無効とする\n", /* 32 */ +#endif +#ifdef WOLFSSL_TRUST_PEER_CERT + "-E 信頼出来るピアの証明書ロードの為のパス\n\n", /* 33 */ +#endif + "-g 基本的な Web ページを返す\n", /* 35 */ + "-C アクセプト可能な接続数を指定する。既定値: 1\n", /* 36 */ + "-H 内部テスト" + " [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 */ + " オプション指定なしの場合、TLS 1.3 にだけ有効\n" + " 'a' を指定した場合、" + "全てのプロトコルバージョンに有効\n" /* 45 */ + " 'o' を指定した場合、TLS 1.2 及び" + "それ以下のプロトコルバージョンに有効\n" /* 46 */ + " 'n' を指定した場合、TLS 1.3 にのみ有効\n", /* 47 */ + +#endif +#ifdef WOLFSSL_TLS13 + "-F 相互認証が無い場合にalert を送信\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 < 256\n", /* 52 */ +#endif + "-1 指定された言語で結果を表示します。" + "\n 0: 英語、 1: 日本語\n", /* 53 */ +#ifdef HAVE_TRUSTED_CA + "-5 信頼できる認証局の鍵表示を使用する\n", /* 54 */ +#endif + "-6 交互の IO 送信で WANT_WRITE エラー" + "をシュミレート\n", + /* 55 */ +#ifdef HAVE_CURVE448 + "-8 Curve448のみを使用して鍵共有を事前生成する\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" + " /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 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 +#ifdef HAVE_PQC + "--pqc post-quantum 名前付きグループとの鍵共有のみ [KYBER_LEVEL1, KYBER_LEVEL3,\n" + " KYBER_LEVEL5, P256_KYBER_LEVEL1, P384_KYBER_LEVEL3, P521_KYBER_LEVEL5]\n", /* 60 */ +#endif +#ifdef WOLFSSL_SRTP + "--srtp (デフォルトはSRTP_AES128_CM_SHA1_80)\n", /* 61 */ +#endif +#if defined(WOLFSSL_TLS13) && defined(HAVE_SESSION_TICKET) + "--send-ticket Application data 中に新しい" + "セッションチケットを送信します\n", + /* 62 */ +#endif +#ifdef CAN_FORCE_CURVE + /* TODO: Need Japanese translation */ + "--force-curve [] Pre-generate a Key Share using .\n" + " Leave blank to list all curves.\n" + " Note: requires TLS1.3\n", + /* 63 */ +#endif +#ifdef HAVE_SUPPORTED_CURVES + "--onlyPskDheKe Must use DHE key exchange with PSK\n", /* 64 */ +#endif + "\n" + "より簡単なwolfSSL TSL クライアントの例については" + "下記にアクセスしてください\n" + "https://github.com/wolfSSL/wolfssl-examples/tree/master/tls\n", /* 65 */ + 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_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 */ + 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 + 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 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 */ +#ifdef HAVE_PQC + printf("%s", msg[++msgId]); /* --pqc */ + printf("%s", msg[++msgId]); /* --pqc options */ + printf("%s", msg[++msgId]); /* more --pqc options */ + printf("%s", msg[++msgId]); /* more --pqc options */ +#endif +#ifdef WOLFSSL_SRTP + printf("%s", msg[++msgId]); /* dtls-srtp */ +#endif +#if defined(WOLFSSL_TLS13) && defined(HAVE_SESSION_TICKET) + printf("%s", msg[++msgId]); /* send-ticket */ +#endif +#ifdef CAN_FORCE_CURVE + printf("%s", msg[++msgId]); /* force-curve */ +#endif +#ifdef HAVE_SUPPORTED_CURVES + printf("%s", msg[++msgId]); /* --onlyPskDheKe */ +#endif + printf("%s", msg[++msgId]); /* Examples repo link */ +} + +#ifdef WOLFSSL_SRTP +/** + * server_srtp_test() - print the ekm and share it with the client + * @ssl: ssl context + * @srtp_helper: srtp_test_helper shared struct with the client + * + * if @srtp_helper is NULL the ekm isn't shared, but it is still printed. + * + * calls srtp_helper_set_ekm() to wake the client and share the ekm with + * him. The client will check that the ekm matches the one computed by itself. + */ +static int server_srtp_test(WOLFSSL *ssl, func_args *args) +{ + size_t srtp_secret_length; + byte *srtp_secret, *p; + int ret; +#if !defined(SINGLE_THREADED) && defined(_POSIX_THREADS) + srtp_test_helper *srtp_helper = args->srtp_helper; +#else + (void)args; +#endif + + ret = wolfSSL_export_dtls_srtp_keying_material(ssl, NULL, + &srtp_secret_length); + if (ret != LENGTH_ONLY_E) { + fprintf(stderr, "DTLS SRTP: Error getting key material length\n"); + return ret; + } + + srtp_secret = (byte*)XMALLOC(srtp_secret_length, + NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (srtp_secret == NULL) { + fprintf(stderr, "DTLS SRTP: Memory error\n"); + return MEMORY_ERROR; + } + + ret = wolfSSL_export_dtls_srtp_keying_material(ssl, srtp_secret, + &srtp_secret_length); + if (ret != WOLFSSL_SUCCESS) { + XFREE(srtp_secret, NULL, DYNAMIC_TYPE_TMP_BUFFER); + fprintf(stderr, "DTLS SRTP: Error getting key material\n"); + return ret; + } + + printf("DTLS SRTP: Exported key material: "); + for (p = srtp_secret; p < srtp_secret + srtp_secret_length; p++) + printf("%02X", *p); + printf("\n"); + +#if !defined(SINGLE_THREADED) && defined(_POSIX_THREADS) + if (srtp_helper != NULL) { + srtp_helper_set_ekm(srtp_helper, srtp_secret, srtp_secret_length); + + /* client code will free srtp_secret buffer after checking for + correctness */ + return 0; + } +#endif /* _POSIX_THREADS */ + + XFREE(srtp_secret, NULL, DYNAMIC_TYPE_TMP_BUFFER); + return 0; +} +#endif + + +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 }, +#if defined(HAVE_PQC) + { "pqc", 1, 259 }, +#endif +#ifdef WOLFSSL_SRTP + { "srtp", 2, 260 }, /* optional argument */ +#endif +#if defined(WOLFSSL_TLS13) && defined(HAVE_SESSION_TICKET) + { "send-ticket", 0, 261 }, +#endif +#ifdef CAN_FORCE_CURVE + { "force-curve", 2, 262}, +#endif +#ifdef WOLFSSL_DTLS_CID + {"cid", 2, 263}, +#endif /* WOLFSSL_DTLS_CID */ +#ifdef HAVE_SUPPORTED_CURVES + {"onlyPskDheKe", 2, 264}, +#endif /* HAVE_SUPPORTED_CURVES */ + { 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 nonBlocking = 0; + int simulateWantWrite = 0; + int fewerPackets = 0; + + 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 + char buffer[WOLFSSL_MAX_ERROR_SZ]; +#ifdef WOLFSSL_TLS13 + int noPskDheKe = 0; +#ifdef HAVE_SUPPORTED_CURVES + int onlyPskDheKe = 0; +#endif +#endif + int updateKeysIVs = 0; +#ifndef NO_CERTS + int mutualAuth = 0; +#endif + int postHandAuth = 0; + int sendTicket = 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_DTLS_CID + int useDtlsCID = 0; + char dtlsCID[DTLS_CID_BUFFER_SIZE] = { 0 }; +#endif /* WOLFSSL_DTLS_CID */ + +#ifdef WOLFSSL_STATIC_MEMORY + /* Note: Actual memory used is much less, this is the entire buffer buckets, + * which is partitioned into pools of common sizes. To adjust the buckets + * sizes see WOLFMEM_BUCKETS in memory.h */ + #if (defined(HAVE_ECC) && !defined(ALT_ECC_SIZE)) \ + || defined(SESSION_CERTS) + /* big enough to handle most cases including session certs */ + #if !defined(WOLFSSL_NO_CLIENT_AUTH) && \ + ((defined(HAVE_ED25519) && !defined(NO_ED25519_CLIENT_AUTH)) || \ + (defined(HAVE_ED448) && !defined(NO_ED448_CLIENT_AUTH))) + /* increase is due to EdDSA_Update */ + byte memory[440000]; + #else + byte memory[320000]; + #endif + #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 usePqc = 0; + char* pqcAlg = NULL; + 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 + +#ifdef WOLFSSL_SRTP + const char* dtlsSrtpProfiles = NULL; +#endif + +#ifdef HAVE_TEST_SESSION_TICKET + MyTicketCtx myTicketCtx; +#endif + +#ifdef CAN_FORCE_CURVE + int force_curve_group_id = 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)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)sendTicket; + (void)mcastID; + (void)loadCertKeyIntoSSLObj; + (void)nonBlocking; + (void)pqcAlg; + (void)usePqc; + +#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 */ + while ((ch = mygetopt_long(argc, argv, "?:" + "abc:defgijk:l:mop:q:rstu;v:wxy" + "A:B:C:D:E:FGH:IJ;KL:MNO:PQR:S:T;UVYZ:" + "01:23:4:567: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 '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 'u' : + doDTLS = 1; + dtlsUDP = 1; + #if (defined(WOLFSSL_SCTP) || defined(WOLFSSL_DTLS_MTU)) && \ + defined(WOLFSSL_DTLS) + dtlsMTU = atoi(myoptarg); + #endif + break; + + #ifdef WOLFSSL_SRTP + case 260: + doDTLS = 1; + dtlsUDP = 1; + dtlsSrtpProfiles = myoptarg != NULL ? myoptarg : + "SRTP_AES128_CM_SHA1_80"; + printf("Using SRTP Profile(s): %s\n", dtlsSrtpProfiles); + break; + #endif + + case 'G' : + #ifdef WOLFSSL_SCTP + doDTLS = 1; + dtlsUDP = 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' : + 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 (XSTRCMP(myoptarg, "defCipherList") == 0) { + printf("Using default cipher list for testing\n"); + useDefCipherList = 1; + } + else if (XSTRCMP(myoptarg, "exitWithRet") == 0) { + printf("Skip exit() for testing\n"); + exitWithRet = 1; + } + else if (XSTRCMP(myoptarg, "verifyFail") == 0) { + printf("Verify should fail\n"); + myVerifyAction = VERIFY_FORCE_FAIL; + } + else if (XSTRCMP(myoptarg, "verifyInfo") == 0) { + printf("Verify should use preverify (just show info)\n"); + myVerifyAction = VERIFY_USE_PREVERFIY; + } + else if (XSTRCMP(myoptarg, "loadSSL") == 0) { + printf("Also load cert/key into wolfSSL object\n"); + #ifndef NO_CERTS + loadCertKeyIntoSSLObj = 2; + #endif + } + else if (XSTRCMP(myoptarg, "loadSSLOnly") == 0) { + printf("Only load cert/key into wolfSSL object\n"); + #ifndef NO_CERTS + loadCertKeyIntoSSLObj = 1; + #endif + } + else if (XSTRCMP(myoptarg, "disallowETM") == 0) { + printf("Disallow Encrypt-Then-MAC\n"); + #ifdef HAVE_ENCRYPT_THEN_MAC + disallowETM = 1; + #endif + } + else if (XSTRCMP(myoptarg, "overrideDateErr") == 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 '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 (XSTRCMP(myoptarg, "a") == 0) { + noTicketTls12 = 1; + #if defined(WOLFSSL_TLS13) + noTicketTls13 = 1; + #endif + } + else if (XSTRCMP(myoptarg, "o") == 0) { + noTicketTls12 = 1; + } + else if (XSTRCMP(myoptarg, "n") == 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; + if (XSTRCMP(myoptarg, "n") == 0) + 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' : +#ifdef WOLFSSL_ASYNC_IO + nonBlocking = 1; + simulateWantWrite = 1; +#else + fprintf(stderr, "Ignoring -6 since async I/O support not " + "compiled in.\n"); +#endif + 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 + +#ifdef HAVE_PQC + case 259: + usePqc = 1; + onlyKeyShare = 2; + pqcAlg = myoptarg; + break; +#endif + +#if defined(WOLFSSL_TLS13) && defined(HAVE_SESSION_TICKET) + case 261: + sendTicket = 1; + break; +#endif +#ifdef CAN_FORCE_CURVE + case 262: { + /* Note: this requires TSL1.3 (version >= 4) */ + #ifdef HAVE_ECC + int j = 0; /* our group index */ + #endif + if (NULL == myoptarg) { + #ifdef HAVE_ECC + int idx = 0; /* ecc curve index */ + #endif + Usage(); + if (lng_index == 1) { + /* TODO: Need Japanese translation */ + printf("\nAvailable choices for --force-curve:\n"); + } else { + printf("\nAvailable choices for --force-curve:\n"); + } + #ifdef HAVE_ECC + for (idx=0; ; ++idx) { + int id = wc_ecc_get_curve_id(idx); + if (ECC_CURVE_INVALID == id) { + break; + } + for (j=0; group_id_to_text[j].group != 0; ++j) { + if (XSTRCMP(group_id_to_text[j].name, + wc_ecc_get_curve_name_from_id(id)) == 0) { + printf("\t%s\n", group_id_to_text[j].name); + } + } + } + #endif + #ifdef HAVE_CURVE25519 + printf("\tCURVE25519\n"); + #endif + #ifdef HAVE_CURVE448 + printf("\tCURVE448\n"); + #endif + printf("\n"); + XEXIT_T(EXIT_SUCCESS); + } + #ifdef HAVE_ECC + for (j=0; group_id_to_text[j].group != 0; ++j) { + if (XSTRCMP(group_id_to_text[j].name, myoptarg) == 0) { + force_curve_group_id = group_id_to_text[j].group; + } + } + #endif + #ifdef HAVE_CURVE25519 + if (force_curve_group_id <= 0) { + if (XSTRCMP(myoptarg, "CURVE25519") == 0) { + force_curve_group_id = WOLFSSL_ECC_X25519; + } + } + #endif + #ifdef HAVE_CURVE448 + if (force_curve_group_id <= 0) { + if (XSTRCMP(myoptarg, "CURVE448") == 0) { + force_curve_group_id = WOLFSSL_ECC_X448; + } + } + #endif + if (force_curve_group_id <= 0) { + if (lng_index == 1) { + /* TODO: Need Japanese translation */ + fprintf(stderr, "Invalid curve '%s'\n", myoptarg); + } else { + fprintf(stderr, "Invalid curve '%s'\n", myoptarg); + } + XEXIT_T(EXIT_FAILURE); + } + } + break; +#endif /* CAN_FORCE_CURVE */ +#ifdef WOLFSSL_DTLS_CID + case 263: + useDtlsCID = 1; + if (myoptarg != NULL) { + if (XSTRLEN(myoptarg) >= DTLS_CID_BUFFER_SIZE) { + fprintf(stderr, "provided connection ID is too big\n"); + return BAD_FUNC_ARG; + } + else { + strcpy(dtlsCID, myoptarg); + } + } + break; +#endif /* WOLFSSL_CID */ + case 264: +#ifdef HAVE_SUPPORTED_CURVES + #ifdef WOLFSSL_TLS13 + onlyPskDheKe = 1; + #endif +#endif + break; + + 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) { + fprintf(stderr, "Cannot use DTLS with both UDP and SCTP.\n"); + } + + /* 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; + } + else if (version == 4) { +#ifdef WOLFSSL_DTLS13 + version = -4; +#else + fprintf(stderr, "Bad DTLS version\n"); +#endif /* WOLFSSL_DTLS13 */ + } + #if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EITHER_SIDE) + else if (version == EITHER_DOWNGRADE_VERSION) { + version = -3; + } + #endif + else if (version == 2) + version = -1; + } + } + +#ifndef HAVE_SESSION_TICKET + if ((version >= 4) && resume) { + fprintf(stderr, "Can't do TLS 1.3 resumption; need session tickets!\n"); + } +#endif + +#ifdef HAVE_PQC + if (usePqc) { + if (version == SERVER_DOWNGRADE_VERSION || + version == EITHER_DOWNGRADE_VERSION) { + fprintf(stderr, + "WARNING: If a TLS 1.3 connection is not negotiated, you " + "will not be using a post-quantum group.\n"); + } else if (version != 4 && version != -4) { + release(ctx, ssl, "can only use post-quantum groups with TLS 1.3 or DTLS 1.3"); + ((func_args*)args)->return_code = VERSION_ERROR; + goto exit; + } + } +#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: + if (!doDTLS) { + method = wolfSSLv23_server_method_ex; + } + else { +#ifdef WOLFSSL_DTLS + method = wolfDTLS_server_method_ex; +#else + fprintf(stderr, "version not supported\n"); +#endif /* WOLFSSL_DTLS */ + } + 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 +#ifdef WOLFSSL_DTLS13 + case -4: + method = wolfDTLSv1_3_server_method_ex; + break; +#endif + #if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EITHER_SIDE) + case -3: + method = wolfDTLSv1_2_method_ex; + break; + #endif +#endif + + default: + fprintf(stderr, "Bad SSL version\n"); + } + + if (method == NULL) + fprintf(stderr, "unable to get method\n"); + +#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) + fprintf(stderr, "unable to load static memory and create ctx\n"); + + /* 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) + fprintf(stderr, "unable to load static memory and create ctx\n"); +#else + if (method != NULL) { + ctx = SSL_CTX_new(method(NULL)); + } +#ifdef WOLFSSL_CALLBACKS + wolfSSL_CTX_set_msg_callback(ctx, msgDebugCb); +#endif +#endif /* WOLFSSL_STATIC_MEMORY */ + if (ctx == NULL) + fprintf(stderr, "unable to get ctx\n"); + + if (minVersion != SERVER_INVALID_VERSION) { +#ifdef WOLFSSL_DTLS + if (doDTLS) { + switch (minVersion) { +#ifdef WOLFSSL_DTLS13 + case 4: + minVersion = WOLFSSL_DTLSV1_3; + break; +#endif /* WOLFSSL_DTLS13 */ + case 3: + minVersion = WOLFSSL_DTLSV1_2; + break; + case 2: + minVersion = WOLFSSL_DTLSV1; + break; + } + } +#endif /* WOLFSSL_DTLS13 */ + if (wolfSSL_CTX_SetMinVersion(ctx, minVersion) != WOLFSSL_SUCCESS) + fprintf(stderr, "can't set minimum downgrade version\n"); + } + +#ifdef OPENSSL_COMPATIBLE_DEFAULTS + /* Restore wolfSSL verify defaults */ + wolfSSL_CTX_set_verify(ctx, WOLFSSL_VERIFY_DEFAULT, NULL); +#endif + +#ifdef WOLFSSL_SRTP + if (dtlsSrtpProfiles != NULL) { + if (wolfSSL_CTX_set_tlsext_use_srtp(ctx, dtlsSrtpProfiles) + != WOLFSSL_SUCCESS) { + fprintf(stderr, "unable to set DTLS SRTP profile\n"); + } + } +#endif + +#ifdef WOLFSSL_WOLFSENTRY_HOOKS + if (wolfsentry_setup(&wolfsentry, wolfsentry_config_path, + WOLFSENTRY_ROUTE_FLAG_DIRECTION_IN) < 0) { + release(ctx, ssl, "unable to initialize wolfSentry"); + ((func_args*)args)->return_code = SSL_ERROR_SSL; + goto exit; + } + + if (wolfSSL_CTX_set_AcceptFilter( + ctx, + (NetworkFilterCallback_t)wolfSentry_NetworkFilterCallback, + wolfsentry) < 0) { + fprintf(stderr, "unable to install wolfSentry_NetworkFilterCallback\n"); + } +#endif + + if (simulateWantWrite) + { + #ifdef USE_WOLFSSL_IO + wolfSSL_CTX_SetIOSend(ctx, SimulateWantWriteIOSendCb); + #endif + } + +#ifdef HAVE_TEST_SESSION_TICKET + if (TicketInit() != 0) + fprintf(stderr, "unable to setup Session Ticket Key context\n"); + wolfSSL_CTX_set_TicketEncCb(ctx, myTicketEncCb); + XMEMSET(&myTicketCtx, 0, sizeof(myTicketCtx)); + wolfSSL_CTX_set_TicketEncCtx(ctx, &myTicketCtx); +#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) { + fprintf(stderr, "error loading static ECDH key\n"); + } + { + 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) { + fprintf(stderr, "error loading static DH key\n"); + } +#endif +#ifdef HAVE_CURVE25519 + ret = wolfSSL_CTX_set_ephemeral_key(ctx, WC_PK_TYPE_CURVE25519, + "./certs/statickeys/x25519.pem", 0, WOLFSSL_FILETYPE_PEM); + if (ret != 0) { + fprintf(stderr, "error loading static X25519 key\n"); + } +#endif +#endif /* WOLFSSL_SNIFFER && WOLFSSL_STATIC_EPHEMERAL */ + + if (cipherList && !useDefCipherList) { + if (SSL_CTX_set_cipher_list(ctx, cipherList) != WOLFSSL_SUCCESS) + fprintf(stderr, "server can't set custom cipher list\n"); + } + +#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)) { + #if defined(NO_FILESYSTEM) && defined(USE_CERT_BUFFERS_2048) + if (wolfSSL_CTX_use_certificate_chain_buffer_format(ctx, + server_cert_der_2048, sizeof_server_cert_der_2048, + WOLFSSL_FILETYPE_ASN1) != WOLFSSL_SUCCESS) + fprintf(stderr, "can't load server cert buffer\n"); + #elif !defined(TEST_LOAD_BUFFER) + if (SSL_CTX_use_certificate_chain_file(ctx, ourCert) + != WOLFSSL_SUCCESS) + fprintf(stderr, "can't load server cert file, check file " + "and run from wolfSSL home dir\n"); + #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) { + fprintf(stderr, "Error setting minimum DH key size\n"); + } +#endif +#ifndef NO_RSA + if (wolfSSL_CTX_SetMinRsaKey_Sz(ctx, minRsaKeyBits) != WOLFSSL_SUCCESS){ + fprintf(stderr, "Error setting minimum RSA key size\n"); + } +#endif +#ifdef HAVE_ECC + if (wolfSSL_CTX_SetMinEccKey_Sz(ctx, minEccKeyBits) != WOLFSSL_SUCCESS){ + fprintf(stderr, "Error setting minimum ECC key size\n"); + } +#endif + +#if !defined(NO_CERTS) + if ((!usePsk || usePskPlus) && !useAnon + && !(loadCertKeyIntoSSLObj == 1) + ) { + #ifdef NO_FILESYSTEM + if (wolfSSL_CTX_use_PrivateKey_buffer(ctx, server_key_der_2048, + sizeof_server_key_der_2048, SSL_FILETYPE_ASN1) != WOLFSSL_SUCCESS) + fprintf(stderr, "can't load server private key buffer\n"); + #elif !defined(TEST_LOAD_BUFFER) + if (SSL_CTX_use_PrivateKey_file(ctx, ourKey, WOLFSSL_FILETYPE_PEM) + != WOLFSSL_SUCCESS) { + fprintf(stderr, "can't load server private key file, " + "check file and run from wolfSSL home dir\n"); + } + #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"; + #elif !defined(NO_AES_CBC) + defaultCipherList = "PSK-AES128-CBC-SHA256"; + #else + defaultCipherList = "PSK-AES128-GCM-SHA256"; + #endif + if (SSL_CTX_set_cipher_list(ctx, defaultCipherList) + != WOLFSSL_SUCCESS) + fprintf(stderr, "server can't set cipher list 2\n"); + } + 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){ + fprintf(stderr, "Error setting ECDHE size\n"); + } +#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) + fprintf(stderr, "server can't set cipher list 4\n"); + } +#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) { + release(ctx, ssl, "can't get WOLFSSL_X509_STORE"); + ((func_args*)args)->return_code = SSL_ERROR_SSL; + goto exit; + } + lookup = wolfSSL_X509_STORE_add_lookup(store, X509_LOOKUP_hash_dir()); + if (lookup == NULL) { + release(ctx, ssl, "can't add lookup"); + ((func_args*)args)->return_code = SSL_ERROR_SSL; + goto exit; + } + if ((ret = wolfSSL_X509_LOOKUP_ctrl(lookup, WOLFSSL_X509_L_ADD_DIR, caCertFolder, + X509_FILETYPE_PEM, NULL)) != WOLFSSL_SUCCESS) { + release(ctx, ssl, "X509_LOOKUP_ctrl w/ L_ADD_DIR failed"); + ((func_args*)args)->return_code = ret; + goto exit; + } + } else { + #endif + if ((ret = wolfSSL_CTX_load_verify_locations_ex(ctx, verifyCert, 0, + verify_flags)) != WOLFSSL_SUCCESS) { + release(ctx, ssl, "can't load ca file, " + "Please run from wolfSSL home dir"); + ((func_args*)args)->return_code = ret; + goto exit; + } + #ifdef WOLFSSL_TRUST_PEER_CERT + if (trustCert) { + if (wolfSSL_CTX_trust_peer_cert(ctx, trustCert, + WOLFSSL_FILETYPE_PEM) != WOLFSSL_SUCCESS) { + fprintf(stderr, "can't load trusted peer cert file\n"); + } + } + #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) { + fprintf(stderr, "server can't set cipher list 3\n"); + } + } +#endif + +#ifdef HAVE_SNI + if (sniHostName) + if (wolfSSL_CTX_UseSNI(ctx, WOLFSSL_SNI_HOST_NAME, sniHostName, + (word16) XSTRLEN(sniHostName)) != WOLFSSL_SUCCESS) + fprintf(stderr, "UseSNI failed\n"); +#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) { + fprintf(stderr, "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); +#ifdef HAVE_SUPPORTED_CURVES + if (onlyPskDheKe) + wolfSSL_CTX_only_dhe_psk(ctx); +#endif +#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)) { + fprintf(stderr, "tcp accept failed\n"); + } + } +#if defined(WOLFSSL_STATIC_MEMORY) && defined(DEBUG_WOLFSSL) + fprintf(stderr, "Before creating SSL\n"); + if (wolfSSL_CTX_is_static_memory(ctx, &mem_stats) != 1) + fprintf(stderr, "ctx not using static memory\n"); + if (wolfSSL_PrintStats(&mem_stats) != 1) /* function in test.h */ + fprintf(stderr, "error printing out memory stats\n"); +#endif + + if (doMcast) { +#ifdef WOLFSSL_MULTICAST + wolfSSL_CTX_mcast_set_member_id(ctx, mcastID); + if ((ret = wolfSSL_CTX_set_cipher_list(ctx, "WDM-NULL-SHA256")) + != WOLFSSL_SUCCESS) { + release(ctx, ssl, "Couldn't set multicast cipher list."); + ((func_args*)args)->return_code = ret; + goto exit; + } +#endif + } + + if (doDTLS && dtlsUDP) { +#if defined(WOLFSSL_DTLS) && defined(USE_WOLFSSL_IO) + if (doBlockSeq) { + wolfSSL_CTX_SetIOSend(ctx, TestEmbedSendTo); + } +#endif + } + + ssl = SSL_new(ctx); + if (ssl == NULL) + fprintf(stderr, "unable to create an SSL object\n"); + +#if defined(OPENSSL_EXTRA) || defined(HAVE_SECRET_CALLBACK) + wolfSSL_KeepArrays(ssl); +#endif + + /* Support for loading private key and cert using WOLFSSL object */ +#if !defined(NO_CERTS) + if ((!usePsk || usePskPlus) && !useAnon && loadCertKeyIntoSSLObj) { + #if defined(NO_FILESYSTEM) && defined(USE_CERT_BUFFERS_2048) + if (wolfSSL_use_certificate_chain_buffer_format(ssl, + server_cert_der_2048, sizeof_server_cert_der_2048, + WOLFSSL_FILETYPE_ASN1) != WOLFSSL_SUCCESS) + fprintf(stderr, "can't load server cert buffer\n"); + #elif !defined(TEST_LOAD_BUFFER) + if (SSL_use_certificate_chain_file(ssl, ourCert) + != WOLFSSL_SUCCESS) + fprintf(stderr, "can't load server cert file, check file " + "and run from wolfSSL home dir\n"); + #else + /* loads cert chain file using buffer API */ + load_ssl_buffer(ssl, ourCert, WOLFSSL_CERT_CHAIN); + #endif + } + + if ((!usePsk || usePskPlus) && !useAnon && + loadCertKeyIntoSSLObj + ) { + #if defined(NO_FILESYSTEM) + if (wolfSSL_use_PrivateKey_buffer(ssl, server_key_der_2048, + sizeof_server_key_der_2048, SSL_FILETYPE_ASN1) != WOLFSSL_SUCCESS) + fprintf(stderr, "can't load server private key buffer\n"); + #elif !defined(TEST_LOAD_BUFFER) + if (SSL_use_PrivateKey_file(ssl, ourKey, WOLFSSL_FILETYPE_PEM) + != WOLFSSL_SUCCESS) + fprintf(stderr, "can't load server private key file, check" + "file and run from wolfSSL home dir\n"); + #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 == 1 && wolfSSL_send_hrr_cookie(ssl, NULL, 0) + != WOLFSSL_SUCCESS) { + release(ctx, ssl, "unable to set use of cookie with HRR msg"); + ((func_args*)args)->return_code = SSL_ERROR_SSL; + goto exit; + } + else if (hrrCookie == -1) { + wolfSSL_disable_hrr_cookie(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) + fprintf(stderr, "ctx not using static memory\n"); + if (wolfSSL_PrintStats(&mem_stats) != 1) /* function in test.h */ + fprintf(stderr, "error printing out memory stats\n"); +#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 ((ret = wolfSSL_set_secret(ssl, 1, pms, sizeof(pms), cr, sr, suite)) + != WOLFSSL_SUCCESS) { + release(ctx, ssl, "unable to set mcast secret"); + ((func_args*)args)->return_code = ret; + goto exit; + } +#endif + } + +#ifdef HAVE_SECURE_RENEGOTIATION + if (scr) { + if (wolfSSL_UseSecureRenegotiation(ssl) != WOLFSSL_SUCCESS) { + fprintf(stderr, "can't enable secure renegotiation\n"); + } + } +#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; + + #ifdef TEST_BEFORE_DATE + verify_flags |= WOLFSSL_LOAD_FLAG_DATE_ERR_OKAY; + #endif + + if ((ret = wolfSSL_CTX_load_verify_locations_ex(ctx, verifyCert, 0, + verify_flags)) + != WOLFSSL_SUCCESS) { + release(ctx, ssl, "can't load ca file, " + "Please run from wolfSSL home dir"); + ((func_args*)args)->return_code = ret; + goto exit; + + } + #ifdef WOLFSSL_TRUST_PEER_CERT + if (trustCert) { + if (wolfSSL_trust_peer_cert(ssl, trustCert, + WOLFSSL_FILETYPE_PEM) != WOLFSSL_SUCCESS) { + fprintf(stderr, "can't load trusted peer cert file\n"); + } + } + #endif /* WOLFSSL_TRUST_PEER_CERT */ + } + #endif +#endif + + +#ifndef NO_HANDSHAKE_DONE_CB + wolfSSL_SetHsDoneCb(ssl, myHsDoneCb, NULL); +#endif +#if defined(HAVE_CRL) && !defined(NO_FILESYSTEM) + if (!disableCRL) { +#ifdef HAVE_CRL_MONITOR + crlFlags = WOLFSSL_CRL_MONITOR | WOLFSSL_CRL_START_MON; +#endif + if (wolfSSL_EnableCRL(ssl, 0) != WOLFSSL_SUCCESS) + fprintf(stderr, "unable to enable CRL\n"); + if (wolfSSL_LoadCRL(ssl, crlPemDir, WOLFSSL_FILETYPE_PEM, crlFlags) + != WOLFSSL_SUCCESS) + fprintf(stderr, "unable to load CRL\n"); + if (wolfSSL_SetCRL_Cb(ssl, CRL_CallBack) != WOLFSSL_SUCCESS) + fprintf(stderr, "unable to set CRL callback url\n"); + } +#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 OCSP Stapling test certs are RSA. */ +#if !defined(NO_FILESYSTEM) && (\ + 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) { + fprintf(stderr, "can't enable OCSP Stapling Certificate Manager\n"); + } + if (SSL_CTX_load_verify_locations(ctx, ca1, 0) != WOLFSSL_SUCCESS) { + fails++; + fprintf(stderr, "can't load ca file, " + "Please run from wolfSSL home dir\n"); + } + if (SSL_CTX_load_verify_locations(ctx, ca2, 0) != WOLFSSL_SUCCESS) { + fails++; + fprintf(stderr, "can't load ca file, Please run from " + "wolfSSL home dir\n"); + } + if (SSL_CTX_load_verify_locations(ctx, ca3, 0) != WOLFSSL_SUCCESS) { + fails++; + fprintf(stderr, "can't load ca file, Please run from " + "wolfSSL home dir\n"); + } + if (fails > 2) { + fprintf(stderr, "Failed to load any intermediates for " + "OCSP stapling test\n"); + } + } /* scope end */ +#endif /* HAVE_CERTIFICATE_STATUS_REQUEST HAVE_CERTIFICATE_STATUS_REQUEST_V2 */ +#endif /* NO_RSA */ +#endif /* HAVE_OCSP */ + + #if defined(WOLFSSL_TLS13) && defined(HAVE_SUPPORTED_CURVES) + if (version >= 4 || version == -4) { + #ifdef CAN_FORCE_CURVE + if (force_curve_group_id > 0) { + do { + ret = wolfSSL_UseKeyShare(ssl, force_curve_group_id); + if (ret == WOLFSSL_SUCCESS) { + + } + #ifdef WOLFSSL_ASYNC_CRYPT + else if (ret == WC_PENDING_E) { + wolfSSL_AsyncPoll(ssl, WOLF_POLL_FLAG_CHECK_HW); + } + #endif + else { + release(ctx, ssl, "Failed wolfSSL_UseKeyShare in force-curve"); + ((func_args*)args)->return_code = ret; + goto exit; + } + } while (ret == WC_PENDING_E); + ret = wolfSSL_set_groups(ssl, &force_curve_group_id, 1); + if (WOLFSSL_SUCCESS != ret) { + release(ctx, ssl, "Failed wolfSSL_set_groups in force-curve"); + ((func_args*)args)->return_code = ret; + goto exit; + } + } + else + #endif + if ((ret = SetKeyShare(ssl, onlyKeyShare, useX25519, useX448, + usePqc, pqcAlg)) != WOLFSSL_SUCCESS) { + release(ctx, ssl, "failed to create a key share entry from group"); + ((func_args*)args)->return_code = ret; + goto exit; + } + } + #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) { + fprintf(stderr, "error in setting fd\n"); + } + +#ifdef HAVE_TRUSTED_CA + if (trustedCaKeyId) { + if (wolfSSL_UseTrustedCA(ssl, WOLFSSL_TRUSTED_CA_PRE_AGREED, + NULL, 0) != WOLFSSL_SUCCESS) { + fprintf(stderr, "UseTrustedCA failed\n"); + } + } +#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 isClientHello = 0; + + while (!isClientHello) { + 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) + fprintf(stderr, "recvfrom failed\n"); + + /* when doing resumption, it may happen that we receive the + alert used to shutdown the first connection as the first + packet of the second accept: + + Client | Server + | WolfSSL_Shutdown() + | <- Alert + | recvfrom(peek) + WolfSSL_Shutdown() | + Alert-> | + | wolfSSL_set_dtls_peer() + + but this will set the wrong src port, making the test fail. + Discard not-handshake message to avoid this. + */ + if (b[0] != 0x16) { + /* discard the packet */ + n = (int)recvfrom(clientfd, (char *)b, sizeof(b), 0, + (struct sockaddr *)&client_addr, &client_len); + + if (n <= 0) + fprintf(stderr, "recvfrom failed\n"); + } + else { + isClientHello = 1; + } + } + + 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); + } + if (simulateWantWrite) { +#ifdef USE_WOLFSSL_IO + /* connect on a udp to associate peer with this fd to make it + * simpler for SimulateWantWriteIOSendCb */ + if (connect(clientfd, (struct sockaddr*)&client_addr, + client_len) != 0) { + fprintf(stderr, "error in connecting to peer\n"); + } + wolfSSL_SetIOWriteCtx(ssl, (void*)&sockfd); +#endif + } + } +#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) + fprintf(stderr, "client_addr.sa_family != local_addr.sa_family\n"); + + if (wolfsentry_store_endpoints( + ssl, &client_addr, &local_addr, + dtlsUDP ? IPPROTO_UDP : IPPROTO_TCP, + WOLFSENTRY_ROUTE_FLAG_DIRECTION_IN, NULL) != WOLFSSL_SUCCESS) + fprintf(stderr, "error in wolfsentry_store_endpoints()\n"); + } +#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 + } + +#ifdef WOLFSSL_DTLS_CID + if (useDtlsCID) { + ret = wolfSSL_dtls_cid_use(ssl); + if (ret != WOLFSSL_SUCCESS) { + release(ctx, ssl, "Can't enable DTLS ConnectionID"); + ((func_args*)args)->return_code = ret; + goto exit; + } + ret = wolfSSL_dtls_cid_set(ssl, (byte*)dtlsCID, + (word32)XSTRLEN(dtlsCID)); + if (ret != WOLFSSL_SUCCESS) { + release(ctx, ssl, "Can't set DTLS ConnectionID"); + ((func_args*)args)->return_code = ret; + goto exit; + } + } +#endif /* WOLFSSL_DTLS_CID */ + +#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) { + /* returns the number of polled items or <0 for + * error */ + ret = wolfSSL_AsyncPoll(ssl, + WOLF_POLL_FLAG_CHECK_HW); + if (ret < 0) break; + } + #endif + } + else 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); + 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 + (void)nonBlocking; + ret = NonBlockingSSL_Accept(ssl); +#endif +#ifdef WOLFSSL_EARLY_DATA + EarlyDataStatus(ssl); +#endif + if (ret != WOLFSSL_SUCCESS) { + err = SSL_get_error(ssl, 0); + fprintf(stderr, "SSL_accept error %d, %s\n", err, + ERR_error_string(err, buffer)); + if (!exitWithRet) { + fprintf(stderr, "SSL_accept failed\n"); + } 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) { + SSL_shutdown(ssl); + fprintf(stderr, "SSL in error state\n"); + } + + /* 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) + fprintf(stderr, "error looking up name of established cipher\n"); + + 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)) + fprintf(stderr, "Unexpected mismatch between " + "names of requested and established ciphers.\n"); + else if ((requested_cipherSuite0 != established_cipherSuite0) || + (requested_cipherSuite != established_cipherSuite)) + fprintf(stderr, "Mismatch between IDs of " + "requested and established ciphers.\n"); + } + } + } + +#if defined(OPENSSL_EXTRA) || defined(HAVE_SECRET_CALLBACK) + { + byte* rnd = NULL; + size_t size; + + /* get size of buffer then print */ + size = wolfSSL_get_server_random(NULL, NULL, 0); + if (size == 0) { + fprintf(stderr, "error getting server random buffer size\n"); + } + else { + rnd = (byte*)XMALLOC(size, NULL, DYNAMIC_TYPE_TMP_BUFFER); + } + + if (rnd == NULL) { + fprintf(stderr, "error creating server random buffer\n"); + } + + size = wolfSSL_get_server_random(ssl, rnd, size); + if (size == 0) { + if (rnd) { + XFREE(rnd, NULL, DYNAMIC_TYPE_TMP_BUFFER); + rnd = NULL; + } + fprintf(stderr, "error getting server random buffer\n"); + } + + if (rnd) { + byte* pt; + 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 WOLFSSL_SRTP + if (dtlsSrtpProfiles != NULL) { + err = server_srtp_test(ssl, (func_args*)args); + ((func_args*)args)->return_code = err; + wolfSSL_free(ssl); ssl = NULL; + wolfSSL_CTX_free(ctx); ctx = NULL; + goto exit; + } +#endif /* WOLFSSL_SRTP */ + +#ifdef WOLFSSL_DTLS_CID + if (useDtlsCID && wolfSSL_dtls_cid_is_enabled(ssl)) { + byte receivedCID[DTLS_CID_BUFFER_SIZE]; + unsigned int receivedCIDSz; + printf("CID extension was negotiated\n"); + ret = wolfSSL_dtls_cid_get_tx_size(ssl, &receivedCIDSz); + if (ret != WOLFSSL_SUCCESS) + release(ctx, ssl, "Can't get negotiated DTLS CID size"); + ((func_args*)args)->return_code = ret; + goto exit; + + if (receivedCIDSz > 0) { + ret = wolfSSL_dtls_cid_get_tx(ssl, receivedCID, + DTLS_CID_BUFFER_SIZE - 1); + if (ret != WOLFSSL_SUCCESS) { + release(ctx, ssl, "Can't get negotiated DTLS CID"); + ((func_args*)args)->return_code = ret; + goto exit; + } + + printf("Sending CID is "); + printBuffer(receivedCID, receivedCIDSz); + printf("\n"); + } + else { + printf("other peer provided empty CID\n"); + } + } +#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 (wolfSSL_Rehandshake(ssl) != WOLFSSL_SUCCESS) { + err = wolfSSL_get_error(ssl, 0); + if (err == WOLFSSL_ERROR_WANT_READ || + err == WOLFSSL_ERROR_WANT_WRITE) { + do { + #ifdef WOLFSSL_ASYNC_CRYPT + if (err == WC_PENDING_E) { + ret = wolfSSL_AsyncPoll(ssl, WOLF_POLL_FLAG_CHECK_HW); + if (ret < 0) break; + } + #endif + if (err == APP_DATA_READY) { + if ((ret = wolfSSL_read(ssl, input, sizeof(input)-1)) < 0) { + release(ctx, ssl, + "APP DATA should be present " + "but error returned"); + ((func_args*)args)->return_code = ret; + goto exit; + } + 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 || + err == WC_PENDING_E)); + + if (ret == WOLFSSL_SUCCESS) { + printf("NON-BLOCKING RENEGOTIATION SUCCESSFUL\n"); + err = 0; + } + } + if (ret != WOLFSSL_SUCCESS) { + err = wolfSSL_get_error(ssl, 0); + fprintf(stderr, + "wolfSSL_Rehandshake error %d, %s\n", err, + wolfSSL_ERR_error_string(err, buffer)); + release(ctx, ssl, "non-blocking wolfSSL_Rehandshake failed"); + ((func_args*)args)->return_code = ret; + goto exit; + } + } + } else { + if (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(NO_FILESYSTEM) && !defined(NO_CERTS) + #if defined(WOLFSSL_TLS13) && defined(WOLFSSL_POST_HANDSHAKE_AUTH) + if (postHandAuth) { + + SSL_set_verify(ssl, WOLFSSL_VERIFY_PEER | + ((usePskPlus) ? WOLFSSL_VERIFY_FAIL_EXCEPT_PSK : + WOLFSSL_VERIFY_FAIL_IF_NO_PEER_CERT), 0); + + wolfSSL_request_certificate(ssl); + + } + + #endif +#endif +#if defined(WOLFSSL_TLS13) && defined(HAVE_SESSION_TICKET) + if (sendTicket) { + if (wolfSSL_send_SessionTicket(ssl) != WOLFSSL_SUCCESS) { + fprintf(stderr, "Sending new session ticket failed\n"); + } + else { + fprintf(stderr, "New session ticket sent\n"); + } + } +#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); + /* Got close notify. Ignore it if not expecting a failure. */ + if (err == WOLFSSL_ERROR_ZERO_RETURN && exitWithRet == 0) + err = 0; + 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 defined(WOLFSSL_DTLS13) + if (wolfSSL_dtls(ssl) && version == -4) { + int zero_return = 0; + while (wolfSSL_dtls13_has_pending_msg(ssl)) { + err = + process_handshake_messages(ssl, !nonBlocking, &zero_return); + if (err < 0) { + /* other peer closes the connection, non fatal */ + if (zero_return) + break; + + release(ctx, ssl, "Error while processing pending " + "DTLSv1.3 messages"); + ((func_args*)args)->return_code = ret; + goto exit; + } + } + } +#endif /* WOLFSSL_DTLS13 */ + + ret = SSL_shutdown(ssl); + if (wc_shutdown && ret == WOLFSSL_SHUTDOWN_NOT_DONE) { + while (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"); + break; + } + else if (ret != WOLFSSL_SHUTDOWN_NOT_DONE) { + fprintf(stderr, "Bidirectional shutdown failed\n"); + break; + } + } + if (ret != WOLFSSL_SUCCESS) + fprintf(stderr, "Bidirectional shutdown failed\n"); + } + + /* display collected statistics */ +#ifdef WOLFSSL_STATIC_MEMORY + if (wolfSSL_is_static_memory(ssl, &ssl_stats) != 1) + fprintf(stderr,"static memory was not used with ssl\n"); + + fprintf(stderr, "\nprint off SSL memory stats\n"); + fprintf(stderr, "*** This is memory state before wolfSSL_free is " + "called\n"); + wolfSSL_PrintStatsConn(&ssl_stats); + +#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_CONTEXT_ARGS_OUT_EX4(&wolfsentry, NULL)); + 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 + +#ifdef HAVE_TEST_SESSION_TICKET + 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) ourDhParam; + (void) ourCert; + (void) useX25519; + (void) useX448; +#ifdef HAVE_SECURE_RENEGOTIATION + (void) forceScr; +#endif +#if defined(WOLFSSL_CALLBACKS) && defined(WOLFSSL_EARLY_DATA) + (void) earlyData; +#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; +#if defined(WOLFSSL_SRTP) && !defined(SINGLE_THREADED) && defined(_POSIX_THREADS) + args.srtp_helper = NULL; +#endif + InitTcpReady(&ready); + +#if defined(DEBUG_WOLFSSL) && !defined(WOLFSSL_MDK_SHELL) + wolfSSL_Debugging_ON(); +#endif + wolfSSL_Init(); +#ifdef WC_RNG_SEED_CB + wc_SetSeed_Cb(wc_GenerateSeed); +#endif + ChangeToWolfRoot(); + +#ifndef NO_WOLFSSL_SERVER +#ifdef HAVE_STACK_SIZE + StackSizeCheck(&args, server_test); +#else + server_test(&args); +#endif +#else + fprintf(stderr, "Server not compiled in!\n"); +#endif + + wolfSSL_Cleanup(); + FreeTcpReady(&ready); + + return args.return_code; + } + + int myoptind = 0; + char* myoptarg = NULL; + +#endif /* NO_MAIN_DRIVER */ diff --git a/src/tools/clu_funcs.c b/src/tools/clu_funcs.c index d1c93b07..2fb49be0 100644 --- a/src/tools/clu_funcs.c +++ b/src/tools/clu_funcs.c @@ -84,6 +84,8 @@ static const struct option crypt_algo_options[] = { WOLFCLU_LOG(WOLFCLU_L0, "x509 X509 certificate processing"); WOLFCLU_LOG(WOLFCLU_L0, "verify X509 certificate verify"); WOLFCLU_LOG(WOLFCLU_L0, "pkcs12 Used for parsing PKCS12 files"); + WOLFCLU_LOG(WOLFCLU_L0, "s_server Basic TLS server for testing" + " connection"); WOLFCLU_LOG(WOLFCLU_L0, "s_client Basic TLS client for testing" " connection"); WOLFCLU_LOG(WOLFCLU_L0, "sha256 Creates a SHA256 hash"); diff --git a/tests/server/include.am b/tests/server/include.am new file mode 100644 index 00000000..22cea69b --- /dev/null +++ b/tests/server/include.am @@ -0,0 +1,6 @@ +# vim:ft=automake +# included from top level Makefile.am +# ALl path should be given relative to root directory + +dist_noinst_SCRIPTS+=tests/server/server-test.sh + diff --git a/tests/server/server-test.sh b/tests/server/server-test.sh new file mode 100755 index 00000000..6cdf8352 --- /dev/null +++ b/tests/server/server-test.sh @@ -0,0 +1,46 @@ +#!/bin/bash + +if [ ! -d ./certs/ ]; then + #return 77 to indicate to automake that the test was skipped + exit 77 +fi + +# Skip test if filesystem disabled +FILESYSTEM=`cat config.log | grep "disable\-filesystem"` +if [ "$FILESYSTEM" != "" ] +then + exit 77 +fi + +READYFILE="readyfile" +rm -f $READYFILE + +# Build s_server in background +./wolfssl s_server -port 11111 -key ./certs/server-key.pem\ + -cert ./certs/server-cert.pem -noVerify -readyFile $READYFILE & +pid_server=$! + +counter=0 +# If readyfile exists, the server is considered ready. +while [ ! -e $READYFILE ] && [ "$counter" -lt 100 ]; do + ((counter++)) + sleep 0.01 +done +rm -f $READYFILE + +# Timeout +if [ "$counter" -eq 100 ]; then + echo "s_server was not built successfully." + kill $pid_server + exit 99 +fi + +./wolfssl s_client -connect 127.0.0.1:11111 -CAfile ./certs/ca-cert.pem\ + -verify_return_error -disable_stdin_check +if [ $? != 0 ] ; then + echo "test communication failed." + exit 99 +fi + +echo "Done" +exit 0 \ No newline at end of file diff --git a/wolfCLU.vcxproj b/wolfCLU.vcxproj index 4979284e..53889d18 100644 --- a/wolfCLU.vcxproj +++ b/wolfCLU.vcxproj @@ -162,6 +162,8 @@ + + @@ -189,6 +191,7 @@ + diff --git a/wolfCLU.vcxproj.filters b/wolfCLU.vcxproj.filters index d6834b9e..db78be99 100644 --- a/wolfCLU.vcxproj.filters +++ b/wolfCLU.vcxproj.filters @@ -146,6 +146,9 @@ Header Files + + Header Files + Header Files diff --git a/wolfclu/clu_header_main.h b/wolfclu/clu_header_main.h index e4aba5a1..61c75c2c 100644 --- a/wolfclu/clu_header_main.h +++ b/wolfclu/clu_header_main.h @@ -1,6 +1,6 @@ /* clu_header_main.h * - * Copyright (C) 2006-2021 wolfSSL Inc. + * Copyright (C) 2006-2023 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -550,6 +550,11 @@ void wolfCLU_ForceZero(void* mem, unsigned int len); */ int wolfCLU_Client(int argc, char** argv); +/** + * @brief example server + */ +int wolfCLU_Server(int argc, char** argv); + /** * @brief function to get password from input */ diff --git a/wolfclu/clu_optargs.h b/wolfclu/clu_optargs.h index c523c4af..b4de1aee 100644 --- a/wolfclu/clu_optargs.h +++ b/wolfclu/clu_optargs.h @@ -1,6 +1,6 @@ /* clu_optargs.h * - * Copyright (C) 2006-2021 wolfSSL Inc. + * Copyright (C) 2006-2023 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -39,6 +39,7 @@ enum { WOLFCLU_PKEY, WOLFCLU_PKCS12, WOLFCLU_CLIENT, + WOLFCLU_SERVER, WOLFCLU_CRL, WOLFCLU_RAND, WOLFCLU_RSALEGACY, @@ -46,14 +47,21 @@ enum { WOLFCLU_DSA, WOLFCLU_DH, + WOLFCLU_VERSION, WOLFCLU_CONNECT, WOLFCLU_STARTTLS, WOLFCLU_NODES, WOLFCLU_NOCERTS, WOLFCLU_NOKEYS, + WOLFCLU_KEYFILE, + WOLFCLU_CERTFILE, WOLFCLU_INFILE, WOLFCLU_CAFILE, WOLFCLU_OUTFILE, + WOLFCLU_PORT, + WOLFCLU_ACCEPT, + WOLFCLU_WWW, + WOLFCLU_READY_FILE, WOLFCLU_CHECK_CRL, WOLFCLU_PARTIAL_CHAIN, WOLFCLU_PASSWORD, @@ -97,6 +105,7 @@ enum { WOLFCLU_DEBUG, WOLFCLU_CHECK, WOLFCLU_VERIFY_RETURN_ERROR, + WOLFCLU_DISABLE_STDINCHK, }; /* algos */ diff --git a/wolfclu/include.am b/wolfclu/include.am index fda9f08b..ffd25213 100644 --- a/wolfclu/include.am +++ b/wolfclu/include.am @@ -5,6 +5,7 @@ nobase_include_HEADERS+=wolfclu/version.h \ wolfclu/client.h \ + wolfclu/server.h \ wolfclu/clu_header_main.h \ wolfclu/clu_optargs.h \ wolfclu/clu_log.h \ diff --git a/wolfclu/server.h b/wolfclu/server.h new file mode 100644 index 00000000..4689dffd --- /dev/null +++ b/wolfclu/server.h @@ -0,0 +1,26 @@ +/* server.h + * + * Copyright (C) 2006-2023 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 + */ + +#define NO_MAIN_DRIVER + +#ifndef WOLFCLU_NO_FILESYSTEM +THREAD_RETURN WOLFSSL_THREAD server_test(void* args); +#endif