Better certificate chain reading

This commit is contained in:
Matt Nadareski
2021-09-27 10:42:54 -07:00
parent bbbf71a603
commit 2779f5ef72
3 changed files with 43 additions and 6 deletions

View File

@@ -101,10 +101,9 @@ namespace NDecrypt.N3DS.Headers
header.ContentSize = reader.ReadInt64();
header.CertificateChain = new Certificate[3];
for (int i = 0; i < 3; i++)
{
header.CertificateChain[i] = Certificate.Read(reader);
}
header.CertificateChain[0] = Certificate.Read(reader); // CA
header.CertificateChain[1] = Certificate.Read(reader); // Ticket
header.CertificateChain[2] = Certificate.Read(reader); // TMD
header.Ticket = Ticket.Read(reader, header.TicketSize);
header.TMDFileData = TitleMetadata.Read(reader, header.TMDFileSize);

View File

@@ -149,6 +149,13 @@ namespace NDecrypt.N3DS.Headers
/// </remarks>
public byte[] Limits { get; private set; }
/// <summary>
/// The Content Index of a ticket has its own size defined within itself,
/// with seemingly a minimal of 20 bytes, the second u32 in big endian defines
/// the full value of X.
/// </summary>
public int ContentIndexSize { get; private set; }
/// <summary>
/// Content Index
/// </summary>
@@ -159,6 +166,14 @@ namespace NDecrypt.N3DS.Headers
/// </remarks>
public byte[] ContentIndex { get; private set; }
/// <summary>
/// Certificate chain
/// </summary>
/// <remarks>
/// https://www.3dbrew.org/wiki/Ticket#Certificate_Chain
/// </remarks>
public Certificate[] CertificateChain { get; set; }
/// <summary>
/// Read from a stream and get ticket, if possible
/// </summary>
@@ -214,9 +229,17 @@ namespace NDecrypt.N3DS.Headers
tk.Audit = reader.ReadByte();
tk.Reserved6 = reader.ReadBytes(0x42);
tk.Limits = reader.ReadBytes(0x40);
reader.ReadBytes(4);
tk.ContentIndexSize = reader.ReadInt32();
reader.BaseStream.Seek(-8, SeekOrigin.Current);
tk.ContentIndex = reader.ReadBytes(tk.ContentIndexSize);
if (ticketSize - 0x164 > 0)
tk.ContentIndex = reader.ReadBytes(ticketSize - 0x164);
if (ticketSize - (0x164 + tk.ContentIndexSize) > 0)
{
tk.CertificateChain = new Certificate[2];
tk.CertificateChain[0] = Certificate.Read(reader); // Ticket
tk.CertificateChain[1] = Certificate.Read(reader); // CA
}
return tk;
}

View File

@@ -136,6 +136,14 @@ namespace NDecrypt.N3DS.Headers
/// </summary>
public ContentChunkRecord[] ContentChunkRecords { get; private set; }
/// <summary>
/// Certificate chain
/// </summary>
/// <remarks>
/// https://www.3dbrew.org/wiki/Title_metadata#Certificate_Chain
/// </remarks>
public Certificate[] CertificateChain { get; set; }
/// <summary>
/// Read from a stream and get ticket metadata, if possible
/// </summary>
@@ -203,6 +211,13 @@ namespace NDecrypt.N3DS.Headers
tm.ContentChunkRecords[i] = ContentChunkRecord.Read(reader);
}
if (metadataSize - (0xC4 + (64 * 0x24) + (tm.ContentCount * 0x30)) > 0)
{
tm.CertificateChain = new Certificate[2];
tm.CertificateChain[0] = Certificate.Read(reader); // TMD
tm.CertificateChain[1] = Certificate.Read(reader); // CA
}
return tm;
}
catch