Completed port to gnutls for linux.
This commit is contained in:
parent
d5ef9f3e85
commit
b652f1974f
|
@ -29,7 +29,7 @@ if (APPLE)
|
|||
endif()
|
||||
endif()
|
||||
project(dolphin-emu)
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_SOURCE_DIR}/CMakeTests)
|
||||
set(CMAKE_MODULE_PATH ${dCMAKE_MODULE_PATH} ${CMAKE_SOURCE_DIR}/CMakeTests)
|
||||
set(DOLPHIN_IS_STABLE FALSE)
|
||||
|
||||
# Set up paths
|
||||
|
@ -418,7 +418,6 @@ if(NOT ANDROID)
|
|||
endif()
|
||||
endif()
|
||||
endif()
|
||||
include(FindOpenSSL REQUIRED)
|
||||
|
||||
########################################
|
||||
# Setup include directories (and make sure they are preferred over the Externals)
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
# - Try to find GNUTLS
|
||||
# Find GNUTLS headers, libraries and the answer to all questions.
|
||||
#
|
||||
# GNUTLS_FOUND True if gnutls got found
|
||||
# GNUTLS_INCLUDE_DIRS Location of gnutls headers
|
||||
# GNUTLS_LIBRARIES List of libaries to use gnutls
|
||||
#
|
||||
# Copyright (c) 2007 Bjoern Ricks <b.ricks@fh-osnabrueck.de>
|
||||
#
|
||||
# Redistribution and use is allowed according to the terms of the New
|
||||
# BSD license.
|
||||
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
|
||||
#
|
||||
|
||||
INCLUDE( FindPkgConfig )
|
||||
|
||||
IF ( GNUTLS_FIND_REQUIRED )
|
||||
SET( _pkgconfig_REQUIRED "REQUIRED" )
|
||||
ELSE( GNUTLS_FIND_REQUIRED )
|
||||
SET( _pkgconfig_REQUIRED "" )
|
||||
ENDIF ( GNUTLS_FIND_REQUIRED )
|
||||
|
||||
IF ( GNUTLS_MIN_VERSION )
|
||||
PKG_SEARCH_MODULE( GNUTLS ${_pkgconfig_REQUIRED} gnutls>=${GNUTLS_MIN_VERSION} )
|
||||
ELSE ( GNUTLS_MIN_VERSION )
|
||||
PKG_SEARCH_MODULE( GNUTLS ${_pkgconfig_REQUIRED} gnutls )
|
||||
ENDIF ( GNUTLS_MIN_VERSION )
|
||||
|
||||
|
||||
IF( NOT GNUTLS_FOUND AND NOT PKG_CONFIG_FOUND )
|
||||
FIND_PATH( GNUTLS_INCLUDE_DIRS gnutls/gnutls.h )
|
||||
FIND_LIBRARY( GNUTLS_LIBRARIES gnutls)
|
||||
|
||||
# Report results
|
||||
IF ( GNUTLS_LIBRARIES AND GNUTLS_INCLUDE_DIRS )
|
||||
SET( GNUTLS_FOUND 1 )
|
||||
IF ( NOT GNUTLS_FIND_QUIETLY )
|
||||
MESSAGE( STATUS "Found gnutls: ${GNUTLS_LIBRARIES}" )
|
||||
ENDIF ( NOT GNUTLS_FIND_QUIETLY )
|
||||
ELSE ( GNUTLS_LIBRARIES AND GNUTLS_INCLUDE_DIRS )
|
||||
IF ( GNUTLS_FIND_REQUIRED )
|
||||
MESSAGE( SEND_ERROR "Could NOT find gnutls" )
|
||||
ELSE ( GNUTLS_FIND_REQUIRED )
|
||||
IF ( NOT GNUTLS_FIND_QUIETLY )
|
||||
MESSAGE( STATUS "Could NOT find gnutls" )
|
||||
ENDIF ( NOT GNUTLS_FIND_QUIETLY )
|
||||
ENDIF ( GNUTLS_FIND_REQUIRED )
|
||||
ENDIF ( GNUTLS_LIBRARIES AND GNUTLS_INCLUDE_DIRS )
|
||||
ENDIF( NOT GNUTLS_FOUND AND NOT PKG_CONFIG_FOUND )
|
||||
|
||||
MARK_AS_ADVANCED( GNUTLS_LIBRARIES GNUTLS_INCLUDE_DIRS )
|
|
@ -230,6 +230,16 @@ if(LIBUSB_FOUND)
|
|||
set(SRCS ${SRCS} Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp)
|
||||
endif(LIBUSB_FOUND)
|
||||
|
||||
set(GNUTLS_MIN_VERSION "3.1.9")
|
||||
set(GNUTLS_FIND_REQUIRED 1)
|
||||
find_package(GnuTLS)
|
||||
set(LIBS ${LIBS} ${GNUTLS_LIBRARIES})
|
||||
|
||||
|
||||
if(NOT GNUTLS_FOUND)
|
||||
message(FATAL_ERROR "GnuTLS not found")
|
||||
endif(NOT GNUTLS_FOUND)
|
||||
|
||||
if(WIN32)
|
||||
set(SRCS ${SRCS} Src/HW/BBA-TAP/TAP_Win32.cpp Src/stdafx.cpp
|
||||
Src/HW/WiimoteReal/IOWin.cpp)
|
||||
|
|
|
@ -20,30 +20,34 @@
|
|||
#pragma optimize("",off)
|
||||
#endif
|
||||
|
||||
#include <openssl/err.h>
|
||||
#include "FileUtil.h"
|
||||
#include "WII_IPC_HLE_Device_net_ssl.h"
|
||||
#include "../Debugger/Debugger_SymbolMap.h"
|
||||
|
||||
|
||||
|
||||
CWII_IPC_HLE_Device_net_ssl::CWII_IPC_HLE_Device_net_ssl(u32 _DeviceID, const std::string& _rDeviceName)
|
||||
: IWII_IPC_HLE_Device(_DeviceID, _rDeviceName)
|
||||
{
|
||||
SSL_library_init();
|
||||
sslfds[0] = NULL;
|
||||
sslfds[1] = NULL;
|
||||
sslfds[2] = NULL;
|
||||
sslfds[3] = NULL;
|
||||
gnutls_global_init();
|
||||
for(int i = 0; i < NET_SSL_MAXINSTANCES; ++i)
|
||||
{
|
||||
_SSL[i].session = NULL;
|
||||
_SSL[i].xcred = NULL;
|
||||
memset(_SSL[i].hostname, 0, MAX_HOSTNAME_LEN);
|
||||
}
|
||||
}
|
||||
|
||||
CWII_IPC_HLE_Device_net_ssl::~CWII_IPC_HLE_Device_net_ssl()
|
||||
{
|
||||
gnutls_global_deinit();
|
||||
}
|
||||
|
||||
int CWII_IPC_HLE_Device_net_ssl::getSSLFreeID()
|
||||
{
|
||||
for (int i = 0; i < NET_SSL_MAXINSTANCES; i++)
|
||||
{
|
||||
if (sslfds[i] == NULL)
|
||||
if (_SSL[i].session == NULL)
|
||||
return i + 1;
|
||||
}
|
||||
return 0;
|
||||
|
@ -87,6 +91,53 @@ bool CWII_IPC_HLE_Device_net_ssl::IOCtlV(u32 _CommandAddress)
|
|||
return true;
|
||||
}
|
||||
|
||||
static int
|
||||
_verify_certificate_callback (gnutls_session_t session)
|
||||
{
|
||||
unsigned int status;
|
||||
int ret;
|
||||
gnutls_certificate_type_t type;
|
||||
const char *hostname;
|
||||
gnutls_datum_t out;
|
||||
|
||||
/* Read hostname. */
|
||||
hostname = (const char *)gnutls_session_get_ptr (session);
|
||||
WARN_LOG(WII_IPC_SSL, "_verify_certificate_callback: Verifying certificate for %s\n", hostname);
|
||||
|
||||
/* This verification function uses the trusted CAs in the credentials
|
||||
* structure.
|
||||
*/
|
||||
ret = gnutls_certificate_verify_peers3 (session, hostname, &status);
|
||||
if (ret < 0)
|
||||
{
|
||||
WARN_LOG(WII_IPC_SSL, "gnutls_certificate_verify_peers3 error %d", ret);
|
||||
return GNUTLS_E_CERTIFICATE_ERROR;
|
||||
}
|
||||
|
||||
type = gnutls_certificate_type_get (session);
|
||||
|
||||
ret = gnutls_certificate_verification_status_print( status, type, &out, 0);
|
||||
if (ret < 0)
|
||||
{
|
||||
WARN_LOG(WII_IPC_SSL, "gnutls_certificate_verification_status_print error %d", ret);
|
||||
return GNUTLS_E_CERTIFICATE_ERROR;
|
||||
}
|
||||
|
||||
WARN_LOG(WII_IPC_SSL, "_verify_certificate_callback: %s", out.data);
|
||||
|
||||
gnutls_free(out.data);
|
||||
|
||||
if (status != 0)
|
||||
{
|
||||
/* Certificate is not trusted */
|
||||
WARN_LOG(WII_IPC_SSL, "_verify_certificate_callback: status = %d", status);
|
||||
return GNUTLS_E_CERTIFICATE_ERROR;
|
||||
}
|
||||
/* Certificate verified successfully. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
u32 CWII_IPC_HLE_Device_net_ssl::ExecuteCommandV(u32 _Parameter, SIOCtlVBuffer CommandBuffer)
|
||||
{
|
||||
s32 returnValue = 0;
|
||||
|
@ -133,24 +184,72 @@ u32 CWII_IPC_HLE_Device_net_ssl::ExecuteCommandV(u32 _Parameter, SIOCtlVBuffer C
|
|||
{
|
||||
case IOCTLV_NET_SSL_NEW:
|
||||
{
|
||||
int verifyOption = Memory::Read_U32(_BufferOut);
|
||||
const char * hostname = (const char*) Memory::GetPointer(_BufferOut2);
|
||||
|
||||
int freeSSL = this->getSSLFreeID();
|
||||
if (freeSSL)
|
||||
{
|
||||
Memory::Write_U32(freeSSL, _BufferIn);
|
||||
int sslID = freeSSL - 1;
|
||||
|
||||
SSL_CTX* ctx = SSL_CTX_new(SSLv23_method());
|
||||
|
||||
//SSL_CTX_set_options(ctx,0);
|
||||
|
||||
SSL* ssl = SSL_new(ctx);
|
||||
sslfds[freeSSL-1] = ssl;
|
||||
|
||||
int ret = gnutls_init (&_SSL[sslID].session, GNUTLS_CLIENT);
|
||||
if(ret)
|
||||
{
|
||||
_SSL[sslID].session = NULL;
|
||||
goto _SSL_NEW_ERROR;
|
||||
}
|
||||
|
||||
gnutls_session_t session = _SSL[sslID].session;
|
||||
|
||||
memcpy(_SSL[sslID].hostname, hostname, min((int)BufferOutSize2, MAX_HOSTNAME_LEN));
|
||||
_SSL[sslID].hostname[MAX_HOSTNAME_LEN-1] = '\0';
|
||||
|
||||
gnutls_session_set_ptr (session, (void *) _SSL[sslID].hostname);
|
||||
gnutls_server_name_set (session, GNUTLS_NAME_DNS, _SSL[sslID].hostname,
|
||||
strnlen(_SSL[sslID].hostname, MAX_HOSTNAME_LEN));
|
||||
|
||||
const char *err = NULL;
|
||||
ret = gnutls_priority_set_direct (session, "NORMAL", &err);
|
||||
if(ret)
|
||||
{
|
||||
_SSL[sslID].session = NULL;
|
||||
goto _SSL_NEW_ERROR;
|
||||
}
|
||||
|
||||
/* X509 stuff */
|
||||
ret = gnutls_certificate_allocate_credentials (&_SSL[sslID].xcred);
|
||||
if(ret)
|
||||
{
|
||||
_SSL[sslID].session = NULL;
|
||||
_SSL[sslID].xcred = NULL;
|
||||
goto _SSL_NEW_ERROR;
|
||||
}
|
||||
|
||||
gnutls_certificate_set_verify_function (_SSL[sslID].xcred, _verify_certificate_callback);
|
||||
|
||||
/* put the x509 credentials to the current session
|
||||
*/
|
||||
ret = gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, _SSL[sslID].xcred);
|
||||
if(ret)
|
||||
{
|
||||
_SSL[sslID].session = NULL;
|
||||
_SSL[sslID].xcred = NULL;
|
||||
goto _SSL_NEW_ERROR;
|
||||
}
|
||||
|
||||
Memory::Write_U32(freeSSL, _BufferIn);
|
||||
}
|
||||
else
|
||||
{
|
||||
_SSL_NEW_ERROR:
|
||||
Memory::Write_U32(-1, _BufferIn);
|
||||
}
|
||||
|
||||
INFO_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_NEW "
|
||||
WARN_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_NEW (%d, %s) "
|
||||
"BufferIn: (%08x, %i), BufferIn2: (%08x, %i), "
|
||||
"BufferIn3: (%08x, %i), BufferOut: (%08x, %i), "
|
||||
"BufferOut2: (%08x, %i), BufferOut3: (%08x, %i)",
|
||||
verifyOption, hostname,
|
||||
_BufferIn, BufferInSize, _BufferIn2, BufferInSize2,
|
||||
_BufferIn3, BufferInSize3, _BufferOut, BufferOutSize,
|
||||
_BufferOut2, BufferOutSize2, _BufferOut3, BufferOutSize3);
|
||||
|
@ -160,16 +259,24 @@ u32 CWII_IPC_HLE_Device_net_ssl::ExecuteCommandV(u32 _Parameter, SIOCtlVBuffer C
|
|||
case IOCTLV_NET_SSL_SHUTDOWN:
|
||||
{
|
||||
int sslID = Memory::Read_U32(_BufferOut) - 1;
|
||||
if (sslID >= 0 && sslID < NET_SSL_MAXINSTANCES && sslfds[sslID] != NULL)
|
||||
if (SSLID_VALID(sslID))
|
||||
{
|
||||
SSL_CTX* ctx = sslfds[sslID]->ctx;
|
||||
SSL_shutdown(sslfds[sslID]);
|
||||
if (ctx)
|
||||
SSL_CTX_free(ctx);
|
||||
sslfds[sslID] = NULL;
|
||||
gnutls_session_t session = _SSL[sslID].session;
|
||||
gnutls_bye (session, GNUTLS_SHUT_RDWR);
|
||||
gnutls_deinit(session);
|
||||
gnutls_certificate_free_credentials (_SSL[sslID].xcred);
|
||||
|
||||
_SSL[sslID].session = NULL;
|
||||
_SSL[sslID].xcred = NULL;
|
||||
memset(_SSL[sslID].hostname, 0, MAX_HOSTNAME_LEN);
|
||||
|
||||
Memory::Write_U32(0, _BufferIn);
|
||||
}
|
||||
INFO_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_SHUTDOWN "
|
||||
else
|
||||
{
|
||||
Memory::Write_U32(-8, _BufferIn);
|
||||
}
|
||||
WARN_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_SHUTDOWN "
|
||||
"BufferIn: (%08x, %i), BufferIn2: (%08x, %i), "
|
||||
"BufferIn3: (%08x, %i), BufferOut: (%08x, %i), "
|
||||
"BufferOut2: (%08x, %i), BufferOut3: (%08x, %i)",
|
||||
|
@ -180,7 +287,7 @@ u32 CWII_IPC_HLE_Device_net_ssl::ExecuteCommandV(u32 _Parameter, SIOCtlVBuffer C
|
|||
}
|
||||
case IOCTLV_NET_SSL_SETROOTCA:
|
||||
{
|
||||
INFO_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_SETROOTCA "
|
||||
WARN_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_SETROOTCA "
|
||||
"BufferIn: (%08x, %i), BufferIn2: (%08x, %i), "
|
||||
"BufferIn3: (%08x, %i), BufferOut: (%08x, %i), "
|
||||
"BufferOut2: (%08x, %i), BufferOut3: (%08x, %i)",
|
||||
|
@ -190,53 +297,29 @@ u32 CWII_IPC_HLE_Device_net_ssl::ExecuteCommandV(u32 _Parameter, SIOCtlVBuffer C
|
|||
|
||||
|
||||
int sslID = Memory::Read_U32(_BufferOut) - 1;
|
||||
void* certca = malloc(BufferOutSize2);
|
||||
if (sslID >= 0 && sslID < NET_SSL_MAXINSTANCES && sslfds[sslID] != NULL)
|
||||
if (SSLID_VALID(sslID))
|
||||
{
|
||||
|
||||
std::string cert_base_path(File::GetUserPath(D_WIIUSER_IDX));
|
||||
|
||||
SSL* ssl = sslfds[sslID];
|
||||
|
||||
|
||||
FILE *wiiclientca = fopen((cert_base_path + "clientca.cer").c_str(), "rb");
|
||||
if (wiiclientca == NULL)
|
||||
break;
|
||||
|
||||
X509 *cert = d2i_X509_fp(wiiclientca, NULL);
|
||||
fclose(wiiclientca);
|
||||
if (SSL_use_certificate(ssl,cert) <= 0)
|
||||
break;
|
||||
if (cert)
|
||||
X509_free(cert);
|
||||
|
||||
|
||||
|
||||
FILE * clientcakey = fopen((cert_base_path + "clientcakey.der").c_str(), "rb");
|
||||
if (clientcakey == NULL)
|
||||
break;
|
||||
|
||||
EVP_PKEY * key = d2i_PrivateKey_fp(clientcakey, NULL);
|
||||
|
||||
if (SSL_use_PrivateKey(ssl,key) <= 0)
|
||||
break;
|
||||
if (!SSL_check_private_key(ssl))
|
||||
break;
|
||||
|
||||
|
||||
if (key)
|
||||
EVP_PKEY_free(key);
|
||||
|
||||
Memory::Write_U32(0, _BufferIn);
|
||||
int ret = gnutls_certificate_set_x509_trust_file (_SSL[sslID].xcred,
|
||||
(cert_base_path + "rootca.pem").c_str(),
|
||||
GNUTLS_X509_FMT_PEM);
|
||||
if(ret < 1)
|
||||
Memory::Write_U32(-1, _BufferIn);
|
||||
else
|
||||
Memory::Write_U32(0, _BufferIn);
|
||||
WARN_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_SETROOTCA = %d", ret);
|
||||
}
|
||||
else
|
||||
{
|
||||
Memory::Write_U32(-8, _BufferIn);
|
||||
}
|
||||
free(certca);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case IOCTLV_NET_SSL_SETBUILTINCLIENTCERT:
|
||||
{
|
||||
INFO_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_SETBUILTINCLIENTCERT "
|
||||
WARN_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_SETBUILTINCLIENTCERT "
|
||||
"BufferIn: (%08x, %i), BufferIn2: (%08x, %i), "
|
||||
"BufferIn3: (%08x, %i), BufferOut: (%08x, %i), "
|
||||
"BufferOut2: (%08x, %i), BufferOut3: (%08x, %i)",
|
||||
|
@ -245,41 +328,24 @@ u32 CWII_IPC_HLE_Device_net_ssl::ExecuteCommandV(u32 _Parameter, SIOCtlVBuffer C
|
|||
_BufferOut2, BufferOutSize2, _BufferOut3, BufferOutSize3);
|
||||
|
||||
int sslID = Memory::Read_U32(_BufferOut) - 1;
|
||||
if (sslID >= 0 && sslID < NET_SSL_MAXINSTANCES && sslfds[sslID] != NULL)
|
||||
if (SSLID_VALID(sslID))
|
||||
{
|
||||
SSL* ssl = sslfds[sslID];
|
||||
|
||||
std::string cert_base_path(File::GetUserPath(D_WIIUSER_IDX));
|
||||
FILE * clientca = fopen((cert_base_path + "clientca.cer").c_str(), "rb");
|
||||
if (clientca == NULL)
|
||||
break;
|
||||
|
||||
X509 *cert = d2i_X509_fp(clientca, NULL);
|
||||
fclose(clientca);
|
||||
|
||||
FILE * clientcakey = fopen((cert_base_path + "clientcakey.der").c_str(), "rb");
|
||||
if (clientcakey == NULL)
|
||||
break;
|
||||
|
||||
|
||||
EVP_PKEY * key = d2i_PrivateKey_fp(clientcakey, NULL);
|
||||
|
||||
|
||||
if (SSL_use_certificate(ssl,cert) <= 0)
|
||||
break;
|
||||
if (SSL_use_PrivateKey(ssl,key) <= 0)
|
||||
break;
|
||||
|
||||
|
||||
if (!SSL_check_private_key(ssl))
|
||||
break;
|
||||
|
||||
if (cert)
|
||||
X509_free(cert);
|
||||
if (key)
|
||||
EVP_PKEY_free(key);
|
||||
|
||||
Memory::Write_U32(0, _BufferIn);
|
||||
int ret = gnutls_certificate_set_x509_key_file (_SSL[sslID].xcred,
|
||||
(cert_base_path + "clientca.pem").c_str(),
|
||||
(cert_base_path + "clientcakey.pem").c_str(),
|
||||
GNUTLS_X509_FMT_PEM);
|
||||
if(ret)
|
||||
Memory::Write_U32(-1, _BufferIn);
|
||||
else
|
||||
Memory::Write_U32(0, _BufferIn);
|
||||
|
||||
WARN_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_SETBUILTINCLIENTCERT = %d", ret);
|
||||
}
|
||||
else
|
||||
{
|
||||
Memory::Write_U32(-8, _BufferIn);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -287,11 +353,23 @@ u32 CWII_IPC_HLE_Device_net_ssl::ExecuteCommandV(u32 _Parameter, SIOCtlVBuffer C
|
|||
case IOCTLV_NET_SSL_SETBUILTINROOTCA:
|
||||
{
|
||||
int sslID = Memory::Read_U32(_BufferOut) - 1;
|
||||
if (sslID >= 0 && sslID < NET_SSL_MAXINSTANCES && sslfds[sslID] != NULL){
|
||||
|
||||
Memory::Write_U32(0, _BufferIn);
|
||||
if (SSLID_VALID(sslID))
|
||||
{
|
||||
std::string cert_base_path(File::GetUserPath(D_WIIUSER_IDX));
|
||||
int ret = gnutls_certificate_set_x509_trust_file (_SSL[sslID].xcred,
|
||||
(cert_base_path + "rootca.pem").c_str(),
|
||||
GNUTLS_X509_FMT_PEM);
|
||||
if(ret < 1)
|
||||
Memory::Write_U32(-1, _BufferIn);
|
||||
else
|
||||
Memory::Write_U32(0, _BufferIn);
|
||||
WARN_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_SETBUILTINROOTCA = %d", ret);
|
||||
}
|
||||
INFO_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_SETBUILTINROOTCA "
|
||||
else
|
||||
{
|
||||
Memory::Write_U32(-8, _BufferIn);
|
||||
}
|
||||
WARN_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_SETBUILTINROOTCA "
|
||||
"BufferIn: (%08x, %i), BufferIn2: (%08x, %i), "
|
||||
"BufferIn3: (%08x, %i), BufferOut: (%08x, %i), "
|
||||
"BufferOut2: (%08x, %i), BufferOut3: (%08x, %i)",
|
||||
|
@ -304,16 +382,22 @@ u32 CWII_IPC_HLE_Device_net_ssl::ExecuteCommandV(u32 _Parameter, SIOCtlVBuffer C
|
|||
case IOCTLV_NET_SSL_CONNECT:
|
||||
{
|
||||
int sslID = Memory::Read_U32(_BufferOut) - 1;
|
||||
if (sslID >= 0 && sslID < NET_SSL_MAXINSTANCES && sslfds[sslID] != NULL)
|
||||
if (SSLID_VALID(sslID))
|
||||
{
|
||||
int sock = Memory::Read_U32(_BufferOut2);
|
||||
SSL* ssl = sslfds[sslID];
|
||||
SSL_set_fd(ssl,sock);
|
||||
|
||||
returnValue = SSL_connect(ssl);
|
||||
gnutls_session_t session = _SSL[sslID].session;
|
||||
|
||||
gnutls_transport_set_int (session, sock);
|
||||
gnutls_handshake_set_timeout (session, GNUTLS_DEFAULT_HANDSHAKE_TIMEOUT);
|
||||
|
||||
returnValue = 1;
|
||||
Memory::Write_U32(0, _BufferIn);
|
||||
}
|
||||
INFO_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_CONNECT "
|
||||
else
|
||||
{
|
||||
Memory::Write_U32(-8, _BufferIn);
|
||||
}
|
||||
WARN_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_CONNECT "
|
||||
"BufferIn: (%08x, %i), BufferIn2: (%08x, %i), "
|
||||
"BufferIn3: (%08x, %i), BufferOut: (%08x, %i), "
|
||||
"BufferOut2: (%08x, %i), BufferOut3: (%08x, %i)",
|
||||
|
@ -326,16 +410,30 @@ u32 CWII_IPC_HLE_Device_net_ssl::ExecuteCommandV(u32 _Parameter, SIOCtlVBuffer C
|
|||
case IOCTLV_NET_SSL_DOHANDSHAKE:
|
||||
{
|
||||
int sslID = Memory::Read_U32(_BufferOut) - 1;
|
||||
if (sslID >= 0 && sslID < NET_SSL_MAXINSTANCES && sslfds[sslID] != NULL)
|
||||
if (SSLID_VALID(sslID))
|
||||
{
|
||||
SSL* ssl = sslfds[sslID];
|
||||
SSL_set_verify(ssl, SSL_VERIFY_NONE, NULL);
|
||||
returnValue = SSL_do_handshake(ssl);
|
||||
gnutls_session_t session = _SSL[sslID].session;
|
||||
do
|
||||
{
|
||||
returnValue = gnutls_handshake (session);
|
||||
}
|
||||
while (returnValue < 0 && gnutls_error_is_fatal (returnValue) == 0);
|
||||
|
||||
// if (returnValue == 1)
|
||||
gnutls_alert_description_t alert = gnutls_alert_get (session);
|
||||
|
||||
WARN_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_DOHANDSHAKE "
|
||||
"%d %d", returnValue, alert);
|
||||
returnValue = returnValue == GNUTLS_E_SUCCESS;
|
||||
if (returnValue)
|
||||
Memory::Write_U32(0, _BufferIn);
|
||||
else
|
||||
Memory::Write_U32(-1, _BufferIn);
|
||||
}
|
||||
INFO_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_DOHANDSHAKE "
|
||||
else
|
||||
{
|
||||
Memory::Write_U32(-8, _BufferIn);
|
||||
}
|
||||
WARN_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_DOHANDSHAKE "
|
||||
"BufferIn: (%08x, %i), BufferIn2: (%08x, %i), "
|
||||
"BufferIn3: (%08x, %i), BufferOut: (%08x, %i), "
|
||||
"BufferOut2: (%08x, %i), BufferOut3: (%08x, %i)",
|
||||
|
@ -349,74 +447,50 @@ u32 CWII_IPC_HLE_Device_net_ssl::ExecuteCommandV(u32 _Parameter, SIOCtlVBuffer C
|
|||
{
|
||||
|
||||
int sslID = Memory::Read_U32(_BufferOut) - 1;
|
||||
if (sslID >= 0 && sslID < NET_SSL_MAXINSTANCES && sslfds[sslID] != NULL)
|
||||
if (SSLID_VALID(sslID))
|
||||
{
|
||||
SSL* ssl = sslfds[sslID];
|
||||
gnutls_session_t session = _SSL[sslID].session;
|
||||
|
||||
returnValue = SSL_write(ssl, Memory::GetPointer(_BufferOut2), BufferOutSize2);
|
||||
returnValue = gnutls_record_send(session, Memory::GetPointer(_BufferOut2), BufferOutSize2);
|
||||
|
||||
File::IOFile("ssl_write.bin", "ab").WriteBytes(Memory::GetPointer(_BufferOut2), BufferOutSize2);
|
||||
|
||||
if (returnValue == -1)
|
||||
returnValue = -SSL_get_error(ssl, returnValue);
|
||||
|
||||
Memory::Write_U32(returnValue, _BufferIn);
|
||||
}
|
||||
INFO_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_WRITE "
|
||||
else
|
||||
{
|
||||
Memory::Write_U32(-8, _BufferIn);
|
||||
}
|
||||
WARN_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_WRITE "
|
||||
"BufferIn: (%08x, %i), BufferIn2: (%08x, %i), "
|
||||
"BufferIn3: (%08x, %i), BufferOut: (%08x, %i), "
|
||||
"BufferOut2: (%08x, %i), BufferOut3: (%08x, %i)",
|
||||
_BufferIn, BufferInSize, _BufferIn2, BufferInSize2,
|
||||
_BufferIn3, BufferInSize3, _BufferOut, BufferOutSize,
|
||||
_BufferOut2, BufferOutSize2, _BufferOut3, BufferOutSize3);
|
||||
INFO_LOG(WII_IPC_SSL, "%s", Memory::GetPointer(_BufferOut2));
|
||||
WARN_LOG(WII_IPC_SSL, "%s", Memory::GetPointer(_BufferOut2));
|
||||
break;
|
||||
}
|
||||
|
||||
case IOCTLV_NET_SSL_READ:
|
||||
{
|
||||
int sslID = Memory::Read_U32(_BufferOut) - 1;
|
||||
if (sslID >= 0 && sslID < NET_SSL_MAXINSTANCES && sslfds[sslID] != NULL)
|
||||
if (SSLID_VALID(sslID))
|
||||
{
|
||||
SSL* ssl = sslfds[sslID];
|
||||
returnValue = SSL_read(ssl, Memory::GetPointer(_BufferIn2), BufferInSize2);
|
||||
if (returnValue == -1)
|
||||
gnutls_session_t session = _SSL[sslID].session;
|
||||
returnValue = gnutls_record_recv(session, Memory::GetPointer(_BufferIn2), BufferInSize2);
|
||||
if (returnValue > 0)
|
||||
{
|
||||
returnValue = -SSL_get_error(ssl, returnValue);
|
||||
INFO_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_READ errorVal= %d", returnValue);
|
||||
}else{
|
||||
File::IOFile("ssl_read.bin", "ab").WriteBytes(Memory::GetPointer(_BufferIn2), returnValue);
|
||||
}
|
||||
|
||||
// According to OpenSSL docs, all TLS calls (including reads) can cause
|
||||
// writing on a socket, so we need to handle SSL_ERROR_WANT_WRITE too
|
||||
// (which happens when OpenSSL writes on a nonblocking busy socket). The
|
||||
// Wii does not like -SSL_ERROR_WANT_WRITE though, so we convert it to
|
||||
// a read error.
|
||||
if (returnValue == -SSL_ERROR_WANT_WRITE)
|
||||
returnValue = -SSL_ERROR_WANT_READ;
|
||||
|
||||
if (returnValue == -SSL_ERROR_SYSCALL)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
int errorCode = WSAGetLastError();
|
||||
bool notConnected = (errorCode == WSAENOTCONN);
|
||||
#else
|
||||
int errorCode = errno;
|
||||
bool notConnected = (errorCode == ENOTCONN);
|
||||
#endif
|
||||
if (notConnected)
|
||||
{
|
||||
returnValue = -SSL_ERROR_WANT_READ;
|
||||
}
|
||||
else
|
||||
{
|
||||
INFO_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_READ ERRORCODE= %d", errorCode);
|
||||
}
|
||||
}
|
||||
Memory::Write_U32(returnValue, _BufferIn);
|
||||
}
|
||||
else
|
||||
{
|
||||
Memory::Write_U32(-8, _BufferIn);
|
||||
}
|
||||
|
||||
INFO_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_READ(%d)"
|
||||
WARN_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_READ(%d)"
|
||||
"BufferIn: (%08x, %i), BufferIn2: (%08x, %i), "
|
||||
"BufferIn3: (%08x, %i), BufferOut: (%08x, %i), "
|
||||
"BufferOut2: (%08x, %i), BufferOut3: (%08x, %i)",
|
||||
|
@ -429,11 +503,16 @@ u32 CWII_IPC_HLE_Device_net_ssl::ExecuteCommandV(u32 _Parameter, SIOCtlVBuffer C
|
|||
case IOCTLV_NET_SSL_SETROOTCADEFAULT:
|
||||
{
|
||||
int sslID = Memory::Read_U32(_BufferOut) - 1;
|
||||
if (sslID >= 0 && sslID < NET_SSL_MAXINSTANCES && sslfds[sslID] != NULL){
|
||||
if (SSLID_VALID(sslID))
|
||||
{
|
||||
|
||||
Memory::Write_U32(0, _BufferIn);
|
||||
}
|
||||
INFO_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_SETROOTCADEFAULT "
|
||||
else
|
||||
{
|
||||
Memory::Write_U32(-8, _BufferIn);
|
||||
}
|
||||
WARN_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_SETROOTCADEFAULT "
|
||||
"BufferIn: (%08x, %i), BufferIn2: (%08x, %i), "
|
||||
"BufferIn3: (%08x, %i), BufferOut: (%08x, %i), "
|
||||
"BufferOut2: (%08x, %i), BufferOut3: (%08x, %i)",
|
||||
|
@ -445,7 +524,7 @@ u32 CWII_IPC_HLE_Device_net_ssl::ExecuteCommandV(u32 _Parameter, SIOCtlVBuffer C
|
|||
|
||||
case IOCTLV_NET_SSL_SETCLIENTCERTDEFAULT:
|
||||
{
|
||||
INFO_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_SETCLIENTCERTDEFAULT "
|
||||
WARN_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_SETCLIENTCERTDEFAULT "
|
||||
"BufferIn: (%08x, %i), BufferIn2: (%08x, %i), "
|
||||
"BufferIn3: (%08x, %i), BufferOut: (%08x, %i), "
|
||||
"BufferOut2: (%08x, %i), BufferOut3: (%08x, %i)",
|
||||
|
@ -454,42 +533,15 @@ u32 CWII_IPC_HLE_Device_net_ssl::ExecuteCommandV(u32 _Parameter, SIOCtlVBuffer C
|
|||
_BufferOut2, BufferOutSize2, _BufferOut3, BufferOutSize3);
|
||||
|
||||
int sslID = Memory::Read_U32(_BufferOut) - 1;
|
||||
if (sslID >= 0 && sslID < NET_SSL_MAXINSTANCES && sslfds[sslID] != NULL)
|
||||
if (SSLID_VALID(sslID))
|
||||
{
|
||||
SSL* ssl = sslfds[sslID];
|
||||
|
||||
std::string cert_base_path(File::GetUserPath(D_WIIUSER_IDX));
|
||||
FILE * clientca = fopen((cert_base_path + "clientca.cer").c_str(), "rb");
|
||||
if (clientca == NULL)
|
||||
break;
|
||||
|
||||
X509 *cert = d2i_X509_fp(clientca, NULL);
|
||||
fclose(clientca);
|
||||
|
||||
FILE * clientcakey = fopen((cert_base_path + "clientcakey.der").c_str(), "rb");
|
||||
if (clientcakey == NULL)
|
||||
break;
|
||||
|
||||
|
||||
EVP_PKEY * key = d2i_PrivateKey_fp(clientcakey, NULL);
|
||||
|
||||
|
||||
if (SSL_use_certificate(ssl,cert) <= 0)
|
||||
break;
|
||||
if (SSL_use_PrivateKey(ssl,key) <= 0)
|
||||
break;
|
||||
|
||||
|
||||
if (!SSL_check_private_key(ssl))
|
||||
break;
|
||||
|
||||
if (cert)
|
||||
X509_free(cert);
|
||||
if (key)
|
||||
EVP_PKEY_free(key);
|
||||
|
||||
//gnutls_session_t session = _SSL[sslID].session;
|
||||
Memory::Write_U32(0, _BufferIn);
|
||||
}
|
||||
else
|
||||
{
|
||||
Memory::Write_U32(-8, _BufferIn);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -517,7 +569,7 @@ u32 CWII_IPC_HLE_Device_net_ssl::ExecuteCommand(u32 _Command,
|
|||
{
|
||||
default:
|
||||
{
|
||||
INFO_LOG(WII_IPC_SSL, "%s unknown %i "
|
||||
WARN_LOG(WII_IPC_SSL, "%s unknown %i "
|
||||
"(BufferIn: (%08x, %i), BufferOut: (%08x, %i)",
|
||||
GetDeviceName().c_str(), _Command,
|
||||
_BufferIn, BufferInSize, _BufferOut, BufferOutSize);
|
||||
|
|
|
@ -24,13 +24,15 @@
|
|||
#endif
|
||||
|
||||
#include "WII_IPC_HLE_Device.h"
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/pkcs12.h>
|
||||
#include <openssl/x509v3.h>
|
||||
|
||||
#include <gnutls/gnutls.h>
|
||||
#include <gnutls/x509.h>
|
||||
|
||||
#define MAX_HOSTNAME_LEN 256
|
||||
#define NET_SSL_MAXINSTANCES 4
|
||||
|
||||
#define SSLID_VALID(x) (x >= 0 && x < NET_SSL_MAXINSTANCES && _SSL[x].session != NULL)
|
||||
|
||||
class CWII_IPC_HLE_Device_net_ssl : public IWII_IPC_HLE_Device
|
||||
{
|
||||
public:
|
||||
|
@ -48,26 +50,31 @@ public:
|
|||
int getSSLFreeID();
|
||||
|
||||
private:
|
||||
SSL * sslfds[NET_SSL_MAXINSTANCES];
|
||||
enum
|
||||
struct _SSL{
|
||||
gnutls_session_t session;
|
||||
gnutls_certificate_credentials_t xcred;
|
||||
char hostname[MAX_HOSTNAME_LEN];
|
||||
} _SSL[NET_SSL_MAXINSTANCES];
|
||||
|
||||
enum
|
||||
{
|
||||
IOCTLV_NET_SSL_NEW = 0x01,
|
||||
IOCTLV_NET_SSL_CONNECT = 0x02,
|
||||
IOCTLV_NET_SSL_DOHANDSHAKE = 0x03,
|
||||
IOCTLV_NET_SSL_READ = 0x04,
|
||||
IOCTLV_NET_SSL_WRITE = 0x05,
|
||||
IOCTLV_NET_SSL_SHUTDOWN = 0x06,
|
||||
IOCTLV_NET_SSL_SHUTDOWN = 0x06,
|
||||
IOCTLV_NET_SSL_SETCLIENTCERT = 0x07,
|
||||
IOCTLV_NET_SSL_SETCLIENTCERTDEFAULT = 0x08,
|
||||
IOCTLV_NET_SSL_REMOVECLIENTCERT = 0x09,
|
||||
IOCTLV_NET_SSL_SETCLIENTCERTDEFAULT = 0x08,
|
||||
IOCTLV_NET_SSL_REMOVECLIENTCERT = 0x09,
|
||||
IOCTLV_NET_SSL_SETROOTCA = 0x0A,
|
||||
IOCTLV_NET_SSL_SETROOTCADEFAULT = 0x0B,
|
||||
IOCTLV_NET_SSL_SETROOTCADEFAULT = 0x0B,
|
||||
IOCTLV_NET_SSL_DOHANDSHAKEEX = 0x0C,
|
||||
IOCTLV_NET_SSL_SETBUILTINROOTCA = 0x0D,
|
||||
IOCTLV_NET_SSL_SETBUILTINCLIENTCERT = 0x0E,
|
||||
IOCTLV_NET_SSL_SETBUILTINROOTCA = 0x0D,
|
||||
IOCTLV_NET_SSL_SETBUILTINCLIENTCERT = 0x0E,
|
||||
IOCTLV_NET_SSL_DISABLEVERIFYOPTIONFORDEBUG = 0x0F,
|
||||
IOCTLV_NET_SSL_DEBUGGETVERSION = 0x14,
|
||||
IOCTLV_NET_SSL_DEBUGGETTIME = 0x15,
|
||||
IOCTLV_NET_SSL_DEBUGGETTIME = 0x15,
|
||||
};
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue