From b662a26c7e2b66d916986b1ed9ffae3b918619d1 Mon Sep 17 00:00:00 2001 From: Ac_K Date: Tue, 13 Apr 2021 03:04:18 +0200 Subject: [PATCH] nifm/ssl: Implement GetCurrentNetworkProfile and stub Ssl Service (#2186) * nifm/ssl: Implement GetCurrentNetworkProfile and stub Ssl Service * remove InterfaceVersion --- .../Nifm/StaticService/IGeneralService.cs | 47 ++++++-- .../Nifm/StaticService/Types/DnsSetting.cs | 15 ++- .../Nifm/StaticService/Types/IpSettingData.cs | 13 ++ .../StaticService/Types/NetworkProfileData.cs | 17 +++ .../Nifm/StaticService/Types/ProxySetting.cs | 27 +++++ .../Types/WirelessSettingData.cs | 15 +++ .../HOS/Services/Sockets/Nsd/IManager.cs | 6 +- .../Sockets/Nsd/Manager/FqdnResolver.cs | 34 ++---- Ryujinx.HLE/HOS/Services/Ssl/ISslService.cs | 16 ++- .../Services/Ssl/SslService/ISslConnection.cs | 113 ++++++++++++++++++ .../Services/Ssl/SslService/ISslContext.cs | 63 +++++++--- .../Services/Ssl/Types/CertificateFormat.cs | 8 ++ Ryujinx.HLE/HOS/Services/Ssl/Types/IoMode.cs | 8 ++ .../HOS/Services/Ssl/Types/OptionType.cs | 10 ++ .../Services/Ssl/Types/SessionCacheMode.cs | 9 ++ .../HOS/Services/Ssl/Types/SslVersion.cs | 15 +++ .../HOS/Services/Ssl/Types/VerifyOption.cs | 15 +++ 17 files changed, 375 insertions(+), 56 deletions(-) create mode 100644 Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/IpSettingData.cs create mode 100644 Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/NetworkProfileData.cs create mode 100644 Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/ProxySetting.cs create mode 100644 Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/WirelessSettingData.cs create mode 100644 Ryujinx.HLE/HOS/Services/Ssl/SslService/ISslConnection.cs create mode 100644 Ryujinx.HLE/HOS/Services/Ssl/Types/CertificateFormat.cs create mode 100644 Ryujinx.HLE/HOS/Services/Ssl/Types/IoMode.cs create mode 100644 Ryujinx.HLE/HOS/Services/Ssl/Types/OptionType.cs create mode 100644 Ryujinx.HLE/HOS/Services/Ssl/Types/SessionCacheMode.cs create mode 100644 Ryujinx.HLE/HOS/Services/Ssl/Types/SslVersion.cs create mode 100644 Ryujinx.HLE/HOS/Services/Ssl/Types/VerifyOption.cs diff --git a/Ryujinx.HLE/HOS/Services/Nifm/StaticService/IGeneralService.cs b/Ryujinx.HLE/HOS/Services/Nifm/StaticService/IGeneralService.cs index 944186d32..2614a54ca 100644 --- a/Ryujinx.HLE/HOS/Services/Nifm/StaticService/IGeneralService.cs +++ b/Ryujinx.HLE/HOS/Services/Nifm/StaticService/IGeneralService.cs @@ -2,8 +2,11 @@ using Ryujinx.Common; using Ryujinx.Common.Logging; using Ryujinx.HLE.HOS.Services.Nifm.StaticService.GeneralService; using Ryujinx.HLE.HOS.Services.Nifm.StaticService.Types; +using Ryujinx.HLE.Utilities; using System; using System.Net.NetworkInformation; +using System.Runtime.CompilerServices; +using System.Text; namespace Ryujinx.HLE.HOS.Services.Nifm.StaticService { @@ -51,6 +54,38 @@ namespace Ryujinx.HLE.HOS.Services.Nifm.StaticService return ResultCode.Success; } + [Command(5)] + // GetCurrentNetworkProfile() -> buffer + 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 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)] // GetCurrentIpAddress() -> nn::nifm::IpV4Address public ResultCode GetCurrentIpAddress(ServiceCtx context) @@ -75,7 +110,7 @@ namespace Ryujinx.HLE.HOS.Services.Nifm.StaticService { (IPInterfaceProperties interfaceProperties, UnicastIPAddressInformation unicastAddress) = GetLocalInterface(); - if (interfaceProperties == null) + if (interfaceProperties == null || unicastAddress == null) { return ResultCode.NoInternetConnection; } @@ -138,11 +173,11 @@ namespace Ryujinx.HLE.HOS.Services.Nifm.StaticService foreach (NetworkInterface adapter in interfaces) { // 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(); - if (properties.GatewayAddresses.Count > 0 && properties.DnsAddresses.Count > 1) + if (properties.GatewayAddresses.Count > 0 && properties.DnsAddresses.Count > 0) { 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; - } } } diff --git a/Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/DnsSetting.cs b/Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/DnsSetting.cs index 96f99dfa7..d6381fba6 100644 --- a/Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/DnsSetting.cs +++ b/Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/DnsSetting.cs @@ -14,8 +14,17 @@ namespace Ryujinx.HLE.HOS.Services.Nifm.StaticService.Types public DnsSetting(IPInterfaceProperties interfaceProperties) { IsDynamicDnsEnabled = interfaceProperties.IsDynamicDnsEnabled; - PrimaryDns = new IpV4Address(interfaceProperties.DnsAddresses[0]); - SecondaryDns = new IpV4Address(interfaceProperties.DnsAddresses[1]); + + if (interfaceProperties.DnsAddresses.Count == 0) + { + PrimaryDns = new IpV4Address(); + SecondaryDns = new IpV4Address(); + } + else + { + PrimaryDns = new IpV4Address(interfaceProperties.DnsAddresses[0]); + SecondaryDns = new IpV4Address(interfaceProperties.DnsAddresses[interfaceProperties.DnsAddresses.Count > 1 ? 1 : 0]); + } } } -} +} \ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/IpSettingData.cs b/Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/IpSettingData.cs new file mode 100644 index 000000000..8ffe824c8 --- /dev/null +++ b/Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/IpSettingData.cs @@ -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; + } +} \ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/NetworkProfileData.cs b/Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/NetworkProfileData.cs new file mode 100644 index 000000000..3c86aed50 --- /dev/null +++ b/Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/NetworkProfileData.cs @@ -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 Name; + public Array4 Unknown; + public WirelessSettingData WirelessSettingData; + public byte Padding; + } +} \ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/ProxySetting.cs b/Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/ProxySetting.cs new file mode 100644 index 000000000..827520f15 --- /dev/null +++ b/Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/ProxySetting.cs @@ -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 User; + public Array32 Pass; + private byte _padding2; + + [StructLayout(LayoutKind.Sequential, Size = 0x64)] + private struct NameStruct { } + + public Span Name => SpanHelpers.AsSpan(ref _name); + } +} \ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/WirelessSettingData.cs b/Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/WirelessSettingData.cs new file mode 100644 index 000000000..8aa122c7d --- /dev/null +++ b/Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/WirelessSettingData.cs @@ -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 Ssid; + public Array3 Unknown; + public Array64 Passphrase1; + public byte Passphrase2; + } +} \ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Sockets/Nsd/IManager.cs b/Ryujinx.HLE/HOS/Services/Sockets/Nsd/IManager.cs index 90f22dfb4..3dc6b245a 100644 --- a/Ryujinx.HLE/HOS/Services/Sockets/Nsd/IManager.cs +++ b/Ryujinx.HLE/HOS/Services/Sockets/Nsd/IManager.cs @@ -132,7 +132,8 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Nsd // Resolve(buffer, 0x15>) -> buffer, 0x16> 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); @@ -147,7 +148,8 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Nsd // ResolveEx(buffer, 0x15>) -> (u32, buffer, 0x16>) 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); diff --git a/Ryujinx.HLE/HOS/Services/Sockets/Nsd/Manager/FqdnResolver.cs b/Ryujinx.HLE/HOS/Services/Sockets/Nsd/Manager/FqdnResolver.cs index 3bdf15a1a..0c5dac172 100644 --- a/Ryujinx.HLE/HOS/Services/Sockets/Nsd/Manager/FqdnResolver.cs +++ b/Ryujinx.HLE/HOS/Services/Sockets/Nsd/Manager/FqdnResolver.cs @@ -73,30 +73,19 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Nsd.Manager return ResultCode.SettingsNotLoaded; } - switch (address) + resolvedAddress = address switch { - case "e97b8a9d672e4ce4845ec6947cd66ef6-sb-api.accounts.nintendo.com": // dp1 environment - resolvedAddress = "e97b8a9d672e4ce4845ec6947cd66ef6-sb.baas.nintendo.com"; - break; - case "api.accounts.nintendo.com": // dp1 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; + "e97b8a9d672e4ce4845ec6947cd66ef6-sb-api.accounts.nintendo.com" => "e97b8a9d672e4ce4845ec6947cd66ef6-sb.baas.nintendo.com", // dp1 environment + "api.accounts.nintendo.com" => "e0d67c509fb203858ebcb2fe3f88c2aa.baas.nintendo.com", // dp1 environment + "e97b8a9d672e4ce4845ec6947cd66ef6-sb.accounts.nintendo.com" => "e97b8a9d672e4ce4845ec6947cd66ef6-sb.baas.nintendo.com", // lp1 environment + "accounts.nintendo.com" => "e0d67c509fb203858ebcb2fe3f88c2aa.baas.nintendo.com", // lp1 environment /* - // TODO: Determine fields of the struct. - case "": // + 0xEB8 || + 0x2BE8 - resolvedAddress = ""; // + 0xEB8 + 0x300 || + 0x2BE8 + 0x300 - break; + // TODO: Determine fields of the struct. + this + 0xEB8 => this + 0xEB8 + 0x300 + this + 0x2BE8 => this + 0x2BE8 + 0x300 */ - default: - resolvedAddress = address; - break; - } + _ => address, + }; } else { @@ -108,7 +97,8 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Nsd.Manager 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]; diff --git a/Ryujinx.HLE/HOS/Services/Ssl/ISslService.cs b/Ryujinx.HLE/HOS/Services/Ssl/ISslService.cs index 7cc153200..b99e7b56f 100644 --- a/Ryujinx.HLE/HOS/Services/Ssl/ISslService.cs +++ b/Ryujinx.HLE/HOS/Services/Ssl/ISslService.cs @@ -1,24 +1,27 @@ using Ryujinx.Common.Logging; using Ryujinx.HLE.HOS.Services.Ssl.SslService; +using Ryujinx.HLE.HOS.Services.Ssl.Types; namespace Ryujinx.HLE.HOS.Services.Ssl { [Service("ssl")] 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) { } [Command(0)] // CreateContext(nn::ssl::sf::SslVersion, u64, pid) -> object public ResultCode CreateContext(ServiceCtx context) { - int sslVersion = context.RequestData.ReadInt32(); - long unknown = context.RequestData.ReadInt64(); - - Logger.Stub?.PrintStub(LogClass.ServiceSsl, new { sslVersion, unknown }); + SslVersion sslVersion = (SslVersion)context.RequestData.ReadUInt32(); + ulong pidPlaceholder = context.RequestData.ReadUInt64(); MakeObject(context, new ISslContext(context)); + Logger.Stub?.PrintStub(LogClass.ServiceSsl, new { sslVersion }); + return ResultCode.Success; } @@ -26,9 +29,10 @@ namespace Ryujinx.HLE.HOS.Services.Ssl // SetInterfaceVersion(u32) 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; } diff --git a/Ryujinx.HLE/HOS/Services/Ssl/SslService/ISslConnection.cs b/Ryujinx.HLE/HOS/Services/Ssl/SslService/ISslConnection.cs new file mode 100644 index 000000000..d039154c5 --- /dev/null +++ b/Ryujinx.HLE/HOS/Services/Ssl/SslService/ISslConnection.cs @@ -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) + 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) -> 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; + } + } +} \ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Ssl/SslService/ISslContext.cs b/Ryujinx.HLE/HOS/Services/Ssl/SslService/ISslContext.cs index b9ca92b04..5341f3603 100644 --- a/Ryujinx.HLE/HOS/Services/Ssl/SslService/ISslContext.cs +++ b/Ryujinx.HLE/HOS/Services/Ssl/SslService/ISslContext.cs @@ -1,27 +1,62 @@ using Ryujinx.Common.Logging; -using System; +using Ryujinx.HLE.HOS.Services.Ssl.Types; +using System.Text; namespace Ryujinx.HLE.HOS.Services.Ssl.SslService { class ISslContext : IpcService { + private ulong _serverCertificateId; + private ulong _clientCertificateId; + public ISslContext(ServiceCtx context) { } - - [Command(4)] - // ImportServerPki(nn::ssl::sf::CertificateFormat certificateFormat, buffer certificate) -> u64 certificateId - public ResultCode ImportServerPki(ServiceCtx context) + + [Command(2)] + // CreateConnection() -> object + public ResultCode CreateConnection(ServiceCtx context) { - int certificateFormat = context.RequestData.ReadInt32(); - long certificateDataPosition = context.Request.SendBuff[0].Position; - long certificateDataSize = context.Request.SendBuff[0].Size; - ulong certificateId = 1; - - context.ResponseData.Write(certificateId); - - Logger.Stub?.PrintStub(LogClass.ServiceSsl, new { certificateFormat, certificateDataPosition, certificateDataSize }); + MakeObject(context, new ISslConnection()); return ResultCode.Success; } + [Command(4)] + // ImportServerPki(nn::ssl::sf::CertificateFormat certificateFormat, buffer certificate) -> u64 certificateId + public ResultCode ImportServerPki(ServiceCtx context) + { + CertificateFormat certificateFormat = (CertificateFormat)context.RequestData.ReadUInt32(); + + long certificateDataPosition = context.Request.SendBuff[0].Position; + long certificateDataSize = context.Request.SendBuff[0].Size; + + context.ResponseData.Write(_serverCertificateId++); + + Logger.Stub?.PrintStub(LogClass.ServiceSsl, new { certificateFormat }); + + return ResultCode.Success; + } + + [Command(5)] + // ImportClientPki(buffer certificate, buffer 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; + } } -} +} \ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Ssl/Types/CertificateFormat.cs b/Ryujinx.HLE/HOS/Services/Ssl/Types/CertificateFormat.cs new file mode 100644 index 000000000..1d80f739e --- /dev/null +++ b/Ryujinx.HLE/HOS/Services/Ssl/Types/CertificateFormat.cs @@ -0,0 +1,8 @@ +namespace Ryujinx.HLE.HOS.Services.Ssl.Types +{ + enum CertificateFormat : uint + { + Pem = 1, + Der = 2 + } +} \ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Ssl/Types/IoMode.cs b/Ryujinx.HLE/HOS/Services/Ssl/Types/IoMode.cs new file mode 100644 index 000000000..1cd06d6de --- /dev/null +++ b/Ryujinx.HLE/HOS/Services/Ssl/Types/IoMode.cs @@ -0,0 +1,8 @@ +namespace Ryujinx.HLE.HOS.Services.Ssl.Types +{ + enum IoMode : uint + { + Blocking = 1, + NonBlocking = 2 + } +} \ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Ssl/Types/OptionType.cs b/Ryujinx.HLE/HOS/Services/Ssl/Types/OptionType.cs new file mode 100644 index 000000000..3673200a4 --- /dev/null +++ b/Ryujinx.HLE/HOS/Services/Ssl/Types/OptionType.cs @@ -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+ + } +} \ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Ssl/Types/SessionCacheMode.cs b/Ryujinx.HLE/HOS/Services/Ssl/Types/SessionCacheMode.cs new file mode 100644 index 000000000..cec7b745e --- /dev/null +++ b/Ryujinx.HLE/HOS/Services/Ssl/Types/SessionCacheMode.cs @@ -0,0 +1,9 @@ +namespace Ryujinx.HLE.HOS.Services.Ssl.Types +{ + enum SessionCacheMode : uint + { + None, + SessionId, + SessionTicket + } +} \ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Ssl/Types/SslVersion.cs b/Ryujinx.HLE/HOS/Services/Ssl/Types/SslVersion.cs new file mode 100644 index 000000000..a8897802a --- /dev/null +++ b/Ryujinx.HLE/HOS/Services/Ssl/Types/SslVersion.cs @@ -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+ + } +} \ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Ssl/Types/VerifyOption.cs b/Ryujinx.HLE/HOS/Services/Ssl/Types/VerifyOption.cs new file mode 100644 index 000000000..d25bb6c34 --- /dev/null +++ b/Ryujinx.HLE/HOS/Services/Ssl/Types/VerifyOption.cs @@ -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+ + } +} \ No newline at end of file