add wolfHSM DTLS server demo
parent
f2dec15dde
commit
8b3c7bee89
|
|
@ -0,0 +1,146 @@
|
|||
## Makefile for TLS/DTLS Server using wolfHSM for crypto operations
|
||||
##
|
||||
## This example demonstrates a server that offloads all cryptographic
|
||||
## operations to a wolfHSM server running on the POSIX transport with
|
||||
## DMA support. By default, DTLS (UDP) mode is used.
|
||||
##
|
||||
## Usage:
|
||||
## 1. Build: make DEBUG=1
|
||||
## 2. Start the wolfHSM server: cd ../../posix/wh_posix_server && ./Build/wh_posix_server.elf --type dma
|
||||
## 3. Run this server: ./Build/wh_server.elf
|
||||
## 4. Connect with a client
|
||||
|
||||
## Project name - sets output filename
|
||||
BIN = wh_server
|
||||
|
||||
## Important directories
|
||||
PROJECT_DIR ?= .
|
||||
CONFIG_DIR ?= $(PROJECT_DIR)/config
|
||||
|
||||
# wolfSSL and wolfHSM directories (relative to this Makefile)
|
||||
WOLFSSL_DIR ?= ../../../../wolfssl
|
||||
WOLFHSM_DIR ?= ../../..
|
||||
WOLFHSM_PORT_DIR ?= $(WOLFHSM_DIR)/port/posix
|
||||
|
||||
# Output directory for build files
|
||||
BUILD_DIR ?= $(PROJECT_DIR)/Build
|
||||
|
||||
## Includes
|
||||
INC = -I$(PROJECT_DIR) \
|
||||
-I$(CONFIG_DIR) \
|
||||
-I$(WOLFSSL_DIR) \
|
||||
-I$(WOLFHSM_DIR) \
|
||||
-I$(WOLFHSM_PORT_DIR)
|
||||
|
||||
## Defines
|
||||
# POSIX requires C source be defined before any header
|
||||
DEF += -D_POSIX_C_SOURCE=200809L
|
||||
|
||||
# Library configuration defines for user-supplied settings
|
||||
DEF += -DWOLFSSL_USER_SETTINGS -DWOLFHSM_CFG
|
||||
|
||||
# Enable DMA transport by default (matches server --type dma)
|
||||
DEF += -DWOLFHSM_CFG_DMA
|
||||
|
||||
## Architecture flags
|
||||
ARCHFLAGS ?=
|
||||
|
||||
## Compiler and linker flags
|
||||
ASFLAGS ?= $(ARCHFLAGS)
|
||||
CFLAGS_EXTRA ?= -Wextra
|
||||
CFLAGS ?= $(ARCHFLAGS) -Wno-cpp -std=c99 -Wall -Werror $(CFLAGS_EXTRA)
|
||||
LDFLAGS ?= $(ARCHFLAGS)
|
||||
LIBS = -lc -lm
|
||||
|
||||
# Platform-specific linker flags for dead code stripping
|
||||
OS_NAME := $(shell uname -s | tr A-Z a-z)
|
||||
ifeq ($(OS_NAME),darwin)
|
||||
LDFLAGS += -Wl,-dead_strip
|
||||
else
|
||||
LDFLAGS += -Wl,--gc-sections
|
||||
endif
|
||||
|
||||
## Makefile options
|
||||
|
||||
# Set to @ to suppress command echo
|
||||
CMD_ECHO ?=
|
||||
|
||||
# Debug build
|
||||
ifeq ($(DEBUG),1)
|
||||
DBGFLAGS = -ggdb -g3 -O0
|
||||
CFLAGS += $(DBGFLAGS)
|
||||
LDFLAGS += $(DBGFLAGS)
|
||||
DEF += -DWOLFHSM_CFG_DEBUG
|
||||
endif
|
||||
|
||||
# Verbose debug output
|
||||
ifeq ($(DEBUG_VERBOSE),1)
|
||||
DBGFLAGS = -ggdb -g3 -O0
|
||||
CFLAGS += $(DBGFLAGS)
|
||||
LDFLAGS += $(DBGFLAGS)
|
||||
DEF += -DWOLFHSM_CFG_DEBUG -DWOLFHSM_CFG_DEBUG_VERBOSE
|
||||
endif
|
||||
|
||||
# Address sanitizer
|
||||
ifeq ($(ASAN),1)
|
||||
CFLAGS += -fsanitize=address
|
||||
LDFLAGS += -fsanitize=address
|
||||
endif
|
||||
|
||||
## Source files
|
||||
|
||||
# wolfCrypt source files
|
||||
SRC_C += $(wildcard $(WOLFSSL_DIR)/wolfcrypt/src/*.c)
|
||||
|
||||
# wolfSSL TLS source files
|
||||
SRC_C += $(wildcard $(WOLFSSL_DIR)/src/*.c)
|
||||
|
||||
# wolfHSM source files
|
||||
SRC_C += $(wildcard $(WOLFHSM_DIR)/src/*.c)
|
||||
|
||||
# wolfHSM POSIX port/HAL code
|
||||
SRC_C += $(wildcard $(WOLFHSM_PORT_DIR)/*.c)
|
||||
|
||||
# Project source files
|
||||
SRC_C += $(PROJECT_DIR)/server.c
|
||||
SRC_C += $(PROJECT_DIR)/server_io.c
|
||||
|
||||
## Automated processing
|
||||
|
||||
FILENAMES_C = $(notdir $(SRC_C))
|
||||
OBJS_C = $(addprefix $(BUILD_DIR)/, $(FILENAMES_C:.c=.o))
|
||||
vpath %.c $(dir $(SRC_C))
|
||||
|
||||
## Makefile Targets
|
||||
|
||||
.PHONY: all build clean help
|
||||
|
||||
all: build
|
||||
|
||||
build: $(BUILD_DIR) $(BUILD_DIR)/$(BIN).elf
|
||||
|
||||
$(BUILD_DIR):
|
||||
$(CMD_ECHO) mkdir -p $(BUILD_DIR)
|
||||
|
||||
$(BUILD_DIR)/%.o: %.c
|
||||
@echo "Compiling: $(notdir $<)"
|
||||
$(CMD_ECHO) $(CC) $(CFLAGS) $(DEF) $(INC) -c -o $@ $<
|
||||
|
||||
$(BUILD_DIR)/$(BIN).elf: $(OBJS_C)
|
||||
@echo "Linking: $(notdir $@)"
|
||||
$(CMD_ECHO) $(CC) $(LDFLAGS) -o $@ $^ $(LIBS)
|
||||
|
||||
clean:
|
||||
@echo "Cleaning build files..."
|
||||
@rm -rf $(BUILD_DIR)
|
||||
|
||||
help:
|
||||
@echo "TLS/DTLS Server with wolfHSM Crypto Offload"
|
||||
@echo ""
|
||||
@echo "Options:"
|
||||
@echo " DEBUG=1 - Enable debug build with symbols"
|
||||
@echo " DEBUG_VERBOSE=1 - Enable verbose debug output"
|
||||
@echo " ASAN=1 - Enable address sanitizer"
|
||||
@echo ""
|
||||
@echo "Example:"
|
||||
@echo " make DEBUG=1"
|
||||
|
|
@ -0,0 +1,219 @@
|
|||
# TLS/DTLS Server with wolfHSM Crypto Offload
|
||||
|
||||
This example demonstrates a TLS/DTLS server that offloads cryptographic
|
||||
operations to a wolfHSM server. By default, DTLS (UDP-based) is used, but
|
||||
the code can be adapted for TLS (TCP-based) connections.
|
||||
|
||||
The wolfHSM server runs separately and communicates via the chosen transport.
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
+-------------------+ Shared Memory (DMA) +-------------------+
|
||||
| | <-----------------------------> | |
|
||||
| TLS/DTLS Server | Crypto Operations Request | wolfHSM Server |
|
||||
| (This Example) | <-----------------------------> | (wh_posix_server)|
|
||||
| | Crypto Operations Response | |
|
||||
+-------------------+ +-------------------+
|
||||
| |
|
||||
| TLS/DTLS | Performs all
|
||||
| | crypto ops:
|
||||
v | - Key Exchange
|
||||
+-------------------+ | - Signing
|
||||
| TLS/DTLS Client | | - Encryption
|
||||
| | | - Hashing
|
||||
+-------------------+ +
|
||||
```
|
||||
|
||||
## How It Works
|
||||
|
||||
1. **wolfHSM Server**: The `wh_posix_server` runs with `--type dma` to provide
|
||||
crypto services over shared memory with DMA support.
|
||||
|
||||
2. **TLS/DTLS Server**: This example connects to the wolfHSM server as a client
|
||||
and registers a crypto callback. All wolfSSL/wolfCrypt operations are
|
||||
forwarded to the HSM.
|
||||
|
||||
3. **Crypto Offload**: When `wolfSSL_CTX_SetDevId()` is called with `WH_DEV_ID`,
|
||||
wolfSSL routes crypto operations through the registered callback to the
|
||||
wolfHSM server.
|
||||
|
||||
## Building
|
||||
|
||||
### Prerequisites
|
||||
|
||||
1. wolfSSL library built with crypto callback support
|
||||
2. wolfHSM library with POSIX port
|
||||
|
||||
### Build Steps
|
||||
|
||||
```bash
|
||||
# Build the server
|
||||
cd examples/demo/dtls_server
|
||||
make
|
||||
|
||||
# Build the wolfHSM POSIX server (if not already built)
|
||||
cd ../../posix/wh_posix_server
|
||||
make DMA=1
|
||||
```
|
||||
|
||||
## Running
|
||||
|
||||
### Step 1: Start the wolfHSM Server
|
||||
|
||||
```bash
|
||||
cd examples/posix/wh_posix_server
|
||||
./Build/wh_posix_server.elf --type dma
|
||||
```
|
||||
|
||||
You should see:
|
||||
```
|
||||
Example wolfHSM POSIX server built with wolfSSL version X.X.X
|
||||
Using DMA with shared memory transport
|
||||
Waiting for connection...
|
||||
```
|
||||
|
||||
### Step 2: Start the Server
|
||||
|
||||
In a new terminal:
|
||||
|
||||
```bash
|
||||
cd examples/demo/dtls_server
|
||||
./Build/wh_server.elf
|
||||
```
|
||||
|
||||
#### Command-Line Options
|
||||
|
||||
```
|
||||
Usage: ./Build/wh_server.elf [options]
|
||||
|
||||
Options:
|
||||
-A <file> CA certificate file (PEM or DER format)
|
||||
If not specified, uses built-in test certificate
|
||||
-c <file> Server certificate file (PEM or DER format)
|
||||
-k <file> Server private key file (PEM or DER format)
|
||||
-p <port> Port to listen on (default: 11111)
|
||||
-h Show this help message
|
||||
```
|
||||
|
||||
#### Examples
|
||||
|
||||
```bash
|
||||
# Use default built-in certificates
|
||||
./Build/wh_server.elf
|
||||
|
||||
# Use client-cert.pem from wolfssl bundle for example client to connect
|
||||
./Build/wh_server.elf -A /path/to/wolfssl/certs/client-cert.pem
|
||||
|
||||
# Use custom certificates and port
|
||||
./Build/wh_server.elf -A ca.pem -c server.pem -k server-key.pem -p 4433
|
||||
```
|
||||
|
||||
You should see:
|
||||
```
|
||||
DTLS server starting on port 11111...
|
||||
Connected to wolfHSM server successfully
|
||||
Waiting for client on port 11111...
|
||||
```
|
||||
|
||||
### Step 3: Connect a Client
|
||||
|
||||
In a third terminal:
|
||||
|
||||
```bash
|
||||
# For DTLS (default mode) - using wolfssl with DTLS 1.3
|
||||
./examples/examples/client -u -v 4
|
||||
```
|
||||
|
||||
## Key Integration Points
|
||||
|
||||
### 1. Registering Crypto Callbacks
|
||||
|
||||
In `server.c`, we register the wolfHSM crypto callbacks:
|
||||
|
||||
```c
|
||||
/* Register crypto callback for non-DMA operations */
|
||||
wc_CryptoCb_RegisterDevice(WH_DEV_ID, wh_Client_CryptoCb, (void*)g_client);
|
||||
|
||||
/* Register crypto callback for DMA operations (larger data) */
|
||||
wc_CryptoCb_RegisterDevice(WH_DEV_ID_DMA, wh_Client_CryptoCbDma, (void*)g_client);
|
||||
```
|
||||
|
||||
### 2. Setting Device ID on wolfSSL Object
|
||||
|
||||
In `server_io.c`, we configure wolfSSL to use the HSM on the WOLFSSL_CTX object:
|
||||
|
||||
```c
|
||||
wolfSSL_CTX_SetDevId(ctx, WH_DEV_ID);
|
||||
```
|
||||
|
||||
### 3. DMA vs Non-DMA
|
||||
|
||||
- **WH_DEV_ID**: Uses standard message-based crypto operations. Suitable for
|
||||
smaller data sizes.
|
||||
|
||||
- **WH_DEV_ID_DMA**: Uses DMA (Direct Memory Access) for data transfer.
|
||||
More efficient for larger data like TLS record encryption.
|
||||
|
||||
## Configuration
|
||||
|
||||
### wolfSSL Configuration (`config/user_settings.h`)
|
||||
|
||||
Key settings for TLS/DTLS with wolfHSM:
|
||||
|
||||
```c
|
||||
/* Enable DTLS 1.3 (for UDP mode) */
|
||||
#define WOLFSSL_DTLS
|
||||
#define WOLFSSL_DTLS13
|
||||
#define WOLFSSL_TLS13
|
||||
|
||||
/* Enable crypto callbacks for wolfHSM */
|
||||
#define WOLF_CRYPTO_CB
|
||||
|
||||
/* Hash DRBG for RNG */
|
||||
#define HAVE_HASHDRBG
|
||||
```
|
||||
|
||||
### wolfHSM Configuration (`config/wolfhsm_cfg.h`)
|
||||
|
||||
Key settings for wolfHSM client:
|
||||
|
||||
```c
|
||||
/* Enable wolfHSM client */
|
||||
#define WOLFHSM_CFG_ENABLE_CLIENT
|
||||
|
||||
/* Enable DMA transport */
|
||||
#define WOLFHSM_CFG_DMA
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### "Failed to connect to wolfHSM server"
|
||||
|
||||
Make sure the `wh_posix_server` is running with `--type dma` before starting
|
||||
the DTLS server.
|
||||
|
||||
### Handshake Failures
|
||||
|
||||
1. Check that both the wolfHSM server and DTLS server are built with the same
|
||||
wolfSSL version.
|
||||
|
||||
2. Verify the shared memory name matches between client and server
|
||||
(default: "wh_example_shm").
|
||||
|
||||
3. Enable verbose debugging:
|
||||
```bash
|
||||
make DEBUG_VERBOSE=1
|
||||
```
|
||||
|
||||
## Adapting for TLS
|
||||
|
||||
To use TLS instead of DTLS:
|
||||
|
||||
1. In `server_io.c`, change the method from `wolfDTLS_server_method()` to
|
||||
`wolfTLSv1_3_server_method()` or another TLS method.
|
||||
|
||||
2. Change the socket initialization from UDP to TCP (replace
|
||||
`initialize_udp_socket()` with a TCP equivalent).
|
||||
|
||||
3. Remove the DTLS-specific peer address setup in `setup_ssl_accept()`.
|
||||
|
|
@ -0,0 +1,135 @@
|
|||
/*
|
||||
* Copyright (C) 2024 wolfSSL Inc.
|
||||
*
|
||||
* This file is part of wolfHSM.
|
||||
*
|
||||
* user_settings.h - wolfSSL configuration for DTLS server demo
|
||||
*
|
||||
* Based on the posix server user_settings.h with TLS enabled.
|
||||
*/
|
||||
|
||||
#ifndef USER_SETTINGS_H
|
||||
#define USER_SETTINGS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** wolfHSM required settings for wolfCrypt */
|
||||
#define WOLF_CRYPTO_CB
|
||||
#define WOLFSSL_KEY_GEN
|
||||
#define WOLFSSL_ASN_TEMPLATE
|
||||
#define WOLFSSL_BASE64_ENCODE
|
||||
#define HAVE_ANONYMOUS_INLINE_AGGREGATES 1
|
||||
|
||||
/** Math library */
|
||||
#define USE_FAST_MATH
|
||||
#define FP_MAX_BITS 8192
|
||||
|
||||
/** General recommended settings */
|
||||
#define WOLFSSL_USE_ALIGN
|
||||
#define WOLFSSL_IGNORE_FILE_WARN
|
||||
#define TFM_TIMING_RESISTANT
|
||||
#define ECC_TIMING_RESISTANT
|
||||
#define WC_RSA_BLINDING
|
||||
|
||||
/** Remove unneeded features */
|
||||
#define NO_MAIN_DRIVER
|
||||
#define NO_INLINE
|
||||
#define NO_DO178
|
||||
|
||||
/** Remove unneeded namespace */
|
||||
#define NO_OLD_RNGNAME
|
||||
#define NO_OLD_WC_NAMES
|
||||
#define NO_OLD_SSL_NAMES
|
||||
#define NO_OLD_SHA_NAMES
|
||||
#define NO_OLD_MD5_NAME
|
||||
|
||||
/** RSA Options */
|
||||
#define RSA_MIN_SIZE 1024
|
||||
#define WC_RSA_PSS
|
||||
#define WOLFSSL_PSS_LONG_SALT
|
||||
|
||||
/** ECC Options */
|
||||
#define HAVE_ECC
|
||||
#define TFM_ECC256
|
||||
#define ECC_SHAMIR
|
||||
#define HAVE_ECC_DHE /* Required for ECDH key agreement (TLS 1.3 key share) */
|
||||
|
||||
/** Curve25519 Options - disabled for this demo
|
||||
* TLS 1.3 will use ECC (P-256) for key share instead */
|
||||
/* #define HAVE_CURVE25519 */
|
||||
|
||||
/** Ed25519 Options - disabled for this demo */
|
||||
/* #define HAVE_ED25519 */
|
||||
|
||||
/** DH Options */
|
||||
#define HAVE_DH_DEFAULT_PARAMS
|
||||
#define HAVE_FFDHE_2048
|
||||
|
||||
/** AES Options */
|
||||
#define HAVE_AES_CBC
|
||||
#define HAVE_AESGCM
|
||||
#define WOLFSSL_AES_COUNTER
|
||||
#define GCM_TABLE_4BIT
|
||||
#define WOLFSSL_AES_DIRECT
|
||||
#define HAVE_AES_ECB
|
||||
#define WOLFSSL_CMAC
|
||||
|
||||
/** SHA Options */
|
||||
/* Keep SHA-1 enabled - required for DTLS 1.2 cipher suites */
|
||||
#define WOLFSSL_SHA224
|
||||
#define WOLFSSL_SHA384
|
||||
#define WOLFSSL_SHA512
|
||||
#define WOLFSSL_SHA512_HASHTYPE
|
||||
|
||||
/** Composite features */
|
||||
#define HAVE_HKDF
|
||||
|
||||
/** RNG configuration */
|
||||
/* Use Hash DRBG (NIST SP 800-90A compliant) */
|
||||
#define HAVE_HASHDRBG
|
||||
|
||||
/** Remove unneeded crypto */
|
||||
#define NO_DSA
|
||||
#define NO_RC4
|
||||
#define NO_MD4
|
||||
/* Keep MD5 for TLS PRF */
|
||||
#define NO_DES3
|
||||
#define NO_PWDBASED
|
||||
|
||||
/** TLS/DTLS settings */
|
||||
#define HAVE_TLS_EXTENSIONS
|
||||
#define HAVE_SUPPORTED_CURVES
|
||||
#define HAVE_EXTENDED_MASTER
|
||||
#define HAVE_ENCRYPT_THEN_MAC
|
||||
#define HAVE_SERVER_RENEGOTIATION_INFO
|
||||
|
||||
/* DTLS support */
|
||||
#define WOLFSSL_DTLS
|
||||
#define WOLFSSL_DTLS13
|
||||
#define WOLFSSL_TLS13
|
||||
#define WOLFSSL_SEND_HRR_COOKIE /* Required for DTLS 1.3 server */
|
||||
|
||||
/* Disable features we don't need */
|
||||
#define NO_PSK
|
||||
#define NO_OLD_TLS
|
||||
|
||||
/* Test certificate buffers for demo */
|
||||
#define USE_CERT_BUFFERS_256
|
||||
#define USE_CERT_BUFFERS_2048
|
||||
|
||||
/* Debug (optional - enabled via Makefile DEBUG=1) */
|
||||
#ifdef WOLFHSM_CFG_DEBUG
|
||||
#define DEBUG_WOLFSSL
|
||||
#endif
|
||||
|
||||
/* Include for POSIX extensions needed by wolfSSL */
|
||||
#include <sys/time.h> /* for struct timeval, gettimeofday */
|
||||
#include <strings.h> /* for strcasecmp */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* USER_SETTINGS_H */
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* Copyright (C) 2024 wolfSSL Inc.
|
||||
*
|
||||
* This file is part of wolfHSM.
|
||||
*
|
||||
* wolfhsm_cfg.h - wolfHSM configuration for DTLS server demo
|
||||
*
|
||||
* This configures the wolfHSM client to connect to the HSM server
|
||||
* for crypto operations.
|
||||
*/
|
||||
|
||||
#ifndef WOLFHSM_CFG_H_
|
||||
#define WOLFHSM_CFG_H_
|
||||
|
||||
#include "port/posix/posix_time.h"
|
||||
|
||||
/* Time function for wolfHSM */
|
||||
#define WOLFHSM_CFG_PORT_GETTIME posixGetTime
|
||||
|
||||
/* Enable wolfHSM client */
|
||||
#define WOLFHSM_CFG_ENABLE_CLIENT
|
||||
|
||||
/* DMA transport is enabled via Makefile -DWOLFHSM_CFG_DMA */
|
||||
/* Debug output is enabled via Makefile when DEBUG=1 */
|
||||
|
||||
/* Verbose debug output (uncomment for detailed tracing) */
|
||||
/* #define WOLFHSM_CFG_DEBUG_VERBOSE */
|
||||
|
||||
/* Enable hexdump utility */
|
||||
#define WOLFHSM_CFG_HEXDUMP
|
||||
|
||||
/* Communication data length - must match server configuration */
|
||||
#define WOLFHSM_CFG_COMM_DATA_LEN 5000
|
||||
|
||||
/* Enable key wrapping support */
|
||||
#define WOLFHSM_CFG_KEYWRAP
|
||||
|
||||
/* Enable global keys feature */
|
||||
#define WOLFHSM_CFG_GLOBAL_KEYS
|
||||
|
||||
#endif /* WOLFHSM_CFG_H_ */
|
||||
|
|
@ -0,0 +1,276 @@
|
|||
/*
|
||||
* Copyright (C) 2024 wolfSSL Inc.
|
||||
*
|
||||
* This file is part of wolfHSM.
|
||||
*
|
||||
* TLS/DTLS Server Demo using wolfHSM for Crypto Operations
|
||||
*
|
||||
* This example demonstrates a server that offloads all cryptographic
|
||||
* operations to a wolfHSM server running on the POSIX transport with
|
||||
* DMA support. By default, DTLS is used but the code can be adapted
|
||||
* for TLS connections.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <getopt.h>
|
||||
|
||||
#include "server.h"
|
||||
|
||||
/* wolfHSM client includes */
|
||||
#include "wolfhsm/wh_error.h"
|
||||
#include "wolfhsm/wh_comm.h"
|
||||
#include "wolfhsm/wh_client.h"
|
||||
#include "wolfhsm/wh_client_cryptocb.h"
|
||||
#include "port/posix/posix_transport_shm.h"
|
||||
|
||||
/* wolfSSL includes for crypto callback registration */
|
||||
#include "wolfssl/wolfcrypt/settings.h"
|
||||
#include "wolfssl/wolfcrypt/cryptocb.h"
|
||||
|
||||
/* Shared POSIX example configuration */
|
||||
#include "examples/posix/wh_posix_cfg.h"
|
||||
|
||||
/* Global wolfHSM client context */
|
||||
static whClientContext g_client[1] = {{0}};
|
||||
static posixTransportShmClientContext g_shm_client_ctx;
|
||||
static posixTransportShmConfig g_shm_config;
|
||||
static whCommClientConfig g_comm_config;
|
||||
static whClientConfig g_client_config;
|
||||
|
||||
#ifdef WOLFHSM_CFG_DMA
|
||||
/* DMA configuration for large data transfers */
|
||||
static whClientDmaConfig g_dma_config;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Connect to the wolfHSM server over shared memory DMA transport.
|
||||
*
|
||||
* This establishes a connection to the HSM server and registers the
|
||||
* crypto callback so that wolfSSL crypto operations are forwarded to
|
||||
* the HSM.
|
||||
*/
|
||||
static int connect_to_hsm_server(void)
|
||||
{
|
||||
int ret;
|
||||
static const whTransportClientCb shm_cb = POSIX_TRANSPORT_SHM_CLIENT_CB;
|
||||
|
||||
|
||||
/* Initialize transport context */
|
||||
memset(&g_shm_client_ctx, 0, sizeof(g_shm_client_ctx));
|
||||
memset(&g_comm_config, 0, sizeof(g_comm_config));
|
||||
memset(&g_client_config, 0, sizeof(g_client_config));
|
||||
|
||||
/* Configure shared memory transport with DMA */
|
||||
g_shm_config.name = WH_POSIX_SHARED_MEMORY_NAME;
|
||||
g_shm_config.req_size = WH_POSIX_REQ_SIZE;
|
||||
g_shm_config.resp_size = WH_POSIX_RESP_SIZE;
|
||||
g_shm_config.dma_size = WH_POSIX_DMA_SIZE;
|
||||
|
||||
/* Configure comm layer */
|
||||
g_comm_config.transport_cb = &shm_cb;
|
||||
g_comm_config.transport_context = (void*)&g_shm_client_ctx;
|
||||
g_comm_config.transport_config = (void*)&g_shm_config;
|
||||
g_comm_config.client_id = WH_POSIX_CLIENT_ID;
|
||||
|
||||
#ifdef WOLFHSM_CFG_DMA
|
||||
/* Configure DMA callbacks for static memory operations */
|
||||
g_dma_config.cb = posixTransportShm_ClientStaticMemDmaCallback;
|
||||
g_dma_config.dmaAddrAllowList = NULL;
|
||||
g_client_config.dmaConfig = &g_dma_config;
|
||||
#endif
|
||||
|
||||
/* Configure client */
|
||||
g_client_config.comm = &g_comm_config;
|
||||
|
||||
/* Initialize the client */
|
||||
ret = wh_Client_Init(g_client, &g_client_config);
|
||||
if (ret != WH_ERROR_OK) {
|
||||
fprintf(stderr, "Failed to initialize wolfHSM client: %d\n", ret);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Initialize communication with the server */
|
||||
ret = wh_Client_CommInit(g_client, NULL, NULL);
|
||||
if (ret != WH_ERROR_OK) {
|
||||
fprintf(stderr, "Failed to initialize wolfHSM client communication: %d\n", ret);
|
||||
wh_Client_Cleanup(g_client);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Register crypto callback for non-DMA operations */
|
||||
ret = wc_CryptoCb_RegisterDevice(WH_DEV_ID, wh_Client_CryptoCb,
|
||||
(void*)g_client);
|
||||
if (ret != 0) {
|
||||
fprintf(stderr, "Failed to register crypto callback: %d\n", ret);
|
||||
wh_Client_CommClose(g_client);
|
||||
wh_Client_Cleanup(g_client);
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef WOLFHSM_CFG_DMA
|
||||
/* Register crypto callback for DMA operations */
|
||||
ret = wc_CryptoCb_RegisterDevice(WH_DEV_ID_DMA, wh_Client_CryptoCbDma,
|
||||
(void*)g_client);
|
||||
if (ret != 0) {
|
||||
fprintf(stderr, "Failed to register DMA crypto callback: %d\n", ret);
|
||||
wc_CryptoCb_UnRegisterDevice(WH_DEV_ID);
|
||||
wh_Client_CommClose(g_client);
|
||||
wh_Client_Cleanup(g_client);
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
printf("Connected to wolfHSM server successfully\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Disconnect from wolfHSM server */
|
||||
static void disconnect_from_hsm_server(void)
|
||||
{
|
||||
printf("Disconnecting from wolfHSM server...\n");
|
||||
|
||||
#ifdef WOLFHSM_CFG_DMA
|
||||
wc_CryptoCb_UnRegisterDevice(WH_DEV_ID_DMA);
|
||||
#endif
|
||||
wc_CryptoCb_UnRegisterDevice(WH_DEV_ID);
|
||||
|
||||
wh_Client_CommClose(g_client);
|
||||
wh_Client_Cleanup(g_client);
|
||||
}
|
||||
|
||||
/* Print usage information */
|
||||
static void print_usage(const char* progname)
|
||||
{
|
||||
printf("Usage: %s [options]\n", progname);
|
||||
printf("\n");
|
||||
printf("TLS/DTLS server demo using wolfHSM for crypto operations.\n");
|
||||
printf("By default, uses DTLS over UDP.\n");
|
||||
printf("\n");
|
||||
printf("Options:\n");
|
||||
printf(" -A <file> CA certificate file (PEM or DER format)\n");
|
||||
printf(" If not specified, uses built-in test certificate\n");
|
||||
printf(" -c <file> Server certificate file (PEM or DER format)\n");
|
||||
printf(" -k <file> Server private key file (PEM or DER format)\n");
|
||||
printf(" -p <port> Port to listen on (default: 11111)\n");
|
||||
printf(" -h Show this help message\n");
|
||||
printf("\n");
|
||||
printf("Prerequisites:\n");
|
||||
printf(" Start the wolfHSM server first:\n");
|
||||
printf(" cd examples/posix/wh_posix_server\n");
|
||||
printf(" ./Build/wh_posix_server.elf --type dma\n");
|
||||
printf("\n");
|
||||
printf("Example:\n");
|
||||
printf(" %s -A ca-cert.pem\n", progname);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* Main application entry point.
|
||||
*
|
||||
* This sets up the wolfHSM client connection, then initializes the
|
||||
* server which will use wolfHSM for all crypto operations.
|
||||
*/
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
SERVER_CONTEXT* ctx;
|
||||
ServerConfig config = {0};
|
||||
int ret;
|
||||
int exit_code = 0;
|
||||
unsigned char buf[256];
|
||||
int bytesRead;
|
||||
int opt;
|
||||
|
||||
/* Set default port */
|
||||
config.port = 11111;
|
||||
|
||||
/* Parse command line arguments */
|
||||
while ((opt = getopt(argc, argv, "A:c:k:p:h")) != -1) {
|
||||
switch (opt) {
|
||||
case 'A':
|
||||
config.caCertFile = optarg;
|
||||
break;
|
||||
case 'c':
|
||||
config.serverCertFile = optarg;
|
||||
break;
|
||||
case 'k':
|
||||
config.serverKeyFile = optarg;
|
||||
break;
|
||||
case 'p':
|
||||
config.port = atoi(optarg);
|
||||
if (config.port <= 0 || config.port > 65535) {
|
||||
fprintf(stderr, "Invalid port number: %s\n", optarg);
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
case 'h':
|
||||
print_usage(argv[0]);
|
||||
return 0;
|
||||
default:
|
||||
print_usage(argv[0]);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
printf("DTLS server starting on port %d...\n", config.port);
|
||||
|
||||
/* Initialize wolfCrypt */
|
||||
ret = wolfCrypt_Init();
|
||||
if (ret != 0) {
|
||||
fprintf(stderr, "Failed to initialize wolfCrypt: %d\n", ret);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Connect to the wolfHSM server */
|
||||
if (connect_to_hsm_server() != 0) {
|
||||
fprintf(stderr, "Failed to connect to wolfHSM server\n");
|
||||
fprintf(stderr, "Make sure wh_posix_server is running with --type dma\n");
|
||||
wolfCrypt_Cleanup();
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Get the server context and initialize it */
|
||||
ctx = Server_Get();
|
||||
ret = Server_Init(ctx, g_client, &config);
|
||||
if (ret != 0) {
|
||||
fprintf(stderr, "Failed to initialize server: %d\n", ret);
|
||||
exit_code = 1;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Accept a connection */
|
||||
printf("Waiting for client...\n");
|
||||
ret = Server_Accept(ctx);
|
||||
if (ret != 0) {
|
||||
fprintf(stderr, "Failed to accept connection: %d\n", ret);
|
||||
exit_code = 1;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
printf("Connected. Entering echo mode...\n");
|
||||
while (1) {
|
||||
memset(buf, 0, sizeof(buf));
|
||||
bytesRead = Server_Read(ctx, buf, sizeof(buf) - 1);
|
||||
if (bytesRead <= 0) {
|
||||
printf("Client disconnected\n");
|
||||
break;
|
||||
}
|
||||
|
||||
printf("Received %d bytes: %s\n", bytesRead, buf);
|
||||
|
||||
/* Echo back */
|
||||
ret = Server_Write(ctx, buf, bytesRead);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Failed to write response\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
cleanup:
|
||||
Server_Cleanup(ctx);
|
||||
disconnect_from_hsm_server();
|
||||
wolfCrypt_Cleanup();
|
||||
return exit_code;
|
||||
}
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* Copyright (C) 2024 wolfSSL Inc.
|
||||
*
|
||||
* This file is part of wolfHSM.
|
||||
*
|
||||
* wolfHSM is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* wolfHSM is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with wolfHSM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/*
|
||||
* server.h
|
||||
*
|
||||
* Header for the TLS/DTLS server demo that uses wolfHSM for crypto operations.
|
||||
* This API is protocol-agnostic and can be used for both TLS and DTLS.
|
||||
*/
|
||||
|
||||
#ifndef SERVER_H_
|
||||
#define SERVER_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include "wolfhsm/wh_client.h"
|
||||
|
||||
/* Forward declaration for opaque server structure */
|
||||
typedef struct SERVER_CONTEXT SERVER_CONTEXT;
|
||||
|
||||
/* Server configuration */
|
||||
typedef struct ServerConfig {
|
||||
const char* caCertFile; /* Path to CA certificate file (PEM or DER) */
|
||||
const char* serverCertFile; /* Path to server certificate file (optional) */
|
||||
const char* serverKeyFile; /* Path to server private key file (optional) */
|
||||
int port; /* Port to listen on (default: 11111) */
|
||||
} ServerConfig;
|
||||
|
||||
/* Server management functions */
|
||||
SERVER_CONTEXT* Server_Get(void);
|
||||
int Server_Init(SERVER_CONTEXT* ctx, whClientContext* client,
|
||||
const ServerConfig* config);
|
||||
int Server_Accept(SERVER_CONTEXT* ctx);
|
||||
void Server_Cleanup(SERVER_CONTEXT* ctx);
|
||||
int Server_Close(SERVER_CONTEXT* ctx);
|
||||
|
||||
/* Data transfer functions */
|
||||
int Server_Read(SERVER_CONTEXT* ctx, unsigned char* data, size_t length);
|
||||
int Server_Write(SERVER_CONTEXT* ctx, unsigned char* data, size_t length);
|
||||
|
||||
#endif /* SERVER_H_ */
|
||||
|
|
@ -0,0 +1,457 @@
|
|||
/*
|
||||
* Copyright (C) 2024 wolfSSL Inc.
|
||||
*
|
||||
* This file is part of wolfHSM.
|
||||
*
|
||||
* Server I/O functions for the TLS/DTLS server demo.
|
||||
*
|
||||
* This module handles TLS/DTLS I/O operations. By default, DTLS is used.
|
||||
* The key integration point with wolfHSM is setting the device ID (WH_DEV_ID)
|
||||
* on the wolfSSL context so that crypto operations are forwarded to the HSM.
|
||||
*/
|
||||
|
||||
#include "server.h"
|
||||
|
||||
/* wolfSSL includes */
|
||||
#include <wolfssl/wolfcrypt/settings.h>
|
||||
#include <wolfssl/ssl.h>
|
||||
#include <wolfssl/wolfcrypt/cryptocb.h>
|
||||
|
||||
/* wolfHSM client includes */
|
||||
#include "wolfhsm/wh_client.h"
|
||||
|
||||
/* Standard includes */
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/* Test certificate buffers from wolfSSL for demo purposes */
|
||||
#undef USE_CERT_BUFFERS_2048
|
||||
#define USE_CERT_BUFFERS_2048
|
||||
#undef USE_CERT_BUFFERS_256
|
||||
#define USE_CERT_BUFFERS_256
|
||||
#include "wolfssl/certs_test.h"
|
||||
|
||||
/* Default server port */
|
||||
#define SERVER_PORT_DEFAULT 11111
|
||||
|
||||
/* Static wolfSSL context - shared across connections */
|
||||
static WOLFSSL_CTX* g_ctx = NULL;
|
||||
|
||||
/* Static configuration - set during init */
|
||||
static ServerConfig g_config = {0};
|
||||
|
||||
/* Server context structure */
|
||||
struct SERVER_CONTEXT {
|
||||
WOLFSSL* ssl;
|
||||
whClientContext* hsm_client;
|
||||
int listenfd;
|
||||
struct sockaddr_in cliaddr;
|
||||
socklen_t cliLen;
|
||||
int port;
|
||||
};
|
||||
|
||||
/* Single static instance of the server */
|
||||
static SERVER_CONTEXT g_server = {
|
||||
.ssl = NULL,
|
||||
.hsm_client = NULL,
|
||||
.listenfd = -1,
|
||||
.port = 0
|
||||
};
|
||||
|
||||
/*
|
||||
* Initialize wolfSSL library and create a context.
|
||||
*
|
||||
* Uses DTLS server method with version negotiation (prefers DTLS 1.3).
|
||||
* This can be changed to TLS by modifying the method call below.
|
||||
*
|
||||
* The key here is setting the device ID to WH_DEV_ID so that all
|
||||
* crypto operations are forwarded to the wolfHSM server.
|
||||
*/
|
||||
static int initialize_wolfssl(WOLFSSL_CTX** ctx, whClientContext* hsm_client)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
ret = wolfSSL_Init();
|
||||
if (ret != WOLFSSL_SUCCESS) {
|
||||
printf("Failed to initialize wolfSSL, ret = %d\n", ret);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Enable debug output */
|
||||
wolfSSL_Debugging_ON();
|
||||
|
||||
/* Create a new context for server - DTLS with version negotiation
|
||||
* This will use DTLS 1.3 if both sides support it, otherwise falls back.
|
||||
* Note: For DTLS 1.3-only, use wolfDTLSv1_3_server_method() but ensure
|
||||
* the crypto callback supports TLS 1.3 key exchange operations. */
|
||||
*ctx = wolfSSL_CTX_new(wolfDTLS_server_method());
|
||||
if (*ctx == NULL) {
|
||||
printf("Failed to create wolfSSL context\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* @TODO have an option for WH_DEV_ID_DMA */
|
||||
wolfSSL_CTX_SetDevId(*ctx, WH_DEV_ID);
|
||||
|
||||
/* Load CA certificate for client verification */
|
||||
if (g_config.caCertFile != NULL) {
|
||||
/* wolfSSL_CTX_load_verify_locations auto-detects PEM vs DER format */
|
||||
ret = wolfSSL_CTX_load_verify_locations(*ctx, g_config.caCertFile, NULL);
|
||||
if (ret != WOLFSSL_SUCCESS) {
|
||||
printf("Failed to load CA certificate from %s, ret = %d\n",
|
||||
g_config.caCertFile, ret);
|
||||
wolfSSL_CTX_free(*ctx);
|
||||
*ctx = NULL;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Use built-in test certificate */
|
||||
ret = wolfSSL_CTX_load_verify_buffer(*ctx, ca_cert_der_2048,
|
||||
sizeof_ca_cert_der_2048,
|
||||
WOLFSSL_FILETYPE_ASN1);
|
||||
if (ret != WOLFSSL_SUCCESS) {
|
||||
printf("Failed to load built-in CA certificate, ret = %d\n", ret);
|
||||
wolfSSL_CTX_free(*ctx);
|
||||
*ctx = NULL;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Load server certificate */
|
||||
if (g_config.serverCertFile != NULL) {
|
||||
ret = wolfSSL_CTX_use_certificate_file(*ctx, g_config.serverCertFile,
|
||||
WOLFSSL_FILETYPE_PEM);
|
||||
if (ret != WOLFSSL_SUCCESS) {
|
||||
/* Try DER format */
|
||||
ret = wolfSSL_CTX_use_certificate_file(*ctx, g_config.serverCertFile,
|
||||
WOLFSSL_FILETYPE_ASN1);
|
||||
}
|
||||
if (ret != WOLFSSL_SUCCESS) {
|
||||
printf("Failed to load server certificate from %s, ret = %d\n",
|
||||
g_config.serverCertFile, ret);
|
||||
wolfSSL_CTX_free(*ctx);
|
||||
*ctx = NULL;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
ret = wolfSSL_CTX_use_certificate_buffer(*ctx, server_cert_der_2048,
|
||||
sizeof_server_cert_der_2048,
|
||||
WOLFSSL_FILETYPE_ASN1);
|
||||
if (ret != WOLFSSL_SUCCESS) {
|
||||
printf("Failed to load built-in server certificate, ret = %d\n", ret);
|
||||
wolfSSL_CTX_free(*ctx);
|
||||
*ctx = NULL;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Load server private key */
|
||||
if (g_config.serverKeyFile != NULL) {
|
||||
ret = wolfSSL_CTX_use_PrivateKey_file(*ctx, g_config.serverKeyFile,
|
||||
WOLFSSL_FILETYPE_PEM);
|
||||
if (ret != WOLFSSL_SUCCESS) {
|
||||
/* Try DER format */
|
||||
ret = wolfSSL_CTX_use_PrivateKey_file(*ctx, g_config.serverKeyFile,
|
||||
WOLFSSL_FILETYPE_ASN1);
|
||||
}
|
||||
if (ret != WOLFSSL_SUCCESS) {
|
||||
printf("Failed to load server private key from %s, ret = %d\n",
|
||||
g_config.serverKeyFile, ret);
|
||||
wolfSSL_CTX_free(*ctx);
|
||||
*ctx = NULL;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
ret = wolfSSL_CTX_use_PrivateKey_buffer(*ctx, server_key_der_2048,
|
||||
sizeof_server_key_der_2048,
|
||||
WOLFSSL_FILETYPE_ASN1);
|
||||
if (ret != WOLFSSL_SUCCESS) {
|
||||
printf("Failed to load built-in server private key, ret = %d\n", ret);
|
||||
wolfSSL_CTX_free(*ctx);
|
||||
*ctx = NULL;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Require mutual authentication */
|
||||
wolfSSL_CTX_set_verify(*ctx,
|
||||
WOLFSSL_VERIFY_PEER | WOLFSSL_VERIFY_FAIL_IF_NO_PEER_CERT,
|
||||
NULL);
|
||||
|
||||
(void)hsm_client;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize the UDP socket for DTLS.
|
||||
* For TLS, this would need to be changed to TCP socket initialization.
|
||||
*/
|
||||
static int initialize_udp_socket(SERVER_CONTEXT* ctx)
|
||||
{
|
||||
int ret;
|
||||
struct sockaddr_in servAddr;
|
||||
char peekBuf[1];
|
||||
int optval = 1;
|
||||
|
||||
/* Create a UDP socket */
|
||||
ctx->listenfd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (ctx->listenfd < 0) {
|
||||
perror("socket()");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Allow socket reuse */
|
||||
ret = setsockopt(ctx->listenfd, SOL_SOCKET, SO_REUSEADDR, &optval,
|
||||
sizeof(optval));
|
||||
if (ret < 0) {
|
||||
perror("setsockopt(SO_REUSEADDR)");
|
||||
close(ctx->listenfd);
|
||||
ctx->listenfd = -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Bind to all interfaces on the specified port */
|
||||
memset(&servAddr, 0, sizeof(servAddr));
|
||||
servAddr.sin_family = AF_INET;
|
||||
servAddr.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
servAddr.sin_port = htons(ctx->port);
|
||||
|
||||
ret = bind(ctx->listenfd, (struct sockaddr*)&servAddr, sizeof(servAddr));
|
||||
if (ret < 0) {
|
||||
perror("bind()");
|
||||
close(ctx->listenfd);
|
||||
ctx->listenfd = -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Wait for the first packet to get client address */
|
||||
printf("Waiting for client on port %d...\n", ctx->port);
|
||||
|
||||
ctx->cliLen = sizeof(ctx->cliaddr);
|
||||
ret = recvfrom(ctx->listenfd, peekBuf, sizeof(peekBuf), MSG_PEEK,
|
||||
(struct sockaddr*)&ctx->cliaddr, &ctx->cliLen);
|
||||
if (ret < 0) {
|
||||
perror("recvfrom()");
|
||||
close(ctx->listenfd);
|
||||
ctx->listenfd = -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("Received initial packet from %s:%d\n",
|
||||
inet_ntoa(ctx->cliaddr.sin_addr),
|
||||
ntohs(ctx->cliaddr.sin_port));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set up the WOLFSSL object for accepting a connection.
|
||||
* For DTLS, this includes setting the peer address.
|
||||
*/
|
||||
static int setup_ssl_accept(SERVER_CONTEXT* ctx)
|
||||
{
|
||||
ctx->ssl = wolfSSL_new(g_ctx);
|
||||
if (ctx->ssl == NULL) {
|
||||
fprintf(stderr, "wolfSSL_new error - check debug output above\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Set the peer address (DTLS-specific) */
|
||||
if (wolfSSL_dtls_set_peer(ctx->ssl, &ctx->cliaddr,
|
||||
ctx->cliLen) != WOLFSSL_SUCCESS) {
|
||||
fprintf(stderr, "wolfSSL_dtls_set_peer error\n");
|
||||
wolfSSL_free(ctx->ssl);
|
||||
ctx->ssl = NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (wolfSSL_set_fd(ctx->ssl, ctx->listenfd) != WOLFSSL_SUCCESS) {
|
||||
fprintf(stderr, "wolfSSL_set_fd error\n");
|
||||
wolfSSL_free(ctx->ssl);
|
||||
ctx->ssl = NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Perform the TLS/DTLS handshake.
|
||||
*
|
||||
* All crypto operations during this handshake (key exchange, signatures,
|
||||
* encryption) will be performed by the wolfHSM server.
|
||||
*/
|
||||
static int perform_ssl_accept(SERVER_CONTEXT* ctx)
|
||||
{
|
||||
int ret;
|
||||
|
||||
printf("Starting handshake (crypto via wolfHSM)...\n");
|
||||
|
||||
ret = wolfSSL_accept(ctx->ssl);
|
||||
if (ret != WOLFSSL_SUCCESS) {
|
||||
int err = wolfSSL_get_error(ctx->ssl, ret);
|
||||
fprintf(stderr, "wolfSSL_accept failed: error = %d, %s\n", err,
|
||||
wolfSSL_ERR_reason_error_string(err));
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("Handshake successful!\n");
|
||||
printf("Cipher: %s\n", wolfSSL_get_cipher(ctx->ssl));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Public API implementations */
|
||||
|
||||
SERVER_CONTEXT* Server_Get(void)
|
||||
{
|
||||
return &g_server;
|
||||
}
|
||||
|
||||
int Server_Init(SERVER_CONTEXT* ctx, whClientContext* client,
|
||||
const ServerConfig* config)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (ctx == NULL || client == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Store config in static variable for use by initialize_wolfssl */
|
||||
if (config != NULL) {
|
||||
g_config = *config;
|
||||
} else {
|
||||
memset(&g_config, 0, sizeof(g_config));
|
||||
g_config.port = SERVER_PORT_DEFAULT;
|
||||
}
|
||||
|
||||
memset(ctx, 0, sizeof(SERVER_CONTEXT));
|
||||
ctx->listenfd = -1; /* Initialize to invalid fd to prevent closing stdin */
|
||||
ctx->hsm_client = client;
|
||||
ctx->port = (g_config.port > 0) ? g_config.port : SERVER_PORT_DEFAULT;
|
||||
|
||||
/* Initialize wolfSSL with HSM crypto offload */
|
||||
ret = initialize_wolfssl(&g_ctx, client);
|
||||
if (ret != 0) {
|
||||
fprintf(stderr, "Failed to initialize wolfSSL\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Initialize UDP socket and wait for client (DTLS mode) */
|
||||
ret = initialize_udp_socket(ctx);
|
||||
if (ret != 0) {
|
||||
fprintf(stderr, "Failed to initialize socket\n");
|
||||
wolfSSL_CTX_free(g_ctx);
|
||||
g_ctx = NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Set up SSL for accepting connection */
|
||||
ret = setup_ssl_accept(ctx);
|
||||
if (ret != 0) {
|
||||
fprintf(stderr, "Failed to set up SSL accept\n");
|
||||
close(ctx->listenfd);
|
||||
ctx->listenfd = -1;
|
||||
wolfSSL_CTX_free(g_ctx);
|
||||
g_ctx = NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Server_Accept(SERVER_CONTEXT* ctx)
|
||||
{
|
||||
if (ctx == NULL || ctx->ssl == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return perform_ssl_accept(ctx);
|
||||
}
|
||||
|
||||
int Server_Read(SERVER_CONTEXT* ctx, unsigned char* data, size_t length)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (ctx == NULL || ctx->ssl == NULL || data == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (length > INT_MAX) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = wolfSSL_read(ctx->ssl, data, (int)length);
|
||||
if (ret < 0) {
|
||||
int err = wolfSSL_get_error(ctx->ssl, ret);
|
||||
if (err != WOLFSSL_ERROR_WANT_READ) {
|
||||
fprintf(stderr, "wolfSSL_read failed: error = %d, %s\n", err,
|
||||
wolfSSL_ERR_reason_error_string(err));
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int Server_Write(SERVER_CONTEXT* ctx, unsigned char* data, size_t length)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (ctx == NULL || ctx->ssl == NULL || data == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (length > INT_MAX) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = wolfSSL_write(ctx->ssl, data, (int)length);
|
||||
if (ret < 0) {
|
||||
int err = wolfSSL_get_error(ctx->ssl, ret);
|
||||
fprintf(stderr, "wolfSSL_write failed: error = %d, %s\n", err,
|
||||
wolfSSL_ERR_reason_error_string(err));
|
||||
return -1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void Server_Cleanup(SERVER_CONTEXT* ctx)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (ctx->ssl != NULL) {
|
||||
wolfSSL_shutdown(ctx->ssl);
|
||||
wolfSSL_free(ctx->ssl);
|
||||
ctx->ssl = NULL;
|
||||
}
|
||||
|
||||
if (ctx->listenfd >= 0) {
|
||||
close(ctx->listenfd);
|
||||
ctx->listenfd = -1;
|
||||
}
|
||||
|
||||
if (g_ctx != NULL) {
|
||||
wolfSSL_CTX_free(g_ctx);
|
||||
g_ctx = NULL;
|
||||
}
|
||||
|
||||
wolfSSL_Cleanup();
|
||||
}
|
||||
|
||||
int Server_Close(SERVER_CONTEXT* ctx)
|
||||
{
|
||||
Server_Cleanup(ctx);
|
||||
return 0;
|
||||
}
|
||||
Loading…
Reference in New Issue