mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2026-01-27 10:42:21 +01:00
1. Update the example client and server to test DTLS-SCTP. 2. Modify the test.h functions for setting up connections to allow for a SCTP option. 3. Update other examples to use the new test.h functions. 4. Removed some prototypes in the client header file were some functions that should have been static to the client.c file and made them static.
1220 lines
36 KiB
C
1220 lines
36 KiB
C
/* server.c
|
|
*
|
|
* Copyright (C) 2006-2016 wolfSSL Inc.
|
|
*
|
|
* This file is part of wolfSSL.
|
|
*
|
|
* wolfSSL is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* wolfSSL is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
|
|
*/
|
|
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
#include <config.h>
|
|
#endif
|
|
#include <cyassl/ssl.h> /* name change portability layer */
|
|
|
|
#include <cyassl/ctaocrypt/settings.h>
|
|
#ifdef HAVE_ECC
|
|
#include <cyassl/ctaocrypt/ecc.h> /* ecc_fp_free */
|
|
#endif
|
|
|
|
#if !defined(WOLFSSL_TRACK_MEMORY) && !defined(NO_MAIN_DRIVER)
|
|
/* in case memory tracker wants stats */
|
|
#define WOLFSSL_TRACK_MEMORY
|
|
#endif
|
|
|
|
#if defined(WOLFSSL_MDK_ARM) || defined(WOLFSSL_KEIL_TCP_NET)
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
|
|
#if !defined(WOLFSSL_MDK_ARM)
|
|
#include "cmsis_os.h"
|
|
#include "rl_fs.h"
|
|
#include "rl_net.h"
|
|
#else
|
|
#include "rtl.h"
|
|
#include "wolfssl_MDK_ARM.h"
|
|
#endif
|
|
|
|
|
|
#endif
|
|
#include <cyassl/openssl/ssl.h>
|
|
#include <cyassl/test.h>
|
|
|
|
#include "examples/server/server.h"
|
|
|
|
#ifdef WOLFSSL_ASYNC_CRYPT
|
|
static int devId = INVALID_DEVID;
|
|
#endif
|
|
|
|
/* 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. */
|
|
|
|
#ifdef CYASSL_CALLBACKS
|
|
int srvHandShakeCB(HandShakeInfo*);
|
|
int srvTimeoutCB(TimeoutInfo*);
|
|
Timeval srvTo;
|
|
#endif
|
|
|
|
#ifndef NO_HANDSHAKE_DONE_CB
|
|
int myHsDoneCb(WOLFSSL* ssl, void* user_ctx);
|
|
#endif
|
|
|
|
|
|
|
|
static int NonBlockingSSL_Accept(SSL* ssl)
|
|
{
|
|
#ifndef CYASSL_CALLBACKS
|
|
int ret = SSL_accept(ssl);
|
|
#else
|
|
int ret = CyaSSL_accept_ex(ssl, srvHandShakeCB, srvTimeoutCB, srvTo);
|
|
#endif
|
|
int error = SSL_get_error(ssl, 0);
|
|
SOCKET_T sockfd = (SOCKET_T)CyaSSL_get_fd(ssl);
|
|
int select_ret;
|
|
|
|
while (ret != SSL_SUCCESS && (error == SSL_ERROR_WANT_READ ||
|
|
error == SSL_ERROR_WANT_WRITE)) {
|
|
int currTimeout = 1;
|
|
|
|
if (error == SSL_ERROR_WANT_READ) {
|
|
/* printf("... server would read block\n"); */
|
|
} else {
|
|
/* printf("... server would write block\n"); */
|
|
}
|
|
|
|
#ifdef CYASSL_DTLS
|
|
currTimeout = CyaSSL_dtls_get_current_timeout(ssl);
|
|
#endif
|
|
select_ret = tcp_select(sockfd, currTimeout);
|
|
|
|
if ((select_ret == TEST_RECV_READY) ||
|
|
(select_ret == TEST_ERROR_READY)) {
|
|
#ifndef CYASSL_CALLBACKS
|
|
ret = SSL_accept(ssl);
|
|
#else
|
|
ret = CyaSSL_accept_ex(ssl,
|
|
srvHandShakeCB, srvTimeoutCB, srvTo);
|
|
#endif
|
|
error = SSL_get_error(ssl, 0);
|
|
}
|
|
else if (select_ret == TEST_TIMEOUT && !CyaSSL_dtls(ssl)) {
|
|
error = SSL_ERROR_WANT_READ;
|
|
}
|
|
#ifdef CYASSL_DTLS
|
|
else if (select_ret == TEST_TIMEOUT && CyaSSL_dtls(ssl) &&
|
|
CyaSSL_dtls_got_timeout(ssl) >= 0) {
|
|
error = SSL_ERROR_WANT_READ;
|
|
}
|
|
#endif
|
|
else {
|
|
error = SSL_FATAL_ERROR;
|
|
}
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
/* Echo number of bytes specified by -e arg */
|
|
int ServerEchoData(SSL* ssl, int clientfd, int echoData, int throughput)
|
|
{
|
|
int ret = 0;
|
|
char* buffer = (char*)malloc(TEST_BUFFER_SIZE);
|
|
if(buffer) {
|
|
double start = 0, rx_time = 0, tx_time = 0;
|
|
int xfer_bytes = 0;
|
|
while((echoData && throughput == 0) || (!echoData && xfer_bytes < throughput)) {
|
|
int select_ret = tcp_select(clientfd, 1); /* Timeout=1 second */
|
|
if (select_ret == TEST_RECV_READY) {
|
|
int len = min(TEST_BUFFER_SIZE, throughput - xfer_bytes);
|
|
int rx_pos = 0;
|
|
if(throughput) {
|
|
start = current_time(1);
|
|
}
|
|
while(rx_pos < len) {
|
|
ret = SSL_read(ssl, &buffer[rx_pos], len - rx_pos);
|
|
if (ret <= 0) {
|
|
int readErr = SSL_get_error(ssl, 0);
|
|
if (readErr != SSL_ERROR_WANT_READ) {
|
|
printf("SSL_read error %d!\n", readErr);
|
|
err_sys("SSL_read failed");
|
|
}
|
|
}
|
|
else {
|
|
rx_pos += ret;
|
|
}
|
|
}
|
|
if(throughput) {
|
|
rx_time += current_time(0) - start;
|
|
start = current_time(1);
|
|
}
|
|
if (SSL_write(ssl, buffer, len) != len) {
|
|
err_sys("SSL_write failed");
|
|
}
|
|
if(throughput) {
|
|
tx_time += current_time(0) - start;
|
|
}
|
|
|
|
xfer_bytes += len;
|
|
}
|
|
}
|
|
free(buffer);
|
|
|
|
if(throughput) {
|
|
printf("wolfSSL Server Benchmark %d bytes\n"
|
|
"\tRX %8.3f ms (%8.3f MBps)\n"
|
|
"\tTX %8.3f ms (%8.3f MBps)\n",
|
|
throughput,
|
|
tx_time * 1000, throughput / tx_time / 1024 / 1024,
|
|
rx_time * 1000, throughput / rx_time / 1024 / 1024
|
|
);
|
|
}
|
|
}
|
|
else {
|
|
err_sys("Server buffer malloc failed");
|
|
}
|
|
|
|
return EXIT_SUCCESS;
|
|
}
|
|
|
|
|
|
static void Usage(void)
|
|
{
|
|
printf("server " LIBCYASSL_VERSION_STRING
|
|
" NOTE: All files relative to wolfSSL home dir\n");
|
|
printf("-? Help, print this usage\n");
|
|
printf("-p <num> Port to listen on, not 0, default %d\n", yasslPort);
|
|
printf("-v <num> SSL version [0-3], SSLv3(0) - TLS1.2(3)), default %d\n",
|
|
SERVER_DEFAULT_VERSION);
|
|
printf("-l <str> Cipher suite list (: delimited)\n");
|
|
printf("-c <file> Certificate file, default %s\n", svrCert);
|
|
printf("-k <file> Key file, default %s\n", svrKey);
|
|
printf("-A <file> Certificate Authority file, default %s\n", cliCert);
|
|
printf("-R <file> Create Ready file for external monitor default none\n");
|
|
#ifndef NO_DH
|
|
printf("-D <file> Diffie-Hellman Params file, default %s\n", dhParam);
|
|
printf("-Z <num> Minimum DH key bits, default %d\n",
|
|
DEFAULT_MIN_DHKEY_BITS);
|
|
#endif
|
|
#ifdef HAVE_ALPN
|
|
printf("-L <str> Application-Layer Protocol Negotiation ({C,F}:<list>)\n");
|
|
#endif
|
|
printf("-d Disable client cert check\n");
|
|
printf("-b Bind to any interface instead of localhost only\n");
|
|
printf("-s Use pre Shared keys\n");
|
|
printf("-t Track wolfSSL memory use\n");
|
|
printf("-u Use UDP DTLS,"
|
|
" add -v 2 for DTLSv1, -v 3 for DTLSv1.2 (default)\n");
|
|
#ifdef WOLFSSL_SCTP
|
|
printf("-G Use SCTP DTLS,"
|
|
" add -v 2 for DTLSv1, -v 3 for DTLSv1.2 (default)\n");
|
|
#endif
|
|
printf("-f Fewer packets/group messages\n");
|
|
printf("-r Allow one client Resumption\n");
|
|
printf("-N Use Non-blocking sockets\n");
|
|
printf("-S <str> Use Host Name Indication\n");
|
|
printf("-w Wait for bidirectional shutdown\n");
|
|
#ifdef HAVE_OCSP
|
|
printf("-o Perform OCSP lookup on peer certificate\n");
|
|
printf("-O <url> Perform OCSP lookup using <url> as responder\n");
|
|
#endif
|
|
#ifdef HAVE_PK_CALLBACKS
|
|
printf("-P Public Key Callbacks\n");
|
|
#endif
|
|
#ifdef HAVE_ANON
|
|
printf("-a Anonymous server\n");
|
|
#endif
|
|
#ifndef NO_PSK
|
|
printf("-I Do not send PSK identity hint\n");
|
|
#endif
|
|
printf("-i Loop indefinitely (allow repeated connections)\n");
|
|
printf("-e Echo data mode (return raw bytes received)\n");
|
|
#ifdef HAVE_NTRU
|
|
printf("-n Use NTRU key (needed for NTRU suites)\n");
|
|
#endif
|
|
printf("-B <num> Benchmark throughput using <num> bytes and print stats\n");
|
|
#ifdef WOLFSSL_TRUST_PEER_CERT
|
|
printf("-E <file> Path to load trusted peer cert\n");
|
|
#endif
|
|
#ifdef HAVE_WNR
|
|
printf("-q <file> Whitewood config file, default %s\n", wnrConfig);
|
|
#endif
|
|
}
|
|
|
|
THREAD_RETURN CYASSL_THREAD server_test(void* args)
|
|
{
|
|
SOCKET_T sockfd = WOLFSSL_SOCKET_INVALID;
|
|
SOCKET_T clientfd = WOLFSSL_SOCKET_INVALID;
|
|
|
|
wolfSSL_method_func method = NULL;
|
|
SSL_CTX* ctx = 0;
|
|
SSL* ssl = 0;
|
|
|
|
#ifndef WOLFSSL_ALT_TEST_STRINGS
|
|
const char msg[] = "I hear you fa shizzle!";
|
|
#else
|
|
const char msg[] = "I hear you fa shizzle!\n";
|
|
#endif
|
|
char input[80];
|
|
int ch;
|
|
int version = SERVER_DEFAULT_VERSION;
|
|
int doCliCertCheck = 1;
|
|
int useAnyAddr = 0;
|
|
word16 port = wolfSSLPort;
|
|
int usePsk = 0;
|
|
int usePskPlus = 0;
|
|
int useAnon = 0;
|
|
int doDTLS = 0;
|
|
int dtlsUDP = 0;
|
|
int dtlsSCTP = 0;
|
|
int needDH = 0;
|
|
int useNtruKey = 0;
|
|
int nonBlocking = 0;
|
|
int trackMemory = 0;
|
|
int fewerPackets = 0;
|
|
int pkCallbacks = 0;
|
|
int wc_shutdown = 0;
|
|
int resume = 0;
|
|
int resumeCount = 0;
|
|
int loopIndefinitely = 0;
|
|
int echoData = 0;
|
|
int 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;
|
|
const char* verifyCert = cliCert;
|
|
const char* ourCert = svrCert;
|
|
const char* ourKey = svrKey;
|
|
const char* ourDhParam = dhParam;
|
|
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_OCSP
|
|
int useOcsp = 0;
|
|
char* ocspUrl = NULL;
|
|
#endif
|
|
|
|
#ifdef HAVE_WNR
|
|
const char* wnrConfigFile = wnrConfig;
|
|
#endif
|
|
|
|
#ifdef WOLFSSL_STATIC_MEMORY
|
|
#if (defined(HAVE_ECC) && !defined(ALT_ECC_SIZE)) \
|
|
|| defined(SESSION_CERTS)
|
|
/* big enough to handle most cases including session certs */
|
|
byte memory[204000];
|
|
#else
|
|
byte memory[80000];
|
|
#endif
|
|
byte memoryIO[34500]; /* max of 17k for IO buffer (TLS packet can be 16k) */
|
|
WOLFSSL_MEM_CONN_STATS ssl_stats;
|
|
#endif
|
|
|
|
((func_args*)args)->return_code = -1; /* error state */
|
|
|
|
#ifdef NO_RSA
|
|
verifyCert = (char*)cliEccCert;
|
|
ourCert = (char*)eccCert;
|
|
ourKey = (char*)eccKey;
|
|
#endif
|
|
(void)pkCallbacks;
|
|
(void)needDH;
|
|
(void)ourKey;
|
|
(void)ourCert;
|
|
(void)ourDhParam;
|
|
(void)verifyCert;
|
|
(void)useNtruKey;
|
|
(void)doCliCertCheck;
|
|
(void)minDhKeyBits;
|
|
(void)minRsaKeyBits;
|
|
(void)minEccKeyBits;
|
|
(void)alpnList;
|
|
(void)alpn_opt;
|
|
(void)crlFlags;
|
|
(void)readySignal;
|
|
|
|
#ifdef CYASSL_TIRTOS
|
|
fdOpenSession(Task_self());
|
|
#endif
|
|
|
|
#ifdef WOLFSSL_VXWORKS
|
|
useAnyAddr = 1;
|
|
#else
|
|
while ((ch = mygetopt(argc, argv,
|
|
"?jdbstnNuGfrawPIR:p:v:l:A:c:k:Z:S:oO:D:L:ieB:E:q:")) != -1) {
|
|
switch (ch) {
|
|
case '?' :
|
|
Usage();
|
|
exit(EXIT_SUCCESS);
|
|
|
|
case 'd' :
|
|
doCliCertCheck = 0;
|
|
break;
|
|
|
|
case 'b' :
|
|
useAnyAddr = 1;
|
|
break;
|
|
|
|
case 's' :
|
|
usePsk = 1;
|
|
break;
|
|
|
|
case 'j' :
|
|
usePskPlus = 1;
|
|
break;
|
|
|
|
case 't' :
|
|
#ifdef USE_WOLFSSL_MEMORY
|
|
trackMemory = 1;
|
|
#endif
|
|
break;
|
|
|
|
case 'n' :
|
|
useNtruKey = 1;
|
|
break;
|
|
|
|
case 'u' :
|
|
doDTLS = 1;
|
|
dtlsUDP = 1;
|
|
break;
|
|
|
|
case 'G' :
|
|
#ifdef WOLFSSL_SCTP
|
|
doDTLS = 1;
|
|
dtlsSCTP = 1;
|
|
#endif
|
|
break;
|
|
|
|
case 'f' :
|
|
fewerPackets = 1;
|
|
break;
|
|
|
|
case 'R' :
|
|
serverReadyFile = myoptarg;
|
|
break;
|
|
|
|
case 'r' :
|
|
#ifndef NO_SESSION_CACHE
|
|
resume = 1;
|
|
#endif
|
|
break;
|
|
|
|
case 'P' :
|
|
#ifdef HAVE_PK_CALLBACKS
|
|
pkCallbacks = 1;
|
|
#endif
|
|
break;
|
|
|
|
case 'p' :
|
|
port = (word16)atoi(myoptarg);
|
|
break;
|
|
|
|
case 'w' :
|
|
wc_shutdown = 1;
|
|
break;
|
|
|
|
case 'v' :
|
|
version = atoi(myoptarg);
|
|
if (version < 0 || version > 3) {
|
|
Usage();
|
|
exit(MY_EX_USAGE);
|
|
}
|
|
break;
|
|
|
|
case 'l' :
|
|
cipherList = myoptarg;
|
|
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();
|
|
exit(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();
|
|
exit(MY_EX_USAGE);
|
|
}
|
|
|
|
alpnList += 2;
|
|
|
|
#endif
|
|
break;
|
|
|
|
case 'i' :
|
|
loopIndefinitely = 1;
|
|
break;
|
|
|
|
case 'e' :
|
|
echoData = 1;
|
|
break;
|
|
|
|
case 'B':
|
|
throughput = atoi(myoptarg);
|
|
if (throughput <= 0) {
|
|
Usage();
|
|
exit(MY_EX_USAGE);
|
|
}
|
|
break;
|
|
|
|
#ifdef WOLFSSL_TRUST_PEER_CERT
|
|
case 'E' :
|
|
trustCert = myoptarg;
|
|
break;
|
|
#endif
|
|
|
|
case 'q' :
|
|
#ifdef HAVE_WNR
|
|
wnrConfigFile = myoptarg;
|
|
#endif
|
|
break;
|
|
|
|
default:
|
|
Usage();
|
|
exit(MY_EX_USAGE);
|
|
}
|
|
}
|
|
|
|
myoptind = 0; /* reset for test cases */
|
|
#endif /* !WOLFSSL_VXWORKS */
|
|
|
|
/* Can only use DTLS over UDP or SCTP, can't do both. */
|
|
if (dtlsUDP && dtlsSCTP) {
|
|
err_sys("Cannot use DTLS with both UDP and SCTP.");
|
|
}
|
|
|
|
/* sort out DTLS versus TLS versions */
|
|
if (version == CLIENT_INVALID_VERSION) {
|
|
if (doDTLS)
|
|
version = CLIENT_DTLS_DEFAULT_VERSION;
|
|
else
|
|
version = CLIENT_DEFAULT_VERSION;
|
|
}
|
|
else {
|
|
if (doDTLS) {
|
|
if (version == 3)
|
|
version = -2;
|
|
else
|
|
version = -1;
|
|
}
|
|
}
|
|
|
|
#if defined(USE_CYASSL_MEMORY) && !defined(WOLFSSL_STATIC_MEMORY)
|
|
if (trackMemory)
|
|
InitMemoryTracker();
|
|
#endif
|
|
|
|
#ifdef HAVE_WNR
|
|
if (wc_InitNetRandom(wnrConfigFile, NULL, 5000) != 0)
|
|
err_sys("can't load whitewood net random config file");
|
|
#endif
|
|
|
|
switch (version) {
|
|
#ifndef NO_OLD_TLS
|
|
#ifdef WOLFSSL_ALLOW_SSLV3
|
|
case 0:
|
|
method = wolfSSLv3_server_method_ex;
|
|
break;
|
|
#endif
|
|
|
|
#ifndef NO_TLS
|
|
case 1:
|
|
method = wolfTLSv1_server_method_ex;
|
|
break;
|
|
|
|
|
|
case 2:
|
|
method = wolfTLSv1_1_server_method_ex;
|
|
break;
|
|
|
|
#endif
|
|
#endif
|
|
|
|
#ifndef NO_TLS
|
|
case 3:
|
|
method = wolfTLSv1_2_server_method_ex;
|
|
break;
|
|
#endif
|
|
|
|
#ifdef CYASSL_DTLS
|
|
#ifndef NO_OLD_TLS
|
|
case -1:
|
|
method = wolfDTLSv1_server_method_ex;
|
|
break;
|
|
#endif
|
|
|
|
case -2:
|
|
method = wolfDTLSv1_2_server_method_ex;
|
|
break;
|
|
#endif
|
|
|
|
default:
|
|
err_sys("Bad SSL version");
|
|
}
|
|
|
|
if (method == NULL)
|
|
err_sys("unable to get method");
|
|
|
|
#ifdef WOLFSSL_STATIC_MEMORY
|
|
#ifdef DEBUG_WOLFSSL
|
|
/* print off helper buffer sizes for use with static memory
|
|
* printing to stderr incase 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)
|
|
!= SSL_SUCCESS)
|
|
err_sys("unable to load static memory and create ctx");
|
|
|
|
/* load in a buffer for IO */
|
|
if (wolfSSL_CTX_load_static_memory(&ctx, NULL, memoryIO, sizeof(memoryIO),
|
|
WOLFMEM_IO_POOL_FIXED | WOLFMEM_TRACK_STATS, 1)
|
|
!= SSL_SUCCESS)
|
|
err_sys("unable to load static memory and create ctx");
|
|
#else
|
|
ctx = SSL_CTX_new(method(NULL));
|
|
#endif
|
|
if (ctx == NULL)
|
|
err_sys("unable to get ctx");
|
|
|
|
#if defined(HAVE_SESSION_TICKET) && defined(HAVE_CHACHA) && \
|
|
defined(HAVE_POLY1305)
|
|
if (TicketInit() != 0)
|
|
err_sys("unable to setup Session Ticket Key context");
|
|
wolfSSL_CTX_set_TicketEncCb(ctx, myTicketEncCb);
|
|
#endif
|
|
|
|
if (cipherList)
|
|
if (SSL_CTX_set_cipher_list(ctx, cipherList) != SSL_SUCCESS)
|
|
err_sys("server can't set cipher list 1");
|
|
|
|
#ifdef CYASSL_LEANPSK
|
|
if (!usePsk) {
|
|
usePsk = 1;
|
|
}
|
|
#endif
|
|
|
|
#if defined(NO_RSA) && !defined(HAVE_ECC)
|
|
if (!usePsk) {
|
|
usePsk = 1;
|
|
}
|
|
#endif
|
|
|
|
if (fewerPackets)
|
|
CyaSSL_CTX_set_group_messages(ctx);
|
|
|
|
#ifdef WOLFSSL_SCTP
|
|
if (dtlsSCTP)
|
|
wolfSSL_CTX_dtls_set_sctp(ctx);
|
|
#endif
|
|
|
|
#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
|
|
SSL_CTX_set_default_passwd_cb(ctx, PasswordCallBack);
|
|
#endif
|
|
|
|
#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS)
|
|
if ((!usePsk || usePskPlus) && !useAnon) {
|
|
if (SSL_CTX_use_certificate_chain_file(ctx, ourCert)
|
|
!= SSL_SUCCESS)
|
|
err_sys("can't load server cert file, check file and run from"
|
|
" wolfSSL home dir");
|
|
}
|
|
#endif
|
|
|
|
#ifndef NO_DH
|
|
if (wolfSSL_CTX_SetMinDhKey_Sz(ctx, (word16)minDhKeyBits) != SSL_SUCCESS) {
|
|
err_sys("Error setting minimum DH key size");
|
|
}
|
|
#endif
|
|
#ifndef NO_RSA
|
|
if (wolfSSL_CTX_SetMinRsaKey_Sz(ctx, minRsaKeyBits) != SSL_SUCCESS){
|
|
err_sys("Error setting minimum RSA key size");
|
|
}
|
|
#endif
|
|
#ifdef HAVE_ECC
|
|
if (wolfSSL_CTX_SetMinEccKey_Sz(ctx, minEccKeyBits) != SSL_SUCCESS){
|
|
err_sys("Error setting minimum ECC key size");
|
|
}
|
|
#endif
|
|
|
|
#ifdef HAVE_NTRU
|
|
if (useNtruKey) {
|
|
if (CyaSSL_CTX_use_NTRUPrivateKey_file(ctx, ourKey)
|
|
!= SSL_SUCCESS)
|
|
err_sys("can't load ntru key file, "
|
|
"Please run from wolfSSL home dir");
|
|
}
|
|
#endif
|
|
#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS)
|
|
if (!useNtruKey && (!usePsk || usePskPlus) && !useAnon) {
|
|
if (SSL_CTX_use_PrivateKey_file(ctx, ourKey, SSL_FILETYPE_PEM)
|
|
!= SSL_SUCCESS)
|
|
err_sys("can't load server private key file, check file and run "
|
|
"from wolfSSL home dir");
|
|
}
|
|
#endif
|
|
|
|
if (usePsk || usePskPlus) {
|
|
#ifndef NO_PSK
|
|
SSL_CTX_set_psk_server_callback(ctx, my_psk_server_cb);
|
|
|
|
if (sendPskIdentityHint == 1)
|
|
SSL_CTX_use_psk_identity_hint(ctx, "cyassl server");
|
|
|
|
if (cipherList == NULL && !usePskPlus) {
|
|
const char *defaultCipherList;
|
|
#if defined(HAVE_AESGCM) && !defined(NO_DH)
|
|
defaultCipherList = "DHE-PSK-AES128-GCM-SHA256";
|
|
needDH = 1;
|
|
#elif defined(HAVE_NULL_CIPHER)
|
|
defaultCipherList = "PSK-NULL-SHA256";
|
|
#else
|
|
defaultCipherList = "PSK-AES128-CBC-SHA256";
|
|
#endif
|
|
if (SSL_CTX_set_cipher_list(ctx, defaultCipherList) != SSL_SUCCESS)
|
|
err_sys("server can't set cipher list 2");
|
|
}
|
|
#endif
|
|
}
|
|
|
|
if (useAnon) {
|
|
#ifdef HAVE_ANON
|
|
CyaSSL_CTX_allow_anon_cipher(ctx);
|
|
if (cipherList == NULL) {
|
|
if (SSL_CTX_set_cipher_list(ctx, "ADH-AES128-SHA") != SSL_SUCCESS)
|
|
err_sys("server can't set cipher list 4");
|
|
}
|
|
#endif
|
|
}
|
|
|
|
#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS)
|
|
/* if not using PSK, verify peer with certs
|
|
if using PSK Plus then verify peer certs except PSK suites */
|
|
if (doCliCertCheck && (usePsk == 0 || usePskPlus) && useAnon == 0) {
|
|
SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER |
|
|
((usePskPlus)? SSL_VERIFY_FAIL_EXCEPT_PSK :
|
|
SSL_VERIFY_FAIL_IF_NO_PEER_CERT),0);
|
|
if (SSL_CTX_load_verify_locations(ctx, verifyCert, 0) != SSL_SUCCESS)
|
|
err_sys("can't load ca file, Please run from wolfSSL home dir");
|
|
#ifdef WOLFSSL_TRUST_PEER_CERT
|
|
if (trustCert) {
|
|
if ((ret = wolfSSL_CTX_trust_peer_cert(ctx, trustCert,
|
|
SSL_FILETYPE_PEM)) != SSL_SUCCESS) {
|
|
err_sys("can't load trusted peer cert file");
|
|
}
|
|
}
|
|
#endif /* WOLFSSL_TRUST_PEER_CERT */
|
|
}
|
|
#endif
|
|
|
|
#if defined(CYASSL_SNIFFER)
|
|
/* don't use EDH, can't sniff tmp keys */
|
|
if (cipherList == NULL) {
|
|
if (SSL_CTX_set_cipher_list(ctx, "AES128-SHA") != SSL_SUCCESS)
|
|
err_sys("server can't set cipher list 3");
|
|
}
|
|
#endif
|
|
|
|
#ifdef HAVE_SNI
|
|
if (sniHostName)
|
|
if (CyaSSL_CTX_UseSNI(ctx, CYASSL_SNI_HOST_NAME, sniHostName,
|
|
XSTRLEN(sniHostName)) != SSL_SUCCESS)
|
|
err_sys("UseSNI failed");
|
|
#endif
|
|
|
|
#ifdef USE_WINDOWS_API
|
|
if (port == 0) {
|
|
/* Generate random port for testing */
|
|
port = GetRandomPort();
|
|
}
|
|
#endif /* USE_WINDOWS_API */
|
|
|
|
#ifdef WOLFSSL_ASYNC_CRYPT
|
|
ret = wolfAsync_DevOpen(&devId);
|
|
if (ret != 0) {
|
|
err_sys("Async device open failed");
|
|
}
|
|
wolfSSL_CTX_UseAsync(ctx, devId);
|
|
#endif /* WOLFSSL_ASYNC_CRYPT */
|
|
|
|
while (1) {
|
|
/* allow resume option */
|
|
if(resumeCount > 1) {
|
|
if (dtlsUDP == 0) {
|
|
SOCKADDR_IN_T client;
|
|
socklen_t client_len = sizeof(client);
|
|
clientfd = accept(sockfd, (struct sockaddr*)&client,
|
|
(ACCEPT_THIRD_T)&client_len);
|
|
} else {
|
|
tcp_listen(&sockfd, &port, useAnyAddr, dtlsUDP, dtlsSCTP);
|
|
clientfd = sockfd;
|
|
}
|
|
if(WOLFSSL_SOCKET_IS_INVALID(clientfd)) {
|
|
err_sys("tcp accept failed");
|
|
}
|
|
}
|
|
#if defined(WOLFSSL_STATIC_MEMORY) && defined(DEBUG_WOLFSSL)
|
|
{
|
|
WOLFSSL_MEM_STATS mem_stats;
|
|
fprintf(stderr, "Before creating SSL\n");
|
|
if (wolfSSL_CTX_is_static_memory(ctx, &mem_stats) != 1)
|
|
err_sys("ctx not using static memory");
|
|
if (wolfSSL_PrintStats(&mem_stats) != 1) /* function in test.h */
|
|
err_sys("error printing out memory stats");
|
|
}
|
|
#endif
|
|
|
|
ssl = SSL_new(ctx);
|
|
if (ssl == NULL)
|
|
err_sys("unable to get SSL");
|
|
|
|
#if defined(WOLFSSL_STATIC_MEMORY) && defined(DEBUG_WOLFSSL)
|
|
{
|
|
WOLFSSL_MEM_STATS mem_stats;
|
|
fprintf(stderr, "After creating SSL\n");
|
|
if (wolfSSL_CTX_is_static_memory(ctx, &mem_stats) != 1)
|
|
err_sys("ctx not using static memory");
|
|
if (wolfSSL_PrintStats(&mem_stats) != 1) /* function in test.h */
|
|
err_sys("error printing out memory stats");
|
|
}
|
|
#endif
|
|
|
|
#ifndef NO_HANDSHAKE_DONE_CB
|
|
wolfSSL_SetHsDoneCb(ssl, myHsDoneCb, NULL);
|
|
#endif
|
|
#ifdef HAVE_CRL
|
|
#ifdef HAVE_CRL_MONITOR
|
|
crlFlags = CYASSL_CRL_MONITOR | CYASSL_CRL_START_MON;
|
|
#endif
|
|
if (CyaSSL_EnableCRL(ssl, 0) != SSL_SUCCESS)
|
|
err_sys("unable to enable CRL");
|
|
if (CyaSSL_LoadCRL(ssl, crlPemDir, SSL_FILETYPE_PEM, crlFlags)
|
|
!= SSL_SUCCESS)
|
|
err_sys("unable to load CRL");
|
|
if (CyaSSL_SetCRL_Cb(ssl, CRL_CallBack) != SSL_SUCCESS)
|
|
err_sys("unable to set CRL callback url");
|
|
#endif
|
|
#ifdef HAVE_OCSP
|
|
if (useOcsp) {
|
|
if (ocspUrl != NULL) {
|
|
CyaSSL_CTX_SetOCSP_OverrideURL(ctx, ocspUrl);
|
|
CyaSSL_CTX_EnableOCSP(ctx, CYASSL_OCSP_NO_NONCE
|
|
| CYASSL_OCSP_URL_OVERRIDE);
|
|
}
|
|
else
|
|
CyaSSL_CTX_EnableOCSP(ctx, CYASSL_OCSP_NO_NONCE);
|
|
}
|
|
#endif
|
|
#if defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
|
|
|| defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
|
|
if (wolfSSL_CTX_EnableOCSPStapling(ctx) != SSL_SUCCESS)
|
|
err_sys("can't enable OCSP Stapling Certificate Manager");
|
|
if (SSL_CTX_load_verify_locations(ctx, "certs/ocsp/intermediate1-ca-cert.pem", 0) != SSL_SUCCESS)
|
|
err_sys("can't load ca file, Please run from wolfSSL home dir");
|
|
if (SSL_CTX_load_verify_locations(ctx, "certs/ocsp/intermediate2-ca-cert.pem", 0) != SSL_SUCCESS)
|
|
err_sys("can't load ca file, Please run from wolfSSL home dir");
|
|
if (SSL_CTX_load_verify_locations(ctx, "certs/ocsp/intermediate3-ca-cert.pem", 0) != SSL_SUCCESS)
|
|
err_sys("can't load ca file, Please run from wolfSSL home dir");
|
|
#endif
|
|
#ifdef HAVE_PK_CALLBACKS
|
|
if (pkCallbacks)
|
|
SetupPkCallbacks(ctx, ssl);
|
|
#endif
|
|
|
|
/* do accept */
|
|
readySignal = ((func_args*)args)->signal;
|
|
if (readySignal) {
|
|
readySignal->srfName = serverReadyFile;
|
|
}
|
|
tcp_accept(&sockfd, &clientfd, (func_args*)args, port, useAnyAddr,
|
|
dtlsUDP, dtlsSCTP, serverReadyFile ? 1 : 0, doListen);
|
|
doListen = 0; /* Don't listen next time */
|
|
|
|
if (SSL_set_fd(ssl, clientfd) != SSL_SUCCESS) {
|
|
err_sys("error in setting fd");
|
|
}
|
|
|
|
#ifdef HAVE_ALPN
|
|
if (alpnList != NULL) {
|
|
printf("ALPN accepted protocols list : %s\n", alpnList);
|
|
wolfSSL_UseALPN(ssl, alpnList, (word32)XSTRLEN(alpnList), alpn_opt);
|
|
}
|
|
#endif
|
|
|
|
#ifdef WOLFSSL_DTLS
|
|
if (doDTLS && dtlsUDP) {
|
|
SOCKADDR_IN_T cliaddr;
|
|
byte b[1500];
|
|
int n;
|
|
socklen_t len = sizeof(cliaddr);
|
|
|
|
/* 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(sockfd, (char*)b, sizeof(b), MSG_PEEK,
|
|
(struct sockaddr*)&cliaddr, &len);
|
|
if (n <= 0)
|
|
err_sys("recvfrom failed");
|
|
|
|
wolfSSL_dtls_set_peer(ssl, &cliaddr, len);
|
|
}
|
|
#endif
|
|
if ((usePsk == 0 || usePskPlus) || useAnon == 1 || cipherList != NULL
|
|
|| needDH == 1) {
|
|
#if !defined(NO_FILESYSTEM) && !defined(NO_DH) && !defined(NO_ASN)
|
|
CyaSSL_SetTmpDH_file(ssl, ourDhParam, SSL_FILETYPE_PEM);
|
|
#elif !defined(NO_DH)
|
|
SetDH(ssl); /* repick suites with DHE, higher priority than PSK */
|
|
#endif
|
|
}
|
|
|
|
#ifndef CYASSL_CALLBACKS
|
|
if (nonBlocking) {
|
|
CyaSSL_set_using_nonblock(ssl, 1);
|
|
tcp_set_nonblocking(&clientfd);
|
|
}
|
|
#endif
|
|
|
|
do {
|
|
#ifdef WOLFSSL_ASYNC_CRYPT
|
|
if (err == WC_PENDING_E) {
|
|
ret = wolfSSL_AsyncPoll(ssl, WOLF_POLL_FLAG_CHECK_HW);
|
|
if (ret < 0) { break; } else if (ret == 0) { continue; }
|
|
}
|
|
#endif
|
|
|
|
err = 0; /* Reset error */
|
|
#ifndef CYASSL_CALLBACKS
|
|
if (nonBlocking) {
|
|
ret = NonBlockingSSL_Accept(ssl);
|
|
}
|
|
else {
|
|
ret = SSL_accept(ssl);
|
|
}
|
|
#else
|
|
ret = NonBlockingSSL_Accept(ssl);
|
|
#endif
|
|
if (ret != SSL_SUCCESS) {
|
|
err = SSL_get_error(ssl, 0);
|
|
}
|
|
} while (ret != SSL_SUCCESS && err == WC_PENDING_E);
|
|
|
|
if (ret != SSL_SUCCESS) {
|
|
char buffer[CYASSL_MAX_ERROR_SZ];
|
|
err = SSL_get_error(ssl, 0);
|
|
printf("error = %d, %s\n", err, ERR_error_string(err, buffer));
|
|
err_sys("SSL_accept failed");
|
|
}
|
|
|
|
showPeer(ssl);
|
|
|
|
#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 == SSL_SUCCESS)
|
|
printf("Sent ALPN protocol : %s (%d)\n",
|
|
protocol_name, protocol_nameSz);
|
|
else if (err == SSL_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 == SSL_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) {
|
|
ret = SSL_read(ssl, input, sizeof(input)-1);
|
|
if (ret > 0) {
|
|
input[ret] = 0;
|
|
printf("Client message: %s\n", input);
|
|
|
|
}
|
|
else if (ret < 0) {
|
|
int readErr = SSL_get_error(ssl, 0);
|
|
if (readErr != SSL_ERROR_WANT_READ)
|
|
err_sys("SSL_read failed");
|
|
}
|
|
|
|
if (SSL_write(ssl, msg, sizeof(msg)) != sizeof(msg))
|
|
err_sys("SSL_write failed");
|
|
}
|
|
else {
|
|
ServerEchoData(ssl, clientfd, echoData, throughput);
|
|
}
|
|
|
|
#if defined(WOLFSSL_MDK_SHELL) && defined(HAVE_MDK_RTX)
|
|
os_dly_wait(500) ;
|
|
#elif defined (CYASSL_TIRTOS)
|
|
Task_yield();
|
|
#endif
|
|
|
|
if (dtlsUDP == 0) {
|
|
ret = SSL_shutdown(ssl);
|
|
if (wc_shutdown && ret == SSL_SHUTDOWN_NOT_DONE)
|
|
SSL_shutdown(ssl); /* bidirectional shutdown */
|
|
}
|
|
/* display collected statistics */
|
|
#ifdef WOLFSSL_STATIC_MEMORY
|
|
if (wolfSSL_is_static_memory(ssl, &ssl_stats) != 1)
|
|
err_sys("static memory was not used with ssl");
|
|
|
|
fprintf(stderr, "\nprint off SSL memory stats\n");
|
|
fprintf(stderr, "*** This is memory state before wolfSSL_free is called\n");
|
|
fprintf(stderr, "peak connection memory = %d\n", ssl_stats.peakMem);
|
|
fprintf(stderr, "current memory in use = %d\n", ssl_stats.curMem);
|
|
fprintf(stderr, "peak connection allocs = %d\n", ssl_stats.peakAlloc);
|
|
fprintf(stderr, "current connection allocs = %d\n",ssl_stats.curAlloc);
|
|
fprintf(stderr, "total connection allocs = %d\n",ssl_stats.totalAlloc);
|
|
fprintf(stderr, "total connection frees = %d\n\n", ssl_stats.totalFr);
|
|
|
|
#endif
|
|
SSL_free(ssl);
|
|
|
|
CloseSocket(clientfd);
|
|
|
|
if (resume == 1 && resumeCount == 0) {
|
|
resumeCount++; /* only do one resume for testing */
|
|
continue;
|
|
}
|
|
resumeCount = 0;
|
|
|
|
if(!loopIndefinitely) {
|
|
break; /* out of while loop, done with normal and resume option */
|
|
}
|
|
} /* while(1) */
|
|
|
|
|
|
CloseSocket(sockfd);
|
|
SSL_CTX_free(ctx);
|
|
|
|
((func_args*)args)->return_code = 0;
|
|
|
|
|
|
#if defined(NO_MAIN_DRIVER) && defined(HAVE_ECC) && defined(FP_ECC) \
|
|
&& defined(HAVE_THREAD_LS)
|
|
ecc_fp_free(); /* free per thread cache */
|
|
#endif
|
|
|
|
#if defined(USE_WOLFSSL_MEMORY) && !defined(WOLFSSL_STATIC_MEMORY)
|
|
if (trackMemory)
|
|
ShowMemoryTracker();
|
|
#endif
|
|
|
|
#ifdef CYASSL_TIRTOS
|
|
fdCloseSession(Task_self());
|
|
#endif
|
|
|
|
#if defined(HAVE_SESSION_TICKET) && defined(HAVE_CHACHA) && \
|
|
defined(HAVE_POLY1305)
|
|
TicketCleanup();
|
|
#endif
|
|
|
|
#ifdef WOLFSSL_ASYNC_CRYPT
|
|
wolfAsync_DevClose(&devId);
|
|
#endif
|
|
|
|
/* There are use cases when these assignments are not read. To avoid
|
|
* potential confusion those warnings have been handled here.
|
|
*/
|
|
(void) ourKey;
|
|
(void) verifyCert;
|
|
(void) doCliCertCheck;
|
|
(void) useNtruKey;
|
|
(void) ourDhParam;
|
|
(void) ourCert;
|
|
(void) trackMemory;
|
|
#ifndef CYASSL_TIRTOS
|
|
return 0;
|
|
#endif
|
|
}
|
|
|
|
|
|
/* 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;
|
|
InitTcpReady(&ready);
|
|
|
|
#if defined(DEBUG_CYASSL) && !defined(WOLFSSL_MDK_SHELL)
|
|
CyaSSL_Debugging_ON();
|
|
#endif
|
|
CyaSSL_Init();
|
|
ChangeToWolfRoot();
|
|
|
|
#ifdef HAVE_STACK_SIZE
|
|
StackSizeCheck(&args, server_test);
|
|
#else
|
|
server_test(&args);
|
|
#endif
|
|
CyaSSL_Cleanup();
|
|
FreeTcpReady(&ready);
|
|
|
|
#ifdef HAVE_WNR
|
|
if (wc_FreeNetRandom() < 0)
|
|
err_sys("Failed to free netRandom context");
|
|
#endif /* HAVE_WNR */
|
|
|
|
return args.return_code;
|
|
}
|
|
|
|
int myoptind = 0;
|
|
char* myoptarg = NULL;
|
|
|
|
#endif /* NO_MAIN_DRIVER */
|
|
|
|
|
|
#ifdef CYASSL_CALLBACKS
|
|
|
|
int srvHandShakeCB(HandShakeInfo* info)
|
|
{
|
|
(void)info;
|
|
return 0;
|
|
}
|
|
|
|
|
|
int srvTimeoutCB(TimeoutInfo* info)
|
|
{
|
|
(void)info;
|
|
return 0;
|
|
}
|
|
|
|
#endif
|
|
|
|
#ifndef NO_HANDSHAKE_DONE_CB
|
|
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
|