Use mbedtls on windows

This commit is contained in:
Tamás Bálint Misius 2023-10-02 17:26:57 +02:00
parent 8385796ca1
commit f94b436cbc
No known key found for this signature in database
GPG Key ID: 5B472A12F6ECA9F2
8 changed files with 131 additions and 14 deletions

View File

@ -1,5 +1 @@
android_resources += configure_file(
input: rendered_icons['icon_exe'],
output: 'ic_launcher.png',
copy: true,
)
android_resources += fs.copyfile(rendered_icons['icon_exe'], 'ic_launcher.png')

View File

@ -18,6 +18,7 @@ if get_option('prepare')
subdir_done()
endif
fs = import('fs')
to_array = generator(
executable('toarray', sources: 'resources/ToArray.cpp', native: true),
output: [ '@PLAINNAME@.cpp', '@PLAINNAME@.h' ],
@ -342,7 +343,7 @@ if host_platform == 'windows'
do_copy = true
endif
if do_copy
configure_file(input: dll_input, output: dll_output, copy: true)
fs.copyfile(dll_input, dll_output)
endif
endforeach
endif

View File

@ -17,6 +17,7 @@ constexpr bool INSTALL_CHECK = @INSTALL_CHECK@;
constexpr bool IGNORE_UPDATES = @IGNORE_UPDATES@;
constexpr bool ENFORCE_HTTPS = @ENFORCE_HTTPS@;
constexpr bool SECURE_CIPHERS_ONLY = @SECURE_CIPHERS_ONLY@;
constexpr bool USE_SYSTEM_CERT_PROVIDER = @USE_SYSTEM_CERT_PROVIDER@;
constexpr bool FFTW_PLAN_MEASURE = @FFTW_PLAN_MEASURE@;
constexpr bool ALLOW_QUIT = @ALLOW_QUIT@;
constexpr bool ALLOW_WINDOW_FRAME_OPS = @ALLOW_WINDOW_FRAME_OPS@;

View File

@ -9,6 +9,7 @@ namespace http
using runtime_error::runtime_error;
};
void UseSystemCertProvider(CURL *easy);
void SetupCurlEasyCiphers(CURL *easy);
void HandleCURLcode(CURLcode code);
void HandleCURLMcode(CURLMcode code);

View File

@ -462,14 +462,6 @@ namespace http
{
HandleCURLcode(curl_easy_setopt(handle->curlEasy, CURLOPT_PROXY, proxy.c_str()));
}
if (cafile.size())
{
HandleCURLcode(curl_easy_setopt(handle->curlEasy, CURLOPT_CAINFO, cafile.c_str()));
}
if (capath.size())
{
HandleCURLcode(curl_easy_setopt(handle->curlEasy, CURLOPT_CAPATH, capath.c_str()));
}
HandleCURLcode(curl_easy_setopt(handle->curlEasy, CURLOPT_PRIVATE, (void *)handle));
HandleCURLcode(curl_easy_setopt(handle->curlEasy, CURLOPT_USERAGENT, userAgent.c_str()));
HandleCURLcode(curl_easy_setopt(handle->curlEasy, CURLOPT_HEADERDATA, (void *)handle));
@ -562,5 +554,20 @@ namespace http
#elif defined(CURL_AT_LEAST_VERSION) && CURL_AT_LEAST_VERSION(7, 44, 0)
HandleCURLcode(curl_easy_setopt(easy, CURLOPT_SSL_OPTIONS, CURLSSLOPT_NO_REVOKE));
#endif
auto &capath = http::RequestManager::Ref().Capath();
auto &cafile = http::RequestManager::Ref().Cafile();
if (capath.size())
{
HandleCURLcode(curl_easy_setopt(easy, CURLOPT_CAPATH, capath.c_str()));
}
else if (cafile.size())
{
HandleCURLcode(curl_easy_setopt(easy, CURLOPT_CAINFO, cafile.c_str()));
}
else if constexpr (USE_SYSTEM_CERT_PROVIDER)
{
UseSystemCertProvider(easy);
}
}
}

