[nstool] NCA external content key can be sourced from a supplied ticket.

This commit is contained in:
jakcron 2018-08-06 18:39:24 +08:00
parent a757116502
commit 1266ba3976
2 changed files with 32 additions and 1 deletions

View file

@ -22,7 +22,8 @@
#include <nx/nso.h> #include <nx/nso.h>
#include <nx/nro.h> #include <nx/nro.h>
#include <nx/aset.h> #include <nx/aset.h>
#include <pki/SignatureBlock.h> #include <pki/SignedData.h>
#include <es/TicketBody_V2.h>
UserSettings::UserSettings() UserSettings::UserSettings()
{} {}
@ -66,6 +67,7 @@ void UserSettings::showHelp()
printf(" --listfs Print file system in embedded partitions.\n"); printf(" --listfs Print file system in embedded partitions.\n");
printf(" --titlekey Specify title key extracted from ticket.\n"); printf(" --titlekey Specify title key extracted from ticket.\n");
printf(" --bodykey Specify body encryption key.\n"); printf(" --bodykey Specify body encryption key.\n");
printf(" --tik Specify ticket to source title key.\n");
printf(" --part0 Extract \"partition 0\" to directory.\n"); printf(" --part0 Extract \"partition 0\" to directory.\n");
printf(" --part1 Extract \"partition 1\" to directory.\n"); printf(" --part1 Extract \"partition 1\" to directory.\n");
printf(" --part2 Extract \"partition 2\" to directory.\n"); printf(" --part2 Extract \"partition 2\" to directory.\n");
@ -297,6 +299,12 @@ void UserSettings::populateCmdArgs(const std::vector<std::string>& arg_list, sCm
cmd_args.nca_bodykey = arg_list[i+1]; cmd_args.nca_bodykey = arg_list[i+1];
} }
else if (arg_list[i] == "--tik")
{
if (!hasParamter) throw fnd::Exception(kModuleName, arg_list[i] + " requries a parameter.");
cmd_args.ticket_path = arg_list[i+1];
}
else if (arg_list[i] == "--part0") else if (arg_list[i] == "--part0")
{ {
if (!hasParamter) throw fnd::Exception(kModuleName, arg_list[i] + " requries a parameter."); if (!hasParamter) throw fnd::Exception(kModuleName, arg_list[i] + " requries a parameter.");
@ -527,6 +535,28 @@ void UserSettings::populateKeyset(sCmdArgs& args)
} }
} }
// get titlekey from ticket
if (args.ticket_path.isSet)
{
fnd::SimpleFile tik_file;
fnd::Vec<byte_t> tik_raw;
pki::SignedData<es::TicketBody_V2> tik;
tik_file.open(args.ticket_path.var, fnd::SimpleFile::Read);
tik_raw.alloc(tik_file.size());
tik_file.read(tik_raw.data(), tik_raw.size());
tik.fromBytes(tik_raw.data(), tik_raw.size());
if (tik.getBody().getTitleKeyEncType() == es::ticket::AES128_CBC)
{
memcpy(mKeyset.nca.manual_title_key_aesctr.key, tik.getBody().getEncTitleKey(), crypto::aes::kAes128KeySize);
}
else
{
std::cout << "[WARNING] Titlekey not imported from ticket because it is personalised" << std::endl;
}
}
#undef _SAVE_KEYDATA #undef _SAVE_KEYDATA
#undef _CONCAT_3_STRINGS #undef _CONCAT_3_STRINGS
#undef _CONCAT_2_STRINGS #undef _CONCAT_2_STRINGS

View file

@ -62,6 +62,7 @@ private:
sOptional<std::string> fs_path; sOptional<std::string> fs_path;
sOptional<std::string> nca_titlekey; sOptional<std::string> nca_titlekey;
sOptional<std::string> nca_bodykey; sOptional<std::string> nca_bodykey;
sOptional<std::string> ticket_path;
sOptional<std::string> part0_path; sOptional<std::string> part0_path;
sOptional<std::string> part1_path; sOptional<std::string> part1_path;
sOptional<std::string> part2_path; sOptional<std::string> part2_path;