Skip to content

Commit 50d513b

Browse files
committed
Show OCSP checking via CertManager
1 parent 9ada2ac commit 50d513b

File tree

3 files changed

+355
-17
lines changed

3 files changed

+355
-17
lines changed

certmanager/Makefile

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,16 @@ WOLFSSL_INSTALL_DIR=/usr/local
33
CFLAGS=-Wall
44
LIBS=-L$(WOLFSSL_INSTALL_DIR)/lib -lwolfssl
55

6-
all: certloadverifybuffer certverify
6+
all: certloadverifybuffer certverify certverify_ocsp
77

88
certloadverifybuffer: certloadverifybuffer.o
99
$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
1010
certverify: certverify.o
1111
$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
12+
certverify_ocsp: certverify_ocsp.o
13+
$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
1214

1315
.PHONY: clean
1416

1517
clean:
16-
rm -f *.o certverify certloadverifybuffer
18+
rm -f *.o certverify certloadverifybuffer certverify_ocsp

certmanager/README.md

Lines changed: 103 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,113 @@
1-
# wolfSSL CertManager Example
1+
# wolfSSL CertManager Examples
22

3-
This directory contains:
3+
This directory contains examples of using the wolfSSL CertManager to verify
4+
certificates in a standalone manner, separate from an SSL/TLS connection.
45

5-
A simple example of using the wolfSSL CertManager to verify a certificate
6-
in a standalone manner, separate from an SSL/TLS connection.
6+
## Example Applications
77

8-
## Compiling and Running the Example
8+
- **certverify.c** - Basic certificate verification example
9+
- **certloadverifybuffer.c** - Certificate verification from memory buffer
10+
- **certverify_ocsp.c** - Certificate verification with OCSP revocation
11+
checking
912

13+
## certverify.c and/or certloadverifybuffer.c
14+
15+
### Building wolfSSL
16+
17+
```bash
18+
cd wolfssl
19+
./autogen.sh
20+
./configure
21+
make all
22+
make check
23+
sudo make install
1024
```
11-
$ cd wolfssl
12-
$ ./autogen.sh # If downloaded from github
13-
$ ./configure --enable-crl # CRL is optional.
14-
$ make all
15-
$ make check
16-
$ sudo make install
25+
26+
### Building the Examples
27+
28+
```bash
29+
cd wolfssl-examples/certmanager
30+
make certverify
31+
make certloadverifybuffer
1732
```
1833

34+
### Running the Examples
35+
36+
```bash
37+
./certverify
38+
./certloadverifybuffer
1939
```
20-
$ cd wolfssl-examples
21-
$ cd certmanager
22-
$ make all
23-
$ ./certverify
40+
41+
## certverify_ocsp
42+
43+
The `certverify_ocsp` example demonstrates certificate verification with
44+
OCSP (Online Certificate Status Protocol) checking. These instructions assume
45+
that your `wolfssl` source directory and the `wolfssl-examples` directory share
46+
the same parent directory.
47+
48+
### Building wolfSSL
49+
50+
```bash
51+
cd wolfssl
52+
./autogen.sh
53+
./configure --enable-crl --enable-ocsp
54+
make all
55+
make check
56+
sudo make install
57+
```
58+
59+
### Building the Example
60+
61+
```bash
62+
cd wolfssl-examples/certmanager
63+
make certverify_ocsp
2464
```
2565

