luigoalma 4e04849860 Support for variable sized tickets
Except for cia building or loading cia just yet.
Added more checks on ticket content index, mainly due to having effects
in the ticket format itself, and are unknown still.
Ability to determine ticket size.
Verify signature with ticket's proper size.
Changes to use the new Ticket struct with the flexible array member.
2020-03-28 07:05:42 -03:00

68 lines
1.8 KiB
C

#pragma once
#include "common.h"
#define TICKET_COMMON_SIZE sizeof(TicketCommon)
#define TICKET_MINIMUM_SIZE sizeof(TicketMinimum)
#define TICKET_CDNCERT_SIZE 0x700
#define TICKET_ISSUER "Root-CA00000003-XS0000000c"
#define TICKET_ISSUER_DEV "Root-CA00000004-XS00000009"
#define TICKET_SIG_TYPE 0x00, 0x01, 0x00, 0x04 // RSA_2048 SHA256
#define TICKET_DEVKIT(tick) (strncmp((char*)tick->issuer, TICKET_ISSUER_DEV, 0x40) == 0)
// from: https://github.com/profi200/Project_CTR/blob/02159e17ee225de3f7c46ca195ff0f9ba3b3d3e4/ctrtool/tik.h#L15-L39
// all numbers in big endian
#define TICKETBASE \
u8 sig_type[4]; \
u8 signature[0x100]; \
u8 padding1[0x3C]; \
u8 issuer[0x40]; \
u8 ecdsa[0x3C]; \
u8 version; \
u8 ca_crl_version; \
u8 signer_crl_version; \
u8 titlekey[0x10]; \
u8 reserved0; \
u8 ticket_id[8]; \
u8 console_id[4]; \
u8 title_id[8]; \
u8 sys_access[2]; \
u8 ticket_version[2]; \
u8 time_mask[4]; \
u8 permit_mask[4]; \
u8 title_export; \
u8 commonkey_idx; \
u8 reserved1[0x2A]; \
u8 eshop_id[4]; \
u8 reserved2; \
u8 audit; \
u8 content_permissions[0x40]; \
u8 reserved3[2]; \
u8 timelimits[0x40]
typedef struct {
TICKETBASE;
u8 content_index[];
} __attribute__((packed, aligned(4))) Ticket;
typedef struct {
TICKETBASE;
u8 content_index[0xAC];
} __attribute__((packed, aligned(4))) TicketCommon;
// minimum allowed content_index is 0x14
typedef struct {
TICKETBASE;
u8 content_index[0x14];
} __attribute__((packed, aligned(4))) TicketMinimum;
u32 ValidateTicket(Ticket* ticket);
u32 ValidateTicketSignature(Ticket* ticket);
u32 BuildFakeTicket(Ticket* ticket, u8* title_id);
u32 GetTicketContentIndexSize(const Ticket* ticket);
u32 GetTicketSize(const Ticket* ticket);
u32 BuildTicketCert(u8* tickcert);