aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcrueter <crueter@eden-emu.dev>2025-11-02 04:01:48 +0100
committercrueter <crueter@eden-emu.dev>2025-11-02 04:01:48 +0100
commit8ae797409205be4ab8ccc9a87283b77ba01cfb9c (patch)
tree7820631c8b8b5ed50d69c288881d79219ff8e605
parentdef4349e7a3d3b37d595f192f9a2030d2c092402 (diff)
[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>
-rw-r--r--src/core/hle/service/ssl/ssl_backend_openssl.cpp78
1 files changed, 78 insertions, 0 deletions
diff --git a/src/core/hle/service/ssl/ssl_backend_openssl.cpp b/src/core/hle/service/ssl/ssl_backend_openssl.cpp
index 795b69a873..02d0b8fba7 100644
--- a/src/core/hle/service/ssl/ssl_backend_openssl.cpp
+++ b/src/core/hle/service/ssl/ssl_backend_openssl.cpp
@@ -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) {