66+
### Running the Example
67+
68+
The OCSP demo requires an OCSP responder to be running. You can start one using
69+
OpenSSL:
70+
71+
**Terminal 1 - Start the OCSP Responder:**
72+
73+
From the `wolfssl-examples/certmanager` directory:
74+
75+
```bash
76+
openssl ocsp -port 22221 -ndays 365 \
77+
-index ../../wolfssl/certs/ocsp/index-intermediate1-ca-issued-certs.txt \
78+
-rsigner ../../wolfssl/certs/ocsp/ocsp-responder-cert.pem \
79+
-rkey ../../wolfssl/certs/ocsp/ocsp-responder-key.pem \
80+
-CA ../../wolfssl/certs/ocsp/intermediate1-ca-cert.pem \
81+
-text
82+
```
83+
84+
**Terminal 2 - Run the Example:**
85+
86+
From the `wolfssl-examples/certmanager` directory:
87+
88+
```bash
89+
./certverify_crl_ocsp
90+
```
91+
92+
### Expected Output
93+
94+
When the OCSP responder is running, you should see output that indicates basic
95+
verification passed and OCSP checking is done and successful. Importantly,
96+
OpenSSL should also show some pretty prints of the OCSP request.
97+
98+
### OCSP Certificate Structure
99+
100+
The OCSP test uses the following certificate chain from the wolfSSL repository's
101+
`certs/ocsp/` directory. This assumes the wolfssl and wolfssl-examples
102+
repositories are in the same parent directory.
103+
104+
105+
- **root-ca-cert.pem** - Root CA certificate
106+
- **intermediate1-ca-cert.pem** - Intermediate CA that issued the server cert
107+
- **server1-cert.pem** - Server certificate with OCSP URL in AIA extension
108+
- **ocsp-responder-cert.pem** - Certificate for the OCSP responder
109+
- **ocsp-responder-key.pem** - Private key for the OCSP responder
110+
111+
The server1-cert.pem certificate contains an Authority Information Access (AIA)
112+
extension pointing to `http://127.0.0.1:22221` for OCSP queries.
113+

certmanager/certverify_ocsp.c

