Use mbedtls on windows
This commit is contained in:
parent
8385796ca1
commit
f94b436cbc
@ -1,5 +1 @@
|
|||||||
android_resources += configure_file(
|
android_resources += fs.copyfile(rendered_icons['icon_exe'], 'ic_launcher.png')
|
||||||
input: rendered_icons['icon_exe'],
|
|
||||||
output: 'ic_launcher.png',
|
|
||||||
copy: true,
|
|
||||||
)
|
|
||||||
|
@ -18,6 +18,7 @@ if get_option('prepare')
|
|||||||
subdir_done()
|
subdir_done()
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
fs = import('fs')
|
||||||
to_array = generator(
|
to_array = generator(
|
||||||
executable('toarray', sources: 'resources/ToArray.cpp', native: true),
|
executable('toarray', sources: 'resources/ToArray.cpp', native: true),
|
||||||
output: [ '@PLAINNAME@.cpp', '@PLAINNAME@.h' ],
|
output: [ '@PLAINNAME@.cpp', '@PLAINNAME@.h' ],
|
||||||
@ -342,7 +343,7 @@ if host_platform == 'windows'
|
|||||||
do_copy = true
|
do_copy = true
|
||||||
endif
|
endif
|
||||||
if do_copy
|
if do_copy
|
||||||
configure_file(input: dll_input, output: dll_output, copy: true)
|
fs.copyfile(dll_input, dll_output)
|
||||||
endif
|
endif
|
||||||
endforeach
|
endforeach
|
||||||
endif
|
endif
|
||||||
|
@ -17,6 +17,7 @@ constexpr bool INSTALL_CHECK = @INSTALL_CHECK@;
|
|||||||
constexpr bool IGNORE_UPDATES = @IGNORE_UPDATES@;
|
constexpr bool IGNORE_UPDATES = @IGNORE_UPDATES@;
|
||||||
constexpr bool ENFORCE_HTTPS = @ENFORCE_HTTPS@;
|
constexpr bool ENFORCE_HTTPS = @ENFORCE_HTTPS@;
|
||||||
constexpr bool SECURE_CIPHERS_ONLY = @SECURE_CIPHERS_ONLY@;
|
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 FFTW_PLAN_MEASURE = @FFTW_PLAN_MEASURE@;
|
||||||
constexpr bool ALLOW_QUIT = @ALLOW_QUIT@;
|
constexpr bool ALLOW_QUIT = @ALLOW_QUIT@;
|
||||||
constexpr bool ALLOW_WINDOW_FRAME_OPS = @ALLOW_WINDOW_FRAME_OPS@;
|
constexpr bool ALLOW_WINDOW_FRAME_OPS = @ALLOW_WINDOW_FRAME_OPS@;
|
||||||
|
@ -9,6 +9,7 @@ namespace http
|
|||||||
using runtime_error::runtime_error;
|
using runtime_error::runtime_error;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void UseSystemCertProvider(CURL *easy);
|
||||||
void SetupCurlEasyCiphers(CURL *easy);
|
void SetupCurlEasyCiphers(CURL *easy);
|
||||||
void HandleCURLcode(CURLcode code);
|
void HandleCURLcode(CURLcode code);
|
||||||
void HandleCURLMcode(CURLMcode code);
|
void HandleCURLMcode(CURLMcode code);
|
||||||
|
@ -462,14 +462,6 @@ namespace http
|
|||||||
{
|
{
|
||||||
HandleCURLcode(curl_easy_setopt(handle->curlEasy, CURLOPT_PROXY, proxy.c_str()));
|
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_PRIVATE, (void *)handle));
|
||||||
HandleCURLcode(curl_easy_setopt(handle->curlEasy, CURLOPT_USERAGENT, userAgent.c_str()));
|
HandleCURLcode(curl_easy_setopt(handle->curlEasy, CURLOPT_USERAGENT, userAgent.c_str()));
|
||||||
HandleCURLcode(curl_easy_setopt(handle->curlEasy, CURLOPT_HEADERDATA, (void *)handle));
|
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)
|
#elif defined(CURL_AT_LEAST_VERSION) && CURL_AT_LEAST_VERSION(7, 44, 0)
|
||||||
HandleCURLcode(curl_easy_setopt(easy, CURLOPT_SSL_OPTIONS, CURLSSLOPT_NO_REVOKE));
|
HandleCURLcode(curl_easy_setopt(easy, CURLOPT_SSL_OPTIONS, CURLSSLOPT_NO_REVOKE));
|
||||||
#endif
|
#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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -89,6 +89,16 @@ namespace http
|
|||||||
return disableNetwork;
|
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);
|
static RequestManagerPtr Create(ByteString newProxy, ByteString newCafile, ByteString newCapath, bool newDisableNetwork);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
95
src/client/http/requestmanager/WindowsCertProvider.cpp
Normal file
95
src/client/http/requestmanager/WindowsCertProvider.cpp
Normal 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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -2,11 +2,17 @@ client_files += files(
|
|||||||
'Common.cpp',
|
'Common.cpp',
|
||||||
)
|
)
|
||||||
|
|
||||||
|
use_system_cert_provider = false
|
||||||
if not enable_http
|
if not enable_http
|
||||||
client_files += files('Null.cpp')
|
client_files += files('Null.cpp')
|
||||||
elif host_platform == 'emscripten'
|
elif host_platform == 'emscripten'
|
||||||
client_files += files('Emscripten.cpp')
|
client_files += files('Emscripten.cpp')
|
||||||
else
|
else
|
||||||
client_files += files('Libcurl.cpp')
|
client_files += files('Libcurl.cpp')
|
||||||
|
if host_platform == 'windows'
|
||||||
|
use_system_cert_provider = true
|
||||||
|
client_files += files('WindowsCertProvider.cpp')
|
||||||
|
endif
|
||||||
endif
|
endif
|
||||||
conf_data.set('NOHTTP', (not enable_http).to_string())
|
conf_data.set('NOHTTP', (not enable_http).to_string())
|
||||||
|
conf_data.set('USE_SYSTEM_CERT_PROVIDER', use_system_cert_provider.to_string())
|
||||||
|
Reference in New Issue
Block a user