1
// Copyright 2013 Dolphin Emulator Project
2
// Licensed under GPLv2
3
// Refer to the license.txt file included.
6
#include "WII_IPC_HLE_Device_net_ssl.h"
7
#include "WII_Socket.h"
9
WII_SSL CWII_IPC_HLE_Device_net_ssl::_SSL[NET_SSL_MAXINSTANCES];
11
CWII_IPC_HLE_Device_net_ssl::CWII_IPC_HLE_Device_net_ssl(u32 _DeviceID, const std::string& _rDeviceName)
12
: IWII_IPC_HLE_Device(_DeviceID, _rDeviceName)
14
for (int i = 0; i < NET_SSL_MAXINSTANCES; ++i)
16
memset(&_SSL[i], 0, sizeof(WII_SSL));
20
CWII_IPC_HLE_Device_net_ssl::~CWII_IPC_HLE_Device_net_ssl()
23
for (int i = 0; i < NET_SSL_MAXINSTANCES; i++)
27
ssl_close_notify(&_SSL[i].ctx);
28
ssl_session_free(&_SSL[i].session);
29
ssl_free(&_SSL[i].ctx);
31
x509_free(&_SSL[i].cacert);
32
x509_free(&_SSL[i].clicert);
34
memset(&_SSL[i].ctx, 0, sizeof(ssl_context));
35
memset(&_SSL[i].session, 0, sizeof(ssl_session));
36
memset(&_SSL[i].hs, 0, sizeof(havege_state));
37
memset(_SSL[i].hostname, 0, NET_SSL_MAX_HOSTNAME_LEN);
39
_SSL[i].active = false;
44
int CWII_IPC_HLE_Device_net_ssl::getSSLFreeID()
46
for (int i = 0; i < NET_SSL_MAXINSTANCES; i++)
56
bool CWII_IPC_HLE_Device_net_ssl::Open(u32 _CommandAddress, u32 _Mode)
58
Memory::Write_U32(GetDeviceID(), _CommandAddress+4);
63
bool CWII_IPC_HLE_Device_net_ssl::Close(u32 _CommandAddress, bool _bForce)
67
Memory::Write_U32(0, _CommandAddress + 4);
73
bool CWII_IPC_HLE_Device_net_ssl::IOCtl(u32 _CommandAddress)
75
u32 BufferIn = Memory::Read_U32(_CommandAddress + 0x10);
76
u32 BufferInSize = Memory::Read_U32(_CommandAddress + 0x14);
77
u32 BufferOut = Memory::Read_U32(_CommandAddress + 0x18);
78
u32 BufferOutSize = Memory::Read_U32(_CommandAddress + 0x1C);
79
u32 Command = Memory::Read_U32(_CommandAddress + 0x0C);
81
INFO_LOG(WII_IPC_SSL, "%s unknown %i "
82
"(BufferIn: (%08x, %i), BufferOut: (%08x, %i)",
83
GetDeviceName().c_str(), Command,
84
BufferIn, BufferInSize, BufferOut, BufferOutSize);
85
Memory::Write_U32(0, _CommandAddress + 0x4);
89
bool CWII_IPC_HLE_Device_net_ssl::IOCtlV(u32 _CommandAddress)
91
SIOCtlVBuffer CommandBuffer(_CommandAddress);
93
u32 _BufferIn = 0, _BufferIn2 = 0, _BufferIn3 = 0;
94
u32 BufferInSize = 0, BufferInSize2 = 0, BufferInSize3 = 0;
96
u32 BufferOut = 0, BufferOut2 = 0, BufferOut3 = 0;
97
u32 BufferOutSize = 0, BufferOutSize2 = 0, BufferOutSize3 = 0;
99
if (CommandBuffer.InBuffer.size() > 0)
101
_BufferIn = CommandBuffer.InBuffer.at(0).m_Address;
102
BufferInSize = CommandBuffer.InBuffer.at(0).m_Size;
104
if (CommandBuffer.InBuffer.size() > 1)
106
_BufferIn2 = CommandBuffer.InBuffer.at(1).m_Address;
107
BufferInSize2 = CommandBuffer.InBuffer.at(1).m_Size;
109
if (CommandBuffer.InBuffer.size() > 2)
111
_BufferIn3 = CommandBuffer.InBuffer.at(2).m_Address;
112
BufferInSize3 = CommandBuffer.InBuffer.at(2).m_Size;
115
if (CommandBuffer.PayloadBuffer.size() > 0)
117
BufferOut = CommandBuffer.PayloadBuffer.at(0).m_Address;
118
BufferOutSize = CommandBuffer.PayloadBuffer.at(0).m_Size;
120
if (CommandBuffer.PayloadBuffer.size() > 1)
122
BufferOut2 = CommandBuffer.PayloadBuffer.at(1).m_Address;
123
BufferOutSize2 = CommandBuffer.PayloadBuffer.at(1).m_Size;
125
if (CommandBuffer.PayloadBuffer.size() > 2)
127
BufferOut3 = CommandBuffer.PayloadBuffer.at(2).m_Address;
128
BufferOutSize3 = CommandBuffer.PayloadBuffer.at(2).m_Size;
131
switch (CommandBuffer.Parameter)
133
case IOCTLV_NET_SSL_NEW:
135
int verifyOption = Memory::Read_U32(BufferOut);
136
const char * hostname = (const char*) Memory::GetPointer(BufferOut2);
138
int freeSSL = this->getSSLFreeID();
141
int sslID = freeSSL - 1;
142
int ret = ssl_init(&_SSL[sslID].ctx);
145
// Cleanup possibly dirty ctx
146
memset(&_SSL[sslID].ctx, 0, sizeof(ssl_context));
150
havege_init(&_SSL[sslID].hs);
151
ssl_set_rng(&_SSL[sslID].ctx, havege_random, &_SSL[sslID].hs);
153
// For some reason we can't use TLSv1.2, v1.1 and below are fine!
154
ssl_set_max_version(&_SSL[sslID].ctx, SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_2);
156
ssl_set_ciphersuites(&_SSL[sslID].ctx, ssl_default_ciphersuites);
157
ssl_set_session(&_SSL[sslID].ctx, &_SSL[sslID].session);
159
ssl_set_endpoint(&_SSL[sslID].ctx, SSL_IS_CLIENT);
160
ssl_set_authmode(&_SSL[sslID].ctx, SSL_VERIFY_NONE);
161
ssl_set_renegotiation(&_SSL[sslID].ctx, SSL_RENEGOTIATION_ENABLED);
163
memcpy(_SSL[sslID].hostname, hostname, min((int)BufferOutSize2, NET_SSL_MAX_HOSTNAME_LEN));
164
_SSL[sslID].hostname[NET_SSL_MAX_HOSTNAME_LEN-1] = '\0';
165
ssl_set_hostname(&_SSL[sslID].ctx, _SSL[sslID].hostname);
167
_SSL[sslID].active = true;
168
Memory::Write_U32(freeSSL, _BufferIn);
173
Memory::Write_U32(SSL_ERR_FAILED, _BufferIn);
176
INFO_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_NEW (%d, %s) "
177
"BufferIn: (%08x, %i), BufferIn2: (%08x, %i), "
178
"BufferIn3: (%08x, %i), BufferOut: (%08x, %i), "
179
"BufferOut2: (%08x, %i), BufferOut3: (%08x, %i)",
180
verifyOption, hostname,
181
_BufferIn, BufferInSize, _BufferIn2, BufferInSize2,
182
_BufferIn3, BufferInSize3, BufferOut, BufferOutSize,
183
BufferOut2, BufferOutSize2, BufferOut3, BufferOutSize3);
186
case IOCTLV_NET_SSL_SHUTDOWN:
188
int sslID = Memory::Read_U32(BufferOut) - 1;
189
if (SSLID_VALID(sslID))
191
ssl_close_notify(&_SSL[sslID].ctx);
192
ssl_session_free(&_SSL[sslID].session);
193
ssl_free(&_SSL[sslID].ctx);
195
x509_free(&_SSL[sslID].cacert);
196
x509_free(&_SSL[sslID].clicert);
198
memset(&_SSL[sslID].ctx, 0, sizeof(ssl_context));
199
memset(&_SSL[sslID].session, 0, sizeof(ssl_session));
200
memset(&_SSL[sslID].hs, 0, sizeof(havege_state));
201
memset(_SSL[sslID].hostname, 0, NET_SSL_MAX_HOSTNAME_LEN);
203
_SSL[sslID].active = false;
205
Memory::Write_U32(SSL_OK, _BufferIn);
209
Memory::Write_U32(SSL_ERR_ID, _BufferIn);
211
INFO_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_SHUTDOWN "
212
"BufferIn: (%08x, %i), BufferIn2: (%08x, %i), "
213
"BufferIn3: (%08x, %i), BufferOut: (%08x, %i), "
214
"BufferOut2: (%08x, %i), BufferOut3: (%08x, %i)",
215
_BufferIn, BufferInSize, _BufferIn2, BufferInSize2,
216
_BufferIn3, BufferInSize3, BufferOut, BufferOutSize,
217
BufferOut2, BufferOutSize2, BufferOut3, BufferOutSize3);
220
case IOCTLV_NET_SSL_SETROOTCA:
222
INFO_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_SETROOTCA "
223
"BufferIn: (%08x, %i), BufferIn2: (%08x, %i), "
224
"BufferIn3: (%08x, %i), BufferOut: (%08x, %i), "
225
"BufferOut2: (%08x, %i), BufferOut3: (%08x, %i)",
226
_BufferIn, BufferInSize, _BufferIn2, BufferInSize2,
227
_BufferIn3, BufferInSize3, BufferOut, BufferOutSize,
228
BufferOut2, BufferOutSize2, BufferOut3, BufferOutSize3);
231
int sslID = Memory::Read_U32(BufferOut) - 1;
232
if (SSLID_VALID(sslID))
234
int ret = x509parse_crt_der(
236
Memory::GetPointer(BufferOut2),
241
Memory::Write_U32(SSL_ERR_FAILED, _BufferIn);
245
ssl_set_ca_chain(&_SSL[sslID].ctx, &_SSL[sslID].cacert, NULL, _SSL[sslID].hostname);
246
Memory::Write_U32(SSL_OK, _BufferIn);
249
INFO_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_SETROOTCA = %d", ret);
253
Memory::Write_U32(SSL_ERR_ID, _BufferIn);
257
case IOCTLV_NET_SSL_SETBUILTINCLIENTCERT:
259
INFO_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_SETBUILTINCLIENTCERT "
260
"BufferIn: (%08x, %i), BufferIn2: (%08x, %i), "
261
"BufferIn3: (%08x, %i), BufferOut: (%08x, %i), "
262
"BufferOut2: (%08x, %i), BufferOut3: (%08x, %i)",
263
_BufferIn, BufferInSize, _BufferIn2, BufferInSize2,
264
_BufferIn3, BufferInSize3, BufferOut, BufferOutSize,
265
BufferOut2, BufferOutSize2, BufferOut3, BufferOutSize3);
267
int sslID = Memory::Read_U32(BufferOut) - 1;
268
if (SSLID_VALID(sslID))
270
std::string cert_base_path(File::GetUserPath(D_WIIUSER_IDX));
271
int ret = x509parse_crtfile(&_SSL[sslID].clicert, (cert_base_path + "clientca.pem").c_str());
272
int rsa_ret = x509parse_keyfile(&_SSL[sslID].rsa, (cert_base_path + "clientcakey.pem").c_str(), NULL);
275
x509_free(&_SSL[sslID].clicert);
276
rsa_free(&_SSL[sslID].rsa);
277
memset(&_SSL[sslID].clicert, 0, sizeof(x509_cert));
278
memset(&_SSL[sslID].rsa, 0, sizeof(rsa_context));
279
Memory::Write_U32(SSL_ERR_FAILED, _BufferIn);
283
ssl_set_own_cert(&_SSL[sslID].ctx, &_SSL[sslID].clicert, &_SSL[sslID].rsa);
284
Memory::Write_U32(SSL_OK, _BufferIn);
287
INFO_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_SETBUILTINCLIENTCERT = (%d, %d)", ret, rsa_ret);
291
Memory::Write_U32(SSL_ERR_ID, _BufferIn);
292
INFO_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_SETBUILTINCLIENTCERT invalid sslID = %d", sslID);
296
case IOCTLV_NET_SSL_REMOVECLIENTCERT:
298
INFO_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_REMOVECLIENTCERT "
299
"BufferIn: (%08x, %i), BufferIn2: (%08x, %i), "
300
"BufferIn3: (%08x, %i), BufferOut: (%08x, %i), "
301
"BufferOut2: (%08x, %i), BufferOut3: (%08x, %i)",
302
_BufferIn, BufferInSize, _BufferIn2, BufferInSize2,
303
_BufferIn3, BufferInSize3, BufferOut, BufferOutSize,
304
BufferOut2, BufferOutSize2, BufferOut3, BufferOutSize3);
306
int sslID = Memory::Read_U32(BufferOut) - 1;
307
if (SSLID_VALID(sslID))
309
x509_free(&_SSL[sslID].clicert);
310
rsa_free(&_SSL[sslID].rsa);
311
memset(&_SSL[sslID].clicert, 0, sizeof(x509_cert));
312
memset(&_SSL[sslID].rsa, 0, sizeof(rsa_context));
314
ssl_set_own_cert(&_SSL[sslID].ctx, NULL, NULL);
315
Memory::Write_U32(SSL_OK, _BufferIn);
319
Memory::Write_U32(SSL_ERR_ID, _BufferIn);
320
INFO_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_SETBUILTINCLIENTCERT invalid sslID = %d", sslID);
324
case IOCTLV_NET_SSL_SETBUILTINROOTCA:
326
int sslID = Memory::Read_U32(BufferOut) - 1;
327
if (SSLID_VALID(sslID))
329
std::string cert_base_path(File::GetUserPath(D_WIIUSER_IDX));
331
int ret = x509parse_crtfile(&_SSL[sslID].cacert, (cert_base_path + "rootca.pem").c_str());
334
x509_free(&_SSL[sslID].clicert);
335
Memory::Write_U32(SSL_ERR_FAILED, _BufferIn);
339
ssl_set_ca_chain(&_SSL[sslID].ctx, &_SSL[sslID].cacert, NULL, _SSL[sslID].hostname);
340
Memory::Write_U32(SSL_OK, _BufferIn);
342
INFO_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_SETBUILTINROOTCA = %d", ret);
346
Memory::Write_U32(SSL_ERR_ID, _BufferIn);
348
INFO_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_SETBUILTINROOTCA "
349
"BufferIn: (%08x, %i), BufferIn2: (%08x, %i), "
350
"BufferIn3: (%08x, %i), BufferOut: (%08x, %i), "
351
"BufferOut2: (%08x, %i), BufferOut3: (%08x, %i)",
352
_BufferIn, BufferInSize, _BufferIn2, BufferInSize2,
353
_BufferIn3, BufferInSize3, BufferOut, BufferOutSize,
354
BufferOut2, BufferOutSize2, BufferOut3, BufferOutSize3);
357
case IOCTLV_NET_SSL_CONNECT:
359
int sslID = Memory::Read_U32(BufferOut) - 1;
360
if (SSLID_VALID(sslID))
362
_SSL[sslID].sockfd = Memory::Read_U32(BufferOut2);
363
INFO_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_CONNECT socket = %d", _SSL[sslID].sockfd);
364
ssl_set_bio(&_SSL[sslID].ctx, net_recv, &_SSL[sslID].sockfd, net_send, &_SSL[sslID].sockfd);
365
Memory::Write_U32(SSL_OK, _BufferIn);
369
Memory::Write_U32(SSL_ERR_ID, _BufferIn);
371
INFO_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_CONNECT "
372
"BufferIn: (%08x, %i), BufferIn2: (%08x, %i), "
373
"BufferIn3: (%08x, %i), BufferOut: (%08x, %i), "
374
"BufferOut2: (%08x, %i), BufferOut3: (%08x, %i)",
375
_BufferIn, BufferInSize, _BufferIn2, BufferInSize2,
376
_BufferIn3, BufferInSize3, BufferOut, BufferOutSize,
377
BufferOut2, BufferOutSize2, BufferOut3, BufferOutSize3);
380
case IOCTLV_NET_SSL_DOHANDSHAKE:
382
int sslID = Memory::Read_U32(BufferOut) - 1;
383
if (SSLID_VALID(sslID))
385
WiiSockMan &sm = WiiSockMan::getInstance();
386
sm.doSock(_SSL[sslID].sockfd, _CommandAddress, IOCTLV_NET_SSL_DOHANDSHAKE);
391
Memory::Write_U32(SSL_ERR_ID, _BufferIn);
395
case IOCTLV_NET_SSL_WRITE:
397
int sslID = Memory::Read_U32(BufferOut) - 1;
398
if (SSLID_VALID(sslID))
400
WiiSockMan &sm = WiiSockMan::getInstance();
401
sm.doSock(_SSL[sslID].sockfd, _CommandAddress, IOCTLV_NET_SSL_WRITE);
406
Memory::Write_U32(SSL_ERR_ID, _BufferIn);
408
INFO_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_WRITE "
409
"BufferIn: (%08x, %i), BufferIn2: (%08x, %i), "
410
"BufferIn3: (%08x, %i), BufferOut: (%08x, %i), "
411
"BufferOut2: (%08x, %i), BufferOut3: (%08x, %i)",
412
_BufferIn, BufferInSize, _BufferIn2, BufferInSize2,
413
_BufferIn3, BufferInSize3, BufferOut, BufferOutSize,
414
BufferOut2, BufferOutSize2, BufferOut3, BufferOutSize3);
415
INFO_LOG(WII_IPC_SSL, "%s", Memory::GetPointer(BufferOut2));
418
case IOCTLV_NET_SSL_READ:
422
int sslID = Memory::Read_U32(BufferOut) - 1;
423
if (SSLID_VALID(sslID))
425
WiiSockMan &sm = WiiSockMan::getInstance();
426
sm.doSock(_SSL[sslID].sockfd, _CommandAddress, IOCTLV_NET_SSL_READ);
431
Memory::Write_U32(SSL_ERR_ID, _BufferIn);
434
INFO_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_READ(%d)"
435
"BufferIn: (%08x, %i), BufferIn2: (%08x, %i), "
436
"BufferIn3: (%08x, %i), BufferOut: (%08x, %i), "
437
"BufferOut2: (%08x, %i), BufferOut3: (%08x, %i)",
439
_BufferIn, BufferInSize, _BufferIn2, BufferInSize2,
440
_BufferIn3, BufferInSize3, BufferOut, BufferOutSize,
441
BufferOut2, BufferOutSize2, BufferOut3, BufferOutSize3);
444
case IOCTLV_NET_SSL_SETROOTCADEFAULT:
446
int sslID = Memory::Read_U32(BufferOut) - 1;
447
if (SSLID_VALID(sslID))
449
Memory::Write_U32(SSL_OK, _BufferIn);
453
Memory::Write_U32(SSL_ERR_ID, _BufferIn);
455
INFO_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_SETROOTCADEFAULT "
456
"BufferIn: (%08x, %i), BufferIn2: (%08x, %i), "
457
"BufferIn3: (%08x, %i), BufferOut: (%08x, %i), "
458
"BufferOut2: (%08x, %i), BufferOut3: (%08x, %i)",
459
_BufferIn, BufferInSize, _BufferIn2, BufferInSize2,
460
_BufferIn3, BufferInSize3, BufferOut, BufferOutSize,
461
BufferOut2, BufferOutSize2, BufferOut3, BufferOutSize3);
464
case IOCTLV_NET_SSL_SETCLIENTCERTDEFAULT:
466
INFO_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_SETCLIENTCERTDEFAULT "
467
"BufferIn: (%08x, %i), BufferIn2: (%08x, %i), "
468
"BufferIn3: (%08x, %i), BufferOut: (%08x, %i), "
469
"BufferOut2: (%08x, %i), BufferOut3: (%08x, %i)",
470
_BufferIn, BufferInSize, _BufferIn2, BufferInSize2,
471
_BufferIn3, BufferInSize3, BufferOut, BufferOutSize,
472
BufferOut2, BufferOutSize2, BufferOut3, BufferOutSize3);
474
int sslID = Memory::Read_U32(BufferOut) - 1;
475
if (SSLID_VALID(sslID))
477
Memory::Write_U32(SSL_OK, _BufferIn);
481
Memory::Write_U32(SSL_ERR_ID, _BufferIn);
486
ERROR_LOG(WII_IPC_SSL, "%i "
487
"BufferIn: (%08x, %i), BufferIn2: (%08x, %i), "
488
"BufferIn3: (%08x, %i), BufferOut: (%08x, %i), "
489
"BufferOut2: (%08x, %i), BufferOut3: (%08x, %i)",
490
CommandBuffer.Parameter,
491
_BufferIn, BufferInSize, _BufferIn2, BufferInSize2,
492
_BufferIn3, BufferInSize3, BufferOut, BufferOutSize,
493
BufferOut2, BufferOutSize2, BufferOut3, BufferOutSize3);
497
// SSL return codes are written to BufferIn
498
Memory::Write_U32(0, _CommandAddress+4);