Improve ticket searching functions

This is applies to encTitlekeys.db / decTitlekeys.bin builders as well as to to legit CIA building
This commit is contained in:
d0k3 2020-10-28 00:00:18 +01:00
parent 355519285a
commit 145bf6de54
3 changed files with 41 additions and 85 deletions

View File

@ -737,6 +737,7 @@ u32 ReadTicketFromDB(const char* path, const u8* title_id, Ticket** ticket) {
TicketEntry* te = NULL; TicketEntry* te = NULL;
u32 entry_size; u32 entry_size;
*ticket = NULL;
if (fvx_open(&file, path, FA_READ | FA_OPEN_EXISTING) != FR_OK) if (fvx_open(&file, path, FA_READ | FA_OPEN_EXISTING) != FR_OK)
return 1; return 1;

View File

@ -1,17 +1,11 @@
#include "ticketdb.h" #include "ticketdb.h"
#include "vbdri.h" #include "bdri.h"
#include "support.h" #include "support.h"
#include "aes.h" #include "aes.h"
#include "vff.h"
#include "fsinit.h" #include "fsinit.h"
#include "image.h" #include "image.h"
const char* virtual_tickdb_dirs[] = { #define PART_PATH "D:/partitionA.bin"
"homebrew",
"eshop",
"system",
"unknown",
};
u32 CryptTitleKey(TitleKeyEntry* tik, bool encrypt, bool devkit) { u32 CryptTitleKey(TitleKeyEntry* tik, bool encrypt, bool devkit) {
// From https://github.com/profi200/Project_CTR/blob/master/makerom/pki/prod.h#L19 // From https://github.com/profi200/Project_CTR/blob/master/makerom/pki/prod.h#L19
@ -65,41 +59,25 @@ u32 FindTicket(Ticket** ticket, u8* title_id, bool force_legit, bool emunand) {
char path_store[256] = { 0 }; char path_store[256] = { 0 };
char* path_bak = NULL; char* path_bak = NULL;
// just to be safe
*ticket = NULL;
// store previous mount path
strncpy(path_store, GetMountPath(), 256); strncpy(path_store, GetMountPath(), 256);
if (*path_store) path_bak = path_store; if (*path_store) path_bak = path_store;
if (!InitImgFS(path_db)) if (!InitImgFS(path_db))
return 1; return 1;
char tid_string[17]; // search ticket in database
u64 tid = getbe64(title_id); if (ReadTicketFromDB(PART_PATH, title_id, ticket) != 0) {
snprintf(tid_string, 17, "%016llX", tid);
DIR dir;
FILINFO fno;
char dir_path[12];
char tik_path[64];
for (u32 i = force_legit ? 1 : 0; i < 4; i++) {
snprintf(dir_path, 12, "T:/%s", virtual_tickdb_dirs[i]);
if (fvx_opendir(&dir, dir_path) != FR_OK) {
InitImgFS(path_bak); InitImgFS(path_bak);
return 1; return 1;
} }
while ((fvx_readdir(&dir, &fno) == FR_OK) && *(fno.fname)) { // (optional) validate ticket signature
if (strncmp(tid_string, fno.fname, 16) == 0) { if (force_legit && (ValidateTicketSignature(*ticket) != 0)) {
snprintf(tik_path, 64, "%s/%s", dir_path, fno.fname);
u32 size = fvx_qsize(tik_path);
if (!(*ticket = malloc(size))) {
InitImgFS(path_bak);
return 1;
}
if ((fvx_qread(tik_path, *ticket, 0, size, NULL) != FR_OK) ||
(force_legit && (ValidateTicketSignature(*ticket) != 0))) {
free(*ticket); free(*ticket);
*ticket = NULL;
InitImgFS(path_bak); InitImgFS(path_bak);
return 1; return 1;
} }
@ -107,14 +85,6 @@ u32 FindTicket(Ticket** ticket, u8* title_id, bool force_legit, bool emunand) {
InitImgFS(path_bak); InitImgFS(path_bak);
return 0; return 0;
} }
}
fvx_closedir(&dir);
}
InitImgFS(path_bak);
return 1;
}
u32 FindTitleKey(Ticket* ticket, u8* title_id) { u32 FindTitleKey(Ticket* ticket, u8* title_id) {
bool found = false; bool found = false;

View File

@ -15,6 +15,9 @@
#define CRYPTO_DECRYPT NCCH_NOCRYPTO #define CRYPTO_DECRYPT NCCH_NOCRYPTO
#define CRYPTO_ENCRYPT NCCH_STDCRYPTO #define CRYPTO_ENCRYPT NCCH_STDCRYPTO
// partitionA path
#define PART_PATH "D:/partitionA.bin"
u32 GetNcchHeaders(NcchHeader* ncch, NcchExtHeader* exthdr, ExeFsHeader* exefs, FIL* file, bool nocrypto) { u32 GetNcchHeaders(NcchHeader* ncch, NcchExtHeader* exthdr, ExeFsHeader* exefs, FIL* file, bool nocrypto) {
u32 offset_ncch = fvx_tell(file); u32 offset_ncch = fvx_tell(file);
UINT btr; UINT btr;
@ -1455,14 +1458,14 @@ u32 UninstallGameData(u64 tid64, bool remove_tie, bool remove_ticket, bool remov
if (remove_ticket) { if (remove_ticket) {
char path_ticketdb[256]; char path_ticketdb[256];
if ((GetInstallDbsPath(path_ticketdb, drv, "ticket.db") != 0) || !InitImgFS(path_ticketdb) || if ((GetInstallDbsPath(path_ticketdb, drv, "ticket.db") != 0) || !InitImgFS(path_ticketdb) ||
((RemoveTicketFromDB("D:/partitionA.bin", title_id)) != 0)) ret = 1; ((RemoveTicketFromDB(PART_PATH, title_id)) != 0)) ret = 1;
} }
// title database // title database
if (remove_tie) { if (remove_tie) {
char path_titledb[256]; char path_titledb[256];
if ((GetInstallDbsPath(path_titledb, drv, "title.db") != 0) || !InitImgFS(path_titledb) || if ((GetInstallDbsPath(path_titledb, drv, "title.db") != 0) || !InitImgFS(path_titledb) ||
((RemoveTitleInfoEntryFromDB("D:/partitionA.bin", title_id)) != 0)) ret = 1; ((RemoveTitleInfoEntryFromDB(PART_PATH, title_id)) != 0)) ret = 1;
} }
// restore old mount path // restore old mount path
@ -1676,14 +1679,14 @@ u32 InstallCiaSystemData(CiaStub* cia, const char* drv) {
// title database // title database
if (!InitImgFS(path_titledb) || if (!InitImgFS(path_titledb) ||
((AddTitleInfoEntryToDB("D:/partitionA.bin", title_id, &tie, true)) != 0)) { ((AddTitleInfoEntryToDB(PART_PATH, title_id, &tie, true)) != 0)) {
InitImgFS(path_bak); InitImgFS(path_bak);
return 1; return 1;
} }
// ticket database // ticket database
if (!InitImgFS(path_ticketdb) || if (!InitImgFS(path_ticketdb) ||
((AddTicketToDB("D:/partitionA.bin", title_id, (Ticket*) ticket, true)) != 0)) { ((AddTicketToDB(PART_PATH, title_id, (Ticket*) ticket, true)) != 0)) {
InitImgFS(path_bak); InitImgFS(path_bak);
return 1; return 1;
} }
@ -3004,45 +3007,27 @@ u32 BuildTitleKeyInfo(const char* path, bool dec, bool dump) {
return 1; return 1;
} }
} else if (filetype & SYS_TICKDB) { } else if (filetype & SYS_TICKDB) {
if (!InitImgFS(path_in)) u32 num_entries = GetNumTickets(PART_PATH);
return 1; if (!num_entries) return 1;
u8* title_ids = (u8*) malloc(num_entries * 8);
if (!title_ids) return 1;
DIR dir; if (!InitImgFS(path_in) || (ListTicketTitleIDs(PART_PATH, title_ids, num_entries) != 0)) {
FILINFO fno; free(title_ids);
TicketCommon ticket;
char tik_path[64];
if (fvx_opendir(&dir, "T:/eshop") != FR_OK) {
InitImgFS(NULL); InitImgFS(NULL);
return 1; return 1;
} }
while ((fvx_readdir(&dir, &fno) == FR_OK) && *(fno.fname)) { // read and validate all tickets, add validated to info
snprintf(tik_path, 64, "T:/eshop/%s", fno.fname); for (u32 i = 0; i < num_entries; i++) {
if (fvx_qread(tik_path, &ticket, 0, TICKET_COMMON_SIZE, NULL) != FR_OK) Ticket* ticket;
continue; if (ReadTicketFromDB(PART_PATH, title_ids + (i * 8), &ticket) != 0) continue;
if (TIKDB_SIZE(tik_info) + 32 > STD_BUFFER_SIZE) break; // no error message if (ValidateTicketSignature(ticket) == 0)
AddTicketToInfo(tik_info, (Ticket*) &ticket, dec); // ignore result AddTicketToInfo(tik_info, ticket, dec); // ignore result
free(ticket);
} }
fvx_closedir(&dir); free(title_ids);
if (fvx_opendir(&dir, "T:/system") != FR_OK) {
InitImgFS(NULL);
return 1;
}
while ((fvx_readdir(&dir, &fno) == FR_OK) && *(fno.fname)) {
snprintf(tik_path, 64, "T:/system/%s", fno.fname);
if ((fvx_qread(tik_path, &ticket, 0, TICKET_COMMON_SIZE, NULL) != FR_OK) ||
(ValidateTicketSignature((Ticket*) &ticket) != 0))
continue;
if (TIKDB_SIZE(tik_info) + 32 > STD_BUFFER_SIZE) break; // no error message
AddTicketToInfo(tik_info, (Ticket*) &ticket, dec); // ignore result
}
fvx_closedir(&dir);
InitImgFS(NULL); InitImgFS(NULL);
} else if (filetype & BIN_TIKDB) { } else if (filetype & BIN_TIKDB) {
TitleKeysInfo* tik_info_merge = (TitleKeysInfo*) malloc(STD_BUFFER_SIZE); TitleKeysInfo* tik_info_merge = (TitleKeysInfo*) malloc(STD_BUFFER_SIZE);