Skip to content

Diogoperei29/x.509-cert-verifier

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

X.509 Certificate Chain Verifier

License C++ Standard Build System Requires Python

A robust, secure, and modern C++ utility for loading and verifying X.509 certificate chains against a local trust store using the OpenSSL library.

Summary

This project provides a CertVerifier class that encapsulates the logic for X.509 certificate verification. It is built with a strong emphasis on security and resource safety, using modern C++ RAII patterns to manage OpenSSL's C-style resources.

The work flow of this class is as such:

  • Loads all PEM-encoded root CAs from a directory
  • Verifies a certificate or full chain against that trust store
  • Uses RAII wrappers (std::unique_ptr) to manage OpenSSL resources
    A small verifier_app executable demonstrates usage, and a test suite verifies valid, expired, and untrusted chains.

Features

  • Secure by Default: Fails closed and provides clear error messages on verification failure.
  • RAII Wrappers: Utilizes std::unique_ptr with custom deleters for all OpenSSL objects (X509, X509_STORE_CTX, etc.) to prevent resource leaks.
  • Dynamic Trust Store: Manual, filesystem-based trust-store loading
  • CMake Build System: Plain C++ build with CMake
  • Test Suite: Google Test (GTest) framework with test cases covering valid, expired, and untrusted certificate chains
  • Certificate creation: Python script to generate test certificates automatically

Prerequisites

To build and run this project, you will need:

  • C++17-capable compiler (GCC 7+, Clang 6+, or MSVC)
  • CMake 3.16 or newer
  • OpenSSL development libraries (system installation)
  • Python 3.7+ and the cryptography library (pip install cryptography)
  • nlohmann/json and Google Test (automatically fetched by CMake)

Installing on MSYS2/MinGW

  1. Open the “MSYS2 MinGW 64-bit” shell and run:
pacman -Syu  
pacman -S mingw-w64-x86_64-cmake mingw-w64-x86_64-openssl mingw-w64-x86_64-toolchain  
  1. Verify:
cmake --version  
openssl version

How to Build

  1. Clone the repository:

    git clone https://github.com/Diogoperei29/x.509-cert-verifier.git x509-verifier
    cd x509-verifier
  2. Configure with CMake:

    cmake -S . -B build

    On Windows with MSYS2/MinGW, you may need to specify OpenSSL location:

    cmake -S . -B build -DOPENSSL_ROOT_DIR="C:/msys64/mingw64"
  3. Compile the project:

    cmake --build build

    The executables verifier_app and run_tests will be created in the build/ directory.

Generating Test Certificates

A Python script automates creation of test certs:
scripts/generate_test_certs.py

  1. Install cryptography:
pip install cryptography  
  1. Run:
python3 scripts/generate_test_certs.py  

This produces:

  • certs/trust_store/rootCA.key & rootCA.pem
  • certs/test_certs/good/valid_chain.pem
  • certs/test_certs/bad_expired/expired_chain.pem
  • certs/test_certs/bad_untrusted/untrustedCA.pem & untrusted_chain.pem

How to Use

1. Prepare the Trust Store

The verifier needs a "trust store" — a directory containing the root Certificate Authority (CA) certificates that you trust. These certificates must be in PEM format (.pem, .crt).

  1. Create a directory to act as your trust store. For this project, we use certs/trust_store/.

  2. Add your trusted root CA PEM files to this directory. You can often acquire these from browser vendors or your operating system's trust store.

    For example, to add a root CA:

    cp /path/to/your/root-ca.pem certs/trust_store/

2. Run the Verifier

The main application verifier_app takes two arguments:

  1. The path to the trust store directory.
  2. The path to the certificate (or certificate chain) file to verify.

Example:

# This command assumes you have a valid root CA in the trust_store
# that signed the certificate chain in valid_chain.pem.
./build/verifier_app certs/trust_store certs/test_certs/good/valid_chain.pem

Expected Output (Success):

Verification Successful

Expected Output (Failure):

Verification Failed: [reason] 

Running Tests

The project uses Google Test framework with test cases covering valid, expired, and untrusted certificate chains.

Using CTest:

cd build
ctest --output-on-failure

Run tests directly:

./build/run_tests

Project Structure

X.509-Certificate-Chain-Verifier/
├── include/
│   ├── CertVerifier.hpp              # Main certificate verifier class
│   └── OpenSslWrappers.hpp           # RAII wrappers for OpenSSL types
├── src/
│   ├── CertVerifier.cpp              # Core verification logic
│   ├── CertVerifierError.cpp         # Error handling implementation
│   └── main.cpp                      # Command-line application
├── tests/
│   └── TestVerifier.cpp              # GTest test suite
├── scripts/
│   └── generate_test_certs.py        # Certificate generation script
├── certs/
│   ├── trust_store/                  # Root CA certificates
│   └── test_certs/                   # Generated test certificates
│       ├── good/                     # Valid certificates
│       ├── bad_expired/              # Expired certificates
│       └── bad_untrusted/            # Untrusted CA certificates
└── CMakeLists.txt                    # Build configuration

Architecture

Core Components

  • CertVerifier: Main class handling certificate verification

    • Trust store loading from filesystem
    • Certificate chain verification against trust store
    • RAII-based resource management
  • OpenSslWrappers: RAII wrappers for OpenSSL C types

    • X509_ptr, X509_STORE_ptr, X509_STORE_CTX_ptr, BIO_ptr
    • Automatic resource cleanup
    • Exception-safe resource management

Security Considerations

  • Trust-store integrity: protect certs/trust_store/ with strict permissions
  • No revocation checking: consider CRL or OCSP for production
  • Keep OpenSSL and the Python cryptography library up-to-date
  • Only files ending in .pem, .crt, .cer are loaded as CAs

About

A small project for loading and verifying X.509 certificate chains against a local trust store using the OpenSSL library.

Topics

Resources

License

Stars

2 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors