From be289b4c5543b58b1835b994ccd901979169a267 Mon Sep 17 00:00:00 2001 From: luigoalma Date: Thu, 6 May 2021 16:02:27 +0100 Subject: [PATCH] Just search both nands for certs on callee Since in all cases that LoadCertFromCertDb is called is always twice, one for sysnand and another for emunand just make it a single call and quit early when cert found. --- arm9/source/game/cert.c | 64 ++++++++++++++++++++------------------- arm9/source/game/cert.h | 2 +- arm9/source/game/ticket.c | 4 +-- arm9/source/game/tmd.c | 4 +-- 4 files changed, 38 insertions(+), 36 deletions(-) diff --git a/arm9/source/game/cert.c b/arm9/source/game/cert.c index 3b96ee8..aecb3d3 100644 --- a/arm9/source/game/cert.c +++ b/arm9/source/game/cert.c @@ -530,7 +530,7 @@ static u32 _ProcessNextCertDbEntry(const char* path, DisaDiffRWInfo* info, Certi return 0; } -u32 LoadCertFromCertDb(bool emunand, Certificate* cert, const char* issuer) { +u32 LoadCertFromCertDb(Certificate* cert, const char* issuer) { if (!issuer || !cert) return 1; u32 _ident = _Issuer_To_StorageIdent(issuer); @@ -538,48 +538,50 @@ u32 LoadCertFromCertDb(bool emunand, Certificate* cert, const char* issuer) { return 0; } - Certificate cert_local = {NULL, NULL}; + int ret = 1; - char path[16]; - DisaDiffRWInfo info; - u8* cache; + for (int i = 0; i < 2 && ret; ++i) { + Certificate cert_local = {NULL, NULL}; - u32 offset, max_offset; + char path[16]; + DisaDiffRWInfo info; + u8* cache; - if (_DisaOpenCertDb(&path, emunand, &info, &cache, &offset, &max_offset)) - return 1; + u32 offset, max_offset; - u32 ret = 1; + if (_DisaOpenCertDb(&path, i ? true : false, &info, &cache, &offset, &max_offset)) + return 1; - // certs.db has no filesystem.. its pretty plain, certificates after another - // but also, certificates are not equally sized - // so most cases of bad data, leads to giving up - while (offset < max_offset) { - char full_issuer[0x41]; - u32 full_size; + // certs.db has no filesystem.. its pretty plain, certificates after another + // but also, certificates are not equally sized + // so most cases of bad data, leads to giving up + while (offset < max_offset) { + char full_issuer[0x41]; + u32 full_size; - if (_ProcessNextCertDbEntry(path, &info, &cert_local, &full_size, &full_issuer, &offset, max_offset)) - break; + if (_ProcessNextCertDbEntry(path, &info, &cert_local, &full_size, &full_issuer, &offset, max_offset)) + break; - if (!strcmp(full_issuer, issuer)) { - ret = 0; - break; + if (!strcmp(full_issuer, issuer)) { + ret = 0; + break; + } + + _Certificate_CleanupImpl(&cert_local); + + offset += full_size; } - _Certificate_CleanupImpl(&cert_local); + if (ret) { + _Certificate_CleanupImpl(&cert_local); + } else { + *cert = cert_local; + _SaveToCertStorage(&cert_local, _ident); + } - offset += full_size; + free(cache); } - if (ret) { - _Certificate_CleanupImpl(&cert_local); - } else { - _SaveToCertStorage(&cert_local, _ident); - } - - *cert = cert_local; - - free(cache); return ret; } diff --git a/arm9/source/game/cert.h b/arm9/source/game/cert.h index 4e8b3c2..f8ed6f7 100644 --- a/arm9/source/game/cert.h +++ b/arm9/source/game/cert.h @@ -47,5 +47,5 @@ u32 Certificate_AllocCopyOut(const Certificate* cert, Certificate* out_cert); u32 Certificate_RawCopy(const Certificate* cert, void* raw); u32 Certificate_Cleanup(Certificate* cert); -u32 LoadCertFromCertDb(bool emunand, Certificate* cert, const char* issuer); +u32 LoadCertFromCertDb(Certificate* cert, const char* issuer); u32 BuildRawCertBundleFromCertDb(void* rawout, size_t* size, const char* const* cert_issuers, int count); diff --git a/arm9/source/game/ticket.c b/arm9/source/game/ticket.c index fbf5139..0ace6f0 100644 --- a/arm9/source/game/ticket.c +++ b/arm9/source/game/ticket.c @@ -32,8 +32,8 @@ u32 ValidateTicketSignature(Ticket* ticket) { u32 mod[2048/8]; u32 exp = 0; - // grab mod/exp from cert from cert.db - if (LoadCertFromCertDb(false, &cert, (char*)(ticket->issuer)) != 0 && LoadCertFromCertDb(true, &cert, (char*)(ticket->issuer)) != 0) + // grab cert from certs.db + if (LoadCertFromCertDb(&cert, (char*)(ticket->issuer)) != 0) return 1; // current code only expects RSA2048 diff --git a/arm9/source/game/tmd.c b/arm9/source/game/tmd.c index 8d78526..50c20f5 100644 --- a/arm9/source/game/tmd.c +++ b/arm9/source/game/tmd.c @@ -28,8 +28,8 @@ u32 ValidateTmdSignature(TitleMetaData* tmd) { u32 mod[2048/8]; u32 exp = 0; - // grab mod/exp from cert from cert.db - if (LoadCertFromCertDb(false, &cert, (char*)(tmd->issuer)) != 0 && LoadCertFromCertDb(true, &cert, (char*)(tmd->issuer)) != 0) + // grab cert from certs.db + if (LoadCertFromCertDb(&cert, (char*)(tmd->issuer)) != 0) return 1; // current code only expects RSA2048