diff options
Diffstat (limited to 'Ryujinx.HLE/HOS/Services/Ssl/ISslService.cs')
| -rw-r--r-- | Ryujinx.HLE/HOS/Services/Ssl/ISslService.cs | 79 |
1 files changed, 78 insertions, 1 deletions
diff --git a/Ryujinx.HLE/HOS/Services/Ssl/ISslService.cs b/Ryujinx.HLE/HOS/Services/Ssl/ISslService.cs index b7811ec1..90814cf9 100644 --- a/Ryujinx.HLE/HOS/Services/Ssl/ISslService.cs +++ b/Ryujinx.HLE/HOS/Services/Ssl/ISslService.cs @@ -1,6 +1,11 @@ using Ryujinx.Common.Logging; +using Ryujinx.HLE.Exceptions; using Ryujinx.HLE.HOS.Services.Ssl.SslService; using Ryujinx.HLE.HOS.Services.Ssl.Types; +using Ryujinx.Memory; +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Services.Ssl { @@ -18,13 +23,85 @@ namespace Ryujinx.HLE.HOS.Services.Ssl SslVersion sslVersion = (SslVersion)context.RequestData.ReadUInt32(); ulong pidPlaceholder = context.RequestData.ReadUInt64(); - MakeObject(context, new ISslContext(context)); + MakeObject(context, new ISslContext(context.Request.HandleDesc.PId, sslVersion)); Logger.Stub?.PrintStub(LogClass.ServiceSsl, new { sslVersion }); return ResultCode.Success; } + private uint ComputeCertificateBufferSizeRequired(ReadOnlySpan<BuiltInCertificateManager.CertStoreEntry> entries) + { + uint totalSize = 0; + + for (int i = 0; i < entries.Length; i++) + { + totalSize += (uint)Unsafe.SizeOf<BuiltInCertificateInfo>(); + totalSize += (uint)entries[i].Data.Length; + } + + return totalSize; + } + + [CommandHipc(2)] + // GetCertificates(buffer<CaCertificateId, 5> ids) -> (u32 certificates_count, buffer<bytes, 6> certificates) + public ResultCode GetCertificates(ServiceCtx context) + { + ReadOnlySpan<CaCertificateId> ids = MemoryMarshal.Cast<byte, CaCertificateId>(context.Memory.GetSpan(context.Request.SendBuff[0].Position, (int)context.Request.SendBuff[0].Size)); + + if (!BuiltInCertificateManager.Instance.TryGetCertificates(ids, out BuiltInCertificateManager.CertStoreEntry[] entries)) + { + throw new InvalidOperationException(); + } + + if (ComputeCertificateBufferSizeRequired(entries) > context.Request.ReceiveBuff[0].Size) + { + return ResultCode.InvalidCertBufSize; + } + + using (WritableRegion region = context.Memory.GetWritableRegion(context.Request.ReceiveBuff[0].Position, (int)context.Request.ReceiveBuff[0].Size)) + { + Span<byte> rawData = region.Memory.Span; + Span<BuiltInCertificateInfo> infos = MemoryMarshal.Cast<byte, BuiltInCertificateInfo>(rawData)[..entries.Length]; + Span<byte> certificatesData = rawData[(Unsafe.SizeOf<BuiltInCertificateInfo>() * entries.Length)..]; + + for (int i = 0; i < infos.Length; i++) + { + entries[i].Data.CopyTo(certificatesData); + + infos[i] = new BuiltInCertificateInfo + { + Id = entries[i].Id, + Status = entries[i].Status, + CertificateDataSize = (ulong)entries[i].Data.Length, + CertificateDataOffset = (ulong)(rawData.Length - certificatesData.Length) + }; + + certificatesData = certificatesData[entries[i].Data.Length..]; + } + } + + context.ResponseData.Write(entries.Length); + + return ResultCode.Success; + } + + [CommandHipc(3)] + // GetCertificateBufSize(buffer<CaCertificateId, 5> ids) -> u32 buffer_size; + public ResultCode GetCertificateBufSize(ServiceCtx context) + { + ReadOnlySpan<CaCertificateId> ids = MemoryMarshal.Cast<byte, CaCertificateId>(context.Memory.GetSpan(context.Request.SendBuff[0].Position, (int)context.Request.SendBuff[0].Size)); + + if (!BuiltInCertificateManager.Instance.TryGetCertificates(ids, out BuiltInCertificateManager.CertStoreEntry[] entries)) + { + throw new InvalidOperationException(); + } + + context.ResponseData.Write(ComputeCertificateBufferSizeRequired(entries)); + + return ResultCode.Success; + } + [CommandHipc(5)] // SetInterfaceVersion(u32) public ResultCode SetInterfaceVersion(ServiceCtx context) |
