[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/sockets.h"
|
||||
|
||||
#ifdef YUZU_BUNDLED_OPENSSL
|
||||
#include <openssl/cert.h>
|
||||
#endif
|
||||
|
||||
using namespace Common::FS;
|
||||
|
||||
namespace Service::SSL {
|
||||
|
|
@ -41,11 +45,85 @@ void OneTimeInit();
|
|||
void OneTimeInitLogFile();
|
||||
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
|
||||
|
||||
class SSLConnectionBackendOpenSSL final : public SSLConnectionBackend {
|
||||
public:
|
||||
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);
|
||||
|
||||
if (!one_time_init_success) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue