Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,8 @@ hash/sha512-hash
ocsp/ocsp_nonblock/ocsp_nonblock
ocsp/stapling/ocsp-client
ocsp/stapling/ocsp-server
ocsp/responder/ocsp-request-response
ocsp/responder/ocsp-responder-http

sslkeylog.log

Expand Down
24 changes: 24 additions & 0 deletions ocsp/responder/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Makefile for OCSP Responder Examples
#
# wolfSSL must be built with:
# ./configure --enable-ocsp --enable-ocsp-responder
# make && sudo make install

CC = gcc
WOLFSSL_INSTALL_DIR = /usr/local
CFLAGS = -Wall -Wextra -g -I$(WOLFSSL_INSTALL_DIR)/include
LIBS = -L$(WOLFSSL_INSTALL_DIR)/lib -lwolfssl

# Uncomment for static linking:
# LIBS = $(WOLFSSL_INSTALL_DIR)/lib/libwolfssl.a -lm -lpthread

SRC = $(wildcard *.c)
TARGETS = $(patsubst %.c, %, $(SRC))

all: $(TARGETS)

%: %.c
$(CC) -o $@ $< $(CFLAGS) $(LIBS)

clean:
rm -f $(TARGETS)
109 changes: 109 additions & 0 deletions ocsp/responder/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
# OCSP Responder Examples

