summaryrefslogtreecommitdiff
path: root/Source
diff options
context:
space:
mode:
authorSepalani <sepalani@hotmail.fr>2020-12-31 18:29:29 +0400
committerSepalani <sepalani@hotmail.fr>2021-02-11 23:13:59 +0400
commit2a15bc6ab25cfd2d2e64bbf58357c53adc5c76e7 (patch)
tree7bc6d63bcc841342c0cfe7df5ccfe43b4070d028 /Source
parent1fc6fbc2c0c77d5ccde9440b54aba1b007b07136 (diff)
SSL: Workaround to remove SNI from ClientHello
Diffstat (limited to 'Source')
-rw-r--r--Source/Core/Core/IOS/Network/SSL.cpp37
-rw-r--r--Source/Core/Core/IOS/Network/SSL.h4
-rw-r--r--Source/Core/Core/IOS/Network/Socket.cpp20
-rw-r--r--Source/Core/DolphinQt/Debugger/NetworkWidget.cpp6
4 files changed, 48 insertions, 19 deletions
diff --git a/Source/Core/Core/IOS/Network/SSL.cpp b/Source/Core/Core/IOS/Network/SSL.cpp
index 30d8286c0f..11498fced6 100644
--- a/Source/Core/Core/IOS/Network/SSL.cpp
+++ b/Source/Core/Core/IOS/Network/SSL.cpp
@@ -35,6 +35,39 @@ static constexpr mbedtls_x509_crt_profile mbedtls_x509_crt_profile_wii = {
0, /* No RSA min key size */
};
+namespace
+{
+// Dirty workaround to disable SNI which isn't supported by the Wii.
+//
+// This SSL extension can ONLY be disabled by undefining
+// MBEDTLS_SSL_SERVER_NAME_INDICATION and recompiling the library. When
+// enabled and if the hostname is set, it uses the SNI extension which is sent
+// with the Client Hello message.
+//
+// This workaround doesn't require recompiling the library. It does so by
+// deferring mbedtls_ssl_set_hostname after the Client Hello message. The send
+// callback is used as it's the (only?) hook called at the beginning of
+// each step of the handshake by the mbedtls_ssl_flush_output function.
+//
+// The hostname still needs to be set as it is checked against the Common Name
+// field during the certificate verification process.
+int SSLSendWithoutSNI(void* ctx, const unsigned char* buf, size_t len)
+{
+ auto* ssl = static_cast<IOS::HLE::WII_SSL*>(ctx);
+
+ if (ssl->ctx.state == MBEDTLS_SSL_SERVER_HELLO)
+ mbedtls_ssl_set_hostname(&ssl->ctx, ssl->hostname.c_str());
+ return mbedtls_net_send(&ssl->hostfd, buf, len);
+}
+
+int SSLRecv(void* ctx, unsigned char* buf, size_t len)
+{
+ auto* ssl = static_cast<IOS::HLE::WII_SSL*>(ctx);
+
+ return mbedtls_net_recv(&ssl->hostfd, buf, len);
+}
+} // namespace
+
NetSSL::NetSSL(Kernel& ios, const std::string& device_name) : Device(ios, device_name)
{
for (WII_SSL& ssl : _SSL)
@@ -223,8 +256,6 @@ IPCCommandResult NetSSL::IOCtlV(const IOCtlVRequest& request)
mbedtls_ssl_conf_renegotiation(&ssl->config, MBEDTLS_SSL_RENEGOTIATION_ENABLED);
ssl->hostname = hostname;
- mbedtls_ssl_set_hostname(&ssl->ctx, ssl->hostname.c_str());
-
ssl->active = true;
WriteReturnValue(freeSSL, BufferIn);
}
@@ -445,7 +476,7 @@ IPCCommandResult NetSSL::IOCtlV(const IOCtlVRequest& request)
WiiSockMan& sm = WiiSockMan::GetInstance();
ssl->hostfd = sm.GetHostSocket(ssl->sockfd);
INFO_LOG_FMT(IOS_SSL, "IOCTLV_NET_SSL_CONNECT socket = {}", ssl->sockfd);
- mbedtls_ssl_set_bio(&ssl->ctx, &ssl->hostfd, mbedtls_net_send, mbedtls_net_recv, nullptr);
+ mbedtls_ssl_set_bio(&ssl->ctx, ssl, SSLSendWithoutSNI, SSLRecv, nullptr);
WriteReturnValue(SSL_OK, BufferIn);
}
else
diff --git a/Source/Core/Core/IOS/Network/SSL.h b/Source/Core/Core/IOS/Network/SSL.h
index d1a29f253e..d3f4e45e05 100644
--- a/Source/Core/Core/IOS/Network/SSL.h
+++ b/Source/Core/Core/IOS/Network/SSL.h
@@ -74,8 +74,8 @@ struct WII_SSL
mbedtls_x509_crt cacert;
mbedtls_x509_crt clicert;
mbedtls_pk_context pk;
- int sockfd;
- int hostfd;
+ int sockfd = -1;
+ int hostfd = -1;
std::string hostname;
bool active;
};
diff --git a/Source/Core/Core/IOS/Network/Socket.cpp b/Source/Core/Core/IOS/Network/Socket.cpp
index 321e8c1efe..3cf193cb57 100644
--- a/Source/Core/Core/IOS/Network/Socket.cpp
+++ b/Source/Core/Core/IOS/Network/Socket.cpp
@@ -457,14 +457,14 @@ void WiiSocket::Update(bool read, bool write, bool except)
}
case IOCTLV_NET_SSL_WRITE:
{
- int ret = mbedtls_ssl_write(&Device::NetSSL::_SSL[sslID].ctx,
- Memory::GetPointer(BufferOut2), BufferOutSize2);
+ WII_SSL* ssl = &Device::NetSSL::_SSL[sslID];
+ const int ret =
+ mbedtls_ssl_write(&ssl->ctx, Memory::GetPointer(BufferOut2), BufferOutSize2);
if (ret >= 0)
{
- PowerPC::debug_interface.NetworkLogger()->LogSSLWrite(
- Memory::GetPointer(BufferOut2), ret,
- static_cast<mbedtls_net_context*>(Device::NetSSL::_SSL[sslID].ctx.p_bio)->fd);
+ PowerPC::debug_interface.NetworkLogger()->LogSSLWrite(Memory::GetPointer(BufferOut2),
+ ret, ssl->hostfd);
// Return bytes written or SSL_ERR_ZERO if none
WriteReturnValue((ret == 0) ? SSL_ERR_ZERO : ret, BufferIn);
}
@@ -491,14 +491,14 @@ void WiiSocket::Update(bool read, bool write, bool except)
}
case IOCTLV_NET_SSL_READ:
{
- int ret = mbedtls_ssl_read(&Device::NetSSL::_SSL[sslID].ctx,
- Memory::GetPointer(BufferIn2), BufferInSize2);
+ WII_SSL* ssl = &Device::NetSSL::_SSL[sslID];
+ const int ret =
+ mbedtls_ssl_read(&ssl->ctx, Memory::GetPointer(BufferIn2), BufferInSize2);
if (ret >= 0)
{
- PowerPC::debug_interface.NetworkLogger()->LogSSLRead(
- Memory::GetPointer(BufferIn2), ret,
- static_cast<mbedtls_net_context*>(Device::NetSSL::_SSL[sslID].ctx.p_bio)->fd);
+ PowerPC::debug_interface.NetworkLogger()->LogSSLRead(Memory::GetPointer(BufferIn2),
+ ret, ssl->hostfd);
// Return bytes read or SSL_ERR_ZERO if none
WriteReturnValue((ret == 0) ? SSL_ERR_ZERO : ret, BufferIn);
}
diff --git a/Source/Core/DolphinQt/Debugger/NetworkWidget.cpp b/Source/Core/DolphinQt/Debugger/NetworkWidget.cpp
index f93b529d54..68cf9c5dbf 100644
--- a/Source/Core/DolphinQt/Debugger/NetworkWidget.cpp
+++ b/Source/Core/DolphinQt/Debugger/NetworkWidget.cpp
@@ -241,11 +241,9 @@ void NetworkWidget::Update()
{
m_ssl_table->insertRow(ssl_id);
s32 host_fd = -1;
- if (IOS::HLE::Device::IsSSLIDValid(ssl_id) &&
- IOS::HLE::Device::NetSSL::_SSL[ssl_id].ctx.p_bio != nullptr)
+ if (IOS::HLE::Device::IsSSLIDValid(ssl_id))
{
- host_fd =
- static_cast<mbedtls_net_context*>(IOS::HLE::Device::NetSSL::_SSL[ssl_id].ctx.p_bio)->fd;
+ host_fd = IOS::HLE::Device::NetSSL::_SSL[ssl_id].hostfd;
}
m_ssl_table->setItem(ssl_id, 0, new QTableWidgetItem(QString::number(ssl_id)));
m_ssl_table->setItem(ssl_id, 1, GetSocketDomain(host_fd));