Add a new ETicket type

This commit is contained in:
Alex Barney 2020-03-17 23:45:28 -07:00
parent cd5d46c81b
commit d3df3e86fb
3 changed files with 117 additions and 1 deletions

76
src/LibHac/Es/ETicket.cs Normal file
View file

@ -0,0 +1,76 @@
using System;
using System.Runtime.InteropServices;
using LibHac.Common;
namespace LibHac.Es
{
[StructLayout(LayoutKind.Explicit, Size = 0x2C0)]
public struct ETicket
{
private const int SignatureSize = 0x200;
private const int IssuerSize = 0x40;
private const int TitleKeySize = 0x100;
private const int RightsIdSize = 0x10;
[FieldOffset(0)] private SignatureType SignatureType;
[FieldOffset(4)] private byte _signature;
[FieldOffset(0x140)] private byte _issuer;
[FieldOffset(0x180)] private byte _titleKey;
[FieldOffset(0x280)] public byte FormatVersion;
[FieldOffset(0x281)] public TitleKeyType TitleKeyType;
[FieldOffset(0x282)] public ushort TicketVersion;
[FieldOffset(0x284)] public LicenseType LicenseType;
[FieldOffset(0x285)] public byte CommonKeyId;
[FieldOffset(0x286)] public TicketProperties PropertyMask;
[FieldOffset(0x290)] public ulong TicketId;
[FieldOffset(0x298)] public ulong DeviceId;
[FieldOffset(0x2A0)] private byte _rightsId;
[FieldOffset(0x2B0)] public uint AccountId;
[FieldOffset(0x2B4)] public int SectTotalSize;
[FieldOffset(0x2B8)] public int SectHeaderOffset;
[FieldOffset(0x2BC)] public short SectNum;
[FieldOffset(0x2BE)] public short SectEntrySize;
public Span<byte> Signature => SpanHelpers.CreateSpan(ref _signature, SignatureSize);
public Span<byte> Issuer => SpanHelpers.CreateSpan(ref _issuer, IssuerSize);
public Span<byte> TitleKey => SpanHelpers.CreateSpan(ref _titleKey, TitleKeySize);
public Span<byte> RightsId => SpanHelpers.CreateSpan(ref _rightsId, RightsIdSize);
}
public enum SignatureType
{
Rsa4096Sha1 = 0x10000,
Rsa2048Sha1,
EcdsaSha1,
Rsa4096Sha256,
Rsa2048Sha256,
EcdsaSha256
}
public enum TitleKeyType : byte
{
Common,
Personalized
}
public enum LicenseType : byte
{
Permanent,
Demo,
Trial,
Rental,
Subscription,
Service
}
[Flags]
public enum TicketProperties : byte
{
PreInstall = 1 << 0,
SharedTitle = 1 << 1,
AllowAllContent = 1 << 2
}
}

View file

@ -0,0 +1,39 @@
using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using LibHac.Spl;
namespace LibHac.Es
{
public class ETicketReader
{
public ETicket Ticket;
public ETicketReader() { }
public ETicketReader(ETicket ticket)
{
Ticket = ticket;
}
public ETicketReader(ReadOnlySpan<byte> ticketData)
{
if (ticketData.Length < Unsafe.SizeOf<ETicket>())
{
throw new ArgumentException($"{nameof(ticketData)} must be at least {Unsafe.SizeOf<ETicket>()} bytes long.");
}
Ticket = Unsafe.As<byte, ETicket>(ref MemoryMarshal.GetReference(ticketData));
}
public AccessKey GetTitleKey(Keyset keyset)
{
if (Ticket.TitleKeyType == TitleKeyType.Common)
{
return Unsafe.As<byte, AccessKey>(ref MemoryMarshal.GetReference(Ticket.TitleKey));
}
return new AccessKey(CryptoOld.DecryptTitleKey(Ticket.TitleKey.ToArray(), keyset.EticketExtKeyRsa));
}
}
}

View file

@ -179,7 +179,8 @@ namespace LibHac.FsSystem
storage.GetSize(out long storageSize).ThrowIfFailure();
var arr = new byte[storageSize];
storage.CopyTo(new MemoryStorage(arr));
storage.Read(0, arr);
return arr;
}