wolfssl-examples/utasker/wolfSSLClientTask.c

835 lines
24 KiB
C

/****************************************************************************
File Name : wolfSSLClientTask.c
Author : wolfSSL Inc.
Date Created : March 25, 2016
Current Revision : 1.0
Notes : This file contains a simple TLS client task with the goal
of demonstrating how the wolfSSL embedded SSL/TLS library
can be used with the uTasker stack. This client connects
to a server over TLS (using raw TCP sockets), sends an
HTTP GET message, reads the response, and closes
the socket.
Copyright (C) wolfSSL, Inc. 2020
*****************************************************************************/
#include "config.h"
#include "wolfSSLClientTask.h"
#include "wolfssl/wolfcrypt/settings.h"
#include "wolfssl/wolfcrypt/aes.h"
#include "wolfssl/wolfcrypt/rsa.h"
#include "wolfssl/ssl.h"
#define TEST_TCP_PORT 0x80
#define TEST_BUFFER_LENGTH 100
#define MAX_TCP_LENGTH 1460
#define RECV_BUFFER_LENGTH 1500
/* ---------------------------- STRUCTS / ENUMS ---------------------------- */
typedef enum
{
clientInit = 0,
clientCryptoTest = 1,
clientIdle = 2,
clientConnecting = 3,
clientTLSInit = 4,
clientTLSConnect = 5,
clientTLSSend = 6,
clientTLSRecv = 7,
clientShutdown = 8,
} clientStates;
/* func_args from wolfCrypt test.h, so don't have to pull in other stuff */
typedef struct func_args {
int argc;
char** argv;
int return_code;
} func_args;
typedef struct stTCP_MESSAGE
{
TCP_HEADER tTCP_Header;
unsigned char ucTCP_Message[MAX_TCP_LENGTH];
} TCP_MESSAGE;
/* wolfSSL send callback context struct */
typedef struct stUTASKER_SENDCTX {
TCP_MESSAGE* message; /* TCP frame to send */
USOCKET* socket; /* socket pointer */
unsigned int dataLen; /* length of data in message frame */
unsigned char ackd; /* has ACK been received for data (0:1) */
unsigned char flags; /* socket flags, ie: TCP_FLAG_PUSH */
} UTASKER_SENDCTX;
/* wolfSSL recv callback context struct */
typedef struct stUTASKER_RECVCTX {
USOCKET* socket; /* socket pointer */
unsigned int used; /* bytes used in buffer */
unsigned int offset; /* current offset in buffer, for processing */
unsigned int bufLen; /* total size of buffer in bytes */
unsigned char* buffer; /* recv data buffer */
} UTASKER_RECVCTX;
/* ------------------------------- VARIABLES ------------------------------- */
static USOCKET client_socket = 0; /* client socket */
static TCP_MESSAGE stMessage; /* structure to hold TCP frame */
static UTASKER_SENDCTX sendCtx; /* wolfSSL send callback context */
static UTASKER_RECVCTX recvCtx; /* wolfSSL recv callback context */
static unsigned char ucRecvBuffer[RECV_BUFFER_LENGTH]; /* TCP recv buffer */
static clientStates clientState = clientCryptoTest; /* TLS task state */
static WOLFSSL_CTX* sslCtx; /* wolfSSL context context */
static WOLFSSL* ssl; /* wolfSSL session object */
/* server IP address and port */
static unsigned char ucRemoteIP[IPV4_LENGTH] = { 93,184,216,34 };
static unsigned int uiRemotePort = 443;
/* ------------------------------- PROTOTYPES ------------------------------ */
int CacheRecvBuffer(UTASKER_RECVCTX* ctx, unsigned char* data,
unsigned short length);
int ResetRecvBuffer(UTASKER_RECVCTX* ctx);
/* ---------------------------- SOCKET LISTENERS --------------------------- */
static int fnClientListener(USOCKET Socket, unsigned char ucEvent,
unsigned char *ucIp_Data, unsigned short usPortLen)
{
int ret = 0;
switch (ucEvent)
{
case TCP_EVENT_CONREQ:
case TCP_EVENT_CONNECTED:
fnDebugMsg("status: TCP_EVENT_CONNECTED\r\n");
clientState = clientTLSInit;
break;
case TCP_EVENT_ACK:
fnDebugMsg("status: TCP_EVENT_ACK\r\n");
/* ACK received, set ackd variable in CTX msg */
sendCtx.ackd = 1;
break;
case TCP_EVENT_ARP_RESOLUTION_FAILED:
fnDebugMsg("status: TCP_EVENT_ARP_RESOLUTION_FAILED\r\n");
break;
case TCP_EVENT_PARTIAL_ACK:
fnDebugMsg("status: TCP_EVENT_PARTIAL_ACK\r\n");
break;
case TCP_EVENT_REGENERATE:
/* frame lost, need to resend last frame, use cached */
fnDebugMsg("status: TCP_EVENT_REGENERATE\r\n");
if (sendCtx.ackd == 0) {
ret = fnSendTCP(*sendCtx.socket,
(unsigned char*)&sendCtx.message->tTCP_Header,
sendCtx.dataLen, sendCtx.flags);
if (ret > 0) {
return APP_SENT_DATA;
}
}
break;
case TCP_EVENT_DATA:
/* data received from server */
fnDebugMsg("status: TCP_EVENT_DATA\r\n");
/* copy data into our temp context buffer */
if (CacheRecvBuffer(&recvCtx, ucIp_Data, usPortLen) < 0) {
return APP_REJECT_DATA;
}
break;
case TCP_EVENT_ABORT:
case TCP_EVENT_CLOSE:
case TCP_EVENT_CLOSED:
/* server closed connection */
fnDebugMsg("status: TCP_EVENT_CLOSE || TCP_EVENT_CLOSED\r\n");
break;
}
return APP_ACCEPT;
}
/* ---------------------------- HELPER FUNCTIONS --------------------------- */
/*
* Copies received data into context buffer to be processed by app task.
* Returns copied length on success, negative value on error.
*/
int CacheRecvBuffer(UTASKER_RECVCTX* ctx, unsigned char* data,
unsigned short length)
{
if (ctx == NULL || ctx->buffer == NULL || data == NULL)
return -1;
/* error if already in use, or too small */
if (ctx->used > 0 || ctx->bufLen < length)
return -1;
uMemcpy(ctx->buffer, data, length);
ctx->used = length;
return length;
}
/* Resets the context buffer and sizes
* Returns 0 on success, -1 on error */
int ResetRecvBuffer(UTASKER_RECVCTX* ctx)
{
if (ctx == NULL)
return -1;
uMemset(ctx->buffer, 0, ctx->bufLen);
ctx->offset = 0;
ctx->used = 0;
return 0;
}
/* -------------------- wolfSSL SEND/RECV/VERIFY CALLBACKS ----------------- */
/*
* wolfSSL receive callback
*
* This function is called by wolfSSL whenever it needs to read data.
* Returns number of bytes received, or negative error.
* WOLFSSL_CBIO_ERR_WANT_READ should be returned if more data is
* needed to be read and wolfSSL should call this function again.
*/
int UTasker_Receive(WOLFSSL* ssl, char* buf, int sz, void* ctx)
{
unsigned int copied = 0;
UTASKER_RECVCTX* stCtx = (UTASKER_RECVCTX*)ctx;
if (stCtx == NULL || stCtx->buffer == NULL) {
fnDebugMsg("UTasker_Receive invalid parameters\r\n");
return WOLFSSL_CBIO_ERR_GENERAL;
}
/* check for socket closed, if no data left return error */
if ((fnGetTCP_state(*stCtx->socket) & TCP_STATE_CLOSED) &&
(stCtx->used == 0)) {
fnDebugMsg("uTasker_Receive socket closed\r\n");
return WOLFSSL_CBIO_ERR_GENERAL;
}
if (stCtx->used == 0) {
return WOLFSSL_CBIO_ERR_WANT_READ;
}
/* copy either desired sz or number of bytes free in buffer */
copied = min((unsigned int)sz, stCtx->used - stCtx->offset);
uMemcpy(buf, stCtx->buffer + stCtx->offset, copied);
stCtx->offset += copied;
if (stCtx->offset == stCtx->used) {
/* packet has been drained, reset */
stCtx->offset = 0;
stCtx->used = 0;
uMemset(stCtx->buffer, 0, stCtx->bufLen);
}
return copied;
}
/*
* wolfSSL send callback
*
* This function is called by wolfSSL whenever it needs to send data.
* Returns number of bytes sent, or negative error.
* WOLFSSL_CBIO_ERR_WANT_WRITE should be returned if more data is
* needed to be sent and wolfSSL should call this function again.
*/
int UTasker_Send(WOLFSSL* ssl, char* buf, int sz, void* ctx)
{
int ret, send;
UTASKER_SENDCTX* stCtx = (UTASKER_SENDCTX*)ctx;
if (stCtx == NULL || stCtx->socket == NULL || stCtx->message == NULL) {
fnDebugMsg("UTasker_Send, invalid parameters\r\n");
return WOLFSSL_CBIO_ERR_GENERAL;
}
/* return error if socket closed */
if (fnGetTCP_state(*stCtx->socket) & TCP_STATE_CLOSED) {
fnDebugMsg("uTasker_Receive socket closed\r\n");
return WOLFSSL_CBIO_ERR_GENERAL;
}
/* return WANT_WRITE if ACK has not been received for last frame */
if (stCtx->dataLen != 0 && stCtx->ackd == 0) {
return WOLFSSL_CBIO_ERR_WANT_WRITE;
}
send = min(sz, MAX_TCP_LENGTH);
uMemcpy(stCtx->message->ucTCP_Message, buf, send);
stCtx->dataLen = send;
ret = fnSendTCP(*stCtx->socket,
(unsigned char*)&stCtx->message->tTCP_Header,
(unsigned short)send, stCtx->flags);
if (ret == NO_ARP_ENTRY) {
/* dest address must be resolved, try again */
return WOLFSSL_CBIO_ERR_WANT_WRITE;
}
else if (ret <= 0) {
/* no data sent or socket error */
return WOLFSSL_CBIO_ERR_GENERAL;
}
stCtx->ackd = 0;
return (int)send;
}
/*
* wolfSSL verification callback
*
* This function is called when peer certificate verification
* fails. The exact error code can be retrieved through
* store->error. Returning "1" from this function will
* allow the SSL/TLS handshake to continue as if verification
* succeeded. Returning "1" here is not recommended.
*/
int myVerify(int preverify, WOLFSSL_X509_STORE_CTX* store)
{
(void)preverify;
char buffer[80];
fnDebugMsg("In verification callback, error = \r\n");
fnDebugDec(store->error, 0);
fnDebugMsg(", ");
fnDebugMsg(wolfSSL_ERR_error_string(store->error, buffer));
fnDebugMsg("\r\n");
return 0;
}
/* ------------------------------- APP TASK -------------------------------- */
/*
* wolfSSL client app task
*/
extern void fnTLSClientTask(TTASKTABLE *ptrTaskTable)
{
int ret, errorCode, msgSz = 0;
char msg[64];
char reply[1024];
/* run crypto tests */
if (clientState == clientCryptoTest)
{
fnDebugMsg("Starting wolfSSL Client Task\r\n");
ret = WolfCryptTest();
if (ret == 0) {
fnDebugMsg("status: wolfCrypt Tests Passed!\r\n\r\n");
clientState = clientInit;
}
else {
fnDebugMsg("ERROR: wolfCrypt Tests Failed!\r\n\r\n");
clientState = clientIdle;
}
}
/* init socket and app state */
if (clientState == clientInit)
{
/* create socket */
client_socket = fnGetTCP_Socket(TOS_MINIMISE_DELAY,
TCP_DEFAULT_TIMEOUT,
fnClientListener);
if (client_socket >= 0) {
fnDebugMsg("status: Created socket\r\n");
clientState = clientConnecting;
}
}
/* connect socket */
if (clientState == clientConnecting)
{
ret = fnTCP_Connect(client_socket, ucRemoteIP,
uiRemotePort, 0, 0);
if (ret != client_socket) {
fnDebugMsg("ERROR: fnTCP_Connect() failed\r\n");
clientState = clientIdle;
}
else {
fnDebugMsg("status: Socket connected\r\n");
clientState = clientTLSInit;
}
}
/* set up SSL/TLS context */
if (clientState == clientTLSInit)
{
/* for debug, compile wolfSSL with DEBUG_WOLFSSL defined */
/* wolfSSL_Debugging_ON(); */
wolfSSL_Init();
/* create wolfSSL context */
sslCtx = wolfSSL_CTX_new(wolfTLSv1_2_client_method());
if (sslCtx == NULL) {
fnDebugMsg("ERROR: wolfSSL_CTX_new() failed\r\n");
clientState = clientShutdown;
}
else {
fnDebugMsg("status: Created WOLFSSL_CTX\r\n");
}
/* turn on peer verification, register callback */
wolfSSL_CTX_set_verify(sslCtx, SSL_VERIFY_PEER, myVerify);
fnDebugMsg("status: Enabled peer verification\r\n");
/* load root CA certificate to verify peer */
ret = wolfSSL_CTX_load_verify_buffer(sslCtx, digicert_ca_2048,
sizeof(digicert_ca_2048),
SSL_FILETYPE_ASN1);
if (ret != SSL_SUCCESS) {
fnDebugMsg("ERROR: wolfSSL_CTX_load_verify_buffer\r\n");
clientState = clientShutdown;
}
else {
fnDebugMsg("status: Loaded trusted CA certificates\r\n");
}
/* set up wolfSSL send/recv context details */
sendCtx.socket = &client_socket;
sendCtx.message = &stMessage;
sendCtx.ackd = 0;
sendCtx.dataLen = 0;
sendCtx.flags = 0;
recvCtx.socket = &client_socket;
recvCtx.buffer = ucRecvBuffer;
recvCtx.bufLen = sizeof(ucRecvBuffer);
/* register wolfSSL send/recv callbacks */
wolfSSL_SetIOSend(sslCtx, UTasker_Send);
wolfSSL_SetIORecv(sslCtx, UTasker_Receive);
/* create wolfSSL session */
ssl = wolfSSL_new(sslCtx);
if (ssl == NULL) {
fnDebugMsg("ERROR: wolfSSL_new\r\n");
clientState = clientShutdown;
}
else {
fnDebugMsg("status: Created WOLFSSL session object\r\n");
}
/* register wolfSSL read/write callback contexts */
wolfSSL_SetIOReadCtx(ssl, &recvCtx);
wolfSSL_SetIOWriteCtx(ssl, &sendCtx);
clientState = clientTLSConnect;
}
/* perform SSL/TLS handshake with peer */
if (clientState == clientTLSConnect)
{
ret = wolfSSL_connect(ssl);
errorCode = wolfSSL_get_error(ssl, ret);
if (ret != SSL_SUCCESS && (errorCode != SSL_ERROR_WANT_READ &&
errorCode != SSL_ERROR_WANT_WRITE)) {
fnDebugMsg("ERROR: wolfSSL_connect: ");
errorCode = wolfSSL_get_error(ssl, ret);
fnDebugDec(errorCode, DISPLAY_NEGATIVE);
fnDebugMsg("\r\n");
clientState = clientShutdown;
}
else if (ret == SSL_SUCCESS) {
fnDebugMsg("wolfSSL_connect() ok, sending GET...\r\n");
clientState = clientTLSSend;
}
}
/* send HTTP GET over SSL/TLS */
if (clientState == clientTLSSend)
{
msgSz = 28;
strncpy(msg, "GET /index.html HTTP/1.0\r\n\r\n", msgSz);
ret = wolfSSL_write(ssl, msg, msgSz);
errorCode = wolfSSL_get_error(ssl, ret);
if (errorCode != SSL_ERROR_WANT_WRITE) {
if (ret != msgSz) {
fnDebugMsg("ERROR: wolfSSL_write() failed: ");
errorCode = wolfSSL_get_error(ssl, ret);
fnDebugDec(errorCode, DISPLAY_NEGATIVE);
fnDebugMsg("\r\n");
clientState = clientShutdown;
}
else {
clientState = clientTLSRecv;
}
}
}
/* read server response */
if (clientState == clientTLSRecv)
{
ret = wolfSSL_read(ssl, reply, sizeof(reply) - 1);
errorCode = wolfSSL_get_error(ssl, ret);
if (errorCode != SSL_ERROR_WANT_READ) {
if (ret > 0) {
fnDebugMsg("Server response: ");
reply[ret] = 0;
fnDebugMsg(reply);
fnDebugMsg("\r\n");
}
else if (ret < 0) {
fnDebugMsg("ERROR: wolfSSL_read() failed: ");
errorCode = wolfSSL_get_error(ssl, ret);
fnDebugDec(errorCode, DISPLAY_NEGATIVE);
fnDebugMsg("\r\n");
}
clientState = clientShutdown;
}
}
/* free resources and shutdown */
if (clientState == clientShutdown)
{
fnReleaseTCP_Socket(client_socket);
wolfSSL_free(ssl);
wolfSSL_CTX_free(sslCtx);
wolfSSL_Cleanup();
fnDebugMsg("status: Released Resources\r\n");
clientState = clientIdle;
}
}
/* ------------------------- wolfCrypt CRYPTO TESTS ------------------------ */
int WolfCryptTest(void)
{
int ret;
#if !defined(NO_BIG_INT)
if (CheckCtcSettings() != 1) {
fnDebugMsg("ERROR: Build vs runtime math mismatch\r\n");
}
#ifdef USE_FAST_MATH
if (CheckFastMathSettings() != 1) {
fnDebugMsg("ERROR: Build vs runtime fastmath FP_MAX_BITS \
mismatch\r\n");
clientState = clientIdle;
}
#endif /* USE_FAST_MATH */
#endif /* NO_BIG_INT */
#ifndef NO_MD5
if ((ret = md5_test()) != 0)
fnDebugMsg("MD5 test failed!\r\n");
else
fnDebugMsg("MD5 test passed!\r\n");
#endif
#ifdef WOLFSSL_MD2
if ((ret = md2_test()) != 0)
fnDebugMsg("MD2 test failed!\r\n");
else
fnDebugMsg("MD2 test passed!\r\n");
#endif
#ifndef NO_MD4
if ((ret = md4_test()) != 0)
fnDebugMsg("MD4 test failed!\r\n");
else
fnDebugMsg("MD4 test passed!\r\n");
#endif
#ifndef NO_SHA
if ((ret = sha_test()) != 0)
fnDebugMsg("SHA test failed!\r\n");
else
fnDebugMsg("SHA test passed!\r\n");
#endif
#ifndef NO_SHA256
if ((ret = sha256_test()) != 0)
fnDebugMsg("SHA-256 test failed!\r\n");
else
fnDebugMsg("SHA-256 test passed!\r\n");
#endif
#ifdef WOLFSSL_SHA384
if ((ret = sha384_test()) != 0)
fnDebugMsg("SHA-384 test failed!\r\n");
else
fnDebugMsg("SHA-384 test passed!\r\n");
#endif
#ifdef WOLFSSL_SHA512
if ((ret = sha512_test()) != 0)
fnDebugMsg("SHA-512 test failed!\r\n");
else
fnDebugMsg("SHA-512 test passed!\r\n");
#endif
#ifdef WOLFSSL_RIPEMD
if ((ret = ripemd_test()) != 0)
fnDebugMsg("RIPEMD test failed!\r\n");
else
fnDebugMsg("RIPEMD test passed!\r\n");
#endif
#ifdef HAVE_BLAKE2
if ((ret = blake2b_test()) != 0)
fnDebugMsg("BLAKE2b test failed!\r\n");
else
fnDebugMsg("BLAKE2b test passed!\r\n");
#endif
#ifndef NO_HMAC
#ifndef NO_MD5
if ((ret = hmac_md5_test()) != 0)
fnDebugMsg("HMAC-MD5 test failed!\r\n");
else
fnDebugMsg("HMAC-MD5 test passed!\r\n");
#endif
#ifndef NO_SHA
if ((ret = hmac_sha_test()) != 0)
fnDebugMsg("HMAC-SHA test failed!\r\n");
else
fnDebugMsg("HMAC-SHA test passed!\r\n");
#endif
#ifndef NO_SHA256
if ((ret = hmac_sha256_test()) != 0)
fnDebugMsg("HMAC-SHA256 test failed!\r\n");
else
fnDebugMsg("HMAC-SHA256 test passed!\r\n");
#endif
#ifdef WOLFSSL_SHA384
if ((ret = hmac_sha384_test()) != 0)
fnDebugMsg("HMAC-SHA384 test failed!\r\n");
else
fnDebugMsg("HMAC-SHA384 test passed!\r\n");
#endif
#ifdef WOLFSSL_SHA512
if ((ret = hmac_sha512_test()) != 0)
fnDebugMsg("HMAC-SHA512 test failed!\r\n");
else
fnDebugMsg("HMAC-SHA512 test passed!\r\n");
#endif
#ifdef HAVE_BLAKE2
if ((ret = hmac_blake2b_test()) != 0)
fnDebugMsg("HMAC-BLAKE2 test failed!\r\n");
else
fnDebugMsg("HMAC-BLAKE2 test passed!\r\n");
#endif
#ifdef HAVE_HKDF
if ((ret = hkdf_test()) != 0)
fnDebugMsg("HMAC-KDF test failed!\r\n");
else
fnDebugMsg("HMAC-KDF test passed!\r\n");
#endif
#endif
#ifdef HAVE_AESGCM
if ((ret = gmac_test()) != 0)
fnDebugMsg("GMAC test failed!\r\n");
else
fnDebugMsg("GMAC test passed!\r\n");
#endif
#ifndef NO_RC4
if ((ret = arc4_test()) != 0)
fnDebugMsg("ARC4 test failed!\r\n");
else
fnDebugMsg("ARC4 test passed!\r\n");
#endif
#ifdef HAVE_CHACHA
if ((ret = chacha_test()) != 0)
fnDebugMsg("Chacha test failed!\r\n");
else
fnDebugMsg("Chacha test passed!\r\n");
#endif
#ifdef HAVE_POLY1305
if ((ret = poly1305_test()) != 0)
fnDebugMsg("POLY1305 test failed!\r\n");
else
fnDebugMsg("POLY1305 test passed!\r\n");
#endif
#if defined(HAVE_CHACHA) && defined(HAVE_POLY1305)
if ((ret = chacha20_poly1305_aead_test()) != 0)
fnDebugMsg("ChaCha20-Poly1305 AEAD test failed!\r\n");
else
fnDebugMsg("ChaCha20-Poly1305 AEAD test passed!\r\n");
#endif
#ifndef NO_DES3
if ((ret = des_test()) != 0)
fnDebugMsg("DES test failed!\r\n");
else
fnDebugMsg("DES test passed!\r\n");
#endif
#ifndef NO_DES3
if ((ret = des3_test()) != 0)
fnDebugMsg("DES3 test failed!\r\n");
else
fnDebugMsg("DES3 test passed!\r\n");
#endif
#ifndef NO_AES
if ((ret = aes_test()) != 0)
fnDebugMsg("AES test failed!\r\n");
else
fnDebugMsg("AES test passed!\r\n");
#ifdef HAVE_AESGCM
if ((ret = aesgcm_test()) != 0)
fnDebugMsg("AES-GCM test failed!\r\n");
else
fnDebugMsg("AES-GCM test passed!\r\n");
#endif
#ifdef HAVE_AESCCM
if ((ret = aesccm_test()) != 0)
fnDebugMsg("AES-CCM test failed!\r\n");
else
fnDebugMsg("AES-CCM test passed!\r\n");
#endif
#endif
#ifdef HAVE_CAMELLIA
if ((ret = camellia_test()) != 0)
fnDebugMsg("CAMELLIA test failed!\r\n");
else
fnDebugMsg("CAMELLIA test passed!\r\n");
#endif
if ((ret = random_test()) != 0)
fnDebugMsg("RANDOM test failed!\r\n");
else
fnDebugMsg("RANDOM test passed!\r\n");
#ifndef NO_RSA
if ((ret = rsa_test()) != 0)
fnDebugMsg("RSA test failed!\r\n");
else
fnDebugMsg("RSA test passed!\r\n");
#endif
#if defined(WOLFSSL_CERT_EXT) && defined(WOLFSSL_TEST_CERT)
if ((ret = certext_test()) != 0)
fnDebugMsg("CERT EXT test failed!\r\n");
else
fnDebugMsg("CERT EXT test passed!\r\n");
#endif
#ifndef NO_DH
if ((ret = dh_test()) != 0)
fnDebugMsg("DH test failed!\r\n");
else
fnDebugMsg("DH test passed!\r\n");
#endif
#ifndef NO_DSA
if ((ret = dsa_test()) != 0)
fnDebugMsg("DSA test failed!\r\n");
else
fnDebugMsg("DSA test passed!\r\n");
#endif
#ifdef WOLFCRYPT_HAVE_SRP
if ((ret = srp_test()) != 0)
fnDebugMsg("SRP test failed!\r\n");
else
fnDebugMsg("SRP test passed!\r\n");
#endif
#ifndef NO_PWDBASED
if ((ret = pwdbased_test()) != 0)
fnDebugMsg("PWDBASED test failed!\r\n");
else
fnDebugMsg("PWDBASED test passed!\r\n");
#endif
#ifdef OPENSSL_EXTRA
if ((ret = openssl_test()) != 0)
fnDebugMsg("OPENSSL test failed!\r\n");
else
fnDebugMsg("OPENSSL test passed!\r\n");
#endif
#ifdef HAVE_ECC
if ((ret = ecc_test()) != 0)
fnDebugMsg("ECC test failed!\r\n");
else
fnDebugMsg("ECC test passed!\r\n");
#ifdef HAVE_ECC_ENCRYPT
if ((ret = ecc_encrypt_test()) != 0)
fnDebugMsg("ECC Enc test failed!\r\n");
else
fnDebugMsg("ECC Enc test passed!\r\n");
#endif
#endif
#ifdef HAVE_CURVE25519
if ((ret = curve25519_test()) != 0)
fnDebugMsg("CURVE25519 test failed!\r\n");
else
fnDebugMsg("CURVE25519 test passed!\r\n");
#endif
#ifdef HAVE_ED25519
if ((ret = ed25519_test()) != 0)
fnDebugMsg("ED25519 test failed!\r\n");
else
fnDebugMsg("ED25519 test passed!\r\n");
#endif
#ifdef HAVE_LIBZ
if ((ret = compress_test()) != 0)
fnDebugMsg("COMPRESS test failed!\r\n");
else
fnDebugMsg("COMPRESS test passed!\r\n");
#endif
#ifdef HAVE_PKCS7
if ((ret = pkcs7enveloped_test()) != 0)
fnDebugMsg("PKCS7enveloped test failed!\r\n");
else
fnDebugMsg("PKCS7enveloped test passed!\r\n");
if ((ret = pkcs7signed_test()) != 0)
fnDebugMsg("PKCS7signed test failed!\r\n");
else
fnDebugMsg("PKCS7signed test passed!\r\n");
#endif
return 0;
}