aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.HLE/HOS/Services/Ssl/ISslService.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Ryujinx.HLE/HOS/Services/Ssl/ISslService.cs')
-rw-r--r--Ryujinx.HLE/HOS/Services/Ssl/ISslService.cs79
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)