Compare commits
18 Commits
af316c3d61
..
main
| Author | SHA1 | Date | |
|---|---|---|---|
| df146989df | |||
| 699dc354c8 | |||
| efca4fd3fd | |||
| 4d54533f9a | |||
| 558f964ce2 | |||
| 409c41e196 | |||
| 55202646ca | |||
| a9c1a30218 | |||
| 6602a25188 | |||
| cd1146d0d8 | |||
| dad8cb55d7 | |||
| 6ad87ecc18 | |||
| e0e0eb5f12 | |||
| c0adefeda1 | |||
| b7a0d494fb | |||
| f5442a8fc4 | |||
| 97fb406c32 | |||
| f585fa48ad |
+14
-5
@@ -17,10 +17,6 @@ if (TINYMITM_TEST)
|
|||||||
set(TINYMITM_LOGS ON CACHE BOOL "" FORCE)
|
set(TINYMITM_LOGS ON CACHE BOOL "" FORCE)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (TINYMITM_LOGS)
|
|
||||||
add_compile_definitions(TINYMITM_LOGS)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# ---------------------
|
# ---------------------
|
||||||
# external dependencies
|
# external dependencies
|
||||||
# ---------------------
|
# ---------------------
|
||||||
@@ -38,7 +34,7 @@ FetchContent_Declare(
|
|||||||
|
|
||||||
# seallib config
|
# seallib config
|
||||||
set(SEALLIB_EVENTS ON CACHE BOOL "" FORCE)
|
set(SEALLIB_EVENTS ON CACHE BOOL "" FORCE)
|
||||||
if (TINYMITM_LOGS)
|
if (TINYMITM_LOGS OR $CACHE{TINYMITM_LOGS})
|
||||||
set(SEALLIB_LOG ON CACHE BOOL "" FORCE)
|
set(SEALLIB_LOG ON CACHE BOOL "" FORCE)
|
||||||
endif()
|
endif()
|
||||||
FetchContent_GetProperties(seallib)
|
FetchContent_GetProperties(seallib)
|
||||||
@@ -47,6 +43,9 @@ FetchContent_MakeAvailable(seallib)
|
|||||||
# wolfssl config
|
# wolfssl config
|
||||||
set(WOLFSSL_ALPN ON CACHE BOOL "" FORCE)
|
set(WOLFSSL_ALPN ON CACHE BOOL "" FORCE)
|
||||||
set(WOLFSSL_CERTGEN ON CACHE BOOL "" FORCE)
|
set(WOLFSSL_CERTGEN ON CACHE BOOL "" FORCE)
|
||||||
|
set(WOLFSSL_CERTEXT ON CACHE BOOL "" FORCE)
|
||||||
|
set(WOLFSSL_KEYGEN ON CACHE BOOL "" FORCE)
|
||||||
|
set(WOLFSSL_SNI ON CACHE BOOL "" FORCE)
|
||||||
set(WOLFSSL_EXAMPLES OFF CACHE BOOL "" FORCE)
|
set(WOLFSSL_EXAMPLES OFF CACHE BOOL "" FORCE)
|
||||||
set(WOLFSSL_CRYPT_TESTS OFF CACHE BOOL "" FORCE)
|
set(WOLFSSL_CRYPT_TESTS OFF CACHE BOOL "" FORCE)
|
||||||
set(BUILD_SHARED_LIBS OFF CACHE BOOL "" FORCE)
|
set(BUILD_SHARED_LIBS OFF CACHE BOOL "" FORCE)
|
||||||
@@ -56,6 +55,8 @@ FetchContent_MakeAvailable(wolfssl)
|
|||||||
target_compile_definitions(wolfssl PUBLIC
|
target_compile_definitions(wolfssl PUBLIC
|
||||||
-DWOLFSSL_ALT_NAMES
|
-DWOLFSSL_ALT_NAMES
|
||||||
-DWOLFSSL_ALPN
|
-DWOLFSSL_ALPN
|
||||||
|
-DWOLFSSL_HAVE_MIN
|
||||||
|
-DWOLFSSL_HAVE_MAX
|
||||||
)
|
)
|
||||||
|
|
||||||
# ---------------------
|
# ---------------------
|
||||||
@@ -79,6 +80,14 @@ target_link_libraries(tinymitm PRIVATE tinymitm-warnings)
|
|||||||
target_link_libraries(tinymitm PUBLIC seallib wolfssl)
|
target_link_libraries(tinymitm PUBLIC seallib wolfssl)
|
||||||
set_target_properties(tinymitm PROPERTIES CXX_EXTENSIONS OFF)
|
set_target_properties(tinymitm PROPERTIES CXX_EXTENSIONS OFF)
|
||||||
|
|
||||||
|
if (TINYMITM_LOGS OR $CACHE{TINYMITM_LOGS})
|
||||||
|
target_compile_definitions(tinymitm PUBLIC TINYMITM_LOGS)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (WIN32)
|
||||||
|
target_link_libraries(tinymitm PRIVATE crypt32)
|
||||||
|
endif()
|
||||||
|
|
||||||
# ------------------------------
|
# ------------------------------
|
||||||
# test
|
# test
|
||||||
# ------------------------------
|
# ------------------------------
|
||||||
|
|||||||
@@ -6,7 +6,10 @@
|
|||||||
|
|
||||||
#if defined(_WIN64) || defined(_WIN32)
|
#if defined(_WIN64) || defined(_WIN32)
|
||||||
#define FD_SETSIZE 1024
|
#define FD_SETSIZE 1024
|
||||||
#define NOMINMAX
|
|
||||||
|
#ifndef NOMINMAX
|
||||||
|
#define NOMINMAX
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <winsock2.h>
|
#include <winsock2.h>
|
||||||
#include <ws2tcpip.h>
|
#include <ws2tcpip.h>
|
||||||
@@ -14,7 +17,6 @@
|
|||||||
#define CLOSE_SOCKET closesocket
|
#define CLOSE_SOCKET closesocket
|
||||||
#define SHUT_RDWR SD_BOTH
|
#define SHUT_RDWR SD_BOTH
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <wolfssl/options.h>
|
#include <wolfssl/options.h>
|
||||||
#include <wolfssl/ssl.h>
|
#include <wolfssl/ssl.h>
|
||||||
#include "ssl.h"
|
#include "ssl.h"
|
||||||
@@ -24,7 +26,7 @@
|
|||||||
#ifdef TINYMITM_LOGS
|
#ifdef TINYMITM_LOGS
|
||||||
#define TINYMITM_WRITELOG(type, ...) _log->type(__VA_ARGS__)
|
#define TINYMITM_WRITELOG(type, ...) _log->type(__VA_ARGS__)
|
||||||
#else
|
#else
|
||||||
#define TINYMITM_WRITELOG()
|
#define TINYMITM_WRITELOG(...)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -194,7 +196,7 @@ bool TinyMITMProxy::init()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
TINYMITM_WRITELOG(verbose, "wolfssl context creation");
|
TINYMITM_WRITELOG(verbose, "wolfssl context creation");
|
||||||
_clientCtx = wolfSSL_CTX_new(wolfTLSv1_3_client_method());
|
_clientCtx = wolfSSL_CTX_new(wolfTLS_client_method());
|
||||||
if (!_clientCtx)
|
if (!_clientCtx)
|
||||||
{
|
{
|
||||||
TINYMITM_WRITELOG(error, "failed to create wolfssl context");
|
TINYMITM_WRITELOG(error, "failed to create wolfssl context");
|
||||||
@@ -435,6 +437,12 @@ void TinyMITMProxy::handleClient(SOCKET clientSocket)
|
|||||||
wolfSSL_set_fd(clientSSL.get(), (int)clientGuard);
|
wolfSSL_set_fd(clientSSL.get(), (int)clientGuard);
|
||||||
wolfSSL_set_fd(remoteSSL.get(), (int)remoteGuard);
|
wolfSSL_set_fd(remoteSSL.get(), (int)remoteGuard);
|
||||||
|
|
||||||
|
char alpnList[] = "http/1.1";
|
||||||
|
wolfSSL_UseALPN(remoteSSL.get(), alpnList, static_cast<word32>(strlen(alpnList)),
|
||||||
|
WOLFSSL_ALPN_CONTINUE_ON_MISMATCH);
|
||||||
|
wolfSSL_UseALPN(clientSSL.get(), alpnList, static_cast<word32>(strlen(alpnList)),
|
||||||
|
WOLFSSL_ALPN_CONTINUE_ON_MISMATCH);
|
||||||
|
|
||||||
wolfSSL_UseSNI(remoteSSL.get(), WOLFSSL_SNI_HOST_NAME, host.c_str(), (unsigned short)host.size());
|
wolfSSL_UseSNI(remoteSSL.get(), WOLFSSL_SNI_HOST_NAME, host.c_str(), (unsigned short)host.size());
|
||||||
|
|
||||||
setNonBlocking(clientGuard, true);
|
setNonBlocking(clientGuard, true);
|
||||||
@@ -457,10 +465,10 @@ void TinyMITMProxy::handleClient(SOCKET clientSocket)
|
|||||||
if (isConnect) return wolfSSL_read(ssl, b, sz);
|
if (isConnect) return wolfSSL_read(ssl, b, sz);
|
||||||
return ::recv(s, b, sz, 0);
|
return ::recv(s, b, sz, 0);
|
||||||
};
|
};
|
||||||
auto sslWrite = [&](WOLFSSL* ssl, SOCKET s, const char* b, int sz) -> int {
|
// auto sslWrite = [&](WOLFSSL* ssl, SOCKET s, const char* b, int sz) -> int {
|
||||||
if (isConnect) return wolfSSL_write(ssl, b, sz);
|
// if (isConnect) return wolfSSL_write(ssl, b, sz);
|
||||||
return ::send(s, b, sz, 0);
|
// return ::send(s, b, sz, 0);
|
||||||
};
|
// };
|
||||||
auto sslPending = [&](WOLFSSL* ssl) -> int {
|
auto sslPending = [&](WOLFSSL* ssl) -> int {
|
||||||
if (isConnect) return wolfSSL_pending(ssl);
|
if (isConnect) return wolfSSL_pending(ssl);
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -6,6 +6,8 @@
|
|||||||
#include <seallib/log.h>
|
#include <seallib/log.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <condition_variable>
|
||||||
|
#include <mutex>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <queue>
|
#include <queue>
|
||||||
|
|||||||
+55
-23
@@ -13,13 +13,12 @@
|
|||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <wincrypt.h>
|
#include <wincrypt.h>
|
||||||
#pragma comment(lib, "crypt32.lib")
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
CertificateManager implementation
|
CertificateManager implementation
|
||||||
*/
|
*/
|
||||||
CertificateManager::CertificateManager() : _rng(new WC_RNG()), _caKey(nullptr), _sessionKey(nullptr) {}
|
CertificateManager::CertificateManager() : _caKey(nullptr), _sessionKey(nullptr), _rng(new WC_RNG()) {}
|
||||||
|
|
||||||
CertificateManager::~CertificateManager()
|
CertificateManager::~CertificateManager()
|
||||||
{
|
{
|
||||||
@@ -62,10 +61,17 @@ WOLFSSL_CTX* CertificateManager::createHostContext(const std::string& host)
|
|||||||
memset(cert.get(), 0, sizeof(Cert));
|
memset(cert.get(), 0, sizeof(Cert));
|
||||||
wc_InitCert(cert.get());
|
wc_InitCert(cert.get());
|
||||||
|
|
||||||
|
cert->isCA = 0;
|
||||||
|
cert->basicConstSet = 1;
|
||||||
|
cert->basicConstCrit = 0;
|
||||||
|
|
||||||
cert->version = 2;
|
cert->version = 2;
|
||||||
cert->sigType = CTC_SHA256wRSA;
|
cert->sigType = CTC_SHA256wRSA;
|
||||||
cert->daysValid = 365;
|
cert->daysValid = 365;
|
||||||
|
|
||||||
|
cert->keyUsage = KEYUSE_DIGITAL_SIG | KEYUSE_KEY_ENCIPHER;
|
||||||
|
cert->extKeyUsage = EXTKEYUSE_SERVER_AUTH;
|
||||||
|
|
||||||
strncpy_s(cert->subject.commonName, sizeof(cert->subject.commonName), hostTrimmed.c_str(), _TRUNCATE);
|
strncpy_s(cert->subject.commonName, sizeof(cert->subject.commonName), hostTrimmed.c_str(), _TRUNCATE);
|
||||||
wc_SetIssuerBuffer(cert.get(), _caCertDer.data(), (int)_caCertDer.size());
|
wc_SetIssuerBuffer(cert.get(), _caCertDer.data(), (int)_caCertDer.size());
|
||||||
|
|
||||||
@@ -77,42 +83,58 @@ WOLFSSL_CTX* CertificateManager::createHostContext(const std::string& host)
|
|||||||
cert->serial[2] = (hash >> 8) & 0xFF;
|
cert->serial[2] = (hash >> 8) & 0xFF;
|
||||||
cert->serial[3] = hash & 0xFF;
|
cert->serial[3] = hash & 0xFF;
|
||||||
|
|
||||||
// SAN
|
/*
|
||||||
std::vector<unsigned char> sanDer;
|
SAN
|
||||||
sanDer.push_back(0x30);
|
*/
|
||||||
sanDer.push_back(static_cast<unsigned char>(hostTrimmed.length() + 2));
|
memset(cert->altNames, 0, CTC_MAX_ALT_SIZE);
|
||||||
sanDer.push_back(0x82);
|
|
||||||
sanDer.push_back(static_cast<unsigned char>(hostTrimmed.length()));
|
|
||||||
sanDer.insert(sanDer.end(), hostTrimmed.begin(), hostTrimmed.end());
|
|
||||||
|
|
||||||
memcpy(cert->altNames, sanDer.data(), sanDer.size());
|
// sequence
|
||||||
cert->altNamesSz = static_cast<word16>(sanDer.size());
|
cert->altNames[0] = 0x30;
|
||||||
|
cert->altNames[1] = static_cast<byte>(hostTrimmed.length() + 2);
|
||||||
|
|
||||||
|
//dNSName tag & len
|
||||||
|
cert->altNames[2] = 0x82;
|
||||||
|
cert->altNames[3] = static_cast<byte>(hostTrimmed.length());
|
||||||
|
|
||||||
|
// actual data
|
||||||
|
memcpy(&cert->altNames[4], hostTrimmed.c_str(), hostTrimmed.length());
|
||||||
|
|
||||||
|
// sz: seq hdr (2) + dNSName hdr (2) + hostName
|
||||||
|
cert->altNamesSz = 4 + static_cast<int>(hostTrimmed.length());
|
||||||
|
cert->altNamesCrit = 0;
|
||||||
|
|
||||||
|
wc_SetSubjectKeyIdFromPublicKey(cert.get(), _sessionKey.get(), nullptr);
|
||||||
|
wc_SetAuthKeyIdFromCert(cert.get(), _caCertDer.data(), static_cast<int>(_caCertDer.size()));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
cert sign
|
cert sign
|
||||||
*/
|
*/
|
||||||
std::vector<unsigned char> hostCertDer(4096);
|
std::vector<unsigned char> hostCertDer(8192);
|
||||||
int certLen =
|
int certLen = wc_MakeCert(cert.get(), hostCertDer.data(), static_cast<word32>(hostCertDer.size()),
|
||||||
wc_MakeCert(cert.get(), hostCertDer.data(), static_cast<word32>(hostCertDer.size()), _sessionKey.get(), nullptr, _rng.get());
|
_sessionKey.get(), nullptr, _rng.get());
|
||||||
|
if (certLen < 0) return nullptr;
|
||||||
|
|
||||||
certLen = wc_SignCert(cert->bodySz, cert->sigType, hostCertDer.data(), static_cast<word32>(hostCertDer.size()), _caKey.get(),
|
int signedLen = wc_SignCert(cert->bodySz, cert->sigType, hostCertDer.data(),
|
||||||
nullptr, _rng.get());
|
static_cast<word32>(hostCertDer.size()), _caKey.get(), nullptr, _rng.get());
|
||||||
hostCertDer.resize(certLen);
|
if (signedLen < 0) return nullptr;
|
||||||
|
hostCertDer.resize(signedLen);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
context setup
|
context setup
|
||||||
*/
|
*/
|
||||||
WOLFSSL_CTX* ctx = wolfSSL_CTX_new(wolfSSLv23_server_method());
|
WOLFSSL_CTX* ctx = wolfSSL_CTX_new(wolfTLS_server_method());
|
||||||
if (!ctx) return nullptr;
|
if (!ctx) return nullptr;
|
||||||
if (wolfSSL_CTX_use_certificate_buffer(ctx, hostCertDer.data(), static_cast<long>(hostCertDer.size()), WOLFSSL_FILETYPE_ASN1) !=
|
if (wolfSSL_CTX_use_certificate_buffer(ctx, hostCertDer.data(), static_cast<long>(hostCertDer.size()),
|
||||||
WOLFSSL_SUCCESS ||
|
WOLFSSL_FILETYPE_ASN1) != WOLFSSL_SUCCESS ||
|
||||||
wolfSSL_CTX_use_PrivateKey_buffer(ctx, _sessionKeyDer.data(), static_cast<long>(_sessionKeyDer.size()),
|
wolfSSL_CTX_use_PrivateKey_buffer(ctx, _sessionKeyDer.data(), static_cast<long>(_sessionKeyDer.size()),
|
||||||
WOLFSSL_FILETYPE_ASN1) != WOLFSSL_SUCCESS)
|
WOLFSSL_FILETYPE_ASN1) != WOLFSSL_SUCCESS)
|
||||||
{
|
{
|
||||||
wolfSSL_CTX_free(ctx);
|
wolfSSL_CTX_free(ctx);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
_hostContexts[host] = ctx;
|
_hostContexts[host] = ctx;
|
||||||
|
|
||||||
return ctx;
|
return ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -125,7 +147,7 @@ bool CertificateManager::installCertificate()
|
|||||||
(DWORD)_caCertDer.size());
|
(DWORD)_caCertDer.size());
|
||||||
|
|
||||||
if (!certCtx) return false;
|
if (!certCtx) return false;
|
||||||
HCERTSTORE rootStore = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, NULL, CERT_SYSTEM_STORE_CURRENT_USER, L"Root");
|
HCERTSTORE rootStore = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, 0, CERT_SYSTEM_STORE_CURRENT_USER, L"Root");
|
||||||
bool success = false;
|
bool success = false;
|
||||||
if (rootStore)
|
if (rootStore)
|
||||||
{
|
{
|
||||||
@@ -172,10 +194,17 @@ bool CertificateManager::generateAndSaveCA(const char* caName, int days, const s
|
|||||||
cert->sigType = CTC_SHA256wRSA;
|
cert->sigType = CTC_SHA256wRSA;
|
||||||
cert->daysValid = days;
|
cert->daysValid = days;
|
||||||
cert->keyUsage = KEYUSE_KEY_CERT_SIGN | KEYUSE_CRL_SIGN;
|
cert->keyUsage = KEYUSE_KEY_CERT_SIGN | KEYUSE_CRL_SIGN;
|
||||||
|
cert->pathLenSet = 0;
|
||||||
|
cert->pathLen = 0;
|
||||||
|
|
||||||
cert->serialSz = 1;
|
cert->serialSz = 1;
|
||||||
cert->serial[0] = 1;
|
cert->serial[0] = 1;
|
||||||
|
|
||||||
|
cert->selfSigned = 1;
|
||||||
|
|
||||||
|
wc_SetSubjectKeyIdFromPublicKey(cert.get(), _caKey.get(), 0);
|
||||||
|
wc_SetAuthKeyIdFromPublicKey(cert.get(), _caKey.get(), 0);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
CA sign
|
CA sign
|
||||||
*/
|
*/
|
||||||
@@ -239,7 +268,8 @@ bool CertificateManager::loadCA(const char* certPath, const char* keyPath)
|
|||||||
std::vector<unsigned char> keyDer;
|
std::vector<unsigned char> keyDer;
|
||||||
DerBuffer* derBuff = nullptr;
|
DerBuffer* derBuff = nullptr;
|
||||||
|
|
||||||
int ret = wc_PemToDer(certPem.data(), static_cast<long>(certPem.size()), CERT_TYPE, &derBuff, nullptr, nullptr, nullptr);
|
int ret =
|
||||||
|
wc_PemToDer(certPem.data(), static_cast<long>(certPem.size()), CERT_TYPE, &derBuff, nullptr, nullptr, nullptr);
|
||||||
if (ret == 0 && derBuff)
|
if (ret == 0 && derBuff)
|
||||||
{
|
{
|
||||||
certDer.assign(derBuff->buffer, derBuff->buffer + derBuff->length);
|
certDer.assign(derBuff->buffer, derBuff->buffer + derBuff->length);
|
||||||
@@ -249,7 +279,8 @@ bool CertificateManager::loadCA(const char* certPath, const char* keyPath)
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
derBuff = nullptr;
|
derBuff = nullptr;
|
||||||
ret = wc_PemToDer(keyPem.data(), static_cast<long>(keyPem.size()), PRIVATEKEY_TYPE, &derBuff, nullptr, nullptr, nullptr);
|
ret = wc_PemToDer(keyPem.data(), static_cast<long>(keyPem.size()), PRIVATEKEY_TYPE, &derBuff, nullptr, nullptr,
|
||||||
|
nullptr);
|
||||||
if (ret == 0 && derBuff)
|
if (ret == 0 && derBuff)
|
||||||
{
|
{
|
||||||
keyDer.assign(derBuff->buffer, derBuff->buffer + derBuff->length);
|
keyDer.assign(derBuff->buffer, derBuff->buffer + derBuff->length);
|
||||||
@@ -260,6 +291,7 @@ bool CertificateManager::loadCA(const char* certPath, const char* keyPath)
|
|||||||
|
|
||||||
return decodeCA(certDer, keyDer);
|
return decodeCA(certDer, keyDer);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CertificateManager::decodeCA(const std::vector<unsigned char>& certDer, const std::vector<unsigned char>& keyDer)
|
bool CertificateManager::decodeCA(const std::vector<unsigned char>& certDer, const std::vector<unsigned char>& keyDer)
|
||||||
{
|
{
|
||||||
if (certDer.empty() || keyDer.empty()) return false;
|
if (certDer.empty() || keyDer.empty()) return false;
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ class ConOutSink : public ILogSink
|
|||||||
public:
|
public:
|
||||||
virtual void receiveLog(LogType type, std::string_view loggerName, std::string_view msg) override
|
virtual void receiveLog(LogType type, std::string_view loggerName, std::string_view msg) override
|
||||||
{
|
{
|
||||||
std::cout << "[" << loggerName << "] " << seallib::getLogTypeColor(type) << "["
|
std::cout << "[" << loggerName << "] " << seallib::getLogTypeColor(type) << "["
|
||||||
<< seallib::getLogTypeName(type) << "]"
|
<< seallib::getLogTypeName(type) << "]"
|
||||||
<< "\x1b[0m " << msg << std::endl;
|
<< "\x1b[0m " << msg << std::endl;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user