Merge branch 'master' of https://github.com/wolfssl/wolfssl-examples into tls-simplify
commit
beab3faa87
|
@ -19,10 +19,10 @@
|
|||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <wolfssl/options.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <termios.h>
|
||||
#include <wolfssl/options.h>
|
||||
#include <wolfssl/wolfcrypt/des3.h>
|
||||
#include <wolfssl/wolfcrypt/sha256.h>
|
||||
#include <wolfssl/wolfcrypt/random.h>
|
||||
|
@ -46,7 +46,7 @@ int GenerateKey(RNG* rng, byte* key, int size, byte* salt, int pad)
|
|||
salt[0] = 0; /* message is padded */
|
||||
|
||||
/* stretches key */
|
||||
ret = wc_PBKDF2(key, key, strlen((const char*)key), salt, SALT_SIZE, 4096,
|
||||
ret = wc_PBKDF2(key, key, strlen((const char*)key), salt, SALT_SIZE, 4096,
|
||||
size, SHA256);
|
||||
if (ret != 0)
|
||||
return -1030;
|
||||
|
@ -55,7 +55,7 @@ int GenerateKey(RNG* rng, byte* key, int size, byte* salt, int pad)
|
|||
}
|
||||
|
||||
/*
|
||||
* Encrypts a file using 3DES
|
||||
* Encrypts a file using 3DES
|
||||
*/
|
||||
int Des3Encrypt(Des3* des3, byte* key, int size, FILE* inFile, FILE* outFile)
|
||||
{
|
||||
|
@ -108,7 +108,7 @@ int Des3Encrypt(Des3* des3, byte* key, int size, FILE* inFile, FILE* outFile)
|
|||
|
||||
/* stretches key to fit size */
|
||||
ret = GenerateKey(&rng, key, size, salt, padCounter);
|
||||
if (ret != 0)
|
||||
if (ret != 0)
|
||||
return -1040;
|
||||
|
||||
/* sets key */
|
||||
|
@ -135,12 +135,13 @@ int Des3Encrypt(Des3* des3, byte* key, int size, FILE* inFile, FILE* outFile)
|
|||
free(key);
|
||||
fclose(inFile);
|
||||
fclose(outFile);
|
||||
wc_FreeRng(&rng);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Decrypts a file using 3DES
|
||||
* Decrypts a file using 3DES
|
||||
*/
|
||||
int Des3Decrypt(Des3* des3, byte* key, int size, FILE* inFile, FILE* outFile)
|
||||
{
|
||||
|
@ -218,6 +219,7 @@ int Des3Decrypt(Des3* des3, byte* key, int size, FILE* inFile, FILE* outFile)
|
|||
free(key);
|
||||
fclose(inFile);
|
||||
fclose(outFile);
|
||||
wc_FreeRng(&rng);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
How to use 3des-file-encrypt.c
|
||||
|
||||
1) a. Compile wolfSSL with ./configure --enable-pwdbased --enable-3des, run
|
||||
1) a. Compile wolfSSL with ./configure --enable-pwdbased --enable-des3, run
|
||||
'make', and then install by typing 'sudo make install'.
|
||||
b. In the crypto/3des directory run the Makefile by typing 'make'.
|
||||
2) Make a file to encode. Can be any file (ex. .txt .in .out .file etc.)
|
||||
3) run the excecutable, for help run with -h flag. Basic command is as follows:
|
||||
|
||||
./3des-file-encrypt <-option> <KeySize> <input.file> <output.file>
|
||||
|
||||
KeySize examples: 56, 112, or 168
|
||||
|
|
|
@ -134,6 +134,7 @@ int AesEncrypt(Aes* aes, byte* key, int size, FILE* inFile, FILE* outFile)
|
|||
free(key);
|
||||
fclose(inFile);
|
||||
fclose(outFile);
|
||||
wc_FreeRng(&rng);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -217,6 +218,7 @@ int AesDecrypt(Aes* aes, byte* key, int size, FILE* inFile, FILE* outFile)
|
|||
free(key);
|
||||
fclose(inFile);
|
||||
fclose(outFile);
|
||||
wc_FreeRng(&rng);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -133,6 +133,7 @@ int CamelliaEncrypt(Camellia* cam, byte* key, int size, FILE* inFile,
|
|||
free(key);
|
||||
fclose(inFile);
|
||||
fclose(outFile);
|
||||
wc_FreeRng(&rng);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -341,6 +342,6 @@ int main(int argc, char** argv)
|
|||
else if (choice == 'n') {
|
||||
printf("Must select either -e or -d for encryption and decryption\n");
|
||||
}
|
||||
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -63,7 +63,6 @@ int main()
|
|||
fclose(derFile);
|
||||
wc_ecc_free(&key);
|
||||
|
||||
|
||||
/* open and read from der file */
|
||||
printf("reading in private key\n");
|
||||
derFile = fopen("ecc-key.der", "rb");
|
||||
|
@ -118,7 +117,7 @@ int main()
|
|||
/* close stuff up */
|
||||
fclose(derFile);
|
||||
wc_ecc_free(&key);
|
||||
|
||||
wc_FreeRng(&rng);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -31,7 +31,6 @@ server-dtls-nonblocking: server-dtls-nonblocking.o
|
|||
server-dtls-threaded: server-dtls-threaded.o
|
||||
$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
|
||||
|
||||
|
||||
.PHONY: clean all
|
||||
|
||||
clean:
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* client-dtls-nonblocking.c
|
||||
/*
|
||||
* client-dtls-nonblocking.c
|
||||
*
|
||||
* Copyright (C) 2006-2015 wolfSSL Inc.
|
||||
*
|
||||
|
@ -24,11 +24,11 @@
|
|||
* Bare-bones example of a DTLS client for instructional/learning purposes.
|
||||
*/
|
||||
|
||||
#include <wolfssl/options.h>
|
||||
#include <unistd.h>
|
||||
#include <wolfssl/ssl.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <wolfssl/options.h>
|
||||
#include <netdb.h>
|
||||
#include <signal.h>
|
||||
#include <sys/socket.h>
|
||||
|
@ -39,7 +39,7 @@
|
|||
#include <string.h>
|
||||
|
||||
#define MAXLINE 4096
|
||||
#define SERV_PORT 11111
|
||||
#define SERV_PORT 11111
|
||||
|
||||
enum {
|
||||
TEST_SELECT_FAIL,
|
||||
|
@ -48,113 +48,29 @@ enum {
|
|||
TEST_ERROR_READY
|
||||
};
|
||||
|
||||
/* Tcp select using dtls nonblocking function */
|
||||
static int dtls_select(int socketfd, int to_sec)
|
||||
int main (int argc, char** argv)
|
||||
{
|
||||
/* standard variables used in a dtls client*/
|
||||
int sockfd = 0;
|
||||
struct sockaddr_in servAddr;
|
||||
const char* host = argv[1];
|
||||
WOLFSSL* ssl = 0;
|
||||
WOLFSSL_CTX* ctx = 0;
|
||||
char cert_array[] = "../certs/ca-cert.pem";
|
||||
char* certs = cert_array;
|
||||
/* variables used for non-blocking DTLS connect */
|
||||
int ret = wolfSSL_connect(ssl);
|
||||
int error = wolfSSL_get_error(ssl, 0);
|
||||
int nb_sockfd = (int) wolfSSL_get_fd(ssl);
|
||||
int select_ret;
|
||||
int currTimeout;
|
||||
int nfds;
|
||||
int result;
|
||||
fd_set recvfds, errfds;
|
||||
struct timeval timeout;
|
||||
|
||||
fd_set recvfds, errfds;
|
||||
int nfds = socketfd +1;
|
||||
struct timeval timeout = { (to_sec > 0) ? to_sec : 0, 0};
|
||||
int result;
|
||||
|
||||
FD_ZERO(&recvfds);
|
||||
FD_SET(socketfd, &recvfds);
|
||||
FD_ZERO(&errfds);
|
||||
FD_SET(socketfd, &errfds);
|
||||
|
||||
result = select(nfds, &recvfds, NULL, &errfds, &timeout);
|
||||
|
||||
if (result == 0)
|
||||
return TEST_TIMEOUT;
|
||||
else if (result > 0) {
|
||||
if (FD_ISSET(socketfd, &recvfds))
|
||||
return TEST_RECV_READY;
|
||||
else if (FD_ISSET(socketfd, &errfds))
|
||||
return TEST_ERROR_READY;
|
||||
}
|
||||
return TEST_SELECT_FAIL;
|
||||
}
|
||||
|
||||
/* Connect using Nonblocking - DTLS version */
|
||||
static void NonBlockingDTLS_Connect(WOLFSSL* ssl)
|
||||
{
|
||||
int ret = wolfSSL_connect(ssl);
|
||||
int error = wolfSSL_get_error(ssl, 0);
|
||||
int sockfd = (int)wolfSSL_get_fd(ssl);
|
||||
int select_ret;
|
||||
|
||||
while (ret != SSL_SUCCESS && (error == SSL_ERROR_WANT_READ ||
|
||||
error == SSL_ERROR_WANT_WRITE)) {
|
||||
int currTimeout = 1;
|
||||
if (error == SSL_ERROR_WANT_READ)
|
||||
printf("... client would read block\n");
|
||||
else
|
||||
printf("... client would write block\n");
|
||||
currTimeout = wolfSSL_dtls_get_current_timeout(ssl);
|
||||
select_ret = dtls_select(sockfd, currTimeout);
|
||||
if ( ( select_ret == TEST_RECV_READY) ||
|
||||
(select_ret == TEST_ERROR_READY)) {
|
||||
ret = wolfSSL_connect(ssl);
|
||||
error = wolfSSL_get_error(ssl, 0);
|
||||
}
|
||||
else if (select_ret == TEST_TIMEOUT && !wolfSSL_dtls(ssl)) {
|
||||
error = 2;
|
||||
}
|
||||
else if (select_ret == TEST_TIMEOUT && wolfSSL_dtls(ssl) &&
|
||||
wolfSSL_dtls_got_timeout(ssl) >= 0) {
|
||||
error = 2;
|
||||
}
|
||||
else{
|
||||
error = SSL_FATAL_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret != SSL_SUCCESS) {
|
||||
printf("SSL_connect failed with");
|
||||
}
|
||||
}
|
||||
|
||||
/* Main send and receive function */
|
||||
void DatagramClient (WOLFSSL* ssl)
|
||||
{
|
||||
int n = 0;
|
||||
char sendLine[MAXLINE], recvLine[MAXLINE - 1];
|
||||
|
||||
while (fgets(sendLine, MAXLINE, stdin) != NULL) {
|
||||
|
||||
while ( ( wolfSSL_write(ssl, sendLine, strlen(sendLine))) !=
|
||||
strlen(sendLine)) {
|
||||
printf("SSL_write failed");
|
||||
}
|
||||
|
||||
while ( (n = wolfSSL_read(ssl, recvLine, sizeof(recvLine)-1)) <= 0) {
|
||||
|
||||
int readErr = wolfSSL_get_error(ssl, 0);
|
||||
if(readErr != SSL_ERROR_WANT_READ)
|
||||
printf("wolfSSL_read failed");
|
||||
}
|
||||
|
||||
recvLine[n] = '\0';
|
||||
fputs(recvLine, stdout);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int main (int argc, char** argv)
|
||||
{
|
||||
int sockfd = 0;
|
||||
struct sockaddr_in servAddr;
|
||||
const char* host = argv[1];
|
||||
WOLFSSL* ssl = 0;
|
||||
WOLFSSL_CTX* ctx = 0;
|
||||
WOLFSSL* sslResume = 0;
|
||||
WOLFSSL_SESSION* session = 0;
|
||||
char cert_array[] = "../certs/ca-cert.pem";
|
||||
char* certs = cert_array;
|
||||
char* srTest = "testing session resume";
|
||||
|
||||
if (argc != 2) {
|
||||
printf("usage: udpcli <IP address>\n");
|
||||
printf("usage: udpcli <IP address>\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -163,18 +79,18 @@ int main (int argc, char** argv)
|
|||
/* wolfSSL_Debugging_ON();*/
|
||||
|
||||
if ( (ctx = wolfSSL_CTX_new(wolfDTLSv1_2_client_method())) == NULL) {
|
||||
fprintf(stderr, "wolfSSL_CTX_new error.\n");
|
||||
return(EXIT_FAILURE);
|
||||
fprintf(stderr, "wolfSSL_CTX_new error.\n");
|
||||
return(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (wolfSSL_CTX_load_verify_locations(ctx,certs, 0) != SSL_SUCCESS) {
|
||||
fprintf(stderr, "Error loading %s, please check the file.\n", certs);
|
||||
return(EXIT_FAILURE);
|
||||
fprintf(stderr, "Error loading %s, please check the file.\n", certs);
|
||||
return(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
ssl = wolfSSL_new(ctx);
|
||||
if (ssl == NULL) {
|
||||
printf("unable to get ssl object");
|
||||
printf("unable to get ssl object");
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -188,67 +104,110 @@ int main (int argc, char** argv)
|
|||
|
||||
wolfSSL_dtls_set_peer(ssl, &servAddr, sizeof(servAddr));
|
||||
|
||||
if ( (sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
|
||||
printf("cannot create a socket.");
|
||||
if ( (sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
|
||||
printf("cannot create a socket.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
wolfSSL_set_fd(ssl, sockfd);
|
||||
wolfSSL_set_using_nonblock(ssl, 1);
|
||||
fcntl(sockfd, F_SETFL, O_NONBLOCK);
|
||||
NonBlockingDTLS_Connect(ssl);
|
||||
|
||||
DatagramClient(ssl);
|
||||
while ( (wolfSSL_write(ssl, srTest, sizeof(srTest))) != sizeof(srTest)) {
|
||||
printf("failed to write");
|
||||
return 1;
|
||||
/*****************************************************************************/
|
||||
/* Non-blocking code for DTLS connect */
|
||||
|
||||
while (ret != SSL_SUCCESS && (error == SSL_ERROR_WANT_READ ||
|
||||
error == SSL_ERROR_WANT_WRITE)) {
|
||||
|
||||
/* Variables that will reset upon every iteration */
|
||||
currTimeout = wolfSSL_dtls_get_current_timeout(ssl);
|
||||
nfds = nb_sockfd + 1;
|
||||
timeout = (struct timeval) { (currTimeout > 0) ? currTimeout : 0, 0};
|
||||
|
||||
if (error == SSL_ERROR_WANT_READ) {
|
||||
printf("... client would read block\n");
|
||||
}
|
||||
else {
|
||||
printf("... client would write block\n");
|
||||
}
|
||||
|
||||
/* Tcp select using dtls nonblocking functionality */
|
||||
FD_ZERO(&recvfds);
|
||||
FD_SET(nb_sockfd, &recvfds);
|
||||
FD_ZERO(&errfds);
|
||||
FD_SET(nb_sockfd, &errfds);
|
||||
|
||||
result = select(nfds, &recvfds, NULL, &errfds, &timeout);
|
||||
|
||||
select_ret = TEST_SELECT_FAIL;
|
||||
|
||||
if (result == 0) {
|
||||
select_ret = TEST_TIMEOUT;
|
||||
}
|
||||
else if (result > 0) {
|
||||
if (FD_ISSET(nb_sockfd, &recvfds)) {
|
||||
select_ret = TEST_RECV_READY;
|
||||
}
|
||||
else if (FD_ISSET(nb_sockfd, &errfds)) {
|
||||
select_ret = TEST_ERROR_READY;
|
||||
}
|
||||
}
|
||||
/* End "Tcp select ..." code */
|
||||
|
||||
if ( select_ret == TEST_RECV_READY ||
|
||||
select_ret == TEST_ERROR_READY ) {
|
||||
ret = wolfSSL_connect(ssl);
|
||||
error = wolfSSL_get_error(ssl, 0);
|
||||
}
|
||||
else if (select_ret == TEST_TIMEOUT && !wolfSSL_dtls(ssl)) {
|
||||
error = 2;
|
||||
}
|
||||
else if (select_ret == TEST_TIMEOUT && wolfSSL_dtls(ssl) &&
|
||||
wolfSSL_dtls_got_timeout(ssl) >= 0) {
|
||||
error = 2;
|
||||
}
|
||||
else {
|
||||
error = SSL_FATAL_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
session = wolfSSL_get_session(ssl);
|
||||
sslResume = wolfSSL_new(ctx);
|
||||
if (ret != SSL_SUCCESS) {
|
||||
printf("SSL_connect failed with");
|
||||
}
|
||||
/* */
|
||||
/*****************************************************************************/
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code for sending datagram to server */
|
||||
|
||||
int n = 0;
|
||||
char sendLine[MAXLINE], recvLine[MAXLINE - 1];
|
||||
|
||||
while (fgets(sendLine, MAXLINE, stdin) != NULL) {
|
||||
|
||||
while ( ( wolfSSL_write(ssl, sendLine, strlen(sendLine))) !=
|
||||
strlen(sendLine)) {
|
||||
printf("SSL_write failed");
|
||||
}
|
||||
|
||||
while ( (n = wolfSSL_read(ssl, recvLine, sizeof(recvLine)-1)) <= 0) {
|
||||
int readErr = wolfSSL_get_error(ssl, 0);
|
||||
if(readErr != SSL_ERROR_WANT_READ) {
|
||||
printf("wolfSSL_read failed");
|
||||
}
|
||||
}
|
||||
|
||||
recvLine[n] = '\0';
|
||||
fputs(recvLine, stdout);
|
||||
}
|
||||
/* */
|
||||
/*****************************************************************************/
|
||||
|
||||
wolfSSL_shutdown(ssl);
|
||||
wolfSSL_free(ssl);
|
||||
|
||||
close(sockfd);
|
||||
|
||||
memset(&servAddr, 0, sizeof(servAddr));
|
||||
servAddr.sin_family = AF_INET;
|
||||
servAddr.sin_port = htons(SERV_PORT);
|
||||
if (inet_pton(AF_INET, host, &servAddr.sin_addr) < 1) {
|
||||
printf("Error and/or invalid IP address");
|
||||
return 1;
|
||||
}
|
||||
|
||||
wolfSSL_dtls_set_peer(sslResume, &servAddr, sizeof(servAddr));
|
||||
|
||||
if ( (sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
|
||||
printf("cannot create a socket.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
wolfSSL_set_fd(sslResume, sockfd);
|
||||
wolfSSL_set_session(sslResume, session);
|
||||
wolfSSL_set_using_nonblock(sslResume, 1);
|
||||
fcntl(sockfd, F_SETFL, O_NONBLOCK);
|
||||
NonBlockingDTLS_Connect(sslResume);
|
||||
|
||||
if(wolfSSL_session_reused(sslResume))
|
||||
printf("reused session id\n");
|
||||
else
|
||||
printf("didn't reuse session id!!!\n");
|
||||
|
||||
DatagramClient(sslResume);
|
||||
while ((wolfSSL_write(sslResume, srTest, sizeof(srTest))) != sizeof(srTest))
|
||||
{
|
||||
printf("failed to write");
|
||||
return 1;
|
||||
}
|
||||
sleep(1);
|
||||
|
||||
wolfSSL_shutdown(sslResume);
|
||||
wolfSSL_free(sslResume);
|
||||
|
||||
close(sockfd);
|
||||
wolfSSL_CTX_free(ctx);
|
||||
wolfSSL_Cleanup();
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* client-dtls-resume.c
|
||||
/*
|
||||
* client-dtls-resume.c
|
||||
*
|
||||
* Copyright (C) 2006-2015 wolfSSL Inc.
|
||||
*
|
||||
|
@ -24,9 +24,9 @@
|
|||
* Bare-bones example of a DTLS client for instructional/learning purposes.
|
||||
*/
|
||||
|
||||
#include <wolfssl/options.h>
|
||||
#include <unistd.h>
|
||||
#include <wolfssl/ssl.h>
|
||||
#include <wolfssl/options.h>
|
||||
#include <netdb.h>
|
||||
#include <signal.h>
|
||||
#include <sys/socket.h>
|
||||
|
@ -37,54 +37,39 @@
|
|||
#include <string.h>
|
||||
|
||||
#define MAXLINE 4096
|
||||
#define SERV_PORT 11111
|
||||
#define SERV_PORT 11111
|
||||
|
||||
/* Send and receive function */
|
||||
void DatagramClient (WOLFSSL* ssl)
|
||||
int main (int argc, char** argv)
|
||||
{
|
||||
int n = 0;
|
||||
char sendLine[MAXLINE], recvLine[MAXLINE - 1];
|
||||
/* standard variables used in a dtls client*/
|
||||
int sockfd = 0;
|
||||
int err1;
|
||||
int readErr;
|
||||
struct sockaddr_in servAddr;
|
||||
const char* host = argv[1];
|
||||
WOLFSSL* ssl = 0;
|
||||
WOLFSSL_CTX* ctx = 0;
|
||||
WOLFSSL* sslResume = 0;
|
||||
WOLFSSL_SESSION* session = 0;
|
||||
char* srTest = "testing session resume";
|
||||
char cert_array[] = "../certs/ca-cert.pem";
|
||||
char buffer[80];
|
||||
char* certs = cert_array;
|
||||
/* variables used in a dtls client for session reuse*/
|
||||
int recvlen;
|
||||
char sendLine[MAXLINE];
|
||||
char recvLine[MAXLINE - 1];
|
||||
|
||||
while (fgets(sendLine, MAXLINE, stdin) != NULL) {
|
||||
|
||||
if ( ( wolfSSL_write(ssl, sendLine, strlen(sendLine))) !=
|
||||
strlen(sendLine)) {
|
||||
printf("SSL_write failed");
|
||||
}
|
||||
|
||||
n = wolfSSL_read(ssl, recvLine, sizeof(recvLine)-1);
|
||||
|
||||
if (n < 0) {
|
||||
int readErr = wolfSSL_get_error(ssl, 0);
|
||||
if(readErr != SSL_ERROR_WANT_READ)
|
||||
printf("wolfSSL_read failed");
|
||||
}
|
||||
|
||||
recvLine[n] = '\0';
|
||||
fputs(recvLine, stdout);
|
||||
}
|
||||
}
|
||||
|
||||
int main (int argc, char** argv)
|
||||
{
|
||||
int sockfd = 0;
|
||||
struct sockaddr_in servAddr;
|
||||
const char* host = argv[1];
|
||||
WOLFSSL* ssl = 0;
|
||||
WOLFSSL_CTX* ctx = 0;
|
||||
WOLFSSL* sslResume = 0;
|
||||
WOLFSSL_SESSION* session = 0;
|
||||
char* srTest = "testing session resume";
|
||||
char cert_array[] = "../certs/ca-cert.pem";
|
||||
char* certs = cert_array;
|
||||
if (argc != 2) {
|
||||
if (argc != 2) {
|
||||
printf("usage: udpcli <IP address>\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
wolfSSL_Init();
|
||||
|
||||
/* Un-comment the following line to enable debugging */
|
||||
/* wolfSSL_Debugging_ON(); */
|
||||
|
||||
|
||||
if ( (ctx = wolfSSL_CTX_new(wolfDTLSv1_2_client_method())) == NULL) {
|
||||
fprintf(stderr, "wolfSSL_CTX_new error.\n");
|
||||
return 1;
|
||||
|
@ -100,7 +85,7 @@ int main (int argc, char** argv)
|
|||
printf("unable to get ssl object");
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
memset(&servAddr, 0, sizeof(servAddr));
|
||||
servAddr.sin_family = AF_INET;
|
||||
servAddr.sin_port = htons(SERV_PORT);
|
||||
|
@ -110,30 +95,61 @@ int main (int argc, char** argv)
|
|||
}
|
||||
|
||||
wolfSSL_dtls_set_peer(ssl, &servAddr, sizeof(servAddr));
|
||||
|
||||
if ( (sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
|
||||
printf("cannot create a socket.");
|
||||
|
||||
if ( (sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
|
||||
printf("cannot create a socket.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
wolfSSL_set_fd(ssl, sockfd);
|
||||
if (wolfSSL_connect(ssl) != SSL_SUCCESS) {
|
||||
int err1 = wolfSSL_get_error(ssl, 0);
|
||||
char buffer[80];
|
||||
printf("err = %d, %s\n", err1, wolfSSL_ERR_error_string(err1, buffer));
|
||||
printf("SSL_connect failed");
|
||||
err1 = wolfSSL_get_error(ssl, 0);
|
||||
memset(buffer, 0, 80);
|
||||
printf("err = %d, %s\n", err1, wolfSSL_ERR_error_string(err1, buffer));
|
||||
printf("SSL_connect failed");
|
||||
return 1;
|
||||
}
|
||||
|
||||
DatagramClient(ssl);
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code for sending datagram to server */
|
||||
|
||||
/* Loop while the user gives input or until an EOF is read */
|
||||
while( fgets(sendLine, MAXLINE, stdin) != NULL ) {
|
||||
|
||||
/* Attempt to send sendLine to the server */
|
||||
if ( ( wolfSSL_write(ssl, sendLine, strlen(sendLine))) !=
|
||||
strlen(sendLine) ) {
|
||||
printf("Error: wolfSSL_write failed.\n");
|
||||
}
|
||||
|
||||
/* Attempt to read a message from server and store it in recvLine */
|
||||
recvlen = wolfSSL_read(ssl, recvLine, sizeof(recvLine) - 1);
|
||||
|
||||
/* Error checking wolfSSL_read */
|
||||
if (recvlen < 0) {
|
||||
readErr = wolfSSL_get_error(ssl, 0);
|
||||
if (readErr != SSL_ERROR_WANT_READ) {
|
||||
printf("Error: wolfSSL_read failed.\n");
|
||||
}
|
||||
}
|
||||
|
||||
recvLine[recvlen] = '\0';
|
||||
fputs(recvLine, stdout);
|
||||
}
|
||||
/* */
|
||||
/*****************************************************************************/
|
||||
|
||||
/* Keep track of the old session information */
|
||||
wolfSSL_write(ssl, srTest, sizeof(srTest));
|
||||
session = wolfSSL_get_session(ssl);
|
||||
sslResume = wolfSSL_new(ctx);
|
||||
|
||||
/* Cleanup the memory used by the old session & ssl object */
|
||||
wolfSSL_shutdown(ssl);
|
||||
wolfSSL_free(ssl);
|
||||
close(sockfd);
|
||||
|
||||
/* Perform setup with new variables/old session information */
|
||||
memset(&servAddr, 0, sizeof(servAddr));
|
||||
servAddr.sin_family = AF_INET;
|
||||
servAddr.sin_port = htons(SERV_PORT);
|
||||
|
@ -143,36 +159,76 @@ int main (int argc, char** argv)
|
|||
}
|
||||
|
||||
wolfSSL_dtls_set_peer(sslResume, &servAddr, sizeof(servAddr));
|
||||
|
||||
if ( (sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
|
||||
printf("cannot create a socket.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
wolfSSL_set_fd(sslResume, sockfd);
|
||||
wolfSSL_set_session(sslResume, session);
|
||||
|
||||
if (wolfSSL_connect(sslResume) != SSL_SUCCESS) {
|
||||
printf("SSL_connect failed");
|
||||
if ( (sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
|
||||
printf("cannot create a socket.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(wolfSSL_session_reused(sslResume))
|
||||
wolfSSL_set_fd(sslResume, sockfd);
|
||||
|
||||
/* New method call - specifies to the WOLFSSL object to use the *
|
||||
* given WOLFSSL_SESSION object */
|
||||
wolfSSL_set_session(sslResume, session);
|
||||
|
||||
wolfSSL_set_fd(sslResume, sockfd);
|
||||
if (wolfSSL_connect(sslResume) != SSL_SUCCESS) {
|
||||
err1 = wolfSSL_get_error(sslResume, 0);
|
||||
memset(buffer, 0, 80);
|
||||
printf("err = %d, %s\n", err1, wolfSSL_ERR_error_string(err1, buffer));
|
||||
printf("SSL_connect failed on session reuse\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (wolfSSL_session_reused(sslResume)) {
|
||||
printf("reused session id\n");
|
||||
else
|
||||
}
|
||||
else {
|
||||
printf("didn't reuse session id!!!\n");
|
||||
|
||||
DatagramClient(sslResume);
|
||||
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code for sending datagram to server */
|
||||
/* Clear out variables for reuse */
|
||||
recvlen = 0;
|
||||
memset(sendLine, 0, MAXLINE);
|
||||
memset(recvLine, 0, MAXLINE - 1);
|
||||
|
||||
/* Loop while the user gives input or until an EOF is read */
|
||||
while( fgets(sendLine, MAXLINE, stdin) != NULL ) {
|
||||
|
||||
/* Attempt to send sendLine to the server */
|
||||
if ( ( wolfSSL_write(ssl, sendLine, strlen(sendLine))) !=
|
||||
strlen(sendLine) ) {
|
||||
printf("Error: wolfSSL_write failed.\n");
|
||||
}
|
||||
|
||||
/* Attempt to read a message from server and store it in recvLine */
|
||||
recvlen = wolfSSL_read(ssl, recvLine, sizeof(recvLine) - 1);
|
||||
|
||||
/* Error checking wolfSSL_read */
|
||||
if (recvlen < 0) {
|
||||
readErr = wolfSSL_get_error(ssl, 0);
|
||||
if (readErr != SSL_ERROR_WANT_READ) {
|
||||
printf("Error: wolfSSL_read failed.\n");
|
||||
}
|
||||
}
|
||||
|
||||
recvLine[recvlen] = '\0';
|
||||
fputs(recvLine, stdout);
|
||||
}
|
||||
/* */
|
||||
/*****************************************************************************/
|
||||
|
||||
wolfSSL_write(sslResume, srTest, sizeof(srTest));
|
||||
|
||||
/* Cleanup memory used for storing the session information */
|
||||
wolfSSL_shutdown(sslResume);
|
||||
wolfSSL_free(sslResume);
|
||||
|
||||
|
||||
close(sockfd);
|
||||
wolfSSL_CTX_free(ctx);
|
||||
wolfSSL_Cleanup();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -46,7 +46,6 @@
|
|||
#define THREADS 3
|
||||
#define SERV_PORT 11111
|
||||
|
||||
|
||||
typedef struct SharedDtls {
|
||||
wolfSSL_Mutex shared_mutex; /* mutex for using */
|
||||
WOLFSSL* ssl; /* WOLFSSL object being shared */
|
||||
|
@ -58,6 +57,10 @@ typedef struct SharedDtls {
|
|||
int handShakeDone; /* is the handshake done? */
|
||||
} SharedDtls;
|
||||
|
||||
static int min (int a, int b)
|
||||
{
|
||||
return a > b ? b : a;
|
||||
}
|
||||
|
||||
int dtls_sendto_cb(WOLFSSL* ssl, char* buf, int sz, void* ctx)
|
||||
{
|
||||
|
@ -67,24 +70,18 @@ int dtls_sendto_cb(WOLFSSL* ssl, char* buf, int sz, void* ctx)
|
|||
(const struct sockaddr*)&shared->servAddr, shared->servSz);
|
||||
}
|
||||
|
||||
|
||||
static int min(int a, int b)
|
||||
{
|
||||
return a > b ? b : a;
|
||||
}
|
||||
|
||||
|
||||
int dtls_recvfrom_cb(WOLFSSL* ssl, char* buf, int sz, void* ctx)
|
||||
{
|
||||
SharedDtls* shared = (SharedDtls*)ctx;
|
||||
int copied;
|
||||
|
||||
if (!shared->handShakeDone) {
|
||||
/* get directly from socket */
|
||||
return recvfrom(shared->sd, buf, sz, 0, NULL, NULL);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
/* get the "pushed" datagram from our cb buffer instead */
|
||||
int copied = min(sz, shared->recvSz);
|
||||
|
||||
copied = min(sz, shared->recvSz);
|
||||
memcpy(buf, shared->recvBuf, copied);
|
||||
shared->recvSz -= copied;
|
||||
|
||||
|
@ -92,34 +89,21 @@ int dtls_recvfrom_cb(WOLFSSL* ssl, char* buf, int sz, void* ctx)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/* each thread should have a simple id at startup */
|
||||
char get_id(SharedDtls* shared)
|
||||
{
|
||||
char ids[] = "abcdefgh";
|
||||
char ret;
|
||||
static int index = 0;
|
||||
|
||||
wc_LockMutex(&shared->shared_mutex);
|
||||
|
||||
ret = ids[index++];
|
||||
|
||||
wc_UnLockMutex(&shared->shared_mutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* DTLS Send function in its own thread */
|
||||
void* DatagramSend(void* arg)
|
||||
{
|
||||
int i;
|
||||
int sendSz;
|
||||
char sendBuf[MAXBUF];
|
||||
int i;
|
||||
int sendSz;
|
||||
char sendBuf[MAXBUF];
|
||||
SharedDtls* shared = (SharedDtls*)arg;
|
||||
char id = get_id(shared);
|
||||
WOLFSSL* ssl = shared->ssl;
|
||||
char id; /* each thread should have a simple ID at startup */
|
||||
char ids[] = "abcdefgh";
|
||||
static int index = 0;
|
||||
|
||||
wc_LockMutex(&shared->shared_mutex);
|
||||
id = ids[index++];
|
||||
wc_UnLockMutex(&shared->shared_mutex);
|
||||
|
||||
for (i= 0; i < MAXMSGS; i++) {
|
||||
|
||||
|
@ -139,46 +123,19 @@ void* DatagramSend(void* arg)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/* DTLS Recv function */
|
||||
void DatagramRecv(WOLFSSL* ssl, SharedDtls* shared)
|
||||
{
|
||||
int i;
|
||||
int sz = 0;
|
||||
char recvBuf[MAXBUF];
|
||||
char plainBuf[MAXBUF];
|
||||
|
||||
for (i = 0; i < THREADS*MAXMSGS; i++) {
|
||||
/* first get datagram, works in blocking mode too */
|
||||
sz = recvfrom(shared->sd, recvBuf, MAXBUF, 0, NULL, NULL);
|
||||
|
||||
wc_LockMutex(&shared->shared_mutex);
|
||||
|
||||
/* push datagram to our cb, no copy needed! */
|
||||
shared->recvBuf = recvBuf;
|
||||
shared->recvSz = sz;
|
||||
|
||||
/* get plaintext */
|
||||
if ( (sz = (wolfSSL_read(ssl, plainBuf, MAXBUF-1))) < 0) {
|
||||
printf("wolfSSL_write failed");
|
||||
}
|
||||
|
||||
wc_UnLockMutex(&shared->shared_mutex);
|
||||
|
||||
plainBuf[MAXBUF-1] = '\0';
|
||||
printf("got msg %s\n", plainBuf);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int main (int argc, char** argv)
|
||||
{
|
||||
int sockfd = 0, i;
|
||||
WOLFSSL* ssl = 0;
|
||||
int sockfd = 0, i;
|
||||
WOLFSSL* ssl = 0;
|
||||
WOLFSSL_CTX* ctx = 0;
|
||||
char* ca = "../certs/ca-cert.pem";
|
||||
char* ecc_ca = "../certs/server-ecc.pem";
|
||||
SharedDtls shared;
|
||||
char* ca = "../certs/ca-cert.pem";
|
||||
char* ecc_ca = "../certs/server-ecc.pem";
|
||||
SharedDtls shared;
|
||||
SharedDtls* recvShared = &shared; /* DTLS Recv var */
|
||||
int sz = 0; /* DTLS Recv var */
|
||||
char recvBuf[MAXBUF]; /* DTLS Recv var */
|
||||
char plainBuf[MAXBUF]; /* DTLS Recv var */
|
||||
int err1;
|
||||
|
||||
if (argc != 2) {
|
||||
printf("usage: udpcli <IP address>\n");
|
||||
|
@ -237,7 +194,7 @@ int main (int argc, char** argv)
|
|||
wolfSSL_SetIOReadCtx(ssl, &shared);
|
||||
|
||||
if (wolfSSL_connect(ssl) != SSL_SUCCESS) {
|
||||
int err1 = wolfSSL_get_error(ssl, 0);
|
||||
err1 = wolfSSL_get_error(ssl, 0);
|
||||
printf("err = %d, %s\n", err1, wolfSSL_ERR_reason_error_string(err1));
|
||||
printf("SSL_connect failed");
|
||||
return 1;
|
||||
|
@ -250,7 +207,27 @@ int main (int argc, char** argv)
|
|||
pthread_create(&tid[i], NULL, DatagramSend, &shared);
|
||||
}
|
||||
|
||||
DatagramRecv(ssl, &shared);
|
||||
/* DTLS Recv */
|
||||
for (i = 0; i < THREADS*MAXMSGS; i++) {
|
||||
/* first get datagram, works in blocking mode too */
|
||||
sz = recvfrom(recvShared->sd, recvBuf, MAXBUF, 0, NULL, NULL);
|
||||
|
||||
wc_LockMutex(&recvShared->shared_mutex);
|
||||
|
||||
/* push datagram to our cb, no copy needed! */
|
||||
recvShared->recvBuf = recvBuf;
|
||||
recvShared->recvSz = sz;
|
||||
|
||||
/* get plaintext */
|
||||
if ( (sz = (wolfSSL_read(ssl, plainBuf, MAXBUF-1))) < 0) {
|
||||
printf("wolfSSL_write failed");
|
||||
}
|
||||
|
||||
wc_UnLockMutex(&recvShared->shared_mutex);
|
||||
|
||||
plainBuf[MAXBUF-1] = '\0';
|
||||
printf("got msg %s\n", plainBuf);
|
||||
}
|
||||
|
||||
for (i = 0; i < THREADS; i++) {
|
||||
pthread_join(tid[i], NULL);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* client-dtls.c
|
||||
/*
|
||||
* client-dtls.c
|
||||
*
|
||||
* Copyright (C) 2006-2015 wolfSSL Inc.
|
||||
*
|
||||
|
@ -24,9 +24,9 @@
|
|||
* Bare-bones example of a DTLS client for instructional/learning purposes.
|
||||
*/
|
||||
|
||||
#include <wolfssl/options.h>
|
||||
#include <unistd.h>
|
||||
#include <wolfssl/ssl.h>
|
||||
#include <wolfssl/options.h>
|
||||
#include <netdb.h>
|
||||
#include <signal.h>
|
||||
#include <sys/socket.h>
|
||||
|
@ -37,69 +37,54 @@
|
|||
#include <string.h>
|
||||
|
||||
#define MAXLINE 4096
|
||||
#define SERV_PORT 11111
|
||||
#define SERV_PORT 11111
|
||||
|
||||
/* Send and receive function */
|
||||
void DatagramClient (WOLFSSL* ssl)
|
||||
int main (int argc, char** argv)
|
||||
{
|
||||
int n = 0;
|
||||
char sendLine[MAXLINE], recvLine[MAXLINE - 1];
|
||||
/* standard variables used in a dtls client*/
|
||||
int n = 0;
|
||||
int sockfd = 0;
|
||||
int err1;
|
||||
int readErr;
|
||||
struct sockaddr_in servAddr;
|
||||
WOLFSSL* ssl = 0;
|
||||
WOLFSSL_CTX* ctx = 0;
|
||||
char cert_array[] = "../certs/ca-cert.pem";
|
||||
char* certs = cert_array;
|
||||
char sendLine[MAXLINE];
|
||||
char recvLine[MAXLINE - 1];
|
||||
|
||||
while (fgets(sendLine, MAXLINE, stdin) != NULL) {
|
||||
|
||||
if ( ( wolfSSL_write(ssl, sendLine, strlen(sendLine))) !=
|
||||
strlen(sendLine)) {
|
||||
printf("SSL_write failed");
|
||||
}
|
||||
|
||||
n = wolfSSL_read(ssl, recvLine, sizeof(recvLine)-1);
|
||||
|
||||
if (n < 0) {
|
||||
int readErr = wolfSSL_get_error(ssl, 0);
|
||||
if(readErr != SSL_ERROR_WANT_READ) {
|
||||
printf("wolfSSL_read failed");
|
||||
}
|
||||
}
|
||||
|
||||
recvLine[n] = '\0';
|
||||
fputs(recvLine, stdout);
|
||||
}
|
||||
}
|
||||
|
||||
int main (int argc, char** argv)
|
||||
{
|
||||
int sockfd = 0;
|
||||
struct sockaddr_in servAddr;
|
||||
WOLFSSL* ssl = 0;
|
||||
WOLFSSL_CTX* ctx = 0;
|
||||
char cert_array[] = "../certs/ca-cert.pem";
|
||||
char* certs = cert_array;
|
||||
|
||||
if (argc != 2) {
|
||||
/* Program argument checking */
|
||||
if (argc != 2) {
|
||||
printf("usage: udpcli <IP address>\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Initialize wolfSSL before assigning ctx */
|
||||
wolfSSL_Init();
|
||||
|
||||
/* wolfSSL_Debugging_ON(); */
|
||||
|
||||
|
||||
if ( (ctx = wolfSSL_CTX_new(wolfDTLSv1_2_client_method())) == NULL) {
|
||||
fprintf(stderr, "wolfSSL_CTX_new error.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (wolfSSL_CTX_load_verify_locations(ctx, certs, 0)
|
||||
/* Load certificates into ctx variable */
|
||||
if (wolfSSL_CTX_load_verify_locations(ctx, certs, 0)
|
||||
!= SSL_SUCCESS) {
|
||||
fprintf(stderr, "Error loading %s, please check the file.\n", certs);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Assign ssl variable */
|
||||
ssl = wolfSSL_new(ctx);
|
||||
if (ssl == NULL) {
|
||||
printf("unable to get ssl object");
|
||||
printf("unable to get ssl object");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* servAddr setup */
|
||||
memset(&servAddr, 0, sizeof(servAddr));
|
||||
servAddr.sin_family = AF_INET;
|
||||
servAddr.sin_port = htons(SERV_PORT);
|
||||
|
@ -109,21 +94,50 @@ int main (int argc, char** argv)
|
|||
}
|
||||
|
||||
wolfSSL_dtls_set_peer(ssl, &servAddr, sizeof(servAddr));
|
||||
|
||||
if ( (sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
|
||||
printf("cannot create a socket.");
|
||||
|
||||
if ( (sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
|
||||
printf("cannot create a socket.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Set the file descriptor for ssl and connect with ssl variable */
|
||||
wolfSSL_set_fd(ssl, sockfd);
|
||||
if (wolfSSL_connect(ssl) != SSL_SUCCESS) {
|
||||
int err1 = wolfSSL_get_error(ssl, 0);
|
||||
err1 = wolfSSL_get_error(ssl, 0);
|
||||
printf("err = %d, %s\n", err1, wolfSSL_ERR_reason_error_string(err1));
|
||||
printf("SSL_connect failed");
|
||||
return 1;
|
||||
}
|
||||
|
||||
DatagramClient(ssl);
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code for sending datagram to server */
|
||||
/* Loop until the user is finished */
|
||||
while (fgets(sendLine, MAXLINE, stdin) != NULL) {
|
||||
|
||||
/* Send sendLine to the server */
|
||||
if ( ( wolfSSL_write(ssl, sendLine, strlen(sendLine)))
|
||||
!= strlen(sendLine)) {
|
||||
printf("SSL_write failed");
|
||||
}
|
||||
|
||||
/* n is the # of bytes received */
|
||||
n = wolfSSL_read(ssl, recvLine, sizeof(recvLine)-1);
|
||||
|
||||
if (n < 0) {
|
||||
readErr = wolfSSL_get_error(ssl, 0);
|
||||
if (readErr != SSL_ERROR_WANT_READ) {
|
||||
printf("wolfSSL_read failed");
|
||||
}
|
||||
}
|
||||
|
||||
/* Add a terminating character to the generic server message */
|
||||
recvLine[n] = '\0';
|
||||
fputs(recvLine, stdout);
|
||||
}
|
||||
/* End code for sending datagram to server */
|
||||
/*****************************************************************************/
|
||||
|
||||
/* Housekeeping */
|
||||
wolfSSL_shutdown(ssl);
|
||||
wolfSSL_free(ssl);
|
||||
close(sockfd);
|
||||
|
@ -132,4 +146,3 @@ int main (int argc, char** argv)
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* client-udp.c
|
||||
/*
|
||||
* client-udp.c
|
||||
*
|
||||
* Copyright (C) 2006-2015 wolfSSL Inc.
|
||||
*
|
||||
|
@ -24,6 +24,7 @@
|
|||
* Bare-bones example of a UDP client for instructional/learning purposes.
|
||||
*/
|
||||
|
||||
#include <wolfssl/options.h>
|
||||
#include <sys/socket.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/in.h>
|
||||
|
@ -34,37 +35,17 @@
|
|||
#define MAXLINE 4096
|
||||
#define SERV_PORT 11111
|
||||
|
||||
/* send and recieve message function */
|
||||
void DatagramClient (FILE* clientInput, int sockfd,
|
||||
const struct sockaddr* servAddr, socklen_t servLen)
|
||||
{
|
||||
|
||||
int n;
|
||||
char sendLine[MAXLINE], recvLine[MAXLINE +1];
|
||||
|
||||
while (fgets(sendLine, MAXLINE, clientInput) != NULL) {
|
||||
|
||||
if ( ( sendto(sockfd, sendLine, strlen(sendLine) - 1, 0, servAddr,
|
||||
servLen)) == -1) {
|
||||
printf("error in sending");
|
||||
}
|
||||
|
||||
|
||||
if ( (n = recvfrom(sockfd, recvLine, MAXLINE, 0, NULL, NULL)) == -1) {
|
||||
printf("Error in receiving");
|
||||
}
|
||||
|
||||
recvLine[n] = 0;
|
||||
fputs(recvLine, stdout);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
/* standard variables used in a udp client */
|
||||
int sockfd;
|
||||
int recvlen;
|
||||
struct sockaddr_in servAddr;
|
||||
const struct sockaddr* servAddr_in;
|
||||
socklen_t servLen;
|
||||
char sendLine[MAXLINE];
|
||||
char recvLine[MAXLINE + 1];
|
||||
|
||||
int sockfd;
|
||||
struct sockaddr_in servAddr;
|
||||
|
||||
if (argc != 2) {
|
||||
printf("usage: udpcli <IP address>\n");
|
||||
return 1;
|
||||
|
@ -73,16 +54,39 @@ int main(int argc, char** argv)
|
|||
if ( (sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
|
||||
printf("cannot create a socket.");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
memset(&servAddr, 0, sizeof(servAddr));
|
||||
|
||||
memset(&servAddr, sizeof(servAddr), 0);
|
||||
servAddr.sin_family = AF_INET;
|
||||
servAddr.sin_port = htons(SERV_PORT);
|
||||
inet_pton(AF_INET, argv[1], &servAddr.sin_addr);
|
||||
|
||||
DatagramClient(stdin, sockfd, (struct sockaddr*) &servAddr,
|
||||
sizeof(servAddr));
|
||||
/****************************************************************************/
|
||||
/* Code for sending the datagram to the server */
|
||||
servAddr_in = &servAddr;
|
||||
servLen = sizeof(servAddr);
|
||||
|
||||
/* Loop while user is giving input or until EOF is read */
|
||||
while (fgets(sendLine, MAXLINE, stdin) != NULL) {
|
||||
|
||||
/* Attempt to send sendLine to the server */
|
||||
if ( ( sendto(sockfd, sendLine, strlen(sendLine) - 1, 0, servAddr_in,
|
||||
servLen)) == -1) {
|
||||
printf("Error in sending.\n");
|
||||
}
|
||||
|
||||
/* Attempt to receive recvLine from the server */
|
||||
if ( (recvlen = recvfrom(sockfd, recvLine, MAXLINE, 0, NULL, NULL))
|
||||
== -1) {
|
||||
printf("Error in receiving.\n");
|
||||
}
|
||||
|
||||
recvLine[recvlen] = '\0';
|
||||
fputs(recvLine, stdout);
|
||||
}
|
||||
/* */
|
||||
/****************************************************************************/
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* server-dtls-nonblocking.c
|
||||
/* server-dtls-nonblocking.c
|
||||
*
|
||||
* Copyright (C) 2006-2015 wolfSSL Inc.
|
||||
*
|
||||
|
@ -20,10 +20,11 @@
|
|||
*
|
||||
*=============================================================================
|
||||
*
|
||||
* Bare-bones example of a nonblocking DTLS erver for instructional/learning purposes.
|
||||
* Utilizes DTLS 1.2.
|
||||
* Bare-bones example of a nonblocking DTLS server for instructional/learning
|
||||
* purposes. Utilizes DTLS 1.2.
|
||||
*/
|
||||
|
||||
#include <wolfssl/options.h>
|
||||
#include <stdio.h> /* standard in/out procedures */
|
||||
#include <stdlib.h> /* defines system calls */
|
||||
#include <string.h> /* necessary for memset */
|
||||
|
@ -42,11 +43,7 @@
|
|||
|
||||
static int cleanup; /* To handle shutdown */
|
||||
|
||||
void dtls_set_nonblocking(int*); /* set the socket non-blocking */
|
||||
int NonBlockingSSL_Accept(WOLFSSL*); /* non-blocking accept */
|
||||
int AwaitDGram(WOLFSSL_CTX* ctx); /* Separate out Handling Datagrams */
|
||||
int udp_read_connect(int); /* broken out to improve readability */
|
||||
int dtls_select();
|
||||
void sig_handler(const int sig);
|
||||
|
||||
/* costumes for select_ret to wear */
|
||||
enum {
|
||||
|
@ -56,263 +53,57 @@ enum {
|
|||
TEST_ERROR_READY
|
||||
};
|
||||
|
||||
int AwaitDGram(WOLFSSL_CTX* ctx)
|
||||
/* For handling ^C interrupts passed by the user */
|
||||
void sig_handler(const int sig)
|
||||
{
|
||||
int on = 1;
|
||||
int res = 1;
|
||||
int recvLen; /* length of string read */
|
||||
int readWriteErr;
|
||||
int listenfd = 0; /* Initialize our socket */
|
||||
int clientfd = 0; /* client connection */
|
||||
int len = sizeof(on);
|
||||
int cont;
|
||||
char buff[MSGLEN]; /* string read from client */
|
||||
WOLFSSL* ssl = NULL; /* Initialize ssl object */
|
||||
struct sockaddr_in servAddr; /* our server's address */
|
||||
char ack[] = "I hear you fashizzle\n";
|
||||
|
||||
while (cleanup != 1) {
|
||||
|
||||
/* Create a UDP/IP socket */
|
||||
if ((listenfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0 ) {
|
||||
printf("Cannot create socket.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("Socket allocated\n");
|
||||
|
||||
dtls_set_nonblocking(&listenfd);
|
||||
|
||||
memset((char *)&servAddr, 0, sizeof(servAddr));
|
||||
|
||||
/* host-to-network-long conversion (htonl) */
|
||||
/* host-to-network-short conversion (htons) */
|
||||
servAddr.sin_family = AF_INET;
|
||||
servAddr.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
servAddr.sin_port = htons(SERV_PORT);
|
||||
|
||||
/* Eliminate socket already in use error */
|
||||
res = setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, len);
|
||||
if (res < 0) {
|
||||
printf("Setsockopt SO_REUSEADDR failed.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*Bind Socket*/
|
||||
if (bind(listenfd,
|
||||
(struct sockaddr *)&servAddr, sizeof(servAddr)) < 0) {
|
||||
printf("Bind failed.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("Awaiting client connection on port %d\n", SERV_PORT);
|
||||
|
||||
|
||||
clientfd = udp_read_connect(listenfd);
|
||||
|
||||
|
||||
// dtls_set_nonblocking(&clientfd);
|
||||
|
||||
/* Create the WOLFSSL Object */
|
||||
if (( ssl = wolfSSL_new(ctx)) == NULL) {
|
||||
printf("wolfSSL_new error.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* set clilen to |cliAddr| */
|
||||
printf("Connected!\n");
|
||||
|
||||
/* set the/ session ssl to client connection port */
|
||||
wolfSSL_set_fd(ssl, clientfd);
|
||||
|
||||
wolfSSL_set_using_nonblock(ssl, 1);
|
||||
cont = NonBlockingSSL_Accept(ssl);
|
||||
|
||||
if (cont != 0) {
|
||||
printf("NonBlockingSSL_Accept failed.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Begin: Reply to the client */
|
||||
recvLen = wolfSSL_read(ssl, buff, sizeof(buff)-1);
|
||||
|
||||
/* Begin do-while read */
|
||||
do {
|
||||
if (cleanup == 1) {
|
||||
memset(buff, 0, sizeof(buff));
|
||||
break;
|
||||
}
|
||||
if (recvLen < 0) {
|
||||
readWriteErr = wolfSSL_get_error(ssl, 0);
|
||||
if (readWriteErr != SSL_ERROR_WANT_READ) {
|
||||
printf("Read Error, error was: %d.\n", readWriteErr);
|
||||
cleanup = 1;
|
||||
} else {
|
||||
recvLen = wolfSSL_read(ssl, buff, sizeof(buff)-1);
|
||||
}
|
||||
}
|
||||
} while (readWriteErr == SSL_ERROR_WANT_READ &&
|
||||
recvLen < 0 &&
|
||||
cleanup != 1);
|
||||
/* End do-while read */
|
||||
|
||||
if (recvLen > 0) {
|
||||
buff[recvLen] = 0;
|
||||
printf("I heard this:\"%s\"\n", buff);
|
||||
}
|
||||
else {
|
||||
printf("Connection Timed Out.\n");
|
||||
}
|
||||
|
||||
/* Begin do-while write */
|
||||
do {
|
||||
if (cleanup == 1) {
|
||||
memset(&buff, 0, sizeof(buff));
|
||||
break;
|
||||
}
|
||||
readWriteErr = wolfSSL_get_error(ssl, 0);
|
||||
if (wolfSSL_write(ssl, ack, sizeof(ack)) < 0) {
|
||||
printf("Write error.\n");
|
||||
cleanup = 1;
|
||||
}
|
||||
printf("Reply sent:\"%s\"\n", ack);
|
||||
}while(readWriteErr == SSL_ERROR_WANT_WRITE && cleanup != 1);
|
||||
/* End do-while write */
|
||||
|
||||
/* free allocated memory */
|
||||
memset(buff, 0, sizeof(buff));
|
||||
wolfSSL_free(ssl);
|
||||
|
||||
/* End: Reply to the Client */
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int udp_read_connect(int listenfd)
|
||||
{
|
||||
int bytesRecvd;
|
||||
unsigned char b[MSGLEN];
|
||||
struct sockaddr_in cliAddr;
|
||||
socklen_t clilen = sizeof(cliAddr);
|
||||
|
||||
do {
|
||||
bytesRecvd = (int)recvfrom(listenfd, (char*)b, sizeof(b), MSG_PEEK,
|
||||
(struct sockaddr*)&cliAddr, &clilen);
|
||||
} while (bytesRecvd <= 0);
|
||||
|
||||
if (bytesRecvd > 0) {
|
||||
if (connect(listenfd, (const struct sockaddr*)&cliAddr,
|
||||
sizeof(cliAddr)) != 0) {
|
||||
printf("udp connect failed.\n");
|
||||
}
|
||||
}
|
||||
else {
|
||||
printf("recvfrom failed.\n");
|
||||
}
|
||||
|
||||
printf("Connected!\n");
|
||||
/* ensure b is empty upon each call */
|
||||
memset(&b, 0, sizeof(b));
|
||||
return listenfd;
|
||||
}
|
||||
|
||||
int NonBlockingSSL_Accept(WOLFSSL* ssl)
|
||||
{
|
||||
int select_ret;
|
||||
int currTimeout = 1;
|
||||
int ret = wolfSSL_accept(ssl);
|
||||
int error = wolfSSL_get_error(ssl, 0);
|
||||
int listenfd = (int)wolfSSL_get_fd(ssl);
|
||||
|
||||
while (cleanup != 1 && (ret != SSL_SUCCESS &&
|
||||
(error == SSL_ERROR_WANT_READ ||
|
||||
error == SSL_ERROR_WANT_WRITE))) {
|
||||
if (cleanup == 1) {
|
||||
wolfSSL_free(ssl);
|
||||
wolfSSL_shutdown(ssl);
|
||||
break;
|
||||
}
|
||||
|
||||
if (error == SSL_ERROR_WANT_READ)
|
||||
printf("... server would read block\n");
|
||||
else
|
||||
printf("... server would write block\n");
|
||||
|
||||
currTimeout = wolfSSL_dtls_get_current_timeout(ssl);
|
||||
select_ret = dtls_select(listenfd, currTimeout);
|
||||
|
||||
if ((select_ret == TEST_RECV_READY) ||
|
||||
(select_ret == TEST_ERROR_READY)) {
|
||||
ret = wolfSSL_accept(ssl);
|
||||
error = wolfSSL_get_error(ssl, 0);
|
||||
}
|
||||
else if (select_ret == TEST_TIMEOUT && !wolfSSL_dtls(ssl)) {
|
||||
error = SSL_ERROR_WANT_READ;
|
||||
}
|
||||
else if (select_ret == TEST_TIMEOUT && wolfSSL_dtls(ssl) &&
|
||||
wolfSSL_dtls_got_timeout(ssl) >= 0) {
|
||||
error = SSL_ERROR_WANT_READ;
|
||||
}
|
||||
else {
|
||||
error = SSL_FATAL_ERROR;
|
||||
}
|
||||
}
|
||||
if (ret != SSL_SUCCESS) {
|
||||
printf("SSL_accept failed.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void dtls_set_nonblocking(int* sockfd)
|
||||
{
|
||||
int flags = fcntl(*sockfd, F_GETFL, 0);
|
||||
if (flags < 0) {
|
||||
printf("fcntl get failed");
|
||||
cleanup = 1;
|
||||
}
|
||||
flags = fcntl(*sockfd, F_SETFL, flags | O_NONBLOCK);
|
||||
if (flags < 0) {
|
||||
printf("fcntl set failed.\n");
|
||||
cleanup = 1;
|
||||
}
|
||||
}
|
||||
|
||||
int dtls_select(int socketfd, int toSec)
|
||||
{
|
||||
int result;
|
||||
int nfds = socketfd + 1;
|
||||
fd_set recvfds, errfds;
|
||||
struct timeval timeout = { (toSec > 0) ? toSec : 0, 0};
|
||||
|
||||
FD_ZERO(&recvfds);
|
||||
FD_SET(socketfd, &recvfds);
|
||||
FD_ZERO(&errfds);
|
||||
FD_SET(socketfd, &errfds);
|
||||
|
||||
result = select(nfds, &recvfds, NULL, &errfds, &timeout);
|
||||
|
||||
if (result == 0)
|
||||
return TEST_TIMEOUT;
|
||||
else if (result > 0) {
|
||||
if (FD_ISSET(socketfd, &recvfds))
|
||||
return TEST_RECV_READY;
|
||||
else if(FD_ISSET(socketfd, &errfds))
|
||||
return TEST_ERROR_READY;
|
||||
}
|
||||
|
||||
return TEST_SELECT_FAIL;
|
||||
printf("\nSIGINT %d handled\n", sig);
|
||||
cleanup = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
/* cont short for "continue?", Loc short for "location" */
|
||||
int cont = 0;
|
||||
char caCertLoc[] = "../certs/ca-cert.pem";
|
||||
char servCertLoc[] = "../certs/server-cert.pem";
|
||||
char servKeyLoc[] = "../certs/server-key.pem";
|
||||
WOLFSSL_CTX* ctx;
|
||||
/* cont short for "continue?", Loc short for "location" */
|
||||
int cont = 0;
|
||||
char caCertLoc[] = "../certs/ca-cert.pem";
|
||||
char servCertLoc[] = "../certs/server-cert.pem";
|
||||
char servKeyLoc[] = "../certs/server-key.pem";
|
||||
WOLFSSL_CTX* ctx;
|
||||
/* Await Datagram variables */
|
||||
int on = 1;
|
||||
int res = 1;
|
||||
int recvLen; /* length of string read */
|
||||
int readWriteErr;
|
||||
int listenfd = 0; /* Initialize our socket */
|
||||
int clientfd = 0; /* client connection */
|
||||
int len = sizeof(on);
|
||||
char buff[MSGLEN]; /* string read from client */
|
||||
WOLFSSL* ssl = NULL; /* Initialize ssl object */
|
||||
struct sockaddr_in servAddr; /* our server's address */
|
||||
char ack[] = "I hear you fashizzle\n";
|
||||
/* DTLS set nonblocking flag */
|
||||
int flags = fcntl(*(&listenfd), F_GETFL, 0);
|
||||
/* NonBlockingSSL_Accept variables */
|
||||
int ret;
|
||||
int select_ret;
|
||||
int currTimeout;
|
||||
int error;
|
||||
int result;
|
||||
int nfds;
|
||||
fd_set recvfds, errfds;
|
||||
struct timeval timeout;
|
||||
/* udp-read-connect variables */
|
||||
int bytesRecvd;
|
||||
unsigned char b[MSGLEN];
|
||||
struct sockaddr_in cliAddr;
|
||||
socklen_t clilen;
|
||||
|
||||
/* Code for handling signals */
|
||||
struct sigaction act, oact;
|
||||
act.sa_handler = sig_handler;
|
||||
sigemptyset(&act.sa_mask);
|
||||
act.sa_flags = 0;
|
||||
sigaction(SIGINT, &act, &oact);
|
||||
|
||||
/* "./config --enable-debug" and uncomment next line for debugging */
|
||||
/* wolfSSL_Debugging_ON(); */
|
||||
|
@ -326,7 +117,7 @@ int main(int argc, char** argv)
|
|||
return 1;
|
||||
}
|
||||
/* Load CA certificates */
|
||||
if (wolfSSL_CTX_load_verify_locations(ctx,caCertLoc,0) !=
|
||||
if (wolfSSL_CTX_load_verify_locations(ctx,caCertLoc,0) !=
|
||||
SSL_SUCCESS) {
|
||||
printf("Error loading %s, please check the file.\n", caCertLoc);
|
||||
return 1;
|
||||
|
@ -338,13 +129,223 @@ int main(int argc, char** argv)
|
|||
return 1;
|
||||
}
|
||||
/* Load server Keys */
|
||||
if (wolfSSL_CTX_use_PrivateKey_file(ctx, servKeyLoc,
|
||||
if (wolfSSL_CTX_use_PrivateKey_file(ctx, servKeyLoc,
|
||||
SSL_FILETYPE_PEM) != SSL_SUCCESS) {
|
||||
printf("Error loading %s, please check the file.\n", servKeyLoc);
|
||||
return 1;
|
||||
}
|
||||
|
||||
cont = AwaitDGram(ctx);
|
||||
/* Await Datagram */
|
||||
cont = 0;
|
||||
while (cleanup != 1) {
|
||||
|
||||
clilen = sizeof(cliAddr);
|
||||
timeout.tv_sec = (currTimeout > 0) ? currTimeout : 0;
|
||||
|
||||
/* Create a UDP/IP socket */
|
||||
if ((listenfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0 ) {
|
||||
printf("Cannot create socket.\n");
|
||||
cont = 1;
|
||||
}
|
||||
|
||||
printf("Socket allocated\n");
|
||||
|
||||
/* DTLS set nonblocking */
|
||||
if (flags < 0) {
|
||||
printf("fcntl get failed");
|
||||
cleanup = 1;
|
||||
}
|
||||
flags = fcntl(*(&listenfd), F_SETFL, flags | O_NONBLOCK);
|
||||
if (flags < 0) {
|
||||
printf("fcntl set failed.\n");
|
||||
cleanup = 1;
|
||||
}
|
||||
|
||||
memset((char *)&servAddr, 0, sizeof(servAddr));
|
||||
|
||||
/* host-to-network-long conversion (htonl) */
|
||||
/* host-to-network-short conversion (htons) */
|
||||
servAddr.sin_family = AF_INET;
|
||||
servAddr.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
servAddr.sin_port = htons(SERV_PORT);
|
||||
|
||||
/* Eliminate socket already in use error */
|
||||
res = setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, len);
|
||||
if (res < 0) {
|
||||
printf("Setsockopt SO_REUSEADDR failed.\n");
|
||||
cont = 1;
|
||||
}
|
||||
|
||||
/*Bind Socket*/
|
||||
if (bind(listenfd,
|
||||
(struct sockaddr *)&servAddr, sizeof(servAddr)) < 0) {
|
||||
printf("Bind failed.\n");
|
||||
cont = 1;
|
||||
}
|
||||
|
||||
printf("Awaiting client connection on port %d\n", SERV_PORT);
|
||||
|
||||
/* UDP-read-connect */
|
||||
do {
|
||||
bytesRecvd = (int)recvfrom(listenfd, (char*)b, sizeof(b), MSG_PEEK,
|
||||
(struct sockaddr*)&cliAddr, &clilen);
|
||||
} while (bytesRecvd <= 0);
|
||||
|
||||
if (bytesRecvd > 0) {
|
||||
if (connect(listenfd, (const struct sockaddr*)&cliAddr,
|
||||
sizeof(cliAddr)) != 0) {
|
||||
printf("udp connect failed.\n");
|
||||
}
|
||||
}
|
||||
else {
|
||||
printf("recvfrom failed.\n");
|
||||
}
|
||||
|
||||
printf("Connected!\n");
|
||||
/* ensure b is empty upon each call */
|
||||
memset(&b, 0, sizeof(b));
|
||||
clientfd = listenfd;
|
||||
|
||||
/* Create the WOLFSSL Object */
|
||||
if (( ssl = wolfSSL_new(ctx)) == NULL) {
|
||||
printf("wolfSSL_new error.\n");
|
||||
cont = 1;
|
||||
}
|
||||
|
||||
/* set clilen to |cliAddr| */
|
||||
printf("Connected!\n");
|
||||
|
||||
/* set the/ session ssl to client connection port */
|
||||
wolfSSL_set_fd(ssl, clientfd);
|
||||
|
||||
wolfSSL_set_using_nonblock(ssl, 1);
|
||||
|
||||
/* NonBlockingSSL_Accept */
|
||||
ret = wolfSSL_accept(ssl);
|
||||
currTimeout = 1;
|
||||
error = wolfSSL_get_error(ssl, 0);
|
||||
listenfd = (int)wolfSSL_get_fd(ssl);
|
||||
nfds = listenfd + 1;
|
||||
while (cleanup != 1 && (ret != SSL_SUCCESS &&
|
||||
(error == SSL_ERROR_WANT_READ ||
|
||||
error == SSL_ERROR_WANT_WRITE))) {
|
||||
if (cleanup == 1) {
|
||||
wolfSSL_free(ssl);
|
||||
wolfSSL_shutdown(ssl);
|
||||
break;
|
||||
}
|
||||
|
||||
if (error == SSL_ERROR_WANT_READ)
|
||||
printf("... server would read block\n");
|
||||
else
|
||||
printf("... server would write block\n");
|
||||
|
||||
currTimeout = wolfSSL_dtls_get_current_timeout(ssl);
|
||||
|
||||
FD_ZERO(&recvfds);
|
||||
FD_SET(listenfd, &recvfds);
|
||||
FD_ZERO(&errfds);
|
||||
FD_SET(listenfd, &errfds);
|
||||
|
||||
result = select(nfds, &recvfds, NULL, &errfds, &timeout);
|
||||
|
||||
if (result == 0) {
|
||||
select_ret = TEST_TIMEOUT;
|
||||
}
|
||||
else if (result > 0) {
|
||||
if (FD_ISSET(listenfd, &recvfds)) {
|
||||
select_ret = TEST_RECV_READY;
|
||||
}
|
||||
else if(FD_ISSET(listenfd, &errfds)) {
|
||||
select_ret = TEST_ERROR_READY;
|
||||
}
|
||||
}
|
||||
else {
|
||||
select_ret = TEST_SELECT_FAIL;
|
||||
}
|
||||
|
||||
if ((select_ret == TEST_RECV_READY) ||
|
||||
(select_ret == TEST_ERROR_READY)) {
|
||||
ret = wolfSSL_accept(ssl);
|
||||
error = wolfSSL_get_error(ssl, 0);
|
||||
}
|
||||
else if (select_ret == TEST_TIMEOUT && !wolfSSL_dtls(ssl)) {
|
||||
error = SSL_ERROR_WANT_READ;
|
||||
}
|
||||
else if (select_ret == TEST_TIMEOUT && wolfSSL_dtls(ssl) &&
|
||||
wolfSSL_dtls_got_timeout(ssl) >= 0) {
|
||||
error = SSL_ERROR_WANT_READ;
|
||||
}
|
||||
else {
|
||||
error = SSL_FATAL_ERROR;
|
||||
}
|
||||
}
|
||||
if (ret != SSL_SUCCESS) {
|
||||
printf("SSL_accept failed.\n");
|
||||
cont = 1;
|
||||
}
|
||||
else {
|
||||
cont = 0;
|
||||
}
|
||||
|
||||
if (cont != 0) {
|
||||
printf("NonBlockingSSL_Accept failed.\n");
|
||||
cont = 1;
|
||||
}
|
||||
|
||||
/* Begin: Reply to the client */
|
||||
recvLen = wolfSSL_read(ssl, buff, sizeof(buff)-1);
|
||||
|
||||
/* Begin do-while read */
|
||||
do {
|
||||
if (cleanup == 1) {
|
||||
memset(buff, 0, sizeof(buff));
|
||||
break;
|
||||
}
|
||||
if (recvLen < 0) {
|
||||
readWriteErr = wolfSSL_get_error(ssl, 0);
|
||||
if (readWriteErr != SSL_ERROR_WANT_READ) {
|
||||
printf("Read Error, error was: %d.\n", readWriteErr);
|
||||
cleanup = 1;
|
||||
}
|
||||
else {
|
||||
recvLen = wolfSSL_read(ssl, buff, sizeof(buff)-1);
|
||||
}
|
||||
}
|
||||
} while (readWriteErr == SSL_ERROR_WANT_READ &&
|
||||
recvLen < 0 &&
|
||||
cleanup != 1);
|
||||
/* End do-while read */
|
||||
|
||||
if (recvLen > 0) {
|
||||
buff[recvLen] = 0;
|
||||
printf("I heard this:\"%s\"\n", buff);
|
||||
}
|
||||
else {
|
||||
printf("Connection Timed Out.\n");
|
||||
}
|
||||
|
||||
/* Begin do-while write */
|
||||
do {
|
||||
if (cleanup == 1) {
|
||||
memset(&buff, 0, sizeof(buff));
|
||||
break;
|
||||
}
|
||||
readWriteErr = wolfSSL_get_error(ssl, 0);
|
||||
if (wolfSSL_write(ssl, ack, sizeof(ack)) < 0) {
|
||||
printf("Write error.\n");
|
||||
cleanup = 1;
|
||||
}
|
||||
printf("Reply sent:\"%s\"\n", ack);
|
||||
} while(readWriteErr == SSL_ERROR_WANT_WRITE && cleanup != 1);
|
||||
/* End do-while write */
|
||||
|
||||
/* free allocated memory */
|
||||
memset(buff, 0, sizeof(buff));
|
||||
wolfSSL_free(ssl);
|
||||
|
||||
/* End: Reply to the Client */
|
||||
}
|
||||
|
||||
if (cont == 1) {
|
||||
wolfSSL_CTX_free(ctx);
|
||||
|
|
|
@ -20,11 +20,12 @@
|
|||
*
|
||||
*=============================================================================
|
||||
*
|
||||
* Bare-bones example of a threaded DTLS server for instructional/learning purposes.
|
||||
* Utilizes DTLS 1.2. and multi-threading
|
||||
* Bare-bones example of a threaded DTLS server for instructional/learning
|
||||
* purposes. Utilizes DTLS 1.2 and multi-threading
|
||||
*/
|
||||
|
||||
|
||||
#include <wolfssl/options.h>
|
||||
#include <wolfssl/ssl.h>
|
||||
#include <stdio.h> /* standard in/out procedures */
|
||||
#include <stdlib.h> /* defines system calls */
|
||||
#include <string.h> /* necessary for memset */
|
||||
|
@ -32,7 +33,6 @@
|
|||
#include <sys/socket.h> /* used for all socket calls */
|
||||
#include <netinet/in.h> /* used for sockaddr_in */
|
||||
#include <arpa/inet.h>
|
||||
#include <wolfssl/ssl.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
|
@ -41,22 +41,103 @@
|
|||
#define SERV_PORT 11111 /* define our server port number */
|
||||
#define MSGLEN 4096
|
||||
|
||||
WOLFSSL_CTX* ctx; /* must be global for ThreadControl */
|
||||
static int cleanup; /* To handle shutdown */
|
||||
struct sockaddr_in cliAddr; /* the client's address */
|
||||
struct sockaddr_in servAddr; /* our server's address */
|
||||
static WOLFSSL_CTX* ctx; /* global for ThreadControl*/
|
||||
static int cleanup; /* To handle shutdown */
|
||||
static struct sockaddr_in cliAddr; /* the client's address */
|
||||
static struct sockaddr_in servAddr; /* our server's address */
|
||||
|
||||
int AwaitDGram(WOLFSSL_CTX* ctx);
|
||||
void sig_handler(const int sig);
|
||||
void* ThreadControl(void*);
|
||||
|
||||
typedef struct {
|
||||
int activefd;
|
||||
int size;
|
||||
unsigned char b[MSGLEN];
|
||||
}threadArgs;
|
||||
} threadArgs;
|
||||
|
||||
int AwaitDGram(WOLFSSL_CTX* ctx)
|
||||
void sig_handler(const int sig)
|
||||
{
|
||||
printf("\nSIGINT %d handled\n", sig);
|
||||
cleanup = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
void* ThreadControl(void* openSock)
|
||||
{
|
||||
pthread_detach(pthread_self());
|
||||
|
||||
threadArgs* args = (threadArgs*)openSock;
|
||||
int recvLen = 0; /* length of message */
|
||||
int activefd = args->activefd; /* the active descriptor */
|
||||
int msgLen = args->size; /* the size of message */
|
||||
unsigned char buff[msgLen]; /* the incoming message */
|
||||
char ack[] = "I hear you fashizzle!\n";
|
||||
WOLFSSL* ssl;
|
||||
int e; /* error */
|
||||
|
||||
memcpy(buff, args->b, msgLen);
|
||||
|
||||
/* Create the WOLFSSL Object */
|
||||
if ((ssl = wolfSSL_new(ctx)) == NULL) {
|
||||
printf("wolfSSL_new error.\n");
|
||||
cleanup = 1;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* set the session ssl to client connection port */
|
||||
wolfSSL_set_fd(ssl, activefd);
|
||||
|
||||
if (wolfSSL_accept(ssl) != SSL_SUCCESS) {
|
||||
|
||||
e = wolfSSL_get_error(ssl, 0);
|
||||
|
||||
printf("error = %d, %s\n", e, wolfSSL_ERR_reason_error_string(e));
|
||||
printf("SSL_accept failed.\n");
|
||||
return NULL;
|
||||
}
|
||||
if ((recvLen = wolfSSL_read(ssl, buff, msgLen-1)) > 0) {
|
||||
printf("heard %d bytes\n", recvLen);
|
||||
|
||||
buff[recvLen] = 0;
|
||||
printf("I heard this: \"%s\"\n", buff);
|
||||
}
|
||||
else if (recvLen < 0) {
|
||||
int readErr = wolfSSL_get_error(ssl, 0);
|
||||
if(readErr != SSL_ERROR_WANT_READ) {
|
||||
printf("SSL_read failed.\n");
|
||||
cleanup = 1;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
if (wolfSSL_write(ssl, ack, sizeof(ack)) < 0) {
|
||||
printf("wolfSSL_write fail.\n");
|
||||
cleanup = 1;
|
||||
return NULL;
|
||||
}
|
||||
else {
|
||||
printf("Sending reply.\n");
|
||||
}
|
||||
|
||||
printf("reply sent \"%s\"\n", ack);
|
||||
|
||||
wolfSSL_shutdown(ssl);
|
||||
wolfSSL_free(ssl);
|
||||
close(activefd);
|
||||
free(openSock); /* valgrind friendly free */
|
||||
|
||||
printf("Client left return to idle state\n");
|
||||
printf("Exiting thread.\n\n");
|
||||
pthread_exit(openSock);
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
/* cont short for "continue?", Loc short for "location" */
|
||||
int cont = 0;
|
||||
char caCertLoc[] = "../certs/ca-cert.pem";
|
||||
char servCertLoc[] = "../certs/server-cert.pem";
|
||||
char servKeyLoc[] = "../certs/server-key.pem";
|
||||
|
||||
int on = 1;
|
||||
int res = 1;
|
||||
int bytesRcvd = 0;
|
||||
|
@ -64,6 +145,46 @@ int AwaitDGram(WOLFSSL_CTX* ctx)
|
|||
socklen_t cliLen;
|
||||
socklen_t len = sizeof(on);
|
||||
unsigned char buf[MSGLEN]; /* watch for incoming messages */
|
||||
/* variables needed for threading */
|
||||
threadArgs* args;
|
||||
pthread_t threadid;
|
||||
|
||||
/* Code for handling signals */
|
||||
struct sigaction act, oact;
|
||||
act.sa_handler = sig_handler;
|
||||
sigemptyset(&act.sa_mask);
|
||||
act.sa_flags = 0;
|
||||
sigaction(SIGINT, &act, &oact);
|
||||
|
||||
/* "./config --enable-debug" and uncomment next line for debugging */
|
||||
/* wolfSSL_Debugging_ON(); */
|
||||
|
||||
/* Initialize wolfSSL */
|
||||
wolfSSL_Init();
|
||||
|
||||
/* Set ctx to DTLS 1.2 */
|
||||
if ((ctx = wolfSSL_CTX_new(wolfDTLSv1_2_server_method())) == NULL) {
|
||||
printf("wolfSSL_CTX_new error.\n");
|
||||
return 1;
|
||||
}
|
||||
/* Load CA certificates */
|
||||
if (wolfSSL_CTX_load_verify_locations(ctx,caCertLoc,0) !=
|
||||
SSL_SUCCESS) {
|
||||
printf("Error loading %s, please check the file.\n", caCertLoc);
|
||||
return 1;
|
||||
}
|
||||
/* Load server certificates */
|
||||
if (wolfSSL_CTX_use_certificate_file(ctx, servCertLoc, SSL_FILETYPE_PEM) !=
|
||||
SSL_SUCCESS) {
|
||||
printf("Error loading %s, please check the file.\n", servCertLoc);
|
||||
return 1;
|
||||
}
|
||||
/* Load server Keys */
|
||||
if (wolfSSL_CTX_use_PrivateKey_file(ctx, servKeyLoc,
|
||||
SSL_FILETYPE_PEM) != SSL_SUCCESS) {
|
||||
printf("Error loading %s, please check the file.\n", servKeyLoc);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Create a UDP/IP socket */
|
||||
if ((listenfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0 ) {
|
||||
|
@ -101,7 +222,8 @@ int AwaitDGram(WOLFSSL_CTX* ctx)
|
|||
|
||||
while (cleanup != 1) {
|
||||
|
||||
threadArgs* args;
|
||||
memset(&threadid, 0, sizeof(threadid));
|
||||
|
||||
args = (threadArgs *) malloc(sizeof(threadArgs));
|
||||
|
||||
cliLen = sizeof(cliAddr);
|
||||
|
@ -110,9 +232,15 @@ int AwaitDGram(WOLFSSL_CTX* ctx)
|
|||
* read any real message to struct and pass struct into thread
|
||||
* for processing.
|
||||
*/
|
||||
|
||||
bytesRcvd = (int)recvfrom(listenfd, (char *)buf, sizeof(buf), 0,
|
||||
(struct sockaddr*)&cliAddr, &cliLen);
|
||||
|
||||
if (cleanup == 1) {
|
||||
free(args);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (bytesRcvd < 0) {
|
||||
printf("No clients in que, enter idle state\n");
|
||||
continue;
|
||||
|
@ -120,6 +248,7 @@ int AwaitDGram(WOLFSSL_CTX* ctx)
|
|||
|
||||
else if (bytesRcvd > 0) {
|
||||
|
||||
/* put all the bytes from buf into args */
|
||||
memcpy(args->b, buf, sizeof(buf));
|
||||
|
||||
args->size = bytesRcvd;
|
||||
|
@ -130,20 +259,23 @@ int AwaitDGram(WOLFSSL_CTX* ctx)
|
|||
}
|
||||
|
||||
res = setsockopt(args->activefd, SOL_SOCKET, SO_REUSEADDR, &on,
|
||||
len);
|
||||
len);
|
||||
|
||||
if (res < 0) {
|
||||
printf("Setsockopt SO_REUSEADDR failed.\n");
|
||||
cleanup = 1;
|
||||
return 1;
|
||||
}
|
||||
#ifdef SO_REUSEPORT
|
||||
res = setsockopt(args->activefd, SOL_SOCKET, SO_REUSEPORT, &on, len);
|
||||
if (res < 0) {
|
||||
printf("Setsockopt SO_REUSEPORT failed.\n");
|
||||
cleanup = 1;
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SO_REUSEPORT
|
||||
res = setsockopt(args->activefd, SOL_SOCKET, SO_REUSEPORT, &on,
|
||||
len);
|
||||
if (res < 0) {
|
||||
printf("Setsockopt SO_REUSEPORT failed.\n");
|
||||
cleanup = 1;
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (connect(args->activefd, (const struct sockaddr *)&cliAddr,
|
||||
sizeof(cliAddr)) != 0) {
|
||||
|
@ -153,128 +285,27 @@ int AwaitDGram(WOLFSSL_CTX* ctx)
|
|||
}
|
||||
}
|
||||
else {
|
||||
/* else bytesRcvd = 0 */
|
||||
printf("Recvfrom failed.\n");
|
||||
cleanup = 1;
|
||||
return 1;
|
||||
}
|
||||
printf("Connected!\n");
|
||||
|
||||
pthread_t threadid;
|
||||
/* SPIN A THREAD HERE TO HANDLE "buff" and "reply/ack" */
|
||||
pthread_create(&threadid, NULL, ThreadControl, args);
|
||||
printf("control passed to thread control.\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void* ThreadControl(void* openSock)
|
||||
{
|
||||
pthread_detach(pthread_self());
|
||||
|
||||
threadArgs* args = (threadArgs*)openSock;
|
||||
int recvLen = 0; /* length of message */
|
||||
int activefd = args->activefd; /* the active descriptor */
|
||||
int msgLen = args->size; /* the size of message */
|
||||
unsigned char buff[msgLen]; /* the incoming message */
|
||||
char ack[] = "I hear you fashizzle!\n";
|
||||
WOLFSSL* ssl;
|
||||
|
||||
memcpy(buff, args->b, msgLen);
|
||||
|
||||
/* Create the WOLFSSL Object */
|
||||
if ((ssl = wolfSSL_new(ctx)) == NULL) {
|
||||
printf("wolfSSL_new error.\n");
|
||||
cleanup = 1;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* set the session ssl to client connection port */
|
||||
wolfSSL_set_fd(ssl, activefd);
|
||||
|
||||
if (wolfSSL_accept(ssl) != SSL_SUCCESS) {
|
||||
|
||||
int e = wolfSSL_get_error(ssl, 0);
|
||||
|
||||
printf("error = %d, %s\n", e, wolfSSL_ERR_reason_error_string(e));
|
||||
printf("SSL_accept failed.\n");
|
||||
return NULL;
|
||||
}
|
||||
if ((recvLen = wolfSSL_read(ssl, buff, msgLen-1)) > 0) {
|
||||
printf("heard %d bytes\n", recvLen);
|
||||
|
||||
buff[recvLen] = 0;
|
||||
printf("I heard this: \"%s\"\n", buff);
|
||||
}
|
||||
else if (recvLen < 0) {
|
||||
int readErr = wolfSSL_get_error(ssl, 0);
|
||||
if(readErr != SSL_ERROR_WANT_READ) {
|
||||
printf("SSL_read failed.\n");
|
||||
cleanup = 1;
|
||||
return NULL;
|
||||
if (cleanup != 1) {
|
||||
/* SPIN A THREAD HERE TO HANDLE "buff" and "reply/ack" */
|
||||
pthread_create(&threadid, NULL, ThreadControl, args);
|
||||
printf("control passed to ThreadControl.\n");
|
||||
}
|
||||
else if (cleanup == 1) {
|
||||
return 1;
|
||||
} else {
|
||||
printf("I don't know what to tell ya man\n");
|
||||
}
|
||||
|
||||
/* clear servAddr each loop */
|
||||
memset((char *)&servAddr, 0, sizeof(servAddr));
|
||||
}
|
||||
if (wolfSSL_write(ssl, ack, sizeof(ack)) < 0) {
|
||||
printf("wolfSSL_write fail.\n");
|
||||
cleanup = 1;
|
||||
return NULL;
|
||||
}
|
||||
else {
|
||||
printf("Sending reply.\n");
|
||||
}
|
||||
|
||||
printf("reply sent \"%s\"\n", ack);
|
||||
|
||||
|
||||
wolfSSL_shutdown(ssl);
|
||||
wolfSSL_free(ssl);
|
||||
close(activefd);
|
||||
free(openSock); /* valgrind friendly free */
|
||||
|
||||
printf("Client left return to idle state\n");
|
||||
printf("Exiting thread.\n\n");
|
||||
pthread_exit(openSock);
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
/* cont short for "continue?", Loc short for "location" */
|
||||
int cont = 0;
|
||||
char caCertLoc[] = "../certs/ca-cert.pem";
|
||||
char servCertLoc[] = "../certs/server-cert.pem";
|
||||
char servKeyLoc[] = "../certs/server-key.pem";
|
||||
|
||||
/* "./config --enable-debug" and uncomment next line for debugging */
|
||||
/* wolfSSL_Debugging_ON(); */
|
||||
|
||||
/* Initialize wolfSSL */
|
||||
wolfSSL_Init();
|
||||
|
||||
/* Set ctx to DTLS 1.2 */
|
||||
if ((ctx = wolfSSL_CTX_new(wolfDTLSv1_2_server_method())) == NULL) {
|
||||
printf("wolfSSL_CTX_new error.\n");
|
||||
return 1;
|
||||
}
|
||||
/* Load CA certificates */
|
||||
if (wolfSSL_CTX_load_verify_locations(ctx,caCertLoc,0) !=
|
||||
SSL_SUCCESS) {
|
||||
printf("Error loading %s, please check the file.\n", caCertLoc);
|
||||
return 1;
|
||||
}
|
||||
/* Load server certificates */
|
||||
if (wolfSSL_CTX_use_certificate_file(ctx, servCertLoc, SSL_FILETYPE_PEM) !=
|
||||
SSL_SUCCESS) {
|
||||
printf("Error loading %s, please check the file.\n", servCertLoc);
|
||||
return 1;
|
||||
}
|
||||
/* Load server Keys */
|
||||
if (wolfSSL_CTX_use_PrivateKey_file(ctx, servKeyLoc,
|
||||
SSL_FILETYPE_PEM) != SSL_SUCCESS) {
|
||||
printf("Error loading %s, please check the file.\n", servKeyLoc);
|
||||
return 1;
|
||||
}
|
||||
|
||||
cont = AwaitDGram(ctx);
|
||||
|
||||
if (cont == 1) {
|
||||
wolfSSL_CTX_free(ctx);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* server-dtls.c
|
||||
/* server-dtls.c
|
||||
*
|
||||
* Copyright (C) 2006-2015 wolfSSL Inc.
|
||||
*
|
||||
|
@ -24,6 +24,7 @@
|
|||
* Utilizes DTLS 1.2.
|
||||
*/
|
||||
|
||||
#include <wolfssl/options.h>
|
||||
#include <stdio.h> /* standard in/out procedures */
|
||||
#include <stdlib.h> /* defines system calls */
|
||||
#include <string.h> /* necessary for memset */
|
||||
|
@ -43,30 +44,82 @@ static int cleanup; /* To handle shutdown */
|
|||
struct sockaddr_in servAddr; /* our server's address */
|
||||
struct sockaddr_in cliaddr; /* the client's address */
|
||||
|
||||
int AwaitDGram(WOLFSSL_CTX* ctx); /* Separate out Handling Datagrams */
|
||||
void CleanUp();
|
||||
void sig_handler(const int sig);
|
||||
|
||||
int AwaitDGram(WOLFSSL_CTX* ctx)
|
||||
void sig_handler(const int sig)
|
||||
{
|
||||
printf("\nSIGINT %d handled\n", sig);
|
||||
cleanup = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
/* cont short for "continue?", Loc short for "location" */
|
||||
int cont = 0;
|
||||
char caCertLoc[] = "../certs/ca-cert.pem";
|
||||
char servCertLoc[] = "../certs/server-cert.pem";
|
||||
char servKeyLoc[] = "../certs/server-key.pem";
|
||||
WOLFSSL_CTX* ctx;
|
||||
/* Variables for awaiting datagram */
|
||||
int on = 1;
|
||||
int res = 1;
|
||||
int connfd = 0;
|
||||
int res = 1;
|
||||
int connfd = 0;
|
||||
int recvLen = 0; /* length of message */
|
||||
int listenfd = 0; /* Initialize our socket */
|
||||
WOLFSSL* ssl = NULL;
|
||||
WOLFSSL* ssl = NULL;
|
||||
socklen_t cliLen;
|
||||
socklen_t len = sizeof(on);
|
||||
socklen_t len = sizeof(int);
|
||||
unsigned char b[MSGLEN]; /* watch for incoming messages */
|
||||
char buff[MSGLEN]; /* the incoming message */
|
||||
char ack[] = "I hear you fashizzle!\n";
|
||||
|
||||
/* Code for handling signals */
|
||||
struct sigaction act, oact;
|
||||
act.sa_handler = sig_handler;
|
||||
sigemptyset(&act.sa_mask);
|
||||
act.sa_flags = 0;
|
||||
sigaction(SIGINT, &act, &oact);
|
||||
|
||||
/* "./config --enable-debug" and uncomment next line for debugging */
|
||||
/* wolfSSL_Debugging_ON(); */
|
||||
|
||||
/* Initialize wolfSSL */
|
||||
wolfSSL_Init();
|
||||
|
||||
/* Set ctx to DTLS 1.2 */
|
||||
if ((ctx = wolfSSL_CTX_new(wolfDTLSv1_2_server_method())) == NULL) {
|
||||
printf("wolfSSL_CTX_new error.\n");
|
||||
return 1;
|
||||
}
|
||||
/* Load CA certificates */
|
||||
if (wolfSSL_CTX_load_verify_locations(ctx,caCertLoc,0) !=
|
||||
SSL_SUCCESS) {
|
||||
printf("Error loading %s, please check the file.\n", caCertLoc);
|
||||
return 1;
|
||||
}
|
||||
/* Load server certificates */
|
||||
if (wolfSSL_CTX_use_certificate_file(ctx, servCertLoc, SSL_FILETYPE_PEM) !=
|
||||
SSL_SUCCESS) {
|
||||
printf("Error loading %s, please check the file.\n", servCertLoc);
|
||||
return 1;
|
||||
}
|
||||
/* Load server Keys */
|
||||
if (wolfSSL_CTX_use_PrivateKey_file(ctx, servKeyLoc,
|
||||
SSL_FILETYPE_PEM) != SSL_SUCCESS) {
|
||||
printf("Error loading %s, please check the file.\n", servKeyLoc);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Await Datagram */
|
||||
while (cleanup != 1) {
|
||||
|
||||
/* Create a UDP/IP socket */
|
||||
if ((listenfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0 ) {
|
||||
printf("Cannot create socket.\n");
|
||||
cleanup = 1;
|
||||
}
|
||||
printf("Socket all/ocated\n");
|
||||
printf("Socket allocated\n");
|
||||
|
||||
/* clear servAddr each loop */
|
||||
memset((char *)&servAddr, 0, sizeof(servAddr));
|
||||
|
@ -82,20 +135,19 @@ int AwaitDGram(WOLFSSL_CTX* ctx)
|
|||
if (res < 0) {
|
||||
printf("Setsockopt SO_REUSEADDR failed.\n");
|
||||
cleanup = 1;
|
||||
return 1;
|
||||
cont = 1;
|
||||
}
|
||||
|
||||
/*Bind Socket*/
|
||||
if (bind(listenfd,
|
||||
(struct sockaddr *)&servAddr, sizeof(servAddr)) < 0) {
|
||||
if (bind(listenfd, (struct sockaddr*)&servAddr, sizeof(servAddr)) < 0) {
|
||||
printf("Bind failed.\n");
|
||||
cleanup = 1;
|
||||
return 1;
|
||||
cont = 1;
|
||||
}
|
||||
|
||||
printf("Awaiting client connection on port %d\n", SERV_PORT);
|
||||
|
||||
cliLen = sizeof(cliaddr);
|
||||
cliLen = sizeof(cliaddr);
|
||||
connfd = (int)recvfrom(listenfd, (char *)&b, sizeof(b), MSG_PEEK,
|
||||
(struct sockaddr*)&cliaddr, &cliLen);
|
||||
|
||||
|
@ -104,17 +156,17 @@ int AwaitDGram(WOLFSSL_CTX* ctx)
|
|||
continue;
|
||||
}
|
||||
else if (connfd > 0) {
|
||||
if (connect(listenfd, (const struct sockaddr *)&cliaddr,
|
||||
if (connect(listenfd, (const struct sockaddr *)&cliaddr,
|
||||
sizeof(cliaddr)) != 0) {
|
||||
printf("Udp connect failed.\n");
|
||||
cleanup = 1;
|
||||
return 1;
|
||||
cont = 1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
printf("Recvfrom failed.\n");
|
||||
cleanup = 1;
|
||||
return 1;
|
||||
cont = 1;
|
||||
}
|
||||
printf("Connected!\n");
|
||||
|
||||
|
@ -122,12 +174,12 @@ int AwaitDGram(WOLFSSL_CTX* ctx)
|
|||
if ((ssl = wolfSSL_new(ctx)) == NULL) {
|
||||
printf("wolfSSL_new error.\n");
|
||||
cleanup = 1;
|
||||
return 1;
|
||||
cont = 1;
|
||||
}
|
||||
|
||||
|
||||
/* set the session ssl to client connection port */
|
||||
wolfSSL_set_fd(ssl, listenfd);
|
||||
|
||||
|
||||
if (wolfSSL_accept(ssl) != SSL_SUCCESS) {
|
||||
|
||||
int e = wolfSSL_get_error(ssl, 0);
|
||||
|
@ -147,69 +199,33 @@ int AwaitDGram(WOLFSSL_CTX* ctx)
|
|||
if(readErr != SSL_ERROR_WANT_READ) {
|
||||
printf("SSL_read failed.\n");
|
||||
cleanup = 1;
|
||||
return 1;
|
||||
cont = 1;
|
||||
}
|
||||
}
|
||||
if (wolfSSL_write(ssl, ack, sizeof(ack)) < 0) {
|
||||
printf("wolfSSL_write fail.\n");
|
||||
cleanup = 1;
|
||||
return 1;
|
||||
}
|
||||
cont = 1;
|
||||
}
|
||||
else {
|
||||
printf("Sending reply.\n");
|
||||
}
|
||||
|
||||
printf("reply sent \"%s\"\n", ack);
|
||||
|
||||
wolfSSL_set_fd(ssl, 0);
|
||||
wolfSSL_shutdown(ssl);
|
||||
wolfSSL_set_fd(ssl, 0);
|
||||
wolfSSL_shutdown(ssl);
|
||||
wolfSSL_free(ssl);
|
||||
|
||||
printf("Client left return to idle state\n");
|
||||
printf("Client left cont to idle state\n");
|
||||
cont = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
/* cont short for "continue?", Loc short for "location" */
|
||||
int cont = 0;
|
||||
char caCertLoc[] = "../certs/ca-cert.pem";
|
||||
char servCertLoc[] = "../certs/server-cert.pem";
|
||||
char servKeyLoc[] = "../certs/server-key.pem";
|
||||
WOLFSSL_CTX* ctx;
|
||||
|
||||
/* "./config --enable-debug" and uncomment next line for debugging */
|
||||
/* wolfSSL_Debugging_ON(); */
|
||||
|
||||
/* Initialize wolfSSL */
|
||||
wolfSSL_Init();
|
||||
|
||||
/* Set ctx to DTLS 1.2 */
|
||||
if ((ctx = wolfSSL_CTX_new(wolfDTLSv1_2_server_method())) == NULL) {
|
||||
printf("wolfSSL_CTX_new error.\n");
|
||||
return 1;
|
||||
/* With the "continue" keywords, it is possible for the loop to exit *
|
||||
* without changing the value of cont */
|
||||
if (cleanup == 1) {
|
||||
cont = 1;
|
||||
}
|
||||
/* Load CA certificates */
|
||||
if (wolfSSL_CTX_load_verify_locations(ctx,caCertLoc,0) !=
|
||||
SSL_SUCCESS) {
|
||||
printf("Error loading %s, please check the file.\n", caCertLoc);
|
||||
return 1;
|
||||
}
|
||||
/* Load server certificates */
|
||||
if (wolfSSL_CTX_use_certificate_file(ctx, servCertLoc, SSL_FILETYPE_PEM) !=
|
||||
SSL_SUCCESS) {
|
||||
printf("Error loading %s, please check the file.\n", servCertLoc);
|
||||
return 1;
|
||||
}
|
||||
/* Load server Keys */
|
||||
if (wolfSSL_CTX_use_PrivateKey_file(ctx, servKeyLoc,
|
||||
SSL_FILETYPE_PEM) != SSL_SUCCESS) {
|
||||
printf("Error loading %s, please check the file.\n", servKeyLoc);
|
||||
return 1;
|
||||
}
|
||||
|
||||
cont = AwaitDGram(ctx);
|
||||
|
||||
if (cont == 1) {
|
||||
wolfSSL_CTX_free(ctx);
|
||||
|
@ -218,3 +234,4 @@ int main(int argc, char** argv)
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* server-udp.c
|
||||
/*
|
||||
* server-udp.c
|
||||
*
|
||||
* Copyright (C) 2006-2015 wolfSSL Inc.
|
||||
* Copyright (C) 2006-2017 wolfSSL Inc.
|
||||
*
|
||||
* This file is part of wolfSSL. (formerly known as CyaSSL)
|
||||
*
|
||||
|
@ -35,7 +35,7 @@
|
|||
#define SERV_PORT 11111 /* define our server port number */
|
||||
#define MSGLEN 4096 /* limit incoming message size */
|
||||
|
||||
int main (int argc, char** argv)
|
||||
int main (void)
|
||||
{
|
||||
int sockfd; /* Initialize our socket */
|
||||
int recvLen; /* number of bytes recieved */
|
||||
|
@ -69,7 +69,7 @@ int main (int argc, char** argv)
|
|||
memset(buf, 0, sizeof(buf));
|
||||
printf("waiting for client message on port %d\n", SERV_PORT);
|
||||
|
||||
recvLen = recvfrom(sockfd, buf, MSGLEN, 0,
|
||||
recvLen = recvfrom(sockfd, buf, MSGLEN, 0,
|
||||
(struct sockaddr *)&cliAddr, &cliAddrLen);
|
||||
|
||||
printf("heard %d bytes\n", recvLen);
|
||||
|
@ -84,7 +84,7 @@ int main (int argc, char** argv)
|
|||
printf("Message #%d received\n", msgNum++);
|
||||
printf("reply sent \"%s\"\n", buf);
|
||||
|
||||
if (sendto(sockfd, buf, sizeof(buf), 0,
|
||||
if (sendto(sockfd, buf, sizeof(buf), 0,
|
||||
(struct sockaddr *)&cliAddr, cliAddrLen) < 0) {
|
||||
printf("\"sendto\" failed.\n");
|
||||
return 1;
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -9,11 +9,12 @@ TCP/PSK Tutorial
|
|||
|
||||
``read(sockfd, recvline, MAXLINE)`` becomes ``wolfSSL_read(ssl, recvline, MAXLINE)``
|
||||
|
||||
3. Change all calls from write() or send() to CySSL_write(), in the simple client
|
||||
3. Change all calls from write() or send() to wolfSSL_write(), in the simple client
|
||||
|
||||
``write(socked, send line,strlen(send line))`` becomes ``wolfSSL_write(ssl, send line, strlen(sendline))``
|
||||
``write(socked, sendline, strlen(sendline))`` becomes ``wolfSSL_write(ssl, sendline, strlen(sendline))``
|
||||
|
||||
4. In the main method initialize wolfSSL and WOLFSSL_CTX.
|
||||
4. In the main method initialize wolfSSL and WOLFSSL_CTX. You must initialize wolfSSL before making any other wolfSSL calls.
|
||||
wolfSSL_CTX_new() takes an argument that defines what SSL/TLS protocol to use. In this case ``wolfTLSv1_2_client_method()`` is used to specify TLS 1.2.
|
||||
|
||||
wolfSSL_Init();
|
||||
|
||||
|
@ -35,10 +36,11 @@ TCP/PSK Tutorial
|
|||
return 1;
|
||||
}
|
||||
|
||||
6. Cleanup. After each wolfSSL object is done being used you can free it up by calling ``wolfSSL_free(ssl);``
|
||||
6. Cleanup. After each wolfSSL object is done being used you can free it up by calling ``wolfSSL_free(ssl);``.
|
||||
|
||||
7. When completely done using SSL/TLS, free the WOLFSSL_CTX object by
|
||||
|
||||
``wolfSSL_CTX_free(CTX);``
|
||||
``wolfSSL_CTX_free(ctx);``
|
||||
|
||||
``wolfSSL_Cleanup();``
|
||||
|
||||
|
@ -82,7 +84,7 @@ TCP/PSK Tutorial
|
|||
|
||||
2. After the function ``wolfSSL_set_fd(ssl,sockfd)``, tell wolfSSL that you want non-blocking to be used. This is done by adding : `` wolfSSL_set_using_nonblock(ssl,1);``
|
||||
|
||||
3. Now we much invoke the fcnt callable serve to use non-blocking.
|
||||
3. Now we must invoke the fcntl callable serve to use non-blocking.
|
||||
|
||||
int flags = fcntl(sockfd, F_GETFL, 0);
|
||||
if (flags < 0) {
|
||||
|
@ -190,7 +192,7 @@ Session resumption allows a client/server pair to re-use previously generated cr
|
|||
WOLFSSL_SESSION* session = wolfSSL_get_session(ssl);
|
||||
WOLFSSL* sslResume = wolfSSL_new(ctx);
|
||||
|
||||
2. Now we must close wolfSSL SSL and close connections. Alos free the socket and ctx.
|
||||
2. Now we must close wolfSSL SSL and close connections i.e. free the socket and ctx.
|
||||
|
||||
/* shut down wolfSSL */
|
||||
wolfSSL_shutdown(ssl);
|
||||
|
@ -198,10 +200,9 @@ Session resumption allows a client/server pair to re-use previously generated cr
|
|||
/* close connection */
|
||||
close(sockfd);
|
||||
|
||||
/* cleanup */
|
||||
/* cleanup without wolfSSL_Cleanup() for now */
|
||||
wolfSSL_free(ssl);
|
||||
wolfSSL_CTX_free(ctx);
|
||||
wolfSSL_Cleanup();
|
||||
|
||||
3. Now we are ready to reconnect and start a new socket but we are going to reuse the session id to make things go a little faster.
|
||||
|
||||
|
@ -209,7 +210,7 @@ Session resumption allows a client/server pair to re-use previously generated cr
|
|||
sock = socket(AF_INET, SOCK_STREAM, 0);
|
||||
|
||||
/* connect to the socket */
|
||||
ret = connect(sock, (struct sockaddr *) &servaddr, sizeof(servaddr));
|
||||
ret = connect(sock, (struct sockaddr *) &servaddr, sizeof(servaddr));
|
||||
|
||||
if (ret != 0){
|
||||
return 1;
|
||||
|
@ -245,7 +246,7 @@ Session resumption allows a client/server pair to re-use previously generated cr
|
|||
/* shut down socket */
|
||||
close(sock);
|
||||
|
||||
/* clean up */
|
||||
/* clean up now with wolfSSL_Cleanup() */
|
||||
wolfSSL_free(sslResume);
|
||||
wolfSSL_CTX_free(ctx);
|
||||
wolfSSL_Cleanup();
|
||||
|
@ -261,13 +262,14 @@ Session resumption allows a client/server pair to re-use previously generated cr
|
|||
|
||||
>(wolfSSL_read on first use also calls wolfSSL_accept if not explicitly called earlier in code.)
|
||||
|
||||
3. Change all calls from write() or send() to CySSL_write(), in the simple server
|
||||
3. Change all calls from write() or send() to wolfSSL_write(), in the simple server
|
||||
``write(sockfd, sendline, strlen(sendline))`` becomes ``wolfSSL_write(ssl, sendline, strlen(sendline))``
|
||||
|
||||
4. Run the wolfSSL method to initalize wolfSSL
|
||||
``wolfSSL_Init()``
|
||||
|
||||
5. Create a ctx pointer that contains using the following process.
|
||||
5. Create a ctx pointer that contains a server method using the following process. The server method wolfSSLv23_server_method()
|
||||
allows clients with TLS 1+ to connect.
|
||||
```
|
||||
WOLFSSL_CTX* ctx;
|
||||
|
||||
|
@ -280,7 +282,7 @@ Session resumption allows a client/server pair to re-use previously generated cr
|
|||
```
|
||||
WOLFSSL* ssl;
|
||||
|
||||
wolfSSL_set_fd(ssl, “integer returned from accept”);
|
||||
wolfSSL_set_fd(ssl, “integer (file descriptor) returned from accept”);
|
||||
|
||||
wolfSSL_free(ssl);
|
||||
|
||||
|
@ -310,9 +312,9 @@ The following steps are on how to use PSK in a wolfSSL server
|
|||
>PSK-AES128-CBC-SHA256 creates the cipher list of having pre shared keys with advanced encryption security using 128 bit key
|
||||
>with cipher block chaining using secure hash algorithm.
|
||||
|
||||
3. Add the my_psk_server_cb function as follows. This is a function needed that is passed in as an argument to the wolfSSL callback.
|
||||
3. Add the my_psk_server_cb function as follows. This is a necessary function that is passed in as an argument to the wolfSSL callback.
|
||||
|
||||
```
|
||||
```
|
||||
static inline unsigned int my_psk_client_cb(WOLFSSL* ssl, char* identity, unsigned
|
||||
char* key, unsigned int key_max_len) {
|
||||
(void)ssl;
|
||||
|
@ -330,12 +332,12 @@ The following steps are on how to use PSK in a wolfSSL server
|
|||
|
||||
return 4;
|
||||
}
|
||||
```
|
||||
```
|
||||
|
||||
|
||||
Example Makefile for Simple wolfSSL PSK Client:
|
||||
|
||||
```
|
||||
```
|
||||
CC=gcc
|
||||
OBJ = client-psk.o
|
||||
CFLAG=-Wall
|
||||
|
@ -350,19 +352,19 @@ Example Makefile for Simple wolfSSL PSK Client:
|
|||
|
||||
clean:
|
||||
rm -f *.o client-psk
|
||||
```
|
||||
```
|
||||
|
||||
The -lwolfssl will link the wolfSSL Libraries to your program
|
||||
|
||||
|
||||
The makefile for the server is going to be similar to that of the client. If the user wants separate makefiles just make a use the same set up of the client makefile and replace every instance of client-psk with server-psk. To combine make files just add a server-psk with similar ending to each time client-psk is referenced and change the target. There will also need to be a target for when compiling all targets.
|
||||
The makefile for the server is going to be similar to that of the client. If the user wants separate makefiles just make and use the same set up of the client makefile and replace every instance of client-psk with server-psk. To combine make files just add a server-psk with similar ending to each time client-psk is referenced and change the target. There will also need to be a target for when compiling all targets.
|
||||
|
||||
```
|
||||
```
|
||||
all: server-psk client-psk
|
||||
|
||||
server-psk: server-psk.c
|
||||
$(CC) -Wall -o server-psk server-psk.c -lwolfssl
|
||||
```
|
||||
```
|
||||
|
||||
## Nonblocking psk
|
||||
###### What is nonblocking?
|
||||
|
@ -411,7 +413,7 @@ When a socket is setup as non-blocking, reads and writes to the socket do not ca
|
|||
|
||||
|
||||
|
||||
5. Before adding the NonblockingSSL_Connect function into our code we much add a tcp_select function that will be used by the NonblockingSSL_Connect. This is done by adding:
|
||||
5. Before adding the NonblockingSSL_Connect function into our code we must add a tcp_select function that will be used by the NonblockingSSL_Connect. This is done by adding:
|
||||
|
||||
```
|
||||
/*
|
||||
|
@ -426,29 +428,28 @@ When a socket is setup as non-blocking, reads and writes to the socket do not ca
|
|||
|
||||
static inline int tcp_select(int socketfd, int to_sec)
|
||||
{
|
||||
fd_set recvfds, errfds;
|
||||
int nfds = socketfd + 1;
|
||||
struct timeval timeout = { (to_sec > 0) ? to_sec : 0, 0};
|
||||
int result;
|
||||
|
||||
FD_ZERO(&recvfds);
|
||||
FD_SET(socketfd, &recvfds);
|
||||
FD_ZERO(&errfds);
|
||||
FD_SET(socketfd, &errfds);
|
||||
|
||||
result = select(nfds, &recvfds, NULL, &errfds, &timeout);
|
||||
|
||||
if (result == 0)
|
||||
return TEST_TIMEOUT;
|
||||
else if (result > 0) {
|
||||
if (FD_ISSET(socketfd, &recvfds))
|
||||
return TEST_RECV_READY;
|
||||
else if(FD_ISSET(socketfd, &errfds))
|
||||
return TEST_ERROR_READY;
|
||||
}
|
||||
|
||||
return TEST_SELECT_FAIL;
|
||||
}
|
||||
fd_set recvfds, errfds;
|
||||
int nfds = socketfd + 1;
|
||||
struct timeval timeout = { (to_sec > 0) ? to_sec : 0, 0};
|
||||
int result;
|
||||
|
||||
FD_ZERO(&recvfds);
|
||||
FD_SET(socketfd, &recvfds);
|
||||
FD_ZERO(&errfds);
|
||||
FD_SET(socketfd, &errfds);
|
||||
|
||||
result = select(nfds, &recvfds, NULL, &errfds, &timeout);
|
||||
|
||||
if (result == 0)
|
||||
return TEST_TIMEOUT;
|
||||
else if (result > 0) {
|
||||
if (FD_ISSET(socketfd, &recvfds))
|
||||
return TEST_RECV_READY;
|
||||
else if(FD_ISSET(socketfd, &errfds))
|
||||
return TEST_ERROR_READY;
|
||||
}
|
||||
return TEST_SELECT_FAIL;
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
@ -494,7 +495,7 @@ When a socket is setup as non-blocking, reads and writes to the socket do not ca
|
|||
}
|
||||
}
|
||||
```
|
||||
##Tutorial for adding nonblocking to a Server.
|
||||
## Tutorial for adding nonblocking to a Server.
|
||||
|
||||
Nonblocking on the server side allows for switching between multiple client connections when reading and writing without closing them.
|
||||
|
||||
|
@ -511,6 +512,7 @@ Nonblocking on the server side allows for switching between multiple client conn
|
|||
>Both F_SETFL and O_NONBLOCK are constants from the fcntl.h file.
|
||||
|
||||
4. Include a function to select tcp. What this function does is it checks file descriptors for readiness of reading, writing, for pending exceptions, and for timeout. The timeout variable needs to point to struct timeval type. If the timeval members are 0 then the function does not block. The function and its input parameters are listed below.
|
||||
|
||||
``select(int nfds, fd_set* read, fd_set* write, fd_set* exception, struct timeval* time)``
|
||||
|
||||
>For the example server we do not consider write when selecting the tcp so it is set to NULL. For ease the example code uses enumerated values for which state the function select returns. This then makes the next loop discussed easier.
|
||||
|
@ -591,4 +593,4 @@ The main thread accepts clients and for each client accepted a new thread is spa
|
|||
}
|
||||
```
|
||||
|
||||
5. Void* arg is the argument that gets passed into wolfssal_thread when pthread_create is called. In this example that argument is used to pass the socket value that the client for the current thread is on.
|
||||
5. Void* arg is the argument that gets passed into wolfssl_thread when pthread_create is called. In this example that argument is used to pass the socket value that the client for the current thread is on.
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
#define SERV_PORT 11111 /* default port*/
|
||||
|
||||
/*
|
||||
* enum used for tcp_select function
|
||||
* enum used for tcp_select function
|
||||
*/
|
||||
enum {
|
||||
TEST_SELECT_FAIL,
|
||||
|
@ -45,80 +45,11 @@ enum {
|
|||
TEST_ERROR_READY
|
||||
};
|
||||
|
||||
|
||||
static inline int tcp_select(int socketfd, int to_sec)
|
||||
{
|
||||
fd_set recvfds, errfds;
|
||||
int nfds = socketfd + 1;
|
||||
struct timeval timeout = { (to_sec > 0) ? to_sec : 0, 0};
|
||||
int result;
|
||||
|
||||
FD_ZERO(&recvfds);
|
||||
FD_SET(socketfd, &recvfds);
|
||||
FD_ZERO(&errfds);
|
||||
FD_SET(socketfd, &errfds);
|
||||
|
||||
result = select(nfds, &recvfds, NULL, &errfds, &timeout);
|
||||
|
||||
if (result == 0)
|
||||
return TEST_TIMEOUT;
|
||||
else if (result > 0) {
|
||||
if (FD_ISSET(socketfd, &recvfds))
|
||||
return TEST_RECV_READY;
|
||||
else if(FD_ISSET(socketfd, &errfds))
|
||||
return TEST_ERROR_READY;
|
||||
}
|
||||
|
||||
return TEST_SELECT_FAIL;
|
||||
}
|
||||
|
||||
/*
|
||||
* sets up and uses nonblocking protocols using wolfssl
|
||||
*/
|
||||
static int NonBlockingSSL_Connect(WOLFSSL* ssl)
|
||||
{
|
||||
int ret, error, sockfd, select_ret, currTimeout;
|
||||
|
||||
ret = wolfSSL_connect(ssl);
|
||||
error = wolfSSL_get_error(ssl, 0);
|
||||
sockfd = (int)wolfSSL_get_fd(ssl);
|
||||
|
||||
while (ret != SSL_SUCCESS && (error == SSL_ERROR_WANT_READ ||
|
||||
error == SSL_ERROR_WANT_WRITE)) {
|
||||
currTimeout = 1;
|
||||
|
||||
if (error == SSL_ERROR_WANT_READ)
|
||||
printf("... client would read block\n");
|
||||
else
|
||||
printf("... client would write block\n");
|
||||
|
||||
select_ret = tcp_select(sockfd, currTimeout);
|
||||
|
||||
if ((select_ret == TEST_RECV_READY) ||
|
||||
(select_ret == TEST_ERROR_READY)) {
|
||||
ret = wolfSSL_connect(ssl);
|
||||
error = wolfSSL_get_error(ssl, 0);
|
||||
}
|
||||
else if (select_ret == TEST_TIMEOUT) {
|
||||
error = SSL_ERROR_WANT_READ;
|
||||
}
|
||||
else {
|
||||
error = SSL_FATAL_ERROR;
|
||||
}
|
||||
}
|
||||
if (ret != SSL_SUCCESS){
|
||||
printf("SSL_connect failed");
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
*psk client set up.
|
||||
*/
|
||||
static inline unsigned int My_Psk_Client_Cb(WOLFSSL* ssl, const char* hint,
|
||||
char* identity, unsigned int id_max_len, unsigned char* key,
|
||||
char* identity, unsigned int id_max_len, unsigned char* key,
|
||||
unsigned int key_max_len)
|
||||
{
|
||||
(void)ssl;
|
||||
|
@ -138,59 +69,38 @@ static inline unsigned int My_Psk_Client_Cb(WOLFSSL* ssl, const char* hint,
|
|||
return 4;
|
||||
}
|
||||
|
||||
/*
|
||||
* this function will send the inputted string to the server and then
|
||||
* recieve the string from the server outputing it to the termial
|
||||
*/
|
||||
int SendReceive(WOLFSSL* ssl)
|
||||
{
|
||||
char sendline[MAXLINE]="Hello Server"; /* string to send to the server */
|
||||
char recvline[MAXLINE]; /* string received from the server */
|
||||
|
||||
/* write string to the server */
|
||||
if (wolfSSL_write(ssl, sendline, MAXLINE) != sizeof(sendline)) {
|
||||
printf("Write Error to Server\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* flags if the Server stopped before the client could end */
|
||||
if (wolfSSL_read(ssl, recvline, MAXLINE) < 0 ) {
|
||||
printf("Client: Server Terminated Prematurely!\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* show message from the server */
|
||||
printf("Server Message: %s\n", recvline);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int sockfd, ret;
|
||||
int sockfd, ret, error, select_ret, currTimeout;
|
||||
int nfds;
|
||||
int result;
|
||||
char sendline[MAXLINE]="Hello Server"; /* string to send to the server */
|
||||
char recvline[MAXLINE]; /* string received from the server */
|
||||
fd_set recvfds, errfds;
|
||||
WOLFSSL_CTX* ctx;
|
||||
WOLFSSL* ssl;
|
||||
struct sockaddr_in servaddr;;
|
||||
struct timeval timeout;
|
||||
struct sockaddr_in servaddr;
|
||||
|
||||
/* must include an ip address of this will flag */
|
||||
if (argc != 2) {
|
||||
printf("Usage: tcpClient <IPaddress>\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
wolfSSL_Init(); /* initialize wolfSSL */
|
||||
|
||||
|
||||
|
||||
|
||||
/* create and initialize WOLFSSL_CTX structure */
|
||||
if ((ctx = wolfSSL_CTX_new(wolfTLSv1_2_client_method())) == NULL) {
|
||||
fprintf(stderr, "SSL_CTX_new error.\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));
|
||||
|
||||
|
@ -199,23 +109,23 @@ int main(int argc, char **argv)
|
|||
|
||||
/* 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");
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* set up pre shared keys */
|
||||
wolfSSL_CTX_set_psk_client_callback(ctx,My_Psk_Client_Cb);
|
||||
|
||||
/* attempts to make a connection on a socket */
|
||||
ret = connect(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr));
|
||||
|
||||
|
||||
if (ret != 0) {
|
||||
printf("Connection Error\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* create wolfSSL object after each tcp connect */
|
||||
if ((ssl = wolfSSL_new(ctx)) == NULL) {
|
||||
fprintf(stderr, "wolfSSL_new error.\n");
|
||||
|
@ -228,7 +138,7 @@ int main(int argc, char **argv)
|
|||
/* tell wolfSSL that nonblocking is going to be used */
|
||||
wolfSSL_set_using_nonblock(ssl, 1);
|
||||
|
||||
/* invokes the fcntl callable service to get the file status
|
||||
/* invokes the fcntl callable service to get the file status
|
||||
* flags for a file. checks if it returns an error, if it does
|
||||
* stop program */
|
||||
int flags = fcntl(sockfd, F_GETFL, 0);
|
||||
|
@ -238,35 +148,99 @@ int main(int argc, char **argv)
|
|||
}
|
||||
|
||||
/* invokes the fcntl callable service to set file status flags.
|
||||
* Do not block an open, a read, or a write on the file
|
||||
* (do not wait for terminal input. If an error occurs,
|
||||
* stop program*/
|
||||
* Do not block an open, a read, or a write on the file
|
||||
* (do not wait for terminal input. If an error occurs,
|
||||
* stop program */
|
||||
flags = fcntl(sockfd, F_SETFL, flags | O_NONBLOCK);
|
||||
if (flags < 0) {
|
||||
printf("fcntl set failed\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* setting up and running nonblocking socket */
|
||||
ret = NonBlockingSSL_Connect(ssl);
|
||||
if (ret != 0) {
|
||||
return 1;
|
||||
ret = wolfSSL_connect(ssl);
|
||||
error = wolfSSL_get_error(ssl, 0);
|
||||
|
||||
while (ret != SSL_SUCCESS && (error == SSL_ERROR_WANT_READ ||
|
||||
error == SSL_ERROR_WANT_WRITE)) {
|
||||
currTimeout = 1;
|
||||
|
||||
if (error == SSL_ERROR_WANT_READ) {
|
||||
printf("... client would read block\n");
|
||||
}
|
||||
else {
|
||||
printf("... client would write block\n");
|
||||
}
|
||||
|
||||
timeout.tv_sec = currTimeout;
|
||||
timeout.tv_usec = 0; /* setting to 0 microseconds */
|
||||
sockfd = (int)wolfSSL_get_fd(ssl);
|
||||
|
||||
FD_ZERO(&recvfds);
|
||||
FD_SET(sockfd, &recvfds);
|
||||
FD_ZERO(&errfds);
|
||||
FD_SET(sockfd, &errfds);
|
||||
|
||||
nfds = sockfd + 1;
|
||||
|
||||
result = select(nfds, &recvfds, NULL, &errfds, &timeout);
|
||||
|
||||
if (result == 0) {
|
||||
select_ret = TEST_TIMEOUT;
|
||||
}
|
||||
else if (result > 0) {
|
||||
if (FD_ISSET(sockfd, &recvfds)) {
|
||||
select_ret = TEST_RECV_READY;
|
||||
}
|
||||
else if(FD_ISSET(sockfd, &errfds)) {
|
||||
select_ret = TEST_ERROR_READY;
|
||||
}
|
||||
}
|
||||
else {
|
||||
select_ret = TEST_SELECT_FAIL;
|
||||
}
|
||||
|
||||
if ((select_ret == TEST_RECV_READY) ||
|
||||
(select_ret == TEST_ERROR_READY)) {
|
||||
ret = wolfSSL_connect(ssl);
|
||||
error = wolfSSL_get_error(ssl, 0);
|
||||
}
|
||||
else if (select_ret == TEST_TIMEOUT) {
|
||||
error = SSL_ERROR_WANT_READ;
|
||||
}
|
||||
else {
|
||||
error = SSL_FATAL_ERROR;
|
||||
}
|
||||
}
|
||||
if (ret != SSL_SUCCESS){
|
||||
printf("SSL_connect failed");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* takes inputting string and outputs it to the server */
|
||||
ret = SendReceive(ssl);
|
||||
if (ret != 0) {
|
||||
/* write string to the server */
|
||||
if (wolfSSL_write(ssl, sendline, MAXLINE) != sizeof(sendline)) {
|
||||
printf("Write Error to Server\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* flags if the Server stopped before the client could end */
|
||||
if (wolfSSL_read(ssl, recvline, MAXLINE) < 0 ) {
|
||||
printf("Client: Server Terminated Prematurely!\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* show message from the server */
|
||||
printf("Server Message: %s\n", recvline);
|
||||
|
||||
/* cleanup */
|
||||
wolfSSL_free(ssl);
|
||||
|
||||
/* when completely done using SSL/TLS, free the
|
||||
/* when completely done using SSL/TLS, free the
|
||||
* wolfssl_ctx object */
|
||||
wolfSSL_CTX_free(ctx);
|
||||
wolfSSL_Cleanup();
|
||||
|
||||
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
|
|
@ -40,7 +40,7 @@
|
|||
*psk client set up.
|
||||
*/
|
||||
static inline unsigned int My_Psk_Client_Cb(WOLFSSL* ssl, const char* hint,
|
||||
char* identity, unsigned int id_max_len, unsigned char* key,
|
||||
char* identity, unsigned int id_max_len, unsigned char* key,
|
||||
unsigned int key_max_len)
|
||||
{
|
||||
(void)ssl;
|
||||
|
@ -60,36 +60,11 @@ static inline unsigned int My_Psk_Client_Cb(WOLFSSL* ssl, const char* hint,
|
|||
return 4;
|
||||
}
|
||||
|
||||
/*
|
||||
* this function will send the inputted string to the server and then
|
||||
* recieve the string from the server outputing it to the termial
|
||||
*/
|
||||
int SendReceive(WOLFSSL* ssl)
|
||||
{
|
||||
int main(int argc, char **argv){
|
||||
|
||||
int sockfd, sock, ret;
|
||||
char sendline[MAXLINE]="Hello Server"; /* string to send to the server */
|
||||
char recvline[MAXLINE]; /* string received from the server */
|
||||
|
||||
/* write string to the server */
|
||||
if (wolfSSL_write(ssl, sendline, MAXLINE) != sizeof(sendline)) {
|
||||
printf("Write Error to Server\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* flags if the Server stopped before the client could end */
|
||||
if (wolfSSL_read(ssl, recvline, MAXLINE) < 0 ) {
|
||||
printf("Client: Server Terminated Prematurely!\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* show message from the server */
|
||||
printf("Server Message: %s\n", recvline);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv){
|
||||
|
||||
int sockfd, sock, ret;
|
||||
WOLFSSL* ssl;
|
||||
WOLFSSL* sslResume = 0;
|
||||
WOLFSSL_SESSION* session = 0;
|
||||
|
@ -101,19 +76,19 @@ int main(int argc, char **argv){
|
|||
printf("Usage: tcpClient <IPaddress>\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
wolfSSL_Init(); /* initialize wolfSSL */
|
||||
|
||||
|
||||
/* create and initialize WOLFSSL_CTX structure */
|
||||
if ((ctx = wolfSSL_CTX_new(wolfTLSv1_2_client_method())) == NULL) {
|
||||
fprintf(stderr, "SSL_CTX_new error.\n");
|
||||
return 1;
|
||||
fprintf(stderr, "SSL_CTX_new error.\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));
|
||||
|
||||
|
@ -122,11 +97,11 @@ int main(int argc, char **argv){
|
|||
|
||||
/* converts IPv4 addresses from text to binary form */
|
||||
ret = inet_pton(AF_INET, argv[1], &servaddr.sin_addr);
|
||||
|
||||
|
||||
if (ret != 1){
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* set up pre shared keys */
|
||||
wolfSSL_CTX_set_psk_client_callback(ctx, My_Psk_Client_Cb);
|
||||
|
||||
|
@ -135,7 +110,7 @@ int main(int argc, char **argv){
|
|||
if (ret != 0 ){
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* create wolfSSL object after each tcp connect */
|
||||
if ( (ssl = wolfSSL_new(ctx)) == NULL) {
|
||||
fprintf(stderr, "wolfSSL_new error.\n");
|
||||
|
@ -146,7 +121,19 @@ int main(int argc, char **argv){
|
|||
wolfSSL_set_fd(ssl, sockfd);
|
||||
|
||||
/* takes inputting string and outputs it to the server */
|
||||
SendReceive(ssl);
|
||||
if (wolfSSL_write(ssl, sendline, sizeof(sendline)) != sizeof(sendline)) {
|
||||
printf("Write Error to Server\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* flags if the Server stopped before the client could end */
|
||||
if (wolfSSL_read(ssl, recvline, MAXLINE) < 0 ) {
|
||||
printf("Client: Server Terminated Prematurely!\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* show message from the server */
|
||||
printf("Server Message: %s\n", recvline);
|
||||
|
||||
/* Save the session ID to reuse */
|
||||
session = wolfSSL_get_session(ssl);
|
||||
|
@ -158,21 +145,19 @@ int main(int argc, char **argv){
|
|||
/* close connection */
|
||||
close(sockfd);
|
||||
|
||||
/* cleanup */
|
||||
/* cleanup without wolfSSL_Cleanup() and wolfSSL_CTX_free() for now */
|
||||
wolfSSL_free(ssl);
|
||||
wolfSSL_CTX_free(ctx);
|
||||
wolfSSL_Cleanup();
|
||||
|
||||
/*
|
||||
* resume session, start new connection and socket
|
||||
* resume session, start new connection and socket
|
||||
*/
|
||||
|
||||
/* start a new socket connection */
|
||||
sock = socket(AF_INET, SOCK_STREAM, 0);
|
||||
|
||||
|
||||
/* connect to the socket */
|
||||
ret = connect(sock, (struct sockaddr *) &servaddr, sizeof(servaddr));
|
||||
|
||||
|
||||
if (ret != 0){
|
||||
return 1;
|
||||
}
|
||||
|
@ -187,28 +172,34 @@ int main(int argc, char **argv){
|
|||
return 1;
|
||||
}
|
||||
|
||||
/* takes inputting string and outputs it to the server */
|
||||
ret = SendReceive(sslResume);
|
||||
if (ret != 0) {
|
||||
if (wolfSSL_write(sslResume, sendline, sizeof(sendline)) != sizeof(sendline)) {
|
||||
printf("Write Error to Server\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* flags if the Server stopped before the client could end */
|
||||
if (wolfSSL_read(sslResume, recvline, MAXLINE) < 0 ) {
|
||||
printf("Client: Server Terminated Prematurely!\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* show message from the server */
|
||||
printf("Server Message: %s\n", recvline);
|
||||
/* check to see if the session id is being reused */
|
||||
if (wolfSSL_session_reused(sslResume))
|
||||
if (wolfSSL_session_reused(sslResume)) {
|
||||
printf("reused session id\n");
|
||||
else
|
||||
}
|
||||
else{
|
||||
printf("didn't reuse session id!!!\n");
|
||||
|
||||
}
|
||||
/* shut down wolfSSL */
|
||||
wolfSSL_shutdown(sslResume);
|
||||
|
||||
/* shut down socket */
|
||||
close(sock);
|
||||
|
||||
/* clean up */
|
||||
wolfSSL_free(sslResume);
|
||||
/* clean up now with wolfSSL_Cleanup() */
|
||||
wolfSSL_free(sslResume);
|
||||
wolfSSL_CTX_free(ctx);
|
||||
wolfSSL_Cleanup();
|
||||
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
*psk client set up.
|
||||
*/
|
||||
static inline unsigned int My_Psk_Client_Cb(WOLFSSL* ssl, const char* hint,
|
||||
char* identity, unsigned int id_max_len, unsigned char* key,
|
||||
char* identity, unsigned int id_max_len, unsigned char* key,
|
||||
unsigned int key_max_len)
|
||||
{
|
||||
(void)ssl;
|
||||
|
@ -58,36 +58,11 @@ static inline unsigned int My_Psk_Client_Cb(WOLFSSL* ssl, const char* hint,
|
|||
return 4;
|
||||
}
|
||||
|
||||
/*
|
||||
* this function will send the inputted string to the server and then
|
||||
* recieve the string from the server outputing it to the termial
|
||||
*/
|
||||
int SendReceive(WOLFSSL* ssl)
|
||||
{
|
||||
char sendline[MAXLINE]="Hello Server"; /* string to send to the server */
|
||||
char recvline[MAXLINE]; /* string received from the server */
|
||||
|
||||
/* write string to the server */
|
||||
if (wolfSSL_write(ssl, sendline, MAXLINE) != sizeof(sendline)) {
|
||||
printf("Write Error to Server\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* flags if the Server stopped before the client could end */
|
||||
if (wolfSSL_read(ssl, recvline, MAXLINE) < 0 ) {
|
||||
printf("Client: Server Terminated Prematurely!\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* show message from the server */
|
||||
printf("Server Message: %s\n", recvline);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int ret, sockfd;
|
||||
char sendline[MAXLINE]="Hello Server"; /* string to send to the server */
|
||||
char recvline[MAXLINE]; /* string received from the server */
|
||||
WOLFSSL* ssl;
|
||||
WOLFSSL_CTX* ctx;
|
||||
struct sockaddr_in servaddr;;
|
||||
|
@ -97,19 +72,19 @@ int main(int argc, char **argv)
|
|||
printf("Usage: tcpClient <IPaddress>\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
wolfSSL_Init(); /* initialize wolfSSL */
|
||||
|
||||
|
||||
/* create and initialize WOLFSSL_CTX structure */
|
||||
if ((ctx = wolfSSL_CTX_new(wolfTLSv1_2_client_method())) == NULL) {
|
||||
fprintf(stderr, "SSL_CTX_new error.\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));
|
||||
|
||||
|
@ -120,44 +95,53 @@ int main(int argc, char **argv)
|
|||
ret = inet_pton(AF_INET, argv[1], &servaddr.sin_addr);
|
||||
|
||||
if (ret != 1) {
|
||||
printf("inet_pton error\n");
|
||||
return 1;
|
||||
printf("inet_pton error\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* set up pre shared keys */
|
||||
wolfSSL_CTX_set_psk_client_callback(ctx, My_Psk_Client_Cb);
|
||||
|
||||
|
||||
/* attempts to make a connection on a socket */
|
||||
ret = connect(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr));
|
||||
|
||||
|
||||
if (ret != 0) {
|
||||
printf("Connection Error\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* creat wolfssl object after each tcp connct */
|
||||
if ( (ssl = wolfSSL_new(ctx)) == NULL) {
|
||||
fprintf(stderr, "wolfSSL_new error.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* associate the file descriptor with the session */
|
||||
ret = wolfSSL_set_fd(ssl, sockfd);
|
||||
|
||||
if (ret != SSL_SUCCESS){
|
||||
|
||||
if (ret != SSL_SUCCESS) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* takes inputting string and outputs it to the server */
|
||||
ret = SendReceive(ssl);
|
||||
if(ret != 0){
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* write string to the server */
|
||||
if (wolfSSL_write(ssl, sendline, MAXLINE) != sizeof(sendline)) {
|
||||
printf("Write Error to Server\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* check if server ended before client could read a response */
|
||||
if (wolfSSL_read(ssl, recvline, MAXLINE) < 0 ) {
|
||||
printf("Client: Server Terminated Prematurely!\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* show message from the server */
|
||||
printf("Server Message: %s\n", recvline);
|
||||
|
||||
/* cleanup */
|
||||
wolfSSL_free(ssl);
|
||||
|
||||
/* when completely done using SSL/TLS, free the
|
||||
/* when completely done using SSL/TLS, free the
|
||||
* wolfssl_ctx object */
|
||||
wolfSSL_CTX_free(ctx);
|
||||
wolfSSL_Cleanup();
|
||||
|
|
|
@ -34,34 +34,15 @@
|
|||
#define SERV_PORT 11111
|
||||
|
||||
/*
|
||||
* this function will send the inputted string to the server and then
|
||||
* this function will send the inputted string to the server and then
|
||||
* recieve the string from the server outputing it to the termial
|
||||
*/
|
||||
int SendReceive(int sockfd)
|
||||
{
|
||||
char sendline[MAXLINE]="Hello Server"; /* string to send to the server */
|
||||
char recvline[MAXLINE]; /* string received from the server */
|
||||
|
||||
/* write string to the server */
|
||||
if (write(sockfd, sendline, strlen(sendline)) != sizeof(sendline)) {
|
||||
printf("Write Error to Server\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* flags if the server stopped before the client could end */
|
||||
if (read(sockfd, recvline, MAXLINE) == 0) {
|
||||
printf("Client: Server Terminated Prematurely!\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("Server Message: %s\n", recvline);
|
||||
|
||||
return 0;
|
||||
}
|
||||
*/
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int sockfd, ret;
|
||||
int sockfd, ret;
|
||||
char sendline[MAXLINE]="Hello Server"; /* string to send to the server */
|
||||
char recvline[MAXLINE]; /* string received from the server */
|
||||
struct sockaddr_in servaddr;
|
||||
|
||||
/* must include an ip address or this will flag */
|
||||
|
@ -72,17 +53,17 @@ int main(int argc, char **argv)
|
|||
|
||||
/* create a stream socket using tcp,internet protocal IPv4,
|
||||
* full-duplex stream */
|
||||
sockfd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
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);
|
||||
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("Not a Valid network address");
|
||||
return 1;
|
||||
|
@ -90,19 +71,28 @@ int main(int argc, char **argv)
|
|||
|
||||
/* attempts to make a connection on a socket */
|
||||
ret = connect(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr));
|
||||
|
||||
|
||||
if (ret != 0) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* takes inputting string and outputs it to the server */
|
||||
ret = SendReceive(sockfd);
|
||||
if (ret != 0){
|
||||
printf("Send Recieve Error");
|
||||
/* write string to the server */
|
||||
if (write(sockfd, sendline, strlen(sendline)) != strlen(sendline)) {
|
||||
printf("Write Error to Server\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* flags if the server stopped before the client could end */
|
||||
if (read(sockfd, recvline, MAXLINE) == 0) {
|
||||
printf("Client: Server Terminated Prematurely!\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("Server Message: %s\n", recvline);
|
||||
|
||||
/* close socket and connection */
|
||||
close(sockfd);
|
||||
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* server-psk-nonblocking.c
|
||||
* A server ecample using a TCP connection with PSK security and non blocking.
|
||||
*
|
||||
* A server ecample using a TCP connection with PSK security and non blocking.
|
||||
*
|
||||
* Copyright (C) 2006-2015 wolfSSL Inc.
|
||||
*
|
||||
* This file is part of wolfSSL. (formerly known as CyaSSL)
|
||||
|
@ -47,118 +47,6 @@ enum{
|
|||
TEST_ERROR_READY
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Pulled in from wolfssl/test.h
|
||||
* Select the tcp, used when nonblocking. Checks the status of the connection.
|
||||
*/
|
||||
int tcp_select(int sockfd, int to_sec)
|
||||
{
|
||||
fd_set recvfds, errfds;
|
||||
int nfds = sockfd + 1;
|
||||
struct timeval timeout = {to_sec, 0};
|
||||
int result;
|
||||
|
||||
/* reset socket values */
|
||||
FD_ZERO(&recvfds);
|
||||
FD_SET(sockfd, &recvfds);
|
||||
FD_ZERO(&errfds);
|
||||
FD_SET(sockfd, &errfds);
|
||||
|
||||
result = select(nfds, &recvfds, NULL, &errfds, &timeout);
|
||||
|
||||
/* logic for which enumerated value is returned */
|
||||
if (result == 0)
|
||||
return TEST_TIMEOUT;
|
||||
else if (result > 0) {
|
||||
if (FD_ISSET(sockfd, &recvfds))
|
||||
return TEST_RECV_READY;
|
||||
else if (FD_ISSET(sockfd, &errfds))
|
||||
return TEST_ERROR_READY;
|
||||
}
|
||||
|
||||
return TEST_SELECT_FAIL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Pulled in from examples/server/server.c
|
||||
* Function to handle nonblocking. Loops until tcp_select notifies that it's
|
||||
* ready for action.
|
||||
*/
|
||||
int NonBlockingSSL(WOLFSSL* ssl)
|
||||
{
|
||||
int ret;
|
||||
int error;
|
||||
int select_ret;
|
||||
int sockfd = wolfSSL_get_fd(ssl);
|
||||
ret = wolfSSL_accept(ssl);
|
||||
error = wolfSSL_get_error(ssl, 0);
|
||||
while (ret != SSL_SUCCESS && (error == SSL_ERROR_WANT_READ ||
|
||||
error == SSL_ERROR_WANT_WRITE)) {
|
||||
int currTimeout = 1;
|
||||
|
||||
/* print out for user notification */
|
||||
if (error == SSL_ERROR_WANT_READ)
|
||||
printf("... server would read block\n");
|
||||
else
|
||||
printf("... server would write block\n");
|
||||
|
||||
select_ret = tcp_select(sockfd, currTimeout);
|
||||
|
||||
/* if tcp_select signals ready try to accept otherwise continue loop*/
|
||||
if ((select_ret == TEST_RECV_READY) ||
|
||||
(select_ret == TEST_ERROR_READY)) {
|
||||
ret = wolfSSL_accept(ssl);
|
||||
error = wolfSSL_get_error(ssl, 0);
|
||||
}
|
||||
else if (select_ret == TEST_TIMEOUT) {
|
||||
error = SSL_ERROR_WANT_READ;
|
||||
}
|
||||
else {
|
||||
error = SSL_FATAL_ERROR;
|
||||
}
|
||||
}
|
||||
/* faliure to accept */
|
||||
if (ret != SSL_SUCCESS) {
|
||||
printf("Fatal error : SSL_accept failed\n");
|
||||
ret = SSL_FATAL_ERROR;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Handles response to client.
|
||||
*/
|
||||
int respond(WOLFSSL* ssl)
|
||||
{
|
||||
int n; /* length of string read */
|
||||
char buf[MAXLINE]; /* string read from client */
|
||||
char response[] = "I hear ya for shizzle";
|
||||
|
||||
memset(buf, 0, MAXLINE);
|
||||
do {
|
||||
if (NonBlockingSSL(ssl) != SSL_SUCCESS)
|
||||
return 1;
|
||||
n = wolfSSL_read(ssl, buf, MAXLINE);
|
||||
if (n > 0) {
|
||||
printf("%s\n", buf);
|
||||
}
|
||||
}
|
||||
while(n < 0);
|
||||
|
||||
if (NonBlockingSSL(ssl) != SSL_SUCCESS)
|
||||
return 1;
|
||||
if (wolfSSL_write(ssl, response, strlen(response)) != strlen(response)) {
|
||||
printf("Fatal error : respond: write error\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Used for finding psk value.
|
||||
*/
|
||||
|
@ -168,8 +56,9 @@ static inline unsigned int my_psk_server_cb(WOLFSSL* ssl, const char* identity,
|
|||
(void)ssl;
|
||||
(void)key_max_len;
|
||||
|
||||
if (strncmp(identity, "Client_identity", 15) != 0)
|
||||
if (strncmp(identity, "Client_identity", 15) != 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
key[0] = 26;
|
||||
key[1] = 43;
|
||||
|
@ -182,28 +71,41 @@ static inline unsigned int my_psk_server_cb(WOLFSSL* ssl, const char* identity,
|
|||
|
||||
int main()
|
||||
{
|
||||
int listenfd, connfd;
|
||||
int opt;
|
||||
struct sockaddr_in cliAddr, servAddr;
|
||||
char buff[MAXLINE];
|
||||
int n; /* length of string read */
|
||||
int ret;
|
||||
int error;
|
||||
int result;
|
||||
int select_ret;
|
||||
int sockfd;
|
||||
int nfds;
|
||||
int currTimeout = 1;
|
||||
int listenfd, connfd;
|
||||
int opt;
|
||||
char buff[MAXLINE]; /* buffer for tcp connection */
|
||||
char buf[MAXLINE]; /* string read from client */
|
||||
char response[] = "I hear ya for shizzle";
|
||||
fd_set recvfds, errfds;
|
||||
socklen_t cliLen;
|
||||
WOLFSSL_CTX* ctx;
|
||||
struct sockaddr_in cliAddr, servAddr;
|
||||
struct timeval timeout = {currTimeout, 0};
|
||||
|
||||
wolfSSL_Init();
|
||||
|
||||
|
||||
if ((ctx = wolfSSL_CTX_new(wolfSSLv23_server_method())) == NULL) {
|
||||
printf("Fatal error : wolfSSL_CTX_new error\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* use psk suite for security */
|
||||
/* use psk suite for security */
|
||||
wolfSSL_CTX_set_psk_server_callback(ctx, my_psk_server_cb);
|
||||
wolfSSL_CTX_use_psk_identity_hint(ctx, "wolfssl server");
|
||||
if (wolfSSL_CTX_set_cipher_list(ctx, "PSK-AES128-CBC-SHA256")
|
||||
!= SSL_SUCCESS)
|
||||
!= SSL_SUCCESS) {
|
||||
printf("Fatal error : server can't set cipher list\n");
|
||||
}
|
||||
|
||||
/* find a socket */
|
||||
/* find a socket */
|
||||
listenfd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (listenfd < 0) {
|
||||
printf("Fatal error : socket error\n");
|
||||
|
@ -221,66 +123,203 @@ int main()
|
|||
if (setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, (const void*)&opt,
|
||||
sizeof(int)) != 0) {
|
||||
printf("Fatal error : setsockopt errer");
|
||||
return 1;
|
||||
return 1;
|
||||
}
|
||||
if (bind(listenfd, (struct sockaddr *) &servAddr, sizeof(servAddr)) < 0) {
|
||||
printf("Fatal error : bind error\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* main loop for accepting and responding to clients */
|
||||
for ( ; ; ) {
|
||||
WOLFSSL* ssl;
|
||||
|
||||
/* listen to the socket */
|
||||
|
||||
/* listen to the socket */
|
||||
if (listen(listenfd, LISTENQ) < 0) {
|
||||
printf("Fatal error : listen error\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
cliLen = sizeof(cliAddr);
|
||||
connfd = accept(listenfd, (struct sockaddr *) &cliAddr, &cliLen);
|
||||
if (connfd < 0) {
|
||||
if (errno != EINTR) {
|
||||
printf("Fatal error : accept error\n");
|
||||
return 1;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
printf("Connection from %s, port %d\n",
|
||||
inet_ntop(AF_INET, &cliAddr.sin_addr, buff, sizeof(buff)),
|
||||
ntohs(cliAddr.sin_port));
|
||||
|
||||
inet_ntop(AF_INET, &cliAddr.sin_addr, buff, sizeof(buff)),
|
||||
ntohs(cliAddr.sin_port));
|
||||
|
||||
/* create WOLFSSL object */
|
||||
if ((ssl = wolfSSL_new(ctx)) == NULL) {
|
||||
printf("Fatal error : wolfSSL_new error\n");
|
||||
return 1;
|
||||
return 1;
|
||||
}
|
||||
wolfSSL_set_fd(ssl, connfd);
|
||||
|
||||
sockfd = wolfSSL_get_fd(ssl);
|
||||
|
||||
/* set wolfSSL and socket to non blocking and respond */
|
||||
wolfSSL_set_using_nonblock(ssl, 1);
|
||||
if (fcntl(connfd, F_SETFL, O_NONBLOCK) < 0) {
|
||||
printf("Fatal error : fcntl set failed\n");
|
||||
return 1;
|
||||
}
|
||||
if (respond(ssl) != 0)
|
||||
printf("Fatal error : respond error\n");
|
||||
return 1;
|
||||
|
||||
ret = wolfSSL_accept(ssl);
|
||||
error = wolfSSL_get_error(ssl, 0);
|
||||
|
||||
/* clearing buffer for client reponse to prevent unexpected output*/
|
||||
memset(buf, 0, MAXLINE);
|
||||
do {
|
||||
|
||||
while (ret != SSL_SUCCESS && (error == SSL_ERROR_WANT_READ ||
|
||||
error == SSL_ERROR_WANT_WRITE)) {
|
||||
|
||||
/* print out for user notification */
|
||||
if (error == SSL_ERROR_WANT_READ) {
|
||||
printf("... server would read block\n");
|
||||
}
|
||||
else {
|
||||
printf("... server would write block\n");
|
||||
}
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* TCP */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
FD_ZERO(&recvfds);
|
||||
FD_SET(sockfd, &recvfds);
|
||||
FD_ZERO(&errfds);
|
||||
FD_SET(sockfd, &errfds);
|
||||
|
||||
nfds = sockfd + 1;
|
||||
result = select(nfds, &recvfds, NULL, &errfds, &timeout);
|
||||
|
||||
if (result == 0) {
|
||||
select_ret = TEST_TIMEOUT;
|
||||
}
|
||||
else if (result > 0) {
|
||||
if (FD_ISSET(sockfd, &recvfds)) {
|
||||
select_ret = TEST_RECV_READY;
|
||||
}
|
||||
else if (FD_ISSET(sockfd, &errfds)) {
|
||||
select_ret = TEST_ERROR_READY;
|
||||
}
|
||||
}
|
||||
else {
|
||||
select_ret = TEST_SELECT_FAIL;
|
||||
}
|
||||
|
||||
/* if tcp_select signals ready try to accept otherwise continue loop*/
|
||||
if ((select_ret == TEST_RECV_READY) ||
|
||||
(select_ret == TEST_ERROR_READY)) {
|
||||
ret = wolfSSL_accept(ssl);
|
||||
error = wolfSSL_get_error(ssl, 0);
|
||||
}
|
||||
else if (select_ret == TEST_TIMEOUT) {
|
||||
error = SSL_ERROR_WANT_READ;
|
||||
}
|
||||
else {
|
||||
error = SSL_FATAL_ERROR;
|
||||
}
|
||||
}
|
||||
/* faliure to accept */
|
||||
if (ret != SSL_SUCCESS) {
|
||||
printf("Fatal error : SSL_accept failed\n");
|
||||
ret = SSL_FATAL_ERROR;
|
||||
}
|
||||
|
||||
if (ret != SSL_SUCCESS) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
n = wolfSSL_read(ssl, buf, MAXLINE);
|
||||
if (n > 0) {
|
||||
printf("%s\n", buf);
|
||||
}
|
||||
}
|
||||
while(n < 0);
|
||||
|
||||
while (ret != SSL_SUCCESS && (error == SSL_ERROR_WANT_READ ||
|
||||
error == SSL_ERROR_WANT_WRITE)) {
|
||||
|
||||
/* print out for user notification */
|
||||
if (error == SSL_ERROR_WANT_READ) {
|
||||
printf("... server would read block\n");
|
||||
}
|
||||
else {
|
||||
printf("... server would write block\n");
|
||||
}
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* TCP */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
FD_ZERO(&recvfds);
|
||||
FD_SET(sockfd, &recvfds);
|
||||
FD_ZERO(&errfds);
|
||||
FD_SET(sockfd, &errfds);
|
||||
|
||||
nfds = sockfd + 1;
|
||||
result = select(nfds, &recvfds, NULL, &errfds, &timeout);
|
||||
|
||||
if (result == 0) {
|
||||
select_ret = TEST_TIMEOUT;
|
||||
}
|
||||
else if (result > 0) {
|
||||
if (FD_ISSET(sockfd, &recvfds)) {
|
||||
select_ret = TEST_RECV_READY;
|
||||
}
|
||||
else if (FD_ISSET(sockfd, &errfds)) {
|
||||
select_ret = TEST_ERROR_READY;
|
||||
}
|
||||
}
|
||||
else {
|
||||
select_ret = TEST_SELECT_FAIL;
|
||||
}
|
||||
|
||||
/* if tcp_select signals ready try to accept otherwise continue loop*/
|
||||
if ((select_ret == TEST_RECV_READY) ||
|
||||
(select_ret == TEST_ERROR_READY)) {
|
||||
ret = wolfSSL_accept(ssl);
|
||||
error = wolfSSL_get_error(ssl, 0);
|
||||
}
|
||||
else if (select_ret == TEST_TIMEOUT) {
|
||||
error = SSL_ERROR_WANT_READ;
|
||||
}
|
||||
else {
|
||||
error = SSL_FATAL_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
/* faliure to accept */
|
||||
if (ret != SSL_SUCCESS) {
|
||||
printf("Fatal error : SSL_accept failed\n");
|
||||
ret = SSL_FATAL_ERROR;
|
||||
}
|
||||
|
||||
if (ret != SSL_SUCCESS) {
|
||||
return 1;
|
||||
}
|
||||
if ( wolfSSL_write(ssl, response, strlen(response)) !=
|
||||
strlen(response)) {
|
||||
printf("Fatal error : respond: write 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;
|
||||
}
|
||||
wolfSSL_shutdown(ssl);
|
||||
wolfSSL_free(ssl);
|
||||
}
|
||||
}
|
||||
|
||||
/* free up memory used by wolfssl */
|
||||
wolfSSL_CTX_free(ctx);
|
||||
wolfSSL_Cleanup();
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* server-psk-threaded.c
|
||||
* A server ecample using a multi-threaded TCP connection with PSK security.
|
||||
*
|
||||
*
|
||||
* Copyright (C) 2006-2015 wolfSSL Inc.
|
||||
*
|
||||
* This file is part of wolfSSL. (formerly known as CyaSSL)
|
||||
|
@ -50,8 +50,9 @@ static inline unsigned int my_psk_server_cb(WOLFSSL* ssl, const char* identity,
|
|||
(void)ssl;
|
||||
(void)key_max_len;
|
||||
|
||||
if (strncmp(identity, "Client_identity", 15) != 0)
|
||||
if (strncmp(identity, "Client_identity", 15) != 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
key[0] = 26;
|
||||
key[1] = 43;
|
||||
|
@ -68,10 +69,10 @@ void* wolfssl_thread(void* fd)
|
|||
{
|
||||
WOLFSSL* ssl;
|
||||
int connfd = *((int*)fd);
|
||||
int n;
|
||||
char buf[MAXLINE];
|
||||
int n;
|
||||
char buf[MAXLINE];
|
||||
char response[] = "I hear ya for shizzle";
|
||||
|
||||
|
||||
memset(buf, 0, MAXLINE);
|
||||
|
||||
/* create WOLFSSL object */
|
||||
|
@ -79,14 +80,15 @@ void* wolfssl_thread(void* fd)
|
|||
printf("Fatal error : wolfSSL_new error");
|
||||
/* place signal for forced error exit here */
|
||||
}
|
||||
|
||||
|
||||
wolfSSL_set_fd(ssl, connfd);
|
||||
|
||||
/* respond to client */
|
||||
n = wolfSSL_read(ssl, buf, MAXLINE);
|
||||
if (n > 0) {
|
||||
printf("%s\n", buf);
|
||||
if (wolfSSL_write(ssl, response, strlen(response)) != strlen(response)) {
|
||||
if (wolfSSL_write(ssl, response, strlen(response))
|
||||
!= strlen(response)) {
|
||||
printf("Fatal error :respond: write error\n");
|
||||
/* place signal for forced error exit here */
|
||||
}
|
||||
|
@ -95,12 +97,12 @@ void* wolfssl_thread(void* fd)
|
|||
printf("Fatal error : respond: read error\n");
|
||||
/* place signal for forced error exit here */
|
||||
}
|
||||
|
||||
|
||||
/* closes the connections after responding */
|
||||
wolfSSL_shutdown(ssl);
|
||||
wolfSSL_free(ssl);
|
||||
if (close(connfd) == -1) {
|
||||
printf("Fatal error : close error\n");
|
||||
printf("Fatal error : close error\n");
|
||||
/* place signal for forced error exit here */
|
||||
}
|
||||
|
||||
|
@ -118,18 +120,20 @@ int main()
|
|||
void* wolfssl_thread(void*);
|
||||
|
||||
wolfSSL_Init();
|
||||
|
||||
if ((ctx = wolfSSL_CTX_new(wolfSSLv23_server_method())) == NULL)
|
||||
printf("Fatal error : wolfSSL_CTX_new error\n");
|
||||
|
||||
/* use psk suite for security */
|
||||
if ((ctx = wolfSSL_CTX_new(wolfSSLv23_server_method())) == NULL) {
|
||||
printf("Fatal error : wolfSSL_CTX_new error\n");
|
||||
}
|
||||
|
||||
/* use psk suite for security */
|
||||
wolfSSL_CTX_set_psk_server_callback(ctx, my_psk_server_cb);
|
||||
wolfSSL_CTX_use_psk_identity_hint(ctx, "wolfssl server");
|
||||
if (wolfSSL_CTX_set_cipher_list(ctx, "PSK-AES128-CBC-SHA256")
|
||||
!= SSL_SUCCESS)
|
||||
!= SSL_SUCCESS) {
|
||||
printf("Fatal error : server can't set cipher list");
|
||||
}
|
||||
|
||||
/* find a socket */
|
||||
/* find a socket */
|
||||
listenfd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (listenfd < 0) {
|
||||
printf("Fatal error : socket error");
|
||||
|
@ -145,17 +149,17 @@ int main()
|
|||
opt = 1;
|
||||
if (setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, (const void *)&opt,
|
||||
sizeof(int))) {
|
||||
return 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
if (bind(listenfd, (struct sockaddr *) &servAddr, sizeof(servAddr)) < 0) {
|
||||
printf("Fatal error : bind error");
|
||||
return 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* main loop for accepting and responding to clients */
|
||||
for ( ; ; ) {
|
||||
/* listen to the socket */
|
||||
/* listen to the socket */
|
||||
if (listen(listenfd, LISTENQ) < 0) {
|
||||
printf("Fatal error : listen error");
|
||||
return 1;
|
||||
|
@ -171,13 +175,13 @@ int main()
|
|||
printf("Connection from %s, port %d\n",
|
||||
inet_ntop(AF_INET, &cliAddr.sin_addr, buff, sizeof(buff)),
|
||||
ntohs(cliAddr.sin_port));
|
||||
|
||||
|
||||
if (pthread_create(&thread, NULL, &wolfssl_thread, (void*) &connfd)
|
||||
!= 0) {
|
||||
return 1;
|
||||
return 1;
|
||||
}
|
||||
if (pthread_detach(thread) != 0) {
|
||||
return 1;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* server-psk.c
|
||||
* A server ecample using a TCP connection with PSK security.
|
||||
*
|
||||
* A server ecample using a TCP connection with PSK security.
|
||||
*
|
||||
* Copyright (C) 2006-2015 wolfSSL Inc.
|
||||
*
|
||||
* This file is part of wolfSSL. (formerly known as CyaSSL)
|
||||
|
@ -36,42 +36,18 @@
|
|||
#define LISTENQ 1024
|
||||
#define SERV_PORT 11111
|
||||
|
||||
/*
|
||||
* Handles response to client.
|
||||
*/
|
||||
int respond(WOLFSSL* ssl)
|
||||
{
|
||||
int n; /* length of string read */
|
||||
char buf[MAXLINE]; /* string read from client */
|
||||
char response[] = "I hear ya for shizzle";
|
||||
memset(buf, 0, MAXLINE);
|
||||
n = wolfSSL_read(ssl, buf, MAXLINE);
|
||||
if (n > 0) {
|
||||
printf("%s\n", buf);
|
||||
if (wolfSSL_write(ssl, response, strlen(response)) > strlen(response)) {
|
||||
printf("Fatal error : respond: write error\n");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if (n < 0) {
|
||||
printf("Fatal error :espond: read error\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Identify which psk key to use.
|
||||
*/
|
||||
static unsigned int my_psk_server_cb(WOLFSSL* ssl, const char* identity, unsigned char* key,
|
||||
unsigned int key_max_len)
|
||||
static unsigned int my_psk_server_cb(WOLFSSL* ssl, const char* identity,
|
||||
unsigned char* key, unsigned int key_max_len)
|
||||
{
|
||||
(void)ssl;
|
||||
(void)key_max_len;
|
||||
|
||||
if (strncmp(identity, "Client_identity", 15) != 0)
|
||||
if (strncmp(identity, "Client_identity", 15) != 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
key[0] = 26;
|
||||
key[1] = 43;
|
||||
|
@ -83,22 +59,25 @@ static unsigned int my_psk_server_cb(WOLFSSL* ssl, const char* identity, unsigne
|
|||
|
||||
int main()
|
||||
{
|
||||
int n; /* length of string read */
|
||||
int listenfd, connfd;
|
||||
int opt;
|
||||
struct sockaddr_in cliAddr, servAddr;
|
||||
char buff[MAXLINE];
|
||||
char buf[MAXLINE]; /* string read from client */
|
||||
char response[] = "I hear ya for shizzle";
|
||||
struct sockaddr_in cliAddr, servAddr;
|
||||
socklen_t cliLen;
|
||||
WOLFSSL_CTX* ctx;
|
||||
|
||||
wolfSSL_Init();
|
||||
|
||||
|
||||
/* create ctx and configure certificates */
|
||||
if ((ctx = wolfSSL_CTX_new(wolfSSLv23_server_method())) == NULL) {
|
||||
printf("Fatal error : wolfSSL_CTX_new error\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* use psk suite for security */
|
||||
|
||||
/* use psk suite for security */
|
||||
wolfSSL_CTX_set_psk_server_callback(ctx, my_psk_server_cb);
|
||||
wolfSSL_CTX_use_psk_identity_hint(ctx, "wolfssl server");
|
||||
if (wolfSSL_CTX_set_cipher_list(ctx, "PSK-AES128-CBC-SHA256")
|
||||
|
@ -114,7 +93,7 @@ int main()
|
|||
servAddr.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
servAddr.sin_port = htons(SERV_PORT);
|
||||
|
||||
/* find a socket */
|
||||
/* find a socket */
|
||||
listenfd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (listenfd < 0) {
|
||||
printf("Fatal error : socket error\n");
|
||||
|
@ -132,17 +111,17 @@ int main()
|
|||
printf("Fatal error : bind error\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* listen to the socket */
|
||||
|
||||
/* listen to the socket */
|
||||
if (listen(listenfd, LISTENQ) < 0) {
|
||||
printf("Fatal error : listen error\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* main loop for accepting and responding to clients */
|
||||
for ( ; ; ) {
|
||||
WOLFSSL* ssl;
|
||||
|
||||
|
||||
cliLen = sizeof(cliAddr);
|
||||
connfd = accept(listenfd, (struct sockaddr *) &cliAddr, &cliLen);
|
||||
if (connfd < 0) {
|
||||
|
@ -153,20 +132,38 @@ int main()
|
|||
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;
|
||||
}
|
||||
wolfSSL_set_fd(ssl, connfd);
|
||||
if (respond(ssl) != 0)
|
||||
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 emprty */
|
||||
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;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* server-tcp.c
|
||||
* A server ecample using a TCP connection.
|
||||
*
|
||||
* A server ecample using a TCP connection.
|
||||
*
|
||||
* Copyright (C) 2006-2015 wolfSSL Inc.
|
||||
*
|
||||
* This file is part of wolfSSL. (formerly known as CyaSSL)
|
||||
|
@ -34,48 +34,32 @@
|
|||
#define LISTENQ 1024
|
||||
#define SERV_PORT 11111
|
||||
|
||||
/*
|
||||
* Fatal error detected, print out and exit.
|
||||
/*
|
||||
* Fatal error detected, print out and exit.
|
||||
*/
|
||||
void err_sys(const char *err, ...)
|
||||
{
|
||||
printf("Fatal error : %s\n", err);
|
||||
}
|
||||
|
||||
/*
|
||||
* Handles response to client.
|
||||
*/
|
||||
void respond(int sockfd)
|
||||
{
|
||||
int n; /* length of string read */
|
||||
char buf[MAXLINE]; /* string read from client */
|
||||
char response[22] = "I hear ya for shizzle";
|
||||
memset(buf, 0, MAXLINE);
|
||||
n = read(sockfd, buf, MAXLINE);
|
||||
if (n > 0) {
|
||||
printf("%s\n", buf);
|
||||
if (write(sockfd, response, 22) > 22) {
|
||||
err_sys("write error");
|
||||
}
|
||||
}
|
||||
if (n < 0) {
|
||||
err_sys("respond: read error");
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int listenfd, connfd;
|
||||
int opt;
|
||||
int listenfd, connfd;
|
||||
int opt;
|
||||
int n; /* length of string read */
|
||||
char buff[MAXLINE];
|
||||
char buf[MAXLINE]; /* string read from client */
|
||||
char response[22] = "I hear ya for shizzle";
|
||||
struct sockaddr_in cliAddr, servAddr;
|
||||
char buff[MAXLINE];
|
||||
socklen_t cliLen;
|
||||
|
||||
/* find a socket , 0 for using TCP option */
|
||||
socklen_t cliLen;
|
||||
|
||||
/* find a socket , 0 for using TCP option */
|
||||
listenfd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (listenfd < 0)
|
||||
if (listenfd < 0) {
|
||||
err_sys("socket error");
|
||||
|
||||
}
|
||||
|
||||
/* set up server address and port */
|
||||
memset(&servAddr, 0, sizeof(servAddr));
|
||||
servAddr.sin_family = AF_INET;
|
||||
|
@ -86,15 +70,16 @@ int main()
|
|||
opt = 1;
|
||||
setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, (const void*)&opt,
|
||||
sizeof(int));
|
||||
if (bind(listenfd, (struct sockaddr *) &servAddr, sizeof(servAddr)) < 0)
|
||||
if (bind(listenfd, (struct sockaddr *) &servAddr, sizeof(servAddr)) < 0) {
|
||||
err_sys("bind error");
|
||||
|
||||
/* listen to the socket */
|
||||
}
|
||||
|
||||
/* listen to the socket */
|
||||
if (listen(listenfd, LISTENQ) < 0) {
|
||||
err_sys("listen error");
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* main loop for accepting and responding to clients */
|
||||
for ( ; ; ) {
|
||||
cliLen = sizeof(cliAddr);
|
||||
|
@ -107,8 +92,19 @@ int main()
|
|||
printf("Connection from %s, port %d\n",
|
||||
inet_ntop(AF_INET, &cliAddr.sin_addr, buff, sizeof(buff)),
|
||||
ntohs(cliAddr.sin_port));
|
||||
|
||||
respond(connfd);
|
||||
|
||||
/* empty response buffer to avoid unexpected output */
|
||||
memset(buf, 0, MAXLINE);
|
||||
n = read(connfd, buf, MAXLINE);
|
||||
if (n > 0) {
|
||||
printf("%s\n", buf);
|
||||
if (write(connfd, response, 22) > 22) {
|
||||
err_sys("write error");
|
||||
}
|
||||
}
|
||||
if (n < 0) {
|
||||
err_sys("respond: read error");
|
||||
}
|
||||
/* closes the connections after responding */
|
||||
if (close(connfd) == -1) {
|
||||
err_sys("close error");
|
||||
|
|
582
tls/README.md
582
tls/README.md
|
@ -194,6 +194,7 @@ int main()
|
|||
return 0; /* Return reporting a success */
|
||||
}
|
||||
```
|
||||
<<<<<<< HEAD
|
||||
|
||||
Let's go over all that.
|
||||
|
||||
|
@ -215,6 +216,10 @@ Now we'll set up the sockets.
|
|||
|
||||
The next step is to get ahold of a socket for our server. Replace the "We'll
|
||||
fill in our work here" comment with these lines:
|
||||
=======
|
||||
Next we will add our `#define DEFAULT_PORT 11111` and the prototype for our
|
||||
`AcceptAndRead` function:
|
||||
>>>>>>> c15ac5e8a37f1eec257b547000f8b970846bff9a
|
||||
|
||||
```c
|
||||
/* Create a socket that uses an internet IPv4 address,
|
||||
|
@ -238,6 +243,7 @@ errors gracefully would obscure the purposes of the examples. As such, we make
|
|||
a nod at the importance of error handling without complicating the matter by
|
||||
putting in the full amount of effort.
|
||||
|
||||
<<<<<<< HEAD
|
||||
Anyway, now that we've opened a socket, we should update the "Cleanup and
|
||||
return" section at the bottom of `main()` to close it when we're done. It
|
||||
should look a bit like this now:
|
||||
|
@ -250,24 +256,58 @@ should look a bit like this now:
|
|||
|
||||
Now that we have a socket, let's fill out our address. Just after the "Create a
|
||||
socket [...]" block, add these lines:
|
||||
=======
|
||||
int AcceptAndRead(WOLFSSL_CTX* ctx, socklen_t sockfd, struct sockaddr_in
|
||||
clientAddr);
|
||||
```
|
||||
Now we will build our `main()` function for the program. What happens here is
|
||||
we create a WOLFSSL context pointer and a socket. We then initialize wolfSSL so
|
||||
that it can be used. After that we tell wolfSSL where our certificate and
|
||||
private key files are that we want our server to use. We then attach our socket
|
||||
to the `DEFAULT_PORT` that we defined above. The last thing to do in the main
|
||||
function is to listen for a new connection on the socket that we binded to our
|
||||
port above. When we get a new connection, we call the `AcceptAndRead` function.
|
||||
The main function should look like:
|
||||
>>>>>>> c15ac5e8a37f1eec257b547000f8b970846bff9a
|
||||
|
||||
```c
|
||||
/* Initialize the server address struct with zeros */
|
||||
memset(&servAddr, 0, sizeof(servAddr));
|
||||
|
||||
<<<<<<< HEAD
|
||||
/* Fill in the server address */
|
||||
servAddr.sin_family = AF_INET; /* using IPv4 */
|
||||
servAddr.sin_port = htons(DEFAULT_PORT); /* on DEFAULT_PORT */
|
||||
servAddr.sin_addr.s_addr = INADDR_ANY; /* from anywhere */
|
||||
```
|
||||
=======
|
||||
/*
|
||||
* Creates a socket that uses an internet IP address,
|
||||
* Sets the type to be Stream based (TCP),
|
||||
* 0 means choose the default protocol.
|
||||
*/
|
||||
socklen_t sockfd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
int loopExit = 0; /* 0 = False, 1 = True */
|
||||
int ret = 0; /* Return value */
|
||||
/* Server and client socket address structures */
|
||||
struct sockaddr_in serverAddr, clientAddr;
|
||||
>>>>>>> c15ac5e8a37f1eec257b547000f8b970846bff9a
|
||||
|
||||
That "Initialize the sever address sturuct wit zeros" step is not strictly
|
||||
necessary, but it's usually a good idea, and it doesn't complicate the example
|
||||
too much.
|
||||
|
||||
<<<<<<< HEAD
|
||||
With the address all filled out, the final stage of setting up the server is to
|
||||
bind our socket to a port and start listening for connections. In total, this
|
||||
should look like this:
|
||||
=======
|
||||
/* If positive value, the socket is valid */
|
||||
if (sockfd == -1) {
|
||||
printf("ERROR: failed to create the socket\n");
|
||||
return EXIT_FAILURE; /* Kill the server with exit status 1 */
|
||||
}
|
||||
>>>>>>> c15ac5e8a37f1eec257b547000f8b970846bff9a
|
||||
|
||||
```c
|
||||
/* Bind the server socket to our port */
|
||||
|
@ -276,18 +316,40 @@ should look like this:
|
|||
return -1;
|
||||
}
|
||||
|
||||
<<<<<<< HEAD
|
||||
/* Listen for a new connection, allow 5 pending connections */
|
||||
if (listen(sockfd, 5) == -1) {
|
||||
fprintf(stderr, "ERROR: failed to listen\n");
|
||||
return -1;
|
||||
=======
|
||||
/* Load server certificate into WOLFSSL_CTX */
|
||||
if (wolfSSL_CTX_use_certificate_file(ctx, "../certs/server-cert.pem",
|
||||
SSL_FILETYPE_PEM) != SSL_SUCCESS) {
|
||||
fprintf(stderr, "Error loading certs/server-cert.pem, please check"
|
||||
"the file.\n");
|
||||
return EXIT_FAILURE;
|
||||
>>>>>>> c15ac5e8a37f1eec257b547000f8b970846bff9a
|
||||
}
|
||||
```
|
||||
|
||||
<<<<<<< HEAD
|
||||
`bind()` makes it such that our server on `sockfd` is now visible at the
|
||||
location described by `servAddr`, and `listen()` causes us to start listening
|
||||
to `sockfd` for incoming client connections.
|
||||
|
||||
And now the setup is complete. Now we just need to deal with I/O.
|
||||
=======
|
||||
/* Load server key into WOLFSSL_CTX */
|
||||
if (wolfSSL_CTX_use_PrivateKey_file(ctx, "../certs/server-key.pem",
|
||||
SSL_FILETYPE_PEM) != SSL_SUCCESS) {
|
||||
fprintf(stderr, "Error loading certs/server-key.pem, please check"
|
||||
"the file.\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
/* Initialize the server address struct to zero */
|
||||
memset((char *)&serverAddr, 0, sizeof(serverAddr));
|
||||
>>>>>>> c15ac5e8a37f1eec257b547000f8b970846bff9a
|
||||
|
||||
We're going to keep accepting clients until one of them tells us "shutdown". To
|
||||
start, let's write up a quick skeleton for this part of the code:
|
||||
|
@ -311,11 +373,25 @@ start, let's write up a quick skeleton for this part of the code:
|
|||
|
||||
printf("Shutdown complete\n");
|
||||
```
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
Now all that is left is the `AcceptAndRead` function. This function accepts the
|
||||
new connection and passes it off to its on file descriptor `connd`. We then
|
||||
create our ssl object and direct it to our clients connection. Once thats done
|
||||
we jump into a `for ( ; ; )` loop and do a `wolfSSL_read` which will decrypt
|
||||
and send any data the client sends to our `buff` array. Once that happens we
|
||||
print the data to the console and then send a reply back to the client letting
|
||||
the client know that we reicieved their message. We then break out of the loop,
|
||||
free our ssl and close the `connd` connection since it's no longer used. We
|
||||
then `return 0` which tells our loop in main that it was successful and to
|
||||
continue listening for new connections.
|
||||
>>>>>>> c15ac5e8a37f1eec257b547000f8b970846bff9a
|
||||
|
||||
We'll deal with accepting clients first. Replace the "Accept clients here"
|
||||
comment with these lines:
|
||||
|
||||
```c
|
||||
<<<<<<< HEAD
|
||||
/* Accept client connections */
|
||||
if ((connd = accept(sockfd, (struct sockaddr*)&clientAddr, &size))
|
||||
== -1) {
|
||||
|
@ -323,6 +399,14 @@ comment with these lines:
|
|||
return -1;
|
||||
}
|
||||
```
|
||||
=======
|
||||
int AcceptAndRead(WOLFSSL_CTX* ctx, socklen_t sockfd, struct sockaddr_in
|
||||
clientAddr)
|
||||
{
|
||||
/* Create our reply message */
|
||||
const char reply[] = "I hear ya fa shizzle!\n";
|
||||
socklen_t size = sizeof(clientAddr);
|
||||
>>>>>>> c15ac5e8a37f1eec257b547000f8b970846bff9a
|
||||
|
||||
This call will block execution until a client connects to our server. At which
|
||||
point, we'll get a connection to the client through `connd`. Now that we've
|
||||
|
@ -352,10 +436,42 @@ with these lines:
|
|||
printf("Client: %s\n", buff);
|
||||
```
|
||||
|
||||
<<<<<<< HEAD
|
||||
This zeros out the buffer, then gets a message from the client and prints it
|
||||
to `stdout` so we can see it. Recall that we want to shutdown when the client
|
||||
tells us "shutdown". To accomplish this, add these lines after we print the
|
||||
message:
|
||||
=======
|
||||
printf("Using Non-Blocking I/O: %d\n", wolfSSL_get_using_nonblock(
|
||||
ssl));
|
||||
|
||||
for ( ; ; ) {
|
||||
char buff[256];
|
||||
int ret = 0;
|
||||
|
||||
/* Clear the buffer memory for anything possibly left over */
|
||||
memset(&buff, 0, sizeof(buff));
|
||||
|
||||
/* Read the client data into our buff array */
|
||||
if ((ret = wolfSSL_read(ssl, buff, sizeof(buff)-1)) > 0) {
|
||||
/* Print any data the client sends to the console */
|
||||
printf("Client: %s\n", buff);
|
||||
|
||||
/* Reply back to the client */
|
||||
if ((ret = wolfSSL_write(ssl, reply, sizeof(reply)-1))
|
||||
< 0)
|
||||
{
|
||||
printf("wolfSSL_write error = %d\n", wolfSSL_get_error(ssl, ret));
|
||||
}
|
||||
}
|
||||
/* if the client disconnects break the loop */
|
||||
else {
|
||||
if (ret < 0)
|
||||
printf("wolfSSL_read error = %d\n", wolfSSL_get_error(ssl
|
||||
,ret));
|
||||
else if (ret == 0)
|
||||
printf("The client has closed the connection.\n");
|
||||
>>>>>>> c15ac5e8a37f1eec257b547000f8b970846bff9a
|
||||
|
||||
```c
|
||||
/* Check for server shutdown command */
|
||||
|
@ -387,12 +503,19 @@ And then we send it to the client like this:
|
|||
return -1;
|
||||
}
|
||||
```
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
And with that, you should now have a basic TLS server that accepts a
|
||||
connection, reads in data from the client, sends a reply back, and closes the
|
||||
clients connection.
|
||||
>>>>>>> c15ac5e8a37f1eec257b547000f8b970846bff9a
|
||||
|
||||
And we're done.
|
||||
|
||||
We've set up a server on a TCP socket and dealt with a quick back-and-forth
|
||||
with a client.
|
||||
|
||||
<<<<<<< HEAD
|
||||
Now we just need a client.
|
||||
|
||||
#### <a name="client-tcp">Client</a>
|
||||
|
@ -402,6 +525,23 @@ there's no reason to copy anything. The finished version can be found
|
|||
[here][c-tcp].
|
||||
|
||||
Once more, we'll start with a skeleton:
|
||||
=======
|
||||
### Adding Server Multi-threading
|
||||
To add multi-threading support to the basic `tls-server.c` that we created
|
||||
above, we will be using pthreads. Multi-threading will allow the server to
|
||||
handle multiple client connections at the same time. It will pass each new
|
||||
connection off into it's own thread. To do this we will create a new function
|
||||
called `ThreadHandler`. This function will be passed off to its own thread when
|
||||
a new client connection is accepted. We will also be making some minor changes
|
||||
to our `main()` and `AcceptAndRead` functions.
|
||||
|
||||
We will start by adding a `#include <pthread.h>` followed by removing our
|
||||
`WOLFSSL_CTX* ctx` from our main() function and making it global. This will
|
||||
allow our threads to have access to it. Because we are no long passing it into
|
||||
the `AcceptAndRead` function, we need to modify the prototype function to no
|
||||
longer take a `wolfSSL_CTX` parameter. The top of your file should now look
|
||||
like:
|
||||
>>>>>>> c15ac5e8a37f1eec257b547000f8b970846bff9a
|
||||
|
||||
```c
|
||||
|
||||
|
@ -419,6 +559,15 @@ Once more, we'll start with a skeleton:
|
|||
#define DEFAULT_PORT 11111
|
||||
|
||||
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
/* Create a ctx pointer for our ssl */
|
||||
WOLFSSL_CTX* ctx;
|
||||
```
|
||||
Moving down to our `main()` function, we need to now remove `WOLFSSL_CTX* ctx`
|
||||
from the top of the function since it is now a global variable. Lastly we need
|
||||
modify the `while` loop at the bottom of `main()` to look like:
|
||||
>>>>>>> c15ac5e8a37f1eec257b547000f8b970846bff9a
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
|
@ -437,6 +586,7 @@ int main(int argc, char** argv)
|
|||
return 0; /* Return reporting a success */
|
||||
}
|
||||
```
|
||||
<<<<<<< HEAD
|
||||
|
||||
It looks quite similar to the server's skeleton, but as you can see, there are
|
||||
way fewer variables. Similarly, we're taking in command line arguments this
|
||||
|
@ -452,6 +602,37 @@ lines:
|
|||
if (argc != 2) {
|
||||
printf("usage: %s <IPv4 address>\n", argv[0]);
|
||||
return 0;
|
||||
=======
|
||||
As you can tell, when we call
|
||||
```c
|
||||
loopExit = AcceptAndRead(sockfd, clientAddr);
|
||||
```
|
||||
we are no longer passing in our `WOLFSSL_CTX` pointer since it's now global.
|
||||
|
||||
Moving on, we can now modify our `AcceptAndRead` function. This function will
|
||||
now pass accepted connections off into their own thread using `pthreads`. This
|
||||
new thread will then loop, reading and writing to the connected client. Because
|
||||
of this most of this function will be moved into the 'ThreadHandler' function.
|
||||
The `AcceptAndRead` function will now look like:
|
||||
|
||||
```c
|
||||
int AcceptAndRead(socklen_t sockfd, struct sockaddr_in clientAddr)
|
||||
{
|
||||
socklen_t size = sizeof(clientAddr);
|
||||
int connd; /* Identify and access the clients connection */
|
||||
|
||||
pthread_t thread_id;
|
||||
|
||||
/* Wait until a client connects */
|
||||
while ((connd = accept(sockfd, (struct sockaddr *)&clientAddr,
|
||||
&size))) {
|
||||
/* Pass the client into a new thread */
|
||||
if (pthread_create(&thread_id, NULL, ThreadHandler, (void *)
|
||||
&connd) < 0) {
|
||||
perror("could not create thread");
|
||||
}
|
||||
printf("Handler assigned\n");
|
||||
>>>>>>> c15ac5e8a37f1eec257b547000f8b970846bff9a
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -482,8 +663,18 @@ return" section look a bit like this:
|
|||
return 0; /* Return reporting a success */
|
||||
```
|
||||
|
||||
<<<<<<< HEAD
|
||||
Now we can fill out the address of the server we want to connect to. After the
|
||||
"Create a socket [...]" block, add these lines:
|
||||
=======
|
||||
Now that we have that passing client connections to their own threads, we need
|
||||
to create the `ThreadHandler`, this function will act just like the original
|
||||
`AcceptAndRead` function, just in it's own thread so that we can have multiple
|
||||
clients connected. In this function we will be create our `ssl` object and
|
||||
directing it at our client. It will continuously run in a `for ( ; ; )` loop,
|
||||
reading and writing to the connected client until the client disconnects. It
|
||||
should look like:
|
||||
>>>>>>> c15ac5e8a37f1eec257b547000f8b970846bff9a
|
||||
|
||||
```c
|
||||
/* Initialize the server address struct with zeros */
|
||||
|
@ -517,6 +708,7 @@ Now we can connect to the server. Add these lines next:
|
|||
}
|
||||
```
|
||||
|
||||
<<<<<<< HEAD
|
||||
`connect()` will block until the connection is successful. If something goes
|
||||
wrong, it returns a -1 that we'll catch as a fatal error.
|
||||
|
||||
|
@ -539,6 +731,31 @@ the message like this:
|
|||
if (write(sockfd, buff, len) != len) {
|
||||
fprintf(stderr, "ERROR: failed to write\n");
|
||||
return -1;
|
||||
=======
|
||||
/* Read the client data into our buff array */
|
||||
if ((ret = wolfSSL_read(ssl, buff, sizeof(buff)-1)) > 0) {
|
||||
/* Print any data the client sends to the console */
|
||||
printf("Client on Socket %d: %s\n", connd, buff);
|
||||
|
||||
/* Reply back to the client */
|
||||
if ((ret = wolfSSL_write(ssl, reply, sizeof(reply)-1))
|
||||
< 0) {
|
||||
printf("wolfSSL_write error = %d\n", wolfSSL_get_error(ssl, ret));
|
||||
}
|
||||
}
|
||||
/* if the client disconnects break the loop */
|
||||
else {
|
||||
if (ret < 0)
|
||||
printf("wolfSSL_read error = %d\n", wolfSSL_get_error(ssl
|
||||
,ret));
|
||||
else if (ret == 0)
|
||||
printf("The client has closed the connection.\n");
|
||||
|
||||
wolfSSL_free(ssl); /* Free the WOLFSSL object */
|
||||
close(connd); /* close the connected socket */
|
||||
break;
|
||||
}
|
||||
>>>>>>> c15ac5e8a37f1eec257b547000f8b970846bff9a
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -556,20 +773,48 @@ and print it to `stdout` so we can see it:
|
|||
/* Print to stdout any data the server sends */
|
||||
printf("Server: %s\n", buff);
|
||||
```
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
And that's it. You now have a TLS server using multi-threading to handle
|
||||
multiple clients in seperate threads.
|
||||
>>>>>>> c15ac5e8a37f1eec257b547000f8b970846bff9a
|
||||
|
||||
And that's everything! Our client will just be a quick one-and-done thing.
|
||||
|
||||
<<<<<<< HEAD
|
||||
#### <a name="run-tcp">Running</a>
|
||||
|
||||
`server-tcp` can be connected to by the following:
|
||||
|
||||
* `client-tcp`
|
||||
=======
|
||||
### Adding Server Non-blocking I/O
|
||||
A Nonblocking server, like the multi-threaded server, can handle multiple
|
||||
connections. It does this by moving clients to the next available socket and
|
||||
handling them all from a single thread. The benefit to this approach is that it
|
||||
there is much less memory consumption than creating a new thread for each
|
||||
connected client. Nonblocking is also much faster. 100 clients connected
|
||||
through nonblocking would be much faster than 100 clients through
|
||||
multi-threading. However, for non-blocking to work the connecting client must
|
||||
also be configured to work with non-blocking servers.
|
||||
|
||||
To add non-blocking input and ouput to our `server-tls.c` file we will need to
|
||||
create two new functions `TCPSelect` and `NonBlocking_ReadWriteAccept`. We will
|
||||
also create an enum that will be used to tell our `NonBlocking_ReadWriteAccept`
|
||||
what exactly to do, does it need to Read? Does it need to Write? or does it
|
||||
need to Accept? this is done so we can re-use the same code and not end up
|
||||
writing three more functions that practically do that same thing.
|
||||
|
||||
To start, let's create our enumerator and prototype functions. The top of your
|
||||
file should look like:
|
||||
>>>>>>> c15ac5e8a37f1eec257b547000f8b970846bff9a
|
||||
|
||||
`client-tcp` can connect to the following:
|
||||
|
||||
* `server-tcp`
|
||||
|
||||
|
||||
<<<<<<< HEAD
|
||||
|
||||
## <a name="tls">Converting to use wolfSSL</a>
|
||||
|
||||
|
@ -612,12 +857,42 @@ these lines after the other variable declarations:
|
|||
|
||||
And now we can start hooking up wolfSSL. The first thing to do is initialize
|
||||
the wolfSSL library. Beneath the variable declarations add the lines:
|
||||
=======
|
||||
/* Create an enum that we will use to tell our
|
||||
* NonBlocking_ReadWriteAccept() method what to do
|
||||
*/
|
||||
enum read_write_t {WRITE, READ, ACCEPT};
|
||||
|
||||
int AcceptAndRead(WOLFSSL_CTX* ctx, socklen_t socketfd,
|
||||
struct sockaddr_in clientAddr);
|
||||
int TCPSelect(socklen_t socketfd);
|
||||
int NonBlocking_ReadWriteAccept(WOLFSSL* ssl, socklen_t socketfd,
|
||||
enum read_write_t rw);
|
||||
```
|
||||
|
||||
We will start by modifying our `main()` function. Because we are using
|
||||
non-blocking we need to give our socket specific options. To do this, we will
|
||||
make a `setsockopt()` call just above our `wolfSSL_init()` call. It should look
|
||||
something like the following:
|
||||
|
||||
```c
|
||||
/* If positive value, the socket is valid */
|
||||
if (socketfd == -1) {
|
||||
printf("ERROR: failed to create the socket\n");
|
||||
exit(EXIT_FAILURE); /* Kill the server with exit status 1 */
|
||||
}
|
||||
/* Set the sockets options for use with nonblocking i/o */
|
||||
if (setsockopt(socketfd, SOL_SOCKET, SO_REUSEADDR, &on, len)
|
||||
< 0)
|
||||
printf("setsockopt SO_REUSEADDR failed\n");
|
||||
>>>>>>> c15ac5e8a37f1eec257b547000f8b970846bff9a
|
||||
|
||||
```c
|
||||
/* Initialize wolfSSL */
|
||||
wolfSSL_Init();
|
||||
```
|
||||
|
||||
<<<<<<< HEAD
|
||||
Next we'll set up the wolfSSL context. After the "Create a socket [...]" block
|
||||
these lines:
|
||||
|
||||
|
@ -635,6 +910,16 @@ The call to `wolfTLSv1_2_server_method()` inside the call to
|
|||
Just like we have to close `sockfd` when we're done, we'll have to cleanup
|
||||
wolfSSL. Edit the "Cleanup and return" section at the bottom of `main()` to
|
||||
look something like this:
|
||||
=======
|
||||
Now we are going to re-write our `AcceptAndRead()` function such that it now
|
||||
takes into consideration non-blocking I/O. This function will be directing our
|
||||
`ssl` object to our client. we will then use a `for ( ; ; )` loop to call our
|
||||
`NonBlocking_ReadWriteAccept()` function passing our `READ` and `WRITE` enums
|
||||
in respectively. This tells our `NonBlocking_ReadWriteAccept()` function what
|
||||
we currently want it to do; read or write.
|
||||
|
||||
The function, with more detailed comments should now look like:
|
||||
>>>>>>> c15ac5e8a37f1eec257b547000f8b970846bff9a
|
||||
|
||||
```c
|
||||
/* Cleanup and return */
|
||||
|
@ -657,12 +942,38 @@ After the "Create and initialize `WOLFSSL_CTX`" block, add these lines:
|
|||
}
|
||||
```
|
||||
|
||||
<<<<<<< HEAD
|
||||
Recall that `CERT_FILE` is one of our own defines.
|
||||
=======
|
||||
/* Direct our ssl to our clients connection */
|
||||
wolfSSL_set_fd(ssl, connd);
|
||||
|
||||
/* Sets wolfSSL_accept(ssl) */
|
||||
if(NonBlocking_ReadWriteAccept(ssl, socketfd, ACCEPT) < 0)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* loop until the connected client disconnects
|
||||
* and read in any messages the client sends
|
||||
*/
|
||||
for ( ; ; ) {
|
||||
/* Read data in when I/O is available */
|
||||
if (NonBlocking_ReadWriteAccept(ssl, socketfd, READ) == 0)
|
||||
break;
|
||||
/* Write data out when I/O is available */
|
||||
if (NonBlocking_ReadWriteAccept(ssl, socketfd, WRITE) == 0)
|
||||
break;
|
||||
}
|
||||
wolfSSL_free(ssl); /* Free the WOLFSSL object */
|
||||
}
|
||||
close(connd); /* close the connected socket */
|
||||
>>>>>>> c15ac5e8a37f1eec257b547000f8b970846bff9a
|
||||
|
||||
What the above does is load the certificate file `CERT_FILE` so that the server
|
||||
can verify itself to clients. This certificate is known to be in the PEM format
|
||||
(indicated by `SSL_FILETYPE_PEM`), and this information is then kept in `ctx`.
|
||||
|
||||
<<<<<<< HEAD
|
||||
Next we need the server to load its private key:
|
||||
|
||||
```c
|
||||
|
@ -692,11 +1003,92 @@ After we accept a new client, we need to make a wolfSSL object. Just after the
|
|||
if ((ssl = wolfSSL_new(ctx)) == NULL) {
|
||||
fprintf(stderr, "ERROR: failed to create WOLFSSL object\n");
|
||||
return -1;
|
||||
=======
|
||||
Next we will write the `NonBlocking_ReadWriteAccept()` function. This function
|
||||
in short swtiches between doing `wolfSSL_accept()`, `wolfSSL_read()`, and
|
||||
`wolfSSL_write()`. It uses a while loop to loop on the socket and assign new
|
||||
client connections to the next available socket using the `TCPSelect()`
|
||||
function we will be writing soon. It then asks each socket if it wants read or
|
||||
wants write. This function should look like:
|
||||
|
||||
```c
|
||||
/* Checks if NonBlocking I/O is wanted, if it is wanted it will
|
||||
* wait until it's available on the socket before reading or writing */
|
||||
int NonBlocking_ReadWriteAccept(WOLFSSL* ssl, socklen_t socketfd,
|
||||
enum read_write_t rw)
|
||||
{
|
||||
const char reply[] = "I hear ya fa shizzle!\n";
|
||||
char buff[256];
|
||||
int rwret = 0;
|
||||
int selectRet;
|
||||
int ret;
|
||||
|
||||
|
||||
/* Clear the buffer memory for anything possibly left
|
||||
over */
|
||||
memset(&buff, 0, sizeof(buff));
|
||||
|
||||
if (rw == READ)
|
||||
rwret = wolfSSL_read(ssl, buff, sizeof(buff)-1);
|
||||
else if (rw == WRITE)
|
||||
rwret = wolfSSL_write(ssl, reply, sizeof(reply)-1);
|
||||
else if (rw == ACCEPT)
|
||||
rwret = wolfSSL_accept(ssl);
|
||||
|
||||
if (rwret == 0) {
|
||||
printf("The client has closed the connection!\n");
|
||||
return 0;
|
||||
}
|
||||
else if (rwret != SSL_SUCCESS) {
|
||||
int error = wolfSSL_get_error(ssl, 0);
|
||||
|
||||
/* while I/O is not ready, keep waiting */
|
||||
while ((error == SSL_ERROR_WANT_READ ||
|
||||
error == SSL_ERROR_WANT_WRITE)) {
|
||||
|
||||
if (error == SSL_ERROR_WANT_READ)
|
||||
printf("... server would read block\n");
|
||||
else
|
||||
printf("... server would write block\n");
|
||||
|
||||
selectRet = TCPSelect(socketfd);
|
||||
|
||||
if ((selectRet == 1) || (selectRet == 2)) {
|
||||
if (rw == READ)
|
||||
rwret = wolfSSL_read(ssl, buff, sizeof(buff)-1);
|
||||
else if (rw == WRITE)
|
||||
rwret = wolfSSL_write(ssl, reply, sizeof(reply)-1);
|
||||
else if (rw == ACCEPT)
|
||||
rwret = wolfSSL_accept(ssl);
|
||||
|
||||
error = wolfSSL_get_error(ssl, 0);
|
||||
}
|
||||
else {
|
||||
error = SSL_FATAL_ERROR;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
/* Print any data the client sends to the console */
|
||||
if (rw == READ)
|
||||
printf("Client: %s\n", buff);
|
||||
/* Reply back to the client */
|
||||
else if (rw == WRITE) {
|
||||
if ((ret = wolfSSL_write(ssl, reply, sizeof(reply)-1)) < 0) {
|
||||
printf("wolfSSL_write error = %d\n",
|
||||
wolfSSL_get_error(ssl, ret));
|
||||
}
|
||||
>>>>>>> c15ac5e8a37f1eec257b547000f8b970846bff9a
|
||||
}
|
||||
|
||||
/* Attach wolfSSL to the socket */
|
||||
wolfSSL_set_fd(ssl, connd);
|
||||
```
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
Lastly, we just need to write our `TCPSelect()` function which will check
|
||||
whether or not any socket is ready for reading and writing and set it
|
||||
accordingly. It should look like:
|
||||
>>>>>>> c15ac5e8a37f1eec257b547000f8b970846bff9a
|
||||
|
||||
This allocates a new wolfSSL object. It will inherit all of the files we
|
||||
registered to `ctx`. After that, we give `ssl` the file descriptor `connd` to
|
||||
|
@ -710,6 +1102,11 @@ connection" section at the bottom of the loop to look like this:
|
|||
wolfSSL_free(ssl); /* Free the wolfSSL object */
|
||||
close(connd); /* Close the connection to the client */
|
||||
```
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
And now you should have a functional TCP TLS Server that uses Nonblocking input
|
||||
and output to accept multiple connections without the use of multi-threading.
|
||||
>>>>>>> c15ac5e8a37f1eec257b547000f8b970846bff9a
|
||||
|
||||
From here on, `ssl` is our new `connd` for purposes of communicating with
|
||||
clients.
|
||||
|
@ -727,8 +1124,14 @@ data [...]" block now should look like this:
|
|||
}
|
||||
```
|
||||
|
||||
<<<<<<< HEAD
|
||||
Second, we need to do something similar to our calls to `write()`. The "Reply
|
||||
back to the client" block now should look like this:
|
||||
=======
|
||||
Again, we will need to import the security library. Just like in the server,
|
||||
add an `#include` statement in your client program. Next we will need to add a
|
||||
global `cert` variable:
|
||||
>>>>>>> c15ac5e8a37f1eec257b547000f8b970846bff9a
|
||||
|
||||
```c
|
||||
/* Reply back to the client */
|
||||
|
@ -738,8 +1141,13 @@ back to the client" block now should look like this:
|
|||
}
|
||||
```
|
||||
|
||||
<<<<<<< HEAD
|
||||
And after this, we've successfully modified our TCP server to use wolfSSL for
|
||||
TLS 1.2 connections. Now we just need a client to connect with.
|
||||
=======
|
||||
Now comes changing the `ClientGreet()` function so its arguments and functions
|
||||
incorporate the security library.
|
||||
>>>>>>> c15ac5e8a37f1eec257b547000f8b970846bff9a
|
||||
|
||||
#### <a name="client-tls">Client</a>
|
||||
|
||||
|
@ -754,8 +1162,16 @@ below the "socket includes" block, add these lines:
|
|||
#include <wolfssl/ssl.h>
|
||||
```
|
||||
|
||||
<<<<<<< HEAD
|
||||
We're going to need a different definition for `CERT_FILE`, however. Just below
|
||||
the definition of `DEFAULT_PORT` add this line:
|
||||
=======
|
||||
You can think of this as, instead of just a normal read and write, it is now a
|
||||
“secure” read and write. We also need to change the call to `ClientGreet()` in
|
||||
`main()`. Instead of calling directly to it, we should make a call to a
|
||||
`Security()` that will then check the server for the correct `certs`. To do
|
||||
this, change:
|
||||
>>>>>>> c15ac5e8a37f1eec257b547000f8b970846bff9a
|
||||
|
||||
```c
|
||||
#define CERT_FILE "../certs/ca-cert.pem"
|
||||
|
@ -772,6 +1188,7 @@ these lines after the other variable declarations:
|
|||
WOLFSSL* ssl;
|
||||
```
|
||||
|
||||
<<<<<<< HEAD
|
||||
And now we can start hooking up wolfSSL. The first thing to do is initialize
|
||||
the wolfSSL library. This time we'll do it after we check our calling
|
||||
convention. Beneath the "Check for proper calling convention" block, add the
|
||||
|
@ -781,6 +1198,20 @@ lines:
|
|||
/* Initialize wolfSSL */
|
||||
wolfSSL_Init();
|
||||
```
|
||||
=======
|
||||
Now we just have to make the `Security()` function. It should look something
|
||||
like:
|
||||
|
||||
```c
|
||||
/*
|
||||
* applies TLS 1.2 security layer to data being sent.
|
||||
*/
|
||||
int Security(int sock)
|
||||
{
|
||||
WOLFSSL_CTX* ctx;
|
||||
WOLFSSL* ssl; /* create WOLFSSL object */
|
||||
int ret = 0;
|
||||
>>>>>>> c15ac5e8a37f1eec257b547000f8b970846bff9a
|
||||
|
||||
Next we set up `ctx`. After the "Create a socket [...]" block, add these
|
||||
lines:
|
||||
|
@ -821,8 +1252,17 @@ like this:
|
|||
return 0; /* Return reporting a success */
|
||||
```
|
||||
|
||||
<<<<<<< HEAD
|
||||
And this concludes the setup. Now we just need to deal with the connection to
|
||||
the server. After the "Connect to the server" block, add these lines:
|
||||
=======
|
||||
As you can see, this is where we make the call to “greet” the server. This
|
||||
function sends its certification, `../ca-certs.pem` to the server which checks
|
||||
for this. If it’s there, it establishes the connection and secures the
|
||||
information being sent and received between the two. Once this has been done,
|
||||
it frees all the data so no processes remain after the connection has been
|
||||
terminated.
|
||||
>>>>>>> c15ac5e8a37f1eec257b547000f8b970846bff9a
|
||||
|
||||
```c
|
||||
/* Create a WOLFSSL object */
|
||||
|
@ -834,6 +1274,7 @@ the server. After the "Connect to the server" block, add these lines:
|
|||
/* Attach wolfSSL to the socket */
|
||||
wolfSSL_set_fd(ssl, sockfd);
|
||||
|
||||
<<<<<<< HEAD
|
||||
/* Connect to wolfSSL on the server side */
|
||||
if (wolfSSL_connect(ssl) != SSL_SUCCESS) {
|
||||
fprintf(stderr, "ERROR: failed to connect to wolfSSL\n");
|
||||
|
@ -864,6 +1305,21 @@ at the bottom of `main()` to free `ssl`. It should now look like this:
|
|||
|
||||
Now all we have to do is update our `write()` and `read()` calls to use
|
||||
wolfSSL. The "Send the message to the server" block should now look like this:
|
||||
=======
|
||||
In case the connection to the server gets lost, and you want to save time,
|
||||
you’ll want to be able to resume the connection. In this example, we disconnect
|
||||
from the server, then reconnect to the same session afterwards, bypassing the
|
||||
handshake process and ultimately saving time. To accomplish this, you’ll need
|
||||
to add some variable declarations in `Security()`.
|
||||
|
||||
```c
|
||||
WOLFSSL_SESSION* session = 0;/* wolfssl session */
|
||||
WOLFSSL* sslResume; /* create WOLFSSL object for connection loss */
|
||||
```
|
||||
|
||||
Next we'll have to add some code to disconnect and then reconnect to the
|
||||
server. This should be added after your `ClientGreet()` call in `Security()`.
|
||||
>>>>>>> c15ac5e8a37f1eec257b547000f8b970846bff9a
|
||||
|
||||
```c
|
||||
/* Send the message to the server */
|
||||
|
@ -898,12 +1354,25 @@ And we're done. We should now have a fully functional TLS client.
|
|||
|
||||
`client-tls` can connect to the following:
|
||||
|
||||
<<<<<<< HEAD
|
||||
* `server-tls`
|
||||
* `server-tls-callback`
|
||||
* `server-tls-nonblocking`
|
||||
* `server-tls-threaded`
|
||||
=======
|
||||
/* checks to see if the new session is the same as the old session */
|
||||
if (wolfSSL_session_reused(sslResume))
|
||||
printf("Re-used session ID\n");
|
||||
else
|
||||
printf("Did not re-use session ID\n");
|
||||
>>>>>>> c15ac5e8a37f1eec257b547000f8b970846bff9a
|
||||
|
||||
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
We will aslo have to slightly alter our last `wolfSSL_free()` call. Instead of
|
||||
`wolfSSL_free(ssl);` it needs to state `wolfSSL_free(sslResume);`
|
||||
>>>>>>> c15ac5e8a37f1eec257b547000f8b970846bff9a
|
||||
|
||||
## <a name="callback">Using callbacks</a>
|
||||
|
||||
|
@ -913,8 +1382,13 @@ whichever `*-tls.c` you want and copy it to `*-tls-callback.c`. The finished
|
|||
version of the server can be found [here][s-tls-c], and the finished version of
|
||||
the client can be found [here][c-tls-c].
|
||||
|
||||
<<<<<<< HEAD
|
||||
The first step is to add `errno.h` to the list of "usual suspects". This block
|
||||
should now look like this:
|
||||
=======
|
||||
The first thing that has to be done in order to make a socket a non-blocking
|
||||
socket is to add another library to the top of the code.
|
||||
>>>>>>> c15ac5e8a37f1eec257b547000f8b970846bff9a
|
||||
|
||||
```c
|
||||
/* the usual suspects */
|
||||
|
@ -924,12 +1398,28 @@ should now look like this:
|
|||
#include <errno.h>
|
||||
```
|
||||
|
||||
<<<<<<< HEAD
|
||||
Next, we're going to need write our callbacks functions. These functions will
|
||||
be called by wolfSSL whenever it need to read or write data through the
|
||||
sockets. These callbacks can be quite sophisticated, but we're going to write
|
||||
simple callbacks that tell us how many bytes they read or write.
|
||||
|
||||
First, the read callback:
|
||||
=======
|
||||
Then we will need to add a few functions and an `enum` after the `cert`
|
||||
variable.
|
||||
|
||||
```c
|
||||
/*
|
||||
* enum used for tcp_select function
|
||||
*/
|
||||
enum {
|
||||
TEST_SELECT_FAIL,
|
||||
TEST_TIMEOUT,
|
||||
TEST_RECV_READY,
|
||||
TEST_ERROR_READY
|
||||
};
|
||||
>>>>>>> c15ac5e8a37f1eec257b547000f8b970846bff9a
|
||||
|
||||
```c
|
||||
int my_IORecv(WOLFSSL* ssl, char* buff, int sz, void* ctx)
|
||||
|
@ -1034,6 +1524,7 @@ int my_IOSend(WOLFSSL* ssl, char* buff, int sz, void* ctx)
|
|||
}
|
||||
```
|
||||
|
||||
<<<<<<< HEAD
|
||||
The most complex part of these callbacks are probably their error reporting.
|
||||
wolfSSL expects more error information that we've been doing in these examples
|
||||
until now. As such, to be responsible we have to translate the `errno` value
|
||||
|
@ -1054,6 +1545,46 @@ with zeros" block is a good place. After this, add these lines:
|
|||
And just like that wolfSSL will use our functions to send and receive data. Now
|
||||
when this program is run we should see a number of "my\_OISend: sent" and
|
||||
"my\_IORecv: recieved" lines in our output.
|
||||
=======
|
||||
We will also need to make some chances to `ClientGreet()` which should now look
|
||||
like this:
|
||||
|
||||
```c
|
||||
/*
|
||||
* clients initial contact with server. (socket to connect, security layer)
|
||||
*/
|
||||
int ClientGreet(WOLFSSL* ssl)
|
||||
{
|
||||
/* data to send to the server, data recieved from the server */
|
||||
char sendBuff[MAXDATASIZE], rcvBuff[MAXDATASIZE] = {0};
|
||||
int ret = 0;
|
||||
|
||||
printf("Message for server:\t");
|
||||
fgets(sendBuff, MAXDATASIZE, stdin);
|
||||
|
||||
if (wolfSSL_write(ssl, sendBuff, strlen(sendBuff)) != strlen(sendBuff)) {
|
||||
/* the message is not able to send, or error trying */
|
||||
ret = wolfSSL_get_error(ssl, 0);
|
||||
printf("Write error: Error: %d\n", ret);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
ret = wolfSSL_read(ssl, rcvBuff, MAXDATASIZE);
|
||||
if (ret <= 0) {
|
||||
/* the server failed to send data, or error trying */
|
||||
ret = wolfSSL_get_error(ssl, 0);
|
||||
while (ret == SSL_ERROR_WANT_READ) {
|
||||
ret = wolfSSL_read(ssl, rcvBuff, MAXDATASIZE);
|
||||
ret = wolfSSL_get_error(ssl, 0);
|
||||
}
|
||||
if (ret < 0) {
|
||||
ret = wolfSSL_get_error(ssl, 0);
|
||||
printf("Read error. Error: %d\n", ret);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
printf("Recieved: \t%s\n", rcvBuff);
|
||||
>>>>>>> c15ac5e8a37f1eec257b547000f8b970846bff9a
|
||||
|
||||
#### <a name="run-callback">Running</a>
|
||||
|
||||
|
@ -1087,6 +1618,11 @@ We'll modify the server first. Copy `server-tls.c` to a new file,
|
|||
The first change will be to our file locations. Change the defines for
|
||||
`CERT_FILE` and `KEY_FILE` to the following:
|
||||
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
Now we need to check for non-blocking in our `Security()` function. To do this,
|
||||
we change:
|
||||
>>>>>>> c15ac5e8a37f1eec257b547000f8b970846bff9a
|
||||
```c
|
||||
#define CERT_FILE "../certs/server-ecc.pem"
|
||||
#define KEY_FILE "../certs/ecc-key.pem"
|
||||
|
@ -1110,6 +1646,7 @@ key into `WOLFSSL_CTX`" block, add these lines:
|
|||
}
|
||||
```
|
||||
|
||||
<<<<<<< HEAD
|
||||
And just like that, we're done!
|
||||
|
||||
#### <a name="client-ecc">Client</a>
|
||||
|
@ -1127,6 +1664,19 @@ this:
|
|||
|
||||
After this, we need two more files and a cipher list. In total, these new
|
||||
defines will look like this:
|
||||
=======
|
||||
Next, we need to change the socket to Non-blocking. This is done by adding the
|
||||
following command after the creation of the socket:
|
||||
|
||||
```c
|
||||
/* sets socket to non-blocking */
|
||||
fcntl(sockfd, F_SETFL, O_NONBLOCK);
|
||||
```
|
||||
|
||||
Then we will need to delay connection to the port until it finishes rewriting
|
||||
itself to a non-blocking state. So we have to change how we connect. Instead
|
||||
of this:
|
||||
>>>>>>> c15ac5e8a37f1eec257b547000f8b970846bff9a
|
||||
|
||||
```c
|
||||
#define ECC_FILE "../certs/client-ecc-cert.pem"
|
||||
|
@ -1139,6 +1689,7 @@ this for `CERT_FILE` in the "Load client certificates into `WOLFSSL_CTX`"
|
|||
block, so add these blocks just after that:
|
||||
|
||||
```c
|
||||
<<<<<<< HEAD
|
||||
/* Load client ecc certificates into WOLFSSL_CTX */
|
||||
if (wolfSSL_CTX_use_certificate_chain_file(ctx, ECC_FILE) != SSL_SUCCESS) {
|
||||
fprintf(stderr, "ERROR: failed to load %s, please check the file.\n",
|
||||
|
@ -1172,9 +1723,20 @@ And now the client is set up.
|
|||
`client-tls-ecdhe` can connect to the following:
|
||||
|
||||
* `server-tls-ecdhe`
|
||||
=======
|
||||
/* keeps trying to connect to the socket until it is able to do so */
|
||||
while (ret != 0)
|
||||
ret = connect(sockfd, (struct sockaddr *) &servAddr,
|
||||
sizeof(servAddr));
|
||||
```
|
||||
|
||||
This keeps trying to connect to the socket until it stops being busy and allows
|
||||
the connection.
|
||||
>>>>>>> c15ac5e8a37f1eec257b547000f8b970846bff9a
|
||||
|
||||
|
||||
|
||||
<<<<<<< HEAD
|
||||
<!-- References -->
|
||||
[make]: https://github.com/wolfssl/wolfssl-examples/blob/master/tls/Makefile
|
||||
|
||||
|
@ -1186,6 +1748,26 @@ And now the client is set up.
|
|||
|
||||
[s-tls-c]: https://github.com/wolfssl/wolfssl-examples/blob/master/tls/server-tls-callback.c
|
||||
[c-tls-c]: https://github.com/wolfssl/wolfssl-examples/blob/master/tls/client-tls-callback.c
|
||||
=======
|
||||
Before running `make` be sure that `SERV_PORT` is the same on both source .c
|
||||
files (11111 by default). You must also have the IP address of the machine
|
||||
where the server is going to be on.
|
||||
|
||||
To do this type `ifconfig` in your terminal and look for `inet addr:` under the
|
||||
`wlan` section. If you are going to be running the client and server off of
|
||||
the same machine look under the `lo` section for the local IP address.
|
||||
|
||||
Run `make` in both the server and client folders, this will compile the source
|
||||
files into an executable file. Anytime you make changes to these source files
|
||||
you will need to re-run `make`. Once this is done you can now start both the
|
||||
client and server. To start the server navigate to the server folder and type
|
||||
`./server-tls` and press enter. To activate the client navigate to the client
|
||||
folder and type `./client-tls <IP Address>` into your terminal. This should
|
||||
work on both the secured and unsecured programs.
|
||||
|
||||
Congratulations, you now have a basic client and server that can communicate
|
||||
with each other in an unsecured or secured manner.
|
||||
>>>>>>> c15ac5e8a37f1eec257b547000f8b970846bff9a
|
||||
|
||||
[s-tls-e]: https://github.com/wolfssl/wolfssl-examples/blob/master/tls/server-tls-ecdhe.c
|
||||
[c-tls-e]: https://github.com/wolfssl/wolfssl-examples/blob/master/tls/client-tls-ecdhe.c
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* client-tls.c
|
||||
/* client-tls-nonblocking.c
|
||||
*
|
||||
* Copyright (C) 2006-2015 wolfSSL Inc.
|
||||
*
|
||||
|
@ -79,6 +79,7 @@ int main(int argc, char** argv)
|
|||
return -1;
|
||||
}
|
||||
|
||||
<<<<<<< HEAD
|
||||
|
||||
/* Create and initialize WOLFSSL_CTX */
|
||||
if ((ctx = wolfSSL_CTX_new(wolfTLSv1_2_client_method())) == NULL) {
|
||||
|
@ -163,20 +164,6 @@ int main(int argc, char** argv)
|
|||
|
||||
|
||||
|
||||
/* Read the server data into our buff array */
|
||||
memset(buff, 0, sizeof(buff));
|
||||
while (wolfSSL_read(ssl, buff, sizeof(buff)-1) == -1) {
|
||||
if (wolfSSL_want_read(ssl)) {
|
||||
/* no error, just non-blocking. Carry on. */
|
||||
continue;
|
||||
}
|
||||
fprintf(stderr, "ERROR: failed to read\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Print to stdout any data the server sends */
|
||||
printf("Server: %s\n", buff);
|
||||
|
||||
|
||||
|
||||
/* Cleanup and return */
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* client-tls-writedup.c
|
||||
*
|
||||
* Copyright (C) 2006-2015 wolfSSL Inc.
|
||||
* Copyright (C) 2006-2017 wolfSSL Inc.
|
||||
*
|
||||
* This file is part of wolfSSL. (formerly known as CyaSSL)
|
||||
*
|
||||
|
|
|
@ -54,11 +54,11 @@
|
|||
#define OPTIONS "?p:v:al:c:k:A:n:N:R:W:B:"
|
||||
|
||||
/* The default server certificate. */
|
||||
#define SVR_CERT "../certs/server-cert.pem"
|
||||
#define SVR_CERT "../certs/server-cert.pem"
|
||||
/* The default server private key. */
|
||||
#define SVR_KEY "../certs/server-key.pem"
|
||||
#define SVR_KEY "../certs/server-key.pem"
|
||||
/* The default certificate/CA file for the client. */
|
||||
#define CLI_CERT "../certs/client-cert.pem"
|
||||
#define CLI_CERT "../certs/client-cert.pem"
|
||||
|
||||
/* The states of the SSL connection. */
|
||||
typedef enum SSLState { ACCEPT, READ, WRITE, CLOSED } SSLState;
|
||||
|
|
|
@ -56,11 +56,11 @@
|
|||
#define OPTIONS "?p:v:al:c:k:A:t:n:N:R:W:B:"
|
||||
|
||||
/* The default server certificate. */
|
||||
#define SVR_CERT "../certs/server-cert.pem"
|
||||
#define SVR_CERT "../certs/server-cert.pem"
|
||||
/* The default server private key. */
|
||||
#define SVR_KEY "../certs/server-key.pem"
|
||||
#define SVR_KEY "../certs/server-key.pem"
|
||||
/* The default certificate/CA file for the client. */
|
||||
#define CLI_CERT "../certs/client-cert.pem"
|
||||
#define CLI_CERT "../certs/client-cert.pem"
|
||||
|
||||
/* The states of the SSL connection. */
|
||||
typedef enum SSLState { ACCEPT, READ, WRITE, CLOSED } SSLState;
|
||||
|
|
Loading…
Reference in New Issue