Merge pull request #2868 from sepalani/dolphin_ssl
Dolphin new Dump SSL features
This commit is contained in:
commit
f121fa07c2
|
@ -64,6 +64,7 @@
|
|||
#define DUMP_FRAMES_DIR "Frames"
|
||||
#define DUMP_AUDIO_DIR "Audio"
|
||||
#define DUMP_DSP_DIR "DSP"
|
||||
#define DUMP_SSL_DIR "SSL"
|
||||
#define LOGS_DIR "Logs"
|
||||
#define MAIL_LOGS_DIR "Mail"
|
||||
#define SHADERS_DIR "Shaders"
|
||||
|
|
|
@ -781,6 +781,7 @@ static void RebuildUserDirectories(unsigned int dir_index)
|
|||
s_user_paths[D_DUMPAUDIO_IDX] = s_user_paths[D_DUMP_IDX] + DUMP_AUDIO_DIR DIR_SEP;
|
||||
s_user_paths[D_DUMPTEXTURES_IDX] = s_user_paths[D_DUMP_IDX] + DUMP_TEXTURES_DIR DIR_SEP;
|
||||
s_user_paths[D_DUMPDSP_IDX] = s_user_paths[D_DUMP_IDX] + DUMP_DSP_DIR DIR_SEP;
|
||||
s_user_paths[D_DUMPSSL_IDX] = s_user_paths[D_DUMP_IDX] + DUMP_SSL_DIR DIR_SEP;
|
||||
s_user_paths[D_LOGS_IDX] = s_user_paths[D_USER_IDX] + LOGS_DIR DIR_SEP;
|
||||
s_user_paths[D_MAILLOGS_IDX] = s_user_paths[D_LOGS_IDX] + MAIL_LOGS_DIR DIR_SEP;
|
||||
s_user_paths[D_THEMES_IDX] = s_user_paths[D_USER_IDX] + THEMES_DIR DIR_SEP;
|
||||
|
@ -825,6 +826,7 @@ static void RebuildUserDirectories(unsigned int dir_index)
|
|||
s_user_paths[D_DUMPAUDIO_IDX] = s_user_paths[D_DUMP_IDX] + DUMP_AUDIO_DIR DIR_SEP;
|
||||
s_user_paths[D_DUMPTEXTURES_IDX] = s_user_paths[D_DUMP_IDX] + DUMP_TEXTURES_DIR DIR_SEP;
|
||||
s_user_paths[D_DUMPDSP_IDX] = s_user_paths[D_DUMP_IDX] + DUMP_DSP_DIR DIR_SEP;
|
||||
s_user_paths[D_DUMPSSL_IDX] = s_user_paths[D_DUMP_IDX] + DUMP_SSL_DIR DIR_SEP;
|
||||
s_user_paths[F_RAMDUMP_IDX] = s_user_paths[D_DUMP_IDX] + RAM_DUMP;
|
||||
s_user_paths[F_ARAMDUMP_IDX] = s_user_paths[D_DUMP_IDX] + ARAM_DUMP;
|
||||
s_user_paths[F_FAKEVMEMDUMP_IDX] = s_user_paths[D_DUMP_IDX] + FAKEVMEM_DUMP;
|
||||
|
|
|
@ -39,6 +39,7 @@ enum
|
|||
D_DUMPAUDIO_IDX,
|
||||
D_DUMPTEXTURES_IDX,
|
||||
D_DUMPDSP_IDX,
|
||||
D_DUMPSSL_IDX,
|
||||
D_LOAD_IDX,
|
||||
D_LOGS_IDX,
|
||||
D_MAILLOGS_IDX,
|
||||
|
|
|
@ -66,6 +66,7 @@ void SConfig::SaveSettings()
|
|||
SaveInputSettings(ini);
|
||||
SaveFifoPlayerSettings(ini);
|
||||
SaveAnalyticsSettings(ini);
|
||||
SaveNetworkSettings(ini);
|
||||
|
||||
ini.Save(File::GetUserPath(F_DOLPHINCONFIG_IDX));
|
||||
m_SYSCONF->Save();
|
||||
|
@ -80,6 +81,7 @@ void CreateDumpPath(const std::string& path)
|
|||
File::SetUserPath(D_DUMP_IDX, path + '/');
|
||||
File::CreateFullPath(File::GetUserPath(D_DUMPAUDIO_IDX));
|
||||
File::CreateFullPath(File::GetUserPath(D_DUMPDSP_IDX));
|
||||
File::CreateFullPath(File::GetUserPath(D_DUMPSSL_IDX));
|
||||
File::CreateFullPath(File::GetUserPath(D_DUMPFRAMES_IDX));
|
||||
File::CreateFullPath(File::GetUserPath(D_DUMPTEXTURES_IDX));
|
||||
}
|
||||
|
@ -300,6 +302,17 @@ void SConfig::SaveFifoPlayerSettings(IniFile& ini)
|
|||
fifoplayer->Set("LoopReplay", bLoopFifoReplay);
|
||||
}
|
||||
|
||||
void SConfig::SaveNetworkSettings(IniFile& ini)
|
||||
{
|
||||
IniFile::Section* network = ini.GetOrCreateSection("Network");
|
||||
|
||||
network->Set("SSLDumpRead", m_SSLDumpRead);
|
||||
network->Set("SSLDumpWrite", m_SSLDumpWrite);
|
||||
network->Set("SSLVerifyCert", m_SSLVerifyCert);
|
||||
network->Set("SSLDumpRootCA", m_SSLDumpRootCA);
|
||||
network->Set("SSLDumpPeerCert", m_SSLDumpPeerCert);
|
||||
}
|
||||
|
||||
void SConfig::SaveAnalyticsSettings(IniFile& ini)
|
||||
{
|
||||
IniFile::Section* analytics = ini.GetOrCreateSection("Analytics");
|
||||
|
@ -324,6 +337,7 @@ void SConfig::LoadSettings()
|
|||
LoadDSPSettings(ini);
|
||||
LoadInputSettings(ini);
|
||||
LoadFifoPlayerSettings(ini);
|
||||
LoadNetworkSettings(ini);
|
||||
LoadAnalyticsSettings(ini);
|
||||
|
||||
m_SYSCONF = new SysConf();
|
||||
|
@ -570,6 +584,17 @@ void SConfig::LoadFifoPlayerSettings(IniFile& ini)
|
|||
fifoplayer->Get("LoopReplay", &bLoopFifoReplay, true);
|
||||
}
|
||||
|
||||
void SConfig::LoadNetworkSettings(IniFile& ini)
|
||||
{
|
||||
IniFile::Section* network = ini.GetOrCreateSection("Network");
|
||||
|
||||
network->Get("SSLDumpRead", &m_SSLDumpRead, false);
|
||||
network->Get("SSLDumpWrite", &m_SSLDumpWrite, false);
|
||||
network->Get("SSLVerifyCert", &m_SSLVerifyCert, false);
|
||||
network->Get("SSLDumpRootCA", &m_SSLDumpRootCA, false);
|
||||
network->Get("SSLDumpPeerCert", &m_SSLDumpPeerCert, false);
|
||||
}
|
||||
|
||||
void SConfig::LoadAnalyticsSettings(IniFile& ini)
|
||||
{
|
||||
IniFile::Section* analytics = ini.GetOrCreateSection("Analytics");
|
||||
|
|
|
@ -290,6 +290,13 @@ struct SConfig : NonCopyable
|
|||
bool m_AdapterRumble[4];
|
||||
bool m_AdapterKonga[4];
|
||||
|
||||
// Network settings
|
||||
bool m_SSLDumpRead;
|
||||
bool m_SSLDumpWrite;
|
||||
bool m_SSLVerifyCert;
|
||||
bool m_SSLDumpRootCA;
|
||||
bool m_SSLDumpPeerCert;
|
||||
|
||||
SysConf* m_SYSCONF;
|
||||
|
||||
// Save settings
|
||||
|
@ -316,6 +323,7 @@ private:
|
|||
void SaveInputSettings(IniFile& ini);
|
||||
void SaveMovieSettings(IniFile& ini);
|
||||
void SaveFifoPlayerSettings(IniFile& ini);
|
||||
void SaveNetworkSettings(IniFile& ini);
|
||||
void SaveAnalyticsSettings(IniFile& ini);
|
||||
|
||||
void LoadGeneralSettings(IniFile& ini);
|
||||
|
@ -327,6 +335,7 @@ private:
|
|||
void LoadInputSettings(IniFile& ini);
|
||||
void LoadMovieSettings(IniFile& ini);
|
||||
void LoadFifoPlayerSettings(IniFile& ini);
|
||||
void LoadNetworkSettings(IniFile& ini);
|
||||
void LoadAnalyticsSettings(IniFile& ini);
|
||||
|
||||
static SConfig* m_Instance;
|
||||
|
|
|
@ -6,12 +6,23 @@
|
|||
|
||||
#include "Common/FileUtil.h"
|
||||
#include "Common/NandPaths.h"
|
||||
#include "Core/ConfigManager.h"
|
||||
#include "Core/Core.h"
|
||||
#include "Core/IPC_HLE/WII_IPC_HLE_Device_net_ssl.h"
|
||||
#include "Core/IPC_HLE/WII_Socket.h"
|
||||
|
||||
WII_SSL CWII_IPC_HLE_Device_net_ssl::_SSL[NET_SSL_MAXINSTANCES];
|
||||
|
||||
static constexpr mbedtls_x509_crt_profile mbedtls_x509_crt_profile_wii = {
|
||||
/* Hashes from SHA-1 and above */
|
||||
MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_SHA1) | MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_RIPEMD160) |
|
||||
MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_SHA224) | MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_SHA256) |
|
||||
MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_SHA384) | MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_SHA512),
|
||||
0xFFFFFFF, /* Any PK alg */
|
||||
0xFFFFFFF, /* Any curve */
|
||||
0, /* No RSA min key size */
|
||||
};
|
||||
|
||||
CWII_IPC_HLE_Device_net_ssl::CWII_IPC_HLE_Device_net_ssl(u32 _DeviceID,
|
||||
const std::string& _rDeviceName)
|
||||
: IWII_IPC_HLE_Device(_DeviceID, _rDeviceName)
|
||||
|
@ -30,13 +41,16 @@ CWII_IPC_HLE_Device_net_ssl::~CWII_IPC_HLE_Device_net_ssl()
|
|||
if (ssl.active)
|
||||
{
|
||||
mbedtls_ssl_close_notify(&ssl.ctx);
|
||||
mbedtls_ssl_session_free(&ssl.session);
|
||||
mbedtls_ssl_free(&ssl.ctx);
|
||||
mbedtls_ssl_config_free(&ssl.config);
|
||||
|
||||
mbedtls_x509_crt_free(&ssl.cacert);
|
||||
mbedtls_x509_crt_free(&ssl.clicert);
|
||||
|
||||
mbedtls_ssl_session_free(&ssl.session);
|
||||
mbedtls_ssl_free(&ssl.ctx);
|
||||
mbedtls_ssl_config_free(&ssl.config);
|
||||
mbedtls_ctr_drbg_free(&ssl.ctr_drbg);
|
||||
mbedtls_entropy_free(&ssl.entropy);
|
||||
|
||||
ssl.hostname.clear();
|
||||
|
||||
ssl.active = false;
|
||||
|
@ -152,13 +166,14 @@ IPCCommandResult CWII_IPC_HLE_Device_net_ssl::IOCtlV(u32 _CommandAddress)
|
|||
WII_SSL* ssl = &_SSL[sslID];
|
||||
mbedtls_ssl_init(&ssl->ctx);
|
||||
mbedtls_entropy_init(&ssl->entropy);
|
||||
const char* pers = "dolphin-emu";
|
||||
static constexpr const char* pers = "dolphin-emu";
|
||||
mbedtls_ctr_drbg_init(&ssl->ctr_drbg);
|
||||
int ret = mbedtls_ctr_drbg_seed(&ssl->ctr_drbg, mbedtls_entropy_func, &ssl->entropy,
|
||||
(const unsigned char*)pers, strlen(pers));
|
||||
if (ret)
|
||||
{
|
||||
mbedtls_ssl_free(&ssl->ctx);
|
||||
mbedtls_ctr_drbg_free(&ssl->ctr_drbg);
|
||||
mbedtls_entropy_free(&ssl->entropy);
|
||||
goto _SSL_NEW_ERROR;
|
||||
}
|
||||
|
@ -171,10 +186,13 @@ IPCCommandResult CWII_IPC_HLE_Device_net_ssl::IOCtlV(u32 _CommandAddress)
|
|||
// For some reason we can't use TLSv1.2, v1.1 and below are fine!
|
||||
mbedtls_ssl_conf_max_version(&ssl->config, MBEDTLS_SSL_MAJOR_VERSION_3,
|
||||
MBEDTLS_SSL_MINOR_VERSION_2);
|
||||
|
||||
mbedtls_ssl_conf_cert_profile(&ssl->config, &mbedtls_x509_crt_profile_wii);
|
||||
mbedtls_ssl_set_session(&ssl->ctx, &ssl->session);
|
||||
|
||||
mbedtls_ssl_conf_authmode(&ssl->config, MBEDTLS_SSL_VERIFY_NONE);
|
||||
if (SConfig::GetInstance().m_SSLVerifyCert && verifyOption)
|
||||
mbedtls_ssl_conf_authmode(&ssl->config, MBEDTLS_SSL_VERIFY_REQUIRED);
|
||||
else
|
||||
mbedtls_ssl_conf_authmode(&ssl->config, MBEDTLS_SSL_VERIFY_NONE);
|
||||
mbedtls_ssl_conf_renegotiation(&ssl->config, MBEDTLS_SSL_RENEGOTIATION_ENABLED);
|
||||
|
||||
ssl->hostname = hostname;
|
||||
|
@ -204,16 +222,18 @@ IPCCommandResult CWII_IPC_HLE_Device_net_ssl::IOCtlV(u32 _CommandAddress)
|
|||
if (SSLID_VALID(sslID))
|
||||
{
|
||||
WII_SSL* ssl = &_SSL[sslID];
|
||||
mbedtls_ssl_close_notify(&ssl->ctx);
|
||||
mbedtls_ssl_session_free(&ssl->session);
|
||||
mbedtls_ssl_free(&ssl->ctx);
|
||||
mbedtls_ssl_config_free(&ssl->config);
|
||||
|
||||
mbedtls_entropy_free(&ssl->entropy);
|
||||
mbedtls_ssl_close_notify(&ssl->ctx);
|
||||
|
||||
mbedtls_x509_crt_free(&ssl->cacert);
|
||||
mbedtls_x509_crt_free(&ssl->clicert);
|
||||
|
||||
mbedtls_ssl_session_free(&ssl->session);
|
||||
mbedtls_ssl_free(&ssl->ctx);
|
||||
mbedtls_ssl_config_free(&ssl->config);
|
||||
mbedtls_ctr_drbg_free(&ssl->ctr_drbg);
|
||||
mbedtls_entropy_free(&ssl->entropy);
|
||||
|
||||
ssl->hostname.clear();
|
||||
|
||||
ssl->active = false;
|
||||
|
@ -248,6 +268,12 @@ IPCCommandResult CWII_IPC_HLE_Device_net_ssl::IOCtlV(u32 _CommandAddress)
|
|||
int ret =
|
||||
mbedtls_x509_crt_parse_der(&ssl->cacert, Memory::GetPointer(BufferOut2), BufferOutSize2);
|
||||
|
||||
if (SConfig::GetInstance().m_SSLDumpRootCA)
|
||||
{
|
||||
std::string filename = File::GetUserPath(D_DUMPSSL_IDX) + ssl->hostname + "_rootca.der";
|
||||
File::IOFile(filename, "wb").WriteBytes(Memory::GetPointer(BufferOut2), BufferOutSize2);
|
||||
}
|
||||
|
||||
if (ret)
|
||||
{
|
||||
Memory::Write_U32(SSL_ERR_FAILED, _BufferIn);
|
||||
|
|
|
@ -3,12 +3,14 @@
|
|||
// Refer to the license.txt file included.
|
||||
|
||||
#include <algorithm>
|
||||
#include <mbedtls/error.h>
|
||||
#ifndef _WIN32
|
||||
#include <arpa/inet.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "Common/FileUtil.h"
|
||||
#include "Core/ConfigManager.h"
|
||||
#include "Core/Core.h"
|
||||
#include "Core/IPC_HLE/WII_IPC_HLE.h"
|
||||
#include "Core/IPC_HLE/WII_IPC_HLE_Device.h"
|
||||
|
@ -312,7 +314,14 @@ void WiiSocket::Update(bool read, bool write, bool except)
|
|||
{
|
||||
case IOCTLV_NET_SSL_DOHANDSHAKE:
|
||||
{
|
||||
int ret = mbedtls_ssl_handshake(&CWII_IPC_HLE_Device_net_ssl::_SSL[sslID].ctx);
|
||||
mbedtls_ssl_context* ctx = &CWII_IPC_HLE_Device_net_ssl::_SSL[sslID].ctx;
|
||||
int ret = mbedtls_ssl_handshake(ctx);
|
||||
if (ret)
|
||||
{
|
||||
char error_buffer[256] = "";
|
||||
mbedtls_strerror(ret, error_buffer, sizeof(error_buffer));
|
||||
ERROR_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_DOHANDSHAKE: %s", error_buffer);
|
||||
}
|
||||
switch (ret)
|
||||
{
|
||||
case 0:
|
||||
|
@ -328,11 +337,49 @@ void WiiSocket::Update(bool read, bool write, bool except)
|
|||
if (!nonBlock)
|
||||
ReturnValue = SSL_ERR_WAGAIN;
|
||||
break;
|
||||
case MBEDTLS_ERR_X509_CERT_VERIFY_FAILED:
|
||||
{
|
||||
char error_buffer[256] = "";
|
||||
int res = mbedtls_ssl_get_verify_result(ctx);
|
||||
mbedtls_x509_crt_verify_info(error_buffer, sizeof(error_buffer), "", res);
|
||||
ERROR_LOG(WII_IPC_SSL, "MBEDTLS_ERR_X509_CERT_VERIFY_FAILED (verify_result = %d): %s",
|
||||
res, error_buffer);
|
||||
|
||||
if (res & MBEDTLS_X509_BADCERT_CN_MISMATCH)
|
||||
res = SSL_ERR_VCOMMONNAME;
|
||||
else if (res & MBEDTLS_X509_BADCERT_NOT_TRUSTED)
|
||||
res = SSL_ERR_VROOTCA;
|
||||
else if (res & MBEDTLS_X509_BADCERT_REVOKED)
|
||||
res = SSL_ERR_VCHAIN;
|
||||
else if (res & MBEDTLS_X509_BADCERT_EXPIRED || res & MBEDTLS_X509_BADCERT_FUTURE)
|
||||
res = SSL_ERR_VDATE;
|
||||
else
|
||||
res = SSL_ERR_FAILED;
|
||||
|
||||
Memory::Write_U32(res, BufferIn);
|
||||
if (!nonBlock)
|
||||
ReturnValue = res;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
Memory::Write_U32(SSL_ERR_FAILED, BufferIn);
|
||||
break;
|
||||
}
|
||||
|
||||
// mbedtls_ssl_get_peer_cert(ctx) seems not to work if handshake failed
|
||||
// Below is an alternative to dump the peer certificate
|
||||
if (SConfig::GetInstance().m_SSLDumpPeerCert && ctx->session_negotiate != nullptr)
|
||||
{
|
||||
const mbedtls_x509_crt* cert = ctx->session_negotiate->peer_cert;
|
||||
if (cert != nullptr)
|
||||
{
|
||||
std::string filename = File::GetUserPath(D_DUMPSSL_IDX) +
|
||||
((ctx->hostname != nullptr) ? ctx->hostname : "") +
|
||||
"_peercert.der";
|
||||
File::IOFile(filename, "wb").WriteBytes(cert->raw.p, cert->raw.len);
|
||||
}
|
||||
}
|
||||
|
||||
INFO_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_DOHANDSHAKE = (%d) "
|
||||
"BufferIn: (%08x, %i), BufferIn2: (%08x, %i), "
|
||||
"BufferOut: (%08x, %i), BufferOut2: (%08x, %i)",
|
||||
|
@ -345,10 +392,13 @@ void WiiSocket::Update(bool read, bool write, bool except)
|
|||
int ret = mbedtls_ssl_write(&CWII_IPC_HLE_Device_net_ssl::_SSL[sslID].ctx,
|
||||
Memory::GetPointer(BufferOut2), BufferOutSize2);
|
||||
|
||||
#ifdef DEBUG_SSL
|
||||
File::IOFile("ssl_write.bin", "ab")
|
||||
.WriteBytes(Memory::GetPointer(BufferOut2), BufferOutSize2);
|
||||
#endif
|
||||
if (SConfig::GetInstance().m_SSLDumpWrite && ret > 0)
|
||||
{
|
||||
std::string filename = File::GetUserPath(D_DUMPSSL_IDX) +
|
||||
SConfig::GetInstance().GetUniqueID() + "_write.bin";
|
||||
File::IOFile(filename, "ab").WriteBytes(Memory::GetPointer(BufferOut2), ret);
|
||||
}
|
||||
|
||||
if (ret >= 0)
|
||||
{
|
||||
// Return bytes written or SSL_ERR_ZERO if none
|
||||
|
@ -379,12 +429,14 @@ void WiiSocket::Update(bool read, bool write, bool except)
|
|||
{
|
||||
int ret = mbedtls_ssl_read(&CWII_IPC_HLE_Device_net_ssl::_SSL[sslID].ctx,
|
||||
Memory::GetPointer(BufferIn2), BufferInSize2);
|
||||
#ifdef DEBUG_SSL
|
||||
if (ret > 0)
|
||||
|
||||
if (SConfig::GetInstance().m_SSLDumpRead && ret > 0)
|
||||
{
|
||||
File::IOFile("ssl_read.bin", "ab").WriteBytes(Memory::GetPointer(BufferIn2), ret);
|
||||
std::string filename = File::GetUserPath(D_DUMPSSL_IDX) +
|
||||
SConfig::GetInstance().GetUniqueID() + "_read.bin";
|
||||
File::IOFile(filename, "ab").WriteBytes(Memory::GetPointer(BufferIn2), ret);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (ret >= 0)
|
||||
{
|
||||
// Return bytes read or SSL_ERR_ZERO if none
|
||||
|
|
|
@ -51,6 +51,7 @@ void CreateDirectories()
|
|||
File::CreateFullPath(File::GetUserPath(D_CACHE_IDX));
|
||||
File::CreateFullPath(File::GetUserPath(D_CONFIG_IDX));
|
||||
File::CreateFullPath(File::GetUserPath(D_DUMPDSP_IDX));
|
||||
File::CreateFullPath(File::GetUserPath(D_DUMPSSL_IDX));
|
||||
File::CreateFullPath(File::GetUserPath(D_DUMPTEXTURES_IDX));
|
||||
File::CreateFullPath(File::GetUserPath(D_GAMESETTINGS_IDX));
|
||||
File::CreateFullPath(File::GetUserPath(D_GCUSER_IDX));
|
||||
|
|
Loading…
Reference in New Issue