From 8c9090fd037ca300e95e0087dd50741498e90038 Mon Sep 17 00:00:00 2001 From: Silent Date: Tue, 11 Jan 2022 19:42:52 +0100 Subject: [PATCH] WolfSSL: Use a custom UTF-8 aware fopen on Windows Fixes loading cacert.pem from Unicode directories --- 3rdparty/wolfssl/extra/win32/user_settings.h | 74 ++++++++++++++++++++ 3rdparty/wolfssl/wolfssl.vcxproj | 10 +-- Utilities/StrFmt.cpp | 39 +++-------- Utilities/StrUtil.h | 5 +- rpcs3/rpcs3qt/curl_handle.cpp | 13 +++- 5 files changed, 100 insertions(+), 41 deletions(-) create mode 100644 3rdparty/wolfssl/extra/win32/user_settings.h diff --git a/3rdparty/wolfssl/extra/win32/user_settings.h b/3rdparty/wolfssl/extra/win32/user_settings.h new file mode 100644 index 0000000000..ea4c408331 --- /dev/null +++ b/3rdparty/wolfssl/extra/win32/user_settings.h @@ -0,0 +1,74 @@ +#ifndef _WIN_USER_SETTINGS_H_ +#define _WIN_USER_SETTINGS_H_ + +/* Verify this is Windows */ +#ifndef _WIN32 +#error This user_settings.h header is only designed for Windows +#endif + +/* Configurations */ +#define WOLFSSL_DES_ECB +#define HAVE_FFDHE_2048 +#define TFM_TIMING_RESISTANT +#define NO_DSA +#define TFM_ECC256 +#define NO_RC4 +#define NO_HC128 +#define NO_RABBIT +#define WOLFSSL_SHA224 +#define WOLFSSL_SHA384 +#define WOLFSSL_SHA3 +#define WOLFSSL_SHA512 +#define WOLFSSL_SHAKE256 +#define HAVE_POLY1305 +#define HAVE_ONE_TIME_AUTH +#define HAVE_CHACHA +#define HAVE_HASHDRBG +#define HAVE_SNI +#define HAVE_ENCRYPT_THEN_MAC +#define NO_MD4 +#define WC_NO_ASYNC_THREADING +#define WC_NO_HARDEN +#define HAVE_WRITE_DUP +#define WC_RSA_BLINDING +#define NO_MULTIBYTE_PRINT +#define OPENSSL_EXTRA +#define WOLFSSL_RIPEMD +#define NO_PSK +#define HAVE_EXTENDED_MASTER +#define WOLFSSL_SNIFFER +#define HAVE_AESGCM +#define HAVE_SUPPORTED_CURVES +#define HAVE_TLS_EXTENSIONS +#define HAVE_ECC +#define ECC_SHAMIR +#define ECC_TIMING_RESISTANT + +/* UTF-8 aware filesystem functions for Windows */ +#define WOLFSSL_USER_FILESYSTEM + +#include +#define XFILE FILE* + +extern FILE* wolfSSL_fopen_utf8(const char* name, const char* mode); +#define XFOPEN wolfSSL_fopen_utf8 + +#define XFDOPEN fdopen +#define XFSEEK fseek +#define XFTELL ftell +#define XREWIND rewind +#define XFREAD fread +#define XFWRITE fwrite +#define XFCLOSE fclose +#define XSEEK_END SEEK_END +#define XBADFILE NULL +#define XFGETS fgets +#define XFPRINTF fprintf +#define XFFLUSH fflush + +#include +#define XSTAT _stat +#define XS_ISREG(s) (s & _S_IFREG) +#define SEPARATOR_CHAR ';' + +#endif /* _WIN_USER_SETTINGS_H_ */ diff --git a/3rdparty/wolfssl/wolfssl.vcxproj b/3rdparty/wolfssl/wolfssl.vcxproj index 6bee087913..2574b934b9 100644 --- a/3rdparty/wolfssl/wolfssl.vcxproj +++ b/3rdparty/wolfssl/wolfssl.vcxproj @@ -47,8 +47,8 @@ Disabled - ./wolfssl;./wolfssl/IDE/WIN;%(AdditionalIncludeDirectories) - WOLFSSL_LIB;WOLFSSL_DES_ECB;HAVE_FFDHE_2048;TFM_TIMING_RESISTANT;NO_DSA;TFM_ECC256;NO_RC4;NO_HC128;NO_RABBIT;WOLFSSL_SHA224;WOLFSSL_SHA3;WOLFSSL_SHAKE256;HAVE_POLY1305;HAVE_ONE_TIME_AUTH;HAVE_CHACHA;HAVE_HASHDRBG;HAVE_SNI;HAVE_ENCRYPT_THEN_MAC;NO_MD4;WC_NO_ASYNC_THREADING;CYASSL_USER_SETTINGS;WC_NO_HARDEN;HAVE_WRITE_DUP;WC_RSA_BLINDING;NO_MULTIBYTE_PRINT;OPENSSL_EXTRA;WOLFSSL_RIPEMD;NO_PSK;HAVE_EXTENDED_MASTER;WOLFSSL_SNIFFER;HAVE_AESGCM;WOLFSSL_SHA384;WOLFSSL_SHA512;HAVE_SUPPORTED_CURVES;HAVE_TLS_EXTENSIONS;HAVE_ECC;ECC_SHAMIR;ECC_TIMING_RESISTANT;%(PreprocessorDefinitions) + ./wolfssl;./extra/win32;%(AdditionalIncludeDirectories) + WOLFSSL_LIB;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) EnableFastChecks @@ -61,8 +61,8 @@ MaxSpeed true - ./wolfssl;./wolfssl/IDE/WIN;%(AdditionalIncludeDirectories) - WOLFSSL_LIB;WOLFSSL_DES_ECB;HAVE_FFDHE_2048;TFM_TIMING_RESISTANT;NO_DSA;TFM_ECC256;NO_RC4;NO_HC128;NO_RABBIT;WOLFSSL_SHA224;WOLFSSL_SHA3;WOLFSSL_SHAKE256;HAVE_POLY1305;HAVE_ONE_TIME_AUTH;HAVE_CHACHA;HAVE_HASHDRBG;HAVE_SNI;HAVE_ENCRYPT_THEN_MAC;NO_MD4;WC_NO_ASYNC_THREADING;CYASSL_USER_SETTINGS;WC_NO_HARDEN;HAVE_WRITE_DUP;WC_RSA_BLINDING;NO_MULTIBYTE_PRINT;OPENSSL_EXTRA;WOLFSSL_RIPEMD;NO_PSK;HAVE_EXTENDED_MASTER;WOLFSSL_SNIFFER;HAVE_AESGCM;WOLFSSL_SHA384;WOLFSSL_SHA512;HAVE_SUPPORTED_CURVES;HAVE_TLS_EXTENSIONS;HAVE_ECC;ECC_SHAMIR;ECC_TIMING_RESISTANT;%(PreprocessorDefinitions) + ./wolfssl;./extra/win32;%(AdditionalIncludeDirectories) + WOLFSSL_LIB;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) true @@ -137,6 +137,7 @@ + false @@ -152,7 +153,6 @@ $(OutDir)%(Filename).obj $(IntDir)%(Filename).obj - diff --git a/Utilities/StrFmt.cpp b/Utilities/StrFmt.cpp index 63eccf8883..a4c2e4630f 100644 --- a/Utilities/StrFmt.cpp +++ b/Utilities/StrFmt.cpp @@ -16,43 +16,22 @@ #endif #ifdef _WIN32 -std::string wchar_to_utf8(const wchar_t *src) +std::string wchar_to_utf8(std::wstring_view src) { std::string utf8_string; - const auto tmp_size = WideCharToMultiByte(CP_UTF8, 0, src, -1, nullptr, 0, nullptr, nullptr); + const auto tmp_size = WideCharToMultiByte(CP_UTF8, 0, src.data(), src.size(), nullptr, 0, nullptr, nullptr); utf8_string.resize(tmp_size); - WideCharToMultiByte(CP_UTF8, 0, src, -1, utf8_string.data(), tmp_size, nullptr, nullptr); + WideCharToMultiByte(CP_UTF8, 0, src.data(), src.size(), utf8_string.data(), tmp_size, nullptr, nullptr); return utf8_string; } -std::string wchar_path_to_ansi_path(const std::wstring& src) +std::wstring utf8_to_wchar(std::string_view src) { - std::wstring buf_short; - std::string buf_final; - - // Get the short path from the wide char path(short path should only contain ansi characters) - auto tmp_size = GetShortPathNameW(src.data(), nullptr, 0); - buf_short.resize(tmp_size); - GetShortPathNameW(src.data(), buf_short.data(), tmp_size); - - // Convert wide char to ansi - tmp_size = WideCharToMultiByte(CP_ACP, 0, buf_short.data(), -1, nullptr, 0, nullptr, nullptr); - buf_final.resize(tmp_size); - WideCharToMultiByte(CP_ACP, 0, buf_short.data(), -1, buf_final.data(), tmp_size, nullptr, nullptr); - - return buf_final; -} - -std::string utf8_path_to_ansi_path(const std::string& src) -{ - std::wstring buf_wide; - - // Converts the utf-8 path to wide char - const auto tmp_size = MultiByteToWideChar(CP_UTF8, 0, src.c_str(), -1, nullptr, 0); - buf_wide.resize(tmp_size); - MultiByteToWideChar(CP_UTF8, 0, src.c_str(), -1, buf_wide.data(), tmp_size); - - return wchar_path_to_ansi_path(buf_wide); + std::wstring wchar_string; + const auto tmp_size = MultiByteToWideChar(CP_UTF8, 0, src.data(), src.size(), nullptr, 0); + wchar_string.resize(tmp_size); + MultiByteToWideChar(CP_UTF8, 0, src.data(), src.size(), wchar_string.data(), tmp_size); + return wchar_string; } #endif diff --git a/Utilities/StrUtil.h b/Utilities/StrUtil.h index 13d4e50ca2..87384bdc87 100644 --- a/Utilities/StrUtil.h +++ b/Utilities/StrUtil.h @@ -9,9 +9,8 @@ #include "util/types.hpp" #ifdef _WIN32 -std::string wchar_to_utf8(const wchar_t *src); -std::string wchar_path_to_ansi_path(const std::wstring& src); -std::string utf8_path_to_ansi_path(const std::string& src); +std::wstring utf8_to_wchar(std::string_view src); +std::string wchar_to_utf8(std::wstring_view src); #endif // Copy null-terminated string from a std::string or a char array to a char array with truncation diff --git a/rpcs3/rpcs3qt/curl_handle.cpp b/rpcs3/rpcs3qt/curl_handle.cpp index 729c4eca4b..47aad01b36 100644 --- a/rpcs3/rpcs3qt/curl_handle.cpp +++ b/rpcs3/rpcs3qt/curl_handle.cpp @@ -28,10 +28,9 @@ curl_handle::curl_handle(QObject* parent) : QObject(parent) #ifdef _WIN32 // This shouldn't be needed on linux const std::string path_to_cert = rpcs3::utils::get_exe_dir() + "cacert.pem"; - const std::string ansi_path = utf8_path_to_ansi_path(path_to_cert); - err = curl_easy_setopt(m_curl, CURLOPT_CAINFO, ansi_path.data()); - if (err != CURLE_OK) network_log.error("curl_easy_setopt(CURLOPT_CAINFO, %s) error: %s", ansi_path, curl_easy_strerror(err)); + err = curl_easy_setopt(m_curl, CURLOPT_CAINFO, path_to_cert.data()); + if (err != CURLE_OK) network_log.error("curl_easy_setopt(CURLOPT_CAINFO, %s) error: %s", path_to_cert, curl_easy_strerror(err)); #endif } @@ -66,3 +65,11 @@ std::string curl_handle::get_verbose_error(CURLcode code) } } + +#ifdef _WIN32 +// Function exported from our user_settings.h in WolfSSL, implemented in RPCS3 +extern "C" FILE* wolfSSL_fopen_utf8(const char* name, const char* mode) +{ + return _wfopen(utf8_to_wchar(name).c_str(), utf8_to_wchar(mode).c_str()); +} +#endif