From c8f510188c5a81c4c4a29f269126abae2ed22fba Mon Sep 17 00:00:00 2001 From: zhupengfei Date: Mon, 3 Aug 2020 22:04:43 +0800 Subject: [PATCH] core/ncch: Add ticket Added structure and fake ticket building (from GodMode9) --- src/core/CMakeLists.txt | 2 ++ src/core/ncch/ticket.cpp | 39 ++++++++++++++++++++++++++++++ src/core/ncch/ticket.h | 52 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 93 insertions(+) create mode 100644 src/core/ncch/ticket.cpp create mode 100644 src/core/ncch/ticket.h diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 8765367..f8291f1 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -17,6 +17,8 @@ add_library(core STATIC ncch/seed_db.h ncch/smdh.cpp ncch/smdh.h + ncch/ticket.cpp + ncch/ticket.h ncch/title_metadata.cpp ncch/title_metadata.h quick_decryptor.cpp diff --git a/src/core/ncch/ticket.cpp b/src/core/ncch/ticket.cpp new file mode 100644 index 0000000..ae52f31 --- /dev/null +++ b/src/core/ncch/ticket.cpp @@ -0,0 +1,39 @@ +// Copyright 2020 Pengfei Zhu +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include +#include +#include "core/ncch/ticket.h" + +namespace Core { + +constexpr std::string_view TicketIssuer = "Root-CA00000003-XS0000000c"; + +// TODO: Make use of this? +constexpr std::string_view TicketIssuerDev = "Root-CA00000004-XS00000009"; + +// From GodMode9 +constexpr std::array TicketContentIndex{ + {0x00, 0x01, 0x00, 0x14, 0x00, 0x00, 0x00, 0xAC, 0x00, 0x00, 0x00, 0x14, 0x00, 0x01, 0x00, + 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x84, 0x00, 0x00, 0x00, 0x84, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}; + +// Values taken from GodMode9 +Ticket BuildFakeTicket(u64 title_id) { + Ticket ticket{}; + ticket.signature_type = 0x10004; // RSA_2048 SHA256 + std::memset(ticket.signature.data(), 0xFF, ticket.signature.size()); + std::memcpy(ticket.issuer.data(), TicketIssuer.data(), TicketIssuer.size()); + std::memset(ticket.ecc_public_key.data(), 0xFF, ticket.ecc_public_key.size()); + ticket.version = 0x01; + std::memset(ticket.title_key.data(), 0xFF, ticket.title_key.size()); + ticket.title_id = title_id; + ticket.common_key_index = 0x00; + ticket.audit = 0x01; + std::memset(ticket.content_index.data(), 0xFF, ticket.content_index.size()); + std::memcpy(ticket.content_index.data(), TicketContentIndex.data(), TicketContentIndex.size()); + return ticket; +} + +} // namespace Core diff --git a/src/core/ncch/ticket.h b/src/core/ncch/ticket.h new file mode 100644 index 0000000..adc816c --- /dev/null +++ b/src/core/ncch/ticket.h @@ -0,0 +1,52 @@ +// Copyright 2018 Citra Emulator Project / 2020 Pengfei Zhu +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include +#include +#include "common/common_funcs.h" +#include "common/common_types.h" +#include "common/swap.h" + +namespace Core { + +/** + * Structure of the ticket. + * The ticket we are using is RSA_2048 SHA256. + */ +#pragma pack(push, 1) +struct Ticket { + u32_be signature_type; + std::array signature; + INSERT_PADDING_BYTES(0x3C); + std::array issuer; + std::array ecc_public_key; + u8 version; + u8 ca_crl_version; + u8 signer_crl_version; + std::array title_key; + INSERT_PADDING_BYTES(1); + u64_be ticket_id; + u32_be console_id; + u64_be title_id; + INSERT_PADDING_BYTES(2); + u16_be ticket_title_version; + INSERT_PADDING_BYTES(8); + u8 license_type; + u8 common_key_index; + INSERT_PADDING_BYTES(0x2A); + u32_be eshop_account_id; + INSERT_PADDING_BYTES(1); + u8 audit; + INSERT_PADDING_BYTES(0x42); + std::array limits; + std::array content_index; +}; +static_assert(sizeof(Ticket) == 0x350, "Ticket size is wrong"); +#pragma pack(pop) + +Ticket BuildFakeTicket(u64 title_id); + +} // namespace Core