Skip to content

Commit

Permalink
Refactor verification process, update ticket structure and improve re…
Browse files Browse the repository at this point in the history
…ader
  • Loading branch information
jvyden committed Jul 24, 2023
1 parent e8c9cc9 commit 3278fa8
Show file tree
Hide file tree
Showing 11 changed files with 118 additions and 66 deletions.
2 changes: 1 addition & 1 deletion NPTicket.Test/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@

Console.WriteLine(JsonSerializer.Serialize(ticket));

TicketVerifier verifier = new(ticket, RpcnSigningKey.Instance);
TicketVerifier verifier = new(ticketData, ticket, RpcnSigningKey.Instance);
Console.WriteLine(JsonSerializer.Serialize(verifier));
Console.WriteLine(verifier.IsTicketValid());
41 changes: 30 additions & 11 deletions NPTicket/Reader/TicketReader.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
using System.Buffers.Binary;
using System.Text;
using NPTicket.Types;
using NPTicket.Verification;

namespace NPTicket.Reader;

Expand Down Expand Up @@ -33,31 +32,51 @@ internal ushort ReadTicketHeader()
return ReadUInt16(); // Ticket length
}

internal TicketSection ReadTicketSectionHeader()
internal TicketDataSection ReadTicketSectionHeader()
{
this.ReadByte(); // Skip first byte of type (which is a short)

TicketSectionType type = (TicketSectionType)this.ReadByte();
TicketDataSectionType type = (TicketDataSectionType)this.ReadByte();
ushort length = this.ReadUInt16();
long position = this.BaseStream.Position;

return new TicketSection(type, length, (uint)position);
return new TicketDataSection(type, length, position);
}

private TicketDataHeader ReadTicketDataHeader() => new(ReadUInt16(), ReadUInt16());
private TicketData ReadTicketData(TicketDataType expectedType)
{
TicketData data = new TicketData((TicketDataType)ReadUInt16(), ReadUInt16());
if (data.Type != expectedType && expectedType != TicketDataType.Empty)
throw new FormatException($"Expected data type to be {expectedType}, was really {data.Type} ({(int)data.Type})");

return data;
}

private byte[] ReadTicketByteArray() => ReadBytes(ReadTicketDataHeader().Length);
internal string ReadTicketString() => Encoding.Default.GetString(ReadTicketByteArray()).TrimEnd('\0');
internal byte[] ReadTicketBinaryData(TicketDataType type = TicketDataType.Binary)
=> ReadBytes(ReadTicketData(type).Length);
internal string ReadTicketStringData(TicketDataType type = TicketDataType.String)
=> Encoding.Default.GetString(ReadTicketBinaryData(type)).TrimEnd('\0');

internal uint ReadTicketUInt32()
internal uint ReadTicketUInt32Data()
{
ReadTicketDataHeader();
ReadTicketData(TicketDataType.UInt32);
return ReadUInt32();
}

internal ulong ReadTicketUInt64()
internal ulong ReadTicketUInt64Data()
{
ReadTicketDataHeader();
ReadTicketData(TicketDataType.UInt64);
return ReadUInt64();
}

internal DateTimeOffset ReadTicketTimestampData()
{
ReadTicketData(TicketDataType.Timestamp);
return DateTimeOffset.FromUnixTimeMilliseconds((long)ReadUInt64());
}

internal void SkipTicketEmptyData(int sections = 1)
{
for (int i = 0; i < sections; i++) ReadTicketData(TicketDataType.Empty);
}
}
44 changes: 30 additions & 14 deletions NPTicket/Ticket.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ private Ticket() {}
public string SerialId { get; set; }
public uint IssuerId { get; set; }

public ulong IssuedDate { get; set; }
public ulong ExpiryDate { get; set; }
public DateTimeOffset IssuedDate { get; set; }
public DateTimeOffset ExpiryDate { get; set; }

public ulong UserId { get; set; }
public string Username { get; set; }
Expand All @@ -38,7 +38,10 @@ private Ticket() {}

public uint Status { get; set; }
public ushort TicketLength { get; set; }
public TicketSection BodySection { get; set; }
public TicketDataSection BodySection { get; set; }

public string SignatureIdentifier { get; set; }
public byte[] SignatureData { get; set; }

// TODO: Use GeneratedRegex, this is not in netstandard yet
private static readonly Regex ServiceIdRegex = new("(?<=-)[A-Z0-9]{9}(?=_)", RegexOptions.Compiled);
Expand Down Expand Up @@ -68,30 +71,43 @@ public static Ticket ReadFromStream(Stream stream)

ticket.BodySection = reader.ReadTicketSectionHeader();

