[ssl] fix bundled OpenSSL ca cert issue (#2932)
I believe this is the final battle with OpenSSL Signed-off-by: crueter <crueter@eden-emu.dev> Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/2932 Reviewed-by: Maufeat <sahyno1996@gmail.com>
This commit is contained in:
parent
def4349e7a
commit
8ae7974092
|
|
@ -19,6 +19,10 @@
|
||||||
#include "core/internal_network/network.h"
|
#include "core/internal_network/network.h"
|
||||||
#include "core/internal_network/sockets.h"
|
#include "core/internal_network/sockets.h"
|
||||||
|
|
||||||
|
#ifdef YUZU_BUNDLED_OPENSSL
|
||||||
|
#include <openssl/cert.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
using namespace Common::FS;
|
using namespace Common::FS;
|
||||||
|
|
||||||
namespace Service::SSL {
|
namespace Service::SSL {
|
||||||
|
|
@ -41,11 +45,85 @@ void OneTimeInit();
|
||||||
void OneTimeInitLogFile();
|
void OneTimeInitLogFile();
|
||||||
bool OneTimeInitBIO();
|
bool OneTimeInitBIO();
|
||||||
|
|
||||||
|
#ifdef YUZU_BUNDLED_OPENSSL
|
||||||
|
// This is ported from httplib
|
||||||
|
struct scope_exit {
|
||||||
|
explicit scope_exit(std::function<void(void)> &&f)
|
||||||
|
: exit_function(std::move(f)), execute_on_destruction{true} {}
|
||||||
|
|
||||||
|
scope_exit(scope_exit &&rhs) noexcept
|
||||||
|
: exit_function(std::move(rhs.exit_function)),
|
||||||
|
execute_on_destruction{rhs.execute_on_destruction} {
|
||||||
|
rhs.release();
|
||||||
|
}
|
||||||
|
|
||||||
|
~scope_exit() {
|
||||||
|
if (execute_on_destruction) { this->exit_function(); }
|
||||||
|
}
|
||||||
|
|
||||||
|
void release() { this->execute_on_destruction = false; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
scope_exit(const scope_exit &) = delete;
|
||||||
|
void operator=(const scope_exit &) = delete;
|
||||||
|
scope_exit &operator=(scope_exit &&) = delete;
|
||||||
|
|
||||||
|
std::function<void(void)> exit_function;
|
||||||
|
bool execute_on_destruction;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline X509_STORE *CreateCaCertStore(const char *ca_cert,
|
||||||
|
std::size_t size) {
|
||||||
|
auto mem = BIO_new_mem_buf(ca_cert, static_cast<int>(size));
|
||||||
|
auto se = scope_exit([&] { BIO_free_all(mem); });
|
||||||
|
if (!mem) { return nullptr; }
|
||||||
|
|
||||||
|
auto inf = PEM_X509_INFO_read_bio(mem, nullptr, nullptr, nullptr);
|
||||||
|
if (!inf) { return nullptr; }
|
||||||
|
|
||||||
|
auto cts = X509_STORE_new();
|
||||||
|
if (cts) {
|
||||||
|
for (auto i = 0; i < static_cast<int>(sk_X509_INFO_num(inf)); i++) {
|
||||||
|
auto itmp = sk_X509_INFO_value(inf, i);
|
||||||
|
if (!itmp) { continue; }
|
||||||
|
|
||||||
|
if (itmp->x509) { X509_STORE_add_cert(cts, itmp->x509); }
|
||||||
|
if (itmp->crl) { X509_STORE_add_crl(cts, itmp->crl); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sk_X509_INFO_pop_free(inf, X509_INFO_free);
|
||||||
|
return cts;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void SetCaCertStore(SSL_CTX *ctx, X509_STORE *ca_cert_store) {
|
||||||
|
if (ca_cert_store) {
|
||||||
|
if (ctx) {
|
||||||
|
if (SSL_CTX_get_cert_store(ctx) != ca_cert_store) {
|
||||||
|
// Free memory allocated for old cert and use new store `ca_cert_store`
|
||||||
|
SSL_CTX_set_cert_store(ctx, ca_cert_store);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
X509_STORE_free(ca_cert_store);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void LoadCaCertStore(SSL_CTX* ctx, const char* ca_cert, std::size_t size)
|
||||||
|
{
|
||||||
|
SetCaCertStore(ctx, CreateCaCertStore(ca_cert, size));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
class SSLConnectionBackendOpenSSL final : public SSLConnectionBackend {
|
class SSLConnectionBackendOpenSSL final : public SSLConnectionBackend {
|
||||||
public:
|
public:
|
||||||
Result Init() {
|
Result Init() {
|
||||||
|
// on bundled OpenSSL, load ca cert store
|
||||||
|
#ifdef YUZU_BUNDLED_OPENSSL
|
||||||
|
LoadCaCertStore(ssl_ctx, kCert, sizeof(kCert));
|
||||||
|
#endif
|
||||||
std::call_once(one_time_init_flag, OneTimeInit);
|
std::call_once(one_time_init_flag, OneTimeInit);
|
||||||
|
|
||||||
if (!one_time_init_success) {
|
if (!one_time_init_success) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue