Skip to content

Commit

Permalink
add: experimental WolfSSL support.
Browse files Browse the repository at this point in the history
This commit adds experimental support to WolfSSL via PCLL
  • Loading branch information
ThePedroo committed May 5, 2024
1 parent 8297bac commit 004ae97
Show file tree
Hide file tree
Showing 6 changed files with 343 additions and 91 deletions.
12 changes: 10 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,14 @@ PORT = 8888# Port that FrequenC will listen on.
AUTHORIZATION = youshallnotpass# Authorization header for the server. Secure it with a strong password.
ALLOW_UNSECURE_RANDOM = 0# Only use this for unsupported platforms.

# SSL/TLS

OPENSSL=1
WOLFSSL=2

PCLL_SSL_LIBRARY = $(OPENSSL)# The SSL/TLS library that is used by FrequenC.
SSL_FLAGS = $(if $(PCLL_SSL_LIBRARY),-lssl -lcrypto,) $(if $(PCLL_SSL_LIBRARY),-lwolfssl)

# Development
HARDCODED_SESSION_ID = 0# Hardcoded session ID for debugging purposes.

Expand All @@ -24,14 +32,14 @@ OBJ_DIR = obj
CVERSION = -std=c99
CFLAGS ?= -Ofast -march=native -fno-signed-zeros -fno-trapping-math -funroll-loops
LDFLAGS ?= -Iinclude -Iexternal -Isources -pthread
OPTIONS = -DPORT=$(PORT) -DAUTHORIZATION=\"$(AUTHORIZATION)\" -DALLOW_UNSECURE_RANDOM=$(ALLOW_UNSECURE_RANDOM) $(if $(CSOCKET_SECURE),-lssl -lcrypto -DCSOCKET_SECURE -DCSOCKET_KEY=\"$(CSOCKET_KEY)\" -DCSOCKET_CERT=\"$(CSOCKET_CERT)\",) $(if $(TCPLIMITS_EXPERIMENTAL_SAVE_MEMORY),-DTCPLIMITS_EXPERIMENTAL_SAVE_MEMORY,) -DHARDCODED_SESSION_ID=$(HARDCODED_SESSION_ID) -DGITHUB_COMMIT_SHA=\"$(GITHUB_COMMIT_SHA)\" -DGITHUB_BRANCH=\"$(GITHUB_BRANCH)\"
OPTIONS = -DPORT=$(PORT) -DAUTHORIZATION=\"$(AUTHORIZATION)\" -DALLOW_UNSECURE_RANDOM=$(ALLOW_UNSECURE_RANDOM) $(if $(CSOCKET_SECURE),-DCSOCKET_SECURE -DCSOCKET_KEY=\"$(CSOCKET_KEY)\" -DCSOCKET_CERT=\"$(CSOCKET_CERT)\",) $(if $(TCPLIMITS_EXPERIMENTAL_SAVE_MEMORY),-DTCPLIMITS_EXPERIMENTAL_SAVE_MEMORY,) -DHARDCODED_SESSION_ID=$(HARDCODED_SESSION_ID) -DGITHUB_COMMIT_SHA=\"$(GITHUB_COMMIT_SHA)\" -DGITHUB_BRANCH=\"$(GITHUB_BRANCH)\" -DPCLL_SSL_LIBRARY=$(PCLL_SSL_LIBRARY)
CHECK_FLAGS = -Wpedantic -Wall -Wextra -Werror -Wformat -Wuninitialized -Wshadow