if (ticket.BodySection.Type != TicketSectionType.Body)
if (ticket.BodySection.Type != TicketDataSectionType.Body)
{
throw new FormatException($"Expected first section to be {nameof(TicketSectionType.Body)}, " +
throw new FormatException($"Expected first section to be {nameof(TicketDataSectionType.Body)}, " +
$"was really {ticket.BodySection.Type} ({(int)ticket.BodySection.Type})");
}

ticket.SerialId = reader.ReadTicketString();
ticket.SerialId = reader.ReadTicketStringData(TicketDataType.Binary);

ticket.IssuerId = reader.ReadTicketUInt32();
ticket.IssuerId = reader.ReadTicketUInt32Data();

ticket.IssuedDate = reader.ReadTicketUInt64();
ticket.ExpiryDate = reader.ReadTicketUInt64();
ticket.IssuedDate = reader.ReadTicketTimestampData();
ticket.ExpiryDate = reader.ReadTicketTimestampData();

ticket.UserId = reader.ReadTicketUInt64();
ticket.Username = reader.ReadTicketString();
ticket.UserId = reader.ReadTicketUInt64Data();
ticket.Username = reader.ReadTicketStringData();

ticket.Country = reader.ReadTicketString(); // No I am not going to brazil
ticket.Domain = reader.ReadTicketString();
ticket.Country = reader.ReadTicketStringData(TicketDataType.Binary); // No I am not going to brazil
ticket.Domain = reader.ReadTicketStringData();

ticket.ServiceId = reader.ReadTicketString();
ticket.ServiceId = reader.ReadTicketStringData(TicketDataType.Binary);
ticket.TitleId = ServiceIdRegex.Matches(ticket.ServiceId)[0].ToString();

ticket.Status = reader.ReadUInt32();

// Skip padding section in ticket
reader.SkipTicketEmptyData(3);

TicketDataSection footer = reader.ReadTicketSectionHeader();
if (footer.Type != TicketDataSectionType.Footer)
{
throw new FormatException($"Expected last section to be {nameof(TicketDataSectionType.Footer)}, " +
$"was really {footer.Type} ({(int)footer.Type})");
}

ticket.SignatureIdentifier = reader.ReadTicketStringData(TicketDataType.Binary);
ticket.SignatureData = reader.ReadTicketBinaryData();

return ticket;
}
}
13 changes: 13 additions & 0 deletions NPTicket/Types/TicketData.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
namespace NPTicket.Types;

public readonly struct TicketData
{
public readonly TicketDataType Type;
public readonly ushort Length;

public TicketData(TicketDataType type, ushort length)
{
Type = type;
Length = length;
}
}
13 changes: 0 additions & 13 deletions NPTicket/Types/TicketDataHeader.cs

This file was deleted.

15 changes: 15 additions & 0 deletions NPTicket/Types/TicketDataSection.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
namespace NPTicket.Types;

public readonly struct TicketDataSection
{
public TicketDataSectionType Type { get; }
public ushort Length { get; }
public int Position { get; }

public TicketDataSection(TicketDataSectionType type, ushort length, long position)
{
Type = type;
Length = length;
Position = (int)position;
}
}
8 changes: 8 additions & 0 deletions NPTicket/Types/TicketDataSectionType.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace NPTicket.Types;

public enum TicketDataSectionType : byte
{
Body = 0,

Footer = 2,
}
13 changes: 13 additions & 0 deletions NPTicket/Types/TicketDataType.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
namespace NPTicket.Types;

public enum TicketDataType : ushort
{
Empty = 0,
UInt32 = 1,
UInt64 = 2,

String = 4,

Timestamp = 7,
Binary = 8,
}
15 changes: 0 additions & 15 deletions NPTicket/Verification/TicketSection.cs

This file was deleted.

6 changes: 0 additions & 6 deletions NPTicket/Verification/TicketSectionType.cs

This file was deleted.

14 changes: 8 additions & 6 deletions NPTicket/Verification/TicketVerifier.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,13 @@ namespace NPTicket.Verification;

public class TicketVerifier
{
private Ticket _ticket;
// private ECPublicKeyParameters _publicKey;
private ISigner _signer;
private readonly Ticket _ticket;
private readonly byte[] _ticketData;
private readonly ISigner _signer;

public TicketVerifier(Ticket ticket, ITicketSigningKey key)
public TicketVerifier(byte[] ticketData, Ticket ticket, ITicketSigningKey key)
{
this._ticketData = ticketData;
this._ticket = ticket;

X9ECParameters xParams = ECNamedCurveTable.GetByName(key.CurveTable);
Expand All @@ -23,11 +24,12 @@ public TicketVerifier(Ticket ticket, ITicketSigningKey key)

ECPublicKeyParameters publicKey = new ECPublicKeyParameters(ecPoint, domainParams);
this._signer = SignerUtilities.GetSigner(key.HashAlgorithm + "withECDSA");
_signer.Init(false, publicKey);
this._signer.Init(false, publicKey);
}

public bool IsTicketValid()
{
return false;
this._signer.BlockUpdate(this._ticketData, this._ticket.BodySection.Position, this._ticket.BodySection.Length);
return this._signer.VerifySignature(this._ticketData);
}
}

0 comments on commit 3278fa8

Please sign in to comment.