https://github.com/jimmy-park/cert-cmake
Generate cert.h for loading in-memory cert
https://github.com/jimmy-park/cert-cmake
certificate cmake cpp cpp17 header-only
Last synced: 7 months ago
JSON representation
Generate cert.h for loading in-memory cert
- Host: GitHub
- URL: https://github.com/jimmy-park/cert-cmake
- Owner: jimmy-park
- License: mit
- Created: 2023-02-12T18:04:56.000Z (over 2 years ago)
- Default Branch: main
- Last Pushed: 2025-03-01T04:39:16.000Z (7 months ago)
- Last Synced: 2025-03-01T05:23:51.988Z (7 months ago)
- Topics: certificate, cmake, cpp, cpp17, header-only
- Language: CMake
- Homepage:
- Size: 48.8 KB
- Stars: 1
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# cert-cmake
[](https://github.com/jimmy-park/cert-cmake/actions/workflows/ci.yaml)
[](https://github.com/jimmy-park/cert-cmake/actions/workflows/latest.yaml)Generate `cert.h` for loading in-memory cert
Require C++17 due to `inline` variable
## CMake Options
| Option | Default | Description |
| -------------- | ------------- | ------------------------------------------------------- |
| `CERT_SOURCE` | `(undefined)` | Specify the location of certificates (URL or file path) |
| `CERT_INSTALL` | `OFF` | Install `cert.h` and CMake targets |- `CERT_SOURCE`
- When this isn't defined, download the latest CA bundle maintained by [curl](https://curl.se/docs/caextract.html)> [!NOTE]
> If you want to use a local PEM file, `CERT_SOURCE` must be an absolute path.## Usage
### Build
```sh
cmake --list-presets all # List all CMake presets
cmake --preset windows # Configure
cmake --build --preset windows # Build
ctest --preset windows # Test
cmake --build --preset windows -t install # Install
```### Integration
Require CMake 3.23+
```CMake
include(FetchContent)
FetchContent_Declare(
cert-cmake
URL https://github.com/jimmy-park/cert-cmake/archive/main.tar.gz
)
FetchContent_MakeAvailable(cert-cmake)# If you're using CPM.cmake
# CPMAddPackage(
# NAME cert-cmake
# URL https://github.com/jimmy-park/cert-cmake/archive/main.tar.gz
# )add_executable(main main.cpp)
target_link_libraries(main PRIVATE cert::cert)
```## Example
### curl
```cpp
static constexpr auto blob = curl_blob {
const_cast(kCert),
sizeof(kCert),
CURL_BLOB_NOCOPY
};auto* curl = curl_easy_init();
curl_easy_setopt(curl, CURLOPT_CAINFO_BLOB, &blob);
curl_easy_setopt(curl, CURLOPT_URL, "https://nghttp2.org/httpbin/get");
curl_easy_perform(curl);
curl_easy_cleanup(curl);
```### OpenSSL
```cpp
template
struct Deleter {
template
constexpr void operator()(T* ptr) const { func(ptr); }
};using X509Info = STACK_OF(X509_INFO);
void FreeX509Info(X509Info* ptr) { sk_X509_INFO_pop_free(ptr, X509_INFO_free); }
using X509Ptr = std::unique_ptr>;
using BioPtr = std::unique_ptr>;void LoadCert(void* ssl_context)
{
// https://www.openssl.org/docs/manmaster/man3/OPENSSL_thread_stop.html
struct OpenSSLCleaner {
~OpenSSLCleaner() { OPENSSL_thread_stop(); }
};
thread_local const OpenSSLCleaner openssl_clenaer;
static const auto x509_ptr = [] {
const auto bio_ptr = BioPtr { BIO_new_mem_buf(kCert, sizeof(kCert)) };
return X509Ptr { PEM_X509_INFO_read_bio(bio_ptr.get(), nullptr, nullptr, nullptr) };
}();static const auto certs = [] {
std::vector x509s;for (int first = 0, last = sk_X509_INFO_num(x509_ptr.get()); first < last; ++first) {
auto* value = sk_X509_INFO_value(x509_ptr.get(), first);
if (value && value->x509)
x509s.push_back(value->x509);
}return x509s;
}();if (!ssl_context)
return;auto* x509_store = SSL_CTX_get_cert_store(static_cast(ssl_context));
for (const auto x509 : certs)
X509_STORE_add_cert(x509_store, x509);
}
```### curl + OpenSSL
```cpp
auto ssl_callback = +[](CURL*, void* ssl_ctx, void*) {
LoadCert(ssl_ctx);
return CURLE_OK;
};auto* curl = curl_easy_init();
curl_easy_setopt(curl, CURLOPT_SSL_CTX_FUNCTION, ssl_callback);
curl_easy_setopt(curl, CURLOPT_URL, "https://nghttp2.org/httpbin/get");
curl_easy_perform(curl);
curl_easy_cleanup(curl);
```