SRCS = $(foreach dir,$(SRC_DIR),$(wildcard $(dir)/*.c))
OBJS = $(patsubst %.c,$(OBJ_DIR)/%.o,$(notdir $(SRCS)))

FrequenC: $(OBJS)
$(CC) $^ -o $@ $(CVERSION) $(CFLAGS) $(CHECK_FLAGS) $(OPTIONS) $(LDFLAGS) -lssl -lcrypto
$(CC) $^ -o $@ $(CVERSION) $(CFLAGS) $(CHECK_FLAGS) $(OPTIONS) $(LDFLAGS) $(SSL_FLAGS)

$(OBJ_DIR)/%.o: lib/%.c | $(OBJ_DIR)
$(CC) -c $< -o $@ $(CVERSION) $(CFLAGS) $(CHECK_FLAGS) $(OPTIONS) $(LDFLAGS)
Expand Down
227 changes: 227 additions & 0 deletions external/pcll.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,227 @@
/*
(PerformanC's) C(ross-compatible) SSL Library
License available on: licenses/performanc.license
*/

#include <stdio.h>
#include <stdlib.h>

#include "pcll.h"

#if PCLL_SSL_LIBRARY == PCLL_OPENSSL
#include <openssl/err.h>
#include <openssl/ssl.h>
#include <openssl/x509_vfy.h>
#include <openssl/x509v3.h>
#elif PCLL_SSL_LIBRARY == PCLL_WOLFSSL
#include <wolfssl/ssl.h>
#endif

int pcll_init_ssl_library(void) {
#if PCLL_SSL_LIBRARY == PCLL_OPENSSL
SSL_library_init();
SSL_load_error_strings();
OpenSSL_add_all_algorithms();
#elif PCLL_SSL_LIBRARY == PCLL_WOLFSSL
wolfSSL_Init();
#endif

return 0;
}

int pcll_init_ssl(struct pcll_connection *connection) {
#if PCLL_SSL_LIBRARY == PCLL_OPENSSL
connection->ctx = SSL_CTX_new(TLS_client_method());
if (!connection->ctx) {
SSL_CTX_free(connection->ctx);

return -1;
}

if (!SSL_CTX_set_min_proto_version(connection->ctx, TLS1_2_VERSION)) {
SSL_CTX_free(connection->ctx);

return -1;
}

connection->ssl = SSL_new(connection->ctx);
if (!connection->ssl) {
SSL_free(connection->ssl);
SSL_CTX_free(connection->ctx);

return -1;
}

return 0;
#elif PCLL_SSL_LIBRARY == PCLL_WOLFSSL
/* TODO: How portable is to use wolfTLSv1_3_client_method? */
connection->ctx = wolfSSL_CTX_new(wolfTLSv1_2_client_method());
if (connection->ctx == NULL) {
wolfSSL_CTX_free(connection->ctx);

return -1;
}

connection->ssl = wolfSSL_new(connection->ctx);
if (connection->ssl == NULL) {
wolfSSL_free(connection->ssl);
wolfSSL_CTX_free(connection->ctx);

return -1;
}

return 0;
#endif

return -1;
}

int pcll_set_fd(struct pcll_connection *connection, int fd) {
#if PCLL_SSL_LIBRARY == PCLL_OPENSSL
if (!SSL_set_fd(connection->ssl, fd)) {
SSL_free(connection->ssl);
SSL_CTX_free(connection->ctx);

return -1;
}

return 0;
#elif PCLL_SSL_LIBRARY == PCLL_WOLFSSL
if (wolfSSL_set_fd(connection->ssl, fd) != WOLFSSL_SUCCESS) {
wolfSSL_free(connection->ssl);
wolfSSL_CTX_free(connection->ctx);

return -1;
}

return 0;
#endif

return 0;
}

int pcll_set_safe_mode(struct pcll_connection *connection, char *hostname) {
#if PCLL_SSL_LIBRARY == PCLL_OPENSSL
SSL_CTX_set_verify(connection->ctx, SSL_VERIFY_PEER, NULL);

if (!SSL_CTX_set_default_verify_paths(connection->ctx)) return -1;

if (SSL_set1_host(connection->ssl, hostname) != 1) return -1;

if (SSL_set_tlsext_host_name(connection->ssl, hostname) != 1) return -1;

if (SSL_get_verify_result(connection->ssl) != X509_V_OK) return -1;

return 0;
#elif PCLL_SSL_LIBRARY == PCLL_WOLFSSL
(void)hostname; /* No SNI */

wolfSSL_CTX_set_verify(connection->ctx, WOLFSSL_VERIFY_PEER, NULL);

/* TODO: WolfSSL SNI support */

if (connection->ssl == NULL) return -1;

return 0;
#endif

return -1;
}

int pcll_connect(struct pcll_connection *connection) {
#if PCLL_SSL_LIBRARY == PCLL_OPENSSL
if (SSL_connect(connection->ssl) != 1) return -1;

return 0;
#elif PCLL_SSL_LIBRARY == PCLL_WOLFSSL
if (wolfSSL_connect(connection->ssl) != SSL_SUCCESS) return -1;

return 0;
#endif

return -1;
}

int pcll_get_error(struct pcll_connection *connection) {
#if PCLL_SSL_LIBRARY == PCLL_OPENSSL
return SSL_get_error(connection->ssl, 0);
#elif PCLL_SSL_LIBRARY == PCLL_WOLFSSL
return wolfSSL_get_error(connection->ssl, 0);
#endif

return 0;
}

int pcll_send(struct pcll_connection *connection, char *data, int length) {
#if PCLL_SSL_LIBRARY == PCLL_OPENSSL
if (SSL_write(connection->ssl, data, length) == -1) {
/* TODO: Should we clean up here or let the dev decide? */
SSL_free(connection->ssl);
SSL_CTX_free(connection->ctx);

return -1;
}

return 0;
#elif PCLL_SSL_LIBRARY == PCLL_WOLFSSL
if (wolfSSL_write(connection->ssl, data, length) == -1) {
/* TODO: Should we clean up here or let the dev decide? */
wolfSSL_free(connection->ssl);
wolfSSL_CTX_free(connection->ctx);

return -1;
}

return 0;
#endif

return -1;
}

int pcll_recv(struct pcll_connection *connection, char *data, int length) {
#if PCLL_SSL_LIBRARY == PCLL_OPENSSL
int recv_length = SSL_read(connection->ssl, data, length);
if (recv_length == -1) {
/* TODO: Should we clean up here or let the dev decide? */
SSL_free(connection->ssl);
SSL_CTX_free(connection->ctx);

return -1;
}

return recv_length;
#elif PCLL_SSL_LIBRARY == PCLL_WOLFSSL
int recv_length = wolfSSL_read(connection->ssl, data, length);
if (recv_length == -1) {
/* TODO: Should we clean up here or let the dev decide? */
wolfSSL_free(connection->ssl);
wolfSSL_CTX_free(connection->ctx);

return -1;
}

return recv_length;
#endif

return -1;
}

void pcll_free(struct pcll_connection *connection) {
#if PCLL_SSL_LIBRARY == PCLL_OPENSSL
SSL_free(connection->ssl);
SSL_CTX_free(connection->ctx);
#elif PCLL_SSL_LIBRARY == PCLL_WOLFSSL
wolfSSL_free(connection->ssl);
wolfSSL_CTX_free(connection->ctx);
wolfSSL_Cleanup();
#endif
}

void pcll_shutdown(struct pcll_connection *connection) {
#if PCLL_SSL_LIBRARY == PCLL_OPENSSL
SSL_shutdown(connection->ssl);
#elif PCLL_SSL_LIBRARY == PCLL_WOLFSSL
wolfSSL_shutdown(connection->ssl);
#endif
}
48 changes: 48 additions & 0 deletions external/pcll.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#ifndef PCLL_H
#define PCLL_H

#define PCLL_OPENSSL 1
#define PCLL_WOLFSSL 2

#if PCLL_SSL_LIBRARY == PCLL_OPENSSL
#include <openssl/err.h>
#include <openssl/ssl.h>
#include <openssl/x509_vfy.h>
#include <openssl/x509v3.h>
#elif PCLL_SSL_LIBRARY == PCLL_WOLFSSL
#pragma message "Using wolfSSL is experimental and may not work as expected. Security is NOT guaranteed."

#include <wolfssl/ssl.h>
#endif

struct pcll_connection {
#if PCLL_SSL_LIBRARY == PCLL_OPENSSL
SSL *ssl;
SSL_CTX *ctx;
#elif PCLL_SSL_LIBRARY == PCLL_WOLFSSL
WOLFSSL *ssl;
WOLFSSL_CTX *ctx;
#endif
};

int pcll_init_ssl_library(void);

int pcll_init_ssl(struct pcll_connection *connection);

int pcll_set_fd(struct pcll_connection *connection, int fd);

int pcll_set_safe_mode(struct pcll_connection *connection, char *hostname);

int pcll_connect(struct pcll_connection *connection);

int pcll_get_error(struct pcll_connection *connection);

int pcll_send(struct pcll_connection *connection, char *data, int length);

int pcll_recv(struct pcll_connection *connection, char *data, int length);

void pcll_free(struct pcll_connection *connection);

void pcll_shutdown(struct pcll_connection *connection);

#endif /* PCLL_H */
7 changes: 3 additions & 4 deletions include/httpclient.h
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
#ifndef HTTPCLIENT_H
#define HTTPCLIENT_H

#include "pcll.h"

#include "types.h"
#include "httpparser.h"

#include <openssl/ssl.h>

struct httpclient_request_params {
char *host;
int port;
Expand All @@ -27,8 +27,7 @@ struct httpclient_response {
size_t body_length;
int finished;
int chunk_length;
SSL *ssl;
SSL_CTX *ctx;
struct pcll_connection connection;
int socket;
};

Expand Down
Loading

0 comments on commit 004ae97

Please sign in to comment.