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
8 changes: 8 additions & 0 deletions .github/workflows/fsanitize-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,14 @@ jobs:
runs-on: ${{ matrix.os }}
timeout-minutes: 4
steps:
- name: Install dependencies
run: |
# Don't prompt for anything
export DEBIAN_FRONTEND=noninteractive
sudo apt-get update
# openssl and nginx used for ocsp testing
sudo apt-get install -y openssl nginx

- name: Checking cache for wolfssl
uses: actions/cache@v4
with:
Expand Down
7 changes: 7 additions & 0 deletions .github/workflows/ubuntu-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,13 @@ jobs:
runs-on: ubuntu-latest

steps:
- name: Install dependencies
run: |
# Don't prompt for anything
export DEBIAN_FRONTEND=noninteractive
sudo apt-get update
# openssl and nginx used for ocsp testing
sudo apt-get install -y openssl nginx
- uses: actions/checkout@master
with:
repository: wolfssl/wolfssl
Expand Down
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ autom4te.cache/
config.log
config.status
configure
configure~
clu_src/config.h.in*
*.lo
*.Plo
Expand All @@ -35,3 +36,7 @@ src/config.h.in~
src/stamp-h1
*.gcno
*.gcda
.cproject
.project
.settings/
AGENTS.md
2 changes: 2 additions & 0 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ include tests/pkey/include.am
include tests/dgst/include.am
include tests/rand/include.am
include tests/base64/include.am
include tests/ocsp/include.am
include tests/ocsp-scgi/include.am
include tests/pkcs/include.am
include tests/x509/include.am
include tests/encrypt/include.am
Expand Down
96 changes: 96 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,102 @@ wolfssl ca -altextend -in B.cert -keyfile ecc-key-A.priv -altkey ml-dsa-key-A.pr
wolfssl ca -altextend -in C.cert -keyfile ecc-key-B.priv -altkey ml-dsa-key-B.priv -altpub ml-dsa-key-C.pub -subjkey ecc-key-C.priv -cert B-chimera.cert -out C-chimera.cert
```

## Deploying an OCSP Responder with nginx and SCGI

wolfCLU includes an OCSP responder that can be deployed in production using nginx as an HTTP frontend and SCGI (Simple Common Gateway Interface) as the communication protocol. **This is the preferred deployment method** because SCGI is much simpler than HTTP while allowing you to leverage a mature and robust HTTP implementation like nginx.

### Why SCGI?

- **Simplicity**: SCGI is a straightforward protocol that's easier to implement than full HTTP
- **Robustness**: nginx handles all HTTP concerns (timeouts, keep-alive, TLS, load balancing, etc.)
- **Separation of roles**: The OCSP responder focuses on OCSP logic, nginx handles web serving

### Prerequisites

Install nginx:
```
sudo apt-get install nginx # Debian/Ubuntu
sudo yum install nginx # RHEL/CentOS
brew install nginx # macOS
```

### Basic Setup

1. **Start the wolfCLU OCSP responder in SCGI mode:**

```bash
wolfssl ocsp -scgi \
-port 8081 \
-index /path/to/index.txt \
-rsigner /path/to/ca-cert.pem \
-rkey /path/to/ca-key.pem \
-CA /path/to/ca-cert.pem
```

The responder will listen on port 8081 for SCGI connections.

2. **Configure nginx to proxy HTTP OCSP requests to the SCGI backend:**

Create a file `/etc/nginx/ocsp-scgi.conf`:

```nginx
# SCGI parameters for OCSP
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 SCRIPT_NAME $fastcgi_script_name;
scgi_param DOCUMENT_URI $document_uri;
scgi_param DOCUMENT_ROOT $document_root;
scgi_param SERVER_PROTOCOL $server_protocol;
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;
```

Add to your nginx site configuration (e.g., `/etc/nginx/sites-available/default`):

```nginx
server {
listen 80;
server_name ocsp.example.com;

location /ocsp {
scgi_pass localhost:8081;
include /etc/nginx/ocsp-scgi.conf;

scgi_connect_timeout 5s;
scgi_send_timeout 10s;
scgi_read_timeout 10s;
}
}
```

3. **Reload nginx:**

```bash
sudo nginx -t # Test configuration
sudo systemctl reload nginx # Reload nginx
```

4. **Test the OCSP responder:**

```bash
wolfssl ocsp \
-issuer ca-cert.pem \
-cert server-cert.pem \
-url http://ocsp.example.com/ocsp
```

### Index File Format

The `-index` file uses OpenSSL's CA index format.

## Contacts

Please contact support@wolfssl.com with any questions or comments.
Expand Down
12 changes: 0 additions & 12 deletions autogen.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,6 @@
# Create configure and makefile stuff...
#

# Git hooks should come before autoreconf.
if [ -d .git ]; then
if [ ! -d .git/hooks ]; then
mkdir .git/hooks || exit $?
fi

if [ ! -e .git/hooks/pre-commit ]; then
ln -s ../../pre-commit.sh .git/hooks/pre-commit || exit $?
fi
fi


set -e
Copy link

Copilot AI Feb 19, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The removal of Git hooks setup from autogen.sh appears intentional but there's no explanation in the PR description. This removes automatic setup of the pre-commit hook. If this is intentional, consider documenting why this change was made.

Copilot uses AI. Check for mistakes.

# if get an error about libtool not setup
Expand Down
27 changes: 27 additions & 0 deletions certs/ocsp-responder-cert.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
-----BEGIN CERTIFICATE-----
MIIEoTCCA4mgAwIBAgIBZDANBgkqhkiG9w0BAQsFADCBlDELMAkGA1UEBhMCVVMx
EDAOBgNVBAgMB01vbnRhbmExEDAOBgNVBAcMB0JvemVtYW4xETAPBgNVBAoMCFNh
d3Rvb3RoMRMwEQYDVQQLDApDb25zdWx0aW5nMRgwFgYDVQQDDA93d3cud29sZnNz
bC5jb20xHzAdBgkqhkiG9w0BCQEWEGluZm9Ad29sZnNzbC5jb20wHhcNMjYwMjE4
MTkxNDQxWhcNMjgxMTE0MTkxNDQxWjB1MQswCQYDVQQGEwJVUzEQMA4GA1UECAwH
TW9udGFuYTEQMA4GA1UEBwwHQm96ZW1hbjEVMBMGA1UECgwMd29sZlNTTCBPQ1NQ
MRIwEAYDVQQLDAlSZXNwb25kZXIxFzAVBgNVBAMMDk9DU1AgUmVzcG9uZGVyMIIB
IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApMVQ84ki9B8QgCRpwhEE0z5A
uKgi3KDK2cFimJrLX/JG7Rzq+SMj8X3yIEB4eP5FYVLvugAAbR0p4Vqb2mgOrleo
hwGg/1tgqoZaxXJVFFySpUUW+L0VCh6+CB80+KHss2Sb7xFNfWzd+yFRyN/jKhaT
nvusFwSnYKdMMxJlV/zAhVEPKIfqS4N8JRQhLJW38z1f7Jb+uB94JReCuKZiayx4
wFh189EjLq9u/bJoCNy60HzzyAHZqiGM2I3Pk6mw2+twJZGOEhH0q+kL/w9ZfJpt
3j+Dct/5jpNsPI3aIw94qAnIQC5de7xdAk9JvVm0ujxsat6t5NyRLYx/xOClOQID
AQABo4IBGjCCARYwCQYDVR0TBAIwADAdBgNVHQ4EFgQUFqtdxd3qLuCtJ53mlNZQ
ugLQ/wIwgdQGA1UdIwSBzDCByYAUJ45nEXTDJh0/7TNjs6TYHTDl6NWhgZqkgZcw
gZQxCzAJBgNVBAYTAlVTMRAwDgYDVQQIDAdNb250YW5hMRAwDgYDVQQHDAdCb3pl
bWFuMREwDwYDVQQKDAhTYXd0b290aDETMBEGA1UECwwKQ29uc3VsdGluZzEYMBYG
A1UEAwwPd3d3LndvbGZzc2wuY29tMR8wHQYJKoZIhvcNAQkBFhBpbmZvQHdvbGZz
c2wuY29tghRrm3DG8aOUZRmhCFjvp40reoPB2jATBgNVHSUEDDAKBggrBgEFBQcD
CTANBgkqhkiG9w0BAQsFAAOCAQEAPZSIsDoFVKciK39jhVI/uBbfwKlgLvRhrofc
5Xt2GsX/ebaY7SXmFcBycG7t6PL8wZCMtisqPb5XFjEXYoTvgYeDSuuEYW7hTYqW
hXLdqLFaMaql2chMDmx5dMO84KKLaq+z3QTHO1Imbz0gsagT4yz3Xk3zcUN07EDc
R/gWq41CxcCyiPeeoscKE8EOq+E9eN8mc34EbUU6swuHNHwGqSLo7d9y0w5/cgRD
Ma0WAC0FvLqfNwek08UzEYOD2BMZhzDQOynINbaGuY1GZdPUK2RwzVgkOOaR08Bv
ZBJs3IwBBgE8u5n63xHrmCnehxxtl0vC0IXw44+lt+fF9gc6Mg==
-----END CERTIFICATE-----
28 changes: 28 additions & 0 deletions certs/ocsp-responder-key.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCkxVDziSL0HxCA
JGnCEQTTPkC4qCLcoMrZwWKYmstf8kbtHOr5IyPxffIgQHh4/kVhUu+6AABtHSnh
WpvaaA6uV6iHAaD/W2CqhlrFclUUXJKlRRb4vRUKHr4IHzT4oeyzZJvvEU19bN37
IVHI3+MqFpOe+6wXBKdgp0wzEmVX/MCFUQ8oh+pLg3wlFCEslbfzPV/slv64H3gl
F4K4pmJrLHjAWHXz0SMur279smgI3LrQfPPIAdmqIYzYjc+TqbDb63AlkY4SEfSr
6Qv/D1l8mm3eP4Ny3/mOk2w8jdojD3ioCchALl17vF0CT0m9WbS6PGxq3q3k3JEt
jH/E4KU5AgMBAAECggEADmjxPPMz2tyyoTpOA3pgjSbnGx8dOWVYiDW47TawbZov
KMJ8LECt/oswtzBcONyn7ayGqaIhZ2mDBaHaen3aNtYUt4Xlch+oMxGf85+doDO+
YXTK3wMOSX3JycUM6Wej30Z/uqctOzhfq3xM/j/SSpaB34gME1FFYBcRe2/y7ABb
TycvgSmvK0hVklDa488He+lNdHPh01aJnKGpKU33qMndhNf+dAcZtXUvkBSe1RdP
y4KWUG+paHWVB7r7upTuVvVV964Ie0+Ji7PwG3eq1yf2SgOpe+/rf8WmNu5qEoLW
Y/nZXwD27RaVb5L4p0itfSM+m61R+lzMasPYruhnAQKBgQDYT2RiDYUdMfgcH/Kl
jmfIpgWrI5rkiN/wbEI+xbkWdzjbbUnAgA6CC5F5xmQA2B/ekNBqxcB6AqPGkD+t
4kx0Kz2VQSBVIWQ0Q2z0xZ9GrYiIGIv8CGdNN+XBvXBXMMYx6QcYtY3aSNV2fx7W
IUVnbzLyHI6KzElx3OT1uWXrwQKBgQDDAP8G0qT9KUnyXBNK27WurGMJo1bOLS1l
8odVXrijQy/geDfxrr0UkoootBIs9aOP/Y1SZ32cqW9H9GDTb6HB4zAaUQvY07wS
wq/0rgwIDWjL7zKaK8Pv9BhZmpQqRDqhZypJ2EkEGdgdd1to2zL5k3OdPN/XW4nG
VrHhsH33eQKBgQCPG0dQT52HiS2afdBsk2A6MQyDAtVQ6PUu/JB/MxSWtl2ZXh5z
CsWOZ9Tg+c3jeRjsiGY6nYYPsntjvL9EbPkjyg++FQ4tBCBlK06ESdJsUhaH46WJ
Io4lWhvZJ1mRdaVKE98sC8FDbvg6ozNlezGNktXjs9ziGvFkMT4RC41QgQKBgGHY
eh5+S3ML6KLHOJbzL3J55SfM4Z2KZaEl1GotoQ+qgrdrGwcV2qIb9V7/G6+bgXqa
ivKyIwEcs02zfXIaLVwQFu7dg8hEVbZEIe3v9vGDaPYLC6T4GNSp8h3jxjx/B7w8
+6cZ82kvXpVKcn9mnWlFZ1maVebFc5gloBPSbyJhAoGAJ2p1TzI8/c2xVOxhE0AO
WTcpIiYNiHMotIBruSl9I2siaKklcyQKaMieAFQgylhsiORhKq0hUfMPQEfFcYL5
mOPEzqf5/FBAFvzNxgk8lvXXM11TuZoKEFg5LTjgdHojl74urWk5asN4OziCZ+qI
W3r7lHub6JynJhqe91sJmnE=
-----END PRIVATE KEY-----
5 changes: 5 additions & 0 deletions certs/ocsp.cnf
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[ v3_ocsp ]
basicConstraints = CA:false
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer:always
extendedKeyUsage = OCSPSigning
11 changes: 11 additions & 0 deletions certs/renew.sh
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,17 @@ cp $CERTS_DIR/intermediate/client-int-cert.pem .
#cp $CERTS_DIR/../examples/client/client.c ../src/client/client.c
#sed -i '' "s/examples\/client\//wolfclu\//" ../src/client/client.c

echo "Generate OCSP responder certificate"
openssl genrsa -out ocsp-responder-key.pem 2048
openssl req -new -key ocsp-responder-key.pem -out ocsp-responder.csr \
-subj "/C=US/ST=Montana/L=Bozeman/O=wolfSSL OCSP/OU=Responder/CN=OCSP Responder"
openssl x509 -req -in ocsp-responder.csr \
-CA ca-cert.pem -CAkey ca-key.pem \
-extfile ocsp.cnf -extensions v3_ocsp \
-days 1000 -set_serial 100 -out ocsp-responder-cert.pem
rm ocsp-responder.csr
echo "OCSP responder certificate created"

echo "Recreate expected encrypted data with new files"
openssl enc -aes-256-cbc -nosalt -in ./crl.der -out ./crl.der.enc -k ""
openssl enc -base64 -aes-256-cbc -nosalt -in ./crl.der -out ./crl.der.enc.base64 -k ""
Expand Down
14 changes: 8 additions & 6 deletions src/client/client.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@

#include <wolfssl/ssl.h>

#include <wolfclu/clu_header_main.h>

#define HAVE_GETADDRINFO 1
#define HAVE_ERRNO_H 1

Expand Down Expand Up @@ -389,7 +391,6 @@ static const char kResumeMsg[] = "resuming wolfssl!" TEST_STR_TERM;
#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_EARLY_DATA)
static const char kEarlyMsg[] = "A drop of info" TEST_STR_TERM;
#endif
static const char kHttpGetMsg[] = "GET /index.html HTTP/1.0\r\n\r\n";

/* Write needs to be largest of the above strings (29) */
#define CLI_MSG_SZ 32
Expand Down Expand Up @@ -943,7 +944,8 @@ static int ClientBenchmarkConnections(WOLFSSL_CTX* ctx, char* host, word16 port,
#endif
{
/* no null term */
if (wolfSSL_write(ssl, kHttpGetMsg, sizeof(kHttpGetMsg)-1) <= 0)
if (wolfSSL_write(ssl, wolfCLU_GetDefaultHttpGet(),
wolfCLU_GetDefaultHttpGetLength()) <= 0)
err_sys("SSL_write failed");

if (wolfSSL_read(ssl, reply, sizeof(reply)-1) <= 0)
Expand Down Expand Up @@ -4141,8 +4143,8 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
if (sendGET) {
printf("SSL connect ok, sending GET...\n");

msgSz = (int)XSTRLEN(kHttpGetMsg);
XMEMCPY(msg, kHttpGetMsg, msgSz);
msgSz = wolfCLU_GetDefaultHttpGetLength();
XMEMCPY(msg, wolfCLU_GetDefaultHttpGet(), msgSz);
}
else {
msgSz = (int)XSTRLEN(kHelloMsg);
Expand Down Expand Up @@ -4436,8 +4438,8 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)

XMEMSET(msg, 0, sizeof(msg));
if (sendGET) {
msgSz = (int)XSTRLEN(kHttpGetMsg);
XMEMCPY(msg, kHttpGetMsg, msgSz);
msgSz = wolfCLU_GetDefaultHttpGetLength();
XMEMCPY(msg, wolfCLU_GetDefaultHttpGet(), msgSz);
}
else {
msgSz = (int)XSTRLEN(kResumeMsg);
Expand Down
9 changes: 9 additions & 0 deletions src/clu_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,9 @@ static const struct option mode_options[] = {
{"rand", no_argument, 0, WOLFCLU_RAND },
{"dsaparam", no_argument, 0, WOLFCLU_DSA },
{"dhparam", no_argument, 0, WOLFCLU_DH },
#if defined(HAVE_OCSP) && defined(HAVE_OCSP_RESPONDER)
{"ocsp", no_argument, 0, WOLFCLU_OCSP },
#endif
{"base64", no_argument, 0, WOLFCLU_BASE64 },
{"help", no_argument, 0, WOLFCLU_HELP },
{"h", no_argument, 0, WOLFCLU_HELP },
Expand Down Expand Up @@ -319,6 +322,12 @@ int main(int argc, char** argv)
ret = wolfCLU_DhParamSetup(argc, argv);
break;

#if defined(HAVE_OCSP) && defined(HAVE_OCSP_RESPONDER)
case WOLFCLU_OCSP:
ret = wolfCLU_OcspSetup(argc, argv);
break;
#endif

case WOLFCLU_BASE64:
ret = wolfCLU_Base64Setup(argc, argv);
break;
Expand Down
6 changes: 5 additions & 1 deletion src/include.am
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ wolfssl_SOURCES = src/clu_main.c \
src/server/clu_server_setup.c \
src/pkcs/clu_pkcs7.c \
src/pkcs/clu_pkcs8.c \
src/tools/clu_base64.c
src/tools/clu_base64.c \
src/tools/clu_http.c \
src/tools/clu_scgi.c \
src/tools/clu_pem_der.c \
src/ocsp/clu_ocsp.c


Loading
Loading