feat: add CertificateManager

This commit is contained in:
2026-05-12 16:41:55 -03:00
parent 2327a33e7d
commit 66ff3d26e5
2 changed files with 163 additions and 0 deletions
+127
View File
@@ -0,0 +1,127 @@
#include "ssl.h"
#define WOLFSSL_ALT_NAMES
#include <wolfssl/options.h>
#include <wolfssl/ssl.h>
#include <wolfssl/wolfcrypt/rsa.h>
#include <wolfssl/wolfcrypt/asn.h>
#include <wolfssl/wolfcrypt/random.h>
#include <wolfssl/wolfcrypt/error-crypt.h>
#include <fstream>
/*
CertificateManager implementation
*/
CertificateManager::CertificateManager() : _rng(new WC_RNG()), _caKey(nullptr), _sessionKey(nullptr) {}
CertificateManager::~CertificateManager()
{
for (auto& pair : _hostContexts)
wolfSSL_CTX_free(pair.second);
}
bool CertificateManager::init()
{
if (wc_InitRng(_rng.get()) != 0) return false;
// session init
_sessionKey.reset(new RsaKey());
wc_InitRsaKey(_sessionKey.get(), nullptr);
if (wc_MakeRsaKey(_sessionKey.get(), 2048, 65537, _rng.get()) != 0) return false;
// der cache
_sessionKeyDer.resize(4096);
int derLen = wc_RsaKeyToDer(_sessionKey.get(), _sessionKeyDer.data(), (word32)_sessionKeyDer.size());
if (derLen < 0) return false;
_sessionKeyDer.resize(derLen);
if (loadCA()) return true;
return generateCA();
}
WOLFSSL_CTX* CertificateManager::createHostContext(const std::string& host)
{
std::lock_guard<std::mutex> lock(_mutex);
if (_hostContexts.count(host)) return _hostContexts[host];
if (!_caKey) return nullptr;
auto cert = std::make_unique<Cert>();
memset(cert.get(), 0, sizeof(Cert));
wc_InitCert(cert.get());
strncpy(cert->subject.commonName, host.c_str(), sizeof(cert->subject.commonName));
cert->sigType = CTC_SHA256wRSA;
cert->daysValid = 365;
uint32_t serial = std::hash<std::string>{}(host) & 0x7FFFFFFF;
memcpy(cert->serial, &serial, sizeof(serial));
cert->serialSz = sizeof(serial);
wc_SetAltNames(cert.get(), host.c_str());
std::vector<unsigned char> hostCertDer(4096);
int certLen =
wc_MakeCert(cert.get(), hostCertDer.data(), (word32)hostCertDer.size(), _sessionKey.get(), nullptr, _rng.get());
certLen = wc_SignCert(cert->bodySz, cert->sigType, hostCertDer.data(), (word32)hostCertDer.size(), _caKey.get(),
nullptr, _rng.get());
hostCertDer.resize(certLen);
WOLFSSL_CTX* ctx = wolfSSL_CTX_new(wolfTLSv1_3_server_method());
if (!ctx) return nullptr;
if (wolfSSL_CTX_use_certificate_buffer(ctx, hostCertDer.data(), (long)hostCertDer.size(), WOLFSSL_FILETYPE_ASN1) !=
WOLFSSL_SUCCESS ||
wolfSSL_CTX_use_PrivateKey_buffer(ctx, _sessionKeyDer.data(), (long)_sessionKeyDer.size(),
WOLFSSL_FILETYPE_ASN1) != WOLFSSL_SUCCESS)
{
wolfSSL_CTX_free(ctx);
return nullptr;
}
_hostContexts[host] = ctx;
return ctx;
}
bool CertificateManager::generateCA()
{
_caKey.reset(new RsaKey());
wc_InitRsaKey(_caKey.get(), nullptr);
if (wc_MakeRsaKey(_caKey.get(), 2048, 65537, _rng.get()) != 0)
{
return false;
}
auto cert = std::make_unique<Cert>();
memset(cert.get(), 0, sizeof(Cert));
wc_InitCert(cert.get());
strncpy(cert->subject.commonName, "TinyMITM-CA", sizeof(cert->subject.commonName));
cert->isCA = 1;
cert->sigType = CTC_SHA256wRSA;
cert->daysValid = 3650;
_caCertDer.resize(4096);
int certLen =
wc_MakeCert(cert.get(), _caCertDer.data(), (word32)_caCertDer.size(), _caKey.get(), nullptr, _rng.get());
if (certLen < 0) return false;
certLen = wc_SignCert(cert->bodySz, cert->sigType, _caCertDer.data(), (word32)_caCertDer.size(), _caKey.get(),
nullptr, _rng.get());
if (certLen < 0) return false;
_caCertDer.resize(certLen);
return true;
}
bool CertificateManager::loadCA()
{
return false;
}
+36
View File
@@ -0,0 +1,36 @@
#pragma once
#include <string>
#include <memory>
#include <mutex>
#include <vector>
#include <unordered_map>
#include "raai-helper.h"
class CertificateManager
{
public:
CertificateManager();
~CertificateManager();
bool init();
WOLFSSL_CTX* createHostContext(const std::string& host);
private:
bool generateCA();
bool loadCA();
std::unique_ptr<RsaKey, WolfSSLDeleter> _caKey;
std::unique_ptr<RsaKey, WolfSSLDeleter> _sessionKey;
std::vector<unsigned char> _caCertDer;
std::vector<unsigned char> _sessionKeyDer;
std::unique_ptr<WC_RNG, WolfSSLDeleter> _rng;
std::mutex _mutex;
std::unordered_map<std::string, WOLFSSL_CTX*> _hostContexts;
};