forked from Mirror/Ryujinx
nifm/ssl: Implement GetCurrentNetworkProfile and stub Ssl Service (#2186)
* nifm/ssl: Implement GetCurrentNetworkProfile and stub Ssl Service * remove InterfaceVersion
This commit is contained in:
parent
73881fad19
commit
b662a26c7e
17 changed files with 375 additions and 56 deletions
|
@ -2,8 +2,11 @@ using Ryujinx.Common;
|
||||||
using Ryujinx.Common.Logging;
|
using Ryujinx.Common.Logging;
|
||||||
using Ryujinx.HLE.HOS.Services.Nifm.StaticService.GeneralService;
|
using Ryujinx.HLE.HOS.Services.Nifm.StaticService.GeneralService;
|
||||||
using Ryujinx.HLE.HOS.Services.Nifm.StaticService.Types;
|
using Ryujinx.HLE.HOS.Services.Nifm.StaticService.Types;
|
||||||
|
using Ryujinx.HLE.Utilities;
|
||||||
using System;
|
using System;
|
||||||
using System.Net.NetworkInformation;
|
using System.Net.NetworkInformation;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
namespace Ryujinx.HLE.HOS.Services.Nifm.StaticService
|
namespace Ryujinx.HLE.HOS.Services.Nifm.StaticService
|
||||||
{
|
{
|
||||||
|
@ -51,6 +54,38 @@ namespace Ryujinx.HLE.HOS.Services.Nifm.StaticService
|
||||||
return ResultCode.Success;
|
return ResultCode.Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Command(5)]
|
||||||
|
// GetCurrentNetworkProfile() -> buffer<nn::nifm::detail::sf::NetworkProfileData, 0x1a, 0x17c>
|
||||||
|
public ResultCode GetCurrentNetworkProfile(ServiceCtx context)
|
||||||
|
{
|
||||||
|
long networkProfileDataPosition = context.Request.RecvListBuff[0].Position;
|
||||||
|
|
||||||
|
(IPInterfaceProperties interfaceProperties, UnicastIPAddressInformation unicastAddress) = GetLocalInterface();
|
||||||
|
|
||||||
|
if (interfaceProperties == null || unicastAddress == null)
|
||||||
|
{
|
||||||
|
return ResultCode.NoInternetConnection;
|
||||||
|
}
|
||||||
|
|
||||||
|
Logger.Info?.Print(LogClass.ServiceNifm, $"Console's local IP is \"{unicastAddress.Address}\".");
|
||||||
|
|
||||||
|
context.Response.PtrBuff[0] = context.Response.PtrBuff[0].WithSize(Unsafe.SizeOf<NetworkProfileData>());
|
||||||
|
|
||||||
|
NetworkProfileData networkProfile = new NetworkProfileData
|
||||||
|
{
|
||||||
|
Uuid = new UInt128(Guid.NewGuid().ToByteArray())
|
||||||
|
};
|
||||||
|
|
||||||
|
networkProfile.IpSettingData.IpAddressSetting = new IpAddressSetting(interfaceProperties, unicastAddress);
|
||||||
|
networkProfile.IpSettingData.DnsSetting = new DnsSetting(interfaceProperties);
|
||||||
|
|
||||||
|
Encoding.ASCII.GetBytes("RyujinxNetwork").CopyTo(networkProfile.Name.ToSpan());
|
||||||
|
|
||||||
|
context.Memory.Write((ulong)networkProfileDataPosition, networkProfile);
|
||||||
|
|
||||||
|
return ResultCode.Success;
|
||||||
|
}
|
||||||
|
|
||||||
[Command(12)]
|
[Command(12)]
|
||||||
// GetCurrentIpAddress() -> nn::nifm::IpV4Address
|
// GetCurrentIpAddress() -> nn::nifm::IpV4Address
|
||||||
public ResultCode GetCurrentIpAddress(ServiceCtx context)
|
public ResultCode GetCurrentIpAddress(ServiceCtx context)
|
||||||
|
@ -75,7 +110,7 @@ namespace Ryujinx.HLE.HOS.Services.Nifm.StaticService
|
||||||
{
|
{
|
||||||
(IPInterfaceProperties interfaceProperties, UnicastIPAddressInformation unicastAddress) = GetLocalInterface();
|
(IPInterfaceProperties interfaceProperties, UnicastIPAddressInformation unicastAddress) = GetLocalInterface();
|
||||||
|
|
||||||
if (interfaceProperties == null)
|
if (interfaceProperties == null || unicastAddress == null)
|
||||||
{
|
{
|
||||||
return ResultCode.NoInternetConnection;
|
return ResultCode.NoInternetConnection;
|
||||||
}
|
}
|
||||||
|
@ -138,11 +173,11 @@ namespace Ryujinx.HLE.HOS.Services.Nifm.StaticService
|
||||||
foreach (NetworkInterface adapter in interfaces)
|
foreach (NetworkInterface adapter in interfaces)
|
||||||
{
|
{
|
||||||
// Ignore loopback and non IPv4 capable interface.
|
// Ignore loopback and non IPv4 capable interface.
|
||||||
if (adapter.NetworkInterfaceType != NetworkInterfaceType.Loopback && adapter.Supports(NetworkInterfaceComponent.IPv4))
|
if (targetProperties == null && adapter.NetworkInterfaceType != NetworkInterfaceType.Loopback && adapter.Supports(NetworkInterfaceComponent.IPv4))
|
||||||
{
|
{
|
||||||
IPInterfaceProperties properties = adapter.GetIPProperties();
|
IPInterfaceProperties properties = adapter.GetIPProperties();
|
||||||
|
|
||||||
if (properties.GatewayAddresses.Count > 0 && properties.DnsAddresses.Count > 1)
|
if (properties.GatewayAddresses.Count > 0 && properties.DnsAddresses.Count > 0)
|
||||||
{
|
{
|
||||||
foreach (UnicastIPAddressInformation info in properties.UnicastAddresses)
|
foreach (UnicastIPAddressInformation info in properties.UnicastAddresses)
|
||||||
{
|
{
|
||||||
|
@ -156,12 +191,6 @@ namespace Ryujinx.HLE.HOS.Services.Nifm.StaticService
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Found the target interface, stop here.
|
|
||||||
if (targetProperties != null)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,8 +14,17 @@ namespace Ryujinx.HLE.HOS.Services.Nifm.StaticService.Types
|
||||||
public DnsSetting(IPInterfaceProperties interfaceProperties)
|
public DnsSetting(IPInterfaceProperties interfaceProperties)
|
||||||
{
|
{
|
||||||
IsDynamicDnsEnabled = interfaceProperties.IsDynamicDnsEnabled;
|
IsDynamicDnsEnabled = interfaceProperties.IsDynamicDnsEnabled;
|
||||||
|
|
||||||
|
if (interfaceProperties.DnsAddresses.Count == 0)
|
||||||
|
{
|
||||||
|
PrimaryDns = new IpV4Address();
|
||||||
|
SecondaryDns = new IpV4Address();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
PrimaryDns = new IpV4Address(interfaceProperties.DnsAddresses[0]);
|
PrimaryDns = new IpV4Address(interfaceProperties.DnsAddresses[0]);
|
||||||
SecondaryDns = new IpV4Address(interfaceProperties.DnsAddresses[1]);
|
SecondaryDns = new IpV4Address(interfaceProperties.DnsAddresses[interfaceProperties.DnsAddresses.Count > 1 ? 1 : 0]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
namespace Ryujinx.HLE.HOS.Services.Nifm.StaticService.Types
|
||||||
|
{
|
||||||
|
[StructLayout(LayoutKind.Sequential, Pack = 1, Size = 0xc2)]
|
||||||
|
struct IpSettingData
|
||||||
|
{
|
||||||
|
public IpAddressSetting IpAddressSetting;
|
||||||
|
public DnsSetting DnsSetting;
|
||||||
|
public ProxySetting ProxySetting;
|
||||||
|
public short Mtu;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
using Ryujinx.Common.Memory;
|
||||||
|
using Ryujinx.HLE.Utilities;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
namespace Ryujinx.HLE.HOS.Services.Nifm.StaticService.Types
|
||||||
|
{
|
||||||
|
[StructLayout(LayoutKind.Sequential, Pack = 1, Size = 0x17C)]
|
||||||
|
struct NetworkProfileData
|
||||||
|
{
|
||||||
|
public IpSettingData IpSettingData;
|
||||||
|
public UInt128 Uuid;
|
||||||
|
public Array64<byte> Name;
|
||||||
|
public Array4<byte> Unknown;
|
||||||
|
public WirelessSettingData WirelessSettingData;
|
||||||
|
public byte Padding;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
using LibHac.Common;
|
||||||
|
using Ryujinx.Common.Memory;
|
||||||
|
using System;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
namespace Ryujinx.HLE.HOS.Services.Nifm.StaticService.Types
|
||||||
|
{
|
||||||
|
[StructLayout(LayoutKind.Sequential, Pack = 1, Size = 0xaa)]
|
||||||
|
public struct ProxySetting
|
||||||
|
{
|
||||||
|
[MarshalAs(UnmanagedType.I1)]
|
||||||
|
public bool Enabled;
|
||||||
|
private byte _padding;
|
||||||
|
public short Port;
|
||||||
|
private NameStruct _name;
|
||||||
|
[MarshalAs(UnmanagedType.I1)]
|
||||||
|
public bool AutoAuthEnabled;
|
||||||
|
public Array32<byte> User;
|
||||||
|
public Array32<byte> Pass;
|
||||||
|
private byte _padding2;
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential, Size = 0x64)]
|
||||||
|
private struct NameStruct { }
|
||||||
|
|
||||||
|
public Span<byte> Name => SpanHelpers.AsSpan<NameStruct, byte>(ref _name);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
using Ryujinx.Common.Memory;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
namespace Ryujinx.HLE.HOS.Services.Nifm.StaticService.Types
|
||||||
|
{
|
||||||
|
[StructLayout(LayoutKind.Sequential, Pack = 1, Size = 0x65)]
|
||||||
|
struct WirelessSettingData
|
||||||
|
{
|
||||||
|
public byte SsidLength;
|
||||||
|
public Array32<byte> Ssid;
|
||||||
|
public Array3<byte> Unknown;
|
||||||
|
public Array64<byte> Passphrase1;
|
||||||
|
public byte Passphrase2;
|
||||||
|
}
|
||||||
|
}
|
|
@ -132,7 +132,8 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Nsd
|
||||||
// Resolve(buffer<unknown<0x100>, 0x15>) -> buffer<unknown<0x100>, 0x16>
|
// Resolve(buffer<unknown<0x100>, 0x15>) -> buffer<unknown<0x100>, 0x16>
|
||||||
public ResultCode Resolve(ServiceCtx context)
|
public ResultCode Resolve(ServiceCtx context)
|
||||||
{
|
{
|
||||||
(long outputPosition, long outputSize) = context.Request.GetBufferType0x22();
|
long outputPosition = context.Request.ReceiveBuff[0].Position;
|
||||||
|
long outputSize = context.Request.ReceiveBuff[0].Size;
|
||||||
|
|
||||||
ResultCode result = _fqdnResolver.ResolveEx(context, out ResultCode errorCode, out string resolvedAddress);
|
ResultCode result = _fqdnResolver.ResolveEx(context, out ResultCode errorCode, out string resolvedAddress);
|
||||||
|
|
||||||
|
@ -147,7 +148,8 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Nsd
|
||||||
// ResolveEx(buffer<unknown<0x100>, 0x15>) -> (u32, buffer<unknown<0x100>, 0x16>)
|
// ResolveEx(buffer<unknown<0x100>, 0x15>) -> (u32, buffer<unknown<0x100>, 0x16>)
|
||||||
public ResultCode ResolveEx(ServiceCtx context)
|
public ResultCode ResolveEx(ServiceCtx context)
|
||||||
{
|
{
|
||||||
(long outputPosition, long outputSize) = context.Request.GetBufferType0x22();
|
long outputPosition = context.Request.ReceiveBuff[0].Position;
|
||||||
|
long outputSize = context.Request.ReceiveBuff[0].Size;
|
||||||
|
|
||||||
ResultCode result = _fqdnResolver.ResolveEx(context, out ResultCode errorCode, out string resolvedAddress);
|
ResultCode result = _fqdnResolver.ResolveEx(context, out ResultCode errorCode, out string resolvedAddress);
|
||||||
|
|
||||||
|
|
|
@ -73,30 +73,19 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Nsd.Manager
|
||||||
return ResultCode.SettingsNotLoaded;
|
return ResultCode.SettingsNotLoaded;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (address)
|
resolvedAddress = address switch
|
||||||
{
|
{
|
||||||
case "e97b8a9d672e4ce4845ec6947cd66ef6-sb-api.accounts.nintendo.com": // dp1 environment
|
"e97b8a9d672e4ce4845ec6947cd66ef6-sb-api.accounts.nintendo.com" => "e97b8a9d672e4ce4845ec6947cd66ef6-sb.baas.nintendo.com", // dp1 environment
|
||||||
resolvedAddress = "e97b8a9d672e4ce4845ec6947cd66ef6-sb.baas.nintendo.com";
|
"api.accounts.nintendo.com" => "e0d67c509fb203858ebcb2fe3f88c2aa.baas.nintendo.com", // dp1 environment
|
||||||
break;
|
"e97b8a9d672e4ce4845ec6947cd66ef6-sb.accounts.nintendo.com" => "e97b8a9d672e4ce4845ec6947cd66ef6-sb.baas.nintendo.com", // lp1 environment
|
||||||
case "api.accounts.nintendo.com": // dp1 environment
|
"accounts.nintendo.com" => "e0d67c509fb203858ebcb2fe3f88c2aa.baas.nintendo.com", // lp1 environment
|
||||||
resolvedAddress = "e0d67c509fb203858ebcb2fe3f88c2aa.baas.nintendo.com";
|
|
||||||
break;
|
|
||||||
case "e97b8a9d672e4ce4845ec6947cd66ef6-sb.accounts.nintendo.com": // lp1 environment
|
|
||||||
resolvedAddress = "e97b8a9d672e4ce4845ec6947cd66ef6-sb.baas.nintendo.com";
|
|
||||||
break;
|
|
||||||
case "accounts.nintendo.com": // lp1 environment
|
|
||||||
resolvedAddress = "e0d67c509fb203858ebcb2fe3f88c2aa.baas.nintendo.com";
|
|
||||||
break;
|
|
||||||
/*
|
/*
|
||||||
// TODO: Determine fields of the struct.
|
// TODO: Determine fields of the struct.
|
||||||
case "": // + 0xEB8 || + 0x2BE8
|
this + 0xEB8 => this + 0xEB8 + 0x300
|
||||||
resolvedAddress = ""; // + 0xEB8 + 0x300 || + 0x2BE8 + 0x300
|
this + 0x2BE8 => this + 0x2BE8 + 0x300
|
||||||
break;
|
|
||||||
*/
|
*/
|
||||||
default:
|
_ => address,
|
||||||
resolvedAddress = address;
|
};
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -108,7 +97,8 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Nsd.Manager
|
||||||
|
|
||||||
public ResultCode ResolveEx(ServiceCtx context, out ResultCode resultCode, out string resolvedAddress)
|
public ResultCode ResolveEx(ServiceCtx context, out ResultCode resultCode, out string resolvedAddress)
|
||||||
{
|
{
|
||||||
(long inputPosition, long inputSize) = context.Request.GetBufferType0x21();
|
long inputPosition = context.Request.SendBuff[0].Position;
|
||||||
|
long inputSize = context.Request.SendBuff[0].Size;
|
||||||
|
|
||||||
byte[] addressBuffer = new byte[inputSize];
|
byte[] addressBuffer = new byte[inputSize];
|
||||||
|
|
||||||
|
|
|
@ -1,24 +1,27 @@
|
||||||
using Ryujinx.Common.Logging;
|
using Ryujinx.Common.Logging;
|
||||||
using Ryujinx.HLE.HOS.Services.Ssl.SslService;
|
using Ryujinx.HLE.HOS.Services.Ssl.SslService;
|
||||||
|
using Ryujinx.HLE.HOS.Services.Ssl.Types;
|
||||||
|
|
||||||
namespace Ryujinx.HLE.HOS.Services.Ssl
|
namespace Ryujinx.HLE.HOS.Services.Ssl
|
||||||
{
|
{
|
||||||
[Service("ssl")]
|
[Service("ssl")]
|
||||||
class ISslService : IpcService
|
class ISslService : IpcService
|
||||||
{
|
{
|
||||||
|
// NOTE: The SSL service is used by games to connect it to various official online services, which we do not intend to support.
|
||||||
|
// In this case it is acceptable to stub all calls of the service.
|
||||||
public ISslService(ServiceCtx context) { }
|
public ISslService(ServiceCtx context) { }
|
||||||
|
|
||||||
[Command(0)]
|
[Command(0)]
|
||||||
// CreateContext(nn::ssl::sf::SslVersion, u64, pid) -> object<nn::ssl::sf::ISslContext>
|
// CreateContext(nn::ssl::sf::SslVersion, u64, pid) -> object<nn::ssl::sf::ISslContext>
|
||||||
public ResultCode CreateContext(ServiceCtx context)
|
public ResultCode CreateContext(ServiceCtx context)
|
||||||
{
|
{
|
||||||
int sslVersion = context.RequestData.ReadInt32();
|
SslVersion sslVersion = (SslVersion)context.RequestData.ReadUInt32();
|
||||||
long unknown = context.RequestData.ReadInt64();
|
ulong pidPlaceholder = context.RequestData.ReadUInt64();
|
||||||
|
|
||||||
Logger.Stub?.PrintStub(LogClass.ServiceSsl, new { sslVersion, unknown });
|
|
||||||
|
|
||||||
MakeObject(context, new ISslContext(context));
|
MakeObject(context, new ISslContext(context));
|
||||||
|
|
||||||
|
Logger.Stub?.PrintStub(LogClass.ServiceSsl, new { sslVersion });
|
||||||
|
|
||||||
return ResultCode.Success;
|
return ResultCode.Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,9 +29,10 @@ namespace Ryujinx.HLE.HOS.Services.Ssl
|
||||||
// SetInterfaceVersion(u32)
|
// SetInterfaceVersion(u32)
|
||||||
public ResultCode SetInterfaceVersion(ServiceCtx context)
|
public ResultCode SetInterfaceVersion(ServiceCtx context)
|
||||||
{
|
{
|
||||||
int version = context.RequestData.ReadInt32();
|
// 1 = 3.0.0+, 2 = 5.0.0+, 3 = 6.0.0+
|
||||||
|
uint interfaceVersion = context.RequestData.ReadUInt32();
|
||||||
|
|
||||||
Logger.Stub?.PrintStub(LogClass.ServiceSsl, new { version });
|
Logger.Stub?.PrintStub(LogClass.ServiceSsl, new { interfaceVersion });
|
||||||
|
|
||||||
return ResultCode.Success;
|
return ResultCode.Success;
|
||||||
}
|
}
|
||||||
|
|
113
Ryujinx.HLE/HOS/Services/Ssl/SslService/ISslConnection.cs
Normal file
113
Ryujinx.HLE/HOS/Services/Ssl/SslService/ISslConnection.cs
Normal file
|
@ -0,0 +1,113 @@
|
||||||
|
using Ryujinx.Common.Logging;
|
||||||
|
using Ryujinx.HLE.HOS.Services.Ssl.Types;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Ryujinx.HLE.HOS.Services.Ssl.SslService
|
||||||
|
{
|
||||||
|
class ISslConnection : IpcService
|
||||||
|
{
|
||||||
|
public ISslConnection() { }
|
||||||
|
|
||||||
|
[Command(0)]
|
||||||
|
// SetSocketDescriptor(u32) -> u32
|
||||||
|
public ResultCode SetSocketDescriptor(ServiceCtx context)
|
||||||
|
{
|
||||||
|
uint socketFd = context.RequestData.ReadUInt32();
|
||||||
|
uint duplicateSocketFd = 0;
|
||||||
|
|
||||||
|
context.ResponseData.Write(duplicateSocketFd);
|
||||||
|
|
||||||
|
Logger.Stub?.PrintStub(LogClass.ServiceSsl, new { socketFd });
|
||||||
|
|
||||||
|
return ResultCode.Success;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Command(1)]
|
||||||
|
// SetHostName(buffer<bytes, 5>)
|
||||||
|
public ResultCode SetHostName(ServiceCtx context)
|
||||||
|
{
|
||||||
|
long hostNameDataPosition = context.Request.SendBuff[0].Position;
|
||||||
|
long hostNameDataSize = context.Request.SendBuff[0].Size;
|
||||||
|
|
||||||
|
byte[] hostNameData = new byte[hostNameDataSize];
|
||||||
|
|
||||||
|
context.Memory.Read((ulong)hostNameDataPosition, hostNameData);
|
||||||
|
|
||||||
|
string hostName = Encoding.ASCII.GetString(hostNameData).Trim('\0');
|
||||||
|
|
||||||
|
Logger.Stub?.PrintStub(LogClass.ServiceSsl, new { hostName });
|
||||||
|
|
||||||
|
return ResultCode.Success;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Command(2)]
|
||||||
|
// SetVerifyOption(nn::ssl::sf::VerifyOption)
|
||||||
|
public ResultCode SetVerifyOption(ServiceCtx context)
|
||||||
|
{
|
||||||
|
VerifyOption verifyOption = (VerifyOption)context.RequestData.ReadUInt32();
|
||||||
|
|
||||||
|
Logger.Stub?.PrintStub(LogClass.ServiceSsl, new { verifyOption });
|
||||||
|
|
||||||
|
return ResultCode.Success;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Command(3)]
|
||||||
|
// SetIoMode(nn::ssl::sf::IoMode)
|
||||||
|
public ResultCode SetIoMode(ServiceCtx context)
|
||||||
|
{
|
||||||
|
IoMode ioMode = (IoMode)context.RequestData.ReadUInt32();
|
||||||
|
|
||||||
|
Logger.Stub?.PrintStub(LogClass.ServiceSsl, new { ioMode });
|
||||||
|
|
||||||
|
return ResultCode.Success;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Command(8)]
|
||||||
|
// DoHandshake()
|
||||||
|
public ResultCode DoHandshake(ServiceCtx context)
|
||||||
|
{
|
||||||
|
Logger.Stub?.PrintStub(LogClass.ServiceSsl);
|
||||||
|
|
||||||
|
return ResultCode.Success;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Command(11)]
|
||||||
|
// Write(buffer<bytes, 5>) -> u32
|
||||||
|
public ResultCode Write(ServiceCtx context)
|
||||||
|
{
|
||||||
|
long inputDataPosition = context.Request.SendBuff[0].Position;
|
||||||
|
long inputDataSize = context.Request.SendBuff[0].Size;
|
||||||
|
|
||||||
|
uint transferredSize = 0;
|
||||||
|
|
||||||
|
context.ResponseData.Write(transferredSize);
|
||||||
|
|
||||||
|
Logger.Stub?.PrintStub(LogClass.ServiceSsl);
|
||||||
|
|
||||||
|
return ResultCode.Success;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Command(17)]
|
||||||
|
// SetSessionCacheMode(nn::ssl::sf::SessionCacheMode)
|
||||||
|
public ResultCode SetSessionCacheMode(ServiceCtx context)
|
||||||
|
{
|
||||||
|
SessionCacheMode sessionCacheMode = (SessionCacheMode)context.RequestData.ReadUInt32();
|
||||||
|
|
||||||
|
Logger.Stub?.PrintStub(LogClass.ServiceSsl, new { sessionCacheMode });
|
||||||
|
|
||||||
|
return ResultCode.Success;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Command(22)]
|
||||||
|
// SetOption(b8, nn::ssl::sf::OptionType)
|
||||||
|
public ResultCode SetOption(ServiceCtx context)
|
||||||
|
{
|
||||||
|
bool optionEnabled = context.RequestData.ReadBoolean();
|
||||||
|
OptionType optionType = (OptionType)context.RequestData.ReadUInt32();
|
||||||
|
|
||||||
|
Logger.Stub?.PrintStub(LogClass.ServiceSsl, new { optionType, optionEnabled });
|
||||||
|
|
||||||
|
return ResultCode.Success;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,27 +1,62 @@
|
||||||
using Ryujinx.Common.Logging;
|
using Ryujinx.Common.Logging;
|
||||||
using System;
|
using Ryujinx.HLE.HOS.Services.Ssl.Types;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
namespace Ryujinx.HLE.HOS.Services.Ssl.SslService
|
namespace Ryujinx.HLE.HOS.Services.Ssl.SslService
|
||||||
{
|
{
|
||||||
class ISslContext : IpcService
|
class ISslContext : IpcService
|
||||||
{
|
{
|
||||||
|
private ulong _serverCertificateId;
|
||||||
|
private ulong _clientCertificateId;
|
||||||
|
|
||||||
public ISslContext(ServiceCtx context) { }
|
public ISslContext(ServiceCtx context) { }
|
||||||
|
|
||||||
|
[Command(2)]
|
||||||
|
// CreateConnection() -> object<nn::ssl::sf::ISslConnection>
|
||||||
|
public ResultCode CreateConnection(ServiceCtx context)
|
||||||
|
{
|
||||||
|
MakeObject(context, new ISslConnection());
|
||||||
|
|
||||||
|
return ResultCode.Success;
|
||||||
|
}
|
||||||
|
|
||||||
[Command(4)]
|
[Command(4)]
|
||||||
// ImportServerPki(nn::ssl::sf::CertificateFormat certificateFormat, buffer<bytes, 5> certificate) -> u64 certificateId
|
// ImportServerPki(nn::ssl::sf::CertificateFormat certificateFormat, buffer<bytes, 5> certificate) -> u64 certificateId
|
||||||
public ResultCode ImportServerPki(ServiceCtx context)
|
public ResultCode ImportServerPki(ServiceCtx context)
|
||||||
{
|
{
|
||||||
int certificateFormat = context.RequestData.ReadInt32();
|
CertificateFormat certificateFormat = (CertificateFormat)context.RequestData.ReadUInt32();
|
||||||
|
|
||||||
long certificateDataPosition = context.Request.SendBuff[0].Position;
|
long certificateDataPosition = context.Request.SendBuff[0].Position;
|
||||||
long certificateDataSize = context.Request.SendBuff[0].Size;
|
long certificateDataSize = context.Request.SendBuff[0].Size;
|
||||||
ulong certificateId = 1;
|
|
||||||
|
|
||||||
context.ResponseData.Write(certificateId);
|
context.ResponseData.Write(_serverCertificateId++);
|
||||||
|
|
||||||
Logger.Stub?.PrintStub(LogClass.ServiceSsl, new { certificateFormat, certificateDataPosition, certificateDataSize });
|
Logger.Stub?.PrintStub(LogClass.ServiceSsl, new { certificateFormat });
|
||||||
|
|
||||||
return ResultCode.Success;
|
return ResultCode.Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Command(5)]
|
||||||
|
// ImportClientPki(buffer<bytes, 5> certificate, buffer<bytes, 5> ascii_password) -> u64 certificateId
|
||||||
|
public ResultCode ImportClientPki(ServiceCtx context)
|
||||||
|
{
|
||||||
|
long certificateDataPosition = context.Request.SendBuff[0].Position;
|
||||||
|
long certificateDataSize = context.Request.SendBuff[0].Size;
|
||||||
|
|
||||||
|
long asciiPasswordDataPosition = context.Request.SendBuff[1].Position;
|
||||||
|
long asciiPasswordDataSize = context.Request.SendBuff[1].Size;
|
||||||
|
|
||||||
|
byte[] asciiPasswordData = new byte[asciiPasswordDataSize];
|
||||||
|
|
||||||
|
context.Memory.Read((ulong)asciiPasswordDataPosition, asciiPasswordData);
|
||||||
|
|
||||||
|
string asciiPassword = Encoding.ASCII.GetString(asciiPasswordData).Trim('\0');
|
||||||
|
|
||||||
|
context.ResponseData.Write(_clientCertificateId++);
|
||||||
|
|
||||||
|
Logger.Stub?.PrintStub(LogClass.ServiceSsl, new { asciiPassword });
|
||||||
|
|
||||||
|
return ResultCode.Success;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
8
Ryujinx.HLE/HOS/Services/Ssl/Types/CertificateFormat.cs
Normal file
8
Ryujinx.HLE/HOS/Services/Ssl/Types/CertificateFormat.cs
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
namespace Ryujinx.HLE.HOS.Services.Ssl.Types
|
||||||
|
{
|
||||||
|
enum CertificateFormat : uint
|
||||||
|
{
|
||||||
|
Pem = 1,
|
||||||
|
Der = 2
|
||||||
|
}
|
||||||
|
}
|
8
Ryujinx.HLE/HOS/Services/Ssl/Types/IoMode.cs
Normal file
8
Ryujinx.HLE/HOS/Services/Ssl/Types/IoMode.cs
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
namespace Ryujinx.HLE.HOS.Services.Ssl.Types
|
||||||
|
{
|
||||||
|
enum IoMode : uint
|
||||||
|
{
|
||||||
|
Blocking = 1,
|
||||||
|
NonBlocking = 2
|
||||||
|
}
|
||||||
|
}
|
10
Ryujinx.HLE/HOS/Services/Ssl/Types/OptionType.cs
Normal file
10
Ryujinx.HLE/HOS/Services/Ssl/Types/OptionType.cs
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
namespace Ryujinx.HLE.HOS.Services.Ssl.Types
|
||||||
|
{
|
||||||
|
enum OptionType : uint
|
||||||
|
{
|
||||||
|
DoNotCloseSocket,
|
||||||
|
GetServerCertChain, // 3.0.0+
|
||||||
|
SkipDefaultVerify, // 5.0.0+
|
||||||
|
EnableAlpn // 9.0.0+
|
||||||
|
}
|
||||||
|
}
|
9
Ryujinx.HLE/HOS/Services/Ssl/Types/SessionCacheMode.cs
Normal file
9
Ryujinx.HLE/HOS/Services/Ssl/Types/SessionCacheMode.cs
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
namespace Ryujinx.HLE.HOS.Services.Ssl.Types
|
||||||
|
{
|
||||||
|
enum SessionCacheMode : uint
|
||||||
|
{
|
||||||
|
None,
|
||||||
|
SessionId,
|
||||||
|
SessionTicket
|
||||||
|
}
|
||||||
|
}
|
15
Ryujinx.HLE/HOS/Services/Ssl/Types/SslVersion.cs
Normal file
15
Ryujinx.HLE/HOS/Services/Ssl/Types/SslVersion.cs
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Ryujinx.HLE.HOS.Services.Ssl.Types
|
||||||
|
{
|
||||||
|
[Flags]
|
||||||
|
enum SslVersion : uint
|
||||||
|
{
|
||||||
|
Auto = 1 << 0,
|
||||||
|
TlsV10 = 1 << 3,
|
||||||
|
TlsV11 = 1 << 4,
|
||||||
|
TlsV12 = 1 << 5,
|
||||||
|
TlsV13 = 1 << 6, // 11.0.0+
|
||||||
|
Auto2 = 1 << 24 // 11.0.0+
|
||||||
|
}
|
||||||
|
}
|
15
Ryujinx.HLE/HOS/Services/Ssl/Types/VerifyOption.cs
Normal file
15
Ryujinx.HLE/HOS/Services/Ssl/Types/VerifyOption.cs
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Ryujinx.HLE.HOS.Services.Ssl.Types
|
||||||
|
{
|
||||||
|
[Flags]
|
||||||
|
enum VerifyOption : uint
|
||||||
|
{
|
||||||
|
PeerCa = 1 << 0,
|
||||||
|
HostName = 1 << 1,
|
||||||
|
DateCheck = 1 << 2,
|
||||||
|
EvCertPartial = 1 << 3,
|
||||||
|
EvPolicyOid = 1 << 4, // 6.0.0+
|
||||||
|
EvCertFingerprint = 1 << 5 // 6.0.0+
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue