init
This commit is contained in:
commit
3b73f82938
6
.gitignore
vendored
Normal file
6
.gitignore
vendored
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
certs
|
||||||
|
build
|
||||||
|
.cache
|
||||||
|
.vscode
|
||||||
|
compile_commands.json
|
||||||
|
test.c
|
58
Makefile
Normal file
58
Makefile
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
# Compiler and flags
|
||||||
|
CPPC = g++
|
||||||
|
CPPC_FLAGS = -std=c++23 -s -O3 -Wall -Wextra -Wno-write-strings -lssl -lcrypto -Wformat -Wformat=2 -Wconversion -Wimplicit-fallthrough -Werror=format-security -D_FORTIFY_SOURCE=3 -D_GLIBCXX_ASSERTIONS -fstrict-flex-arrays=3 -fstack-clash-protection -fstack-protector-strong -Wl,-z,nodlopen -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now -Wl,--as-needed -Wl,--no-copy-dt-needed-entries -fPIE -pie -fcf-protection=full -fstack-protector -fstack-protector-all -fstack-protector-strong
|
||||||
|
DEBUG_FLAGS = -ggdb -std=c++23 -Wall -Wextra -Wno-write-strings -lssl -lcrypto -Wformat -Wformat=2 -Wconversion -Wimplicit-fallthrough -Werror=format-security -D_FORTIFY_SOURCE=3 -D_GLIBCXX_ASSERTIONS -fstrict-flex-arrays=3 -fstack-clash-protection -fstack-protector-strong -Wl,-z,nodlopen -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now -Wl,--as-needed -Wl,--no-copy-dt-needed-entries -fPIE -pie -fcf-protection=full -fstack-protector -fstack-protector-all -fstack-protector-strong
|
||||||
|
DEBUG_ASANITIZE = -fsanitize=address -ggdb -fno-omit-frame-pointer -std=c++23 -Wall -Wextra -Wno-write-strings -lssl -lcrypto -Wformat -Wformat=2 -Wconversion -Wimplicit-fallthrough -Werror=format-security -D_FORTIFY_SOURCE=5 -D_GLIBCXX_ASSERTIONS -fstrict-flex-arrays=3 -fstack-clash-protection -fstack-protector-strong -Wl,-z,nodlopen -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now -Wl,--as-needed -Wl,--no-copy-dt-needed-entries -fPIE -pie -fcf-protection=full -fstack-protector -fstack-protector-all -fstack-protector-strong
|
||||||
|
|
||||||
|
|
||||||
|
SRC_PATH_CLIENT := client
|
||||||
|
SRC_PATH_RELAY := relay
|
||||||
|
OBJ_PATH_CLIENT := build/obj/client
|
||||||
|
OBJ_PATH_RELAY := build/obj/relay
|
||||||
|
OBJ_PATH := build/obj
|
||||||
|
BIN_PATH := build/bin
|
||||||
|
|
||||||
|
|
||||||
|
SRC_FILES_CLIENT := $(shell find $(SRC_PATH_CLIENT) -name '*.cpp')
|
||||||
|
OBJ_FILES_CLIENT := $(patsubst $(SRC_PATH_CLIENT)/%.cpp,$(OBJ_PATH_CLIENT)/%.o,$(SRC_FILES_CLIENT))
|
||||||
|
|
||||||
|
SRC_FILES_RELAY := $(shell find $(SRC_PATH_RELAY) -name '*.cpp')
|
||||||
|
OBJ_FILES_RELAY := $(patsubst $(SRC_PATH_RELAY)/%.cpp,$(OBJ_PATH_RELAY)/%.o,$(SRC_FILES_RELAY))
|
||||||
|
|
||||||
|
all: make-build-dir $(BIN_PATH)/pupes-message $(BIN_PATH)/pupes-message-relay
|
||||||
|
|
||||||
|
|
||||||
|
debug: CPPC_FLAGS = $(DEBUG_FLAGS)
|
||||||
|
debug: make-build-dir $(BIN_PATH)/pupes-message $(BIN_PATH)/pupes-message-relay
|
||||||
|
|
||||||
|
asan: CPPC_FLAGS = $(DEBUG_ASANITIZE)
|
||||||
|
asan: make-build-dir $(BIN_PATH)/pupes-message $(BIN_PATH)/pupes-message-relay
|
||||||
|
|
||||||
|
|
||||||
|
make-build-dir:
|
||||||
|
mkdir -p $(OBJ_PATH_CLIENT)
|
||||||
|
mkdir -p $(OBJ_PATH_RELAY)
|
||||||
|
mkdir -p $(BIN_PATH)
|
||||||
|
|
||||||
|
|
||||||
|
$(BIN_PATH)/pupes-message: $(OBJ_FILES_CLIENT)
|
||||||
|
$(CPPC) $(CPPC_FLAGS) $^ -o $@
|
||||||
|
|
||||||
|
$(BIN_PATH)/pupes-message-relay: $(OBJ_FILES_RELAY)
|
||||||
|
$(CPPC) $(CPPC_FLAGS) $^ -o $@
|
||||||
|
|
||||||
|
|
||||||
|
$(OBJ_PATH_CLIENT)/%.o: $(SRC_PATH_CLIENT)/%.cpp
|
||||||
|
$(CPPC) $(CPPC_FLAGS) -c $< -o $@
|
||||||
|
|
||||||
|
$(OBJ_PATH_RELAY)/%.o: $(SRC_PATH_RELAY)/%.cpp
|
||||||
|
$(CPPC) $(CPPC_FLAGS) -c $< -o $@
|
||||||
|
|
||||||
|
|
||||||
|
install:
|
||||||
|
@install -vpm 755 -o root -g root $(BIN_PATH)/pupes-message /usr/bin/
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -fr build
|
||||||
|
|
||||||
|
.PHONY: all clean install debug asan
|
155
client/main.cpp
Normal file
155
client/main.cpp
Normal file
@ -0,0 +1,155 @@
|
|||||||
|
#include "../common/defines.h"
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <openssl/err.h>
|
||||||
|
#include <openssl/ssl.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
void error(const char *msg) {
|
||||||
|
perror(msg);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
if (argc < 3) {
|
||||||
|
fprintf(stderr, "Usage: %s <server_ip> <port>\n", argv[0]);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize OpenSSL (for OpenSSL 1.1.0+ this is optional as it's automatic)
|
||||||
|
OPENSSL_init_ssl(0, NULL);
|
||||||
|
|
||||||
|
// Create a TLS 1.3 client context
|
||||||
|
SSL_CTX *ctx = SSL_CTX_new(TLS_client_method());
|
||||||
|
if (ctx == NULL) {
|
||||||
|
ERR_print_errors_fp(stderr);
|
||||||
|
error("Failed to create SSL_CTX");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set minimum TLS version to 1.3
|
||||||
|
if (SSL_CTX_set_min_proto_version(ctx, TLS1_3_VERSION) != 1) {
|
||||||
|
SSL_CTX_free(ctx);
|
||||||
|
ERR_print_errors_fp(stderr);
|
||||||
|
error("Error setting minimum TLS version");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load CA certificate for server verification
|
||||||
|
if (SSL_CTX_load_verify_locations(ctx, "certs/mldsa87_root_cert.pem", NULL) !=
|
||||||
|
1) {
|
||||||
|
SSL_CTX_free(ctx);
|
||||||
|
ERR_print_errors_fp(stderr);
|
||||||
|
error("Error loading CA certificate");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set cipher suite for TLS 1.3
|
||||||
|
if (SSL_CTX_set_ciphersuites(ctx, "TLS_AES_256_GCM_SHA384") != 1) {
|
||||||
|
SSL_CTX_free(ctx);
|
||||||
|
ERR_print_errors_fp(stderr);
|
||||||
|
error("Error setting cipher list");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a TCP socket
|
||||||
|
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
|
||||||
|
if (sockfd < 0)
|
||||||
|
error("Socket creation failed");
|
||||||
|
|
||||||
|
// Set up server address
|
||||||
|
struct sockaddr_in serv_addr;
|
||||||
|
memset(&serv_addr, 0, sizeof(serv_addr));
|
||||||
|
serv_addr.sin_family = AF_INET;
|
||||||
|
serv_addr.sin_port = htons(atoi(argv[2]));
|
||||||
|
if (inet_pton(AF_INET, argv[1], &serv_addr.sin_addr) <= 0)
|
||||||
|
error("Invalid address/address not supported");
|
||||||
|
|
||||||
|
// Connect to server
|
||||||
|
if (connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
|
||||||
|
error("Connection failed");
|
||||||
|
|
||||||
|
printf("Connected to %s:%s\n", argv[1], argv[2]);
|
||||||
|
|
||||||
|
// Create an SSL object
|
||||||
|
SSL *ssl = SSL_new(ctx);
|
||||||
|
if (ssl == NULL) {
|
||||||
|
close(sockfd);
|
||||||
|
SSL_CTX_free(ctx);
|
||||||
|
ERR_print_errors_fp(stderr);
|
||||||
|
error("Failed to create SSL object");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Associate the socket with SSL
|
||||||
|
if (SSL_set_fd(ssl, sockfd) != 1) {
|
||||||
|
SSL_free(ssl);
|
||||||
|
close(sockfd);
|
||||||
|
SSL_CTX_free(ctx);
|
||||||
|
ERR_print_errors_fp(stderr);
|
||||||
|
error("Failed to set SSL file descriptor");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Connect using TLS
|
||||||
|
int ret = SSL_connect(ssl);
|
||||||
|
if (ret != 1) {
|
||||||
|
fprintf(stderr, "TLS handshake failed: %d\n", SSL_get_error(ssl, ret));
|
||||||
|
ERR_print_errors_fp(stderr);
|
||||||
|
SSL_free(ssl);
|
||||||
|
close(sockfd);
|
||||||
|
SSL_CTX_free(ctx);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("TLS 1.3 handshake successful using %s\n", SSL_get_cipher(ssl));
|
||||||
|
|
||||||
|
// Fork to handle sending and receiving
|
||||||
|
pid_t pid = fork();
|
||||||
|
if (pid < 0)
|
||||||
|
error("Fork failed");
|
||||||
|
|
||||||
|
if (pid == 0) { // Child process: receive from server
|
||||||
|
char buffer[BUFFER_SIZE];
|
||||||
|
int bytes_read;
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
bytes_read = SSL_read(ssl, buffer, BUFFER_SIZE);
|
||||||
|
|
||||||
|
if (bytes_read > 0) {
|
||||||
|
fwrite(buffer, 1, bytes_read, stdout);
|
||||||
|
fflush(stdout);
|
||||||
|
memset(buffer, 0, BUFFER_SIZE);
|
||||||
|
} else {
|
||||||
|
int err = SSL_get_error(ssl, bytes_read);
|
||||||
|
if (err == SSL_ERROR_WANT_READ)
|
||||||
|
continue;
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
kill(getppid(), SIGTERM); // Signal parent to terminate
|
||||||
|
exit(0);
|
||||||
|
} else { // Parent process: send to server
|
||||||
|
char buffer[BUFFER_SIZE];
|
||||||
|
int bytes_read;
|
||||||
|
|
||||||
|
while ((bytes_read = read(STDIN_FILENO, buffer, BUFFER_SIZE)) > 0) {
|
||||||
|
if (SSL_write(ssl, buffer, bytes_read) < 0) {
|
||||||
|
fprintf(stderr, "SSL_write error: %d\n", SSL_get_error(ssl, 0));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
kill(pid, SIGTERM); // Signal child to terminate
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clean up
|
||||||
|
SSL_shutdown(ssl);
|
||||||
|
SSL_free(ssl);
|
||||||
|
close(sockfd);
|
||||||
|
SSL_CTX_free(ctx);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
1
common/defines.h
Normal file
1
common/defines.h
Normal file
@ -0,0 +1 @@
|
|||||||
|
#define BUFFER_SIZE 1024
|
64
misc/certgen.sh
Normal file
64
misc/certgen.sh
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# Script to generate ML-DSA-87 certificates for wolfSSL
|
||||||
|
# Creates both root CA and entity certificates using ML-DSA-87
|
||||||
|
|
||||||
|
set -e # Exit on any error
|
||||||
|
|
||||||
|
# Create certificates directory if it doesn't exist
|
||||||
|
mkdir -p certs
|
||||||
|
|
||||||
|
echo "==== Generating ML-DSA-87 Root CA ===="
|
||||||
|
|
||||||
|
# Generate the root private key
|
||||||
|
openssl genpkey -algorithm mldsa87 -out certs/mldsa87_root_key.pem
|
||||||
|
echo "Root private key generated."
|
||||||
|
|
||||||
|
# Generate self-signed root certificate
|
||||||
|
openssl req -new -x509 -key certs/mldsa87_root_key.pem -out certs/mldsa87_root_cert.pem \
|
||||||
|
-days 3650 -subj "/C=US/ST=Washington/L=Seattle/O=wolfSSL/OU=Development/CN=www.wolfssl.com" \
|
||||||
|
-addext "basicConstraints=critical,CA:true" \
|
||||||
|
-addext "keyUsage=critical,keyCertSign,cRLSign"
|
||||||
|
echo "Root certificate generated."
|
||||||
|
|
||||||
|
echo "==== Generating ML-DSA-87 Entity Certificate ===="
|
||||||
|
|
||||||
|
# Generate entity private key
|
||||||
|
openssl genpkey -algorithm mldsa87 -out certs/mldsa87_entity_key.pem
|
||||||
|
echo "Entity private key generated."
|
||||||
|
|
||||||
|
# Generate certificate request
|
||||||
|
openssl req -new -key certs/mldsa87_entity_key.pem -out certs/mldsa87_entity.csr \
|
||||||
|
-subj "/C=US/ST=Washington/L=Seattle/O=wolfSSL/OU=Development/CN=www.wolfssl.com"
|
||||||
|
echo "Entity certificate request generated."
|
||||||
|
|
||||||
|
# Create an extension file for the certificate
|
||||||
|
cat > certs/mldsa87_entity_extfile.cnf << EOF
|
||||||
|
basicConstraints=CA:FALSE
|
||||||
|
keyUsage=digitalSignature,keyEncipherment
|
||||||
|
extendedKeyUsage=serverAuth,clientAuth
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# Sign the certificate with the root CA
|
||||||
|
openssl x509 -req -in certs/mldsa87_entity.csr -out certs/mldsa87_entity_cert.pem \
|
||||||
|
-CA certs/mldsa87_root_cert.pem -CAkey certs/mldsa87_root_key.pem \
|
||||||
|
-CAcreateserial -days 3650 \
|
||||||
|
-extfile certs/mldsa87_entity_extfile.cnf
|
||||||
|
echo "Entity certificate generated."
|
||||||
|
|
||||||
|
# Clean up temporary files
|
||||||
|
rm -f certs/mldsa87_entity.csr certs/mldsa87_entity_extfile.cnf certs/mldsa87_root_cert.srl
|
||||||
|
|
||||||
|
echo "==== Certificate Verification ===="
|
||||||
|
# Verify entity certificate against root
|
||||||
|
openssl verify -CAfile certs/mldsa87_root_cert.pem certs/mldsa87_entity_cert.pem
|
||||||
|
echo "Verification completed."
|
||||||
|
|
||||||
|
echo "==== Certificate Generation Complete ===="
|
||||||
|
echo "Files generated:"
|
||||||
|
ls -la certs/
|
||||||
|
|
||||||
|
echo "==== Instructions for Use with wolfSSL ===="
|
||||||
|
echo "In your wolfSSL code, use the following file paths:"
|
||||||
|
echo " Root CA: certs/mldsa87_root_cert.pem"
|
||||||
|
echo " Entity Certificate: certs/mldsa87_entity_cert.pem"
|
||||||
|
echo " Entity Private Key: certs/mldsa87_entity_key.pem"
|
227
relay/main.cpp
Normal file
227
relay/main.cpp
Normal file
@ -0,0 +1,227 @@
|
|||||||
|
#include "../common/defines.h"
|
||||||
|
#include <algorithm>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <fstream>
|
||||||
|
#include <iostream>
|
||||||
|
#include <mutex>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <openssl/err.h>
|
||||||
|
#include <openssl/ssl.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <thread>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <vector>
|
||||||
|
#define PORT 9009
|
||||||
|
|
||||||
|
struct Client {
|
||||||
|
SSL *ssl;
|
||||||
|
int socket;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::vector<Client> clients;
|
||||||
|
std::mutex clients_mutex;
|
||||||
|
|
||||||
|
void handle_client(SSL *ssl, int client_socket) {
|
||||||
|
char buffer[BUFFER_SIZE];
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
// Read data securely using OpenSSL
|
||||||
|
int bytes_read = SSL_read(ssl, buffer, sizeof(buffer));
|
||||||
|
if (bytes_read <= 0) {
|
||||||
|
// Check for OpenSSL specific errors
|
||||||
|
int err = SSL_get_error(ssl, bytes_read);
|
||||||
|
if (err == SSL_ERROR_WANT_READ)
|
||||||
|
continue;
|
||||||
|
break; // Client disconnected or error occurred
|
||||||
|
}
|
||||||
|
|
||||||
|
// Broadcast to all other clients
|
||||||
|
std::lock_guard<std::mutex> lock(clients_mutex);
|
||||||
|
for (const auto &client : clients) {
|
||||||
|
if (client.socket != client_socket) {
|
||||||
|
// Send data securely using OpenSSL
|
||||||
|
SSL_write(client.ssl, buffer, bytes_read);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clean up when client disconnects
|
||||||
|
std::lock_guard<std::mutex> lock(clients_mutex);
|
||||||
|
clients.erase(std::remove_if(clients.begin(), clients.end(),
|
||||||
|
[client_socket](const Client &c) {
|
||||||
|
return c.socket == client_socket;
|
||||||
|
}),
|
||||||
|
clients.end());
|
||||||
|
|
||||||
|
// Free OpenSSL resources
|
||||||
|
SSL_free(ssl);
|
||||||
|
close(client_socket);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
// Initialize OpenSSL
|
||||||
|
SSL_library_init();
|
||||||
|
OpenSSL_add_all_algorithms();
|
||||||
|
SSL_load_error_strings();
|
||||||
|
|
||||||
|
// Create a TLS 1.3 server context
|
||||||
|
SSL_CTX *ctx = SSL_CTX_new(TLS_server_method());
|
||||||
|
if (ctx == NULL) {
|
||||||
|
std::cerr << "Failed to create SSL_CTX" << std::endl;
|
||||||
|
ERR_print_errors_fp(stderr);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set min/max protocol to TLS 1.3
|
||||||
|
SSL_CTX_set_min_proto_version(ctx, TLS1_3_VERSION);
|
||||||
|
SSL_CTX_set_max_proto_version(ctx, TLS1_3_VERSION);
|
||||||
|
|
||||||
|
// Load ML-DSA post-quantum certificates and keys
|
||||||
|
if (SSL_CTX_use_certificate_file(ctx, "certs/mldsa87_entity_cert.pem",
|
||||||
|
SSL_FILETYPE_PEM) != 1) {
|
||||||
|
std::cerr << "Error loading certificate file" << std::endl;
|
||||||
|
ERR_print_errors_fp(stderr);
|
||||||
|
|
||||||
|
std::ifstream file("certs/mldsa87_entity_cert.pem");
|
||||||
|
if (file) {
|
||||||
|
std::cout << "Certificate file exists and is readable" << std::endl;
|
||||||
|
} else {
|
||||||
|
std::cout << "Cannot access certificate file" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
SSL_CTX_free(ctx);
|
||||||
|
EVP_cleanup();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SSL_CTX_use_PrivateKey_file(ctx, "certs/mldsa87_entity_key.pem",
|
||||||
|
SSL_FILETYPE_PEM) != 1) {
|
||||||
|
std::cerr << "Error loading private key file" << std::endl;
|
||||||
|
ERR_print_errors_fp(stderr);
|
||||||
|
SSL_CTX_free(ctx);
|
||||||
|
EVP_cleanup();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load CA certificate for client verification
|
||||||
|
if (SSL_CTX_load_verify_locations(ctx, "certs/mldsa87_root_cert.pem", NULL) !=
|
||||||
|
1) {
|
||||||
|
std::cerr << "Error loading CA certificate" << std::endl;
|
||||||
|
ERR_print_errors_fp(stderr);
|
||||||
|
SSL_CTX_free(ctx);
|
||||||
|
EVP_cleanup();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Configure TLS 1.3 cipher suites
|
||||||
|
if (SSL_CTX_set_ciphersuites(ctx, "TLS_AES_256_GCM_SHA384") != 1) {
|
||||||
|
std::cerr << "Error setting cipher suites" << std::endl;
|
||||||
|
ERR_print_errors_fp(stderr);
|
||||||
|
SSL_CTX_free(ctx);
|
||||||
|
EVP_cleanup();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a TCP socket
|
||||||
|
int server_fd = socket(AF_INET, SOCK_STREAM, 0);
|
||||||
|
if (server_fd < 0) {
|
||||||
|
std::cerr << "Socket creation failed" << std::endl;
|
||||||
|
SSL_CTX_free(ctx);
|
||||||
|
EVP_cleanup();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set socket options
|
||||||
|
int opt = 1;
|
||||||
|
if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0) {
|
||||||
|
std::cerr << "setsockopt failed" << std::endl;
|
||||||
|
close(server_fd);
|
||||||
|
SSL_CTX_free(ctx);
|
||||||
|
EVP_cleanup();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bind socket to port
|
||||||
|
sockaddr_in address{};
|
||||||
|
address.sin_family = AF_INET;
|
||||||
|
address.sin_addr.s_addr = INADDR_ANY;
|
||||||
|
address.sin_port = htons(PORT);
|
||||||
|
if (bind(server_fd, (sockaddr *)&address, sizeof(address)) < 0) {
|
||||||
|
std::cerr << "Bind failed" << std::endl;
|
||||||
|
close(server_fd);
|
||||||
|
SSL_CTX_free(ctx);
|
||||||
|
EVP_cleanup();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Listen for connections
|
||||||
|
if (listen(server_fd, 5) < 0) {
|
||||||
|
std::cerr << "Listen failed" << std::endl;
|
||||||
|
close(server_fd);
|
||||||
|
SSL_CTX_free(ctx);
|
||||||
|
EVP_cleanup();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << "Secure server started on port " << PORT << std::endl;
|
||||||
|
std::cout << "Using TLS 1.3 with post-quantum cryptography" << std::endl;
|
||||||
|
|
||||||
|
// Accept and handle client connections
|
||||||
|
while (true) {
|
||||||
|
sockaddr_in client_addr{};
|
||||||
|
socklen_t client_len = sizeof(client_addr);
|
||||||
|
int client_socket =
|
||||||
|
accept(server_fd, (sockaddr *)&client_addr, &client_len);
|
||||||
|
|
||||||
|
if (client_socket < 0) {
|
||||||
|
std::cerr << "Accept failed" << std::endl;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
char client_ip[INET_ADDRSTRLEN];
|
||||||
|
inet_ntop(AF_INET, &(client_addr.sin_addr), client_ip, INET_ADDRSTRLEN);
|
||||||
|
std::cout << "New connection from " << client_ip << std::endl;
|
||||||
|
|
||||||
|
// Create a new SSL object for this connection
|
||||||
|
SSL *ssl = SSL_new(ctx);
|
||||||
|
if (ssl == NULL) {
|
||||||
|
std::cerr << "SSL_new failed" << std::endl;
|
||||||
|
ERR_print_errors_fp(stderr);
|
||||||
|
close(client_socket);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Associate the socket with SSL
|
||||||
|
if (SSL_set_fd(ssl, client_socket) != 1) {
|
||||||
|
std::cerr << "SSL_set_fd failed" << std::endl;
|
||||||
|
ERR_print_errors_fp(stderr);
|
||||||
|
SSL_free(ssl);
|
||||||
|
close(client_socket);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Accept the TLS connection
|
||||||
|
if (SSL_accept(ssl) != 1) {
|
||||||
|
std::cerr << "TLS handshake failed: " << SSL_get_error(ssl, 0)
|
||||||
|
<< std::endl;
|
||||||
|
ERR_print_errors_fp(stderr);
|
||||||
|
SSL_free(ssl);
|
||||||
|
close(client_socket);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add client to the list
|
||||||
|
std::lock_guard<std::mutex> lock(clients_mutex);
|
||||||
|
clients.push_back({ssl, client_socket});
|
||||||
|
|
||||||
|
// Create a thread to handle this client
|
||||||
|
std::thread(handle_client, ssl, client_socket).detach();
|
||||||
|
std::cout << "Client connected and secured with TLS 1.3" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clean up resources
|
||||||
|
close(server_fd);
|
||||||
|
SSL_CTX_free(ctx);
|
||||||
|
EVP_cleanup();
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user