View File

@ -89,6 +89,16 @@ namespace http
return disableNetwork;
}
const ByteString &Cafile() const
{
return cafile;
}
const ByteString &Capath() const
{
return capath;
}
static RequestManagerPtr Create(ByteString newProxy, ByteString newCafile, ByteString newCapath, bool newDisableNetwork);
};
}

View File

@ -0,0 +1,95 @@
#include "CurlError.h"
#include "common/String.h"
#include <wincrypt.h> // crypt32.lib is pulled in by tpt-libs
#include <iostream>
#include <memory>
namespace http
{
// see https://stackoverflow.com/questions/9507184/can-openssl-on-windows-use-the-system-certificate-store
void UseSystemCertProvider(CURL *easy)
{
struct DoOnce
{
ByteString allPems;
void InitPem()
{
struct StoreDeleter
{
typedef HCERTSTORE pointer;
void operator ()(HCERTSTORE p) const
{
::CertCloseStore(p, 0);
}
};
using StorePtr = std::unique_ptr<void, StoreDeleter>;
struct ContextDeleter
{
typedef PCCERT_CONTEXT pointer;
void operator ()(PCCERT_CONTEXT p) const
{
::CertFreeCertificateContext(p);
}
};
using ContextPtr = std::unique_ptr<void, ContextDeleter>;
auto die = [](ByteString message) {
std::cerr << "failed to enumerate system certificates: " << message << ": " << GetLastError() << std::endl;
};
auto store = StorePtr(::CertOpenSystemStore(0, L"ROOT"), StoreDeleter{});
if (!store)
{
return die("CertOpenSystemStore failed");
}
ContextPtr context;
while (true)
{
context = ContextPtr(::CertEnumCertificatesInStore(store.get(), context.release()), ContextDeleter{});
if (!context)
{
if (::GetLastError() != DWORD(CRYPT_E_NOT_FOUND))
{
return die("CertEnumCertificatesInStore failed");
}
break;
}
DWORD pemLength;
// get required buffer size first
if (!CryptBinaryToStringA(context->pbCertEncoded, context->cbCertEncoded, CRYPT_STRING_BASE64HEADER, NULL, &pemLength))
{
return die("CryptBinaryToStringA failed");
}
std::vector<char> pem(pemLength);
// actually get the data
if (!CryptBinaryToStringA(context->pbCertEncoded, context->cbCertEncoded, CRYPT_STRING_BASE64HEADER, &pem[0], &pemLength))
{
return die("CryptBinaryToStringA failed");
}
allPems += ByteString(&pem[0], &pem[0] + pem.size() - 1); // buffer includes the zero terminator, omit that
}
if (!allPems.size())
{
die("no system certificates");
}
}
DoOnce()
{
InitPem();
}
};
static DoOnce doOnce;
if (doOnce.allPems.size())
{
curl_blob blob;
blob.data = &doOnce.allPems[0];
blob.len = doOnce.allPems.size();
blob.flags = CURL_BLOB_COPY;
HandleCURLcode(curl_easy_setopt(easy, CURLOPT_CAINFO_BLOB, &blob));
}
}
}

View File

@ -2,11 +2,17 @@ client_files += files(
'Common.cpp',
)
use_system_cert_provider = false
if not enable_http
client_files += files('Null.cpp')
elif host_platform == 'emscripten'
client_files += files('Emscripten.cpp')
else
client_files += files('Libcurl.cpp')
if host_platform == 'windows'
use_system_cert_provider = true
client_files += files('WindowsCertProvider.cpp')
endif
endif
conf_data.set('NOHTTP', (not enable_http).to_string())
conf_data.set('USE_SYSTEM_CERT_PROVIDER', use_system_cert_provider.to_string())