Examples demonstrating the wolfSSL OCSP Responder API added in
[wolfSSL/wolfssl#9761](https://github.com/wolfSSL/wolfssl/pull/9761).

## Prerequisites

Build and install wolfSSL with OCSP responder support:

```sh
cd wolfssl
./configure --enable-ocsp --enable-ocsp-responder
make
sudo make install
sudo ldconfig
```

## Examples

### 1. Raw DER Request/Response (`ocsp-request-response.c`)

Demonstrates the core API without any networking:

- Parse a certificate and build a DER-encoded OCSP request
(`wc_InitOcspRequest`, `wc_EncodeOcspRequest`)
- Create an `OcspResponder`, register a signer, and set certificate statuses
(`wc_OcspResponder_new`, `wc_OcspResponder_AddSigner`,
`wc_OcspResponder_SetCertStatus`)
- Generate a signed OCSP response from the request
(`wc_OcspResponder_WriteResponse`)
- Verify the response against a `WOLFSSL_CERT_MANAGER`
(`wc_CheckCertOcspResponse`)
- Show REVOKED status and error response generation

```sh
make ocsp-request-response
./ocsp-request-response
```

Uses the wolfSSL test certs in `../../certs/` by default.

### 2. Minimal HTTP Responder (`ocsp-responder-http.c`)

A tiny HTTP server that accepts POST requests containing DER OCSP requests and
returns DER OCSP responses. Kept as small as possible.

```sh
make ocsp-responder-http

# Start the responder, marking the server cert as GOOD
./ocsp-responder-http 8080 ../../certs/ca-cert.pem ../../certs/ca-key.pem \
../../certs/server-cert.pem

# Test with OpenSSL (in another terminal)
openssl ocsp -issuer ../../certs/ca-cert.pem -cert ../../certs/server-cert.pem \
-url http://127.0.0.1:8080/ -no_nonce
```

Any certificate files listed after the CA key have their serial numbers
registered as CERT_GOOD. Certificates not registered will get CERT_UNKNOWN.

### 3. nginx + wolfclu SCGI (`nginx-scgi/`)

Production-style deployment: nginx handles HTTP and forwards raw OCSP request
bodies to wolfclu over SCGI. nginx provides TLS termination, access control,
logging, and load balancing while wolfclu focuses on OCSP processing.

Requirements:
- [wolfCLU](https://github.com/wolfSSL/wolfCLU) built and installed
- nginx with SCGI support (enabled by default)

```
+---------+ HTTP POST +-------+ SCGI +---------+
| Client |------------>| nginx |-------->| wolfclu |
|(openssl) |<------------| :8080 |<--------| :8081 |
+---------+ OCSP resp +-------+ +---------+
```

Quick start:

```sh
cd nginx-scgi
./run.sh
```

Or run manually:

```sh
# Terminal 1: Start wolfclu SCGI backend
wolfssl ocsp -scgi -port 8081 \
-rsigner ../../certs/ca-cert.pem \
-rkey ../../certs/ca-key.pem \
-CA ../../certs/ca-cert.pem

# Terminal 2: Start nginx
nginx -c $(pwd)/nginx-scgi/nginx-ocsp.conf

# Terminal 3: Test
openssl ocsp -issuer ../../certs/ca-cert.pem -cert ../../certs/server-cert.pem \
-url http://127.0.0.1:8080/ -no_nonce
```

The `nginx-ocsp.conf` file can be customized for your environment. See the
comments in the file for standalone vs. installed nginx usage.

## Shared Code

`ocsp-load-certs.h` contains file loading utilities (`LoadFile`, `LoadCertDer`,
`LoadKeyDer`) shared between the C examples.
47 changes: 47 additions & 0 deletions ocsp/responder/nginx-scgi/nginx-ocsp.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# nginx configuration for proxying OCSP requests to wolfclu via SCGI.
#
# Install: copy this to /etc/nginx/sites-enabled/ or include it from
# nginx.conf, then reload nginx. Alternatively run a standalone nginx:
#
# nginx -c $(pwd)/nginx-ocsp.conf -p $(pwd)
#
# Adjust paths/ports below as needed.

# Run as a foreground process for testing (comment out for daemon mode).
daemon off;
# Uncomment and set if running without root:
# pid /tmp/nginx-ocsp.pid;

events {
worker_connections 64;
}

http {
# Where nginx writes temp files when running standalone.
client_body_temp_path /tmp/nginx-ocsp-body;
proxy_temp_path /tmp/nginx-ocsp-proxy;
fastcgi_temp_path /tmp/nginx-ocsp-fastcgi;
uwsgi_temp_path /tmp/nginx-ocsp-uwsgi;
scgi_temp_path /tmp/nginx-ocsp-scgi;

access_log /dev/stdout;
error_log /dev/stderr info;

server {
listen 8080;

location / {
# Forward OCSP requests to wolfclu running in SCGI mode.
scgi_pass 127.0.0.1:8081;

# Standard SCGI parameter: tell the backend the content length.
include scgi_params;

# Ensure the OCSP request body is forwarded.
scgi_param CONTENT_LENGTH $content_length;
scgi_param CONTENT_TYPE $content_type;
scgi_param REQUEST_METHOD $request_method;
scgi_param REQUEST_URI $request_uri;
}
}
}
183 changes: 183 additions & 0 deletions ocsp/responder/nginx-scgi/run.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
#!/bin/sh
#
# run.sh - Start an OCSP responder using wolfclu (SCGI) behind nginx.
#
# This script:
# 1. Starts wolfclu in SCGI mode on port 8081
# 2. Starts nginx on port 8080, forwarding to wolfclu via SCGI
# 3. Sends a test OCSP query using wolfssl's built-in test certs
#
# Prerequisites:
# - wolfssl built with: --enable-ocsp --enable-ocsp-responder
# - wolfclu built and installed
# - nginx installed with SCGI support (default in most packages)
#
# Usage:
# ./run.sh [options]
#
# Options:
# --ca-cert <file> CA certificate (default: wolfSSL test ca-cert.pem)
# --ca-key <file> CA private key (default: wolfSSL test ca-key.pem)
# --index <file> OpenSSL-format index.txt (optional)
# --port <num> nginx listen port (default: 8080)
# --scgi-port <num> wolfclu SCGI port (default: 8081)

set -e

# Defaults - use wolfSSL test certificates
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
CA_CERT="${SCRIPT_DIR}/../../../certs/ca-cert.pem"
CA_KEY="${SCRIPT_DIR}/../../../certs/ca-key.pem"
INDEX_FILE=""
HTTP_PORT=8080
SCGI_PORT=8081
WOLFCLU_PID=""
NGINX_PID=""

cleanup() {
echo ""
echo "Shutting down..."
[ -n "$WOLFCLU_PID" ] && kill "$WOLFCLU_PID" 2>/dev/null || true
[ -n "$NGINX_PID" ] && kill "$NGINX_PID" 2>/dev/null || true
wait 2>/dev/null || true
[ -n "$WORK_DIR" ] && rm -rf "$WORK_DIR"
echo "Done."
}
trap cleanup EXIT INT TERM

# Parse arguments
while [ $# -gt 0 ]; do
case "$1" in
--ca-cert) CA_CERT="$2"; shift 2 ;;
--ca-key) CA_KEY="$2"; shift 2 ;;
--index) INDEX_FILE="$2"; shift 2 ;;
--port) HTTP_PORT="$2"; shift 2 ;;
--scgi-port) SCGI_PORT="$2"; shift 2 ;;
*)
echo "Unknown option: $1"
exit 1
;;
esac
done

