From 93df62b91bbc7bbafdad79abac1e4a60f08919e5 Mon Sep 17 00:00:00 2001 From: neru Date: Wed, 13 May 2026 11:20:06 -0300 Subject: [PATCH] fix: implement correct SAN for ctx cert --- src/proxy/tinymitm/ssl.cpp | 46 +++++++++++++++++++++++++++++--------- 1 file changed, 36 insertions(+), 10 deletions(-) diff --git a/src/proxy/tinymitm/ssl.cpp b/src/proxy/tinymitm/ssl.cpp index 8cf3406..7904e3e 100644 --- a/src/proxy/tinymitm/ssl.cpp +++ b/src/proxy/tinymitm/ssl.cpp @@ -38,7 +38,7 @@ bool CertificateManager::init() // der cache _sessionKeyDer.resize(4096); - int derLen = wc_RsaKeyToDer(_sessionKey.get(), _sessionKeyDer.data(), (word32)_sessionKeyDer.size()); + int derLen = wc_RsaKeyToDer(_sessionKey.get(), _sessionKeyDer.data(), static_cast(_sessionKeyDer.size())); if (derLen < 0) return false; _sessionKeyDer.resize(derLen); @@ -51,32 +51,59 @@ WOLFSSL_CTX* CertificateManager::createHostContext(const std::string& host) if (_hostContexts.count(host)) return _hostContexts[host]; if (!_caKey) return nullptr; + std::string hostTrimmed = host; + hostTrimmed.erase(0, hostTrimmed.find_first_not_of(" \t\r\n")); + hostTrimmed.erase(hostTrimmed.find_last_not_of(" \t\r\n") + 1); + + /* + cert config + */ auto cert = std::make_unique(); memset(cert.get(), 0, sizeof(Cert)); wc_InitCert(cert.get()); - strncpy_s(cert->subject.commonName, sizeof(cert->subject.commonName), host.c_str(), _TRUNCATE); + cert->version = 2; cert->sigType = CTC_SHA256wRSA; cert->daysValid = 365; - uint32_t serial = std::hash{}(host) & 0x7FFFFFFF; - memcpy(cert->serial, &serial, sizeof(serial)); - cert->serialSz = sizeof(serial); + strncpy_s(cert->subject.commonName, sizeof(cert->subject.commonName), hostTrimmed.c_str(), _TRUNCATE); + wc_SetIssuerBuffer(cert.get(), _caCertDer.data(), (int)_caCertDer.size()); - wc_SetAltNames(cert.get(), host.c_str()); + // serial hash based on host + uint32_t hash = (uint32_t)std::hash{}(hostTrimmed) & 0x7FFFFFFF; + cert->serialSz = 4; + cert->serial[0] = (hash >> 24) & 0xFF; + cert->serial[1] = (hash >> 16) & 0xFF; + cert->serial[2] = (hash >> 8) & 0xFF; + cert->serial[3] = hash & 0xFF; + // SAN + std::vector sanDer; + sanDer.push_back(0x30); + sanDer.push_back(static_cast(hostTrimmed.length() + 2)); + sanDer.push_back(0x82); + sanDer.push_back(static_cast(hostTrimmed.length())); + sanDer.insert(sanDer.end(), hostTrimmed.begin(), hostTrimmed.end()); + + memcpy(cert->altNames, sanDer.data(), sanDer.size()); + cert->altNamesSz = (word16)sanDer.size(); + + /* + cert sign + */ std::vector 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()); + /* + context setup + */ + WOLFSSL_CTX* ctx = wolfSSL_CTX_new(wolfSSLv23_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(), @@ -85,7 +112,6 @@ WOLFSSL_CTX* CertificateManager::createHostContext(const std::string& host) wolfSSL_CTX_free(ctx); return nullptr; } - _hostContexts[host] = ctx; return ctx; }