Add some samples for embedded use/testing
parent
fcd440fa6e
commit
7ed94abe13
|
@ -161,3 +161,11 @@ pk/ED25519/gen_key_files
|
|||
pk/ED25519/sign_and_verify
|
||||
|
||||
wolfCLU/tests/somejunk/*somejunk*.txt
|
||||
|
||||
embedded/tls-client-server
|
||||
embedded/tls-sock-client
|
||||
embedded/tls-sock-client-ca
|
||||
embedded/tls-sock-server
|
||||
embedded/tls-sock-server-ca
|
||||
embedded/tls-sock-threaded
|
||||
embedded/tls-threaded
|
||||
|
|
|
@ -0,0 +1,102 @@
|
|||
# TLS Examples Makefile
|
||||
CC = gcc
|
||||
LIB_PATH = /usr/local
|
||||
CFLAGS = -Wall -I$(LIB_PATH)/include
|
||||
LIBS = -L$(LIB_PATH)/lib -lm
|
||||
|
||||
# option variables
|
||||
DYN_LIB = -lwolfssl
|
||||
STATIC_LIB = $(LIB_PATH)/lib/libwolfssl.a
|
||||
DEBUG_FLAGS = -g -DDEBUG
|
||||
DEBUG_INC_PATHS = -MD
|
||||
OPTIMIZE = -Os
|
||||
|
||||
# Options
|
||||
#CFLAGS+=$(DEBUG_FLAGS)
|
||||
CFLAGS+=$(OPTIMIZE)
|
||||
#CFLAGS+=$(QAT_FLAGS)
|
||||
#LIBS+=$(QAT_LIBS)
|
||||
#LIBS+=$(STATIC_LIB)
|
||||
LIBS+=$(DYN_LIB)
|
||||
|
||||
# build targets
|
||||
SRC=$(wildcard *.c)
|
||||
TARGETS=$(patsubst %.c, %, $(SRC))
|
||||
LINUX_SPECIFIC=client-tls-perf \
|
||||
server-tls-epoll-perf \
|
||||
server-tls-epoll-threaded
|
||||
|
||||
|
||||
# Intel QuickAssist
|
||||
QAT_PATH=../../QAT1.6
|
||||
QAT_FLAGS=-DDO_CRYPTO -DUSER_SPACE \
|
||||
-I$(QAT_PATH)/quickassist/include \
|
||||
-I$(QAT_PATH)/quickassist/include/lac \
|
||||
-I$(QAT_PATH)/quickassist/utilities/osal/include \
|
||||
-I$(QAT_PATH)/quickassist/utilities/osal/src/linux/user_space/include \
|
||||
-I$(QAT_PATH)/quickassist/lookaside/access_layer/include \
|
||||
-I$(QAT_PATH)/quickassist/lookaside/access_layer/src/common/include
|
||||
QAT_LIBS=-L$(QAT_PATH) -ladf_proxy -losal -licp_qa_al_s -lpthread
|
||||
|
||||
|
||||
# OS / CPU Detection
|
||||
OS_DET=UNKNOWN
|
||||
CPU_DET=UNKNOWN
|
||||
ifeq ($(OS),Windows_NT)
|
||||
OS_DET=WIN32
|
||||
ifeq ($(PROCESSOR_ARCHITEW6432),AMD64)
|
||||
CPU_DET=AMD64
|
||||
else
|
||||
ifeq ($(PROCESSOR_ARCHITECTURE),AMD64)
|
||||
CPU_DET=AMD64
|
||||
endif
|
||||
ifeq ($(PROCESSOR_ARCHITECTURE),x86)
|
||||
CPU_DET=IA32
|
||||
endif
|
||||
endif
|
||||
else
|
||||
UNAME_S := $(shell uname -s)
|
||||
ifeq ($(UNAME_S),Linux)
|
||||
OS_DET=LINUX
|
||||
endif
|
||||
ifeq ($(UNAME_S),Darwin)
|
||||
OS_DET=OSX
|
||||
endif
|
||||
UNAME_P := $(shell uname -p)
|
||||
ifeq ($(UNAME_P),x86_64)
|
||||
CPU_DET=AMD64
|
||||
endif
|
||||
ifneq ($(filter %86,$(UNAME_P)),)
|
||||
CPU_DET=IA32
|
||||
endif
|
||||
ifneq ($(filter arm%,$(UNAME_P)),)
|
||||
CPU_DET=ARM
|
||||
endif
|
||||
endif
|
||||
|
||||
# $(info $$OS_DET is [${OS_DET}])
|
||||
# $(info $$CPU_DET is [${CPU_DET}])
|
||||
|
||||
.PHONY: clean all
|
||||
|
||||
ifneq ($(OS_DET),LINUX)
|
||||
all: $(filter-out $(LINUX_SPECIFIC), $(TARGETS))
|
||||
else
|
||||
all: $(TARGETS)
|
||||
endif
|
||||
|
||||
debug: CFLAGS+=$(DEBUG_FLAGS)
|
||||
debug: all
|
||||
|
||||
# add the -pthread flag to any threaded examples
|
||||
%-threaded: CFLAGS+=-pthread
|
||||
|
||||
# compile tcp examples without the LIBS variable
|
||||
%-tcp: LIBS=
|
||||
|
||||
# build template
|
||||
%: %.c *.h
|
||||
$(CC) -o $@ $< $(CFLAGS) $(LIBS)
|
||||
|
||||
clean:
|
||||
rm -f $(TARGETS)
|
|
@ -0,0 +1,62 @@
|
|||
/* certs.h
|
||||
*
|
||||
* Copyright (C) 2006-2019 wolfSSL Inc.
|
||||
*
|
||||
* This file is part of wolfSSL. (formerly known as CyaSSL)
|
||||
*
|
||||
* 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-1301, USA
|
||||
*/
|
||||
|
||||
|
||||
/* Use the certificate buffers instead of using filesystem. */
|
||||
#ifndef NO_RSA
|
||||
#define USE_CERT_BUFFERS_2048
|
||||
#define SERVER_CERT server_cert_der_2048
|
||||
#define SERVER_CERT_LEN sizeof_server_cert_der_2048
|
||||
#define SERVER_KEY server_key_der_2048
|
||||
#define SERVER_KEY_LEN sizeof_server_key_der_2048
|
||||
#define CA_CERTS ca_cert_der_2048
|
||||
#define CA_CERTS_LEN sizeof_ca_cert_der_2048
|
||||
#define CLIENT_CERT client_cert_der_2048
|
||||
#define CLIENT_CERT_LEN sizeof_client_cert_der_2048
|
||||
#define CLIENT_KEY client_key_der_2048
|
||||
#define CLIENT_KEY_LEN sizeof_client_key_der_2048
|
||||
#elif defined(HAVE_ECC)
|
||||
#define USE_CERT_BUFFERS_256
|
||||
#define SERVER_CERT serv_ecc_der_256
|
||||
#define SERVER_CERT_LEN sizeof_serv_ecc_der_256
|
||||
#define SERVER_KEY ecc_key_der_256
|
||||
#define SERVER_KEY_LEN sizeof_ecc_key_der_256
|
||||
#define CA_CERTS ca_ecc_cert_der_256
|
||||
#define CA_CERTS_LEN sizeof_ca_ecc_cert_der_256
|
||||
#define CLIENT_CERT cliecc_cert_der_256
|
||||
#define CLIENT_CERT_LEN sizeof_cliecc_cert_der_256
|
||||
#define CLIENT_KEY ecc_clikey_der_256
|
||||
#define CLIENT_KEY_LEN sizeof_ecc_clikey_der_256
|
||||
#elif defined(HAVE_ED25519)
|
||||
#define SERVER_CERT server_ed25519_cert
|
||||
#define SERVER_CERT_LEN sizeof_server_ed25519_cert
|
||||
#define SERVER_KEY server_ed25519_key
|
||||
#define SERVER_KEY_LEN sizeof_server_ed25519_key
|
||||
#define CA_CERTS ca_ed25519_cert
|
||||
#define CA_CERTS_LEN sizeof_ca_ed25519_cert
|
||||
#define CLIENT_CERT client_ed25519_cert
|
||||
#define CLIENT_CERT_LEN sizeof_client_ed25519_cert
|
||||
#define CLIENT_KEY client_ed25519_key
|
||||
#define CLIENT_KEY_LEN sizeof_client_ed25519_key
|
||||
#endif
|
||||
|
||||
#include <wolfssl/certs_test.h>
|
||||
|
|
@ -0,0 +1,605 @@
|
|||
/* sockets.h
|
||||
*
|
||||
* Copyright (C) 2006-2019 wolfSSL Inc.
|
||||
*
|
||||
* This file is part of wolfSSL. (formerly known as CyaSSL)
|
||||
*
|
||||
* 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-1301, USA
|
||||
*/
|
||||
|
||||
|
||||
#ifdef USE_WINDOWS_API
|
||||
#include <winsock2.h>
|
||||
#ifdef TEST_IPV6 /* don't require newer SDK for IPV4 */
|
||||
#include <ws2tcpip.h>
|
||||
#include <wspiapi.h>
|
||||
#endif
|
||||
#define SOCKET_T SOCKET
|
||||
#define SNPRINTF _snprintf
|
||||
#elif defined(WOLFSSL_MDK_ARM) || defined(WOLFSSL_KEIL_TCP_NET)
|
||||
#include <string.h>
|
||||
#include "rl_net.h"
|
||||
#define SOCKET_T int
|
||||
typedef int socklen_t ;
|
||||
static unsigned long inet_addr(const char *cp)
|
||||
{
|
||||
unsigned int a[4] ; unsigned long ret ;
|
||||
sscanf(cp, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]) ;
|
||||
ret = ((a[3]<<24) + (a[2]<<16) + (a[1]<<8) + a[0]) ;
|
||||
return(ret) ;
|
||||
}
|
||||
#if defined(HAVE_KEIL_RTX)
|
||||
#define sleep(t) os_dly_wait(t/1000+1) ;
|
||||
#elif defined (WOLFSSL_CMSIS_RTOS)
|
||||
#define sleep(t) osDelay(t/1000+1) ;
|
||||
#endif
|
||||
#elif defined(WOLFSSL_TIRTOS)
|
||||
#include <string.h>
|
||||
#include <netdb.h>
|
||||
#include <sys/types.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/socket.h>
|
||||
#include <ti/sysbios/knl/Task.h>
|
||||
struct hostent {
|
||||
char *h_name; /* official name of host */
|
||||
char **h_aliases; /* alias list */
|
||||
int h_addrtype; /* host address type */
|
||||
int h_length; /* length of address */
|
||||
char **h_addr_list; /* list of addresses from name server */
|
||||
};
|
||||
#define SOCKET_T int
|
||||
#elif defined(WOLFSSL_VXWORKS)
|
||||
#include <hostLib.h>
|
||||
#include <sockLib.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <string.h>
|
||||
#include <selectLib.h>
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/time.h>
|
||||
#include <netdb.h>
|
||||
#define SOCKET_T int
|
||||
#elif defined(WOLFSSL_ZEPHYR)
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <net/socket.h>
|
||||
#define SOCKET_T int
|
||||
#define SOL_SOCKET 1
|
||||
#define SO_REUSEADDR 201
|
||||
#define WOLFSSL_USE_GETADDRINFO
|
||||
|
||||
static unsigned long inet_addr(const char *cp)
|
||||
{
|
||||
unsigned int a[4]; unsigned long ret;
|
||||
int i, j;
|
||||
for (i=0, j=0; i<4; i++) {
|
||||
a[i] = 0;
|
||||
while (cp[j] != '.' && cp[j] != '\0') {
|
||||
a[i] *= 10;
|
||||
a[i] += cp[j] - '0';
|
||||
j++;
|
||||
}
|
||||
}
|
||||
ret = ((a[3]<<24) + (a[2]<<16) + (a[1]<<8) + a[0]) ;
|
||||
return(ret) ;
|
||||
}
|
||||
#else
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#ifndef WOLFSSL_LEANPSK
|
||||
#include <unistd.h>
|
||||
#include <netdb.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/socket.h>
|
||||
#include <fcntl.h>
|
||||
#ifdef TEST_IPV6
|
||||
#include <netdb.h>
|
||||
#endif
|
||||
#endif
|
||||
#define SOCKET_T int
|
||||
#ifndef SO_NOSIGPIPE
|
||||
#include <signal.h> /* ignore SIGPIPE */
|
||||
#endif
|
||||
#define SNPRINTF snprintf
|
||||
#endif /* USE_WINDOWS_API */
|
||||
|
||||
|
||||
#ifdef WOLFSSL_KEIL_TCP_NET
|
||||
#define SOCK_LISTEN_MAX_QUEUE 1
|
||||
#else
|
||||
#define SOCK_LISTEN_MAX_QUEUE 5
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef WOLFSSL_SOCKET_INVALID
|
||||
#ifdef USE_WINDOWS_API
|
||||
#define WOLFSSL_SOCKET_INVALID ((SOCKET_T)INVALID_SOCKET)
|
||||
#define WOLFSSL_SOCKET_IS_INVALID(s) \
|
||||
((SOCKET_T)(s) == WOLFSSL_SOCKET_INVALID)
|
||||
#elif defined(WOLFSSL_TIRTOS)
|
||||
#define WOLFSSL_SOCKET_INVALID ((SOCKET_T)-1)
|
||||
#define WOLFSSL_SOCKET_IS_INVALID(s) \
|
||||
((SOCKET_T)(s) == WOLFSSL_SOCKET_INVALID)
|
||||
#else
|
||||
#define WOLFSSL_SOCKET_INVALID (SOCKET_T)(0)
|
||||
#define WOLFSSL_SOCKET_IS_INVALID(s) \
|
||||
((SOCKET_T)(s) < WOLFSSL_SOCKET_INVALID)
|
||||
#endif
|
||||
#endif /* WOLFSSL_SOCKET_INVALID */
|
||||
|
||||
|
||||
#ifdef SAMPLE_IPV6
|
||||
typedef struct sockaddr_in6 SOCKADDR_IN_T;
|
||||
#define AF_INET_V AF_INET6
|
||||
static const char* const wolfSSLIP = "::1";
|
||||
#else
|
||||
typedef struct sockaddr_in SOCKADDR_IN_T;
|
||||
#define AF_INET_V AF_INET
|
||||
static const char* const wolfSSLIP = "127.0.0.1";
|
||||
#endif
|
||||
static const word16 wolfSSLPort = 11111;
|
||||
|
||||
/* HPUX doesn't use socklent_t for third parameter to accept, unless
|
||||
_XOPEN_SOURCE_EXTENDED is defined */
|
||||
#if (!defined(__hpux__) && !defined(WOLFSSL_MDK_ARM) && \
|
||||
!defined(WOLFSSL_IAR_ARM) && !defined(WOLFSSL_ROWLEY_ARM) && \
|
||||
!defined(WOLFSSL_KEIL_TCP_NET)) || defined(_XOPEN_SOURCE_EXTENDED)
|
||||
typedef socklen_t* ACCEPT_THIRD_T;
|
||||
#else
|
||||
typedef int* ACCEPT_THIRD_T;
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef USE_WINDOWS_API
|
||||
static WC_INLINE int tcp_set_nonblocking(SOCKET_T* sockfd)
|
||||
{
|
||||
int ret = 0;
|
||||
unsigned long blocking = 1;
|
||||
|
||||
ret = ioctlsocket(*sockfd, FIONBIO, &blocking);
|
||||
if (ret == SOCKET_ERROR)
|
||||
printf("ioctlsocket failed");
|
||||
|
||||
return ret;
|
||||
}
|
||||
#elif defined(WOLFSSL_MDK_ARM) || defined(WOLFSSL_KEIL_TCP_NET) || \
|
||||
defined(WOLFSSL_TIRTOS)|| defined(WOLFSSL_VXWORKS) || \
|
||||
defined(WOLFSSL_ZEPHYR)
|
||||
static WC_INLINE int tcp_set_nonblocking(SOCKET_T* sockfd)
|
||||
{
|
||||
(void)sockfd;
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
static WC_INLINE int tcp_set_nonblocking(SOCKET_T* sockfd)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
int flags = fcntl(*sockfd, F_GETFL, 0);
|
||||
if (flags < 0) {
|
||||
printf("fcntl get failed");
|
||||
ret = -1;
|
||||
}
|
||||
flags = fcntl(*sockfd, F_SETFL, flags | O_NONBLOCK);
|
||||
if (flags < 0) {
|
||||
printf("fcntl set failed");
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(HAVE_GETADDRINFO) || defined(WOLF_C99)
|
||||
|
||||
#ifndef SAMPLE_IPV6
|
||||
|
||||
static WC_INLINE int get_addr(SOCKADDR_IN_T* addr, const char* peer,
|
||||
word16 port, int udp, int sctp)
|
||||
{
|
||||
int ret = 0;
|
||||
struct addrinfo hints;
|
||||
struct addrinfo* answer = NULL;
|
||||
char strPort[6];
|
||||
|
||||
(void)sctp;
|
||||
|
||||
XMEMSET(&hints, 0, sizeof(hints));
|
||||
|
||||
hints.ai_family = AF_INET_V;
|
||||
if (udp) {
|
||||
hints.ai_socktype = SOCK_DGRAM;
|
||||
hints.ai_protocol = IPPROTO_UDP;
|
||||
}
|
||||
#ifdef WOLFSSL_SCTP
|
||||
else if (sctp) {
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
hints.ai_protocol = IPPROTO_SCTP;
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
hints.ai_protocol = IPPROTO_TCP;
|
||||
}
|
||||
|
||||
SNPRINTF(strPort, sizeof(strPort), "%d", port);
|
||||
strPort[sizeof(strPort)-1] = '\0';
|
||||
|
||||
ret = getaddrinfo(peer, strPort, &hints, &answer);
|
||||
if (ret < 0 || answer == NULL) {
|
||||
printf("getaddrinfo failed\n");
|
||||
ret = -1;
|
||||
}
|
||||
else
|
||||
XMEMCPY(addr, answer->ai_addr, answer->ai_addrlen);
|
||||
freeaddrinfo(answer);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#else /* SAMPLE_IPV6 */
|
||||
|
||||
static WC_INLINE int get_addr(SOCKADDR_IN_T* addr, const char* peer,
|
||||
word16 port, int udp, int sctp)
|
||||
{
|
||||
int ret = 0;
|
||||
struct zsock_addrinfo hints, *addrInfo;
|
||||
char portStr[6];
|
||||
|
||||
(void)sctp;
|
||||
|
||||
XSNPRINTF(portStr, sizeof(portStr), "%d", port);
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_family = AF_UNSPEC;
|
||||
hints.ai_socktype = udp ? SOCK_DGRAM : SOCK_STREAM;
|
||||
hints.ai_protocol = udp ? IPPROTO_UDP : IPPROTO_TCP;
|
||||
ret = getaddrinfo((char*)peer, portStr, &hints, &addrInfo);
|
||||
if (ret == 0)
|
||||
XMEMCPY(addr, addrInfo->ai_addr, sizeof(*addr));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* SAMPLE_IPV6 */
|
||||
|
||||
#else /* !GETADDRINFO */
|
||||
|
||||
#ifndef SAMPLE_IPV6
|
||||
|
||||
static WC_INLINE int get_addr(SOCKADDR_IN_T* addr, const char* peer,
|
||||
word16 port, int udp, int sctp)
|
||||
{
|
||||
int ret = 0;
|
||||
#if defined(WOLFSSL_MDK_ARM) || defined(WOLFSSL_KEIL_TCP_NET)
|
||||
int err;
|
||||
struct hostent* entry = gethostbyname(peer, &err);
|
||||
#elif defined(WOLFSSL_TIRTOS)
|
||||
struct hostent* entry = DNSGetHostByName(peer);
|
||||
#elif defined(WOLFSSL_VXWORKS)
|
||||
struct hostent* entry = (struct hostent*)hostGetByName(
|
||||
(char*)peer);
|
||||
#else
|
||||
struct hostent* entry = gethostbyname(peer);
|
||||
#endif
|
||||
|
||||
(void)port;
|
||||
(void)udp;
|
||||
(void)sctp;
|
||||
|
||||
if (entry)
|
||||
XMEMCPY(&addr->sin_addr.s_addr, entry->h_addr_list[0], entry->h_length);
|
||||
else
|
||||
ret = -1;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static WC_INLINE int get_addr(SOCKADDR_IN_T* addr, const char* peer,
|
||||
word16 port, int udp, int sctp)
|
||||
{
|
||||
(void)peer;
|
||||
(void)port;
|
||||
(void)udp;
|
||||
(void)sctp;
|
||||
|
||||
printf("no ipv6 getaddrinfo, loopback only\n");
|
||||
addr->sin6_addr = in6addr_loopback;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* SAMPLE_IPV6 */
|
||||
|
||||
#endif /* !GETADDRINFO */
|
||||
|
||||
|
||||
|
||||
static WC_INLINE int build_addr(SOCKADDR_IN_T* addr, const char* peer,
|
||||
word16 port, int udp, int sctp)
|
||||
{
|
||||
int ret = 0;
|
||||
int useLookup = 0;
|
||||
(void)useLookup;
|
||||
|
||||
if (addr == NULL) {
|
||||
printf("invalid argument to build_addr, addr is NULL\n");
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
XMEMSET(addr, 0, sizeof(SOCKADDR_IN_T));
|
||||
|
||||
#ifndef SAMPLE_IPV6
|
||||
#if defined(WOLFSSL_MDK_ARM) || defined(WOLFSSL_KEIL_TCP_NET)
|
||||
addr->sin_family = PF_INET;
|
||||
#else
|
||||
addr->sin_family = AF_INET_V;
|
||||
#endif
|
||||
addr->sin_port = XHTONS(port);
|
||||
if ((size_t)peer == INADDR_ANY)
|
||||
addr->sin_addr.s_addr = INADDR_ANY;
|
||||
else {
|
||||
/* peer could be in human readable form */
|
||||
if (isalpha((int)peer[0])) {
|
||||
ret = get_addr(addr, peer, port, udp, sctp);
|
||||
if (ret == 0)
|
||||
useLookup = 1;
|
||||
else
|
||||
printf("no entry for host");
|
||||
}
|
||||
if (ret == 0 && !useLookup)
|
||||
addr->sin_addr.s_addr = inet_addr(peer);
|
||||
}
|
||||
#else /* SAMPLE_IPV6 */
|
||||
addr->sin6_family = AF_INET_V;
|
||||
addr->sin6_port = XHTONS(port);
|
||||
if ((size_t)peer == INADDR_ANY)
|
||||
addr->sin6_addr = in6addr_any;
|
||||
else
|
||||
ret = get_addr(addr, peer, port, udp, sctp);
|
||||
#endif /* SAMPL_IPV6 */
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
#ifdef SO_NOSIGPIPE
|
||||
static WC_INLINE int tcp_set_socket_no_sig_pipe(SOCKET_T sockfd)
|
||||
{
|
||||
int ret;
|
||||
int on = 1;
|
||||
socklen_t len = sizeof(on);
|
||||
|
||||
ret = setsockopt(sockfd, SOL_SOCKET, SO_NOSIGPIPE, &on, len);
|
||||
if (ret < 0)
|
||||
printf("setsockopt SO_NOSIGPIPE failed\n");
|
||||
|
||||
return ret;
|
||||
}
|
||||
#elif defined(WOLFSSL_MDK_ARM) || defined (WOLFSSL_TIRTOS) || \
|
||||
defined(WOLFSSL_KEIL_TCP_NET) || defined(WOLFSSL_ZEPHYR) || \
|
||||
defined(USE_WINDOWS_API)
|
||||
static WC_INLINE int tcp_set_socket_no_sig_pipe(SOCKET_T sockfd)
|
||||
{
|
||||
(void)sockfd;
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
static WC_INLINE int tcp_set_socket_no_sig_pipe(SOCKET_T sockfd)
|
||||
{
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef TCP_NODELAY
|
||||
static WC_INLINE int tcp_set_socket_tcp_no_delay(SOCKET_T sockfd)
|
||||
{
|
||||
int ret;
|
||||
int on = 1;
|
||||
socklen_t len = sizeof(on);
|
||||
|
||||
ret = setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, &on, len);
|
||||
if (ret < 0)
|
||||
printf("setsockopt TCP_NODELAY failed\n");
|
||||
|
||||
return ret;
|
||||
}
|
||||
#else
|
||||
static WC_INLINE int tcp_set_socket_tcp_no_delay(SOCKET_T sockfd)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static WC_INLINE int tcp_set_socket_opts(SOCKET_T sockfd, int udp, int sctp)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
ret = tcp_set_socket_no_sig_pipe(sockfd);
|
||||
if (ret == 0 && !udp && !sctp)
|
||||
ret = tcp_set_socket_tcp_no_delay(sockfd);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static WC_INLINE int tcp_socket(SOCKET_T* sockfd, int udp, int sctp)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (udp)
|
||||
*sockfd = socket(AF_INET_V, SOCK_DGRAM, IPPROTO_UDP);
|
||||
#ifdef WOLFSSL_SCTP
|
||||
else if (sctp)
|
||||
*sockfd = socket(AF_INET_V, SOCK_STREAM, IPPROTO_SCTP);
|
||||
#endif
|
||||
else
|
||||
*sockfd = socket(AF_INET_V, SOCK_STREAM, IPPROTO_TCP);
|
||||
|
||||
if(WOLFSSL_SOCKET_IS_INVALID(*sockfd)) {
|
||||
printf("socket failed\n");
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
if (ret == 0)
|
||||
ret = tcp_set_socket_opts(*sockfd, udp, sctp);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static WC_INLINE int tcp_connect(SOCKET_T* sockfd, const char* ip, word16 port,
|
||||
int udp, int sctp, WOLFSSL* ssl)
|
||||
{
|
||||
int ret = 0;
|
||||
SOCKADDR_IN_T addr;
|
||||
|
||||
ret = build_addr(&addr, ip, port, udp, sctp);
|
||||
if (ret != 0)
|
||||
printf("build address failed\n");
|
||||
if (ret == 0) {
|
||||
if (udp)
|
||||
wolfSSL_dtls_set_peer(ssl, &addr, sizeof(addr));
|
||||
ret = tcp_socket(sockfd, udp, sctp);
|
||||
}
|
||||
|
||||
if (ret == 0 && !udp) {
|
||||
if (connect(*sockfd, (const struct sockaddr*)&addr, sizeof(addr)) !=
|
||||
0) {
|
||||
printf("tcp connect failed");
|
||||
ret = -1;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
#if defined(USE_WINDOWS_API) || defined(WOLFSSL_MDK_ARM) || \
|
||||
defined(WOLFSSL_KEIL_TCP_NET) || defined(WOLFSSL_ZEPHYR)
|
||||
static WC_INLINE int tcp_set_socket_reuseaddr(SOCKET_T sockfd)
|
||||
{
|
||||
(void)sockfd;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
static WC_INLINE int tcp_set_socket_reuseaddr(SOCKET_T sockfd)
|
||||
{
|
||||
int ret;
|
||||
int on = 1;
|
||||
socklen_t len = sizeof(on);
|
||||
|
||||
ret = setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on, len);
|
||||
if (ret < 0)
|
||||
printf("setsockopt SO_REUSEADDR failed\n");
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(USE_WINDOWS_API) || defined(WOLFSSL_TIRTOS) || \
|
||||
defined(WOLFSSL_ZEPHYR)
|
||||
static WC_INLINE int tcp_get_sock_name(SOCKET_T sockfd, SOCKADDR_IN_T* addr,
|
||||
word16* port)
|
||||
{
|
||||
(void)sockfd;
|
||||
(void)addr;
|
||||
(void)port;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
static WC_INLINE int tcp_get_sock_name(SOCKET_T sockfd, SOCKADDR_IN_T* addr,
|
||||
word16* port)
|
||||
{
|
||||
socklen_t len = sizeof(*addr);
|
||||
|
||||
if (getsockname(sockfd, (struct sockaddr*)addr, &len) == 0) {
|
||||
#ifndef SAMPLE_IPV6
|
||||
*port = XNTOHS(addr->sin_port);
|
||||
#else
|
||||
*port = XNTOHS(addr->sin6_port);
|
||||
#endif
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static WC_INLINE int tcp_listen(SOCKET_T* sockfd, word16* port, int useAnyAddr,
|
||||
int udp, int sctp)
|
||||
{
|
||||
int ret;
|
||||
SOCKADDR_IN_T addr;
|
||||
|
||||
/* don't use INADDR_ANY by default, firewall may block, make user switch
|
||||
on */
|
||||
ret = build_addr(&addr, (useAnyAddr ? INADDR_ANY : wolfSSLIP), *port, udp,
|
||||
sctp);
|
||||
if (ret != 0)
|
||||
printf("build address failed\n");
|
||||
if (ret == 0) {
|
||||
ret = tcp_socket(sockfd, udp, sctp);
|
||||
if (ret != 0)
|
||||
printf("socket listen failed\n");
|
||||
}
|
||||
|
||||
if (ret == 0)
|
||||
ret = tcp_set_socket_reuseaddr(*sockfd);
|
||||
|
||||
if (ret == 0) {
|
||||
if (bind(*sockfd, (const struct sockaddr*)&addr, sizeof(addr)) != 0) {
|
||||
printf("tcp bind failed\n");
|
||||
ret = -1;
|
||||
}
|
||||
}
|
||||
if (ret == 0 && !udp) {
|
||||
if (listen(*sockfd, SOCK_LISTEN_MAX_QUEUE) != 0) {
|
||||
printf("tcp listen failed\n");
|
||||
ret = -1;
|
||||
}
|
||||
}
|
||||
if (ret == 0 && *port == 0)
|
||||
ret = tcp_get_sock_name(*sockfd, &addr, port);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static WC_INLINE int tcp_accept(SOCKET_T* sockfd, SOCKET_T* clientfd)
|
||||
{
|
||||
int ret = 0;
|
||||
SOCKADDR_IN_T client;
|
||||
socklen_t client_len = sizeof(client);
|
||||
|
||||
*clientfd = accept(*sockfd, (struct sockaddr*)&client,
|
||||
(ACCEPT_THIRD_T)&client_len);
|
||||
if (WOLFSSL_SOCKET_IS_INVALID(*clientfd)) {
|
||||
printf("tcp accept failed\n");
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
/* threading.h
|
||||
*
|
||||
* Copyright (C) 2006-2019 wolfSSL Inc.
|
||||
*
|
||||
* This file is part of wolfSSL. (formerly known as CyaSSL)
|
||||
*
|
||||
* 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-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef SINGLE_THREADED
|
||||
|
||||
#if defined(_POSIX_THREADS) && !defined(__MINGW32__)
|
||||
typedef void* THREAD_RETURN;
|
||||
typedef pthread_t THREAD_TYPE;
|
||||
#define WOLFSSL_THREAD
|
||||
#define INFINITE -1
|
||||
#define WAIT_OBJECT_0 0L
|
||||
#elif defined(WOLFSSL_MDK_ARM)|| defined(WOLFSSL_KEIL_TCP_NET)
|
||||
typedef unsigned int THREAD_RETURN;
|
||||
typedef int THREAD_TYPE;
|
||||
#define WOLFSSL_THREAD
|
||||
#elif defined(WOLFSSL_TIRTOS)
|
||||
typedef void THREAD_RETURN;
|
||||
typedef Task_Handle THREAD_TYPE;
|
||||
#define WOLFSSL_THREAD
|
||||
#elif defined(WOLFSSL_ZEPHYR)
|
||||
typedef void THREAD_RETURN;
|
||||
typedef struct k_thread THREAD_TYPE;
|
||||
#define WOLFSSL_THREAD
|
||||
#elif defined(USE_WINDOWS_API)
|
||||
typedef unsigned int THREAD_RETURN;
|
||||
typedef intptr_t THREAD_TYPE;
|
||||
#define WOLFSSL_THREAD __stdcall
|
||||
#else
|
||||
#error "Threading API not supported in sample"
|
||||
#endif
|
||||
|
||||
typedef THREAD_RETURN WOLFSSL_THREAD THREAD_FUNC(void*);
|
||||
typedef struct func_args {
|
||||
int argc;
|
||||
char** argv;
|
||||
int return_code;
|
||||
} func_args;
|
||||
|
||||
|
||||
static void start_thread(THREAD_FUNC, func_args*, THREAD_TYPE*);
|
||||
static void join_thread(THREAD_TYPE);
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,480 @@
|
|||
/* tls-client-server.c
|
||||
*
|
||||
* Copyright (C) 2006-2019 wolfSSL Inc.
|
||||
*
|
||||
* This file is part of wolfSSL. (formerly known as CyaSSL)
|
||||
*
|
||||
* 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-1301, USA
|
||||
*/
|
||||
|
||||
#include <wolfssl/options.h>
|
||||
#include <wolfssl/ssl.h>
|
||||
|
||||
#include "certs.h"
|
||||
|
||||
|
||||
/* I/O buffer size - wolfSSL buffers messages internally as well. */
|
||||
#define BUFFER_SIZE 2048
|
||||
/* Size of static buffer for dynamic memory allocation. */
|
||||
#ifdef WOLFSSL_STATIC_MEMORY_SMALL
|
||||
#define STATIC_MEM_SIZE (24*1024)
|
||||
#elif defined(HAVE_ECC)
|
||||
#define STATIC_MEM_SIZE (144*1024)
|
||||
#else
|
||||
#define STATIC_MEM_SIZE (96*1024)
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef WOLFSSL_STATIC_MEMORY
|
||||
/* Hint pointers for dynamic memory allocating from buffer. */
|
||||
static WOLFSSL_HEAP_HINT* HEAP_HINT_SERVER;
|
||||
static WOLFSSL_HEAP_HINT* HEAP_HINT_CLIENT;
|
||||
|
||||
/* Static buffers to dynamically allocate from. */
|
||||
static byte gTestMemoryServer[STATIC_MEM_SIZE];
|
||||
static byte gTestMemoryClient[STATIC_MEM_SIZE];
|
||||
#else
|
||||
#define HEAP_HINT_SERVER NULL
|
||||
#define HEAP_HINT_CLIENT NULL
|
||||
#endif /* WOLFSSL_STATIC_MEMORY */
|
||||
|
||||
|
||||
/* Buffer for client connection to allocate dynamic memory from. */
|
||||
static unsigned char client_buffer[BUFFER_SIZE];
|
||||
static int client_buffer_sz = 0;
|
||||
/* Buffer for server connection to allocate dynamic memory from. */
|
||||
static unsigned char server_buffer[BUFFER_SIZE];
|
||||
static int server_buffer_sz = 0;
|
||||
|
||||
|
||||
/* Application data to send. */
|
||||
static const char msgHTTPGet[] = "GET /index.html HTTP/1.0\r\n\r\n";
|
||||
static const char msgHTTPIndex[] =
|
||||
"HTTP/1.1 200 OK\n"
|
||||
"Content-Type: text/html\n"
|
||||
"Connection: close\n"
|
||||
"\n"
|
||||
"<html>\n"
|
||||
"<head>\n"
|
||||
"<title>Welcome to wolfSSL!</title>\n"
|
||||
"</head>\n"
|
||||
"<body>\n"
|
||||
"<p>wolfSSL has successfully performed handshake!</p>\n"
|
||||
"</body>\n"
|
||||
"</html>\n";
|
||||
|
||||
|
||||
/* Client attempts to read data from server. */
|
||||
static int recv_client(WOLFSSL* ssl, char* buff, int sz, void* ctx)
|
||||
{
|
||||
if (client_buffer_sz > 0) {
|
||||
if (sz > client_buffer_sz)
|
||||
sz = client_buffer_sz;
|
||||
XMEMCPY(buff, client_buffer, sz);
|
||||
if (sz < client_buffer_sz) {
|
||||
XMEMMOVE(client_buffer, client_buffer + sz, client_buffer_sz - sz);
|
||||
}
|
||||
client_buffer_sz -= sz;
|
||||
}
|
||||
else
|
||||
sz = WOLFSSL_CBIO_ERR_WANT_READ;
|
||||
|
||||
return sz;
|
||||
}
|
||||
|
||||
/* Client attempts to write data to server. */
|
||||
static int send_client(WOLFSSL* ssl, char* buff, int sz, void* ctx)
|
||||
{
|
||||
if (server_buffer_sz < BUFFER_SIZE)
|
||||
{
|
||||
if (sz > BUFFER_SIZE - server_buffer_sz)
|
||||
sz = BUFFER_SIZE - server_buffer_sz;
|
||||
XMEMCPY(server_buffer + server_buffer_sz, buff, sz);
|
||||
server_buffer_sz += sz;
|
||||
}
|
||||
else
|
||||
sz = WOLFSSL_CBIO_ERR_WANT_WRITE;
|
||||
|
||||
return sz;
|
||||
}
|
||||
|
||||
/* Server attempts to read data from client. */
|
||||
static int recv_server(WOLFSSL* ssl, char* buff, int sz, void* ctx)
|
||||
{
|
||||
|
||||
if (server_buffer_sz > 0) {
|
||||
if (sz > server_buffer_sz)
|
||||
sz = server_buffer_sz;
|
||||
XMEMCPY(buff, server_buffer, sz);
|
||||
if (sz < server_buffer_sz) {
|
||||
XMEMMOVE(server_buffer, server_buffer + sz, server_buffer_sz - sz);
|
||||
}
|
||||
server_buffer_sz -= sz;
|
||||
}
|
||||
else
|
||||
sz = WOLFSSL_CBIO_ERR_WANT_READ;
|
||||
|
||||
return sz;
|
||||
}
|
||||
|
||||
/* Server attempts to write data to client. */
|
||||
static int send_server(WOLFSSL* ssl, char* buff, int sz, void* ctx)
|
||||
{
|
||||
if (client_buffer_sz < BUFFER_SIZE)
|
||||
{
|
||||
if (sz > BUFFER_SIZE - client_buffer_sz)
|
||||
sz = BUFFER_SIZE - client_buffer_sz;
|
||||
XMEMCPY(client_buffer + client_buffer_sz, buff, sz);
|
||||
client_buffer_sz += sz;
|
||||
}
|
||||
else
|
||||
sz = WOLFSSL_CBIO_ERR_WANT_WRITE;
|
||||
|
||||
return sz;
|
||||
}
|
||||
|
||||
|
||||
/* Create a new wolfSSL client with a server CA certificate. */
|
||||
static int wolfssl_client_new(WOLFSSL_CTX** ctx, WOLFSSL** ssl)
|
||||
{
|
||||
int ret = 0;
|
||||
WOLFSSL_CTX* client_ctx = NULL;
|
||||
WOLFSSL* client_ssl = NULL;
|
||||
|
||||
/* Create and initialize WOLFSSL_CTX */
|
||||
if ((client_ctx = wolfSSL_CTX_new_ex(wolfTLSv1_2_client_method(),
|
||||
HEAP_HINT_CLIENT)) == NULL) {
|
||||
printf("ERROR: failed to create WOLFSSL_CTX\n");
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
/* Load CA certificates into WOLFSSL_CTX */
|
||||
if (wolfSSL_CTX_load_verify_buffer(client_ctx, CA_CERTS, CA_CERTS_LEN,
|
||||
WOLFSSL_FILETYPE_ASN1) != WOLFSSL_SUCCESS) {
|
||||
printf("ERROR: failed to load CA certiifcate\n");
|
||||
ret = -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
/* Register callbacks */
|
||||
wolfSSL_SetIORecv(client_ctx, recv_client);
|
||||
wolfSSL_SetIOSend(client_ctx, send_client);
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
/* Create a WOLFSSL object */
|
||||
if ((client_ssl = wolfSSL_new(client_ctx)) == NULL) {
|
||||
printf("ERROR: failed to create WOLFSSL object\n");
|
||||
ret = -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
/* make wolfSSL object nonblocking */
|
||||
wolfSSL_set_using_nonblock(client_ssl, 1);
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
*ctx = client_ctx;
|
||||
*ssl = client_ssl;
|
||||
}
|
||||
else {
|
||||
if (client_ssl != NULL)
|
||||
wolfSSL_free(client_ssl);
|
||||
if (client_ctx != NULL)
|
||||
wolfSSL_CTX_free(client_ctx);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Client connecting to server using TLS */
|
||||
static int wolfssl_client_connect(WOLFSSL* client_ssl)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (wolfSSL_connect(client_ssl) != WOLFSSL_SUCCESS) {
|
||||
if (wolfSSL_want_read(client_ssl)) {
|
||||
printf("Client waiting for server\n");
|
||||
}
|
||||
else if (wolfSSL_want_write(client_ssl)) {
|
||||
printf("Client waiting for buffer\n");
|
||||
}
|
||||
else
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* Create a new wolfSSL server with a certificate for authentication. */
|
||||
static int wolfssl_server_new(WOLFSSL_CTX** ctx, WOLFSSL** ssl)
|
||||
{
|
||||
int ret = 0;
|
||||
WOLFSSL_CTX* server_ctx = NULL;
|
||||
WOLFSSL* server_ssl = NULL;
|
||||
|
||||
/* Create and initialize WOLFSSL_CTX */
|
||||
if ((server_ctx = wolfSSL_CTX_new_ex(wolfTLSv1_2_server_method(),
|
||||
HEAP_HINT_SERVER)) == NULL) {
|
||||
printf("ERROR: failed to create WOLFSSL_CTX\n");
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
/* Load client certificates into WOLFSSL_CTX */
|
||||
if (wolfSSL_CTX_use_certificate_buffer(server_ctx, SERVER_CERT,
|
||||
SERVER_CERT_LEN, WOLFSSL_FILETYPE_ASN1) != WOLFSSL_SUCCESS) {
|
||||
printf("ERROR: failed to load server certiifcate\n");
|
||||
ret = -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
/* Load client certificates into WOLFSSL_CTX */
|
||||
if (wolfSSL_CTX_use_PrivateKey_buffer(server_ctx,
|
||||
SERVER_KEY, SERVER_KEY_LEN, WOLFSSL_FILETYPE_ASN1) !=
|
||||
WOLFSSL_SUCCESS) {
|
||||
printf("ERROR: failed to load server key\n");
|
||||
ret = -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
/* Register callbacks */
|
||||
wolfSSL_SetIORecv(server_ctx, recv_server);
|
||||
wolfSSL_SetIOSend(server_ctx, send_server);
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
/* Create a WOLFSSL object */
|
||||
if ((server_ssl = wolfSSL_new(server_ctx)) == NULL) {
|
||||
printf("ERROR: failed to create WOLFSSL object\n");
|
||||
ret = -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
/* make wolfSSL object nonblocking */
|
||||
wolfSSL_set_using_nonblock(server_ssl, 1);
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
*ctx = server_ctx;
|
||||
*ssl = server_ssl;
|
||||
}
|
||||
else {
|
||||
if (server_ssl != NULL)
|
||||
wolfSSL_free(server_ssl);
|
||||
if (server_ctx != NULL)
|
||||
wolfSSL_CTX_free(server_ctx);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Server accepting a client using TLS */
|
||||
static int wolfssl_server_accept(WOLFSSL* server_ssl)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (wolfSSL_accept(server_ssl) != WOLFSSL_SUCCESS) {
|
||||
if (wolfSSL_want_read(server_ssl)) {
|
||||
printf("Server waiting for server\n");
|
||||
}
|
||||
else if (wolfSSL_want_write(server_ssl)) {
|
||||
printf("Server waiting for buffer\n");
|
||||
}
|
||||
else
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* Send application data. */
|
||||
static int wolfssl_send(WOLFSSL* ssl, const char* msg)
|
||||
{
|
||||
int ret;
|
||||
|
||||
printf("%s", msg);
|
||||
ret = wolfSSL_write(ssl, msg, XSTRLEN(msg));
|
||||
if (ret < XSTRLEN(msg))
|
||||
ret = -1;
|
||||
else
|
||||
ret = 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Receive application data. */
|
||||
static int wolfssl_recv(WOLFSSL* ssl)
|
||||
{
|
||||
int ret;
|
||||
byte reply[256];
|
||||
|
||||
ret = wolfSSL_read(ssl, reply, sizeof(reply)-1);
|
||||
if (ret > 0) {
|
||||
reply[ret] = '\0';
|
||||
printf("%s", reply);
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* Free the WOLFSSL object and context. */
|
||||
static void wolfssl_free(WOLFSSL_CTX* ctx, WOLFSSL* ssl)
|
||||
{
|
||||
if (ssl != NULL)
|
||||
wolfSSL_free(ssl);
|
||||
if (ctx != NULL)
|
||||
wolfSSL_CTX_free(ctx);
|
||||
}
|
||||
|
||||
|
||||
/* Display dynamic memory usage statistics. */
|
||||
static void wolfssl_memstats(WOLFSSL* ssl)
|
||||
{
|
||||
#ifdef WOLFSSL_STATIC_MEMORY
|
||||
WOLFSSL_MEM_CONN_STATS ssl_stats;
|
||||
|
||||
XMEMSET(&ssl_stats, 0 , sizeof(ssl_stats));
|
||||
|
||||
if (wolfSSL_is_static_memory(ssl, &ssl_stats) != 1)
|
||||
printf("static memory was not used with ssl");
|
||||
else {
|
||||
printf("*** This is memory state before wolfSSL_free is called\n");
|
||||
printf("peak connection memory = %d\n", ssl_stats.peakMem);
|
||||
printf("current memory in use = %d\n", ssl_stats.curMem);
|
||||
printf("peak connection allocs = %d\n", ssl_stats.peakAlloc);
|
||||
printf("current connection allocs = %d\n",ssl_stats.curAlloc);
|
||||
printf("total connection allocs = %d\n",ssl_stats.totalAlloc);
|
||||
printf("total connection frees = %d\n\n", ssl_stats.totalFr);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Display dynamic memory usage statistics of the client connection. */
|
||||
static void wolfssl_client_memstats(WOLFSSL* client_ssl)
|
||||
{
|
||||
#ifdef WOLFSSL_STATIC_MEMORY
|
||||
printf("Client Memory Stats\n");
|
||||
#endif
|
||||
wolfssl_memstats(client_ssl);
|
||||
}
|
||||
|
||||
/* Display dynamic memory usage statistics of the server connection. */
|
||||
static void wolfssl_server_memstats(WOLFSSL* server_ssl)
|
||||
{
|
||||
#ifdef WOLFSSL_STATIC_MEMORY
|
||||
printf("Server Memory Stats\n");
|
||||
#endif
|
||||
wolfssl_memstats(server_ssl);
|
||||
}
|
||||
|
||||
/* Main entry point. */
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
int ret = 0;
|
||||
WOLFSSL_CTX* client_ctx = NULL;
|
||||
WOLFSSL* client_ssl = NULL;
|
||||
WOLFSSL_CTX* server_ctx = NULL;
|
||||
WOLFSSL* server_ssl = NULL;
|
||||
|
||||
#if defined(DEBUG_WOLFSSL)
|
||||
wolfSSL_Debugging_ON();
|
||||
#endif
|
||||
/* Initialize wolfSSL library. */
|
||||
wolfSSL_Init();
|
||||
|
||||
#ifdef WOLFSSL_STATIC_MEMORY
|
||||
if (wc_LoadStaticMemory(&HEAP_HINT_SERVER, gTestMemoryServer,
|
||||
sizeof(gTestMemoryServer),
|
||||
WOLFMEM_GENERAL | WOLFMEM_TRACK_STATS, 1) != 0) {
|
||||
printf("unable to load static memory");
|
||||
ret = -1;
|
||||
}
|
||||
if (wc_LoadStaticMemory(&HEAP_HINT_CLIENT, gTestMemoryClient,
|
||||
sizeof(gTestMemoryClient),
|
||||
WOLFMEM_GENERAL | WOLFMEM_TRACK_STATS, 1) != 0) {
|
||||
printf("unable to load static memory");
|
||||
ret = -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Create server and client SSL objects. */
|
||||
if (ret == 0)
|
||||
ret = wolfssl_server_new(&server_ctx, &server_ssl);
|
||||
if (ret == 0)
|
||||
ret = wolfssl_client_new(&client_ctx, &client_ssl);
|
||||
|
||||
/* Loop to perform SSL handshake. */
|
||||
while (ret == 0) {
|
||||
ret = wolfssl_client_connect(client_ssl);
|
||||
if (ret == 0)
|
||||
ret = wolfssl_server_accept(server_ssl);
|
||||
if (ret == 0 && wolfSSL_is_init_finished(client_ssl) &&
|
||||
wolfSSL_is_init_finished(server_ssl)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == 0)
|
||||
printf("Handshake complete\n");
|
||||
|
||||
/* Send and receive HTTP messages. */
|
||||
if (ret == 0) {
|
||||
printf("\nClient Sending:\n");
|
||||
ret = wolfssl_send(client_ssl, msgHTTPGet);
|
||||
}
|
||||
if (ret == 0) {
|
||||
printf("\nServer Received:\n");
|
||||
ret = wolfssl_recv(server_ssl);
|
||||
}
|
||||
if (ret == 0) {
|
||||
printf("\nServer Sending:\n");
|
||||
ret = wolfssl_send(server_ssl, msgHTTPIndex);
|
||||
}
|
||||
if (ret == 0) {
|
||||
printf("\nClient Received:\n");
|
||||
ret = wolfssl_recv(client_ssl);
|
||||
}
|
||||
|
||||
/* Display memory statistics. */
|
||||
wolfssl_client_memstats(client_ssl);
|
||||
wolfssl_server_memstats(server_ssl);
|
||||
|
||||
/* Dispose of SSL objects. */
|
||||
wolfssl_free(client_ctx, client_ssl);
|
||||
wolfssl_free(server_ctx, server_ssl);
|
||||
|
||||
/* Cleanup wolfSSL library. */
|
||||
wolfSSL_Cleanup();
|
||||
|
||||
if (ret == 0)
|
||||
printf("Done\n");
|
||||
else {
|
||||
char buffer[80];
|
||||
printf("Error: %d, %s\n", ret, wolfSSL_ERR_error_string(ret, buffer));
|
||||
}
|
||||
|
||||
return (ret == 0) ? 0 : 1;
|
||||
}
|
||||
|
|
@ -0,0 +1,232 @@
|
|||
/* tls-info.h
|
||||
*
|
||||
* Copyright (C) 2006-2019 wolfSSL Inc.
|
||||
*
|
||||
* This file is part of wolfSSL. (formerly known as CyaSSL)
|
||||
*
|
||||
* 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-1301, USA
|
||||
*/
|
||||
|
||||
static const char* client_showpeer_msg[][8] = {
|
||||
/* English */
|
||||
{
|
||||
"SSL version is",
|
||||
"SSL cipher suite is",
|
||||
"SSL curve name is",
|
||||
"SSL DH size is",
|
||||
"SSL reused session",
|
||||
"Alternate cert chain used",
|
||||
"peer's cert info:",
|
||||
NULL
|
||||
},
|
||||
#ifndef NO_MULTIBYTE_PRINT
|
||||
/* Japanese */
|
||||
{
|
||||
"SSL バージョンは",
|
||||
"SSL 暗号スイートは",
|
||||
"SSL 曲線名は",
|
||||
"SSL DH サイズは",
|
||||
"SSL 再利用セッション",
|
||||
"代替証明チェーンを使用",
|
||||
"相手方証明書情報",
|
||||
NULL
|
||||
},
|
||||
#endif
|
||||
};
|
||||
|
||||
#if defined(KEEP_PEER_CERT) || defined(SESSION_CERTS)
|
||||
static const char* client_showx509_msg[][5] = {
|
||||
/* English */
|
||||
{
|
||||
"issuer",
|
||||
"subject",
|
||||
"altname",
|
||||
"serial number",
|
||||
NULL
|
||||
},
|
||||
#ifndef NO_MULTIBYTE_PRINT
|
||||
/* Japanese */
|
||||
{
|
||||
"発行者",
|
||||
"サブジェクト",
|
||||
"代替名",
|
||||
"シリアル番号",
|
||||
NULL
|
||||
},
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
/* lng_index is to specify the language for displaying message. */
|
||||
/* 0:English, 1:Japanese */
|
||||
static WC_INLINE void ShowX509Ex(WOLFSSL_X509* x509, const char* hdr,
|
||||
int lng_index)
|
||||
{
|
||||
char* altName;
|
||||
char* issuer;
|
||||
char* subject;
|
||||
byte serial[32];
|
||||
int ret;
|
||||
int sz = sizeof(serial);
|
||||
const char** words = client_showx509_msg[lng_index];
|
||||
|
||||
if (x509 == NULL) {
|
||||
printf("%s No Cert\n", hdr);
|
||||
return;
|
||||
}
|
||||
|
||||
issuer = wolfSSL_X509_NAME_oneline(
|
||||
wolfSSL_X509_get_issuer_name(x509), 0, 0);
|
||||
subject = wolfSSL_X509_NAME_oneline(
|
||||
wolfSSL_X509_get_subject_name(x509), 0, 0);
|
||||
|
||||
printf("%s\n %s : %s\n %s: %s\n", hdr, words[0], issuer, words[1], subject);
|
||||
|
||||
while ( (altName = wolfSSL_X509_get_next_altname(x509)) != NULL)
|
||||
printf(" %s = %s\n", words[2], altName);
|
||||
|
||||
ret = wolfSSL_X509_get_serial_number(x509, serial, &sz);
|
||||
if (ret == WOLFSSL_SUCCESS) {
|
||||
int i;
|
||||
int strLen;
|
||||
char serialMsg[80];
|
||||
|
||||
/* testsuite has multiple threads writing to stdout, get output
|
||||
message ready to write once */
|
||||
strLen = sprintf(serialMsg, " %s", words[3]);
|
||||
for (i = 0; i < sz; i++)
|
||||
sprintf(serialMsg + strLen + (i*3), ":%02x ", serial[i]);
|
||||
printf("%s\n", serialMsg);
|
||||
}
|
||||
|
||||
XFREE(subject, 0, DYNAMIC_TYPE_OPENSSL);
|
||||
XFREE(issuer, 0, DYNAMIC_TYPE_OPENSSL);
|
||||
|
||||
#if defined(OPENSSL_EXTRA) && defined(SHOW_CERTS)
|
||||
{
|
||||
WOLFSSL_BIO* bio;
|
||||
char buf[256]; /* should be size of ASN_NAME_MAX */
|
||||
int textSz;
|
||||
|
||||
|
||||
/* print out domain component if certificate has it */
|
||||
textSz = wolfSSL_X509_NAME_get_text_by_NID(
|
||||
wolfSSL_X509_get_subject_name(x509), NID_domainComponent,
|
||||
buf, sizeof(buf));
|
||||
if (textSz > 0) {
|
||||
printf("Domain Component = %s\n", buf);
|
||||
}
|
||||
|
||||
bio = wolfSSL_BIO_new(wolfSSL_BIO_s_file());
|
||||
if (bio != NULL) {
|
||||
wolfSSL_BIO_set_fp(bio, stdout, BIO_NOCLOSE);
|
||||
wolfSSL_X509_print(bio, x509);
|
||||
wolfSSL_BIO_free(bio);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(SESSION_CERTS) && defined(SHOW_CERTS)
|
||||
static WC_INLINE void ShowX509Chain(WOLFSSL_X509_CHAIN* chain, int count,
|
||||
const char* hdr)
|
||||
{
|
||||
int i;
|
||||
int length;
|
||||
unsigned char buffer[3072];
|
||||
WOLFSSL_X509* chainX509;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
wolfSSL_get_chain_cert_pem(chain, i, buffer, sizeof(buffer), &length);
|
||||
buffer[length] = 0;
|
||||
printf("\n%s: %d has length %d data = \n%s\n", hdr, i, length, buffer);
|
||||
|
||||
chainX509 = wolfSSL_get_chain_X509(chain, i);
|
||||
if (chainX509)
|
||||
ShowX509(chainX509, hdr);
|
||||
else
|
||||
printf("get_chain_X509 failed\n");
|
||||
wolfSSL_FreeX509(chainX509);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static WC_INLINE void showPeerEx(WOLFSSL* ssl, int lng_index)
|
||||
{
|
||||
WOLFSSL_CIPHER* cipher;
|
||||
const char** words = client_showpeer_msg[lng_index];
|
||||
|
||||
#ifdef HAVE_ECC
|
||||
const char *name;
|
||||
#endif
|
||||
#ifndef NO_DH
|
||||
int bits;
|
||||
#endif
|
||||
#ifdef KEEP_PEER_CERT
|
||||
WOLFSSL_X509* peer = wolfSSL_get_peer_certificate(ssl);
|
||||
if (peer)
|
||||
ShowX509Ex(peer, words[6], lng_index);
|
||||
else
|
||||
printf("peer has no cert!\n");
|
||||
wolfSSL_FreeX509(peer);
|
||||
#endif
|
||||
#if defined(SHOW_CERTS) && defined(OPENSSL_EXTRA) && defined(KEEP_OUR_CERT)
|
||||
ShowX509(wolfSSL_get_certificate(ssl), "our cert info:");
|
||||
printf("Peer verify result = %lu\n", wolfSSL_get_verify_result(ssl));
|
||||
#endif /* SHOW_CERTS */
|
||||
printf("%s %s\n", words[0], wolfSSL_get_version(ssl));
|
||||
|
||||
cipher = wolfSSL_get_current_cipher(ssl);
|
||||
#ifdef HAVE_QSH
|
||||
printf("%s %s%s\n", words[1], (wolfSSL_isQSH(ssl))? "QSH:": "",
|
||||
wolfSSL_CIPHER_get_name(cipher));
|
||||
#else
|
||||
printf("%s %s\n", words[1], wolfSSL_CIPHER_get_name(cipher));
|
||||
#endif
|
||||
#ifdef HAVE_ECC
|
||||
if ((name = wolfSSL_get_curve_name(ssl)) != NULL)
|
||||
printf("%s %s\n", words[2], name);
|
||||
#endif
|
||||
#ifndef NO_DH
|
||||
if ((bits = wolfSSL_GetDhKey_Sz(ssl)) > 0)
|
||||
printf("%s %d bits\n", words[3], bits);
|
||||
#endif
|
||||
if (wolfSSL_session_reused(ssl))
|
||||
printf("%s\n", words[4]);
|
||||
#ifdef WOLFSSL_ALT_CERT_CHAINS
|
||||
if (wolfSSL_is_peer_alt_cert_chain(ssl))
|
||||
printf("%s\n", words[5]);
|
||||
#endif
|
||||
|
||||
#if defined(SESSION_CERTS) && defined(SHOW_CERTS)
|
||||
{
|
||||
WOLFSSL_X509_CHAIN* chain;
|
||||
|
||||
chain = wolfSSL_get_peer_chain(ssl);
|
||||
ShowX509Chain(chain, wolfSSL_get_chain_count(chain), "session cert");
|
||||
|
||||
#ifdef WOLFSSL_ALT_CERT_CHAINS
|
||||
if (wolfSSL_is_peer_alt_cert_chain(ssl)) {
|
||||
chain = wolfSSL_get_peer_alt_chain(ssl);
|
||||
ShowX509Chain(chain, wolfSSL_get_chain_count(chain), "alt cert");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif /* SESSION_CERTS && SHOW_CERTS */
|
||||
(void)ssl;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,261 @@
|
|||
/* tls-sock-client-ca.c
|
||||
*
|
||||
* Copyright (C) 2006-2019 wolfSSL Inc.
|
||||
*
|
||||
* This file is part of wolfSSL. (formerly known as CyaSSL)
|
||||
*
|
||||
* 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-1301, USA
|
||||
*/
|
||||
|
||||
#include <wolfssl/options.h>
|
||||
#include <wolfssl/ssl.h>
|
||||
|
||||
#include "sockets.h"
|
||||
#include "tls-info.h"
|
||||
#include "certs.h"
|
||||
|
||||
/* Application data to send. */
|
||||
static const char msgHTTPGet[] = "GET /index.html HTTP/1.0\r\n\r\n";
|
||||
|
||||
/* Create a new wolfSSL client context with a server CA certificate and a
|
||||
* client certificate and key.
|
||||
*/
|
||||
static int wolfssl_client_ctx_new(WOLFSSL_CTX** ctx)
|
||||
{
|
||||
int ret = 0;
|
||||
WOLFSSL_CTX* client_ctx = NULL;
|
||||
|
||||
/* Create and initialize WOLFSSL_CTX */
|
||||
if ((client_ctx = wolfSSL_CTX_new(wolfSSLv23_client_method())) == NULL) {
|
||||
printf("ERROR: failed to create WOLFSSL_CTX\n");
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
/* Load client certificates into WOLFSSL_CTX */
|
||||
if (wolfSSL_CTX_load_verify_buffer(client_ctx, CA_CERTS, CA_CERTS_LEN,
|
||||
WOLFSSL_FILETYPE_ASN1) != WOLFSSL_SUCCESS) {
|
||||
printf("ERROR: failed to load CA certiifcate\n");
|
||||
ret = -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
/* Load client certificates into WOLFSSL_CTX */
|
||||
if (wolfSSL_CTX_use_certificate_buffer(client_ctx, CLIENT_CERT,
|
||||
CLIENT_CERT_LEN, WOLFSSL_FILETYPE_ASN1) != WOLFSSL_SUCCESS) {
|
||||
printf("ERROR: failed to load client certiifcate\n");
|
||||
ret = -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
/* Load client certificates into WOLFSSL_CTX */
|
||||
if (wolfSSL_CTX_use_PrivateKey_buffer(client_ctx, CLIENT_KEY,
|
||||
CLIENT_KEY_LEN, WOLFSSL_FILETYPE_ASN1) != WOLFSSL_SUCCESS) {
|
||||
printf("ERROR: failed to load client key\n");
|
||||
ret = -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
/* Return newly created wolfSSL context */
|
||||
*ctx = client_ctx;
|
||||
}
|
||||
else {
|
||||
if (client_ctx != NULL)
|
||||
wolfSSL_CTX_free(client_ctx);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Create a new wolfSSL client object. */
|
||||
static int wolfssl_client_ssl_new(WOLFSSL_CTX* ctx, WOLFSSL** ssl)
|
||||
{
|
||||
int ret = 0;
|
||||
WOLFSSL* client_ssl = NULL;
|
||||
|
||||
/* Create a WOLFSSL object */
|
||||
if ((client_ssl = wolfSSL_new(ctx)) == NULL) {
|
||||
printf("ERROR: failed to create WOLFSSL object\n");
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
/* make wolfSSL object nonblocking */
|
||||
wolfSSL_set_using_nonblock(client_ssl, 1);
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
/* Return newly created wolfSSL object */
|
||||
*ssl = client_ssl;
|
||||
}
|
||||
else {
|
||||
if (client_ssl != NULL)
|
||||
wolfSSL_free(client_ssl);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Client connecting to server using TLS */
|
||||
static int wolfssl_client_connect(WOLFSSL* ssl)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (wolfSSL_connect(ssl) != WOLFSSL_SUCCESS) {
|
||||
ret = wolfSSL_get_error(ssl, 0);
|
||||
if (ret == WOLFSSL_ERROR_WANT_READ)
|
||||
ret = 0;
|
||||
else if (ret > 0)
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* Send application data. */
|
||||
static int wolfssl_send(WOLFSSL* ssl, const char* msg)
|
||||
{
|
||||
int ret = 0;
|
||||
int len;
|
||||
|
||||
printf("Sending:\n%s\n", msg);
|
||||
len = wolfSSL_write(ssl, msg, XSTRLEN(msg));
|
||||
if (len < 0)
|
||||
ret = len;
|
||||
else if (len != XSTRLEN(msg))
|
||||
ret = -1;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Receive application data. */
|
||||
static int wolfssl_recv(WOLFSSL* ssl)
|
||||
{
|
||||
int ret;
|
||||
int err = 0;
|
||||
byte reply[80];
|
||||
int total = 0;
|
||||
|
||||
printf("Receive:\n");
|
||||
do {
|
||||
ret = wolfSSL_read(ssl, reply, sizeof(reply)-1);
|
||||
if (ret > 0) {
|
||||
reply[ret] = '\0';
|
||||
printf("%s", reply);
|
||||
total += ret;
|
||||
err = 0;
|
||||
}
|
||||
else if (ret == -1)
|
||||
err = wolfSSL_get_error(ssl, 0);
|
||||
}
|
||||
while (err == 0 || (total == 0 && err == WOLFSSL_ERROR_WANT_READ));
|
||||
|
||||
if (total > 0 && err == WOLFSSL_ERROR_WANT_READ)
|
||||
ret = 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* TCP connect to the server. */
|
||||
int wolfssl_client_connect_tcp(WOLFSSL* ssl, SOCKET_T* fd)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
ret = tcp_connect(fd, wolfSSLIP, wolfSSLPort, 0, 0, ssl);
|
||||
if (ret == 0)
|
||||
ret = tcp_set_nonblocking(fd);
|
||||
|
||||
if (ret == 0) {
|
||||
if (wolfSSL_set_fd(ssl, *fd) != WOLFSSL_SUCCESS)
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Client connection operations */
|
||||
static int client(WOLFSSL_CTX* client_ctx)
|
||||
{
|
||||
int ret = 0;
|
||||
WOLFSSL* client_ssl = NULL;
|
||||
SOCKET_T sockfd = WOLFSSL_SOCKET_INVALID;
|
||||
|
||||
/* Create a new client connection */
|
||||
ret = wolfssl_client_ssl_new(client_ctx, &client_ssl);
|
||||
|
||||
if (ret == 0)
|
||||
wolfssl_client_connect_tcp(client_ssl, &sockfd);
|
||||
|
||||
/* Keep trying to connect until handshake finished */
|
||||
while (ret == 0) {
|
||||
ret = wolfssl_client_connect(client_ssl);
|
||||
if (ret == 0 && wolfSSL_is_init_finished(client_ssl))
|
||||
break;
|
||||
}
|
||||
if (ret == 0)
|
||||
showPeerEx(client_ssl, 0);
|
||||
|
||||
/* Send HTTP request */
|
||||
if (ret == 0)
|
||||
ret = wolfssl_send(client_ssl, msgHTTPGet);
|
||||
/* Receive HTTP response */
|
||||
if (ret == 0)
|
||||
ret = wolfssl_recv(client_ssl);
|
||||
|
||||
if (sockfd != WOLFSSL_SOCKET_INVALID)
|
||||
CloseSocket(sockfd);
|
||||
if (client_ssl != NULL)
|
||||
wolfSSL_free(client_ssl);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
int ret = 0;
|
||||
WOLFSSL_CTX* client_ctx = NULL;
|
||||
|
||||
#if defined(DEBUG_WOLFSSL)
|
||||
wolfSSL_Debugging_ON();
|
||||
#endif
|
||||
/* Initialise wolfSSL library */
|
||||
wolfSSL_Init();
|
||||
|
||||
ret = wolfssl_client_ctx_new(&client_ctx);
|
||||
|
||||
/* Do client */
|
||||
client(client_ctx);
|
||||
|
||||
if (client_ctx != NULL)
|
||||
wolfSSL_CTX_free(client_ctx);
|
||||
|
||||
/* Cleanup wolfSSL library */
|
||||
wolfSSL_Cleanup();
|
||||
|
||||
if (ret == 0)
|
||||
printf("Done\n");
|
||||
else {
|
||||
char buffer[80];
|
||||
printf("Error: %d, %s\n", ret, wolfSSL_ERR_error_string(ret, buffer));
|
||||
}
|
||||
|
||||
return (ret == 0) ? 0 : 1;
|
||||
}
|
||||
|
|
@ -0,0 +1,241 @@
|
|||
/* tls-sock-client.c
|
||||
*
|
||||
* Copyright (C) 2006-2019 wolfSSL Inc.
|
||||
*
|
||||
* This file is part of wolfSSL. (formerly known as CyaSSL)
|
||||
*
|
||||
* 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-1301, USA
|
||||
*/
|
||||
|
||||
#include <wolfssl/options.h>
|
||||
#include <wolfssl/ssl.h>
|
||||
|
||||
#include "sockets.h"
|
||||
#include "tls-info.h"
|
||||
#include "certs.h"
|
||||
|
||||
/* Application data to send. */
|
||||
static const char msgHTTPGet[] = "GET /index.html HTTP/1.0\r\n\r\n";
|
||||
|
||||
/* Create a new wolfSSL client context with a server CA certificate. */
|
||||
static int wolfssl_client_ctx_new(WOLFSSL_CTX** ctx)
|
||||
{
|
||||
int ret = 0;
|
||||
WOLFSSL_CTX* client_ctx = NULL;
|
||||
|
||||
/* Create and initialize WOLFSSL_CTX */
|
||||
if ((client_ctx = wolfSSL_CTX_new(wolfSSLv23_client_method())) == NULL) {
|
||||
printf("ERROR: failed to create WOLFSSL_CTX\n");
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
/* Load client certificates into WOLFSSL_CTX */
|
||||
if (wolfSSL_CTX_load_verify_buffer(client_ctx, CA_CERTS, CA_CERTS_LEN,
|
||||
WOLFSSL_FILETYPE_ASN1) != WOLFSSL_SUCCESS) {
|
||||
printf("ERROR: failed to load CA certiifcate\n");
|
||||
ret = -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
/* Return newly created wolfSSL context */
|
||||
*ctx = client_ctx;
|
||||
}
|
||||
else {
|
||||
if (client_ctx != NULL)
|
||||
wolfSSL_CTX_free(client_ctx);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Create a new wolfSSL client object. */
|
||||
static int wolfssl_client_ssl_new(WOLFSSL_CTX* ctx, WOLFSSL** ssl)
|
||||
{
|
||||
int ret = 0;
|
||||
WOLFSSL* client_ssl = NULL;
|
||||
|
||||
/* Create a WOLFSSL object */
|
||||
if ((client_ssl = wolfSSL_new(ctx)) == NULL) {
|
||||
printf("ERROR: failed to create WOLFSSL object\n");
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
/* make wolfSSL object nonblocking */
|
||||
wolfSSL_set_using_nonblock(client_ssl, 1);
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
/* Return newly created wolfSSL object */
|
||||
*ssl = client_ssl;
|
||||
}
|
||||
else {
|
||||
if (client_ssl != NULL)
|
||||
wolfSSL_free(client_ssl);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Client connecting to server using TLS */
|
||||
static int wolfssl_client_connect(WOLFSSL* ssl)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (wolfSSL_connect(ssl) != WOLFSSL_SUCCESS) {
|
||||
ret = wolfSSL_get_error(ssl, 0);
|
||||
if (ret == WOLFSSL_ERROR_WANT_READ)
|
||||
ret = 0;
|
||||
else if (ret > 0)
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* Send application data. */
|
||||
static int wolfssl_send(WOLFSSL* ssl, const char* msg)
|
||||
{
|
||||
int ret = 0;
|
||||
int len;
|
||||
|
||||
printf("Sending:\n%s\n", msg);
|
||||
len = wolfSSL_write(ssl, msg, XSTRLEN(msg));
|
||||
if (len < 0)
|
||||
ret = len;
|
||||
else if (len != XSTRLEN(msg))
|
||||
ret = -1;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Receive application data. */
|
||||
static int wolfssl_recv(WOLFSSL* ssl)
|
||||
{
|
||||
int ret;
|
||||
int err = 0;
|
||||
byte reply[80];
|
||||
int total = 0;
|
||||
|
||||
printf("Receive:\n");
|
||||
do {
|
||||
ret = wolfSSL_read(ssl, reply, sizeof(reply)-1);
|
||||
if (ret > 0) {
|
||||
reply[ret] = '\0';
|
||||
printf("%s", reply);
|
||||
total += ret;
|
||||
err = 0;
|
||||
}
|
||||
else if (ret == -1)
|
||||
err = wolfSSL_get_error(ssl, 0);
|
||||
}
|
||||
while (err == 0 || (total == 0 && err == WOLFSSL_ERROR_WANT_READ));
|
||||
|
||||
if (total > 0 && err == WOLFSSL_ERROR_WANT_READ)
|
||||
ret = 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* TCP connect to the server. */
|
||||
int wolfssl_client_connect_tcp(WOLFSSL* ssl, SOCKET_T* fd)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
ret = tcp_connect(fd, wolfSSLIP, wolfSSLPort, 0, 0, ssl);
|
||||
if (ret == 0)
|
||||
ret = tcp_set_nonblocking(fd);
|
||||
|
||||
if (ret == 0) {
|
||||
if (wolfSSL_set_fd(ssl, *fd) != WOLFSSL_SUCCESS)
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Client connection operations */
|
||||
static int client(WOLFSSL_CTX* client_ctx)
|
||||
{
|
||||
int ret = 0;
|
||||
WOLFSSL* client_ssl = NULL;
|
||||
SOCKET_T sockfd = WOLFSSL_SOCKET_INVALID;
|
||||
|
||||
/* Create a new client connection */
|
||||
ret = wolfssl_client_ssl_new(client_ctx, &client_ssl);
|
||||
|
||||
if (ret == 0)
|
||||
ret = wolfssl_client_connect_tcp(client_ssl, &sockfd);
|
||||
|
||||
/* Keep trying to connect until handshake finished */
|
||||
while (ret == 0) {
|
||||
ret = wolfssl_client_connect(client_ssl);
|
||||
if (ret == 0 && wolfSSL_is_init_finished(client_ssl))
|
||||
break;
|
||||
}
|
||||
if (ret == 0)
|
||||
showPeerEx(client_ssl, 0);
|
||||
|
||||
/* Send HTTP request */
|
||||
if (ret == 0)
|
||||
ret = wolfssl_send(client_ssl, msgHTTPGet);
|
||||
/* Receive HTTP response */
|
||||
if (ret == 0)
|
||||
ret = wolfssl_recv(client_ssl);
|
||||
|
||||
if (sockfd != WOLFSSL_SOCKET_INVALID)
|
||||
CloseSocket(sockfd);
|
||||
if (client_ssl != NULL)
|
||||
wolfSSL_free(client_ssl);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
int ret = 0;
|
||||
WOLFSSL_CTX* client_ctx = NULL;
|
||||
|
||||
#if defined(DEBUG_WOLFSSL)
|
||||
wolfSSL_Debugging_ON();
|
||||
#endif
|
||||
/* Initialise wolfSSL library */
|
||||
wolfSSL_Init();
|
||||
|
||||
ret = wolfssl_client_ctx_new(&client_ctx);
|
||||
|
||||
/* Do client */
|
||||
ret = client(client_ctx);
|
||||
|
||||
if (client_ctx != NULL)
|
||||
wolfSSL_CTX_free(client_ctx);
|
||||
|
||||
/* Cleanup wolfSSL library */
|
||||
wolfSSL_Cleanup();
|
||||
|
||||
if (ret == 0)
|
||||
printf("Done\n");
|
||||
else {
|
||||
char buffer[80];
|
||||
printf("Error: %d, %s\n", ret, wolfSSL_ERR_error_string(ret, buffer));
|
||||
}
|
||||
|
||||
return (ret == 0) ? 0 : 1;
|
||||
}
|
||||
|
|
@ -0,0 +1,298 @@
|
|||
/* tls-sock-server-ca.c
|
||||
*
|
||||
* Copyright (C) 2006-2019 wolfSSL Inc.
|
||||
*
|
||||
* This file is part of wolfSSL. (formerly known as CyaSSL)
|
||||
*
|
||||
* 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-1301, USA
|
||||
*/
|
||||
|
||||
#include <wolfssl/options.h>
|
||||
#include <wolfssl/ssl.h>
|
||||
|
||||
#include "sockets.h"
|
||||
#include "tls-info.h"
|
||||
#include "certs.h"
|
||||
|
||||
/* Application data to send. */
|
||||
static const char msgHTTPIndex[] =
|
||||
"HTTP/1.1 200 OK\n"
|
||||
"Content-Type: text/html\n"
|
||||
"Connection: close\n"
|
||||
"\n"
|
||||
"<html>\n"
|
||||
"<head>\n"
|
||||
"<title>Welcome to wolfSSL!</title>\n"
|
||||
"</head>\n"
|
||||
"<body>\n"
|
||||
"<p>wolfSSL has successfully performed handshake!</p>\n"
|
||||
"</body>\n"
|
||||
"</html>\n";
|
||||
|
||||
|
||||
/* Create a new wolfSSL CTX server with a certificate for authentication and a
|
||||
* client certificate for client authentication.
|
||||
*/
|
||||
static int wolfssl_server_ctx_new(WOLFSSL_CTX** ctx)
|
||||
{
|
||||
int ret = 0;
|
||||
WOLFSSL_CTX* server_ctx = NULL;
|
||||
|
||||
/* Create and initialize WOLFSSL_CTX */
|
||||
if ((server_ctx = wolfSSL_CTX_new(wolfSSLv23_server_method())) == NULL) {
|
||||
printf("ERROR: failed to create WOLFSSL_CTX\n");
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
/* Load client certificates into WOLFSSL_CTX */
|
||||
if (wolfSSL_CTX_use_certificate_buffer(server_ctx, SERVER_CERT,
|
||||
SERVER_CERT_LEN, WOLFSSL_FILETYPE_ASN1) != WOLFSSL_SUCCESS) {
|
||||
printf("ERROR: failed to load server certiifcate\n");
|
||||
ret = -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
/* Load client certificates into WOLFSSL_CTX */
|
||||
if (wolfSSL_CTX_use_PrivateKey_buffer(server_ctx, SERVER_KEY,
|
||||
SERVER_KEY_LEN, WOLFSSL_FILETYPE_ASN1) != WOLFSSL_SUCCESS) {
|
||||
printf("ERROR: failed to load server key\n");
|
||||
ret = -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
wolfSSL_CTX_set_verify(server_ctx, WOLFSSL_VERIFY_PEER |
|
||||
WOLFSSL_VERIFY_FAIL_IF_NO_PEER_CERT, 0);
|
||||
|
||||
/* Load server certificates into WOLFSSL_CTX */
|
||||
if (wolfSSL_CTX_load_verify_buffer(server_ctx, CLIENT_CERT,
|
||||
CLIENT_CERT_LEN, WOLFSSL_FILETYPE_ASN1) != WOLFSSL_SUCCESS) {
|
||||
printf("ERROR: failed to load CA certiifcate\n");
|
||||
ret = -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
/* Return newly created wolfSSL context */
|
||||
*ctx = server_ctx;
|
||||
}
|
||||
else {
|
||||
if (server_ctx != NULL)
|
||||
wolfSSL_CTX_free(server_ctx);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Create a new wolfSSL server with a certificate for authentication. */
|
||||
static int wolfssl_server_ssl_new(WOLFSSL_CTX* ctx, WOLFSSL** ssl)
|
||||
{
|
||||
int ret = 0;
|
||||
WOLFSSL* server_ssl = NULL;
|
||||
|
||||
if (ret == 0) {
|
||||
/* Create a WOLFSSL object */
|
||||
if ((server_ssl = wolfSSL_new(ctx)) == NULL) {
|
||||
printf("ERROR: failed to create WOLFSSL object\n");
|
||||
ret = -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
/* make wolfSSL object nonblocking */
|
||||
wolfSSL_set_using_nonblock(server_ssl, 1);
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
/* Return newly created wolfSSL context and object */
|
||||
*ssl = server_ssl;
|
||||
}
|
||||
else {
|
||||
if (server_ssl != NULL)
|
||||
wolfSSL_free(server_ssl);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Server accepting a client using TLS */
|
||||
static int wolfssl_server_accept(WOLFSSL* ssl)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (wolfSSL_accept(ssl) != WOLFSSL_SUCCESS) {
|
||||
ret = wolfSSL_get_error(ssl, 0);
|
||||
if (ret == WOLFSSL_ERROR_WANT_READ)
|
||||
ret = 0;
|
||||
else if (ret > 0)
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* Send application data. */
|
||||
static int wolfssl_send(WOLFSSL* ssl, const char* msg)
|
||||
{
|
||||
int ret = 0;
|
||||
int len;
|
||||
|
||||
printf("Sending:\n%s\n", msg);
|
||||
len = wolfSSL_write(ssl, msg, XSTRLEN(msg));
|
||||
if (len < 0)
|
||||
ret = len;
|
||||
else if (len != XSTRLEN(msg))
|
||||
ret = -1;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Receive application data. */
|
||||
static int wolfssl_recv(WOLFSSL* ssl)
|
||||
{
|
||||
int ret;
|
||||
int err = 0;
|
||||
byte reply[80];
|
||||
int total = 0;
|
||||
|
||||
printf("Receive:\n");
|
||||
do {
|
||||
ret = wolfSSL_read(ssl, reply, sizeof(reply)-1);
|
||||
if (ret > 0) {
|
||||
reply[ret] = '\0';
|
||||
printf("%s", reply);
|
||||
total += ret;
|
||||
err = 0;
|
||||
}
|
||||
else if (ret == -1)
|
||||
err = wolfSSL_get_error(ssl, 0);
|
||||
}
|
||||
while (err == 0 || (total == 0 && err == WOLFSSL_ERROR_WANT_READ));
|
||||
|
||||
if (total > 0 && err == WOLFSSL_ERROR_WANT_READ)
|
||||
ret = 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Establish a socket to listen on. */
|
||||
static int wolfssl_server_listen_tcp(SOCKET_T* fd)
|
||||
{
|
||||
word16 port = wolfSSLPort;
|
||||
|
||||
return tcp_listen(fd, &port, 1, 0, 0);
|
||||
}
|
||||
|
||||
/* Accept the TCP connection from the client. */
|
||||
static int wolfssl_server_accept_tcp(WOLFSSL* ssl, SOCKET_T fd,
|
||||
SOCKET_T* acceptfd)
|
||||
{
|
||||
int ret = 0;
|
||||
SOCKET_T clientfd = WOLFSSL_SOCKET_INVALID;
|
||||
|
||||
ret = tcp_accept(&fd, &clientfd);
|
||||
if (ret == 0) {
|
||||
*acceptfd = clientfd;
|
||||
ret = tcp_set_nonblocking(&clientfd);
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
if (wolfSSL_set_fd(ssl, clientfd) != WOLFSSL_SUCCESS)
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* Server operations. */
|
||||
static int server(WOLFSSL_CTX* server_ctx, SOCKET_T sockfd)
|
||||
{
|
||||
int ret;
|
||||
WOLFSSL* server_ssl = NULL;
|
||||
SOCKET_T clientfd = WOLFSSL_SOCKET_INVALID;
|
||||
|
||||
do {
|
||||
ret = wolfssl_server_ssl_new(server_ctx, &server_ssl);
|
||||
if (ret == 0)
|
||||
ret = wolfssl_server_accept_tcp(server_ssl, sockfd, &clientfd);
|
||||
|
||||
while (ret == 0) {
|
||||
ret = wolfssl_server_accept(server_ssl);
|
||||
if (ret == 0 && wolfSSL_is_init_finished(server_ssl))
|
||||
break;
|
||||
}
|
||||
|
||||
if (ret == 0)
|
||||
showPeerEx(server_ssl, 0);
|
||||
|
||||
/* Receive HTTP request */
|
||||
if (ret == 0)
|
||||
ret = wolfssl_recv(server_ssl);
|
||||
/* Send HTTP repsonse */
|
||||
if (ret == 0)
|
||||
ret = wolfssl_send(server_ssl, msgHTTPIndex);
|
||||
|
||||
if (server_ssl != NULL)
|
||||
wolfSSL_free(server_ssl);
|
||||
|
||||
if (clientfd != WOLFSSL_SOCKET_INVALID)
|
||||
CloseSocket(clientfd);
|
||||
}
|
||||
while (ret == 0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Main entry point. */
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
int ret = 0;
|
||||
WOLFSSL_CTX* server_ctx = NULL;
|
||||
SOCKET_T sockfd = WOLFSSL_SOCKET_INVALID;
|
||||
|
||||
#if defined(DEBUG_WOLFSSL)
|
||||
wolfSSL_Debugging_ON();
|
||||
#endif
|
||||
/* Initialise wolfSSL library */
|
||||
wolfSSL_Init();
|
||||
|
||||
ret = wolfssl_server_ctx_new(&server_ctx);
|
||||
if (ret == 0)
|
||||
ret = wolfssl_server_listen_tcp(&sockfd);
|
||||
|
||||
/* Do server */
|
||||
ret = server(server_ctx, sockfd);
|
||||
|
||||
if (server_ctx != NULL)
|
||||
wolfSSL_CTX_free(server_ctx);
|
||||
if (sockfd != WOLFSSL_SOCKET_INVALID)
|
||||
CloseSocket(sockfd);
|
||||
|
||||
/* Cleanup wolfSSL library */
|
||||
wolfSSL_Cleanup();
|
||||
|
||||
if (ret == 0)
|
||||
printf("Done\n");
|
||||
else {
|
||||
char buffer[80];
|
||||
printf("Error: %d, %s\n", ret, wolfSSL_ERR_error_string(ret, buffer));
|
||||
}
|
||||
|
||||
return (ret == 0) ? 0 : 1;
|
||||
}
|
||||
|
|
@ -0,0 +1,284 @@
|
|||
/* tls-sock-server.c
|
||||
*
|
||||
* Copyright (C) 2006-2019 wolfSSL Inc.
|
||||
*
|
||||
* This file is part of wolfSSL. (formerly known as CyaSSL)
|
||||
*
|
||||
* 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-1301, USA
|
||||
*/
|
||||
|
||||
#include <wolfssl/options.h>
|
||||
#include <wolfssl/ssl.h>
|
||||
|
||||
#include "sockets.h"
|
||||
#include "tls-info.h"
|
||||
#include "certs.h"
|
||||
|
||||
/* Application data to send. */
|
||||
static const char msgHTTPIndex[] =
|
||||
"HTTP/1.1 200 OK\n"
|
||||
"Content-Type: text/html\n"
|
||||
"Connection: close\n"
|
||||
"\n"
|
||||
"<html>\n"
|
||||
"<head>\n"
|
||||
"<title>Welcome to wolfSSL!</title>\n"
|
||||
"</head>\n"
|
||||
"<body>\n"
|
||||
"<p>wolfSSL has successfully performed handshake!</p>\n"
|
||||
"</body>\n"
|
||||
"</html>\n";
|
||||
|
||||
|
||||
/* Create a new wolfSSL CTX server with a certificate for authentication. */
|
||||
static int wolfssl_server_ctx_new(WOLFSSL_CTX** ctx)
|
||||
{
|
||||
int ret = 0;
|
||||
WOLFSSL_CTX* server_ctx = NULL;
|
||||
|
||||
/* Create and initialize WOLFSSL_CTX */
|
||||
if ((server_ctx = wolfSSL_CTX_new(wolfSSLv23_server_method())) == NULL) {
|
||||
printf("ERROR: failed to create WOLFSSL_CTX\n");
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
/* Load client certificates into WOLFSSL_CTX */
|
||||
if (wolfSSL_CTX_use_certificate_buffer(server_ctx, SERVER_CERT,
|
||||
SERVER_CERT_LEN, WOLFSSL_FILETYPE_ASN1) != WOLFSSL_SUCCESS) {
|
||||
printf("ERROR: failed to load server certiifcate\n");
|
||||
ret = -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
/* Load client certificates into WOLFSSL_CTX */
|
||||
if (wolfSSL_CTX_use_PrivateKey_buffer(server_ctx, SERVER_KEY,
|
||||
SERVER_KEY_LEN, WOLFSSL_FILETYPE_ASN1) != WOLFSSL_SUCCESS) {
|
||||
printf("ERROR: failed to load server key\n");
|
||||
ret = -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
/* Return newly created wolfSSL context */
|
||||
*ctx = server_ctx;
|
||||
}
|
||||
else {
|
||||
if (server_ctx != NULL)
|
||||
wolfSSL_CTX_free(server_ctx);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Create a new wolfSSL server with a certificate for authentication. */
|
||||
static int wolfssl_server_ssl_new(WOLFSSL_CTX* ctx, WOLFSSL** ssl)
|
||||
{
|
||||
int ret = 0;
|
||||
WOLFSSL* server_ssl = NULL;
|
||||
|
||||
if (ret == 0) {
|
||||
/* Create a WOLFSSL object */
|
||||
if ((server_ssl = wolfSSL_new(ctx)) == NULL) {
|
||||
printf("ERROR: failed to create WOLFSSL object\n");
|
||||
ret = -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
/* make wolfSSL object nonblocking */
|
||||
wolfSSL_set_using_nonblock(server_ssl, 1);
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
/* Return newly created wolfSSL context and object */
|
||||
*ssl = server_ssl;
|
||||
}
|
||||
else {
|
||||
if (server_ssl != NULL)
|
||||
wolfSSL_free(server_ssl);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Server accepting a client using TLS */
|
||||
static int wolfssl_server_accept(WOLFSSL* ssl)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (wolfSSL_accept(ssl) != WOLFSSL_SUCCESS) {
|
||||
ret = wolfSSL_get_error(ssl, 0);
|
||||
if (ret == WOLFSSL_ERROR_WANT_READ)
|
||||
ret = 0;
|
||||
else if (ret > 0)
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* Send application data. */
|
||||
static int wolfssl_send(WOLFSSL* ssl, const char* msg)
|
||||
{
|
||||
int ret = 0;
|
||||
int len;
|
||||
|
||||
printf("Sending:\n%s\n", msg);
|
||||
len = wolfSSL_write(ssl, msg, XSTRLEN(msg));
|
||||
if (len < 0)
|
||||
ret = len;
|
||||
else if (len != XSTRLEN(msg))
|
||||
ret = -1;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Receive application data. */
|
||||
static int wolfssl_recv(WOLFSSL* ssl)
|
||||
{
|
||||
int ret;
|
||||
int err = 0;
|
||||
byte reply[80];
|
||||
int total = 0;
|
||||
|
||||
printf("Receive:\n");
|
||||
do {
|
||||
ret = wolfSSL_read(ssl, reply, sizeof(reply)-1);
|
||||
if (ret > 0) {
|
||||
reply[ret] = '\0';
|
||||
printf("%s", reply);
|
||||
total += ret;
|
||||
err = 0;
|
||||
}
|
||||
else if (ret == -1)
|
||||
err = wolfSSL_get_error(ssl, 0);
|
||||
}
|
||||
while (err == 0 || (total == 0 && err == WOLFSSL_ERROR_WANT_READ));
|
||||
|
||||
if (total > 0 && err == WOLFSSL_ERROR_WANT_READ)
|
||||
ret = 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Establish a socket to listen on. */
|
||||
static int wolfssl_server_listen_tcp(SOCKET_T* fd)
|
||||
{
|
||||
word16 port = wolfSSLPort;
|
||||
|
||||
return tcp_listen(fd, &port, 1, 0, 0);
|
||||
}
|
||||
|
||||
/* Accept the TCP connection from the client. */
|
||||
static int wolfssl_server_accept_tcp(WOLFSSL* ssl, SOCKET_T fd,
|
||||
SOCKET_T* acceptfd)
|
||||
{
|
||||
int ret = 0;
|
||||
SOCKET_T clientfd = WOLFSSL_SOCKET_INVALID;
|
||||
|
||||
ret = tcp_accept(&fd, &clientfd);
|
||||
if (ret == 0) {
|
||||
*acceptfd = clientfd;
|
||||
ret = tcp_set_nonblocking(&clientfd);
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
if (wolfSSL_set_fd(ssl, clientfd) != WOLFSSL_SUCCESS)
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* Server operations. */
|
||||
static int server(WOLFSSL_CTX* server_ctx, SOCKET_T sockfd)
|
||||
{
|
||||
int ret;
|
||||
WOLFSSL* server_ssl = NULL;
|
||||
SOCKET_T clientfd = WOLFSSL_SOCKET_INVALID;
|
||||
|
||||
do {
|
||||
ret = wolfssl_server_ssl_new(server_ctx, &server_ssl);
|
||||
if (ret == 0)
|
||||
ret = wolfssl_server_accept_tcp(server_ssl, sockfd, &clientfd);
|
||||
|
||||
while (ret == 0) {
|
||||
ret = wolfssl_server_accept(server_ssl);
|
||||
if (ret == 0 && wolfSSL_is_init_finished(server_ssl))
|
||||
break;
|
||||
}
|
||||
|
||||
if (ret == 0)
|
||||
showPeerEx(server_ssl, 0);
|
||||
|
||||
/* Receive HTTP request */
|
||||
if (ret == 0)
|
||||
ret = wolfssl_recv(server_ssl);
|
||||
/* Send HTTP repsonse */
|
||||
if (ret == 0)
|
||||
ret = wolfssl_send(server_ssl, msgHTTPIndex);
|
||||
|
||||
if (server_ssl != NULL)
|
||||
wolfSSL_free(server_ssl);
|
||||
|
||||
if (clientfd != WOLFSSL_SOCKET_INVALID)
|
||||
CloseSocket(clientfd);
|
||||
}
|
||||
while (ret == 0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Main entry point. */
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
int ret = 0;
|
||||
WOLFSSL_CTX* server_ctx = NULL;
|
||||
SOCKET_T sockfd = WOLFSSL_SOCKET_INVALID;
|
||||
|
||||
#if defined(DEBUG_WOLFSSL)
|
||||
wolfSSL_Debugging_ON();
|
||||
#endif
|
||||
/* Initialise wolfSSL library */
|
||||
wolfSSL_Init();
|
||||
|
||||
ret = wolfssl_server_ctx_new(&server_ctx);
|
||||
if (ret == 0)
|
||||
ret = wolfssl_server_listen_tcp(&sockfd);
|
||||
|
||||
/* Do server */
|
||||
ret = server(server_ctx, sockfd);
|
||||
|
||||
if (server_ctx != NULL)
|
||||
wolfSSL_CTX_free(server_ctx);
|
||||
if (sockfd != WOLFSSL_SOCKET_INVALID)
|
||||
CloseSocket(sockfd);
|
||||
|
||||
/* Cleanup wolfSSL library */
|
||||
wolfSSL_Cleanup();
|
||||
|
||||
if (ret == 0)
|
||||
printf("Done\n");
|
||||
else {
|
||||
char buffer[80];
|
||||
printf("Error: %d, %s\n", ret, wolfSSL_ERR_error_string(ret, buffer));
|
||||
}
|
||||
|
||||
return (ret == 0) ? 0 : 1;
|
||||
}
|
||||
|
|
@ -0,0 +1,468 @@
|
|||
/* tls-sock-threaded.c
|
||||
*
|
||||
* Copyright (C) 2006-2019 wolfSSL Inc.
|
||||
*
|
||||
* This file is part of wolfSSL. (formerly known as CyaSSL)
|
||||
*
|
||||
* 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-1301, USA
|
||||
*/
|
||||
|
||||
#include <wolfssl/options.h>
|
||||
#include <wolfssl/ssl.h>
|
||||
|
||||
#ifndef SINGLE_THREADED
|
||||
|
||||
#include "sockets.h"
|
||||
#include "threading.h"
|
||||
#include "certs.h"
|
||||
|
||||
/* Mutex to wait for server to be ready. */
|
||||
wolfSSL_Mutex server_mutex;
|
||||
|
||||
/* Application data to send. */
|
||||
static const char msgHTTPGet[] = "GET /index.html HTTP/1.0\r\n\r\n";
|
||||
static const char msgHTTPIndex[] =
|
||||
"HTTP/1.1 200 OK\n"
|
||||
"Content-Type: text/html\n"
|
||||
"Connection: close\n"
|
||||
"\n"
|
||||
"<html>\n"
|
||||
"<head>\n"
|
||||
"<title>Welcome to wolfSSL!</title>\n"
|
||||
"</head>\n"
|
||||
"<body>\n"
|
||||
"<p>wolfSSL has successfully performed handshake!</p>\n"
|
||||
"</body>\n"
|
||||
"</html>\n";
|
||||
|
||||
|
||||
/* Create a new wolfSSL client with a server CA certificate. */
|
||||
static int wolfssl_client_new(WOLFSSL_CTX** ctx, WOLFSSL** ssl)
|
||||
{
|
||||
int ret = 0;
|
||||
WOLFSSL_CTX* client_ctx = NULL;
|
||||
WOLFSSL* client_ssl = NULL;
|
||||
|
||||
/* Create and initialize WOLFSSL_CTX */
|
||||
if ((client_ctx = wolfSSL_CTX_new(wolfSSLv23_client_method())) == NULL) {
|
||||
printf("ERROR: failed to create WOLFSSL_CTX\n");
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
/* Load client certificates into WOLFSSL_CTX */
|
||||
if (wolfSSL_CTX_load_verify_buffer(client_ctx, CA_CERTS, CA_CERTS_LEN,
|
||||
WOLFSSL_FILETYPE_ASN1) != WOLFSSL_SUCCESS) {
|
||||
printf("ERROR: failed to load CA certiifcate\n");
|
||||
ret = -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
/* Create a WOLFSSL object */
|
||||
if ((client_ssl = wolfSSL_new(client_ctx)) == NULL) {
|
||||
printf("ERROR: failed to create WOLFSSL object\n");
|
||||
ret = -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
/* make wolfSSL object nonblocking */
|
||||
wolfSSL_set_using_nonblock(client_ssl, 1);
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
/* Return newly created wolfSSL context and object */
|
||||
*ctx = client_ctx;
|
||||
*ssl = client_ssl;
|
||||
}
|
||||
else {
|
||||
if (client_ssl != NULL)
|
||||
wolfSSL_free(client_ssl);
|
||||
if (client_ctx != NULL)
|
||||
wolfSSL_CTX_free(client_ctx);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Client connecting to server using TLS */
|
||||
static int wolfssl_client_connect(WOLFSSL* ssl)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (wolfSSL_connect(ssl) != WOLFSSL_SUCCESS) {
|
||||
ret = wolfSSL_get_error(ssl, 0);
|
||||
if (ret == WOLFSSL_ERROR_WANT_READ)
|
||||
ret = 0;
|
||||
else if (ret > 0)
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Create a new wolfSSL server with a certificate for authentication. */
|
||||
static int wolfssl_server_new(WOLFSSL_CTX** ctx, WOLFSSL** ssl)
|
||||
{
|
||||
int ret = 0;
|
||||
WOLFSSL_CTX* server_ctx = NULL;
|
||||
WOLFSSL* server_ssl = NULL;
|
||||
|
||||
/* Create and initialize WOLFSSL_CTX */
|
||||
if ((server_ctx = wolfSSL_CTX_new(wolfSSLv23_server_method())) == NULL) {
|
||||
printf("ERROR: failed to create WOLFSSL_CTX\n");
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
/* Load client certificates into WOLFSSL_CTX */
|
||||
if (wolfSSL_CTX_use_certificate_buffer(server_ctx, SERVER_CERT,
|
||||
SERVER_CERT_LEN, WOLFSSL_FILETYPE_ASN1) != WOLFSSL_SUCCESS) {
|
||||
printf("ERROR: failed to load server certiifcate\n");
|
||||
ret = -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
/* Load client certificates into WOLFSSL_CTX */
|
||||
if (wolfSSL_CTX_use_PrivateKey_buffer(server_ctx, SERVER_KEY,
|
||||
SERVER_KEY_LEN, WOLFSSL_FILETYPE_ASN1) != WOLFSSL_SUCCESS) {
|
||||
printf("ERROR: failed to load server key\n");
|
||||
ret = -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
/* Create a WOLFSSL object */
|
||||
if ((server_ssl = wolfSSL_new(server_ctx)) == NULL) {
|
||||
printf("ERROR: failed to create WOLFSSL object\n");
|
||||
ret = -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
/* make wolfSSL object nonblocking */
|
||||
wolfSSL_set_using_nonblock(server_ssl, 1);
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
/* Return newly created wolfSSL context and object */
|
||||
*ctx = server_ctx;
|
||||
*ssl = server_ssl;
|
||||
}
|
||||
else {
|
||||
if (server_ssl != NULL)
|
||||
wolfSSL_free(server_ssl);
|
||||
if (server_ctx != NULL)
|
||||
wolfSSL_CTX_free(server_ctx);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Server accepting a client using TLS */
|
||||
static int wolfssl_server_accept(WOLFSSL* ssl)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (wolfSSL_accept(ssl) != WOLFSSL_SUCCESS) {
|
||||
ret = wolfSSL_get_error(ssl, 0);
|
||||
if (ret == WOLFSSL_ERROR_WANT_READ)
|
||||
ret = 0;
|
||||
else if (ret > 0)
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* Send application data. */
|
||||
static int wolfssl_send(WOLFSSL* ssl, const char* msg)
|
||||
{
|
||||
int ret = 0;
|
||||
int len;
|
||||
|
||||
printf("Sending:\n%s\n", msg);
|
||||
len = wolfSSL_write(ssl, msg, XSTRLEN(msg));
|
||||
if (len < 0)
|
||||
ret = len;
|
||||
else if (len != XSTRLEN(msg))
|
||||
ret = -1;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Receive application data. */
|
||||
static int wolfssl_recv(WOLFSSL* ssl)
|
||||
{
|
||||
int ret;
|
||||
byte reply[256];
|
||||
|
||||
ret = wolfSSL_read(ssl, reply, sizeof(reply)-1);
|
||||
if (ret > 0) {
|
||||
reply[ret] = '\0';
|
||||
printf("Received:\n%s\n", reply);
|
||||
ret = 1;
|
||||
}
|
||||
else if (wolfSSL_want_read(ssl) || wolfSSL_want_write(ssl))
|
||||
ret = 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* Free the WOLFSSL object and context. */
|
||||
static void wolfssl_free(WOLFSSL_CTX* ctx, WOLFSSL* ssl)
|
||||
{
|
||||
if (ssl != NULL)
|
||||
wolfSSL_free(ssl);
|
||||
if (ctx != NULL)
|
||||
wolfSSL_CTX_free(ctx);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Start the server thread. */
|
||||
static void start_thread(THREAD_FUNC func, func_args* args, THREAD_TYPE* thread)
|
||||
{
|
||||
#if defined(_POSIX_THREADS) && !defined(__MINGW32__)
|
||||
pthread_create(thread, 0, func, args);
|
||||
#elif defined(WOLFSSL_TIRTOS)
|
||||
/* Initialize the defaults and set the parameters. */
|
||||
Task_Params taskParams;
|
||||
Task_Params_init(&taskParams);
|
||||
taskParams.arg0 = (UArg)args;
|
||||
taskParams.stackSize = 24*1024;
|
||||
*thread = Task_create((Task_FuncPtr)func, &taskParams, NULL);
|
||||
if (*thread == NULL) {
|
||||
printf("Failed to create new Task\n");
|
||||
}
|
||||
Task_yield();
|
||||
#elif defined(USE_WINDOWS_API)
|
||||
*thread = (THREAD_TYPE)_beginthreadex(0, 0, func, args, 0, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void join_thread(THREAD_TYPE thread)
|
||||
{
|
||||
#if defined(_POSIX_THREADS) && !defined(__MINGW32__)
|
||||
pthread_join(thread, 0);
|
||||
#elif defined(WOLFSSL_TIRTOS)
|
||||
while (1) {
|
||||
if (Task_getMode(thread) == Task_Mode_TERMINATED) {
|
||||
Task_sleep(5);
|
||||
break;
|
||||
}
|
||||
Task_yield();
|
||||
}
|
||||
#elif defined(USE_WINDOWS_API)
|
||||
WaitForSingleObject((HANDLE)thread, INFINITE);
|
||||
CloseHandle((HANDLE)thread);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/* Accept the TCP connection from the client. */
|
||||
int wolfssl_server_accept_tcp(WOLFSSL* ssl, SOCKET_T* fd, SOCKET_T* acceptfd)
|
||||
{
|
||||
int ret = 0;
|
||||
SOCKET_T sockfd = WOLFSSL_SOCKET_INVALID;
|
||||
SOCKET_T clientfd = WOLFSSL_SOCKET_INVALID;
|
||||
word16 port = wolfSSLPort;
|
||||
|
||||
ret = tcp_listen(&sockfd, &port, 1, 0, 0);
|
||||
|
||||
wc_UnLockMutex(&server_mutex);
|
||||
|
||||
if (ret == 0)
|
||||
ret = tcp_accept(&sockfd, &clientfd);
|
||||
if (ret == 0) {
|
||||
*acceptfd = clientfd;
|
||||
ret = tcp_set_nonblocking(&clientfd);
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
printf("Server has accepted client\n");
|
||||
if (wolfSSL_set_fd(ssl, clientfd) != WOLFSSL_SUCCESS)
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* Thread to do the server operations. */
|
||||
static THREAD_RETURN WOLFSSL_THREAD server_thread(void* args)
|
||||
{
|
||||
int ret = 0;
|
||||
WOLFSSL_CTX* server_ctx = NULL;
|
||||
WOLFSSL* server_ssl = NULL;
|
||||
SOCKET_T sockfd = WOLFSSL_SOCKET_INVALID;
|
||||
SOCKET_T clientfd = WOLFSSL_SOCKET_INVALID;
|
||||
|
||||
|
||||
if (ret == 0)
|
||||
ret = wolfssl_server_new(&server_ctx, &server_ssl);
|
||||
|
||||
if (ret == 0)
|
||||
ret = wolfssl_server_accept_tcp(server_ssl, &sockfd, &clientfd);
|
||||
|
||||
while (ret == 0) {
|
||||
ret = wolfssl_server_accept(server_ssl);
|
||||
if (ret == 0 && wolfSSL_is_init_finished(server_ssl))
|
||||
break;
|
||||
}
|
||||
|
||||
/* Receive HTTP request */
|
||||
while (ret == 0) {
|
||||
ret = wolfssl_recv(server_ssl);
|
||||
}
|
||||
if (ret == 1)
|
||||
ret = 0;
|
||||
/* Send HTTP repsonse */
|
||||
if (ret == 0)
|
||||
ret = wolfssl_send(server_ssl, msgHTTPIndex);
|
||||
|
||||
printf("Server Return: %d\n", ret);
|
||||
|
||||
wolfssl_free(server_ctx, server_ssl);
|
||||
|
||||
if (clientfd != WOLFSSL_SOCKET_INVALID)
|
||||
CloseSocket(clientfd);
|
||||
if (sockfd != WOLFSSL_SOCKET_INVALID)
|
||||
CloseSocket(sockfd);
|
||||
|
||||
#if defined(HAVE_ECC) && defined(FP_ECC)
|
||||
wc_ecc_fp_free(); /* free per thread cache */
|
||||
#endif
|
||||
|
||||
#ifndef WOLFSSL_TIRTOS
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* TCP connect to the server. */
|
||||
int wolfssl_client_connect_tcp(WOLFSSL* ssl, SOCKET_T* fd)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
ret = tcp_connect(fd, wolfSSLIP, wolfSSLPort, 0, 0, ssl);
|
||||
if (ret == 0)
|
||||
ret = tcp_set_nonblocking(fd);
|
||||
|
||||
if (ret == 0) {
|
||||
printf("Client has connected to server\n");
|
||||
if (wolfSSL_set_fd(ssl, *fd) != WOLFSSL_SUCCESS)
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Client connection operations */
|
||||
static int client()
|
||||
{
|
||||
int ret = 0;
|
||||
WOLFSSL_CTX* client_ctx = NULL;
|
||||
WOLFSSL* client_ssl = NULL;
|
||||
SOCKET_T sockfd = WOLFSSL_SOCKET_INVALID;
|
||||
|
||||
/* Create a new client connection */
|
||||
ret = wolfssl_client_new(&client_ctx, &client_ssl);
|
||||
|
||||
if (ret == 0)
|
||||
wolfssl_client_connect_tcp(client_ssl, &sockfd);
|
||||
|
||||
/* Keep trying to connect until handshake finished */
|
||||
while (ret == 0) {
|
||||
ret = wolfssl_client_connect(client_ssl);
|
||||
if (ret == 0 && wolfSSL_is_init_finished(client_ssl))
|
||||
break;
|
||||
}
|
||||
if (ret == 0)
|
||||
printf("Handshake complete\n");
|
||||
|
||||
/* Send HTTP request */
|
||||
if (ret == 0)
|
||||
ret = wolfssl_send(client_ssl, msgHTTPGet);
|
||||
/* Receive HTTP response */
|
||||
while (ret == 0)
|
||||
ret = wolfssl_recv(client_ssl);
|
||||
if (ret == 1)
|
||||
ret = 0;
|
||||
|
||||
printf("Client Return: %d\n", ret);
|
||||
|
||||
/* Free client conenction data */
|
||||
wolfssl_free(client_ctx, client_ssl);
|
||||
|
||||
if (sockfd != WOLFSSL_SOCKET_INVALID)
|
||||
CloseSocket(sockfd);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
int ret = 0;
|
||||
THREAD_TYPE serverThread;
|
||||
|
||||
#if defined(DEBUG_WOLFSSL)
|
||||
wolfSSL_Debugging_ON();
|
||||
#endif
|
||||
/* Initialise wolfSSL library */
|
||||
wolfSSL_Init();
|
||||
|
||||
/* Initialise mutex that synchronises when server is ready for client */
|
||||
wc_InitMutex(&server_mutex);
|
||||
|
||||
/* Unlocked by server thread */
|
||||
wc_LockMutex(&server_mutex);
|
||||
|
||||
/* Start server */
|
||||
start_thread(server_thread, NULL, &serverThread);
|
||||
|
||||
/* Wait for server to be ready */
|
||||
wc_LockMutex(&server_mutex);
|
||||
wc_UnLockMutex(&server_mutex);
|
||||
|
||||
/* Do client */
|
||||
client();
|
||||
|
||||
/* Cleanup finished thread */
|
||||
join_thread(serverThread);
|
||||
|
||||
/* Cleanup wolfSSL library */
|
||||
wolfSSL_Cleanup();
|
||||
|
||||
printf("Done\n");
|
||||
|
||||
return (ret == 0) ? 0 : 1;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
printf("Threading required - compile wolfSSL without SINGLE_THREAED\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,494 @@
|
|||
/* tls-threaded.c
|
||||
*
|
||||
* Copyright (C) 2006-2019 wolfSSL Inc.
|
||||
*
|
||||
* This file is part of wolfSSL. (formerly known as CyaSSL)
|
||||
*
|
||||
* 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-1301, USA
|
||||
*/
|
||||
|
||||
#include <wolfssl/options.h>
|
||||
#include <wolfssl/ssl.h>
|
||||
|
||||
#ifndef SINGLE_THREADED
|
||||
|
||||
#include "threading.h"
|
||||
#include "certs.h"
|
||||
|
||||
|
||||
/* I/O buffer size - wolfSSL buffers messages internally as well. */
|
||||
#define BUFFER_SIZE 2048
|
||||
|
||||
|
||||
/* Buffer to hold data for client to read. */
|
||||
unsigned char client_buffer[BUFFER_SIZE];
|
||||
int client_buffer_sz = 0;
|
||||
/* Mutex protecting access to client's read buffer. */
|
||||
wolfSSL_Mutex client_mutex;
|
||||
|
||||
/* Buffer to hold data for server to read. */
|
||||
unsigned char server_buffer[BUFFER_SIZE];
|
||||
int server_buffer_sz = 0;
|
||||
/* Mutex protecting access to server's read buffer. */
|
||||
wolfSSL_Mutex server_mutex;
|
||||
|
||||
/* Application data to send. */
|
||||
static const char msgHTTPGet[] = "GET /index.html HTTP/1.0\r\n\r\n";
|
||||
static const char msgHTTPIndex[] =
|
||||
"HTTP/1.1 200 OK\n"
|
||||
"Content-Type: text/html\n"
|
||||
"Connection: close\n"
|
||||
"\n"
|
||||
"<html>\n"
|
||||
"<head>\n"
|
||||
"<title>Welcome to wolfSSL!</title>\n"
|
||||
"</head>\n"
|
||||
"<body>\n"
|
||||
"<p>wolfSSL has successfully performed handshake!</p>\n"
|
||||
"</body>\n"
|
||||
"</html>\n";
|
||||
|
||||
|
||||
/* wolfSSL client wants to read data from the server. */
|
||||
static int recv_client(WOLFSSL* ssl, char* buff, int sz, void* ctx)
|
||||
{
|
||||
wc_LockMutex(&client_mutex);
|
||||
if (client_buffer_sz > 0) {
|
||||
/* Take as many bytes is available or requested from buffer. */
|
||||
if (sz > client_buffer_sz)
|
||||
sz = client_buffer_sz;
|
||||
XMEMCPY(buff, client_buffer, sz);
|
||||
if (sz < client_buffer_sz) {
|
||||
XMEMMOVE(client_buffer, client_buffer + sz, client_buffer_sz - sz);
|
||||
}
|
||||
client_buffer_sz -= sz;
|
||||
}
|
||||
else
|
||||
sz = WOLFSSL_CBIO_ERR_WANT_READ;
|
||||
wc_UnLockMutex(&client_mutex);
|
||||
|
||||
return sz;
|
||||
}
|
||||
|
||||
/* wolfSSL client wants to write data to the server. */
|
||||
static int send_client(WOLFSSL* ssl, char* buff, int sz, void* ctx)
|
||||
{
|
||||
wc_LockMutex(&server_mutex);
|
||||
if (server_buffer_sz < BUFFER_SIZE)
|
||||
{
|
||||
/* Put in as many bytes requested or will fit in buffer. */
|
||||
if (sz > BUFFER_SIZE - server_buffer_sz)
|
||||
sz = BUFFER_SIZE - server_buffer_sz;
|
||||
XMEMCPY(server_buffer + server_buffer_sz, buff, sz);
|
||||
server_buffer_sz += sz;
|
||||
}
|
||||
else
|
||||
sz = WOLFSSL_CBIO_ERR_WANT_WRITE;
|
||||
wc_UnLockMutex(&server_mutex);
|
||||
|
||||
return sz;
|
||||
}
|
||||
|
||||
/* wolfSSL server wants to read data from the client. */
|
||||
static int recv_server(WOLFSSL* ssl, char* buff, int sz, void* ctx)
|
||||
{
|
||||
wc_LockMutex(&server_mutex);
|
||||
if (server_buffer_sz > 0) {
|
||||
/* Take as many bytes is available or requested from buffer. */
|
||||
if (sz > server_buffer_sz)
|
||||
sz = server_buffer_sz;
|
||||
XMEMCPY(buff, server_buffer, sz);
|
||||
if (sz < server_buffer_sz) {
|
||||
XMEMMOVE(server_buffer, server_buffer + sz, server_buffer_sz - sz);
|
||||
}
|
||||
server_buffer_sz -= sz;
|
||||
}
|
||||
else
|
||||
sz = WOLFSSL_CBIO_ERR_WANT_READ;
|
||||
wc_UnLockMutex(&server_mutex);
|
||||
|
||||
return sz;
|
||||
}
|
||||
|
||||
/* wolfSSL server wants to write data to the client. */
|
||||
static int send_server(WOLFSSL* ssl, char* buff, int sz, void* ctx)
|
||||
{
|
||||
wc_LockMutex(&client_mutex);
|
||||
if (client_buffer_sz < BUFFER_SIZE)
|
||||
{
|
||||
/* Put in as many bytes requested or will fit in buffer. */
|
||||
if (sz > BUFFER_SIZE - client_buffer_sz)
|
||||
sz = BUFFER_SIZE - client_buffer_sz;
|
||||
XMEMCPY(client_buffer + client_buffer_sz, buff, sz);
|
||||
client_buffer_sz += sz;
|
||||
}
|
||||
else
|
||||
sz = WOLFSSL_CBIO_ERR_WANT_WRITE;
|
||||
wc_UnLockMutex(&client_mutex);
|
||||
|
||||
return sz;
|
||||
}
|
||||
|
||||
/* Create a new wolfSSL client with a server CA certificate. */
|
||||
static int wolfssl_client_new(WOLFSSL_CTX** ctx, WOLFSSL** ssl)
|
||||
{
|
||||
int ret = 0;
|
||||
WOLFSSL_CTX* client_ctx = NULL;
|
||||
WOLFSSL* client_ssl = NULL;
|
||||
|
||||
/* Create and initialize WOLFSSL_CTX */
|
||||
if ((client_ctx = wolfSSL_CTX_new(wolfSSLv23_client_method())) == NULL) {
|
||||
printf("ERROR: failed to create WOLFSSL_CTX\n");
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
/* Load client certificates into WOLFSSL_CTX */
|
||||
if (wolfSSL_CTX_load_verify_buffer(client_ctx, CA_CERTS, CA_CERTS_LEN,
|
||||
WOLFSSL_FILETYPE_ASN1) != WOLFSSL_SUCCESS) {
|
||||
printf("ERROR: failed to load CA certiifcate\n");
|
||||
ret = -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
/* Register callbacks */
|
||||
wolfSSL_SetIORecv(client_ctx, recv_client);
|
||||
wolfSSL_SetIOSend(client_ctx, send_client);
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
/* Create a WOLFSSL object */
|
||||
if ((client_ssl = wolfSSL_new(client_ctx)) == NULL) {
|
||||
printf("ERROR: failed to create WOLFSSL object\n");
|
||||
ret = -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
/* make wolfSSL object nonblocking */
|
||||
wolfSSL_set_using_nonblock(client_ssl, 1);
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
/* Return newly created wolfSSL context and object */
|
||||
*ctx = client_ctx;
|
||||
*ssl = client_ssl;
|
||||
}
|
||||
else {
|
||||
if (client_ssl != NULL)
|
||||
wolfSSL_free(client_ssl);
|
||||
if (client_ctx != NULL)
|
||||
wolfSSL_CTX_free(client_ctx);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Client connecting to server using TLS */
|
||||
static int wolfssl_client_connect(WOLFSSL* ssl)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (wolfSSL_connect(ssl) != WOLFSSL_SUCCESS) {
|
||||
if (!wolfSSL_want_read(ssl) && !wolfSSL_want_write(ssl))
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Create a new wolfSSL server with a certificate for authentication. */
|
||||
static int wolfssl_server_new(WOLFSSL_CTX** ctx, WOLFSSL** ssl)
|
||||
{
|
||||
int ret = 0;
|
||||
WOLFSSL_CTX* server_ctx = NULL;
|
||||
WOLFSSL* server_ssl = NULL;
|
||||
|
||||
/* Create and initialize WOLFSSL_CTX */
|
||||
if ((server_ctx = wolfSSL_CTX_new(wolfSSLv23_server_method())) == NULL) {
|
||||
printf("ERROR: failed to create WOLFSSL_CTX\n");
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
/* Load client certificates into WOLFSSL_CTX */
|
||||
if (wolfSSL_CTX_use_certificate_buffer(server_ctx, SERVER_CERT,
|
||||
SERVER_CERT_LEN, WOLFSSL_FILETYPE_ASN1) != WOLFSSL_SUCCESS) {
|
||||
printf("ERROR: failed to load server certiifcate\n");
|
||||
ret = -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
/* Load client certificates into WOLFSSL_CTX */
|
||||
if (wolfSSL_CTX_use_PrivateKey_buffer(server_ctx, SERVER_KEY,
|
||||
SERVER_KEY_LEN, WOLFSSL_FILETYPE_ASN1) != WOLFSSL_SUCCESS) {
|
||||
printf("ERROR: failed to load server key\n");
|
||||
ret = -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
/* Register callbacks */
|
||||
wolfSSL_SetIORecv(server_ctx, recv_server);
|
||||
wolfSSL_SetIOSend(server_ctx, send_server);
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
/* Create a WOLFSSL object */
|
||||
if ((server_ssl = wolfSSL_new(server_ctx)) == NULL) {
|
||||
printf("ERROR: failed to create WOLFSSL object\n");
|
||||
ret = -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
/* make wolfSSL object nonblocking */
|
||||
wolfSSL_set_using_nonblock(server_ssl, 1);
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
/* Return newly created wolfSSL context and object */
|
||||
*ctx = server_ctx;
|
||||
*ssl = server_ssl;
|
||||
}
|
||||
else {
|
||||
if (server_ssl != NULL)
|
||||
wolfSSL_free(server_ssl);
|
||||
if (server_ctx != NULL)
|
||||
wolfSSL_CTX_free(server_ctx);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Server accepting a client using TLS */
|
||||
static int wolfssl_server_accept(WOLFSSL* ssl)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (wolfSSL_accept(ssl) != WOLFSSL_SUCCESS) {
|
||||
if (!wolfSSL_want_read(ssl) && !wolfSSL_want_write(ssl))
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* Send application data. */
|
||||
static int wolfssl_send(WOLFSSL* ssl, const char* msg)
|
||||
{
|
||||
int ret = 0;
|
||||
int len;
|
||||
|
||||
printf("Sending:\n%s\n", msg);
|
||||
len = wolfSSL_write(ssl, msg, XSTRLEN(msg));
|
||||
if (len < 0)
|
||||
ret = len;
|
||||
else if (len != XSTRLEN(msg))
|
||||
ret = -1;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Receive application data. */
|
||||
static int wolfssl_recv(WOLFSSL* ssl)
|
||||
{
|
||||
int ret;
|
||||
byte reply[256];
|
||||
|
||||
ret = wolfSSL_read(ssl, reply, sizeof(reply)-1);
|
||||
if (ret > 0) {
|
||||
reply[ret] = '\0';
|
||||
printf("Received:\n%s\n", reply);
|
||||
ret = 1;
|
||||
}
|
||||
else if (wolfSSL_want_read(ssl) || wolfSSL_want_write(ssl))
|
||||
ret = 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* Free the WOLFSSL object and context. */
|
||||
static void wolfssl_free(WOLFSSL_CTX* ctx, WOLFSSL* ssl)
|
||||
{
|
||||
if (ssl != NULL)
|
||||
wolfSSL_free(ssl);
|
||||
if (ctx != NULL)
|
||||
wolfSSL_CTX_free(ctx);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Start the server thread. */
|
||||
static void start_thread(THREAD_FUNC func, func_args* args, THREAD_TYPE* thread)
|
||||
{
|
||||
#if defined(_POSIX_THREADS) && !defined(__MINGW32__)
|
||||
pthread_create(thread, 0, func, args);
|
||||
#elif defined(WOLFSSL_TIRTOS)
|
||||
/* Initialize the defaults and set the parameters. */
|
||||
Task_Params taskParams;
|
||||
Task_Params_init(&taskParams);
|
||||
taskParams.arg0 = (UArg)args;
|
||||
taskParams.stackSize = 24*1024;
|
||||
*thread = Task_create((Task_FuncPtr)func, &taskParams, NULL);
|
||||
if (*thread == NULL) {
|
||||
printf("Failed to create new Task\n");
|
||||
}
|
||||
Task_yield();
|
||||
#elif defined(USE_WINDOWS_API)
|
||||
*thread = (THREAD_TYPE)_beginthreadex(0, 0, func, args, 0, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void join_thread(THREAD_TYPE thread)
|
||||
{
|
||||
#if defined(_POSIX_THREADS) && !defined(__MINGW32__)
|
||||
pthread_join(thread, 0);
|
||||
#elif defined(WOLFSSL_TIRTOS)
|
||||
while(1) {
|
||||
if (Task_getMode(thread) == Task_Mode_TERMINATED) {
|
||||
Task_sleep(5);
|
||||
break;
|
||||
}
|
||||
Task_yield();
|
||||
}
|
||||
#elif defined(USE_WINDOWS_API)
|
||||
WaitForSingleObject((HANDLE)thread, INFINITE);
|
||||
CloseHandle((HANDLE)thread);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/* Thread to do the server operations. */
|
||||
static THREAD_RETURN WOLFSSL_THREAD server_thread(void* args)
|
||||
{
|
||||
int ret = 0;
|
||||
WOLFSSL_CTX* server_ctx = NULL;
|
||||
WOLFSSL* server_ssl = NULL;
|
||||
|
||||
|
||||
if (ret == 0)
|
||||
ret = wolfssl_server_new(&server_ctx, &server_ssl);
|
||||
|
||||
while (ret == 0) {
|
||||
ret = wolfssl_server_accept(server_ssl);
|
||||
if (ret == 0 && wolfSSL_is_init_finished(server_ssl))
|
||||
break;
|
||||
}
|
||||
|
||||
/* Receive HTTP request */
|
||||
while (ret == 0) {
|
||||
ret = wolfssl_recv(server_ssl);
|
||||
}
|
||||
if (ret == 1)
|
||||
ret = 0;
|
||||
/* Send HTTP repsonse */
|
||||
if (ret == 0)
|
||||
ret = wolfssl_send(server_ssl, msgHTTPIndex);
|
||||
|
||||
printf("Server Return: %d\n", ret);
|
||||
|
||||
wolfssl_free(server_ctx, server_ssl);
|
||||
|
||||
#if defined(HAVE_ECC) && defined(FP_ECC)
|
||||
wc_ecc_fp_free(); /* free per thread cache */
|
||||
#endif
|
||||
|
||||
#ifndef WOLFSSL_TIRTOS
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Client connection operations */
|
||||
static int client()
|
||||
{
|
||||
int ret = 0;
|
||||
WOLFSSL_CTX* client_ctx = NULL;
|
||||
WOLFSSL* client_ssl = NULL;
|
||||
|
||||
/* Create a new client connection */
|
||||
ret = wolfssl_client_new(&client_ctx, &client_ssl);
|
||||
|
||||
/* Keep trying to connect until handshake finished */
|
||||
while (ret == 0) {
|
||||
ret = wolfssl_client_connect(client_ssl);
|
||||
if (ret == 0 && wolfSSL_is_init_finished(client_ssl))
|
||||
break;
|
||||
}
|
||||
if (ret == 0)
|
||||
printf("Handshake complete\n");
|
||||
|
||||
/* Send HTTP request */
|
||||
if (ret == 0)
|
||||
ret = wolfssl_send(client_ssl, msgHTTPGet);
|
||||
/* Receive HTTP response */
|
||||
while (ret == 0)
|
||||
ret = wolfssl_recv(client_ssl);
|
||||
if (ret == 1)
|
||||
ret = 0;
|
||||
|
||||
printf("Client Return: %d\n", ret);
|
||||
|
||||
/* Free client conenction data */
|
||||
wolfssl_free(client_ctx, client_ssl);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
int ret = 0;
|
||||
THREAD_TYPE serverThread;
|
||||
|
||||
#if defined(DEBUG_WOLFSSL)
|
||||
wolfSSL_Debugging_ON();
|
||||
#endif
|
||||
/* Initialise wolfSSL library */
|
||||
wolfSSL_Init();
|
||||
|
||||
/* Initialise mutexs protecting I/O buffers */
|
||||
wc_InitMutex(&client_mutex);
|
||||
wc_InitMutex(&server_mutex);
|
||||
|
||||
/* Start server */
|
||||
start_thread(server_thread, NULL, &serverThread);
|
||||
/* Do client */
|
||||
client();
|
||||
/* Cleanup finished thread */
|
||||
join_thread(serverThread);
|
||||
|
||||
/* Cleanup wolfSSL library */
|
||||
wolfSSL_Cleanup();
|
||||
|
||||
printf("Done\n");
|
||||
|
||||
return (ret == 0) ? 0 : 1;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
printf("Requires threading - compile wolfssl without SINGLE_THREADED\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue