Merge pull request #9408 from sepalani/sni
SSL: Workaround to remove SNI from ClientHello
This commit is contained in:
commit
3ce72d4005
|
@ -35,6 +35,39 @@ static constexpr mbedtls_x509_crt_profile mbedtls_x509_crt_profile_wii = {
|
||||||
0, /* No RSA min key size */
|
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)
|
NetSSL::NetSSL(Kernel& ios, const std::string& device_name) : Device(ios, device_name)
|
||||||
{
|
{
|
||||||
for (WII_SSL& ssl : _SSL)
|
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);
|
mbedtls_ssl_conf_renegotiation(&ssl->config, MBEDTLS_SSL_RENEGOTIATION_ENABLED);
|
||||||
|
|
||||||
ssl->hostname = hostname;
|
ssl->hostname = hostname;
|
||||||
mbedtls_ssl_set_hostname(&ssl->ctx, ssl->hostname.c_str());
|
|
||||||
|
|
||||||
ssl->active = true;
|
ssl->active = true;
|
||||||
WriteReturnValue(freeSSL, BufferIn);
|
WriteReturnValue(freeSSL, BufferIn);
|
||||||
}
|
}
|
||||||
|
@ -445,7 +476,7 @@ IPCCommandResult NetSSL::IOCtlV(const IOCtlVRequest& request)
|
||||||
WiiSockMan& sm = WiiSockMan::GetInstance();
|
WiiSockMan& sm = WiiSockMan::GetInstance();
|
||||||
ssl->hostfd = sm.GetHostSocket(ssl->sockfd);
|
ssl->hostfd = sm.GetHostSocket(ssl->sockfd);
|
||||||
INFO_LOG_FMT(IOS_SSL, "IOCTLV_NET_SSL_CONNECT socket = {}", 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);
|
WriteReturnValue(SSL_OK, BufferIn);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -74,8 +74,8 @@ struct WII_SSL
|
||||||
mbedtls_x509_crt cacert;
|
mbedtls_x509_crt cacert;
|
||||||
mbedtls_x509_crt clicert;
|
mbedtls_x509_crt clicert;
|
||||||
mbedtls_pk_context pk;
|
mbedtls_pk_context pk;
|
||||||
int sockfd;
|
int sockfd = -1;
|
||||||
int hostfd;
|
int hostfd = -1;
|
||||||
std::string hostname;
|
std::string hostname;
|
||||||
bool active;
|
bool active;
|
||||||
};
|
};
|
||||||
|
|
|
@ -457,14 +457,14 @@ void WiiSocket::Update(bool read, bool write, bool except)
|
||||||
}
|
}
|
||||||
case IOCTLV_NET_SSL_WRITE:
|
case IOCTLV_NET_SSL_WRITE:
|
||||||
{
|
{
|
||||||
int ret = mbedtls_ssl_write(&Device::NetSSL::_SSL[sslID].ctx,
|
WII_SSL* ssl = &Device::NetSSL::_SSL[sslID];
|
||||||
Memory::GetPointer(BufferOut2), BufferOutSize2);
|
const int ret =
|
||||||
|
mbedtls_ssl_write(&ssl->ctx, Memory::GetPointer(BufferOut2), BufferOutSize2);
|
||||||
|
|
||||||
if (ret >= 0)
|
if (ret >= 0)
|
||||||
{
|
{
|
||||||
PowerPC::debug_interface.NetworkLogger()->LogSSLWrite(
|
PowerPC::debug_interface.NetworkLogger()->LogSSLWrite(Memory::GetPointer(BufferOut2),
|
||||||
Memory::GetPointer(BufferOut2), ret,
|
ret, ssl->hostfd);
|
||||||
static_cast<mbedtls_net_context*>(Device::NetSSL::_SSL[sslID].ctx.p_bio)->fd);
|
|
||||||
// Return bytes written or SSL_ERR_ZERO if none
|
// Return bytes written or SSL_ERR_ZERO if none
|
||||||
WriteReturnValue((ret == 0) ? SSL_ERR_ZERO : ret, BufferIn);
|
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:
|
case IOCTLV_NET_SSL_READ:
|
||||||
{
|
{
|
||||||
int ret = mbedtls_ssl_read(&Device::NetSSL::_SSL[sslID].ctx,
|
WII_SSL* ssl = &Device::NetSSL::_SSL[sslID];
|
||||||
Memory::GetPointer(BufferIn2), BufferInSize2);
|
const int ret =
|
||||||
|
mbedtls_ssl_read(&ssl->ctx, Memory::GetPointer(BufferIn2), BufferInSize2);
|
||||||
|
|
||||||
if (ret >= 0)
|
if (ret >= 0)
|
||||||
{
|
{
|
||||||
PowerPC::debug_interface.NetworkLogger()->LogSSLRead(
|
PowerPC::debug_interface.NetworkLogger()->LogSSLRead(Memory::GetPointer(BufferIn2),
|
||||||
Memory::GetPointer(BufferIn2), ret,
|
ret, ssl->hostfd);
|
||||||
static_cast<mbedtls_net_context*>(Device::NetSSL::_SSL[sslID].ctx.p_bio)->fd);
|
|
||||||
// Return bytes read or SSL_ERR_ZERO if none
|
// Return bytes read or SSL_ERR_ZERO if none
|
||||||
WriteReturnValue((ret == 0) ? SSL_ERR_ZERO : ret, BufferIn);
|
WriteReturnValue((ret == 0) ? SSL_ERR_ZERO : ret, BufferIn);
|
||||||
}
|
}
|
||||||
|
|
|
@ -241,11 +241,9 @@ void NetworkWidget::Update()
|
||||||
{
|
{
|
||||||
m_ssl_table->insertRow(ssl_id);
|
m_ssl_table->insertRow(ssl_id);
|
||||||
s32 host_fd = -1;
|
s32 host_fd = -1;
|
||||||
if (IOS::HLE::Device::IsSSLIDValid(ssl_id) &&
|
if (IOS::HLE::Device::IsSSLIDValid(ssl_id))
|
||||||
IOS::HLE::Device::NetSSL::_SSL[ssl_id].ctx.p_bio != nullptr)
|
|
||||||
{
|
{
|
||||||
host_fd =
|
host_fd = IOS::HLE::Device::NetSSL::_SSL[ssl_id].hostfd;
|
||||||
static_cast<mbedtls_net_context*>(IOS::HLE::Device::NetSSL::_SSL[ssl_id].ctx.p_bio)->fd;
|
|
||||||
}
|
}
|
||||||
m_ssl_table->setItem(ssl_id, 0, new QTableWidgetItem(QString::number(ssl_id)));
|
m_ssl_table->setItem(ssl_id, 0, new QTableWidgetItem(QString::number(ssl_id)));
|
||||||
m_ssl_table->setItem(ssl_id, 1, GetSocketDomain(host_fd));
|
m_ssl_table->setItem(ssl_id, 1, GetSocketDomain(host_fd));
|
||||||
|
|
Loading…
Reference in New Issue