# Validate files exist
if [ ! -f "$CA_CERT" ]; then
echo "Error: CA cert not found: $CA_CERT"
exit 1
fi
if [ ! -f "$CA_KEY" ]; then
echo "Error: CA key not found: $CA_KEY"
exit 1
fi

# Check for required tools
if ! command -v wolfssl >/dev/null 2>&1; then
echo "Error: 'wolfssl' (wolfCLU) not found in PATH"
echo "Build wolfCLU from https://github.com/wolfSSL/wolfCLU"
exit 1
fi
if ! command -v nginx >/dev/null 2>&1; then
echo "Error: nginx not found in PATH"
exit 1
fi

echo "=== OCSP Responder: nginx + wolfclu (SCGI) ==="
echo ""
echo "CA cert: $CA_CERT"
echo "CA key: $CA_KEY"
echo "HTTP port: $HTTP_PORT (nginx)"
echo "SCGI port: $SCGI_PORT (wolfclu)"
echo ""

# --- Step 1: Start wolfclu OCSP responder in SCGI mode ---
echo "Starting wolfclu OCSP responder (SCGI on port $SCGI_PORT)..."

set -- -scgi -port "$SCGI_PORT" -rsigner "$CA_CERT" -rkey "$CA_KEY" -CA "$CA_CERT"
if [ -n "$INDEX_FILE" ]; then
set -- "$@" -index "$INDEX_FILE"
fi

wolfssl ocsp "$@" &
WOLFCLU_PID=$!
sleep 1

if ! kill -0 "$WOLFCLU_PID" 2>/dev/null; then
echo "Error: wolfclu failed to start"
exit 1
fi
echo "wolfclu started (PID $WOLFCLU_PID)"

# --- Step 2: Generate nginx config with correct ports ---
WORK_DIR="$(mktemp -d "$SCRIPT_DIR/tmp.XXXXXX")"
NGINX_CONF="$WORK_DIR/nginx-ocsp.conf"
cat > "$NGINX_CONF" <<EOF
daemon off;
pid $WORK_DIR/nginx-ocsp.pid;
error_log /dev/stderr info;

events {
worker_connections 64;
}

http {
client_body_temp_path $WORK_DIR/body;
proxy_temp_path $WORK_DIR/proxy;
fastcgi_temp_path $WORK_DIR/fastcgi;
uwsgi_temp_path $WORK_DIR/uwsgi;
scgi_temp_path $WORK_DIR/scgi;

access_log /dev/stdout;

server {
listen $HTTP_PORT;

location / {
scgi_pass 127.0.0.1:$SCGI_PORT;

scgi_param REQUEST_METHOD \$request_method;
scgi_param REQUEST_URI \$request_uri;
scgi_param QUERY_STRING \$query_string;
scgi_param CONTENT_TYPE \$content_type;
scgi_param CONTENT_LENGTH \$content_length;
scgi_param DOCUMENT_URI \$document_uri;
scgi_param DOCUMENT_ROOT \$document_root;
scgi_param SCGI 1;
scgi_param SERVER_PROTOCOL \$server_protocol;
scgi_param REQUEST_SCHEME \$scheme;
scgi_param HTTPS \$https if_not_empty;
scgi_param REMOTE_ADDR \$remote_addr;
scgi_param REMOTE_PORT \$remote_port;
scgi_param SERVER_PORT \$server_port;
scgi_param SERVER_NAME \$server_name;
}
}
}
EOF

echo "Starting nginx (HTTP on port $HTTP_PORT)..."
nginx -c "$NGINX_CONF" &
NGINX_PID=$!
sleep 1

if ! kill -0 "$NGINX_PID" 2>/dev/null; then
echo "Error: nginx failed to start"
exit 1
fi
echo "nginx started (PID $NGINX_PID)"

echo ""
echo "=== OCSP responder is running ==="
echo ""
echo "Test with wolfssl:"
echo " wolfssl ocsp -issuer $CA_CERT -cert ../../certs/server-cert.pem \\"
echo " -url http://127.0.0.1:$HTTP_PORT/"
echo ""
echo "Test with openssl:"
echo " openssl ocsp -issuer $CA_CERT -cert ../../certs/server-cert.pem \\"
echo " -url http://127.0.0.1:$HTTP_PORT/ -resp_text"
echo ""
echo "Press Ctrl-C to stop."
echo ""

# Wait for either process to exit
wait
Loading