diff --git a/.gitignore b/.gitignore index 1bc8d81d..cac97196 100644 --- a/.gitignore +++ b/.gitignore @@ -59,12 +59,15 @@ android/wolfssljni-ndk-sample/proguard-project.txt /dtls/server-dtls /dtls/server-udp +/psk/client-psk-bio-custom /psk/client-psk-nonblocking /psk/client-psk-resume +/psk/client-psk-tls13-multi-id /psk/client-psk /psk/client-tcp /psk/server-psk-nonblocking /psk/server-psk-threaded +/psk/server-psk-tls13-multi-id /psk/server-psk /psk/server-tcp diff --git a/psk/Makefile b/psk/Makefile index 8f93961a..71a63395 100644 --- a/psk/Makefile +++ b/psk/Makefile @@ -1,13 +1,13 @@ CC=gcc -CFLAGS=-Wall -I/usr/local/include -LIBS=-lwolfssl -lm -L/usr/local/lib +CFLAGS=-Wall -I../../wolfssl -g -DDEBUG +LIBS=-lwolfssl -lm -L../../wolfssl/src/.libs # For debug (./configure --enable-debug --disable-shared) #LIBS=/usr/local/lib/libwolfssl.a #CFLAGS+=-g -DDEBUG -all: client-tcp client-psk client-psk-nonblocking client-psk-resume server-tcp server-psk server-psk-nonblocking server-psk-threaded client-psk-bio-custom +all: client-tcp client-psk client-psk-nonblocking client-psk-resume client-psk-tls13-multi-id server-tcp server-psk server-psk-nonblocking server-psk-threaded client-psk-bio-custom server-psk-tls13-multi-id client-tcp: client-tcp.o $(CC) -o $@ $^ $(CFLAGS) @@ -21,6 +21,9 @@ client-psk-nonblocking: client-psk-nonblocking.o client-psk-resume: client-psk-resume.o $(CC) -o $@ $^ $(CFLAGS) $(LIBS) +client-psk-tls13-multi-id: client-psk-tls13-multi-id.o + $(CC) -o $@ $^ $(CFLAGS) $(LIBS) + server-tcp: server-tcp.o $(CC) -o $@ $^ $(CFLAGS) @@ -36,7 +39,10 @@ server-psk-threaded: server-psk-threaded.o client-psk-bio-custom: client-psk-bio-custom.o $(CC) -o $@ $^ $(CFLAGS) $(LIBS) +server-psk-tls13-multi-id: server-psk-tls13-multi-id.o + $(CC) -o $@ $^ $(CFLAGS) $(LIBS) + .PHONY: clean all clean: - rm -f *.o client-tcp client-psk client-psk-nonblocking client-psk-resume server-tcp server-psk server-psk-nonblocking server-psk-threaded client-psk-bio-custom + rm -f *.o client-tcp client-psk client-psk-nonblocking client-psk-resume client-psk-tls13-multi-id server-tcp server-psk server-psk-nonblocking server-psk-threaded client-psk-bio-custom server-psk-tls13-multi-id diff --git a/psk/client-psk-tls13-multi-id.c b/psk/client-psk-tls13-multi-id.c new file mode 100644 index 00000000..9221271c --- /dev/null +++ b/psk/client-psk-tls13-multi-id.c @@ -0,0 +1,182 @@ + +/* client-psk.c + * + * Copyright (C) 2006-2020 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 /* included for options sync */ +#include /* must include this to use wolfSSL security */ + +#include +#include +#include +#include +#include +#include +#include + +#define MAXLINE 256 /* max text line length */ +#define SERV_PORT 11111 /* default port*/ +#define PSK_KEY_LEN 4 + +/* + *psk client set up. + */ +static inline unsigned int My_Tls13_Psk_Client_Cs_Cb(WOLFSSL* ssl, + const char* hint, char* identity, unsigned int id_max_len, + unsigned char* key, unsigned int key_max_len, const char* ciphersuite) +{ + (void)ssl; + (void)hint; + (void)key_max_len; + + if (strncmp(ciphersuite, "TLS13-AES128-GCM-SHA256", + XSTRLEN(ciphersuite)) == 0) { + + /* identity is OpenSSL testing default for openssl s_client, keep same*/ + strncpy(identity, "Client_Id_AES", id_max_len); + + /* test key n hex is 0x1a2b3c4d */ + key[0] = 0x1a; + key[1] = 0x2b; + key[2] = 0x3c; + key[3] = 0x4d; + } + else if (strncmp(ciphersuite, "TLS13-CHACHA20-POLY1305-SHA256", + XSTRLEN(ciphersuite)) == 0) { + + /* identity is OpenSSL testing default for openssl s_client, keep same*/ + strncpy(identity, "Client_Id_ChaCha", id_max_len); + + /* test key n hex is 0xa1b2c3d4 */ + key[0] = 0xa1; + key[1] = 0xb2; + key[2] = 0xc3; + key[3] = 0xd4; + } + else { + return 0; + } + + return PSK_KEY_LEN; +} + +int main(int argc, char **argv) +{ + int ret; + int sockfd = SOCKET_INVALID; + char sendline[MAXLINE]="Hello Server"; /* string to send to the server */ + char recvline[MAXLINE]; /* string received from the server */ + struct sockaddr_in servaddr;; + + WOLFSSL* ssl = NULL; + WOLFSSL_CTX* ctx = NULL; + + /* must include an ip address of this will flag */ + if (argc != 2) { + printf("Usage: tcpClient \n"); + return -1; + } + + /* create a stream socket using tcp,internet protocal IPv4, + * full-duplex stream */ + sockfd = socket(AF_INET, SOCK_STREAM, 0); + + /* places n zero-valued bytes in the address servaddr */ + memset(&servaddr, 0, sizeof(servaddr)); + + servaddr.sin_family = AF_INET; + servaddr.sin_port = htons(SERV_PORT); + + /* converts IPv4 addresses from text to binary form */ + ret = inet_pton(AF_INET, argv[1], &servaddr.sin_addr); + if (ret != 1) { + printf("inet_pton error\n"); + ret = -1; + goto exit; + } + + /* attempts to make a connection on a socket */ + ret = connect(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr)); + if (ret != 0) { + printf("Connection Error\n"); + ret = -1; + goto exit; + } + + + wolfSSL_Init(); /* initialize wolfSSL */ + + /* create and initialize WOLFSSL_CTX structure */ + if ((ctx = wolfSSL_CTX_new(wolfTLSv1_3_client_method())) == NULL) { + fprintf(stderr, "wolfSSL_CTX_new error.\n"); + ret = -1; + goto exit; + } + + /* set up pre shared keys */ + wolfSSL_CTX_set_psk_client_cs_callback(ctx, My_Tls13_Psk_Client_Cs_Cb); + + /* creat wolfssl object after each tcp connect */ + if ( (ssl = wolfSSL_new(ctx)) == NULL) { + fprintf(stderr, "wolfSSL_new error.\n"); + ret = -1; + goto exit; + } + + /* associate the file descriptor with the session */ + ret = wolfSSL_set_fd(ssl, sockfd); + if (ret != WOLFSSL_SUCCESS) { + goto exit; + } + + /* write string to the server */ + if (wolfSSL_write(ssl, sendline, MAXLINE) != sizeof(sendline)) { + printf("Write Error to Server\n"); + ret = -1; + goto exit; + } + + /* check if server ended before client could read a response */ + if (wolfSSL_read(ssl, recvline, MAXLINE) < 0 ) { + printf("Client: Server Terminated Prematurely!\n"); + ret = -1; + goto exit; + } + + WOLFSSL_CIPHER* cipher = wolfSSL_get_current_cipher(ssl); + printf("Cipher suite: %s\n", wolfSSL_CIPHER_get_name(cipher)); + + /* show message from the server */ + printf("Server Message: %s\n", recvline); + + ret = 0; + +exit: + /* Cleanup and return */ + if (ssl) + wolfSSL_free(ssl); /* Free the wolfSSL object */ + if (sockfd != SOCKET_INVALID) + close(sockfd); /* Close the socket */ + if (ctx) + wolfSSL_CTX_free(ctx); /* Free the wolfSSL context object */ + wolfSSL_Cleanup(); /* Cleanup the wolfSSL environment */ + + return ret; /* Return reporting a success */ +} diff --git a/psk/server-psk-tls13-multi-id.c b/psk/server-psk-tls13-multi-id.c new file mode 100644 index 00000000..4946b2e8 --- /dev/null +++ b/psk/server-psk-tls13-multi-id.c @@ -0,0 +1,215 @@ +/* server-psk.c + * A server ecample using a TCP connection with PSK security. + * + * Copyright (C) 2006-2020 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 /* included for options sync */ +#include /* include wolfSSL security */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define MAXLINE 4096 +#define LISTENQ 1024 +#define SERV_PORT 11111 +#define PSK_KEY_LEN 4 +#define dhParamFile "../certs/dh2048.pem" + +/* + * Identify which psk key to use. + */ +static unsigned int my_tls13_psk_server_cb(WOLFSSL* ssl, const char* identity, + unsigned char* key, unsigned int key_max_len, const char** ciphersuite) +{ + (void)ssl; + (void)key_max_len; + + if (strncmp(identity, "Client_Id_AES", 14) == 0) { + + key[0] = 0x1a; + key[1] = 0x2b; + key[2] = 0x3c; + key[3] = 0x4d; + + *ciphersuite = "TLS13-AES128-GCM-SHA256"; + } + else if (strncmp(identity, "Client_Id_ChaCha", 17) == 0) { + + key[0] = 0xa1; + key[1] = 0xb2; + key[2] = 0xc3; + key[3] = 0xd4; + + *ciphersuite = "TLS13-CHACHA20-POLY1305-SHA256"; + } + else { + return 0; + } + + return PSK_KEY_LEN; +} + +int main() +{ + int n; /* length of string read */ + int listenfd, connfd, ret; + int opt; + char buff[MAXLINE]; + char buf[MAXLINE]; /* string read from client */ + char response[] = "I hear ya for shizzle"; + char suites[] = "TLS13-CHACHA20-POLY1305-SHA256:" + "TLS13-AES128-GCM-SHA256:" + "TLS13-AES256-GCM-SHA384:"; + + struct sockaddr_in cliAddr, servAddr; + socklen_t cliLen; + WOLFSSL_CTX* ctx; + + +#if defined(DEBUG_WOLFSSL) + wolfSSL_Debugging_ON(); +#endif + + /* set up server address and port */ + memset(&servAddr, 0, sizeof(servAddr)); + servAddr.sin_family = AF_INET; + servAddr.sin_addr.s_addr = htonl(INADDR_ANY); + servAddr.sin_port = htons(SERV_PORT); + + /* find a socket */ + listenfd = socket(AF_INET, SOCK_STREAM, 0); + if (listenfd < 0) { + printf("Fatal error : socket error\n"); + return 1; + } + + /* bind to a socket */ + opt = 1; + if (setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, (const void *)&opt, + sizeof(int)) != 0) { + printf("Fatal error : setsockopt error\n"); + return 1; + } + if (bind(listenfd, (struct sockaddr *) &servAddr, sizeof(servAddr)) < 0) { + printf("Fatal error : bind error\n"); + return 1; + } + + /* listen to the socket */ + if (listen(listenfd, LISTENQ) < 0) { + printf("Fatal error : listen error\n"); + return 1; + } + + wolfSSL_Init(); + /* create ctx and configure certificates */ + if ((ctx = wolfSSL_CTX_new(wolfTLSv1_3_server_method())) == NULL) { + printf("Fatal error : wolfSSL_CTX_new error\n"); + return 1; + } + + /* use psk suite for security */ + wolfSSL_CTX_set_psk_server_tls13_callback(ctx, my_tls13_psk_server_cb); + + if ((ret = wolfSSL_CTX_use_psk_identity_hint(ctx, "wolfssl server")) + != WOLFSSL_SUCCESS) { + printf("Fatal error : ctx use psk identity hint returned %d\n", ret); + return ret; + } + + if ((ret = wolfSSL_CTX_set_cipher_list(ctx, suites)) != WOLFSSL_SUCCESS) { + printf("Fatal error : server set cipher list returned %d\n", ret); + return ret; + } + +#ifndef NO_DH + if ((ret = wolfSSL_CTX_SetTmpDH_file(ctx, dhParamFile, WOLFSSL_FILETYPE_PEM) + ) != WOLFSSL_SUCCESS) { + printf("Fatal error: server set temp DH params returned %d\n", ret); + return ret; + } +#endif + + /* main loop for accepting and responding to clients */ + for ( ; ; ) { + WOLFSSL* ssl; + + cliLen = sizeof(cliAddr); + connfd = accept(listenfd, (struct sockaddr *) &cliAddr, &cliLen); + if (connfd < 0) { + printf("Fatal error : accept error\n"); + return 1; + } + else { + printf("Connection from %s, port %d\n", + inet_ntop(AF_INET, &cliAddr.sin_addr, buff, sizeof(buff)), + ntohs(cliAddr.sin_port)); + + /* create WOLFSSL object and respond */ + if ((ssl = wolfSSL_new(ctx)) == NULL) { + printf("Fatal error : wolfSSL_new error\n"); + return 1; + } + + /* sets the file descriptor of the socket for the ssl session */ + wolfSSL_set_fd(ssl, connfd); + + /* making sure buffered to store data sent from client is empty */ + memset(buf, 0, MAXLINE); + + /* reads and displays data sent by client if no errors occur */ + n = wolfSSL_read(ssl, buf, MAXLINE); + if (n > 0) { + printf("%s\n", buf); + /* server response */ + if (wolfSSL_write(ssl, response, strlen(response)) > + strlen(response)) { + printf("Fatal error : respond: write error\n"); + return 1; + } + } + if (n < 0) { + printf("Fatal error :respond: read error\n"); + return 1; + } + + /* closes the connections after responding */ + wolfSSL_shutdown(ssl); + wolfSSL_free(ssl); + + if (close(connfd) == -1) { + printf("Fatal error : close error\n"); + return 1; + } + } + } + /* free up memory used by wolfSSL */ + wolfSSL_CTX_free(ctx); + wolfSSL_Cleanup(); + + return 0; +} +