-
Notifications
You must be signed in to change notification settings - Fork 192
Show OCSP checking via CertManager #539
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
anhu
wants to merge
1
commit into
wolfSSL:master
Choose a base branch
from
anhu:certmanager_ocsp
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,25 +1,85 @@ | ||
| # wolfSSL CertManager Example | ||
| # wolfSSL CertManager Examples | ||
|
|
||
| This directory contains: | ||
| This directory contains examples of using the wolfSSL CertManager to verify | ||
| certificates in a standalone manner, separate from an SSL/TLS connection. | ||
|
|
||
| A simple example of using the wolfSSL CertManager to verify a certificate | ||
| in a standalone manner, separate from an SSL/TLS connection. | ||
| ## Examples | ||
|
|
||
| ## Compiling and Running the Example | ||
| - **certverify.c** - Basic certificate verification example | ||
| - **certloadverifybuffer.c** - Certificate verification from memory buffer | ||
| - **certverify_ocsp.c** - Certificate verification with OCSP | ||
| revocation checking | ||
|
|
||
| ## Building wolfSSL | ||
|
|
||
| ```bash | ||
| cd wolfssl | ||
| ./autogen.sh | ||
| ./configure --enable-crl --enable-ocsp | ||
| make all | ||
| make check | ||
| sudo make install | ||
| ``` | ||
| $ cd wolfssl | ||
| $ ./autogen.sh # If downloaded from github | ||
| $ ./configure --enable-crl # CRL is optional. | ||
| $ make all | ||
| $ make check | ||
| $ sudo make install | ||
|
|
||
| ## Building the Examples | ||
|
|
||
| ```bash | ||
| cd wolfssl-examples/certmanager | ||
| make all | ||
| ``` | ||
|
|
||
| ## Running the Basic Example | ||
|
|
||
| ```bash | ||
| ./certverify | ||
| ./certloadverifybuffer | ||
| ``` | ||
| $ cd wolfssl-examples | ||
| $ cd certmanager | ||
| $ make all | ||
| $ ./certverify | ||
|
|
||
| ## Running the OCSP Example | ||
|
|
||
| The `certverify_ocsp` example demonstrates certificate verification with | ||
| OCSP (Online Certificate Status Protocol) checking. | ||
|
|
||
| The OCSP demo requires an OCSP responder to be running. You can start one using | ||
| OpenSSL: | ||
|
|
||
| **Terminal 1 - Start the OCSP Responder:** | ||
|
|
||
| From the wolfSSL library source code directory: | ||
|
|
||
| ```bash | ||
| openssl ocsp -port 22221 -ndays 365 \ | ||
| -index certs/ocsp/index-intermediate1-ca-issued-certs.txt \ | ||
| -rsigner certs/ocsp/ocsp-responder-cert.pem \ | ||
| -rkey certs/ocsp/ocsp-responder-key.pem \ | ||
| -CA certs/ocsp/intermediate1-ca-cert.pem \ | ||
| -text | ||
| ``` | ||
|
|
||
| **Terminal 2 - Run the Example:** | ||
| ```bash | ||
| ./certverify_crl_ocsp | ||
| ``` | ||
|
|
||
| ### Expected Output | ||
|
|
||
| When the OCSP responder is running, you should see output that indicates basic | ||
| verification passed and OCSP checking is done and successful. Importantly, | ||
| OpenSSL should also show some pretty prints of the OCSP request. | ||
|
|
||
| ### OCSP Certificate Structure | ||
|
|
||
| The OCSP test uses the following certificate chain from the wolfSSL repository's | ||
| `certs/ocsp/` directory. This assumes the wolfssl and wolfssl-examples | ||
| repositories are in the same parent directory. | ||
|
|
||
|
|
||
| - **root-ca-cert.pem** - Root CA certificate | ||
| - **intermediate1-ca-cert.pem** - Intermediate CA that issued the server cert | ||
| - **server1-cert.pem** - Server certificate with OCSP URL in AIA extension | ||
| - **ocsp-responder-cert.pem** - Certificate for the OCSP responder | ||
| - **ocsp-responder-key.pem** - Private key for the OCSP responder | ||
|
|
||
| The server1-cert.pem certificate contains an Authority Information Access (AIA) | ||
| extension pointing to `http://127.0.0.1:22221` for OCSP queries. | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,248 @@ | ||
| /* certverify_crl_ocsp.c | ||
| * | ||
| * Copyright (C) 2006-2025 wolfSSL Inc. | ||
| * | ||
| * This file is part of wolfSSL. | ||
| * | ||
| * wolfSSL 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 2 of the License, or | ||
| * (at your option) any later version. | ||
| * | ||
| * wolfSSL 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 this program; if not, write to the Free Software | ||
| * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA | ||
| */ | ||
|
|
||
| /* This example demonstrates certificate verification using the wolfSSL | ||
| * Certificate Manager API with CRL (Certificate Revocation List) and | ||
| * OCSP (Online Certificate Status Protocol) checking. | ||
| * | ||
| * For OCSP testing, this example requires an OpenSSL OCSP responder. | ||
| * See README.md for instructions on starting the OCSP responder. | ||
| * | ||
| * Build wolfSSL with: | ||
| * ./configure --enable-crl --enable-ocsp | ||
| * make && sudo make install | ||
| */ | ||
|
|
||
| #include <stdio.h> | ||
| #include <stdlib.h> | ||
| #include <string.h> | ||
|
|
||
| #include <wolfssl/options.h> | ||
| #include <wolfssl/ssl.h> | ||
| #include <wolfssl/wolfcrypt/error-crypt.h> | ||
| #include <wolfssl/test.h> | ||
|
|
||
| #ifdef HAVE_OCSP | ||
| /* Certificate paths for OCSP testing | ||
| * These certificates are from wolfSSL's certs/ocsp directory and are | ||
| * configured to work with an OpenSSL OCSP responder. | ||
| * The server1-cert.pem certificate has an AIA extension with OCSP URL: | ||
| * http://127.0.0.1:22221 | ||
| * | ||
| * Note: This assumes wolfssl and wolfssl-examples repos are in the same | ||
| * parent directory. | ||
| */ | ||
| #define OCSP_ROOT_CA "../../wolfssl/certs/ocsp/root-ca-cert.pem" | ||
| #define OCSP_INTER_CA "../../wolfssl/certs/ocsp/intermediate1-ca-cert.pem" | ||
| #define OCSP_SERVER_CERT "../../wolfssl/certs/ocsp/server1-cert.pem" | ||
|
|
||
| /* Demonstrate OCSP checking with a real OCSP responder | ||
| * | ||
| * Before running this demo, start the OpenSSL OCSP responder: | ||
| * cd <wolfssl-dir> | ||
| * openssl ocsp -port 22221 -ndays 365 \ | ||
| * -index certs/ocsp/index-intermediate1-ca-issued-certs.txt \ | ||
| * -rsigner certs/ocsp/ocsp-responder-cert.pem \ | ||
| * -rkey certs/ocsp/ocsp-responder-key.pem \ | ||
| * -CA certs/ocsp/intermediate1-ca-cert.pem | ||
| */ | ||
| static int demoOCSPCheck(void) | ||
| { | ||
| int ret; | ||
| WOLFSSL_CERT_MANAGER* cm = NULL; | ||
| FILE* fp = NULL; | ||
| long certSz; | ||
| unsigned char* certBuf = NULL; | ||
|
|
||
| /* Create a new Certificate Manager for OCSP testing | ||
| * We use a separate CM because we need different CA certificates | ||
| * for the OCSP certificate chain. | ||
| */ | ||
| cm = wolfSSL_CertManagerNew(); | ||
| if (cm == NULL) { | ||
| printf("Failed to create Certificate Manager for OCSP\n"); | ||
| return -1; | ||
| } | ||
|
|
||
| /* Load the root CA certificate */ | ||
| ret = wolfSSL_CertManagerLoadCA(cm, OCSP_ROOT_CA, NULL); | ||
| if (ret != WOLFSSL_SUCCESS) { | ||
| printf("Failed to load OCSP root CA (%d): %s\n", | ||
| ret, wolfSSL_ERR_reason_error_string(ret)); | ||
| wolfSSL_CertManagerFree(cm); | ||
| return ret; | ||
| } | ||
| printf("Loaded root CA: %s\n", OCSP_ROOT_CA); | ||
|
|
||
| /* Load the intermediate CA certificate */ | ||
| ret = wolfSSL_CertManagerLoadCA(cm, OCSP_INTER_CA, NULL); | ||
| if (ret != WOLFSSL_SUCCESS) { | ||
| printf("Failed to load OCSP intermediate CA (%d): %s\n", | ||
| ret, wolfSSL_ERR_reason_error_string(ret)); | ||
| wolfSSL_CertManagerFree(cm); | ||
| return ret; | ||
| } | ||
| printf("Loaded intermediate CA: %s\n", OCSP_INTER_CA); | ||
|
|
||
| /* Enable OCSP checking | ||
| * Options (can be combined with |): | ||
| * WOLFSSL_OCSP_URL_OVERRIDE - Use override URL instead of cert's AIA | ||
| * WOLFSSL_OCSP_NO_NONCE - Don't include nonce in request | ||
| * WOLFSSL_OCSP_CHECKALL - Check all certificates in chain | ||
| * | ||
| * We use WOLFSSL_OCSP_NO_NONCE because OpenSSL's OCSP responder | ||
| * may not support nonces by default. | ||
| */ | ||
| ret = wolfSSL_CertManagerEnableOCSP(cm, WOLFSSL_OCSP_NO_NONCE); | ||
| if (ret != WOLFSSL_SUCCESS) { | ||
| printf("Failed to enable OCSP (%d): %s\n", | ||
| ret, wolfSSL_ERR_reason_error_string(ret)); | ||
| wolfSSL_CertManagerFree(cm); | ||
| return ret; | ||
| } | ||
| printf("OCSP checking enabled\n"); | ||
|
|
||
| /* First, verify the certificate chain without OCSP. | ||
| * Note: wolfSSL_CertManagerVerify() does NOT perform OCSP checks. | ||
| */ | ||
| printf("Verifying certificate: %s\n", OCSP_SERVER_CERT); | ||
| ret = wolfSSL_CertManagerVerify(cm, OCSP_SERVER_CERT, WOLFSSL_FILETYPE_PEM); | ||
| if (ret != WOLFSSL_SUCCESS) { | ||
| printf("Certificate chain verification failed (%d): %s\n", | ||
| ret, wolfSSL_ERR_reason_error_string(ret)); | ||
| wolfSSL_CertManagerFree(cm); | ||
| return ret; | ||
| } | ||
| printf("Certificate chain verification: PASSED\n"); | ||
|
|
||
| /* Now perform explicit OCSP check using wolfSSL_CertManagerCheckOCSP() | ||
| * This function requires DER-encoded certificate data, so we need to | ||
| * load the certificate file and convert it. | ||
| */ | ||
| printf("Performing OCSP check...\n"); | ||
|
|
||
| /* Load the certificate file into memory */ | ||
| fp = fopen(OCSP_SERVER_CERT, "rb"); | ||
| if (fp == NULL) { | ||
| printf("Failed to open certificate file: %s\n", OCSP_SERVER_CERT); | ||
| wolfSSL_CertManagerFree(cm); | ||
| return -1; | ||
| } | ||
| fseek(fp, 0, SEEK_END); | ||
| certSz = ftell(fp); | ||
| fseek(fp, 0, SEEK_SET); | ||
|
|
||
| certBuf = (unsigned char*)malloc(certSz); | ||
| if (certBuf == NULL) { | ||
| printf("Failed to allocate memory for certificate\n"); | ||
| fclose(fp); | ||
| wolfSSL_CertManagerFree(cm); | ||
| return -1; | ||
| } | ||
| if (fread(certBuf, 1, certSz, fp) != (size_t)certSz) { | ||
| printf("Failed to read certificate file\n"); | ||
| free(certBuf); | ||
| fclose(fp); | ||
| wolfSSL_CertManagerFree(cm); | ||
| return -1; | ||
| } | ||
| fclose(fp); | ||
|
|
||
| /* Convert PEM to DER if needed and check OCSP | ||
| * wolfSSL_CertManagerCheckOCSP requires DER format, but we can use | ||
| * wolfSSL_CertManagerCheckOCSPResponse for more control, or convert | ||
| * the PEM to DER first. For simplicity, let's use the internal | ||
| * conversion by loading the cert into a buffer. | ||
| */ | ||
| { | ||
| DerBuffer* derCert = NULL; | ||
|
|
||
| /* Convert PEM to DER */ | ||
| ret = wc_PemToDer(certBuf, certSz, CERT_TYPE, &derCert, NULL, NULL, | ||
| NULL); | ||
| if (ret != 0) { | ||
| printf("Failed to convert PEM to DER (%d)\n", ret); | ||
| free(certBuf); | ||
| wolfSSL_CertManagerFree(cm); | ||
| return ret; | ||
| } | ||
|
|
||
| /* Perform OCSP check - this will contact the OCSP responder */ | ||
| ret = wolfSSL_CertManagerCheckOCSP(cm, derCert->buffer, | ||
| derCert->length); | ||
| wc_FreeDer(&derCert); | ||
| } | ||
| free(certBuf); | ||
|
|
||
| if (ret == WOLFSSL_SUCCESS) { | ||
| printf("OCSP check: PASSED\n"); | ||
| printf("Certificate status: GOOD (not revoked)\n"); | ||
| } else { | ||
| printf("OCSP check failed (%d): %s\n", | ||
| ret, wolfSSL_ERR_reason_error_string(ret)); | ||
|
|
||
| /* Provide helpful error messages */ | ||
| if (ret == OCSP_CERT_REVOKED) { | ||
| printf("\nCertificate has been REVOKED!\n"); | ||
| } | ||
| else if (ret == OCSP_LOOKUP_FAIL || ret == OCSP_INVALID_STATUS) { | ||
| printf("\nOCSP lookup failed!\n"); | ||
| printf("Make sure the OCSP responder is running:\n"); | ||
| printf(" cd <wolfssl-dir>\n"); | ||
| printf(" openssl ocsp -port 22221 -ndays 365 \\\n"); | ||
| printf(" -index certs/ocsp/" | ||
| "index-intermediate1-ca-issued-certs.txt \\\n"); | ||
| printf(" -rsigner certs/ocsp/ocsp-responder-cert.pem \\\n"); | ||
| printf(" -rkey certs/ocsp/ocsp-responder-key.pem \\\n"); | ||
| printf(" -CA certs/ocsp/intermediate1-ca-cert.pem\n"); | ||
| } | ||
| } | ||
|
|
||
| wolfSSL_CertManagerFree(cm); | ||
| return ret; | ||
| } | ||
| #endif /* HAVE_OCSP */ | ||
|
|
||
| int main(int argc, char** argv) | ||
| { | ||
| (void)argc; | ||
| (void)argv; | ||
|
|
||
| /* Initialize wolfSSL library */ | ||
| if (wolfSSL_Init() != WOLFSSL_SUCCESS) { | ||
| printf("wolfSSL_Init() failed\n"); | ||
| return -1; | ||
| } | ||
|
|
||
| #ifdef DEBUG_WOLFSSL | ||
| //wolfSSL_Debugging_ON(); | ||
| #endif | ||
|
|
||
| #ifdef HAVE_OCSP | ||
| demoOCSPCheck(); | ||
| #else | ||
| printf("OCSP checking not available (compile with --enable-ocsp)\n"); | ||
| #endif | ||
|
|
||
| /* Cleanup wolfSSL */ | ||
| wolfSSL_Cleanup(); | ||
|
|
||
| } |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is in a few places