Lines changed: 248 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,248 @@
1+
/* certverify_crl_ocsp.c
2+
*
3+
* Copyright (C) 2006-2025 wolfSSL Inc.
4+
*
5+
* This file is part of wolfSSL.
6+
*
7+
* wolfSSL is free software; you can redistribute it and/or modify
8+
* it under the terms of the GNU General Public License as published by
9+
* the Free Software Foundation; either version 2 of the License, or
10+
* (at your option) any later version.
11+
*
12+
* wolfSSL is distributed in the hope that it will be useful,
13+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
* GNU General Public License for more details.
16+
*
17+
* You should have received a copy of the GNU General Public License
18+
* along with this program; if not, write to the Free Software
19+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
20+
*/
21+
22+
/* This example demonstrates certificate verification using the wolfSSL
23+
* Certificate Manager API with CRL (Certificate Revocation List) and
24+
* OCSP (Online Certificate Status Protocol) checking.
25+
*
26+
* For OCSP testing, this example requires an OpenSSL OCSP responder.
27+
* See README.md for instructions on starting the OCSP responder.
28+
*
29+
* Build wolfSSL with:
30+
* ./configure --enable-crl --enable-ocsp
31+
* make && sudo make install
32+
*/
33+
34+
#include <stdio.h>
35+
#include <stdlib.h>
36+
#include <string.h>
37+
38+
#include <wolfssl/options.h>
39+
#include <wolfssl/ssl.h>
40+
#include <wolfssl/wolfcrypt/error-crypt.h>
41+
#include <wolfssl/test.h>
42+
43+
#ifdef HAVE_OCSP
44+
/* Certificate paths for OCSP testing
45+
* These certificates are from wolfSSL's certs/ocsp directory and are
46+
* configured to work with an OpenSSL OCSP responder.
47+
* The server1-cert.pem certificate has an AIA extension with OCSP URL:
48+
* http://127.0.0.1:22221
49+
*
50+
* Note: This assumes wolfssl and wolfssl-examples repos are in the same
51+
* parent directory.
52+
*/
53+
#define OCSP_ROOT_CA "../../wolfssl/certs/ocsp/root-ca-cert.pem"
54+
#define OCSP_INTER_CA "../../wolfssl/certs/ocsp/intermediate1-ca-cert.pem"
55+
#define OCSP_SERVER_CERT "../../wolfssl/certs/ocsp/server1-cert.pem"
56+
57+
/* Demonstrate OCSP checking with a real OCSP responder
58+
*
59+
* Before running this demo, start the OpenSSL OCSP responder:
60+
* cd <wolfssl-dir>
61+
* openssl ocsp -port 22221 -ndays 365 \
62+
* -index certs/ocsp/index-intermediate1-ca-issued-certs.txt \
63+
* -rsigner certs/ocsp/ocsp-responder-cert.pem \
64+
* -rkey certs/ocsp/ocsp-responder-key.pem \
65+
* -CA certs/ocsp/intermediate1-ca-cert.pem
66+
*/
67+
static int demoOCSPCheck(void)
68+
{
69+
int ret;
70+
WOLFSSL_CERT_MANAGER* cm = NULL;
71+
FILE* fp = NULL;
72+
long certSz;
73+
unsigned char* certBuf = NULL;
74+
75+
/* Create a new Certificate Manager for OCSP testing
76+
* We use a separate CM because we need different CA certificates
77+
* for the OCSP certificate chain.
78+
*/
79+
cm = wolfSSL_CertManagerNew();
80+
if (cm == NULL) {
81+
printf("Failed to create Certificate Manager for OCSP\n");
82+
return -1;
83+
}
84+
85+
/* Load the root CA certificate */
86+
ret = wolfSSL_CertManagerLoadCA(cm, OCSP_ROOT_CA, NULL);
87+
if (ret != WOLFSSL_SUCCESS) {
88+
printf("Failed to load OCSP root CA (%d): %s\n",
89+
ret, wolfSSL_ERR_reason_error_string(ret));
90+
wolfSSL_CertManagerFree(cm);
91+
return ret;
92+
}
93+
printf("Loaded root CA: %s\n", OCSP_ROOT_CA);
94+
95+
/* Load the intermediate CA certificate */
96+
ret = wolfSSL_CertManagerLoadCA(cm, OCSP_INTER_CA, NULL);
97+
if (ret != WOLFSSL_SUCCESS) {
98+
printf("Failed to load OCSP intermediate CA (%d): %s\n",
99+
ret, wolfSSL_ERR_reason_error_string(ret));
100+
wolfSSL_CertManagerFree(cm);
101+
return ret;
102+
}
103+
printf("Loaded intermediate CA: %s\n", OCSP_INTER_CA);
104+
105+
/* Enable OCSP checking
106+
* Options (can be combined with |):
107+
* WOLFSSL_OCSP_URL_OVERRIDE - Use override URL instead of cert's AIA
108+
* WOLFSSL_OCSP_NO_NONCE - Don't include nonce in request
109+
* WOLFSSL_OCSP_CHECKALL - Check all certificates in chain
110+
*
111+
* We use WOLFSSL_OCSP_NO_NONCE because OpenSSL's OCSP responder
112+
* may not support nonces by default.
113+
*/
114+
ret = wolfSSL_CertManagerEnableOCSP(cm, WOLFSSL_OCSP_NO_NONCE);
115+
if (ret != WOLFSSL_SUCCESS) {
116+
printf("Failed to enable OCSP (%d): %s\n",
117+
ret, wolfSSL_ERR_reason_error_string(ret));
118+
wolfSSL_CertManagerFree(cm);
119+
return ret;
120+
}
121+
printf("OCSP checking enabled\n");
122+
123+
/* First, verify the certificate chain without OCSP.
124+
* Note: wolfSSL_CertManagerVerify() does NOT perform OCSP checks.
125+
*/
126+
printf("Verifying certificate: %s\n", OCSP_SERVER_CERT);
127+
ret = wolfSSL_CertManagerVerify(cm, OCSP_SERVER_CERT, WOLFSSL_FILETYPE_PEM);
128+
if (ret != WOLFSSL_SUCCESS) {
129+
printf("Certificate chain verification failed (%d): %s\n",
130+
ret, wolfSSL_ERR_reason_error_string(ret));
131+
wolfSSL_CertManagerFree(cm);
132+
return ret;
133+
}
134+
printf("Certificate chain verification: PASSED\n");
135+
136+
/* Now perform explicit OCSP check using wolfSSL_CertManagerCheckOCSP()
137+
* This function requires DER-encoded certificate data, so we need to
138+
* load the certificate file and convert it.
139+
*/
140+
printf("Performing OCSP check...\n");
141+
142+
/* Load the certificate file into memory */
143+
fp = fopen(OCSP_SERVER_CERT, "rb");
144+
if (fp == NULL) {
145+
printf("Failed to open certificate file: %s\n", OCSP_SERVER_CERT);
146+
wolfSSL_CertManagerFree(cm);
147+
return -1;
148+
}
149+
fseek(fp, 0, SEEK_END);
150+
certSz = ftell(fp);
151+
fseek(fp, 0, SEEK_SET);
152+
153+
certBuf = (unsigned char*)malloc(certSz);
154+
if (certBuf == NULL) {
155+
printf("Failed to allocate memory for certificate\n");
156+
fclose(fp);
157+
wolfSSL_CertManagerFree(cm);
158+
return -1;
159+
}
160+
if (fread(certBuf, 1, certSz, fp) != (size_t)certSz) {
161+
printf("Failed to read certificate file\n");
162+
free(certBuf);
163+
fclose(fp);
164+
wolfSSL_CertManagerFree(cm);
165+
return -1;
166+
}
167+
fclose(fp);
168+
169+
/* Convert PEM to DER if needed and check OCSP
170+
* wolfSSL_CertManagerCheckOCSP requires DER format, but we can use
171+
* wolfSSL_CertManagerCheckOCSPResponse for more control, or convert
172+
* the PEM to DER first. For simplicity, let's use the internal
173+
* conversion by loading the cert into a buffer.
174+
*/
175+
{
176+
DerBuffer* derCert = NULL;
177+
178+
/* Convert PEM to DER */
179+
ret = wc_PemToDer(certBuf, certSz, CERT_TYPE, &derCert, NULL, NULL,
180+
NULL);
181+
if (ret != 0) {
182+
printf("Failed to convert PEM to DER (%d)\n", ret);
183+
free(certBuf);
184+
wolfSSL_CertManagerFree(cm);
185+
return ret;
186+
}
187+
188+
/* Perform OCSP check - this will contact the OCSP responder */
189+
ret = wolfSSL_CertManagerCheckOCSP(cm, derCert->buffer,
190+
derCert->length);
191+
wc_FreeDer(&derCert);
192+
}
193+
free(certBuf);
194+
195+
if (ret == WOLFSSL_SUCCESS) {
196+
printf("OCSP check: PASSED\n");
197+
printf("Certificate status: GOOD (not revoked)\n");
198+
} else {
199+
printf("OCSP check failed (%d): %s\n",
200+
ret, wolfSSL_ERR_reason_error_string(ret));
201+
202+
/* Provide helpful error messages */
203+
if (ret == OCSP_CERT_REVOKED) {
204+
printf("\nCertificate has been REVOKED!\n");
205+
}
206+
else if (ret == OCSP_LOOKUP_FAIL || ret == OCSP_INVALID_STATUS) {
207+
printf("\nOCSP lookup failed!\n");
208+
printf("Make sure the OCSP responder is running:\n");
209+
printf(" cd <wolfssl-dir>\n");
210+
printf(" openssl ocsp -port 22221 -ndays 365 \\\n");
211+
printf(" -index certs/ocsp/"
212+
"index-intermediate1-ca-issued-certs.txt \\\n");
213+
printf(" -rsigner certs/ocsp/ocsp-responder-cert.pem \\\n");
214+
printf(" -rkey certs/ocsp/ocsp-responder-key.pem \\\n");
215+
printf(" -CA certs/ocsp/intermediate1-ca-cert.pem\n");
216+
}
217+
}
218+
219+
wolfSSL_CertManagerFree(cm);
220+
return ret;
221+
}
222+
#endif /* HAVE_OCSP */
223+
224+
int main(int argc, char** argv)
225+
{
226+
(void)argc;
227+
(void)argv;
228+
229+
/* Initialize wolfSSL library */
230+
if (wolfSSL_Init() != WOLFSSL_SUCCESS) {
231+
printf("wolfSSL_Init() failed\n");
232+
return -1;
233+
}
234+
235+
#ifdef DEBUG_WOLFSSL
236+
//wolfSSL_Debugging_ON();
237+
#endif
238+
239+
#ifdef HAVE_OCSP
240+
demoOCSPCheck();
241+
#else
242+
printf("OCSP checking not available (compile with --enable-ocsp)\n");
243+
#endif
244+
245+
/* Cleanup wolfSSL */
246+
wolfSSL_Cleanup();
247+
248+
}

0 commit comments

Comments
 (0)