fix random crashing when installing xcz/nsz certs

This commit is contained in:
mrdude2478 2023-09-20 21:04:52 +01:00
parent 00f42bca05
commit 2b0ce6c7eb
13 changed files with 93 additions and 74 deletions

View File

@ -44,7 +44,7 @@ DATA := data
INCLUDES := include include/ui include/data include/install include/nx include/nx/ipc include/util $(CURDIR)/include/Plutonium/Plutonium/include
APP_TITLE := TinWoo Installer
APP_AUTHOR := MrDude
APP_VERSION := 1.0.19
APP_VERSION := 1.0.20
ROMFS := romfs
APP_ICON := icon.jpg

View File

@ -54,13 +54,13 @@ namespace tin::install
virtual void InstallContentMetaRecords(tin::data::ByteBuffer& installContentMetaBuf, int i);
virtual void InstallApplicationRecord(int i);
virtual void InstallTicketCert() = 0;
virtual void InstallNCA(const NcmContentId& ncaId) = 0;
public:
virtual ~Install();
virtual void Prepare();
virtual void InstallTicketCert();
virtual void Begin();
virtual u64 GetTitleId(int i = 0);

View File

@ -5,7 +5,7 @@
namespace inst::config {
static const std::string appDir = "sdmc:/switch/tinwoo";
static const std::string configPath = appDir + "/config.json";
static const std::string appVersion = "1.0.19";
static const std::string appVersion = "1.0.20";
extern std::string gAuthKey;
extern std::string sigPatchesUrl;

View File

@ -87,6 +87,7 @@ namespace nspInstStuff_B {
inst::ui::instPage::setInstInfoText("inst.info_page.preparing"_lang);
inst::ui::instPage::setInstBarPerc(0);
installTask->Prepare();
installTask->InstallTicketCert();
installTask->Begin();
togo = (togo - 1);
}

View File

@ -160,16 +160,6 @@ namespace tin::install
void Install::Begin()
{
LOG_DEBUG("Installing ticket and cert...\n");
try
{
this->InstallTicketCert();
}
catch (std::runtime_error& e)
{
LOG_DEBUG("WARNING: Ticket installation failed! This may not be an issue, depending on your use case.\nProceed with caution!\n");
}
for (nx::ncm::ContentMeta contentMeta : m_contentMeta) {
LOG_DEBUG("Installing NCAs...\n");
for (auto& record : contentMeta.GetContentInfos())
@ -180,6 +170,10 @@ namespace tin::install
}
}
void Install::InstallTicketCert() {
this->InstallTicketCert();
}
u64 Install::GetTitleId(int i)
{
return m_contentMeta[i].GetContentMetaKey().id;

View File

@ -75,7 +75,6 @@ namespace tin::install::nsp
CNMTList.push_back({ tin::util::GetContentMetaFromNCA(cnmtNCAFullPath), cnmtContentInfo });
}
return CNMTList;
}
@ -150,18 +149,9 @@ namespace tin::install::nsp
void NSPInstall::InstallTicketCert()
{
u16 ECDSA = 0;
u16 RSA_2048 = 0;
u16 RSA_4096 = 0;
// Read the tik files and put it into a buffer
std::vector<const PFS0FileEntry*> tikFileEntries = m_NSP->GetFileEntriesByExtension("tik");
std::vector<const PFS0FileEntry*> certFileEntries = m_NSP->GetFileEntriesByExtension("cert");
// https://switchbrew.org/wiki/Ticket#Certificate_chain
ECDSA = (0x4 + 0x3C + 0x40 + 0x146);
RSA_2048 = (0x4 + 0x100 + 0x3C + 0x146);
RSA_4096 = (0x4 + 0x200 + 0x3C + 0x146);
for (size_t i = 0; i < tikFileEntries.size(); i++)
{
if (tikFileEntries[i] == nullptr) {
@ -186,8 +176,16 @@ namespace tin::install::nsp
m_NSP->BufferData(certBuf.get(), m_NSP->GetDataOffset() + certFileEntries[i]->dataOffset, certSize);
// try to fix a temp ticket and change it t a permanent one
// https://switchbrew.org/wiki/Ticket#Certificate_chain
if (inst::config::fixticket) {
//ECDSA SHA256
u16 ECDSA = 0;
u16 RSA_2048 = 0;
u16 RSA_4096 = 0;
ECDSA = (0x4 + 0x3C + 0x40 + 0x146);
RSA_2048 = (0x4 + 0x100 + 0x3C + 0x146);
RSA_4096 = (0x4 + 0x200 + 0x3C + 0x146);
if (tikBuf.get()[0x0] == 0x5 && (tikBuf.get()[ECDSA] == 0x10 || tikBuf.get()[ECDSA] == 0x30))
{
tikBuf.get()[ECDSA] = 0x0;
@ -229,8 +227,6 @@ namespace tin::install::nsp
tikBuf.get()[RSA_4096 - 1] = 0x10;
}
}
//printout the cert and ticket to a file in the tinwoo directory for testing.
/*
FILE * pFile;
@ -242,6 +238,7 @@ namespace tin::install::nsp
fwrite (tikBuf.get(), sizeof(char), tikSize, pFile);
fclose (pFile);
*/
}
// Finally, let's actually import the ticket
ASSERT_OK(esImportTicket(tikBuf.get(), tikSize, certBuf.get(), certSize), "Failed to import ticket");

View File

@ -145,21 +145,13 @@ namespace tin::install::xci
catch (...) {}
}
//xci files don't have a ticket or cert - so this is useful when installing a converted nsp to xci
void XCIInstallTask::InstallTicketCert()
{
u16 ECDSA = 0;
u16 RSA_2048 = 0;
u16 RSA_4096 = 0;
// Read the tik files and put it into a buffer
std::vector<const HFS0FileEntry*> tikFileEntries = m_xci->GetFileEntriesByExtension("tik");
std::vector<const HFS0FileEntry*> certFileEntries = m_xci->GetFileEntriesByExtension("cert");
// https://switchbrew.org/wiki/Ticket#Certificate_chain
ECDSA = (0x4 + 0x3C + 0x40 + 0x146);
RSA_2048 = (0x4 + 0x100 + 0x3C + 0x146);
RSA_4096 = (0x4 + 0x200 + 0x3C + 0x146);
for (size_t i = 0; i < tikFileEntries.size(); i++)
{
if (tikFileEntries[i] == nullptr)
@ -186,6 +178,15 @@ namespace tin::install::xci
// try to fix a temp ticket and change it t a permanent one
if (inst::config::fixticket) {
u16 ECDSA = 0;
u16 RSA_2048 = 0;
u16 RSA_4096 = 0;
// https://switchbrew.org/wiki/Ticket#Certificate_chain
ECDSA = (0x4 + 0x3C + 0x40 + 0x146);
RSA_2048 = (0x4 + 0x100 + 0x3C + 0x146);
RSA_4096 = (0x4 + 0x200 + 0x3C + 0x146);
//ECDSA SHA256
if (tikBuf.get()[0x0] == 0x5 && (tikBuf.get()[ECDSA] == 0x10 || tikBuf.get()[ECDSA] == 0x30))
{

View File

@ -69,15 +69,6 @@ namespace tin::install::nsp
size_t fileEntryOffset = sizeof(PFS0BaseHeader) + index * sizeof(PFS0FileEntry);
/*
//print fileEntryOffset
FILE * fp;
fp = fopen ("offset.txt", "a+");
size_t debug = fileEntryOffset;
fprintf(fp, "%zu\n", debug);
fclose(fp);
*/
if (m_headerBytes.size() < fileEntryOffset + sizeof(PFS0FileEntry))
THROW_FORMAT("Header bytes is too small to get file entry!");
@ -92,7 +83,15 @@ namespace tin::install::nsp
{
const PFS0FileEntry* fileEntry = this->GetFileEntry(i);
std::string name(this->GetFileEntryName(fileEntry));
auto foundExtension = name.substr(name.find(".") + 1);
// fix cert filname extension becoming corrupted when xcz/nsz is installing certs/ticks.
FILE* fp;
int pos = 0;
std::string mystr = name;
pos = mystr.find_last_of('.');
mystr = mystr.substr(5, pos);
//auto foundExtension = name.substr(name.find(".") + 1);
auto foundExtension = mystr.substr(mystr.find(".") + 1);
if (foundExtension == extension)
entryList.push_back(fileEntry);
@ -103,14 +102,27 @@ namespace tin::install::nsp
const PFS0FileEntry* NSP::GetFileEntryByName(std::string name)
{
//returns only the .nca and .cnmt.nca filenames
for (unsigned int i = 0; i < this->GetBaseHeader()->numFiles; i++)
{
const PFS0FileEntry* fileEntry = this->GetFileEntry(i);
std::string foundName(this->GetFileEntryName(fileEntry));
if (foundName == name)
if (foundName == name) {
/*
//Debug code
FILE * fp;
fp = fopen ("name.txt", "a+");
std::string x = foundName;
const char *info = x.c_str();
fprintf(fp, "%s\n", info);
fclose(fp);
*/
return fileEntry;
}
}
return nullptr;
}
@ -140,6 +152,17 @@ namespace tin::install::nsp
const char* NSP::GetFileEntryName(const PFS0FileEntry* fileEntry)
{
u64 stringTableStart = sizeof(PFS0BaseHeader) + this->GetBaseHeader()->numFiles * sizeof(PFS0FileEntry);
//check for messed up filenames in our table.... usually when instaling xcz/xci
/*
FILE * fp;
fp = fopen ("st.txt", "a+");
std::string x = reinterpret_cast<const char*>(m_headerBytes.data() + stringTableStart + fileEntry->stringTableOffset);
const char *info = x.c_str();
fprintf(fp, "%s\n", info);
fclose(fp);
*/
return reinterpret_cast<const char*>(m_headerBytes.data() + stringTableStart + fileEntry->stringTableOffset);
}
@ -155,16 +178,6 @@ namespace tin::install::nsp
{
if (m_headerBytes.empty())
THROW_FORMAT("Cannot get data offset as header is empty. Have you retrieved it yet?\n");
/*
//print size of header
FILE * fp;
fp = fopen ("file.txt", "a+");
u64 debug = m_headerBytes.size();
fprintf(fp, "%lu\n", debug);
fclose(fp);
*/
return m_headerBytes.size();
}
}

View File

@ -158,7 +158,15 @@ namespace tin::install::xci
{
const HFS0FileEntry* fileEntry = this->GetFileEntry(i);
std::string name(this->GetFileEntryName(fileEntry));
auto foundExtension = name.substr(name.find(".") + 1);
// fix cert filname extension becoming corrupted when xcz/nsz is installing certs/ticks.
FILE* fp;
int pos = 0;
std::string mystr = name;
pos = mystr.find_last_of('.');
mystr = mystr.substr(5, pos);
//auto foundExtension = name.substr(name.find(".") + 1);
auto foundExtension = mystr.substr(mystr.find(".") + 1);
if (foundExtension == extension)
entryList.push_back(fileEntry);

View File

@ -228,6 +228,7 @@ namespace netInstStuff {
inst::ui::instPage::setInstInfoText("inst.info_page.preparing"_lang);
inst::ui::instPage::setInstBarPerc(0);
installTask->Prepare();
installTask->InstallTicketCert();
installTask->Begin();
togo = (togo - 1);
}

View File

@ -101,6 +101,8 @@ public:
class SectionContext : public Section
{
public:
Crypto::Aes128Ctr crypto;
SectionContext(const Section& s) : Section(s), crypto(s.cryptoKey, Crypto::AesCtr(Crypto::swapEndian(((u64*)&s.cryptoCounter)[0])))
{
}
@ -111,27 +113,27 @@ public:
void decrypt(void* p, u64 sz, u64 offset)
{
if (this->cryptoType != 3)
if (this->cryptoType == 3 || this->cryptoType == 4)
{
return;
}
crypto.seek(offset);
crypto.decrypt(p, p, sz);
}
else {
return;
}
}
void encrypt(void* p, u64 sz, u64 offset)
{
if (this->cryptoType != 3)
if (this->cryptoType == 3 || this->cryptoType == 4)
{
return;
}
crypto.seek(offset);
crypto.encrypt(p, p, sz);
}
Crypto::Aes128Ctr crypto;
else {
return;
}
}
};
const bool isValid()

View File

@ -87,7 +87,8 @@ namespace nspInstStuff {
inst::ui::instPage::setInstInfoText("inst.info_page.preparing"_lang);
inst::ui::instPage::setInstBarPerc(0);
installTask->Prepare();
installTask->Begin();
installTask->InstallTicketCert();
installTask->Begin(); //install nca files
togo = (togo - 1);
}

View File

@ -137,6 +137,7 @@ namespace usbInstStuff {
inst::ui::instPage::setInstInfoText("inst.info_page.preparing"_lang);
inst::ui::instPage::setInstBarPerc(0);
installTask->Prepare();
installTask->InstallTicketCert();
installTask->Begin();
togo = (togo - 1);
}